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 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 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 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