Path: blob/master/drivers/media/video/cx231xx/cx231xx-video.c
17995 views
/*1cx231xx-video.c - driver for Conexant Cx23100/101/1022USB video capture devices34Copyright (C) 2008 <srinivasa.deevi at conexant dot com>5Based on em28xx driver6Based on cx23885 driver7Based on cx88 driver89This program is free software; you can redistribute it and/or modify10it under the terms of the GNU General Public License as published by11the Free Software Foundation; either version 2 of the License, or12(at your option) any later version.1314This program is distributed in the hope that it will be useful,15but WITHOUT ANY WARRANTY; without even the implied warranty of16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the17GNU General Public License for more details.1819You should have received a copy of the GNU General Public License20along with this program; if not, write to the Free Software21Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.22*/2324#include <linux/init.h>25#include <linux/list.h>26#include <linux/module.h>27#include <linux/kernel.h>28#include <linux/bitmap.h>29#include <linux/usb.h>30#include <linux/i2c.h>31#include <linux/version.h>32#include <linux/mm.h>33#include <linux/mutex.h>34#include <linux/slab.h>3536#include <media/v4l2-common.h>37#include <media/v4l2-ioctl.h>38#include <media/v4l2-chip-ident.h>39#include <media/msp3400.h>40#include <media/tuner.h>4142#include "dvb_frontend.h"4344#include "cx231xx.h"45#include "cx231xx-vbi.h"4647#define CX231XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)4849#define DRIVER_AUTHOR "Srinivasa Deevi <[email protected]>"50#define DRIVER_DESC "Conexant cx231xx based USB video device driver"5152#define cx231xx_videodbg(fmt, arg...) do {\53if (video_debug) \54printk(KERN_INFO "%s %s :"fmt, \55dev->name, __func__ , ##arg); } while (0)5657static unsigned int isoc_debug;58module_param(isoc_debug, int, 0644);59MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");6061#define cx231xx_isocdbg(fmt, arg...) \62do {\63if (isoc_debug) { \64printk(KERN_INFO "%s %s :"fmt, \65dev->name, __func__ , ##arg); \66} \67} while (0)6869MODULE_AUTHOR(DRIVER_AUTHOR);70MODULE_DESCRIPTION(DRIVER_DESC);71MODULE_LICENSE("GPL");7273static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };74static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };75static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };76static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };7778module_param_array(card, int, NULL, 0444);79module_param_array(video_nr, int, NULL, 0444);80module_param_array(vbi_nr, int, NULL, 0444);81module_param_array(radio_nr, int, NULL, 0444);8283MODULE_PARM_DESC(card, "card type");84MODULE_PARM_DESC(video_nr, "video device numbers");85MODULE_PARM_DESC(vbi_nr, "vbi device numbers");86MODULE_PARM_DESC(radio_nr, "radio device numbers");8788static unsigned int video_debug;89module_param(video_debug, int, 0644);90MODULE_PARM_DESC(video_debug, "enable debug messages [video]");9192/* supported video standards */93static struct cx231xx_fmt format[] = {94{95.name = "16bpp YUY2, 4:2:2, packed",96.fourcc = V4L2_PIX_FMT_YUYV,97.depth = 16,98.reg = 0,99},100};101102/* supported controls */103/* Common to all boards */104105/* ------------------------------------------------------------------- */106107static const struct v4l2_queryctrl no_ctl = {108.name = "42",109.flags = V4L2_CTRL_FLAG_DISABLED,110};111112static struct cx231xx_ctrl cx231xx_ctls[] = {113/* --- video --- */114{115.v = {116.id = V4L2_CID_BRIGHTNESS,117.name = "Brightness",118.minimum = 0x00,119.maximum = 0xff,120.step = 1,121.default_value = 0x7f,122.type = V4L2_CTRL_TYPE_INTEGER,123},124.off = 128,125.reg = LUMA_CTRL,126.mask = 0x00ff,127.shift = 0,128}, {129.v = {130.id = V4L2_CID_CONTRAST,131.name = "Contrast",132.minimum = 0,133.maximum = 0xff,134.step = 1,135.default_value = 0x3f,136.type = V4L2_CTRL_TYPE_INTEGER,137},138.off = 0,139.reg = LUMA_CTRL,140.mask = 0xff00,141.shift = 8,142}, {143.v = {144.id = V4L2_CID_HUE,145.name = "Hue",146.minimum = 0,147.maximum = 0xff,148.step = 1,149.default_value = 0x7f,150.type = V4L2_CTRL_TYPE_INTEGER,151},152.off = 128,153.reg = CHROMA_CTRL,154.mask = 0xff0000,155.shift = 16,156}, {157/* strictly, this only describes only U saturation.158* V saturation is handled specially through code.159*/160.v = {161.id = V4L2_CID_SATURATION,162.name = "Saturation",163.minimum = 0,164.maximum = 0xff,165.step = 1,166.default_value = 0x7f,167.type = V4L2_CTRL_TYPE_INTEGER,168},169.off = 0,170.reg = CHROMA_CTRL,171.mask = 0x00ff,172.shift = 0,173}, {174/* --- audio --- */175.v = {176.id = V4L2_CID_AUDIO_MUTE,177.name = "Mute",178.minimum = 0,179.maximum = 1,180.default_value = 1,181.type = V4L2_CTRL_TYPE_BOOLEAN,182},183.reg = PATH1_CTL1,184.mask = (0x1f << 24),185.shift = 24,186}, {187.v = {188.id = V4L2_CID_AUDIO_VOLUME,189.name = "Volume",190.minimum = 0,191.maximum = 0x3f,192.step = 1,193.default_value = 0x3f,194.type = V4L2_CTRL_TYPE_INTEGER,195},196.reg = PATH1_VOL_CTL,197.mask = 0xff,198.shift = 0,199}200};201static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls);202203static const u32 cx231xx_user_ctrls[] = {204V4L2_CID_USER_CLASS,205V4L2_CID_BRIGHTNESS,206V4L2_CID_CONTRAST,207V4L2_CID_SATURATION,208V4L2_CID_HUE,209V4L2_CID_AUDIO_VOLUME,210#if 0211V4L2_CID_AUDIO_BALANCE,212#endif213V4L2_CID_AUDIO_MUTE,2140215};216217static const u32 *ctrl_classes[] = {218cx231xx_user_ctrls,219NULL220};221222/* ------------------------------------------------------------------223Video buffer and parser functions224------------------------------------------------------------------*/225226/*227* Announces that a buffer were filled and request the next228*/229static inline void buffer_filled(struct cx231xx *dev,230struct cx231xx_dmaqueue *dma_q,231struct cx231xx_buffer *buf)232{233/* Advice that buffer was filled */234cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);235buf->vb.state = VIDEOBUF_DONE;236buf->vb.field_count++;237do_gettimeofday(&buf->vb.ts);238239if (dev->USE_ISO)240dev->video_mode.isoc_ctl.buf = NULL;241else242dev->video_mode.bulk_ctl.buf = NULL;243244list_del(&buf->vb.queue);245wake_up(&buf->vb.done);246}247248static inline void print_err_status(struct cx231xx *dev, int packet, int status)249{250char *errmsg = "Unknown";251252switch (status) {253case -ENOENT:254errmsg = "unlinked synchronuously";255break;256case -ECONNRESET:257errmsg = "unlinked asynchronuously";258break;259case -ENOSR:260errmsg = "Buffer error (overrun)";261break;262case -EPIPE:263errmsg = "Stalled (device not responding)";264break;265case -EOVERFLOW:266errmsg = "Babble (bad cable?)";267break;268case -EPROTO:269errmsg = "Bit-stuff error (bad cable?)";270break;271case -EILSEQ:272errmsg = "CRC/Timeout (could be anything)";273break;274case -ETIME:275errmsg = "Device does not respond";276break;277}278if (packet < 0) {279cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg);280} else {281cx231xx_isocdbg("URB packet %d, status %d [%s].\n",282packet, status, errmsg);283}284}285286/*287* video-buf generic routine to get the next available buffer288*/289static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,290struct cx231xx_buffer **buf)291{292struct cx231xx_video_mode *vmode =293container_of(dma_q, struct cx231xx_video_mode, vidq);294struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);295296char *outp;297298if (list_empty(&dma_q->active)) {299cx231xx_isocdbg("No active queue to serve\n");300if (dev->USE_ISO)301dev->video_mode.isoc_ctl.buf = NULL;302else303dev->video_mode.bulk_ctl.buf = NULL;304*buf = NULL;305return;306}307308/* Get the next buffer */309*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);310311/* Cleans up buffer - Useful for testing for frame/URB loss */312outp = videobuf_to_vmalloc(&(*buf)->vb);313memset(outp, 0, (*buf)->vb.size);314315if (dev->USE_ISO)316dev->video_mode.isoc_ctl.buf = *buf;317else318dev->video_mode.bulk_ctl.buf = *buf;319320return;321}322323/*324* Controls the isoc copy of each urb packet325*/326static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)327{328struct cx231xx_buffer *buf;329struct cx231xx_dmaqueue *dma_q = urb->context;330unsigned char *outp = NULL;331int i, rc = 1;332unsigned char *p_buffer;333u32 bytes_parsed = 0, buffer_size = 0;334u8 sav_eav = 0;335336if (!dev)337return 0;338339if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))340return 0;341342if (urb->status < 0) {343print_err_status(dev, -1, urb->status);344if (urb->status == -ENOENT)345return 0;346}347348buf = dev->video_mode.isoc_ctl.buf;349if (buf != NULL)350outp = videobuf_to_vmalloc(&buf->vb);351352for (i = 0; i < urb->number_of_packets; i++) {353int status = urb->iso_frame_desc[i].status;354355if (status < 0) {356print_err_status(dev, i, status);357if (urb->iso_frame_desc[i].status != -EPROTO)358continue;359}360361if (urb->iso_frame_desc[i].actual_length <= 0) {362/* cx231xx_isocdbg("packet %d is empty",i); - spammy */363continue;364}365if (urb->iso_frame_desc[i].actual_length >366dev->video_mode.max_pkt_size) {367cx231xx_isocdbg("packet bigger than packet size");368continue;369}370371/* get buffer pointer and length */372p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;373buffer_size = urb->iso_frame_desc[i].actual_length;374bytes_parsed = 0;375376if (dma_q->is_partial_line) {377/* Handle the case of a partial line */378sav_eav = dma_q->last_sav;379} else {380/* Check for a SAV/EAV overlapping381the buffer boundary */382sav_eav =383cx231xx_find_boundary_SAV_EAV(p_buffer,384dma_q->partial_buf,385&bytes_parsed);386}387388sav_eav &= 0xF0;389/* Get the first line if we have some portion of an SAV/EAV from390the last buffer or a partial line */391if (sav_eav) {392bytes_parsed += cx231xx_get_video_line(dev, dma_q,393sav_eav, /* SAV/EAV */394p_buffer + bytes_parsed, /* p_buffer */395buffer_size - bytes_parsed);/* buf size */396}397398/* Now parse data that is completely in this buffer */399/* dma_q->is_partial_line = 0; */400401while (bytes_parsed < buffer_size) {402u32 bytes_used = 0;403404sav_eav = cx231xx_find_next_SAV_EAV(405p_buffer + bytes_parsed, /* p_buffer */406buffer_size - bytes_parsed, /* buf size */407&bytes_used);/* bytes used to get SAV/EAV */408409bytes_parsed += bytes_used;410411sav_eav &= 0xF0;412if (sav_eav && (bytes_parsed < buffer_size)) {413bytes_parsed += cx231xx_get_video_line(dev,414dma_q, sav_eav, /* SAV/EAV */415p_buffer + bytes_parsed,/* p_buffer */416buffer_size - bytes_parsed);/*buf size*/417}418}419420/* Save the last four bytes of the buffer so we can check the421buffer boundary condition next time */422memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);423bytes_parsed = 0;424425}426return rc;427}428429static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)430{431struct cx231xx_buffer *buf;432struct cx231xx_dmaqueue *dma_q = urb->context;433unsigned char *outp = NULL;434int rc = 1;435unsigned char *p_buffer;436u32 bytes_parsed = 0, buffer_size = 0;437u8 sav_eav = 0;438439if (!dev)440return 0;441442if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))443return 0;444445if (urb->status < 0) {446print_err_status(dev, -1, urb->status);447if (urb->status == -ENOENT)448return 0;449}450451buf = dev->video_mode.bulk_ctl.buf;452if (buf != NULL)453outp = videobuf_to_vmalloc(&buf->vb);454455if (1) {456457/* get buffer pointer and length */458p_buffer = urb->transfer_buffer;459buffer_size = urb->actual_length;460bytes_parsed = 0;461462if (dma_q->is_partial_line) {463/* Handle the case of a partial line */464sav_eav = dma_q->last_sav;465} else {466/* Check for a SAV/EAV overlapping467the buffer boundary */468sav_eav =469cx231xx_find_boundary_SAV_EAV(p_buffer,470dma_q->partial_buf,471&bytes_parsed);472}473474sav_eav &= 0xF0;475/* Get the first line if we have some portion of an SAV/EAV from476the last buffer or a partial line */477if (sav_eav) {478bytes_parsed += cx231xx_get_video_line(dev, dma_q,479sav_eav, /* SAV/EAV */480p_buffer + bytes_parsed, /* p_buffer */481buffer_size - bytes_parsed);/* buf size */482}483484/* Now parse data that is completely in this buffer */485/* dma_q->is_partial_line = 0; */486487while (bytes_parsed < buffer_size) {488u32 bytes_used = 0;489490sav_eav = cx231xx_find_next_SAV_EAV(491p_buffer + bytes_parsed, /* p_buffer */492buffer_size - bytes_parsed, /* buf size */493&bytes_used);/* bytes used to get SAV/EAV */494495bytes_parsed += bytes_used;496497sav_eav &= 0xF0;498if (sav_eav && (bytes_parsed < buffer_size)) {499bytes_parsed += cx231xx_get_video_line(dev,500dma_q, sav_eav, /* SAV/EAV */501p_buffer + bytes_parsed,/* p_buffer */502buffer_size - bytes_parsed);/*buf size*/503}504}505506/* Save the last four bytes of the buffer so we can check the507buffer boundary condition next time */508memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);509bytes_parsed = 0;510511}512return rc;513}514515516u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,517u32 *p_bytes_used)518{519u32 bytes_used;520u8 boundary_bytes[8];521u8 sav_eav = 0;522523*p_bytes_used = 0;524525/* Create an array of the last 4 bytes of the last buffer and the first5264 bytes of the current buffer. */527528memcpy(boundary_bytes, partial_buf, 4);529memcpy(boundary_bytes + 4, p_buffer, 4);530531/* Check for the SAV/EAV in the boundary buffer */532sav_eav = cx231xx_find_next_SAV_EAV((u8 *)&boundary_bytes, 8,533&bytes_used);534535if (sav_eav) {536/* found a boundary SAV/EAV. Updates the bytes used to reflect537only those used in the new buffer */538*p_bytes_used = bytes_used - 4;539}540541return sav_eav;542}543544u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used)545{546u32 i;547u8 sav_eav = 0;548549/*550* Don't search if the buffer size is less than 4. It causes a page551* fault since buffer_size - 4 evaluates to a large number in that552* case.553*/554if (buffer_size < 4) {555*p_bytes_used = buffer_size;556return 0;557}558559for (i = 0; i < (buffer_size - 3); i++) {560561if ((p_buffer[i] == 0xFF) &&562(p_buffer[i + 1] == 0x00) && (p_buffer[i + 2] == 0x00)) {563564*p_bytes_used = i + 4;565sav_eav = p_buffer[i + 3];566return sav_eav;567}568}569570*p_bytes_used = buffer_size;571return 0;572}573574u32 cx231xx_get_video_line(struct cx231xx *dev,575struct cx231xx_dmaqueue *dma_q, u8 sav_eav,576u8 *p_buffer, u32 buffer_size)577{578u32 bytes_copied = 0;579int current_field = -1;580581switch (sav_eav) {582case SAV_ACTIVE_VIDEO_FIELD1:583/* looking for skipped line which occurred in PAL 720x480 mode.584In this case, there will be no active data contained585between the SAV and EAV */586if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&587(p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&588((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||589(p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||590(p_buffer[3] == EAV_VBLANK_FIELD1) ||591(p_buffer[3] == EAV_VBLANK_FIELD2)))592return bytes_copied;593current_field = 1;594break;595596case SAV_ACTIVE_VIDEO_FIELD2:597/* looking for skipped line which occurred in PAL 720x480 mode.598In this case, there will be no active data contained between599the SAV and EAV */600if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&601(p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&602((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||603(p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||604(p_buffer[3] == EAV_VBLANK_FIELD1) ||605(p_buffer[3] == EAV_VBLANK_FIELD2)))606return bytes_copied;607current_field = 2;608break;609}610611dma_q->last_sav = sav_eav;612613bytes_copied = cx231xx_copy_video_line(dev, dma_q, p_buffer,614buffer_size, current_field);615616return bytes_copied;617}618619u32 cx231xx_copy_video_line(struct cx231xx *dev,620struct cx231xx_dmaqueue *dma_q, u8 *p_line,621u32 length, int field_number)622{623u32 bytes_to_copy;624struct cx231xx_buffer *buf;625u32 _line_size = dev->width * 2;626627if (dma_q->current_field != field_number)628cx231xx_reset_video_buffer(dev, dma_q);629630/* get the buffer pointer */631if (dev->USE_ISO)632buf = dev->video_mode.isoc_ctl.buf;633else634buf = dev->video_mode.bulk_ctl.buf;635636/* Remember the field number for next time */637dma_q->current_field = field_number;638639bytes_to_copy = dma_q->bytes_left_in_line;640if (bytes_to_copy > length)641bytes_to_copy = length;642643if (dma_q->lines_completed >= dma_q->lines_per_field) {644dma_q->bytes_left_in_line -= bytes_to_copy;645dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ?6460 : 1;647return 0;648}649650dma_q->is_partial_line = 1;651652/* If we don't have a buffer, just return the number of bytes we would653have copied if we had a buffer. */654if (!buf) {655dma_q->bytes_left_in_line -= bytes_to_copy;656dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0)657? 0 : 1;658return bytes_to_copy;659}660661/* copy the data to video buffer */662cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy);663664dma_q->pos += bytes_to_copy;665dma_q->bytes_left_in_line -= bytes_to_copy;666667if (dma_q->bytes_left_in_line == 0) {668dma_q->bytes_left_in_line = _line_size;669dma_q->lines_completed++;670dma_q->is_partial_line = 0;671672if (cx231xx_is_buffer_done(dev, dma_q) && buf) {673buffer_filled(dev, dma_q, buf);674675dma_q->pos = 0;676buf = NULL;677dma_q->lines_completed = 0;678}679}680681return bytes_to_copy;682}683684void cx231xx_reset_video_buffer(struct cx231xx *dev,685struct cx231xx_dmaqueue *dma_q)686{687struct cx231xx_buffer *buf;688689/* handle the switch from field 1 to field 2 */690if (dma_q->current_field == 1) {691if (dma_q->lines_completed >= dma_q->lines_per_field)692dma_q->field1_done = 1;693else694dma_q->field1_done = 0;695}696697if (dev->USE_ISO)698buf = dev->video_mode.isoc_ctl.buf;699else700buf = dev->video_mode.bulk_ctl.buf;701702if (buf == NULL) {703u8 *outp = NULL;704/* first try to get the buffer */705get_next_buf(dma_q, &buf);706707if (buf)708outp = videobuf_to_vmalloc(&buf->vb);709710dma_q->pos = 0;711dma_q->field1_done = 0;712dma_q->current_field = -1;713}714715/* reset the counters */716dma_q->bytes_left_in_line = dev->width << 1;717dma_q->lines_completed = 0;718}719720int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,721u8 *p_buffer, u32 bytes_to_copy)722{723u8 *p_out_buffer = NULL;724u32 current_line_bytes_copied = 0;725struct cx231xx_buffer *buf;726u32 _line_size = dev->width << 1;727void *startwrite;728int offset, lencopy;729730if (dev->USE_ISO)731buf = dev->video_mode.isoc_ctl.buf;732else733buf = dev->video_mode.bulk_ctl.buf;734735if (buf == NULL)736return -1;737738p_out_buffer = videobuf_to_vmalloc(&buf->vb);739740current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line;741742/* Offset field 2 one line from the top of the buffer */743offset = (dma_q->current_field == 1) ? 0 : _line_size;744745/* Offset for field 2 */746startwrite = p_out_buffer + offset;747748/* lines already completed in the current field */749startwrite += (dma_q->lines_completed * _line_size * 2);750751/* bytes already completed in the current line */752startwrite += current_line_bytes_copied;753754lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?755bytes_to_copy : dma_q->bytes_left_in_line;756757if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + buf->vb.size))758return 0;759760/* The below copies the UYVY data straight into video buffer */761cx231xx_swab((u16 *) p_buffer, (u16 *) startwrite, (u16) lencopy);762763return 0;764}765766void cx231xx_swab(u16 *from, u16 *to, u16 len)767{768u16 i;769770if (len <= 0)771return;772773for (i = 0; i < len / 2; i++)774to[i] = (from[i] << 8) | (from[i] >> 8);775}776777u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q)778{779u8 buffer_complete = 0;780781/* Dual field stream */782buffer_complete = ((dma_q->current_field == 2) &&783(dma_q->lines_completed >= dma_q->lines_per_field) &&784dma_q->field1_done);785786return buffer_complete;787}788789/* ------------------------------------------------------------------790Videobuf operations791------------------------------------------------------------------*/792793static int794buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)795{796struct cx231xx_fh *fh = vq->priv_data;797struct cx231xx *dev = fh->dev;798799*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3;800if (0 == *count)801*count = CX231XX_DEF_BUF;802803if (*count < CX231XX_MIN_BUF)804*count = CX231XX_MIN_BUF;805806return 0;807}808809/* This is called *without* dev->slock held; please keep it that way */810static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)811{812struct cx231xx_fh *fh = vq->priv_data;813struct cx231xx *dev = fh->dev;814unsigned long flags = 0;815816if (in_interrupt())817BUG();818819/* We used to wait for the buffer to finish here, but this didn't work820because, as we were keeping the state as VIDEOBUF_QUEUED,821videobuf_queue_cancel marked it as finished for us.822(Also, it could wedge forever if the hardware was misconfigured.)823824This should be safe; by the time we get here, the buffer isn't825queued anymore. If we ever start marking the buffers as826VIDEOBUF_ACTIVE, it won't be, though.827*/828spin_lock_irqsave(&dev->video_mode.slock, flags);829if (dev->USE_ISO) {830if (dev->video_mode.isoc_ctl.buf == buf)831dev->video_mode.isoc_ctl.buf = NULL;832} else {833if (dev->video_mode.bulk_ctl.buf == buf)834dev->video_mode.bulk_ctl.buf = NULL;835}836spin_unlock_irqrestore(&dev->video_mode.slock, flags);837838videobuf_vmalloc_free(&buf->vb);839buf->vb.state = VIDEOBUF_NEEDS_INIT;840}841842static int843buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,844enum v4l2_field field)845{846struct cx231xx_fh *fh = vq->priv_data;847struct cx231xx_buffer *buf =848container_of(vb, struct cx231xx_buffer, vb);849struct cx231xx *dev = fh->dev;850int rc = 0, urb_init = 0;851852/* The only currently supported format is 16 bits/pixel */853buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth854+ 7) >> 3;855if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)856return -EINVAL;857858buf->vb.width = dev->width;859buf->vb.height = dev->height;860buf->vb.field = field;861862if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {863rc = videobuf_iolock(vq, &buf->vb, NULL);864if (rc < 0)865goto fail;866}867868if (dev->USE_ISO) {869if (!dev->video_mode.isoc_ctl.num_bufs)870urb_init = 1;871} else {872if (!dev->video_mode.bulk_ctl.num_bufs)873urb_init = 1;874}875/*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n",876urb_init, dev->video_mode.max_pkt_size);*/877if (urb_init) {878dev->mode_tv = 0;879if (dev->USE_ISO)880rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,881CX231XX_NUM_BUFS,882dev->video_mode.max_pkt_size,883cx231xx_isoc_copy);884else885rc = cx231xx_init_bulk(dev, CX231XX_NUM_PACKETS,886CX231XX_NUM_BUFS,887dev->video_mode.max_pkt_size,888cx231xx_bulk_copy);889if (rc < 0)890goto fail;891}892893buf->vb.state = VIDEOBUF_PREPARED;894return 0;895896fail:897free_buffer(vq, buf);898return rc;899}900901static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)902{903struct cx231xx_buffer *buf =904container_of(vb, struct cx231xx_buffer, vb);905struct cx231xx_fh *fh = vq->priv_data;906struct cx231xx *dev = fh->dev;907struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;908909buf->vb.state = VIDEOBUF_QUEUED;910list_add_tail(&buf->vb.queue, &vidq->active);911912}913914static void buffer_release(struct videobuf_queue *vq,915struct videobuf_buffer *vb)916{917struct cx231xx_buffer *buf =918container_of(vb, struct cx231xx_buffer, vb);919struct cx231xx_fh *fh = vq->priv_data;920struct cx231xx *dev = (struct cx231xx *)fh->dev;921922cx231xx_isocdbg("cx231xx: called buffer_release\n");923924free_buffer(vq, buf);925}926927static struct videobuf_queue_ops cx231xx_video_qops = {928.buf_setup = buffer_setup,929.buf_prepare = buffer_prepare,930.buf_queue = buffer_queue,931.buf_release = buffer_release,932};933934/********************* v4l2 interface **************************************/935936void video_mux(struct cx231xx *dev, int index)937{938dev->video_input = index;939dev->ctl_ainput = INPUT(index)->amux;940941cx231xx_set_video_input_mux(dev, index);942943cx25840_call(dev, video, s_routing, INPUT(index)->vmux, 0, 0);944945cx231xx_set_audio_input(dev, dev->ctl_ainput);946947cx231xx_info("video_mux : %d\n", index);948949/* do mode control overrides if required */950cx231xx_do_mode_ctrl_overrides(dev);951}952953/* Usage lock check functions */954static int res_get(struct cx231xx_fh *fh)955{956struct cx231xx *dev = fh->dev;957int rc = 0;958959/* This instance already has stream_on */960if (fh->stream_on)961return rc;962963if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {964if (dev->stream_on)965return -EBUSY;966dev->stream_on = 1;967} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {968if (dev->vbi_stream_on)969return -EBUSY;970dev->vbi_stream_on = 1;971} else972return -EINVAL;973974fh->stream_on = 1;975976return rc;977}978979static int res_check(struct cx231xx_fh *fh)980{981return fh->stream_on;982}983984static void res_free(struct cx231xx_fh *fh)985{986struct cx231xx *dev = fh->dev;987988fh->stream_on = 0;989990if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)991dev->stream_on = 0;992if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)993dev->vbi_stream_on = 0;994}995996static int check_dev(struct cx231xx *dev)997{998if (dev->state & DEV_DISCONNECTED) {999cx231xx_errdev("v4l2 ioctl: device not present\n");1000return -ENODEV;1001}10021003if (dev->state & DEV_MISCONFIGURED) {1004cx231xx_errdev("v4l2 ioctl: device is misconfigured; "1005"close and open it again\n");1006return -EIO;1007}1008return 0;1009}10101011/* ------------------------------------------------------------------1012IOCTL vidioc handling1013------------------------------------------------------------------*/10141015static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,1016struct v4l2_format *f)1017{1018struct cx231xx_fh *fh = priv;1019struct cx231xx *dev = fh->dev;10201021f->fmt.pix.width = dev->width;1022f->fmt.pix.height = dev->height;1023f->fmt.pix.pixelformat = dev->format->fourcc;1024f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;1025f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;1026f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;10271028f->fmt.pix.field = V4L2_FIELD_INTERLACED;10291030return 0;1031}10321033static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc)1034{1035unsigned int i;10361037for (i = 0; i < ARRAY_SIZE(format); i++)1038if (format[i].fourcc == fourcc)1039return &format[i];10401041return NULL;1042}10431044static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,1045struct v4l2_format *f)1046{1047struct cx231xx_fh *fh = priv;1048struct cx231xx *dev = fh->dev;1049unsigned int width = f->fmt.pix.width;1050unsigned int height = f->fmt.pix.height;1051unsigned int maxw = norm_maxw(dev);1052unsigned int maxh = norm_maxh(dev);1053struct cx231xx_fmt *fmt;10541055fmt = format_by_fourcc(f->fmt.pix.pixelformat);1056if (!fmt) {1057cx231xx_videodbg("Fourcc format (%08x) invalid.\n",1058f->fmt.pix.pixelformat);1059return -EINVAL;1060}10611062/* width must even because of the YUYV format1063height must be even because of interlacing */1064v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);10651066f->fmt.pix.width = width;1067f->fmt.pix.height = height;1068f->fmt.pix.pixelformat = fmt->fourcc;1069f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;1070f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;1071f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;1072f->fmt.pix.field = V4L2_FIELD_INTERLACED;10731074return 0;1075}10761077static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,1078struct v4l2_format *f)1079{1080struct cx231xx_fh *fh = priv;1081struct cx231xx *dev = fh->dev;1082int rc;1083struct cx231xx_fmt *fmt;1084struct v4l2_mbus_framefmt mbus_fmt;10851086rc = check_dev(dev);1087if (rc < 0)1088return rc;10891090vidioc_try_fmt_vid_cap(file, priv, f);10911092fmt = format_by_fourcc(f->fmt.pix.pixelformat);1093if (!fmt)1094return -EINVAL;10951096if (videobuf_queue_is_busy(&fh->vb_vidq)) {1097cx231xx_errdev("%s queue busy\n", __func__);1098return -EBUSY;1099}11001101if (dev->stream_on && !fh->stream_on) {1102cx231xx_errdev("%s device in use by another fh\n", __func__);1103return -EBUSY;1104}11051106/* set new image size */1107dev->width = f->fmt.pix.width;1108dev->height = f->fmt.pix.height;1109dev->format = fmt;11101111v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);1112call_all(dev, video, s_mbus_fmt, &mbus_fmt);1113v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);11141115return rc;1116}11171118static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)1119{1120struct cx231xx_fh *fh = priv;1121struct cx231xx *dev = fh->dev;11221123*id = dev->norm;1124return 0;1125}11261127static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)1128{1129struct cx231xx_fh *fh = priv;1130struct cx231xx *dev = fh->dev;1131struct v4l2_mbus_framefmt mbus_fmt;1132struct v4l2_format f;1133int rc;11341135rc = check_dev(dev);1136if (rc < 0)1137return rc;11381139cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);11401141dev->norm = *norm;11421143/* Adjusts width/height, if needed */1144f.fmt.pix.width = dev->width;1145f.fmt.pix.height = dev->height;1146vidioc_try_fmt_vid_cap(file, priv, &f);11471148call_all(dev, core, s_std, dev->norm);11491150/* We need to reset basic properties in the decoder related to1151resolution (since a standard change effects things like the number1152of lines in VACT, etc) */1153v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED);1154call_all(dev, video, s_mbus_fmt, &mbus_fmt);1155v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt);11561157/* set new image size */1158dev->width = f.fmt.pix.width;1159dev->height = f.fmt.pix.height;11601161/* do mode control overrides */1162cx231xx_do_mode_ctrl_overrides(dev);11631164return 0;1165}11661167static const char *iname[] = {1168[CX231XX_VMUX_COMPOSITE1] = "Composite1",1169[CX231XX_VMUX_SVIDEO] = "S-Video",1170[CX231XX_VMUX_TELEVISION] = "Television",1171[CX231XX_VMUX_CABLE] = "Cable TV",1172[CX231XX_VMUX_DVB] = "DVB",1173[CX231XX_VMUX_DEBUG] = "for debug only",1174};11751176static int vidioc_enum_input(struct file *file, void *priv,1177struct v4l2_input *i)1178{1179struct cx231xx_fh *fh = priv;1180struct cx231xx *dev = fh->dev;1181unsigned int n;11821183n = i->index;1184if (n >= MAX_CX231XX_INPUT)1185return -EINVAL;1186if (0 == INPUT(n)->type)1187return -EINVAL;11881189i->index = n;1190i->type = V4L2_INPUT_TYPE_CAMERA;11911192strcpy(i->name, iname[INPUT(n)->type]);11931194if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||1195(CX231XX_VMUX_CABLE == INPUT(n)->type))1196i->type = V4L2_INPUT_TYPE_TUNER;11971198i->std = dev->vdev->tvnorms;11991200return 0;1201}12021203static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)1204{1205struct cx231xx_fh *fh = priv;1206struct cx231xx *dev = fh->dev;12071208*i = dev->video_input;12091210return 0;1211}12121213static int vidioc_s_input(struct file *file, void *priv, unsigned int i)1214{1215struct cx231xx_fh *fh = priv;1216struct cx231xx *dev = fh->dev;1217int rc;12181219dev->mode_tv = 0;1220rc = check_dev(dev);1221if (rc < 0)1222return rc;12231224if (i >= MAX_CX231XX_INPUT)1225return -EINVAL;1226if (0 == INPUT(i)->type)1227return -EINVAL;12281229video_mux(dev, i);12301231if (INPUT(i)->type == CX231XX_VMUX_TELEVISION ||1232INPUT(i)->type == CX231XX_VMUX_CABLE) {1233/* There's a tuner, so reset the standard and put it on the1234last known frequency (since it was probably powered down1235until now */1236call_all(dev, core, s_std, dev->norm);1237}12381239return 0;1240}12411242static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)1243{1244struct cx231xx_fh *fh = priv;1245struct cx231xx *dev = fh->dev;12461247switch (a->index) {1248case CX231XX_AMUX_VIDEO:1249strcpy(a->name, "Television");1250break;1251case CX231XX_AMUX_LINE_IN:1252strcpy(a->name, "Line In");1253break;1254default:1255return -EINVAL;1256}12571258a->index = dev->ctl_ainput;1259a->capability = V4L2_AUDCAP_STEREO;12601261return 0;1262}12631264static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)1265{1266struct cx231xx_fh *fh = priv;1267struct cx231xx *dev = fh->dev;1268int status = 0;12691270/* Doesn't allow manual routing */1271if (a->index != dev->ctl_ainput)1272return -EINVAL;12731274dev->ctl_ainput = INPUT(a->index)->amux;1275status = cx231xx_set_audio_input(dev, dev->ctl_ainput);12761277return status;1278}12791280static int vidioc_queryctrl(struct file *file, void *priv,1281struct v4l2_queryctrl *qc)1282{1283struct cx231xx_fh *fh = priv;1284struct cx231xx *dev = fh->dev;1285int id = qc->id;1286int i;1287int rc;12881289rc = check_dev(dev);1290if (rc < 0)1291return rc;12921293qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);1294if (unlikely(qc->id == 0))1295return -EINVAL;12961297memset(qc, 0, sizeof(*qc));12981299qc->id = id;13001301if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1)1302return -EINVAL;13031304for (i = 0; i < CX231XX_CTLS; i++)1305if (cx231xx_ctls[i].v.id == qc->id)1306break;13071308if (i == CX231XX_CTLS) {1309*qc = no_ctl;1310return 0;1311}1312*qc = cx231xx_ctls[i].v;13131314call_all(dev, core, queryctrl, qc);13151316if (qc->type)1317return 0;1318else1319return -EINVAL;1320}13211322static int vidioc_g_ctrl(struct file *file, void *priv,1323struct v4l2_control *ctrl)1324{1325struct cx231xx_fh *fh = priv;1326struct cx231xx *dev = fh->dev;1327int rc;13281329rc = check_dev(dev);1330if (rc < 0)1331return rc;13321333call_all(dev, core, g_ctrl, ctrl);1334return rc;1335}13361337static int vidioc_s_ctrl(struct file *file, void *priv,1338struct v4l2_control *ctrl)1339{1340struct cx231xx_fh *fh = priv;1341struct cx231xx *dev = fh->dev;1342int rc;13431344rc = check_dev(dev);1345if (rc < 0)1346return rc;13471348call_all(dev, core, s_ctrl, ctrl);1349return rc;1350}13511352static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)1353{1354struct cx231xx_fh *fh = priv;1355struct cx231xx *dev = fh->dev;1356int rc;13571358rc = check_dev(dev);1359if (rc < 0)1360return rc;13611362if (0 != t->index)1363return -EINVAL;13641365strcpy(t->name, "Tuner");13661367t->type = V4L2_TUNER_ANALOG_TV;1368t->capability = V4L2_TUNER_CAP_NORM;1369t->rangehigh = 0xffffffffUL;1370t->signal = 0xffff; /* LOCKED */13711372return 0;1373}13741375static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)1376{1377struct cx231xx_fh *fh = priv;1378struct cx231xx *dev = fh->dev;1379int rc;13801381rc = check_dev(dev);1382if (rc < 0)1383return rc;13841385if (0 != t->index)1386return -EINVAL;1387#if 01388call_all(dev, tuner, s_tuner, t);1389#endif1390return 0;1391}13921393static int vidioc_g_frequency(struct file *file, void *priv,1394struct v4l2_frequency *f)1395{1396struct cx231xx_fh *fh = priv;1397struct cx231xx *dev = fh->dev;13981399f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;1400f->frequency = dev->ctl_freq;14011402call_all(dev, tuner, g_frequency, f);14031404return 0;1405}14061407static int vidioc_s_frequency(struct file *file, void *priv,1408struct v4l2_frequency *f)1409{1410struct cx231xx_fh *fh = priv;1411struct cx231xx *dev = fh->dev;1412int rc;1413u32 if_frequency = 5400000;14141415cx231xx_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n",1416f->frequency, f->type);1417/*cx231xx_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/14181419rc = check_dev(dev);1420if (rc < 0)1421return rc;14221423if (0 != f->tuner)1424return -EINVAL;14251426if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))1427return -EINVAL;1428if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))1429return -EINVAL;14301431/* set pre channel change settings in DIF first */1432rc = cx231xx_tuner_pre_channel_change(dev);14331434dev->ctl_freq = f->frequency;1435call_all(dev, tuner, s_frequency, f);14361437/* set post channel change settings in DIF first */1438rc = cx231xx_tuner_post_channel_change(dev);14391440if (dev->tuner_type == TUNER_NXP_TDA18271) {1441if (dev->norm & (V4L2_STD_MN | V4L2_STD_NTSC_443))1442if_frequency = 5400000; /*5.4MHz */1443else if (dev->norm & V4L2_STD_B)1444if_frequency = 6000000; /*6.0MHz */1445else if (dev->norm & (V4L2_STD_PAL_DK | V4L2_STD_SECAM_DK))1446if_frequency = 6900000; /*6.9MHz */1447else if (dev->norm & V4L2_STD_GH)1448if_frequency = 7100000; /*7.1MHz */1449else if (dev->norm & V4L2_STD_PAL_I)1450if_frequency = 7250000; /*7.25MHz */1451else if (dev->norm & V4L2_STD_SECAM_L)1452if_frequency = 6900000; /*6.9MHz */1453else if (dev->norm & V4L2_STD_SECAM_LC)1454if_frequency = 1250000; /*1.25MHz */14551456cx231xx_info("if_frequency is set to %d\n", if_frequency);1457cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1);14581459update_HH_register_after_set_DIF(dev);1460}14611462cx231xx_info("Set New FREQUENCY to %d\n", f->frequency);14631464return rc;1465}14661467#ifdef CONFIG_VIDEO_ADV_DEBUG14681469/*1470-R, --list-registers=type=<host/i2cdrv/i2caddr>,1471chip=<chip>[,min=<addr>,max=<addr>]1472dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]1473-r, --set-register=type=<host/i2cdrv/i2caddr>,1474chip=<chip>,reg=<addr>,val=<val>1475set the register [VIDIOC_DBG_S_REGISTER]14761477if type == host, then <chip> is the hosts chip ID (default 0)1478if type == i2cdrv (default), then <chip> is the I2C driver name or ID1479if type == i2caddr, then <chip> is the 7-bit I2C address1480*/14811482static int vidioc_g_register(struct file *file, void *priv,1483struct v4l2_dbg_register *reg)1484{1485struct cx231xx_fh *fh = priv;1486struct cx231xx *dev = fh->dev;1487int ret = 0;1488u8 value[4] = { 0, 0, 0, 0 };1489u32 data = 0;14901491switch (reg->match.type) {1492case V4L2_CHIP_MATCH_HOST:1493switch (reg->match.addr) {1494case 0: /* Cx231xx - internal registers */1495ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,1496(u16)reg->reg, value, 4);1497reg->val = value[0] | value[1] << 8 |1498value[2] << 16 | value[3] << 24;1499break;1500case 1: /* AFE - read byte */1501ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,1502(u16)reg->reg, 2, &data, 1);1503reg->val = le32_to_cpu(data & 0xff);1504break;1505case 14: /* AFE - read dword */1506ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,1507(u16)reg->reg, 2, &data, 4);1508reg->val = le32_to_cpu(data);1509break;1510case 2: /* Video Block - read byte */1511ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,1512(u16)reg->reg, 2, &data, 1);1513reg->val = le32_to_cpu(data & 0xff);1514break;1515case 24: /* Video Block - read dword */1516ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,1517(u16)reg->reg, 2, &data, 4);1518reg->val = le32_to_cpu(data);1519break;1520case 3: /* I2S block - read byte */1521ret = cx231xx_read_i2c_data(dev,1522I2S_BLK_DEVICE_ADDRESS,1523(u16)reg->reg, 1,1524&data, 1);1525reg->val = le32_to_cpu(data & 0xff);1526break;1527case 34: /* I2S Block - read dword */1528ret =1529cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,1530(u16)reg->reg, 1, &data, 4);1531reg->val = le32_to_cpu(data);1532break;1533}1534return ret < 0 ? ret : 0;15351536case V4L2_CHIP_MATCH_I2C_DRIVER:1537call_all(dev, core, g_register, reg);1538return 0;1539case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/1540switch (reg->match.addr) {1541case 0: /* Cx231xx - internal registers */1542ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,1543(u16)reg->reg, value, 4);1544reg->val = value[0] | value[1] << 8 |1545value[2] << 16 | value[3] << 24;15461547break;1548case 0x600:/* AFE - read byte */1549ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS,1550(u16)reg->reg, 2,1551&data, 1 , 0);1552reg->val = le32_to_cpu(data & 0xff);1553break;15541555case 0x880:/* Video Block - read byte */1556if (reg->reg < 0x0b) {1557ret = cx231xx_read_i2c_master(dev,1558VID_BLK_I2C_ADDRESS,1559(u16)reg->reg, 2,1560&data, 1 , 0);1561reg->val = le32_to_cpu(data & 0xff);1562} else {1563ret = cx231xx_read_i2c_master(dev,1564VID_BLK_I2C_ADDRESS,1565(u16)reg->reg, 2,1566&data, 4 , 0);1567reg->val = le32_to_cpu(data);1568}1569break;1570case 0x980:1571ret = cx231xx_read_i2c_master(dev,1572I2S_BLK_DEVICE_ADDRESS,1573(u16)reg->reg, 1,1574&data, 1 , 0);1575reg->val = le32_to_cpu(data & 0xff);1576break;1577case 0x400:1578ret =1579cx231xx_read_i2c_master(dev, 0x40,1580(u16)reg->reg, 1,1581&data, 1 , 0);1582reg->val = le32_to_cpu(data & 0xff);1583break;1584case 0xc01:1585ret =1586cx231xx_read_i2c_master(dev, 0xc0,1587(u16)reg->reg, 2,1588&data, 38, 1);1589reg->val = le32_to_cpu(data);1590break;1591case 0x022:1592ret =1593cx231xx_read_i2c_master(dev, 0x02,1594(u16)reg->reg, 1,1595&data, 1, 2);1596reg->val = le32_to_cpu(data & 0xff);1597break;1598case 0x322:1599ret = cx231xx_read_i2c_master(dev,16000x32,1601(u16)reg->reg, 1,1602&data, 4 , 2);1603reg->val = le32_to_cpu(data);1604break;1605case 0x342:1606ret = cx231xx_read_i2c_master(dev,16070x34,1608(u16)reg->reg, 1,1609&data, 4 , 2);1610reg->val = le32_to_cpu(data);1611break;16121613default:1614cx231xx_info("no match device address!!\n");1615break;1616}1617return ret < 0 ? ret : 0;1618/*return -EINVAL;*/1619default:1620if (!v4l2_chip_match_host(®->match))1621return -EINVAL;1622}16231624call_all(dev, core, g_register, reg);16251626return ret;1627}16281629static int vidioc_s_register(struct file *file, void *priv,1630struct v4l2_dbg_register *reg)1631{1632struct cx231xx_fh *fh = priv;1633struct cx231xx *dev = fh->dev;1634int ret = 0;1635__le64 buf;1636u32 value;1637u8 data[4] = { 0, 0, 0, 0 };16381639buf = cpu_to_le64(reg->val);16401641switch (reg->match.type) {1642case V4L2_CHIP_MATCH_HOST:1643{1644value = (u32) buf & 0xffffffff;16451646switch (reg->match.addr) {1647case 0: /* cx231xx internal registers */1648data[0] = (u8) value;1649data[1] = (u8) (value >> 8);1650data[2] = (u8) (value >> 16);1651data[3] = (u8) (value >> 24);1652ret = cx231xx_write_ctrl_reg(dev,1653VRT_SET_REGISTER,1654(u16)reg->reg, data,16554);1656break;1657case 1: /* AFE - read byte */1658ret = cx231xx_write_i2c_data(dev,1659AFE_DEVICE_ADDRESS,1660(u16)reg->reg, 2,1661value, 1);1662break;1663case 14: /* AFE - read dword */1664ret = cx231xx_write_i2c_data(dev,1665AFE_DEVICE_ADDRESS,1666(u16)reg->reg, 2,1667value, 4);1668break;1669case 2: /* Video Block - read byte */1670ret =1671cx231xx_write_i2c_data(dev,1672VID_BLK_I2C_ADDRESS,1673(u16)reg->reg, 2,1674value, 1);1675break;1676case 24: /* Video Block - read dword */1677ret =1678cx231xx_write_i2c_data(dev,1679VID_BLK_I2C_ADDRESS,1680(u16)reg->reg, 2,1681value, 4);1682break;1683case 3: /* I2S block - read byte */1684ret =1685cx231xx_write_i2c_data(dev,1686I2S_BLK_DEVICE_ADDRESS,1687(u16)reg->reg, 1,1688value, 1);1689break;1690case 34: /* I2S block - read dword */1691ret =1692cx231xx_write_i2c_data(dev,1693I2S_BLK_DEVICE_ADDRESS,1694(u16)reg->reg, 1,1695value, 4);1696break;1697}1698}1699return ret < 0 ? ret : 0;1700case V4L2_CHIP_MATCH_I2C_ADDR:1701{1702value = (u32) buf & 0xffffffff;17031704switch (reg->match.addr) {1705case 0:/*cx231xx internal registers*/1706data[0] = (u8) value;1707data[1] = (u8) (value >> 8);1708data[2] = (u8) (value >> 16);1709data[3] = (u8) (value >> 24);1710ret = cx231xx_write_ctrl_reg(dev,1711VRT_SET_REGISTER,1712(u16)reg->reg, data,17134);1714break;1715case 0x600:/* AFE - read byte */1716ret = cx231xx_write_i2c_master(dev,1717AFE_DEVICE_ADDRESS,1718(u16)reg->reg, 2,1719value, 1 , 0);1720break;17211722case 0x880:/* Video Block - read byte */1723if (reg->reg < 0x0b)1724cx231xx_write_i2c_master(dev,1725VID_BLK_I2C_ADDRESS,1726(u16)reg->reg, 2,1727value, 1, 0);1728else1729cx231xx_write_i2c_master(dev,1730VID_BLK_I2C_ADDRESS,1731(u16)reg->reg, 2,1732value, 4, 0);1733break;1734case 0x980:1735ret =1736cx231xx_write_i2c_master(dev,1737I2S_BLK_DEVICE_ADDRESS,1738(u16)reg->reg, 1,1739value, 1, 0);1740break;1741case 0x400:1742ret =1743cx231xx_write_i2c_master(dev,17440x40,1745(u16)reg->reg, 1,1746value, 1, 0);1747break;1748case 0xc01:1749ret =1750cx231xx_write_i2c_master(dev,17510xc0,1752(u16)reg->reg, 1,1753value, 1, 1);1754break;17551756case 0x022:1757ret =1758cx231xx_write_i2c_master(dev,17590x02,1760(u16)reg->reg, 1,1761value, 1, 2);1762case 0x322:1763ret =1764cx231xx_write_i2c_master(dev,17650x32,1766(u16)reg->reg, 1,1767value, 4, 2);1768break;17691770case 0x342:1771ret =1772cx231xx_write_i2c_master(dev,17730x34,1774(u16)reg->reg, 1,1775value, 4, 2);1776break;1777default:1778cx231xx_info("no match device address, "1779"the value is %x\n", reg->match.addr);1780break;17811782}17831784}1785default:1786break;1787}17881789call_all(dev, core, s_register, reg);17901791return ret;1792}1793#endif17941795static int vidioc_cropcap(struct file *file, void *priv,1796struct v4l2_cropcap *cc)1797{1798struct cx231xx_fh *fh = priv;1799struct cx231xx *dev = fh->dev;18001801if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)1802return -EINVAL;18031804cc->bounds.left = 0;1805cc->bounds.top = 0;1806cc->bounds.width = dev->width;1807cc->bounds.height = dev->height;1808cc->defrect = cc->bounds;1809cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */1810cc->pixelaspect.denominator = 59;18111812return 0;1813}18141815static int vidioc_streamon(struct file *file, void *priv,1816enum v4l2_buf_type type)1817{1818struct cx231xx_fh *fh = priv;1819struct cx231xx *dev = fh->dev;1820int rc;18211822rc = check_dev(dev);1823if (rc < 0)1824return rc;18251826rc = res_get(fh);18271828if (likely(rc >= 0))1829rc = videobuf_streamon(&fh->vb_vidq);18301831call_all(dev, video, s_stream, 1);18321833return rc;1834}18351836static int vidioc_streamoff(struct file *file, void *priv,1837enum v4l2_buf_type type)1838{1839struct cx231xx_fh *fh = priv;1840struct cx231xx *dev = fh->dev;1841int rc;18421843rc = check_dev(dev);1844if (rc < 0)1845return rc;18461847if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&1848(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))1849return -EINVAL;1850if (type != fh->type)1851return -EINVAL;18521853cx25840_call(dev, video, s_stream, 0);18541855videobuf_streamoff(&fh->vb_vidq);1856res_free(fh);18571858return 0;1859}18601861static int vidioc_querycap(struct file *file, void *priv,1862struct v4l2_capability *cap)1863{1864struct cx231xx_fh *fh = priv;1865struct cx231xx *dev = fh->dev;18661867strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));1868strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));1869usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));18701871cap->version = CX231XX_VERSION_CODE;18721873cap->capabilities = V4L2_CAP_VBI_CAPTURE |1874#if 01875V4L2_CAP_SLICED_VBI_CAPTURE |1876#endif1877V4L2_CAP_VIDEO_CAPTURE |1878V4L2_CAP_AUDIO |1879V4L2_CAP_READWRITE |1880V4L2_CAP_STREAMING;18811882if (dev->tuner_type != TUNER_ABSENT)1883cap->capabilities |= V4L2_CAP_TUNER;18841885return 0;1886}18871888static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,1889struct v4l2_fmtdesc *f)1890{1891if (unlikely(f->index >= ARRAY_SIZE(format)))1892return -EINVAL;18931894strlcpy(f->description, format[f->index].name, sizeof(f->description));1895f->pixelformat = format[f->index].fourcc;18961897return 0;1898}18991900/* Sliced VBI ioctls */1901static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,1902struct v4l2_format *f)1903{1904struct cx231xx_fh *fh = priv;1905struct cx231xx *dev = fh->dev;1906int rc;19071908rc = check_dev(dev);1909if (rc < 0)1910return rc;19111912f->fmt.sliced.service_set = 0;19131914call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);19151916if (f->fmt.sliced.service_set == 0)1917rc = -EINVAL;19181919return rc;1920}19211922static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,1923struct v4l2_format *f)1924{1925struct cx231xx_fh *fh = priv;1926struct cx231xx *dev = fh->dev;1927int rc;19281929rc = check_dev(dev);1930if (rc < 0)1931return rc;19321933call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);19341935if (f->fmt.sliced.service_set == 0)1936return -EINVAL;19371938return 0;1939}19401941/* RAW VBI ioctls */19421943static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,1944struct v4l2_format *f)1945{1946struct cx231xx_fh *fh = priv;1947struct cx231xx *dev = fh->dev;1948f->fmt.vbi.sampling_rate = 6750000 * 4;1949f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;1950f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;1951f->fmt.vbi.offset = 0;1952f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?1953PAL_VBI_START_LINE : NTSC_VBI_START_LINE;1954f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?1955PAL_VBI_LINES : NTSC_VBI_LINES;1956f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?1957PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;1958f->fmt.vbi.count[1] = f->fmt.vbi.count[0];19591960return 0;19611962}19631964static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,1965struct v4l2_format *f)1966{1967struct cx231xx_fh *fh = priv;1968struct cx231xx *dev = fh->dev;19691970if (dev->vbi_stream_on && !fh->stream_on) {1971cx231xx_errdev("%s device in use by another fh\n", __func__);1972return -EBUSY;1973}19741975f->type = V4L2_BUF_TYPE_VBI_CAPTURE;1976f->fmt.vbi.sampling_rate = 6750000 * 4;1977f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;1978f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;1979f->fmt.vbi.offset = 0;1980f->fmt.vbi.flags = 0;1981f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?1982PAL_VBI_START_LINE : NTSC_VBI_START_LINE;1983f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?1984PAL_VBI_LINES : NTSC_VBI_LINES;1985f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?1986PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;1987f->fmt.vbi.count[1] = f->fmt.vbi.count[0];19881989return 0;19901991}19921993static int vidioc_reqbufs(struct file *file, void *priv,1994struct v4l2_requestbuffers *rb)1995{1996struct cx231xx_fh *fh = priv;1997struct cx231xx *dev = fh->dev;1998int rc;19992000rc = check_dev(dev);2001if (rc < 0)2002return rc;20032004return videobuf_reqbufs(&fh->vb_vidq, rb);2005}20062007static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b)2008{2009struct cx231xx_fh *fh = priv;2010struct cx231xx *dev = fh->dev;2011int rc;20122013rc = check_dev(dev);2014if (rc < 0)2015return rc;20162017return videobuf_querybuf(&fh->vb_vidq, b);2018}20192020static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)2021{2022struct cx231xx_fh *fh = priv;2023struct cx231xx *dev = fh->dev;2024int rc;20252026rc = check_dev(dev);2027if (rc < 0)2028return rc;20292030return videobuf_qbuf(&fh->vb_vidq, b);2031}20322033static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)2034{2035struct cx231xx_fh *fh = priv;2036struct cx231xx *dev = fh->dev;2037int rc;20382039rc = check_dev(dev);2040if (rc < 0)2041return rc;20422043return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);2044}20452046/* ----------------------------------------------------------- */2047/* RADIO ESPECIFIC IOCTLS */2048/* ----------------------------------------------------------- */20492050static int radio_querycap(struct file *file, void *priv,2051struct v4l2_capability *cap)2052{2053struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;20542055strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));2056strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));2057usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));20582059cap->version = CX231XX_VERSION_CODE;2060cap->capabilities = V4L2_CAP_TUNER;2061return 0;2062}20632064static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)2065{2066struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;20672068if (unlikely(t->index > 0))2069return -EINVAL;20702071strcpy(t->name, "Radio");2072t->type = V4L2_TUNER_RADIO;20732074call_all(dev, tuner, s_tuner, t);20752076return 0;2077}20782079static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i)2080{2081if (i->index != 0)2082return -EINVAL;2083strcpy(i->name, "Radio");2084i->type = V4L2_INPUT_TYPE_TUNER;20852086return 0;2087}20882089static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)2090{2091if (unlikely(a->index))2092return -EINVAL;20932094strcpy(a->name, "Radio");2095return 0;2096}20972098static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)2099{2100struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;21012102if (0 != t->index)2103return -EINVAL;21042105call_all(dev, tuner, s_tuner, t);21062107return 0;2108}21092110static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)2111{2112return 0;2113}21142115static int radio_s_input(struct file *file, void *fh, unsigned int i)2116{2117return 0;2118}21192120static int radio_queryctrl(struct file *file, void *priv,2121struct v4l2_queryctrl *c)2122{2123int i;21242125if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)2126return -EINVAL;2127if (c->id == V4L2_CID_AUDIO_MUTE) {2128for (i = 0; i < CX231XX_CTLS; i++) {2129if (cx231xx_ctls[i].v.id == c->id)2130break;2131}2132if (i == CX231XX_CTLS)2133return -EINVAL;2134*c = cx231xx_ctls[i].v;2135} else2136*c = no_ctl;2137return 0;2138}21392140/*2141* cx231xx_v4l2_open()2142* inits the device and starts isoc transfer2143*/2144static int cx231xx_v4l2_open(struct file *filp)2145{2146int errCode = 0, radio = 0;2147struct video_device *vdev = video_devdata(filp);2148struct cx231xx *dev = video_drvdata(filp);2149struct cx231xx_fh *fh;2150enum v4l2_buf_type fh_type = 0;21512152switch (vdev->vfl_type) {2153case VFL_TYPE_GRABBER:2154fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;2155break;2156case VFL_TYPE_VBI:2157fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;2158break;2159case VFL_TYPE_RADIO:2160radio = 1;2161break;2162}21632164cx231xx_videodbg("open dev=%s type=%s users=%d\n",2165video_device_node_name(vdev), v4l2_type_names[fh_type],2166dev->users);21672168#if 02169errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);2170if (errCode < 0) {2171cx231xx_errdev2172("Device locked on digital mode. Can't open analog\n");2173return -EBUSY;2174}2175#endif21762177fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL);2178if (!fh) {2179cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");2180return -ENOMEM;2181}2182fh->dev = dev;2183fh->radio = radio;2184fh->type = fh_type;2185filp->private_data = fh;21862187if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {2188dev->width = norm_maxw(dev);2189dev->height = norm_maxh(dev);21902191/* Power up in Analog TV mode */2192if (dev->board.external_av)2193cx231xx_set_power_mode(dev,2194POLARIS_AVMODE_ENXTERNAL_AV);2195else2196cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);21972198#if 02199cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);2200#endif22012202/* set video alternate setting */2203cx231xx_set_video_alternate(dev);22042205/* Needed, since GPIO might have disabled power of2206some i2c device */2207cx231xx_config_i2c(dev);22082209/* device needs to be initialized before isoc transfer */2210dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;22112212}2213if (fh->radio) {2214cx231xx_videodbg("video_open: setting radio device\n");22152216/* cx231xx_start_radio(dev); */22172218call_all(dev, tuner, s_radio);2219}22202221dev->users++;22222223if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)2224videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops,2225NULL, &dev->video_mode.slock,2226fh->type, V4L2_FIELD_INTERLACED,2227sizeof(struct cx231xx_buffer),2228fh, &dev->lock);2229if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {2230/* Set the required alternate setting VBI interface works in2231Bulk mode only */2232cx231xx_set_alt_setting(dev, INDEX_VANC, 0);22332234videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,2235NULL, &dev->vbi_mode.slock,2236fh->type, V4L2_FIELD_SEQ_TB,2237sizeof(struct cx231xx_buffer),2238fh, &dev->lock);2239}22402241return errCode;2242}22432244/*2245* cx231xx_realease_resources()2246* unregisters the v4l2,i2c and usb devices2247* called when the device gets disconected or at module unload2248*/2249void cx231xx_release_analog_resources(struct cx231xx *dev)2250{22512252/*FIXME: I2C IR should be disconnected */22532254if (dev->radio_dev) {2255if (video_is_registered(dev->radio_dev))2256video_unregister_device(dev->radio_dev);2257else2258video_device_release(dev->radio_dev);2259dev->radio_dev = NULL;2260}2261if (dev->vbi_dev) {2262cx231xx_info("V4L2 device %s deregistered\n",2263video_device_node_name(dev->vbi_dev));2264if (video_is_registered(dev->vbi_dev))2265video_unregister_device(dev->vbi_dev);2266else2267video_device_release(dev->vbi_dev);2268dev->vbi_dev = NULL;2269}2270if (dev->vdev) {2271cx231xx_info("V4L2 device %s deregistered\n",2272video_device_node_name(dev->vdev));22732274if (dev->board.has_417)2275cx231xx_417_unregister(dev);22762277if (video_is_registered(dev->vdev))2278video_unregister_device(dev->vdev);2279else2280video_device_release(dev->vdev);2281dev->vdev = NULL;2282}2283}22842285/*2286* cx231xx_v4l2_close()2287* stops streaming and deallocates all resources allocated by the v4l22288* calls and ioctls2289*/2290static int cx231xx_v4l2_close(struct file *filp)2291{2292struct cx231xx_fh *fh = filp->private_data;2293struct cx231xx *dev = fh->dev;22942295cx231xx_videodbg("users=%d\n", dev->users);22962297cx231xx_videodbg("users=%d\n", dev->users);2298if (res_check(fh))2299res_free(fh);23002301/*2302* To workaround error number=-71 on EP0 for VideoGrabber,2303* need exclude following.2304* FIXME: It is probably safe to remove most of these, as we're2305* now avoiding the alternate setting for INDEX_VANC2306*/2307if (!dev->board.no_alt_vanc)2308if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {2309videobuf_stop(&fh->vb_vidq);2310videobuf_mmap_free(&fh->vb_vidq);23112312/* the device is already disconnect,2313free the remaining resources */2314if (dev->state & DEV_DISCONNECTED) {2315if (atomic_read(&dev->devlist_count) > 0) {2316cx231xx_release_resources(dev);2317kfree(dev);2318dev = NULL;2319return 0;2320}2321return 0;2322}23232324/* do this before setting alternate! */2325cx231xx_uninit_vbi_isoc(dev);23262327/* set alternate 0 */2328if (!dev->vbi_or_sliced_cc_mode)2329cx231xx_set_alt_setting(dev, INDEX_VANC, 0);2330else2331cx231xx_set_alt_setting(dev, INDEX_HANC, 0);23322333kfree(fh);2334dev->users--;2335wake_up_interruptible_nr(&dev->open, 1);2336return 0;2337}23382339if (dev->users == 1) {2340videobuf_stop(&fh->vb_vidq);2341videobuf_mmap_free(&fh->vb_vidq);23422343/* the device is already disconnect,2344free the remaining resources */2345if (dev->state & DEV_DISCONNECTED) {2346cx231xx_release_resources(dev);2347kfree(dev);2348dev = NULL;2349return 0;2350}23512352/* Save some power by putting tuner to sleep */2353call_all(dev, core, s_power, 0);23542355/* do this before setting alternate! */2356if (dev->USE_ISO)2357cx231xx_uninit_isoc(dev);2358else2359cx231xx_uninit_bulk(dev);2360cx231xx_set_mode(dev, CX231XX_SUSPEND);23612362/* set alternate 0 */2363cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);2364}2365kfree(fh);2366dev->users--;2367wake_up_interruptible_nr(&dev->open, 1);2368return 0;2369}23702371/*2372* cx231xx_v4l2_read()2373* will allocate buffers when called for the first time2374*/2375static ssize_t2376cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,2377loff_t *pos)2378{2379struct cx231xx_fh *fh = filp->private_data;2380struct cx231xx *dev = fh->dev;2381int rc;23822383rc = check_dev(dev);2384if (rc < 0)2385return rc;23862387if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||2388(fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {2389rc = res_get(fh);23902391if (unlikely(rc < 0))2392return rc;23932394return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,2395filp->f_flags & O_NONBLOCK);2396}2397return 0;2398}23992400/*2401* cx231xx_v4l2_poll()2402* will allocate buffers when called for the first time2403*/2404static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait)2405{2406struct cx231xx_fh *fh = filp->private_data;2407struct cx231xx *dev = fh->dev;2408int rc;24092410rc = check_dev(dev);2411if (rc < 0)2412return rc;24132414rc = res_get(fh);24152416if (unlikely(rc < 0))2417return POLLERR;24182419if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||2420(V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))2421return videobuf_poll_stream(filp, &fh->vb_vidq, wait);2422else2423return POLLERR;2424}24252426/*2427* cx231xx_v4l2_mmap()2428*/2429static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)2430{2431struct cx231xx_fh *fh = filp->private_data;2432struct cx231xx *dev = fh->dev;2433int rc;24342435rc = check_dev(dev);2436if (rc < 0)2437return rc;24382439rc = res_get(fh);24402441if (unlikely(rc < 0))2442return rc;24432444rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);24452446cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",2447(unsigned long)vma->vm_start,2448(unsigned long)vma->vm_end -2449(unsigned long)vma->vm_start, rc);24502451return rc;2452}24532454static const struct v4l2_file_operations cx231xx_v4l_fops = {2455.owner = THIS_MODULE,2456.open = cx231xx_v4l2_open,2457.release = cx231xx_v4l2_close,2458.read = cx231xx_v4l2_read,2459.poll = cx231xx_v4l2_poll,2460.mmap = cx231xx_v4l2_mmap,2461.unlocked_ioctl = video_ioctl2,2462};24632464static const struct v4l2_ioctl_ops video_ioctl_ops = {2465.vidioc_querycap = vidioc_querycap,2466.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,2467.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,2468.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,2469.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,2470.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,2471.vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,2472.vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,2473.vidioc_g_audio = vidioc_g_audio,2474.vidioc_s_audio = vidioc_s_audio,2475.vidioc_cropcap = vidioc_cropcap,2476.vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,2477.vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,2478.vidioc_reqbufs = vidioc_reqbufs,2479.vidioc_querybuf = vidioc_querybuf,2480.vidioc_qbuf = vidioc_qbuf,2481.vidioc_dqbuf = vidioc_dqbuf,2482.vidioc_s_std = vidioc_s_std,2483.vidioc_g_std = vidioc_g_std,2484.vidioc_enum_input = vidioc_enum_input,2485.vidioc_g_input = vidioc_g_input,2486.vidioc_s_input = vidioc_s_input,2487.vidioc_queryctrl = vidioc_queryctrl,2488.vidioc_g_ctrl = vidioc_g_ctrl,2489.vidioc_s_ctrl = vidioc_s_ctrl,2490.vidioc_streamon = vidioc_streamon,2491.vidioc_streamoff = vidioc_streamoff,2492.vidioc_g_tuner = vidioc_g_tuner,2493.vidioc_s_tuner = vidioc_s_tuner,2494.vidioc_g_frequency = vidioc_g_frequency,2495.vidioc_s_frequency = vidioc_s_frequency,2496#ifdef CONFIG_VIDEO_ADV_DEBUG2497.vidioc_g_register = vidioc_g_register,2498.vidioc_s_register = vidioc_s_register,2499#endif2500};25012502static struct video_device cx231xx_vbi_template;25032504static const struct video_device cx231xx_video_template = {2505.fops = &cx231xx_v4l_fops,2506.release = video_device_release,2507.ioctl_ops = &video_ioctl_ops,2508.tvnorms = V4L2_STD_ALL,2509.current_norm = V4L2_STD_PAL,2510};25112512static const struct v4l2_file_operations radio_fops = {2513.owner = THIS_MODULE,2514.open = cx231xx_v4l2_open,2515.release = cx231xx_v4l2_close,2516.ioctl = video_ioctl2,2517};25182519static const struct v4l2_ioctl_ops radio_ioctl_ops = {2520.vidioc_querycap = radio_querycap,2521.vidioc_g_tuner = radio_g_tuner,2522.vidioc_enum_input = radio_enum_input,2523.vidioc_g_audio = radio_g_audio,2524.vidioc_s_tuner = radio_s_tuner,2525.vidioc_s_audio = radio_s_audio,2526.vidioc_s_input = radio_s_input,2527.vidioc_queryctrl = radio_queryctrl,2528.vidioc_g_ctrl = vidioc_g_ctrl,2529.vidioc_s_ctrl = vidioc_s_ctrl,2530.vidioc_g_frequency = vidioc_g_frequency,2531.vidioc_s_frequency = vidioc_s_frequency,2532#ifdef CONFIG_VIDEO_ADV_DEBUG2533.vidioc_g_register = vidioc_g_register,2534.vidioc_s_register = vidioc_s_register,2535#endif2536};25372538static struct video_device cx231xx_radio_template = {2539.name = "cx231xx-radio",2540.fops = &radio_fops,2541.ioctl_ops = &radio_ioctl_ops,2542};25432544/******************************** usb interface ******************************/25452546static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,2547const struct video_device2548*template, const char *type_name)2549{2550struct video_device *vfd;25512552vfd = video_device_alloc();2553if (NULL == vfd)2554return NULL;25552556*vfd = *template;2557vfd->v4l2_dev = &dev->v4l2_dev;2558vfd->release = video_device_release;2559vfd->debug = video_debug;2560vfd->lock = &dev->lock;25612562snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);25632564video_set_drvdata(vfd, dev);2565return vfd;2566}25672568int cx231xx_register_analog_devices(struct cx231xx *dev)2569{2570int ret;25712572cx231xx_info("%s: v4l2 driver version %d.%d.%d\n",2573dev->name,2574(CX231XX_VERSION_CODE >> 16) & 0xff,2575(CX231XX_VERSION_CODE >> 8) & 0xff,2576CX231XX_VERSION_CODE & 0xff);25772578/* set default norm */2579/*dev->norm = cx231xx_video_template.current_norm; */2580dev->width = norm_maxw(dev);2581dev->height = norm_maxh(dev);2582dev->interlaced = 0;25832584/* Analog specific initialization */2585dev->format = &format[0];25862587/* Set the initial input */2588video_mux(dev, dev->video_input);25892590/* Audio defaults */2591dev->mute = 1;2592dev->volume = 0x1f;25932594/* enable vbi capturing */2595/* write code here... */25962597/* allocate and fill video video_device struct */2598dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video");2599if (!dev->vdev) {2600cx231xx_errdev("cannot allocate video_device.\n");2601return -ENODEV;2602}26032604/* register v4l2 video video_device */2605ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,2606video_nr[dev->devno]);2607if (ret) {2608cx231xx_errdev("unable to register video device (error=%i).\n",2609ret);2610return ret;2611}26122613cx231xx_info("%s/0: registered device %s [v4l2]\n",2614dev->name, video_device_node_name(dev->vdev));26152616/* Initialize VBI template */2617memcpy(&cx231xx_vbi_template, &cx231xx_video_template,2618sizeof(cx231xx_vbi_template));2619strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");26202621/* Allocate and fill vbi video_device struct */2622dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi");26232624/* register v4l2 vbi video_device */2625ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,2626vbi_nr[dev->devno]);2627if (ret < 0) {2628cx231xx_errdev("unable to register vbi device\n");2629return ret;2630}26312632cx231xx_info("%s/0: registered device %s\n",2633dev->name, video_device_node_name(dev->vbi_dev));26342635if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {2636dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,2637"radio");2638if (!dev->radio_dev) {2639cx231xx_errdev("cannot allocate video_device.\n");2640return -ENODEV;2641}2642ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,2643radio_nr[dev->devno]);2644if (ret < 0) {2645cx231xx_errdev("can't register radio device\n");2646return ret;2647}2648cx231xx_info("Registered radio device as %s\n",2649video_device_node_name(dev->radio_dev));2650}26512652cx231xx_info("V4L2 device registered as %s and %s\n",2653video_device_node_name(dev->vdev),2654video_device_node_name(dev->vbi_dev));26552656return 0;2657}265826592660