[go: nahoru, domu]

128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller/*
228abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   em28xx-vbi.c - VBI driver for em28xx
328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
428abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
528abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
628abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   This work was sponsored by EyeMagnet Limited.
728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   This program is free software; you can redistribute it and/or modify
928abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   it under the terms of the GNU General Public License as published by
1028abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   the Free Software Foundation; either version 2 of the License, or
1128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   (at your option) any later version.
1228abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
1328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   This program is distributed in the hope that it will be useful,
1428abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   but WITHOUT ANY WARRANTY; without even the implied warranty of
1528abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1628abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   GNU General Public License for more details.
1728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
1828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   You should have received a copy of the GNU General Public License
1928abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   along with this program; if not, write to the Free Software
2028abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller   02110-1301, USA.
2228abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller */
2328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
2428abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller#include <linux/kernel.h>
2528abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller#include <linux/module.h>
26c59a9bfabfc2a6359f046652c6bfa0a82fb17a05Randy Dunlap#include <linux/hardirq.h>
2728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller#include <linux/init.h>
2828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
2928abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller#include "em28xx.h"
3001c2819330b1e0ec6b53dcfac76ad75ff2c8ba4fMauro Carvalho Chehab#include "em28xx-v4l.h"
3128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
3228abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller/* ------------------------------------------------------------------ */
3328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
34d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmuellerstatic int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
35d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller			   unsigned int *nbuffers, unsigned int *nplanes,
36d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller			   unsigned int sizes[], void *alloc_ctxs[])
3728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller{
38d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	struct em28xx *dev = vb2_get_drv_priv(vq);
39753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer	struct em28xx_v4l2 *v4l2 = dev->v4l2;
40d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	unsigned long size;
4128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
42d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	if (fmt)
43d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		size = fmt->fmt.pix.sizeimage;
44d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	else
45753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer		size = v4l2->vbi_width * v4l2->vbi_height * 2;
4628abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
47d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	if (0 == *nbuffers)
48d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		*nbuffers = 32;
49d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	if (*nbuffers < 2)
50d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		*nbuffers = 2;
51d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	if (*nbuffers > 32)
52d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		*nbuffers = 32;
5366d9cbad5330d6df30c82f10ee18b62b096b84efDevin Heitmueller
54d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	*nplanes = 1;
55d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	sizes[0] = size;
5666d9cbad5330d6df30c82f10ee18b62b096b84efDevin Heitmueller
5728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller	return 0;
5828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller}
5928abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
60d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmuellerstatic int vbi_buffer_prepare(struct vb2_buffer *vb)
6128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller{
62753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer	struct em28xx        *dev  = vb2_get_drv_priv(vb->vb2_queue);
63753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer	struct em28xx_v4l2   *v4l2 = dev->v4l2;
64753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer	struct em28xx_buffer *buf  = container_of(vb, struct em28xx_buffer, vb);
65d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	unsigned long        size;
6628abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
67753aee7738ed2ee8c810524ee32b556ac7617f2eFrank Schaefer	size = v4l2->vbi_width * v4l2->vbi_height * 2;
6828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
69d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	if (vb2_plane_size(vb, 0) < size) {
70d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n",
71d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller		       __func__, vb2_plane_size(vb, 0), size);
7228abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller		return -EINVAL;
7328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller	}
74d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	vb2_set_plane_payload(&buf->vb, 0, size);
7528abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
7628abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller	return 0;
7728abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller}
7828abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
7928abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmuellerstatic void
80d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmuellervbi_buffer_queue(struct vb2_buffer *vb)
8128abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller{
82d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
8328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
84d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	struct em28xx_dmaqueue *vbiq = &dev->vbiq;
85d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	unsigned long flags = 0;
86d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller
87d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	buf->mem = vb2_plane_vaddr(vb, 0);
88d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	buf->length = vb2_plane_size(vb, 0);
89d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller
90d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	spin_lock_irqsave(&dev->slock, flags);
91d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	list_add_tail(&buf->list, &vbiq->active);
92d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	spin_unlock_irqrestore(&dev->slock, flags);
9328abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller}
9428abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller
95d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller
96d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmuellerstruct vb2_ops em28xx_vbi_qops = {
97d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.queue_setup    = vbi_queue_setup,
98d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.buf_prepare    = vbi_buffer_prepare,
99d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.buf_queue      = vbi_buffer_queue,
100d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.start_streaming = em28xx_start_analog_streaming,
101d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.stop_streaming = em28xx_stop_vbi_streaming,
102d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.wait_prepare   = vb2_ops_wait_prepare,
103d3829fadc4611e96aa360b8ead5adefdf61f45eaDevin Heitmueller	.wait_finish    = vb2_ops_wait_finish,
10428abf083d356bc4ec459ded7a95b6a22a20f6c3dDevin Heitmueller};
105