xref: /openbmc/linux/drivers/media/usb/au0828/au0828-vbi.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
116216333SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c0d06caSMauro Carvalho Chehab /*
30c0d06caSMauro Carvalho Chehab    au0828-vbi.c - VBI driver for au0828
40c0d06caSMauro Carvalho Chehab 
50c0d06caSMauro Carvalho Chehab    Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
60c0d06caSMauro Carvalho Chehab 
70c0d06caSMauro Carvalho Chehab    This work was sponsored by GetWellNetwork Inc.
80c0d06caSMauro Carvalho Chehab 
90c0d06caSMauro Carvalho Chehab  */
100c0d06caSMauro Carvalho Chehab 
1183afb32aSMauro Carvalho Chehab #include "au0828.h"
1283afb32aSMauro Carvalho Chehab 
130c0d06caSMauro Carvalho Chehab #include <linux/kernel.h>
140c0d06caSMauro Carvalho Chehab #include <linux/module.h>
150c0d06caSMauro Carvalho Chehab #include <linux/init.h>
160c0d06caSMauro Carvalho Chehab #include <linux/slab.h>
17*c4cd4c8bSHans Verkuil #include <media/v4l2-mc.h>
180c0d06caSMauro Carvalho Chehab 
190c0d06caSMauro Carvalho Chehab /* ------------------------------------------------------------------ */
200c0d06caSMauro Carvalho Chehab 
vbi_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])21df9ecb0cSHans Verkuil static int vbi_queue_setup(struct vb2_queue *vq,
2205439b1aSShuah Khan 			   unsigned int *nbuffers, unsigned int *nplanes,
2336c0f8b3SHans Verkuil 			   unsigned int sizes[], struct device *alloc_devs[])
240c0d06caSMauro Carvalho Chehab {
2505439b1aSShuah Khan 	struct au0828_dev *dev = vb2_get_drv_priv(vq);
26df9ecb0cSHans Verkuil 	unsigned long size = dev->vbi_width * dev->vbi_height * 2;
270c0d06caSMauro Carvalho Chehab 
28df9ecb0cSHans Verkuil 	if (*nplanes)
29df9ecb0cSHans Verkuil 		return sizes[0] < size ? -EINVAL : 0;
3005439b1aSShuah Khan 	*nplanes = 1;
3105439b1aSShuah Khan 	sizes[0] = size;
3205439b1aSShuah Khan 	return 0;
330c0d06caSMauro Carvalho Chehab }
340c0d06caSMauro Carvalho Chehab 
vbi_buffer_prepare(struct vb2_buffer * vb)3505439b1aSShuah Khan static int vbi_buffer_prepare(struct vb2_buffer *vb)
3605439b1aSShuah Khan {
3705439b1aSShuah Khan 	struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
3805439b1aSShuah Khan 	unsigned long size;
390c0d06caSMauro Carvalho Chehab 
4005439b1aSShuah Khan 	size = dev->vbi_width * dev->vbi_height * 2;
4105439b1aSShuah Khan 
4205439b1aSShuah Khan 	if (vb2_plane_size(vb, 0) < size) {
4305439b1aSShuah Khan 		pr_err("%s data will not fit into plane (%lu < %lu)\n",
4405439b1aSShuah Khan 			__func__, vb2_plane_size(vb, 0), size);
4505439b1aSShuah Khan 		return -EINVAL;
4605439b1aSShuah Khan 	}
472d700715SJunghak Sung 	vb2_set_plane_payload(vb, 0, size);
4805439b1aSShuah Khan 
4905439b1aSShuah Khan 	return 0;
500c0d06caSMauro Carvalho Chehab }
510c0d06caSMauro Carvalho Chehab 
520c0d06caSMauro Carvalho Chehab static void
vbi_buffer_queue(struct vb2_buffer * vb)5305439b1aSShuah Khan vbi_buffer_queue(struct vb2_buffer *vb)
540c0d06caSMauro Carvalho Chehab {
5505439b1aSShuah Khan 	struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
562d700715SJunghak Sung 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
572d700715SJunghak Sung 	struct au0828_buffer *buf =
582d700715SJunghak Sung 			container_of(vbuf, struct au0828_buffer, vb);
5905439b1aSShuah Khan 	struct au0828_dmaqueue *vbiq = &dev->vbiq;
6005439b1aSShuah Khan 	unsigned long flags = 0;
6105439b1aSShuah Khan 
6205439b1aSShuah Khan 	buf->mem = vb2_plane_vaddr(vb, 0);
6305439b1aSShuah Khan 	buf->length = vb2_plane_size(vb, 0);
6405439b1aSShuah Khan 
6505439b1aSShuah Khan 	spin_lock_irqsave(&dev->slock, flags);
6605439b1aSShuah Khan 	list_add_tail(&buf->list, &vbiq->active);
6705439b1aSShuah Khan 	spin_unlock_irqrestore(&dev->slock, flags);
680c0d06caSMauro Carvalho Chehab }
690c0d06caSMauro Carvalho Chehab 
70ac71484eSBhumika Goyal const struct vb2_ops au0828_vbi_qops = {
7105439b1aSShuah Khan 	.queue_setup     = vbi_queue_setup,
7205439b1aSShuah Khan 	.buf_prepare     = vbi_buffer_prepare,
7305439b1aSShuah Khan 	.buf_queue       = vbi_buffer_queue,
74*c4cd4c8bSHans Verkuil 	.prepare_streaming = v4l_vb2q_enable_media_source,
7505439b1aSShuah Khan 	.start_streaming = au0828_start_analog_streaming,
7605439b1aSShuah Khan 	.stop_streaming  = au0828_stop_vbi_streaming,
7705439b1aSShuah Khan 	.wait_prepare    = vb2_ops_wait_prepare,
7805439b1aSShuah Khan 	.wait_finish     = vb2_ops_wait_finish,
790c0d06caSMauro Carvalho Chehab };
80