From patchwork Fri Nov 20 03:24:50 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Huang Shijie X-Patchwork-Id: 61543 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nAK3PXKN012353 for ; Fri, 20 Nov 2009 03:25:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758264AbZKTDZX (ORCPT ); Thu, 19 Nov 2009 22:25:23 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758263AbZKTDZX (ORCPT ); Thu, 19 Nov 2009 22:25:23 -0500 Received: from mail-yx0-f187.google.com ([209.85.210.187]:58859 "EHLO mail-yx0-f187.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758254AbZKTDZR (ORCPT ); Thu, 19 Nov 2009 22:25:17 -0500 Received: by mail-yx0-f187.google.com with SMTP id 17so2630577yxe.33 for ; Thu, 19 Nov 2009 19:25:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=BN4hZ/3u1cYpYl7XcGeZlEIZ3U60Y8No5zkoJtJzqds=; b=S+2nU9p5VS8R0a9XR+iMGqyIpUb/9rvYZFd+pl81IulR0mB9Y/HzvxjNLLoC4zqo67 82LVPsVcUoo/gJuJbNQ9oJK8z/MegCRP/PQ1P05R2Lm7YerVclCH/+cZ0FK+KY40UjMs +9f2q7ZXdu9TH/UWrx0MRGX34jqfL7xOAB6aw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=Wwu0kHU0p8jTNtaM6yfM7BX13Sy97CKmI1Rnkq2E05rFMktZOnFhmrTJyTc/vpmTuK +com11HB3KLgainjE1Kh/MaY88gGymqB3AvuwWEnzm0Mf7mLMdsga/wMWoKO/sPhQHha xsgguABSg369Pv41xoLKQARIriTX0T6bVLkVs= Received: by 10.150.239.1 with SMTP id m1mr1616585ybh.152.1258687523490; Thu, 19 Nov 2009 19:25:23 -0800 (PST) Received: from localhost.localdomain ([211.144.218.162]) by mx.google.com with ESMTPS id 9sm192108ywe.26.2009.11.19.19.25.20 (version=SSLv3 cipher=RC4-MD5); Thu, 19 Nov 2009 19:25:23 -0800 (PST) From: Huang Shijie To: mchehab@redhat.com Cc: linux-media@vger.kernel.org, Huang Shijie Subject: [PATCH 08/11] add vbi code for tlg2300 Date: Fri, 20 Nov 2009 11:24:50 +0800 Message-Id: <1258687493-4012-9-git-send-email-shijie8@gmail.com> X-Mailer: git-send-email 1.6.0.6 In-Reply-To: <1258687493-4012-8-git-send-email-shijie8@gmail.com> References: <1258687493-4012-1-git-send-email-shijie8@gmail.com> <1258687493-4012-2-git-send-email-shijie8@gmail.com> <1258687493-4012-3-git-send-email-shijie8@gmail.com> <1258687493-4012-4-git-send-email-shijie8@gmail.com> <1258687493-4012-5-git-send-email-shijie8@gmail.com> <1258687493-4012-6-git-send-email-shijie8@gmail.com> <1258687493-4012-7-git-send-email-shijie8@gmail.com> <1258687493-4012-8-git-send-email-shijie8@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org diff --git a/drivers/media/video/tlg2300/pd-vbi.c b/drivers/media/video/tlg2300/pd-vbi.c new file mode 100644 index 0000000..fb9ee0d --- /dev/null +++ b/drivers/media/video/tlg2300/pd-vbi.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vendorcmds.h" +#include "pd-common.h" + +int vbi_request_buf(struct vbi_data *vbi_data, size_t size) +{ + int i, count = 4; + + pd_bufqueue_init(&vbi_data->vbi_queue, &count, size, KERNEL_MEM); + + for (i = 0; i < count; i++) + pd_bufqueue_qbuf(&vbi_data->vbi_queue, i); + + vbi_data->buf_count = count; + return 0; +} + +int vbi_release_buf(struct vbi_data *vbi_data) +{ + if (vbi_data->buf_count) { + pd_bufqueue_cleanup(&vbi_data->vbi_queue); + pd_bufqueue_wakeup(&vbi_data->vbi_queue); + vbi_data->buf_count = 0; + } + return 0; +} + +static long vbi_v4l2_ioctl(struct file *file, + u32 cmd, unsigned long argp) +{ + struct poseidon *pd = file->private_data; + int ret = 0; + + mutex_lock(&pd->lock); + switch (cmd) { + case VIDIOC_QUERYCAP: { + struct v4l2_capability *t_cap = (struct v4l2_capability *)argp; + + strcpy(t_cap->driver, "Telegent Driver"); + strcpy(t_cap->card, "Telegent Poseidon"); + strcpy(t_cap->bus_info, "USB bus"); + t_cap->version = 0; + t_cap->capabilities = V4L2_CAP_VBI_CAPTURE; + } + break; + + case VIDIOC_S_FMT: + case VIDIOC_G_FMT: { + struct v4l2_format *v4l2_f = (struct v4l2_format *)argp; + + v4l2_f->fmt.vbi.sampling_rate = 6750000 * 4; + v4l2_f->fmt.vbi.samples_per_line = 720*2/* VBI_LINE_LENGTH */; + v4l2_f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; + v4l2_f->fmt.vbi.offset = 64 * 4; /*FIXME: why offset */ + if (pd->video_data.tvnormid & V4L2_STD_525_60) { + v4l2_f->fmt.vbi.start[0] = 10; + v4l2_f->fmt.vbi.start[1] = 264; + v4l2_f->fmt.vbi.count[0] = V4L_NTSC_VBI_LINES; + v4l2_f->fmt.vbi.count[1] = V4L_NTSC_VBI_LINES; + } else { + v4l2_f->fmt.vbi.start[0] = 6; + v4l2_f->fmt.vbi.start[1] = 314; + v4l2_f->fmt.vbi.count[0] = V4L_PAL_VBI_LINES; + v4l2_f->fmt.vbi.count[1] = V4L_PAL_VBI_LINES; + } + /* VBI_UNSYNC VBI_INTERLACED */ + v4l2_f->fmt.vbi.flags = V4L2_VBI_UNSYNC; + } + break; + + default: + ret = -EINVAL; + } + mutex_unlock(&pd->lock); + return ret; +} + +static ssize_t vbi_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct poseidon *pd = file->private_data; + struct vbi_data *vbi = &pd->vbi_data; + + return vbi->buf_count ? + pd_bufqueue_read(&vbi->vbi_queue, file->f_flags, buffer, count) + : -EINVAL; +} + +static int vbi_open(struct file *file) +{ + int ret = 0; + struct video_device *vd = video_devdata(file); + struct poseidon *pd = video_get_drvdata(vd); + + if (!pd) + return -ENODEV; + + mutex_lock(&pd->lock); + if (pd->state & POSEIDON_STATE_DISCONNECT) { + ret = -ENODEV; + goto out; + } + kref_get(&pd->kref); + file->private_data = pd; + set_debug_mode(vd, debug_mode); +out: + mutex_unlock(&pd->lock); + return ret; +} + +static int vbi_release(struct file *file) +{ + struct poseidon *pd = file->private_data; + + if (!pd) + return -ENODEV; + + kref_put(&pd->kref, poseidon_delete); + return 0; +} + +static const struct v4l2_file_operations vbi_file_ops = { + .owner = THIS_MODULE, + .open = vbi_open, + .release = vbi_release, + .read = vbi_read, + .ioctl = vbi_v4l2_ioctl, +}; + +static struct video_device vbi_device = { + .name = "poseidon_vbi", + .fops = &vbi_file_ops, + .release = video_device_release, +}; + +int vbi_init(struct poseidon *pd) +{ + int ret = 0; + + memset(&(pd->vbi_data), 0, sizeof(struct vbi_data)); + + pd->vbi_data.vbi_dev = vdev_init(pd, &vbi_device); + if (pd->vbi_data.vbi_dev == NULL) { + ret = -ENOMEM; + goto vbi_error; + } + + if (video_register_device(pd->vbi_data.vbi_dev, VFL_TYPE_VBI, -1) < 0) { + video_device_release(pd->vbi_data.vbi_dev); + pd->vbi_data.vbi_dev = NULL; + printk(KERN_DEBUG"vbi_init : video device register failed\n"); + ret = -1; + } + +vbi_error: + return ret; +} + +int vbi_exit(struct poseidon *pd) +{ + struct vbi_data *vbi_data = &pd->vbi_data; + + if (vbi_data->vbi_dev) { + video_unregister_device(vbi_data->vbi_dev); + vbi_data->vbi_dev = NULL; + } + return 0; +}