0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "au0828.h"
0012
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/init.h>
0016 #include <linux/slab.h>
0017
0018
0019
0020 static int vbi_queue_setup(struct vb2_queue *vq,
0021 unsigned int *nbuffers, unsigned int *nplanes,
0022 unsigned int sizes[], struct device *alloc_devs[])
0023 {
0024 struct au0828_dev *dev = vb2_get_drv_priv(vq);
0025 unsigned long size = dev->vbi_width * dev->vbi_height * 2;
0026
0027 if (*nplanes)
0028 return sizes[0] < size ? -EINVAL : 0;
0029 *nplanes = 1;
0030 sizes[0] = size;
0031 return 0;
0032 }
0033
0034 static int vbi_buffer_prepare(struct vb2_buffer *vb)
0035 {
0036 struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
0037 unsigned long size;
0038
0039 size = dev->vbi_width * dev->vbi_height * 2;
0040
0041 if (vb2_plane_size(vb, 0) < size) {
0042 pr_err("%s data will not fit into plane (%lu < %lu)\n",
0043 __func__, vb2_plane_size(vb, 0), size);
0044 return -EINVAL;
0045 }
0046 vb2_set_plane_payload(vb, 0, size);
0047
0048 return 0;
0049 }
0050
0051 static void
0052 vbi_buffer_queue(struct vb2_buffer *vb)
0053 {
0054 struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
0055 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0056 struct au0828_buffer *buf =
0057 container_of(vbuf, struct au0828_buffer, vb);
0058 struct au0828_dmaqueue *vbiq = &dev->vbiq;
0059 unsigned long flags = 0;
0060
0061 buf->mem = vb2_plane_vaddr(vb, 0);
0062 buf->length = vb2_plane_size(vb, 0);
0063
0064 spin_lock_irqsave(&dev->slock, flags);
0065 list_add_tail(&buf->list, &vbiq->active);
0066 spin_unlock_irqrestore(&dev->slock, flags);
0067 }
0068
0069 const struct vb2_ops au0828_vbi_qops = {
0070 .queue_setup = vbi_queue_setup,
0071 .buf_prepare = vbi_buffer_prepare,
0072 .buf_queue = vbi_buffer_queue,
0073 .start_streaming = au0828_start_analog_streaming,
0074 .stop_streaming = au0828_stop_vbi_streaming,
0075 .wait_prepare = vb2_ops_wait_prepare,
0076 .wait_finish = vb2_ops_wait_finish,
0077 };