1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 au0828-vbi.c - VBI driver for au0828 4 5 Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com> 6 7 This work was sponsored by GetWellNetwork Inc. 8 9 */ 10 11 #include "au0828.h" 12 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/slab.h> 17 18 /* ------------------------------------------------------------------ */ 19 20 static int vbi_queue_setup(struct vb2_queue *vq, 21 unsigned int *nbuffers, unsigned int *nplanes, 22 unsigned int sizes[], struct device *alloc_devs[]) 23 { 24 struct au0828_dev *dev = vb2_get_drv_priv(vq); 25 unsigned long size = dev->vbi_width * dev->vbi_height * 2; 26 27 if (*nplanes) 28 return sizes[0] < size ? -EINVAL : 0; 29 *nplanes = 1; 30 sizes[0] = size; 31 return 0; 32 } 33 34 static int vbi_buffer_prepare(struct vb2_buffer *vb) 35 { 36 struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 37 unsigned long size; 38 39 size = dev->vbi_width * dev->vbi_height * 2; 40 41 if (vb2_plane_size(vb, 0) < size) { 42 pr_err("%s data will not fit into plane (%lu < %lu)\n", 43 __func__, vb2_plane_size(vb, 0), size); 44 return -EINVAL; 45 } 46 vb2_set_plane_payload(vb, 0, size); 47 48 return 0; 49 } 50 51 static void 52 vbi_buffer_queue(struct vb2_buffer *vb) 53 { 54 struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 55 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 56 struct au0828_buffer *buf = 57 container_of(vbuf, struct au0828_buffer, vb); 58 struct au0828_dmaqueue *vbiq = &dev->vbiq; 59 unsigned long flags = 0; 60 61 buf->mem = vb2_plane_vaddr(vb, 0); 62 buf->length = vb2_plane_size(vb, 0); 63 64 spin_lock_irqsave(&dev->slock, flags); 65 list_add_tail(&buf->list, &vbiq->active); 66 spin_unlock_irqrestore(&dev->slock, flags); 67 } 68 69 const struct vb2_ops au0828_vbi_qops = { 70 .queue_setup = vbi_queue_setup, 71 .buf_prepare = vbi_buffer_prepare, 72 .buf_queue = vbi_buffer_queue, 73 .start_streaming = au0828_start_analog_streaming, 74 .stop_streaming = au0828_stop_vbi_streaming, 75 .wait_prepare = vb2_ops_wait_prepare, 76 .wait_finish = vb2_ops_wait_finish, 77 }; 78