/*
* Driver for the Conexant CX25821 PCIe bridge
*
* Copyright (C) 2009 Conexant Systems Inc.
* Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
* Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
* Parts adapted/taken from Eduardo Moscoso Rubino
* Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include "cx25821-video.h"
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
MODULE_LICENSE("GPL");
static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "video device numbers");
static unsigned int video_debug = VIDEO_DEBUG;
module_param(video_debug, int, 0644);
MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
static unsigned int irq_debug;
module_param(irq_debug, int, 0644);
MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
static unsigned int vid_limit = 16;
module_param(vid_limit, int, 0644);
MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
#define FORMAT_FLAGS_PACKED 0x01
static const struct cx25821_fmt formats[] = {
{
.name = "4:1:1, packed, Y41P",
.fourcc = V4L2_PIX_FMT_Y41P,
.depth = 12,
.flags = FORMAT_FLAGS_PACKED,
}, {
.name = "4:2:2, packed, YUYV",
.fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16,
.flags = FORMAT_FLAGS_PACKED,
},
};
static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(formats); i++)
if (formats[i].fourcc == fourcc)
return formats + i;
return NULL;
}
void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
u32 count)
{
struct cx25821_buffer *buf;
int bc;
for (bc = 0;; bc++) {
if (list_empty(&q->active)) {
dprintk(1, "bc=%d (=0: active empty)\n", bc);
break;
}
buf = list_entry(q->active.next, struct cx25821_buffer,
vb.queue);
/* count comes from the hw and it is 16bit wide --
* this trick handles wrap-arounds correctly for
* up to 32767 buffers in flight... */
if ((s16) (count - buf->count) < 0)
break;
v4l2_get_timestamp(&buf->vb.ts);
buf->vb.state = VIDEOBUF_DONE;
list_del(&buf->vb.queue);
wake_up(&buf->vb.done);
}
if (list_empty(&q->active))
del_timer(&q->timeout);
else
mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
if (bc != 1)
pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);
}
int cx25821_start_video_dma(struct cx25821_dev *dev,
struct cx25821_dmaqueue *q,
struct cx25821_buffer *buf,
const struct sram_channel *channel)
{
int tmp = 0;