linux/drivers/media/usb/au0828/au0828-vbi.c
<<
>>
Prefs
   1/*
   2   au0828-vbi.c - VBI driver for au0828
   3
   4   Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
   5
   6   This work was sponsored by GetWellNetwork Inc.
   7
   8   This program is free software; you can redistribute it and/or modify
   9   it under the terms of the GNU General Public License as published by
  10   the Free Software Foundation; either version 2 of the License, or
  11   (at your option) any later version.
  12
  13   This program is distributed in the hope that it will be useful,
  14   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16   GNU General Public License for more details.
  17
  18   You should have received a copy of the GNU General Public License
  19   along with this program; if not, write to the Free Software
  20   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21   02110-1301, USA.
  22 */
  23
  24#include "au0828.h"
  25
  26#include <linux/kernel.h>
  27#include <linux/module.h>
  28#include <linux/init.h>
  29#include <linux/slab.h>
  30
  31/* ------------------------------------------------------------------ */
  32
  33static int vbi_queue_setup(struct vb2_queue *vq,
  34                           unsigned int *nbuffers, unsigned int *nplanes,
  35                           unsigned int sizes[], struct device *alloc_devs[])
  36{
  37        struct au0828_dev *dev = vb2_get_drv_priv(vq);
  38        unsigned long size = dev->vbi_width * dev->vbi_height * 2;
  39
  40        if (*nplanes)
  41                return sizes[0] < size ? -EINVAL : 0;
  42        *nplanes = 1;
  43        sizes[0] = size;
  44        return 0;
  45}
  46
  47static int vbi_buffer_prepare(struct vb2_buffer *vb)
  48{
  49        struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
  50        unsigned long size;
  51
  52        size = dev->vbi_width * dev->vbi_height * 2;
  53
  54        if (vb2_plane_size(vb, 0) < size) {
  55                pr_err("%s data will not fit into plane (%lu < %lu)\n",
  56                        __func__, vb2_plane_size(vb, 0), size);
  57                return -EINVAL;
  58        }
  59        vb2_set_plane_payload(vb, 0, size);
  60
  61        return 0;
  62}
  63
  64static void
  65vbi_buffer_queue(struct vb2_buffer *vb)
  66{
  67        struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
  68        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
  69        struct au0828_buffer *buf =
  70                        container_of(vbuf, struct au0828_buffer, vb);
  71        struct au0828_dmaqueue *vbiq = &dev->vbiq;
  72        unsigned long flags = 0;
  73
  74        buf->mem = vb2_plane_vaddr(vb, 0);
  75        buf->length = vb2_plane_size(vb, 0);
  76
  77        spin_lock_irqsave(&dev->slock, flags);
  78        list_add_tail(&buf->list, &vbiq->active);
  79        spin_unlock_irqrestore(&dev->slock, flags);
  80}
  81
  82struct vb2_ops au0828_vbi_qops = {
  83        .queue_setup     = vbi_queue_setup,
  84        .buf_prepare     = vbi_buffer_prepare,
  85        .buf_queue       = vbi_buffer_queue,
  86        .start_streaming = au0828_start_analog_streaming,
  87        .stop_streaming  = au0828_stop_vbi_streaming,
  88        .wait_prepare    = vb2_ops_wait_prepare,
  89        .wait_finish     = vb2_ops_wait_finish,
  90};
  91