Commit 84b5dbf3 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (10955): cx231xx: CodingStyle automatic fixes with Lindent

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e0d3bafd
...@@ -58,21 +58,20 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) ...@@ -58,21 +58,20 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
dprintk("Stopping isoc\n"); dprintk("Stopping isoc\n");
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
if(dev->adev.urb[i]) { if (dev->adev.urb[i]) {
if (!irqs_disabled()) if (!irqs_disabled())
usb_kill_urb(dev->adev.urb[i]); usb_kill_urb(dev->adev.urb[i]);
else else
usb_unlink_urb(dev->adev.urb[i]); usb_unlink_urb(dev->adev.urb[i]);
usb_free_urb(dev->adev.urb[i]); usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL; dev->adev.urb[i] = NULL;
kfree(dev->adev.transfer_buffer[i]); kfree(dev->adev.transfer_buffer[i]);
dev->adev.transfer_buffer[i] = NULL; dev->adev.transfer_buffer[i] = NULL;
} }
} }
return 0; return 0;
...@@ -80,27 +79,27 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) ...@@ -80,27 +79,27 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
static void cx231xx_audio_isocirq(struct urb *urb) static void cx231xx_audio_isocirq(struct urb *urb)
{ {
struct cx231xx *dev = urb->context; struct cx231xx *dev = urb->context;
int i; int i;
unsigned int oldptr; unsigned int oldptr;
int period_elapsed = 0; int period_elapsed = 0;
int status; int status;
unsigned char *cp; unsigned char *cp;
unsigned int stride; unsigned int stride;
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
switch (urb->status) { switch (urb->status) {
case 0: /* success */ case 0: /* success */
case -ETIMEDOUT: /* NAK */ case -ETIMEDOUT: /* NAK */
break; break;
case -ECONNRESET: /* kill */ case -ECONNRESET: /* kill */
case -ENOENT: case -ENOENT:
case -ESHUTDOWN: case -ESHUTDOWN:
return; return;
default: /* error */ default: /* error */
dprintk("urb completition error %d.\n", urb->status); dprintk("urb completition error %d.\n", urb->status);
break; break;
} }
if (dev->adev.capture_pcm_substream) { if (dev->adev.capture_pcm_substream) {
...@@ -145,7 +144,6 @@ static void cx231xx_audio_isocirq(struct urb *urb) ...@@ -145,7 +144,6 @@ static void cx231xx_audio_isocirq(struct urb *urb)
runtime->period_size; runtime->period_size;
period_elapsed = 1; period_elapsed = 1;
} }
snd_pcm_stream_unlock(substream); snd_pcm_stream_unlock(substream);
} }
if (period_elapsed) if (period_elapsed)
...@@ -156,19 +154,19 @@ static void cx231xx_audio_isocirq(struct urb *urb) ...@@ -156,19 +154,19 @@ static void cx231xx_audio_isocirq(struct urb *urb)
status = usb_submit_urb(urb, GFP_ATOMIC); status = usb_submit_urb(urb, GFP_ATOMIC);
if (status < 0) { if (status < 0) {
cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
status); status);
} }
return; return;
} }
static int cx231xx_init_audio_isoc(struct cx231xx *dev) static int cx231xx_init_audio_isoc(struct cx231xx *dev)
{ {
int i, errCode; int i, errCode;
int sb_size; int sb_size;
cx231xx_info("%s: Starting AUDIO transfers\n",__func__); cx231xx_info("%s: Starting AUDIO transfers\n", __func__);
sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
struct urb *urb; struct urb *urb;
...@@ -191,7 +189,8 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -191,7 +189,8 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
urb->dev = dev->udev; urb->dev = dev->udev;
urb->context = dev; urb->context = dev;
urb->pipe = usb_rcvisocpipe(dev->udev, dev->adev.end_point_addr); urb->pipe =
usb_rcvisocpipe(dev->udev, dev->adev.end_point_addr);
urb->transfer_flags = URB_ISO_ASAP; urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->transfer_buffer = dev->adev.transfer_buffer[i];
urb->interval = 1; urb->interval = 1;
...@@ -200,10 +199,9 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -200,10 +199,9 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
urb->transfer_buffer_length = sb_size; urb->transfer_buffer_length = sb_size;
for (j = k = 0; j < CX231XX_NUM_AUDIO_PACKETS; for (j = k = 0; j < CX231XX_NUM_AUDIO_PACKETS;
j++, k += dev->adev.max_pkt_size) { j++, k += dev->adev.max_pkt_size) {
urb->iso_frame_desc[j].offset = k; urb->iso_frame_desc[j].offset = k;
urb->iso_frame_desc[j].length = urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
dev->adev.max_pkt_size;
} }
dev->adev.urb[i] = urb; dev->adev.urb[i] = urb;
} }
...@@ -221,11 +219,11 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -221,11 +219,11 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg) static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg)
{ {
dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON)? dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
"stop" : "start"); "stop" : "start");
switch (cmd) { switch (cmd) {
case CX231XX_CAPTURE_STREAM_EN: case CX231XX_CAPTURE_STREAM_EN:
if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
dev->adev.capture_stream = STREAM_ON; dev->adev.capture_stream = STREAM_ON;
cx231xx_init_audio_isoc(dev); cx231xx_init_audio_isoc(dev);
...@@ -233,8 +231,8 @@ static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg) ...@@ -233,8 +231,8 @@ static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg)
dev->adev.capture_stream = STREAM_OFF; dev->adev.capture_stream = STREAM_OFF;
cx231xx_isoc_audio_deinit(dev); cx231xx_isoc_audio_deinit(dev);
} else { } else {
cx231xx_errdev( "An underrun very likely occurred. " cx231xx_errdev("An underrun very likely occurred. "
"Ignoring it.\n"); "Ignoring it.\n");
} }
return 0; return 0;
default: default:
...@@ -265,9 +263,8 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, ...@@ -265,9 +263,8 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
static struct snd_pcm_hardware snd_cx231xx_hw_capture = { static struct snd_pcm_hardware snd_cx231xx_hw_capture = {
.info = SNDRV_PCM_INFO_BLOCK_TRANSFER | .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID,
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE,
...@@ -278,10 +275,10 @@ static struct snd_pcm_hardware snd_cx231xx_hw_capture = { ...@@ -278,10 +275,10 @@ static struct snd_pcm_hardware snd_cx231xx_hw_capture = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */ .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
.period_bytes_min = 64, /* 12544/2, */ .period_bytes_min = 64, /* 12544/2, */
.period_bytes_max = 12544, .period_bytes_max = 12544,
.periods_min = 2, .periods_min = 2,
.periods_max = 98, /* 12544, */ .periods_max = 98, /* 12544, */
}; };
static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
...@@ -294,29 +291,29 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ...@@ -294,29 +291,29 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
if (!dev) { if (!dev) {
cx231xx_errdev("BUG: cx231xx can't find device struct." cx231xx_errdev("BUG: cx231xx can't find device struct."
" Can't proceed with open\n"); " Can't proceed with open\n");
return -ENODEV; return -ENODEV;
} }
/* Sets volume, mute, etc */ /* Sets volume, mute, etc */
dev->mute = 0; dev->mute = 0;
/* set alternate setting for audio interface */ /* set alternate setting for audio interface */
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1); /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1); /* 1 - 48000 samples per sec */
if (ret < 0) { if (ret < 0) {
cx231xx_errdev("failed to set alternate setting !\n"); cx231xx_errdev("failed to set alternate setting !\n");
return ret; return ret;
} }
/* inform hardware to start streaming */ /* inform hardware to start streaming */
ret = cx231xx_capture_start(dev, 1, Audio); ret = cx231xx_capture_start(dev, 1, Audio);
runtime->hw = snd_cx231xx_hw_capture; runtime->hw = snd_cx231xx_hw_capture;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
dev->adev.users++; dev->adev.users++;
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
dev->adev.capture_pcm_substream = substream; dev->adev.capture_pcm_substream = substream;
...@@ -327,26 +324,25 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ...@@ -327,26 +324,25 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
{ {
int ret; int ret;
struct cx231xx *dev = snd_pcm_substream_chip(substream); struct cx231xx *dev = snd_pcm_substream_chip(substream);
dprintk("closing device\n"); dprintk("closing device\n");
/* set alternate setting for audio interface */ /* set alternate setting for audio interface */
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); /* 1 - 48000 samples per sec */
if (ret < 0) { if (ret < 0) {
cx231xx_errdev("failed to set alternate setting !\n"); cx231xx_errdev("failed to set alternate setting !\n");
return ret; return ret;
} }
/* inform hardware to start streaming */ /* inform hardware to start streaming */
ret = cx231xx_capture_start(dev, 0, Audio); ret = cx231xx_capture_start(dev, 0, Audio);
dev->mute = 1; dev->mute = 1;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
dev->adev.users--; dev->adev.users--;
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
if (dev->adev.users == 0 && dev->adev.shutdown == 1) { if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
...@@ -360,7 +356,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) ...@@ -360,7 +356,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
} }
static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params) struct snd_pcm_hw_params *hw_params)
{ {
unsigned int channels, rate, format; unsigned int channels, rate, format;
int ret; int ret;
...@@ -368,7 +364,7 @@ static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, ...@@ -368,7 +364,7 @@ static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
dprintk("Setting capture parameters\n"); dprintk("Setting capture parameters\n");
ret = snd_pcm_alloc_vmalloc_buffer(substream, ret = snd_pcm_alloc_vmalloc_buffer(substream,
params_buffer_bytes(hw_params)); params_buffer_bytes(hw_params));
format = params_format(hw_params); format = params_format(hw_params);
rate = params_rate(hw_params); rate = params_rate(hw_params);
channels = params_channels(hw_params); channels = params_channels(hw_params);
...@@ -397,45 +393,45 @@ static int snd_cx231xx_prepare(struct snd_pcm_substream *substream) ...@@ -397,45 +393,45 @@ static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
} }
static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream, static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
int cmd) int cmd)
{ {
struct cx231xx *dev = snd_pcm_substream_chip(substream); struct cx231xx *dev = snd_pcm_substream_chip(substream);
int retval; int retval;
dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
"start" : "stop");
dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)? spin_lock(&dev->adev.slock);
"start": "stop");
spin_lock(&dev->adev.slock);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_START_AUDIO); cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN,
CX231XX_START_AUDIO);
retval = 0; retval = 0;
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO); cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO);
retval = 0; retval = 0;
break; break;
default: default:
retval = -EINVAL; retval = -EINVAL;
} }
spin_unlock(&dev->adev.slock); spin_unlock(&dev->adev.slock);
return retval; return retval;
} }
static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
*substream) *substream)
{ {
struct cx231xx *dev; struct cx231xx *dev;
unsigned long flags; unsigned long flags;
snd_pcm_uframes_t hwptr_done; snd_pcm_uframes_t hwptr_done;
dev = snd_pcm_substream_chip(substream); dev = snd_pcm_substream_chip(substream);
spin_lock_irqsave(&dev->adev.slock, flags); spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture; hwptr_done = dev->adev.hwptr_done_capture;
spin_unlock_irqrestore(&dev->adev.slock, flags); spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done; return hwptr_done;
} }
...@@ -449,26 +445,26 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, ...@@ -449,26 +445,26 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
} }
static struct snd_pcm_ops snd_cx231xx_pcm_capture = { static struct snd_pcm_ops snd_cx231xx_pcm_capture = {
.open = snd_cx231xx_capture_open, .open = snd_cx231xx_capture_open,
.close = snd_cx231xx_pcm_close, .close = snd_cx231xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cx231xx_hw_capture_params, .hw_params = snd_cx231xx_hw_capture_params,
.hw_free = snd_cx231xx_hw_capture_free, .hw_free = snd_cx231xx_hw_capture_free,
.prepare = snd_cx231xx_prepare, .prepare = snd_cx231xx_prepare,
.trigger = snd_cx231xx_capture_trigger, .trigger = snd_cx231xx_capture_trigger,
.pointer = snd_cx231xx_capture_pointer, .pointer = snd_cx231xx_capture_pointer,
.page = snd_pcm_get_vmalloc_page, .page = snd_pcm_get_vmalloc_page,
}; };
static int cx231xx_audio_init(struct cx231xx *dev) static int cx231xx_audio_init(struct cx231xx *dev)
{ {
struct cx231xx_audio *adev = &dev->adev; struct cx231xx_audio *adev = &dev->adev;
struct snd_pcm *pcm; struct snd_pcm *pcm;
struct snd_card *card; struct snd_card *card;
static int devnr; static int devnr;
int err; int err;
struct usb_interface *uif; struct usb_interface *uif;
int i, isoc_pipe = 0; int i, isoc_pipe = 0;
if (dev->has_alsa_audio != 1) { if (dev->has_alsa_audio != 1) {
/* This device does not support the extension (in this case /* This device does not support the extension (in this case
...@@ -478,7 +474,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) ...@@ -478,7 +474,7 @@ static int cx231xx_audio_init(struct cx231xx *dev)
} }
cx231xx_info("cx231xx-audio.c: probing for cx231xx " cx231xx_info("cx231xx-audio.c: probing for cx231xx "
"non standard usbaudio\n"); "non standard usbaudio\n");
card = snd_card_new(index[devnr], "Cx231xx Audio", THIS_MODULE, 0); card = snd_card_new(index[devnr], "Cx231xx Audio", THIS_MODULE, 0);
if (card == NULL) { if (card == NULL) {
...@@ -492,7 +488,8 @@ static int cx231xx_audio_init(struct cx231xx *dev) ...@@ -492,7 +488,8 @@ static int cx231xx_audio_init(struct cx231xx *dev)
return err; return err;
} }
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx231xx_pcm_capture); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&snd_cx231xx_pcm_capture);
pcm->info_flags = 0; pcm->info_flags = 0;
pcm->private_data = dev; pcm->private_data = dev;
strcpy(pcm->name, "Conexant cx231xx Capture"); strcpy(pcm->name, "Conexant cx231xx Capture");
...@@ -508,29 +505,35 @@ static int cx231xx_audio_init(struct cx231xx *dev) ...@@ -508,29 +505,35 @@ static int cx231xx_audio_init(struct cx231xx *dev)
adev->sndcard = card; adev->sndcard = card;
adev->udev = dev->udev; adev->udev = dev->udev;
/* compute alternate max packet sizes for Audio */ /* compute alternate max packet sizes for Audio */
uif = dev->udev->actconfig->interface[dev->current_pcb_config.hs_config_info[0].interface_info.audio_index+1]; uif =
dev->udev->actconfig->interface[dev->current_pcb_config.
hs_config_info[0].interface_info.
audio_index + 1];
adev->end_point_addr = le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress); adev->end_point_addr =
le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
bEndpointAddress);
adev->num_alt = uif->num_altsetting; adev->num_alt = uif->num_altsetting;
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n", adev->end_point_addr, cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n",
adev->num_alt); adev->end_point_addr, adev->num_alt);
adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
if (adev->alt_max_pkt_size == NULL) { if (adev->alt_max_pkt_size == NULL) {
cx231xx_errdev("out of memory!\n"); cx231xx_errdev("out of memory!\n");
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < adev->num_alt ; i++) { for (i = 0; i < adev->num_alt; i++) {
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. u16 tmp =
wMaxPacketSize); le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
adev->alt_max_pkt_size[i] = wMaxPacketSize);
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); adev->alt_max_pkt_size[i] =
cx231xx_info("Alternate setting %i, max size= %i\n", i, (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
adev->alt_max_pkt_size[i]); cx231xx_info("Alternate setting %i, max size= %i\n", i,
} adev->alt_max_pkt_size[i]);
}
return 0; return 0;
} }
...@@ -549,7 +552,7 @@ static int cx231xx_audio_fini(struct cx231xx *dev) ...@@ -549,7 +552,7 @@ static int cx231xx_audio_fini(struct cx231xx *dev)
if (dev->adev.sndcard) { if (dev->adev.sndcard) {
snd_card_free(dev->adev.sndcard); snd_card_free(dev->adev.sndcard);
kfree(dev->adev.alt_max_pkt_size); kfree(dev->adev.alt_max_pkt_size);
dev->adev.sndcard = NULL; dev->adev.sndcard = NULL;
} }
...@@ -557,7 +560,7 @@ static int cx231xx_audio_fini(struct cx231xx *dev) ...@@ -557,7 +560,7 @@ static int cx231xx_audio_fini(struct cx231xx *dev)
} }
static struct cx231xx_ops audio_ops = { static struct cx231xx_ops audio_ops = {
.id = CX231XX_AUDIO, .id = CX231XX_AUDIO,
.name = "Cx231xx Audio Extension", .name = "Cx231xx Audio Extension",
.init = cx231xx_audio_init, .init = cx231xx_audio_init,
.fini = cx231xx_audio_fini, .fini = cx231xx_audio_fini,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
cx231xx-cards.c - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx-cards.c - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -50,131 +50,151 @@ static unsigned long cx231xx_devused; ...@@ -50,131 +50,151 @@ static unsigned long cx231xx_devused;
*/ */
static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = { static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = {
{ 0x03, 0x01, 10 }, {0x03, 0x01, 10},
{ 0x03, 0x00, 30 }, {0x03, 0x00, 30},
{ 0x03, 0x01, 10 }, {0x03, 0x01, 10},
{ -1, -1, -1 }, {-1, -1, -1},
}; };
/* /*
* Board definitions * Board definitions
*/ */
struct cx231xx_board cx231xx_boards[] = { struct cx231xx_board cx231xx_boards[] = {
[CX231XX_BOARD_UNKNOWN] = { [CX231XX_BOARD_UNKNOWN] = {
.name = "Unknown CX231xx video grabber", .name = "Unknown CX231xx video grabber",
.tuner_type = TUNER_ABSENT, .tuner_type = TUNER_ABSENT,
.input = { { .input = {{
.type = CX231XX_VMUX_TELEVISION, .type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1, .vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO, .amux = CX231XX_AMUX_VIDEO,
.gpio = 0, .gpio = 0,
}, { }, {
.type = CX231XX_VMUX_COMPOSITE1, .type =
.vmux = CX231XX_VIN_2_1, CX231XX_VMUX_COMPOSITE1,
.amux = CX231XX_AMUX_LINE_IN, .vmux = CX231XX_VIN_2_1,
.gpio = 0, .amux = CX231XX_AMUX_LINE_IN,
}, { .gpio = 0,
.type = CX231XX_VMUX_SVIDEO, }, {
.vmux = CX231XX_VIN_1_1 | (CX231XX_VIN_1_2 << 8 ) | .type =
CX25840_SVIDEO_ON, CX231XX_VMUX_SVIDEO,
.amux = CX231XX_AMUX_LINE_IN, .vmux =
.gpio = 0, CX231XX_VIN_1_1 |
} }, (CX231XX_VIN_1_2 << 8) |
}, CX25840_SVIDEO_ON,
.amux =
CX231XX_AMUX_LINE_IN,
.gpio = 0,
}},
},
[CX231XX_BOARD_CNXT_RDE_250] = { [CX231XX_BOARD_CNXT_RDE_250] = {
.name = "Conexant Hybrid TV - RDE250", .name = "Conexant Hybrid TV - RDE250",
.valid = CX231XX_BOARD_VALIDATED, .valid = CX231XX_BOARD_VALIDATED,
.tuner_type = TUNER_XC5000, .tuner_type = TUNER_XC5000,
.tuner_addr = 0x61, .tuner_addr = 0x61,
.tuner_gpio = RDE250_XCV_TUNER, .tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05, .tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a, .tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b, .tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER, .decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0, .demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4, .ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x0c, .agc_analog_digital_select_gpio = 0x0c,
.gpio_pin_status_mask = 0x4001000, .gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1, .tuner_i2c_master = 1,
.demod_i2c_master = 2, .demod_i2c_master = 2,
.has_dvb = 1, .has_dvb = 1,
.demod_addr = 0x02, .demod_addr = 0x02,
.norm = V4L2_STD_PAL, .norm = V4L2_STD_PAL,
.input = { { .input = {{
.type = CX231XX_VMUX_TELEVISION, .type =
.vmux = CX231XX_VIN_3_1, CX231XX_VMUX_TELEVISION,
.amux = CX231XX_AMUX_VIDEO, .vmux = CX231XX_VIN_3_1,
.gpio = 0, .amux = CX231XX_AMUX_VIDEO,
}, { .gpio = 0,
.type = CX231XX_VMUX_COMPOSITE1, }, {
.vmux = CX231XX_VIN_2_1, .type =
.amux = CX231XX_AMUX_LINE_IN, CX231XX_VMUX_COMPOSITE1,
.gpio = 0, .vmux = CX231XX_VIN_2_1,
}, { .amux =
.type = CX231XX_VMUX_SVIDEO, CX231XX_AMUX_LINE_IN,
.vmux = CX231XX_VIN_1_1 | (CX231XX_VIN_1_2 << 8 ) | .gpio = 0,
CX25840_SVIDEO_ON, }, {
.amux = CX231XX_AMUX_LINE_IN, .type =
.gpio = 0, CX231XX_VMUX_SVIDEO,
} }, .vmux =
}, CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 <<
[CX231XX_BOARD_CNXT_RDU_250] = { 8) |
.name = "Conexant Hybrid TV - RDU250", CX25840_SVIDEO_ON,
.valid = CX231XX_BOARD_VALIDATED, .amux =
.tuner_type = TUNER_XC5000, CX231XX_AMUX_LINE_IN,
.tuner_addr = 0x61, .gpio = 0,
.tuner_gpio = RDE250_XCV_TUNER, }},
.tuner_sif_gpio = 0x05, },
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b, [CX231XX_BOARD_CNXT_RDU_250] = {
.decoder = CX231XX_AVDECODER, .name = "Conexant Hybrid TV - RDU250",
.demod_xfer_mode = 0, .valid = CX231XX_BOARD_VALIDATED,
.ctl_pin_status_mask = 0xFFFFFFC4, .tuner_type = TUNER_XC5000,
.agc_analog_digital_select_gpio = 0x0c, .tuner_addr = 0x61,
.gpio_pin_status_mask = 0x4001000, .tuner_gpio = RDE250_XCV_TUNER,
.tuner_i2c_master = 1, .tuner_sif_gpio = 0x05,
.demod_i2c_master = 2, .tuner_scl_gpio = 0x1a,
.has_dvb = 1, .tuner_sda_gpio = 0x1b,
.demod_addr = 0x32, .decoder = CX231XX_AVDECODER,
.norm = V4L2_STD_NTSC, .demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.input = { { .agc_analog_digital_select_gpio = 0x0c,
.type = CX231XX_VMUX_TELEVISION, .gpio_pin_status_mask = 0x4001000,
.vmux = CX231XX_VIN_3_1, .tuner_i2c_master = 1,
.amux = CX231XX_AMUX_VIDEO, .demod_i2c_master = 2,
.gpio = 0, .has_dvb = 1,
}, { .demod_addr = 0x32,
.type = CX231XX_VMUX_COMPOSITE1, .norm = V4L2_STD_NTSC,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN, .input = {{
.gpio = 0, .type =
}, { CX231XX_VMUX_TELEVISION,
.type = CX231XX_VMUX_SVIDEO, .vmux = CX231XX_VIN_3_1,
.vmux = CX231XX_VIN_1_1 | (CX231XX_VIN_1_2 << 8 ) | .amux = CX231XX_AMUX_VIDEO,
CX25840_SVIDEO_ON, .gpio = 0,
.amux = CX231XX_AMUX_LINE_IN, }, {
.gpio = 0, .type =
} }, CX231XX_VMUX_COMPOSITE1,
}, .vmux = CX231XX_VIN_2_1,
.amux =
CX231XX_AMUX_LINE_IN,
.gpio = 0,
}, {
.type =
CX231XX_VMUX_SVIDEO,
.vmux =
CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 <<
8) |
CX25840_SVIDEO_ON,
.amux =
CX231XX_AMUX_LINE_IN,
.gpio = 0,
}},
},
}; };
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
/* table of devices that work with this driver */ /* table of devices that work with this driver */
struct usb_device_id cx231xx_id_table [] = { struct usb_device_id cx231xx_id_table[] = {
{ USB_DEVICE(0x0572, 0x58A0), {USB_DEVICE(0x0572, 0x58A0),
.driver_info = CX231XX_BOARD_UNKNOWN }, .driver_info = CX231XX_BOARD_UNKNOWN},
{ USB_DEVICE(0x0572, 0x58A2), {USB_DEVICE(0x0572, 0x58A2),
.driver_info = CX231XX_BOARD_CNXT_RDE_250 }, .driver_info = CX231XX_BOARD_CNXT_RDE_250},
{ USB_DEVICE(0x0572, 0x5A3C), {USB_DEVICE(0x0572, 0x5A3C),
.driver_info = CX231XX_BOARD_CNXT_RDU_250 }, .driver_info = CX231XX_BOARD_CNXT_RDU_250},
{ }, {},
}; };
MODULE_DEVICE_TABLE(usb, cx231xx_id_table); MODULE_DEVICE_TABLE(usb, cx231xx_id_table);
/* cx231xx_tuner_callback /* cx231xx_tuner_callback
...@@ -186,21 +206,26 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) ...@@ -186,21 +206,26 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
int rc = 0; int rc = 0;
struct cx231xx *dev = ptr; struct cx231xx *dev = ptr;
if (dev->tuner_type == TUNER_XC5000) { if (dev->tuner_type == TUNER_XC5000) {
if (command == XC5000_TUNER_RESET) { if (command == XC5000_TUNER_RESET) {
cx231xx_info("Tuner Call back : RESET : command %d : tuner type %d \n", cx231xx_info
command, dev->tuner_type); ("Tuner Call back : RESET : command %d : tuner type %d \n",
command, dev->tuner_type);
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,1);
msleep(10); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,0); 1);
msleep(330); msleep(10);
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,1); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
msleep(10); 0);
} msleep(330);
} cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
1);
msleep(10);
}
}
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(cx231xx_tuner_callback); EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
static void inline cx231xx_set_model(struct cx231xx *dev) static void inline cx231xx_set_model(struct cx231xx *dev)
...@@ -217,34 +242,34 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) ...@@ -217,34 +242,34 @@ void cx231xx_pre_card_setup(struct cx231xx *dev)
cx231xx_set_model(dev); cx231xx_set_model(dev);
cx231xx_info("Identified as %s (card=%d)\n", cx231xx_info("Identified as %s (card=%d)\n",
dev->board.name, dev->model); dev->board.name, dev->model);
/* Do card specific if any */ /* Do card specific if any */
switch (dev->model) { switch (dev->model) {
case CX231XX_BOARD_CNXT_RDE_250: case CX231XX_BOARD_CNXT_RDE_250:
/* do card specific GPIO settings if required */ /* do card specific GPIO settings if required */
cx231xx_info("Precard: Board is Conexnat RDE 250\n"); cx231xx_info("Precard: Board is Conexnat RDE 250\n");
/* set the direction for GPIO pins */ /* set the direction for GPIO pins */
cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit,1); cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,1); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio,1); cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
break; break;
case CX231XX_BOARD_CNXT_RDU_250: case CX231XX_BOARD_CNXT_RDU_250:
/* do card specific GPIO settings if required */ /* do card specific GPIO settings if required */
cx231xx_info("Precard: Board is Conexnat RDU 250\n"); cx231xx_info("Precard: Board is Conexnat RDU 250\n");
/* set the direction for GPIO pins */ /* set the direction for GPIO pins */
cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit,1); cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,1); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio,1); cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
break; break;
} }
/* request some modules if any required */ /* request some modules if any required */
/* reset the Tuner */ /* reset the Tuner */
cx231xx_gpio_set(dev, dev->board.tuner_gpio); cx231xx_gpio_set(dev, dev->board.tuner_gpio);
/* set the mode to Analog mode initially */ /* set the mode to Analog mode initially */
cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
/* Unlock device */ /* Unlock device */
...@@ -256,8 +281,8 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) ...@@ -256,8 +281,8 @@ void cx231xx_pre_card_setup(struct cx231xx *dev)
static void cx231xx_config_tuner(struct cx231xx *dev) static void cx231xx_config_tuner(struct cx231xx *dev)
{ {
struct tuner_setup tun_setup; struct tuner_setup tun_setup;
struct v4l2_frequency f; struct v4l2_frequency f;
if (dev->tuner_type == TUNER_ABSENT) if (dev->tuner_type == TUNER_ABSENT)
return; return;
...@@ -267,26 +292,28 @@ static void cx231xx_config_tuner(struct cx231xx *dev) ...@@ -267,26 +292,28 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
tun_setup.addr = dev->tuner_addr; tun_setup.addr = dev->tuner_addr;
tun_setup.tuner_callback = cx231xx_tuner_callback; tun_setup.tuner_callback = cx231xx_tuner_callback;
cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_TYPE_ADDR, &tun_setup); cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_TYPE_ADDR,
&tun_setup);
#if 0 #if 0
if (tun_setup.type == TUNER_XC5000) { if (tun_setup.type == TUNER_XC5000) {
static struct xc2028_ctrl ctrl = { static struct xc2028_ctrl ctrl = {
.fname = XC5000_DEFAULT_FIRMWARE, .fname = XC5000_DEFAULT_FIRMWARE,
.max_len = 64, .max_len = 64,
.demod = 0; .demod = 0;
}; };
struct v4l2_priv_tun_config cfg = { struct v4l2_priv_tun_config cfg = {
.tuner = dev->tuner_type, .tuner = dev->tuner_type,
.priv = &ctrl, .priv = &ctrl,
}; };
cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_CONFIG, &cfg); cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_CONFIG,
&cfg);
} }
#endif #endif
/* configure tuner */ /* configure tuner */
f.tuner = 0; f.tuner = 0;
f.type = V4L2_TUNER_ANALOG_TV; f.type = V4L2_TUNER_ANALOG_TV;
f.frequency = 9076; /* just a magic number */ f.frequency = 9076; /* just a magic number */
dev->ctl_freq = f.frequency; dev->ctl_freq = f.frequency;
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f);
} }
...@@ -298,18 +325,18 @@ void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir) ...@@ -298,18 +325,18 @@ void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
{ {
if (disable_ir) { if (disable_ir) {
ir->get_key = NULL; ir->get_key = NULL;
return ; return;
} }
/* detect & configure */ /* detect & configure */
switch (dev->model) { switch (dev->model) {
case CX231XX_BOARD_CNXT_RDE_250: case CX231XX_BOARD_CNXT_RDE_250:
break; break;
case CX231XX_BOARD_CNXT_RDU_250: case CX231XX_BOARD_CNXT_RDU_250:
break; break;
default: default:
break; break;
} }
} }
...@@ -321,58 +348,55 @@ void cx231xx_card_setup(struct cx231xx *dev) ...@@ -321,58 +348,55 @@ void cx231xx_card_setup(struct cx231xx *dev)
if (cx231xx_boards[dev->model].tuner_addr) if (cx231xx_boards[dev->model].tuner_addr)
dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr; dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;
cx231xx_info(": tuner type %d, tuner address %d \n", cx231xx_info(": tuner type %d, tuner address %d \n",
dev->tuner_type, dev->tuner_addr); dev->tuner_type, dev->tuner_addr);
/* Do card specific if any */ /* Do card specific if any */
switch (dev->model) { switch (dev->model) {
case CX231XX_BOARD_CNXT_RDE_250: case CX231XX_BOARD_CNXT_RDE_250:
/* do card specific GPIO settings if required */ /* do card specific GPIO settings if required */
cx231xx_info("Board is Conexnat RDE 250\n"); cx231xx_info("Board is Conexnat RDE 250\n");
break; break;
case CX231XX_BOARD_CNXT_RDU_250: case CX231XX_BOARD_CNXT_RDU_250:
/* do card specific GPIO settings if required */ /* do card specific GPIO settings if required */
cx231xx_info("Board is Conexnat RDU 250\n"); cx231xx_info("Board is Conexnat RDU 250\n");
break; break;
} }
if (dev->board.valid == CX231XX_BOARD_NOT_VALIDATED) { if (dev->board.valid == CX231XX_BOARD_NOT_VALIDATED) {
cx231xx_errdev("\n\n"); cx231xx_errdev("\n\n");
cx231xx_errdev("The support for this board weren't " cx231xx_errdev("The support for this board weren't "
"valid yet.\n"); "valid yet.\n");
cx231xx_errdev("Please send a report of having this working\n"); cx231xx_errdev("Please send a report of having this working\n");
cx231xx_errdev("not to V4L mailing list (and/or to other " cx231xx_errdev("not to V4L mailing list (and/or to other "
"addresses)\n\n"); "addresses)\n\n");
} }
/* request some modules */ /* request some modules */
if (dev->board.decoder == CX231XX_AVDECODER) { if (dev->board.decoder == CX231XX_AVDECODER) {
cx231xx_info(": Requesting cx25840 module\n"); cx231xx_info(": Requesting cx25840 module\n");
request_module("cx25840"); request_module("cx25840");
} }
#if 0 #if 0
if (dev->board.tuner_type != TUNER_ABSENT) { if (dev->board.tuner_type != TUNER_ABSENT) {
cx231xx_info(": Requesting Tuner module\n"); cx231xx_info(": Requesting Tuner module\n");
request_module("tuner"); request_module("tuner");
} }
cx231xx_config_tuner(dev); cx231xx_config_tuner(dev);
/* TBD IR will be added later */ /* TBD IR will be added later */
cx231xx_ir_init(dev); cx231xx_ir_init(dev);
#endif #endif
} }
/* /*
* cx231xx_config() * cx231xx_config()
* inits registers with sane defaults * inits registers with sane defaults
*/ */
int cx231xx_config(struct cx231xx *dev) int cx231xx_config(struct cx231xx *dev)
{ {
/* TBD need to add cx231xx specific code */ /* TBD need to add cx231xx specific code */
dev->mute = 1; /* maybe not the right place... */ dev->mute = 1; /* maybe not the right place... */
dev->volume = 0x1f; dev->volume = 0x1f;
...@@ -401,30 +425,29 @@ void cx231xx_config_i2c(struct cx231xx *dev) ...@@ -401,30 +425,29 @@ void cx231xx_config_i2c(struct cx231xx *dev)
void cx231xx_release_resources(struct cx231xx *dev) void cx231xx_release_resources(struct cx231xx *dev)
{ {
#if 0 /* TBD IR related */ #if 0 /* TBD IR related */
if (dev->ir) if (dev->ir)
cx231xx_ir_fini(dev); cx231xx_ir_fini(dev);
#endif #endif
cx231xx_release_analog_resources(dev); cx231xx_release_analog_resources(dev);
cx231xx_remove_from_devlist(dev); cx231xx_remove_from_devlist(dev);
cx231xx_dev_uninit(dev); cx231xx_dev_uninit(dev);
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
/* Mark device as unused */ /* Mark device as unused */
cx231xx_devused &= ~(1<<dev->devno); cx231xx_devused &= ~(1 << dev->devno);
} }
/* /*
* cx231xx_init_dev() * cx231xx_init_dev()
* allocates and inits the device structs, registers i2c bus and v4l device * allocates and inits the device structs, registers i2c bus and v4l device
*/ */
static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
int minor) int minor)
{ {
struct cx231xx *dev = *devhandle; struct cx231xx *dev = *devhandle;
int retval = -ENOMEM; int retval = -ENOMEM;
...@@ -434,26 +457,26 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -434,26 +457,26 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
dev->udev = udev; dev->udev = udev;
mutex_init(&dev->lock); mutex_init(&dev->lock);
mutex_init(&dev->ctrl_urb_lock); mutex_init(&dev->ctrl_urb_lock);
mutex_init(&dev->gpio_i2c_lock); mutex_init(&dev->gpio_i2c_lock);
spin_lock_init(&dev->video_mode.slock); spin_lock_init(&dev->video_mode.slock);
spin_lock_init(&dev->vbi_mode.slock); spin_lock_init(&dev->vbi_mode.slock);
spin_lock_init(&dev->sliced_cc_mode.slock); spin_lock_init(&dev->sliced_cc_mode.slock);
init_waitqueue_head(&dev->open); init_waitqueue_head(&dev->open);
init_waitqueue_head(&dev->wait_frame); init_waitqueue_head(&dev->wait_frame);
init_waitqueue_head(&dev->wait_stream); init_waitqueue_head(&dev->wait_stream);
dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg; dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg;
dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg; dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg;
dev->cx231xx_send_usb_command = cx231xx_send_usb_command; dev->cx231xx_send_usb_command = cx231xx_send_usb_command;
dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read; dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read;
dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write; dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
/* Query cx231xx to find what pcb config it is related to */ /* Query cx231xx to find what pcb config it is related to */
initialize_cx231xx(dev); initialize_cx231xx(dev);
/* Cx231xx pre card setup */ /* Cx231xx pre card setup */
cx231xx_pre_card_setup(dev); cx231xx_pre_card_setup(dev);
errCode = cx231xx_config(dev); errCode = cx231xx_config(dev);
...@@ -462,14 +485,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -462,14 +485,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
return -ENOMEM; return -ENOMEM;
} }
/* set default norm */ /* set default norm */
dev->norm = dev->board.norm; dev->norm = dev->board.norm;
/* register i2c bus */ /* register i2c bus */
errCode = cx231xx_dev_init(dev); errCode = cx231xx_dev_init(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
__func__, errCode); __func__, errCode);
return errCode; return errCode;
} }
...@@ -493,7 +516,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -493,7 +516,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
errCode = cx231xx_config(dev); errCode = cx231xx_config(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
__func__, errCode); __func__, errCode);
return errCode; return errCode;
} }
...@@ -501,13 +524,13 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -501,13 +524,13 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
INIT_LIST_HEAD(&dev->video_mode.vidq.active); INIT_LIST_HEAD(&dev->video_mode.vidq.active);
INIT_LIST_HEAD(&dev->video_mode.vidq.queued); INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
/* init vbi dma queues */ /* init vbi dma queues */
INIT_LIST_HEAD(&dev->vbi_mode.vidq.active); INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued); INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
/* Reset other chips required if they are tied up with GPIO pins */ /* Reset other chips required if they are tied up with GPIO pins */
cx231xx_add_into_devlist(dev); cx231xx_add_into_devlist(dev);
retval = cx231xx_register_analog_devices(dev); retval = cx231xx_register_analog_devices(dev);
if (retval < 0) { if (retval < 0) {
...@@ -519,7 +542,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -519,7 +542,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
return 0; return 0;
fail_reg_devices: fail_reg_devices:
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return retval; return retval;
} }
...@@ -528,8 +551,7 @@ fail_reg_devices: ...@@ -528,8 +551,7 @@ fail_reg_devices:
static void request_module_async(struct work_struct *work) static void request_module_async(struct work_struct *work)
{ {
struct cx231xx *dev = container_of(work, struct cx231xx *dev = container_of(work,
struct cx231xx, request_module_wk); struct cx231xx, request_module_wk);
if (dev->has_alsa_audio) if (dev->has_alsa_audio)
request_module("cx231xx-alsa"); request_module("cx231xx-alsa");
...@@ -548,130 +570,130 @@ static void request_modules(struct cx231xx *dev) ...@@ -548,130 +570,130 @@ static void request_modules(struct cx231xx *dev)
#define request_modules(dev) #define request_modules(dev)
#endif /* CONFIG_MODULES */ #endif /* CONFIG_MODULES */
/* /*
* cx231xx_usb_probe() * cx231xx_usb_probe()
* checks for supported devices * checks for supported devices
*/ */
static int cx231xx_usb_probe(struct usb_interface *interface, static int cx231xx_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *uif; struct usb_interface *uif;
struct cx231xx *dev = NULL; struct cx231xx *dev = NULL;
int retval = -ENODEV; int retval = -ENODEV;
int nr, ifnum; int nr, ifnum;
int i, isoc_pipe = 0; int i, isoc_pipe = 0;
char *speed; char *speed;
char descr[255] = ""; char descr[255] = "";
struct usb_interface *lif = NULL; struct usb_interface *lif = NULL;
int skip_interface = 0; int skip_interface = 0;
struct usb_interface_assoc_descriptor *assoc_desc; struct usb_interface_assoc_descriptor *assoc_desc;
udev = usb_get_dev(interface_to_usbdev(interface)); udev = usb_get_dev(interface_to_usbdev(interface));
ifnum = interface->altsetting[0].desc.bInterfaceNumber; ifnum = interface->altsetting[0].desc.bInterfaceNumber;
cx231xx_info(": Interface Number %d\n", ifnum); cx231xx_info(": Interface Number %d\n", ifnum);
/* Interface number 0 - IR interface */ /* Interface number 0 - IR interface */
if(ifnum == 0 ){ if (ifnum == 0) {
/* Check to see next free device and mark as used */ /* Check to see next free device and mark as used */
nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
cx231xx_devused |= 1<<nr; cx231xx_devused |= 1 << nr;
if (nr >= CX231XX_MAXBOARDS) { if (nr >= CX231XX_MAXBOARDS) {
cx231xx_info(": Supports only %i cx231xx boards.\n", cx231xx_info(": Supports only %i cx231xx boards.\n",
CX231XX_MAXBOARDS); CX231XX_MAXBOARDS);
cx231xx_devused &= ~(1<<nr); cx231xx_devused &= ~(1 << nr);
return -ENOMEM; return -ENOMEM;
} }
/* allocate memory for our device state and initialize it */ /* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL); dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) { if (dev == NULL) {
cx231xx_err(DRIVER_NAME ": out of memory!\n"); cx231xx_err(DRIVER_NAME ": out of memory!\n");
cx231xx_devused &= ~(1<<nr); cx231xx_devused &= ~(1 << nr);
return -ENOMEM; return -ENOMEM;
} }
snprintf(dev->name, 29, "cx231xx #%d", nr); snprintf(dev->name, 29, "cx231xx #%d", nr);
dev->devno = nr; dev->devno = nr;
dev->model = id->driver_info; dev->model = id->driver_info;
dev->video_mode.alt = -1; dev->video_mode.alt = -1;
dev->interface_count++; dev->interface_count++;
/* reset gpio dir and value */ /* reset gpio dir and value */
dev->gpio_dir = 0; dev->gpio_dir = 0;
dev->gpio_val = 0; dev->gpio_val = 0;
dev->xc_fw_load_done = 0; dev->xc_fw_load_done = 0;
dev->has_alsa_audio = 1; dev->has_alsa_audio = 1;
dev->power_mode = -1; dev->power_mode = -1;
dev->vbi_or_sliced_cc_mode = 0; /* 0 - vbi ; 1 -sliced cc mode */ dev->vbi_or_sliced_cc_mode = 0; /* 0 - vbi ; 1 -sliced cc mode */
/* get maximum no.of IAD interfaces */ /* get maximum no.of IAD interfaces */
assoc_desc = udev->actconfig->intf_assoc[0]; assoc_desc = udev->actconfig->intf_assoc[0];
dev->max_iad_interface_count = assoc_desc->bInterfaceCount; dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
cx231xx_info(": Found IAD interface count %d\n", dev->max_iad_interface_count); cx231xx_info(": Found IAD interface count %d\n",
dev->max_iad_interface_count);
/* init CIR module TBD */
/* init CIR module TBD */
/* store the current interface */
lif = interface; /* store the current interface */
lif = interface;
}
else if(ifnum == 1 ){ } else if (ifnum == 1) {
/* Get dev structure first */ /* Get dev structure first */
dev = usb_get_intfdata(udev->actconfig->interface[0]); dev = usb_get_intfdata(udev->actconfig->interface[0]);
if(dev == NULL){ if (dev == NULL) {
cx231xx_err(DRIVER_NAME ": out of first interface!\n"); cx231xx_err(DRIVER_NAME ": out of first interface!\n");
return -ENODEV; return -ENODEV;
} }
/* store the interface 0 back */ /* store the interface 0 back */
lif = udev->actconfig->interface[0]; lif = udev->actconfig->interface[0];
/* increment interface count */ /* increment interface count */
dev->interface_count++; dev->interface_count++;
/* get device number */ /* get device number */
nr = dev->devno; nr = dev->devno;
assoc_desc = udev->actconfig->intf_assoc[0]; assoc_desc = udev->actconfig->intf_assoc[0];
if(assoc_desc->bFirstInterface == ifnum){ if (assoc_desc->bFirstInterface == ifnum) {
cx231xx_info(": Found IAD interface match: AV Descriptor Start!! \n"); cx231xx_info
} else { (": Found IAD interface match: AV Descriptor Start!! \n");
cx231xx_err(DRIVER_NAME " Not found matching interface\n"); } else {
return -ENODEV; cx231xx_err(DRIVER_NAME
} " Not found matching interface\n");
return -ENODEV;
} }
else if(ifnum >= 2) {
/* Get dev structure first */ } else if (ifnum >= 2) {
dev = usb_get_intfdata(udev->actconfig->interface[0]); /* Get dev structure first */
if(dev == NULL){ dev = usb_get_intfdata(udev->actconfig->interface[0]);
cx231xx_err(DRIVER_NAME ": out of first interface!\n"); if (dev == NULL) {
return -ENODEV; cx231xx_err(DRIVER_NAME ": out of first interface!\n");
} return -ENODEV;
}
/* store the interface 0 back */
lif = udev->actconfig->interface[0]; /* store the interface 0 back */
lif = udev->actconfig->interface[0];
/* increment interface count */
dev->interface_count++; /* increment interface count */
dev->interface_count++;
/* get device number */
nr = dev->devno; /* get device number */
nr = dev->devno;
/* set skip interface */
if((dev->interface_count -1) != dev->max_iad_interface_count ) /* set skip interface */
skip_interface = 1; /* set skipping */ if ((dev->interface_count - 1) != dev->max_iad_interface_count)
else{ skip_interface = 1; /* set skipping */
cx231xx_info(": Found IAD interface number match with AV Device number!! \n"); else {
} cx231xx_info
} (": Found IAD interface number match with AV Device number!! \n");
}
}
switch (udev->speed) { switch (udev->speed) {
case USB_SPEED_LOW: case USB_SPEED_LOW:
...@@ -700,153 +722,184 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -700,153 +722,184 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
strlcat(descr, " ", sizeof(descr)); strlcat(descr, " ", sizeof(descr));
cx231xx_info("New device %s@ %s Mbps " cx231xx_info("New device %s@ %s Mbps "
"(%04x:%04x, interface %d, class %d)\n", "(%04x:%04x, interface %d, class %d)\n",
descr, descr,
speed, speed,
le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct), le16_to_cpu(udev->descriptor.idProduct),
ifnum, ifnum, interface->altsetting->desc.bInterfaceNumber);
interface->altsetting->desc.bInterfaceNumber);
/* AV device initialization */
/* AV device initialization */ if ((dev->interface_count - 1) == dev->max_iad_interface_count) {
if((dev->interface_count -1) == dev->max_iad_interface_count ) { cx231xx_info(" Calling init_dev\n");
cx231xx_info(" Calling init_dev\n"); /* allocate device struct */
/* allocate device struct */ retval = cx231xx_init_dev(&dev, udev, nr);
retval = cx231xx_init_dev(&dev, udev, nr); if (retval) {
if (retval) { cx231xx_devused &= ~(1 << dev->devno);
cx231xx_devused &= ~(1<<dev->devno); kfree(dev);
kfree(dev);
return retval;
return retval; }
}
/* compute alternate max packet sizes for video */
/* compute alternate max packet sizes for video */ uif =
uif = udev->actconfig->interface[dev->current_pcb_config.hs_config_info[0].interface_info.video_index+1]; udev->actconfig->interface[dev->current_pcb_config.
hs_config_info[0].interface_info.
dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress); video_index + 1];
dev->video_mode.num_alt = uif->num_altsetting; dev->video_mode.end_point_addr =
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n", dev->video_mode.end_point_addr, le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
dev->video_mode.num_alt); bEndpointAddress);
dev->video_mode.alt_max_pkt_size = kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
dev->video_mode.num_alt = uif->num_altsetting;
if (dev->video_mode.alt_max_pkt_size == NULL) { cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n",
cx231xx_errdev("out of memory!\n"); dev->video_mode.end_point_addr,
cx231xx_devused &= ~(1<<nr); dev->video_mode.num_alt);
kfree(dev); dev->video_mode.alt_max_pkt_size =
return -ENOMEM; kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
}
if (dev->video_mode.alt_max_pkt_size == NULL) {
for (i = 0; i < dev->video_mode.num_alt ; i++) { cx231xx_errdev("out of memory!\n");
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. cx231xx_devused &= ~(1 << nr);
wMaxPacketSize); kfree(dev);
dev->video_mode.alt_max_pkt_size[i] = return -ENOMEM;
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); }
cx231xx_info("Alternate setting %i, max size= %i\n", i,
dev->video_mode.alt_max_pkt_size[i]); for (i = 0; i < dev->video_mode.num_alt; i++) {
} u16 tmp =
le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
desc.wMaxPacketSize);
/* compute alternate max packet sizes for vbi */ dev->video_mode.alt_max_pkt_size[i] =
uif = udev->actconfig->interface[dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index+1]; (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
cx231xx_info("Alternate setting %i, max size= %i\n", i,
dev->vbi_mode.end_point_addr = dev->video_mode.alt_max_pkt_size[i]);
le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress); }
dev->vbi_mode.num_alt = uif->num_altsetting; /* compute alternate max packet sizes for vbi */
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n", dev->vbi_mode.end_point_addr, uif =
dev->vbi_mode.num_alt); udev->actconfig->interface[dev->current_pcb_config.
dev->vbi_mode.alt_max_pkt_size = kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL); hs_config_info[0].interface_info.
vanc_index + 1];
if (dev->vbi_mode.alt_max_pkt_size == NULL) {
cx231xx_errdev("out of memory!\n"); dev->vbi_mode.end_point_addr =
cx231xx_devused &= ~(1<<nr); le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
kfree(dev); bEndpointAddress);
return -ENOMEM;
} dev->vbi_mode.num_alt = uif->num_altsetting;
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n",
for (i = 0; i < dev->vbi_mode.num_alt ; i++) { dev->vbi_mode.end_point_addr,
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. dev->vbi_mode.num_alt);
wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size =
dev->vbi_mode.alt_max_pkt_size[i] = kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL);
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
cx231xx_info("Alternate setting %i, max size= %i\n", i, if (dev->vbi_mode.alt_max_pkt_size == NULL) {
dev->vbi_mode.alt_max_pkt_size[i]); cx231xx_errdev("out of memory!\n");
} cx231xx_devused &= ~(1 << nr);
kfree(dev);
/* compute alternate max packet sizes for sliced CC */ return -ENOMEM;
uif = udev->actconfig->interface[dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index+1]; }
dev->sliced_cc_mode.end_point_addr = for (i = 0; i < dev->vbi_mode.num_alt; i++) {
le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress); u16 tmp =
le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
dev->sliced_cc_mode.num_alt = uif->num_altsetting; desc.wMaxPacketSize);
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n", dev->sliced_cc_mode.end_point_addr, dev->vbi_mode.alt_max_pkt_size[i] =
dev->sliced_cc_mode.num_alt); (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
dev->sliced_cc_mode.alt_max_pkt_size = kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL); cx231xx_info("Alternate setting %i, max size= %i\n", i,
dev->vbi_mode.alt_max_pkt_size[i]);
if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { }
cx231xx_errdev("out of memory!\n");
cx231xx_devused &= ~(1<<nr); /* compute alternate max packet sizes for sliced CC */
kfree(dev); uif =
return -ENOMEM; udev->actconfig->interface[dev->current_pcb_config.
} hs_config_info[0].interface_info.
hanc_index + 1];
for (i = 0; i < dev->sliced_cc_mode.num_alt ; i++) {
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. dev->sliced_cc_mode.end_point_addr =
wMaxPacketSize); le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
dev->sliced_cc_mode.alt_max_pkt_size[i] = bEndpointAddress);
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
cx231xx_info("Alternate setting %i, max size= %i\n", i, dev->sliced_cc_mode.num_alt = uif->num_altsetting;
dev->sliced_cc_mode.alt_max_pkt_size[i]); cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n",
} dev->sliced_cc_mode.end_point_addr,
dev->sliced_cc_mode.num_alt);
if(dev->current_pcb_config.ts1_source != 0xff ) { dev->sliced_cc_mode.alt_max_pkt_size =
kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL);
/* compute alternate max packet sizes for TS1 */
uif = udev->actconfig->interface[dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index+1]; if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
cx231xx_errdev("out of memory!\n");
dev->ts1_mode.end_point_addr = cx231xx_devused &= ~(1 << nr);
le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress); kfree(dev);
return -ENOMEM;
dev->ts1_mode.num_alt = uif->num_altsetting; }
cx231xx_info(": EndPoint Addr 0x%x, Alternate settings: %i\n", dev->ts1_mode.end_point_addr,
dev->ts1_mode.num_alt); for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
dev->ts1_mode.alt_max_pkt_size = kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL); u16 tmp =
le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
if (dev->ts1_mode.alt_max_pkt_size == NULL) { desc.wMaxPacketSize);
cx231xx_errdev("out of memory!\n"); dev->sliced_cc_mode.alt_max_pkt_size[i] =
cx231xx_devused &= ~(1<<nr); (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
kfree(dev); cx231xx_info("Alternate setting %i, max size= %i\n", i,
return -ENOMEM; dev->sliced_cc_mode.alt_max_pkt_size[i]);
} }
for (i = 0; i < dev->ts1_mode.num_alt ; i++) { if (dev->current_pcb_config.ts1_source != 0xff) {
u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
wMaxPacketSize); /* compute alternate max packet sizes for TS1 */
dev->ts1_mode.alt_max_pkt_size[i] = uif =
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); udev->actconfig->interface[dev->current_pcb_config.
cx231xx_info("Alternate setting %i, max size= %i\n", i, hs_config_info[0].
dev->ts1_mode.alt_max_pkt_size[i]); interface_info.
} ts1_index + 1];
}
dev->ts1_mode.end_point_addr =
} le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
desc.bEndpointAddress);
dev->ts1_mode.num_alt = uif->num_altsetting;
cx231xx_info
(": EndPoint Addr 0x%x, Alternate settings: %i\n",
dev->ts1_mode.end_point_addr,
dev->ts1_mode.num_alt);
dev->ts1_mode.alt_max_pkt_size =
kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL);
if (dev->ts1_mode.alt_max_pkt_size == NULL) {
cx231xx_errdev("out of memory!\n");
cx231xx_devused &= ~(1 << nr);
kfree(dev);
return -ENOMEM;
}
for (i = 0; i < dev->ts1_mode.num_alt; i++) {
u16 tmp =
le16_to_cpu(uif->altsetting[i].
endpoint[isoc_pipe].desc.
wMaxPacketSize);
dev->ts1_mode.alt_max_pkt_size[i] =
(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) +
1);
cx231xx_info
("Alternate setting %i, max size= %i\n", i,
dev->ts1_mode.alt_max_pkt_size[i]);
}
}
}
/* save our data pointer in this interface device */ /* save our data pointer in this interface device */
usb_set_intfdata(lif, dev); usb_set_intfdata(lif, dev);
/* load other modules required */ /* load other modules required */
if((dev->interface_count -1) == dev->max_iad_interface_count ) if ((dev->interface_count - 1) == dev->max_iad_interface_count) {
{ cx231xx_info("Calling request modules\n");
cx231xx_info("Calling request modules\n"); request_modules(dev);
request_modules(dev); }
}
if(skip_interface ) { if (skip_interface) {
cx231xx_info("Skipping the interface\n"); cx231xx_info("Skipping the interface\n");
return -ENODEV; return -ENODEV;
} }
return 0; return 0;
} }
...@@ -860,7 +913,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -860,7 +913,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
{ {
struct cx231xx *dev; struct cx231xx *dev;
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
if (!dev) if (!dev)
...@@ -875,8 +928,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -875,8 +928,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
if (dev->users) { if (dev->users) {
cx231xx_warn cx231xx_warn
("device /dev/video%d is open! Deregistration and memory " ("device /dev/video%d is open! Deregistration and memory "
"deallocation are deferred on close.\n", "deallocation are deferred on close.\n", dev->vdev->num);
dev->vdev->num);
dev->state |= DEV_MISCONFIGURED; dev->state |= DEV_MISCONFIGURED;
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
...@@ -888,15 +940,15 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -888,15 +940,15 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
cx231xx_release_resources(dev); cx231xx_release_resources(dev);
} }
cx231xx_close_extension(dev); cx231xx_close_extension(dev);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
if (!dev->users) { if (!dev->users) {
kfree(dev->video_mode.alt_max_pkt_size); kfree(dev->video_mode.alt_max_pkt_size);
kfree(dev->vbi_mode.alt_max_pkt_size); kfree(dev->vbi_mode.alt_max_pkt_size);
kfree(dev->sliced_cc_mode.alt_max_pkt_size); kfree(dev->sliced_cc_mode.alt_max_pkt_size);
kfree(dev->ts1_mode.alt_max_pkt_size); kfree(dev->ts1_mode.alt_max_pkt_size);
kfree(dev); kfree(dev);
} }
} }
...@@ -920,7 +972,7 @@ static int __init cx231xx_module_init(void) ...@@ -920,7 +972,7 @@ static int __init cx231xx_module_init(void)
result = usb_register(&cx231xx_usb_driver); result = usb_register(&cx231xx_usb_driver);
if (result) if (result)
cx231xx_err(DRIVER_NAME cx231xx_err(DRIVER_NAME
" usb_register failed. Error number %d.\n", result); " usb_register failed. Error number %d.\n", result);
return result; return result;
} }
......
/* /*
cx231xx_conf-reg.h - driver for Conexant Cx23100/101/102 USB cx231xx_conf-reg.h - driver for Conexant Cx23100/101/102 USB
video capture devices video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef _POLARIS_REG_H_ #ifndef _POLARIS_REG_H_
#define _POLARIS_REG_H_ #define _POLARIS_REG_H_
...@@ -43,30 +42,30 @@ ...@@ -43,30 +42,30 @@
#define PWR_CTL_EN 0x74 #define PWR_CTL_EN 0x74
/* Polaris Endpoints capture mask for register EP_MODE_SET */ /* Polaris Endpoints capture mask for register EP_MODE_SET */
#define ENABLE_EP1 0x01 /* Bit[0]=1 */ #define ENABLE_EP1 0x01 /* Bit[0]=1 */
#define ENABLE_EP2 0x02 /* Bit[1]=1 */ #define ENABLE_EP2 0x02 /* Bit[1]=1 */
#define ENABLE_EP3 0x04 /* Bit[2]=1 */ #define ENABLE_EP3 0x04 /* Bit[2]=1 */
#define ENABLE_EP4 0x08 /* Bit[3]=1 */ #define ENABLE_EP4 0x08 /* Bit[3]=1 */
#define ENABLE_EP5 0x10 /* Bit[4]=1 */ #define ENABLE_EP5 0x10 /* Bit[4]=1 */
#define ENABLE_EP6 0x20 /* Bit[5]=1 */ #define ENABLE_EP6 0x20 /* Bit[5]=1 */
/* Bit definition for register PWR_CTL_EN */ /* Bit definition for register PWR_CTL_EN */
#define PWR_MODE_MASK 0x17f #define PWR_MODE_MASK 0x17f
#define PWR_AV_EN 0x08 /* bit3 */ #define PWR_AV_EN 0x08 /* bit3 */
#define PWR_ISO_EN 0x40 /* bit6 */ #define PWR_ISO_EN 0x40 /* bit6 */
#define PWR_AV_MODE 0x30 /* bit4,5 */ #define PWR_AV_MODE 0x30 /* bit4,5 */
#define PWR_TUNER_EN 0x04 /* bit2 */ #define PWR_TUNER_EN 0x04 /* bit2 */
#define PWR_DEMOD_EN 0x02 /* bit1 */ #define PWR_DEMOD_EN 0x02 /* bit1 */
#define I2C_DEMOD_EN 0x01 /* bit0 */ #define I2C_DEMOD_EN 0x01 /* bit0 */
#define PWR_RESETOUT_EN 0x100 /* bit8 */ #define PWR_RESETOUT_EN 0x100 /* bit8 */
typedef enum{ typedef enum {
POLARIS_AVMODE_DEFAULT = 0, POLARIS_AVMODE_DEFAULT = 0,
POLARIS_AVMODE_DIGITAL = 0x10, POLARIS_AVMODE_DIGITAL = 0x10,
POLARIS_AVMODE_ANALOGT_TV = 0x20, POLARIS_AVMODE_ANALOGT_TV = 0x20,
POLARIS_AVMODE_ENXTERNAL_AV = 0x30, POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
}AV_MODE; } AV_MODE;
/* Colibri Registers */ /* Colibri Registers */
...@@ -75,8 +74,6 @@ typedef enum{ ...@@ -75,8 +74,6 @@ typedef enum{
#define EU_IF 0x9 #define EU_IF 0x9
#define US_IF 0xa #define US_IF 0xa
#define SUP_BLK_TUNE1 0x00 #define SUP_BLK_TUNE1 0x00
#define SUP_BLK_TUNE2 0x01 #define SUP_BLK_TUNE2 0x01
#define SUP_BLK_TUNE3 0x02 #define SUP_BLK_TUNE3 0x02
...@@ -129,7 +126,7 @@ typedef enum{ ...@@ -129,7 +126,7 @@ typedef enum{
#define ADC_INPUT_CH1 0x28 #define ADC_INPUT_CH1 0x28
#define ADC_INPUT_CH2 0x48 #define ADC_INPUT_CH2 0x48
#define ADC_INPUT_CH3 0x68 #define ADC_INPUT_CH3 0x68
#define INPUT_SEL_MASK 0x30 /* [5:4] in_sel */ #define INPUT_SEL_MASK 0x30 /* [5:4] in_sel */
#define ADC_NTF_PRECLMP_EN_CH1 0x29 #define ADC_NTF_PRECLMP_EN_CH1 0x29
#define ADC_NTF_PRECLMP_EN_CH2 0x49 #define ADC_NTF_PRECLMP_EN_CH2 0x49
...@@ -148,12 +145,12 @@ typedef enum{ ...@@ -148,12 +145,12 @@ typedef enum{
#define TESTBUS_CTRL_CH3 0x72 #define TESTBUS_CTRL_CH3 0x72
/****************************************************************************** /******************************************************************************
* DIF registers * * DIF registers *
******************************************************************************/ ******************************************************************************/
#define DIRECT_IF_REVB_BASE 0x00300 #define DIRECT_IF_REVB_BASE 0x00300
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_FREQ_WORD (DIRECT_IF_REVB_BASE + 0x00000000) /* Reg Size 32 */ #define DIF_PLL_FREQ_WORD (DIRECT_IF_REVB_BASE + 0x00000000) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_PLL_LOCK 0x80000000 #define FLD_DIF_PLL_LOCK 0x80000000
/* Reserved [30:29] */ /* Reserved [30:29] */
...@@ -161,7 +158,7 @@ typedef enum{ ...@@ -161,7 +158,7 @@ typedef enum{
#define FLD_DIF_PLL_FREQ 0x0FFFFFFF #define FLD_DIF_PLL_FREQ 0x0FFFFFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_CTRL (DIRECT_IF_REVB_BASE + 0x00000004) /* Reg Size 32 */ #define DIF_PLL_CTRL (DIRECT_IF_REVB_BASE + 0x00000004) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_KD_PD 0xFF000000 #define FLD_DIF_KD_PD 0xFF000000
/* Reserved [23:20] */ /* Reserved [23:20] */
...@@ -171,7 +168,7 @@ typedef enum{ ...@@ -171,7 +168,7 @@ typedef enum{
#define FLD_DIF_KIS_PD 0x0000000F #define FLD_DIF_KIS_PD 0x0000000F
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_CTRL1 (DIRECT_IF_REVB_BASE + 0x00000008) /* Reg Size 32 */ #define DIF_PLL_CTRL1 (DIRECT_IF_REVB_BASE + 0x00000008) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_KD_FD 0xFF000000 #define FLD_DIF_KD_FD 0xFF000000
/* Reserved [23:20] */ /* Reserved [23:20] */
...@@ -181,7 +178,7 @@ typedef enum{ ...@@ -181,7 +178,7 @@ typedef enum{
#define FLD_DIF_KIS_FD 0x0000000F #define FLD_DIF_KIS_FD 0x0000000F
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_CTRL2 (DIRECT_IF_REVB_BASE + 0x0000000C) /* Reg Size 32 */ #define DIF_PLL_CTRL2 (DIRECT_IF_REVB_BASE + 0x0000000C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_PLL_AGC_REF 0xFFF00000 #define FLD_DIF_PLL_AGC_REF 0xFFF00000
#define FLD_DIF_PLL_AGC_KI 0x000F0000 #define FLD_DIF_PLL_AGC_KI 0x000F0000
...@@ -191,7 +188,7 @@ typedef enum{ ...@@ -191,7 +188,7 @@ typedef enum{
#define FLD_DIF_DOWNSMPL_FD 0x000000FF #define FLD_DIF_DOWNSMPL_FD 0x000000FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_CTRL3 (DIRECT_IF_REVB_BASE + 0x00000010) /* Reg Size 32 */ #define DIF_PLL_CTRL3 (DIRECT_IF_REVB_BASE + 0x00000010) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:16] */ /* Reserved [31:16] */
#define FLD_DIF_PLL_AGC_EN 0x00008000 #define FLD_DIF_PLL_AGC_EN 0x00008000
...@@ -199,7 +196,7 @@ typedef enum{ ...@@ -199,7 +196,7 @@ typedef enum{
#define FLD_DIF_PLL_MAN_GAIN 0x00000FFF #define FLD_DIF_PLL_MAN_GAIN 0x00000FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_IF_REF (DIRECT_IF_REVB_BASE + 0x00000014) /* Reg Size 32 */ #define DIF_AGC_IF_REF (DIRECT_IF_REVB_BASE + 0x00000014) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_K_AGC_RF 0xF0000000 #define FLD_DIF_K_AGC_RF 0xF0000000
#define FLD_DIF_K_AGC_IF 0x0F000000 #define FLD_DIF_K_AGC_IF 0x0F000000
...@@ -208,40 +205,40 @@ typedef enum{ ...@@ -208,40 +205,40 @@ typedef enum{
#define FLD_DIF_IF_REF 0x00000FFF #define FLD_DIF_IF_REF 0x00000FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_CTRL_IF (DIRECT_IF_REVB_BASE + 0x00000018) /* Reg Size 32 */ #define DIF_AGC_CTRL_IF (DIRECT_IF_REVB_BASE + 0x00000018) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_IF_MAX 0xFF000000 #define FLD_DIF_IF_MAX 0xFF000000
#define FLD_DIF_IF_MIN 0x00FF0000 #define FLD_DIF_IF_MIN 0x00FF0000
#define FLD_DIF_IF_AGC 0x0000FFFF #define FLD_DIF_IF_AGC 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_CTRL_INT (DIRECT_IF_REVB_BASE + 0x0000001C) /* Reg Size 32 */ #define DIF_AGC_CTRL_INT (DIRECT_IF_REVB_BASE + 0x0000001C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_INT_MAX 0xFF000000 #define FLD_DIF_INT_MAX 0xFF000000
#define FLD_DIF_INT_MIN 0x00FF0000 #define FLD_DIF_INT_MIN 0x00FF0000
#define FLD_DIF_INT_AGC 0x0000FFFF #define FLD_DIF_INT_AGC 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_CTRL_RF (DIRECT_IF_REVB_BASE + 0x00000020) /* Reg Size 32 */ #define DIF_AGC_CTRL_RF (DIRECT_IF_REVB_BASE + 0x00000020) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_RF_MAX 0xFF000000 #define FLD_DIF_RF_MAX 0xFF000000
#define FLD_DIF_RF_MIN 0x00FF0000 #define FLD_DIF_RF_MIN 0x00FF0000
#define FLD_DIF_RF_AGC 0x0000FFFF #define FLD_DIF_RF_AGC 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_IF_INT_CURRENT (DIRECT_IF_REVB_BASE + 0x00000024) /* Reg Size 32 */ #define DIF_AGC_IF_INT_CURRENT (DIRECT_IF_REVB_BASE + 0x00000024) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_IF_AGC_IN 0xFFFF0000 #define FLD_DIF_IF_AGC_IN 0xFFFF0000
#define FLD_DIF_INT_AGC_IN 0x0000FFFF #define FLD_DIF_INT_AGC_IN 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AGC_RF_CURRENT (DIRECT_IF_REVB_BASE + 0x00000028) /* Reg Size 32 */ #define DIF_AGC_RF_CURRENT (DIRECT_IF_REVB_BASE + 0x00000028) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:16] */ /* Reserved [31:16] */
#define FLD_DIF_RF_AGC_IN 0x0000FFFF #define FLD_DIF_RF_AGC_IN 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_VIDEO_AGC_CTRL (DIRECT_IF_REVB_BASE + 0x0000002C) /* Reg Size 32 */ #define DIF_VIDEO_AGC_CTRL (DIRECT_IF_REVB_BASE + 0x0000002C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_AFD 0xC0000000 #define FLD_DIF_AFD 0xC0000000
#define FLD_DIF_K_VID_AGC 0x30000000 #define FLD_DIF_K_VID_AGC 0x30000000
...@@ -249,7 +246,7 @@ typedef enum{ ...@@ -249,7 +246,7 @@ typedef enum{
#define FLD_DIF_AGC_GAIN 0x0000FFFF #define FLD_DIF_AGC_GAIN 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_VID_AUD_OVERRIDE (DIRECT_IF_REVB_BASE + 0x00000030) /* Reg Size 32 */ #define DIF_VID_AUD_OVERRIDE (DIRECT_IF_REVB_BASE + 0x00000030) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_AUDIO_AGC_OVERRIDE 0x80000000 #define FLD_DIF_AUDIO_AGC_OVERRIDE 0x80000000
/* Reserved [30:30] */ /* Reserved [30:30] */
...@@ -259,14 +256,14 @@ typedef enum{ ...@@ -259,14 +256,14 @@ typedef enum{
#define FLD_DIF_VID_MAN_GAIN 0x0000FFFF #define FLD_DIF_VID_MAN_GAIN 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_AV_SEP_CTRL (DIRECT_IF_REVB_BASE + 0x00000034) /* Reg Size 32 */ #define DIF_AV_SEP_CTRL (DIRECT_IF_REVB_BASE + 0x00000034) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_LPF_FREQ 0xC0000000 #define FLD_DIF_LPF_FREQ 0xC0000000
#define FLD_DIF_AV_PHASE_INC 0x3F000000 #define FLD_DIF_AV_PHASE_INC 0x3F000000
#define FLD_DIF_AUDIO_FREQ 0x00FFFFFF #define FLD_DIF_AUDIO_FREQ 0x00FFFFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_COMP_FLT_CTRL (DIRECT_IF_REVB_BASE + 0x00000038) /* Reg Size 32 */ #define DIF_COMP_FLT_CTRL (DIRECT_IF_REVB_BASE + 0x00000038) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:24] */ /* Reserved [31:24] */
#define FLD_DIF_IIR23_R2 0x00FF0000 #define FLD_DIF_IIR23_R2 0x00FF0000
...@@ -274,7 +271,7 @@ typedef enum{ ...@@ -274,7 +271,7 @@ typedef enum{
#define FLD_DIF_IIR1_R1 0x000000FF #define FLD_DIF_IIR1_R1 0x000000FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_MISC_CTRL (DIRECT_IF_REVB_BASE + 0x0000003C) /* Reg Size 32 */ #define DIF_MISC_CTRL (DIRECT_IF_REVB_BASE + 0x0000003C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
#define FLD_DIF_DIF_BYPASS 0x80000000 #define FLD_DIF_DIF_BYPASS 0x80000000
#define FLD_DIF_FM_NYQ_GAIN 0x40000000 #define FLD_DIF_FM_NYQ_GAIN 0x40000000
...@@ -299,20 +296,20 @@ typedef enum{ ...@@ -299,20 +296,20 @@ typedef enum{
#define FLD_DIF_RF_IF_LOCK 0x00000001 #define FLD_DIF_RF_IF_LOCK 0x00000001
/*****************************************************************************/ /*****************************************************************************/
#define DIF_SRC_PHASE_INC (DIRECT_IF_REVB_BASE + 0x00000040) /* Reg Size 32 */ #define DIF_SRC_PHASE_INC (DIRECT_IF_REVB_BASE + 0x00000040) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:29] */ /* Reserved [31:29] */
#define FLD_DIF_PHASE_INC 0x1FFFFFFF #define FLD_DIF_PHASE_INC 0x1FFFFFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_SRC_GAIN_CONTROL (DIRECT_IF_REVB_BASE + 0x00000044) /* Reg Size 32 */ #define DIF_SRC_GAIN_CONTROL (DIRECT_IF_REVB_BASE + 0x00000044) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:16] */ /* Reserved [31:16] */
#define FLD_DIF_SRC_KI 0x0000FF00 #define FLD_DIF_SRC_KI 0x0000FF00
#define FLD_DIF_SRC_KD 0x000000FF #define FLD_DIF_SRC_KD 0x000000FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF01 (DIRECT_IF_REVB_BASE + 0x00000048) /* Reg Size 32 */ #define DIF_BPF_COEFF01 (DIRECT_IF_REVB_BASE + 0x00000048) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:19] */ /* Reserved [31:19] */
#define FLD_DIF_BPF_COEFF_0 0x00070000 #define FLD_DIF_BPF_COEFF_0 0x00070000
...@@ -320,7 +317,7 @@ typedef enum{ ...@@ -320,7 +317,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_1 0x0000000F #define FLD_DIF_BPF_COEFF_1 0x0000000F
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF23 (DIRECT_IF_REVB_BASE + 0x0000004c) /* Reg Size 32 */ #define DIF_BPF_COEFF23 (DIRECT_IF_REVB_BASE + 0x0000004c) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:22] */ /* Reserved [31:22] */
#define FLD_DIF_BPF_COEFF_2 0x003F0000 #define FLD_DIF_BPF_COEFF_2 0x003F0000
...@@ -328,7 +325,7 @@ typedef enum{ ...@@ -328,7 +325,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_3 0x0000007F #define FLD_DIF_BPF_COEFF_3 0x0000007F
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF45 (DIRECT_IF_REVB_BASE + 0x00000050) /* Reg Size 32 */ #define DIF_BPF_COEFF45 (DIRECT_IF_REVB_BASE + 0x00000050) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:24] */ /* Reserved [31:24] */
#define FLD_DIF_BPF_COEFF_4 0x00FF0000 #define FLD_DIF_BPF_COEFF_4 0x00FF0000
...@@ -336,7 +333,7 @@ typedef enum{ ...@@ -336,7 +333,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_5 0x000000FF #define FLD_DIF_BPF_COEFF_5 0x000000FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF67 (DIRECT_IF_REVB_BASE + 0x00000054) /* Reg Size 32 */ #define DIF_BPF_COEFF67 (DIRECT_IF_REVB_BASE + 0x00000054) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:25] */ /* Reserved [31:25] */
#define FLD_DIF_BPF_COEFF_6 0x01FF0000 #define FLD_DIF_BPF_COEFF_6 0x01FF0000
...@@ -344,7 +341,7 @@ typedef enum{ ...@@ -344,7 +341,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_7 0x000001FF #define FLD_DIF_BPF_COEFF_7 0x000001FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF89 (DIRECT_IF_REVB_BASE + 0x00000058) /* Reg Size 32 */ #define DIF_BPF_COEFF89 (DIRECT_IF_REVB_BASE + 0x00000058) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:26] */ /* Reserved [31:26] */
#define FLD_DIF_BPF_COEFF_8 0x03FF0000 #define FLD_DIF_BPF_COEFF_8 0x03FF0000
...@@ -352,7 +349,7 @@ typedef enum{ ...@@ -352,7 +349,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_9 0x000003FF #define FLD_DIF_BPF_COEFF_9 0x000003FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF1011 (DIRECT_IF_REVB_BASE + 0x0000005C) /* Reg Size 32 */ #define DIF_BPF_COEFF1011 (DIRECT_IF_REVB_BASE + 0x0000005C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:27] */ /* Reserved [31:27] */
#define FLD_DIF_BPF_COEFF_10 0x07FF0000 #define FLD_DIF_BPF_COEFF_10 0x07FF0000
...@@ -360,7 +357,7 @@ typedef enum{ ...@@ -360,7 +357,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_11 0x000007FF #define FLD_DIF_BPF_COEFF_11 0x000007FF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF1213 (DIRECT_IF_REVB_BASE + 0x00000060) /* Reg Size 32 */ #define DIF_BPF_COEFF1213 (DIRECT_IF_REVB_BASE + 0x00000060) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:27] */ /* Reserved [31:27] */
#define FLD_DIF_BPF_COEFF_12 0x07FF0000 #define FLD_DIF_BPF_COEFF_12 0x07FF0000
...@@ -368,7 +365,7 @@ typedef enum{ ...@@ -368,7 +365,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_13 0x00000FFF #define FLD_DIF_BPF_COEFF_13 0x00000FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF1415 (DIRECT_IF_REVB_BASE + 0x00000064) /* Reg Size 32 */ #define DIF_BPF_COEFF1415 (DIRECT_IF_REVB_BASE + 0x00000064) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:28] */ /* Reserved [31:28] */
#define FLD_DIF_BPF_COEFF_14 0x0FFF0000 #define FLD_DIF_BPF_COEFF_14 0x0FFF0000
...@@ -376,7 +373,7 @@ typedef enum{ ...@@ -376,7 +373,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_15 0x00000FFF #define FLD_DIF_BPF_COEFF_15 0x00000FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF1617 (DIRECT_IF_REVB_BASE + 0x00000068) /* Reg Size 32 */ #define DIF_BPF_COEFF1617 (DIRECT_IF_REVB_BASE + 0x00000068) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:29] */ /* Reserved [31:29] */
#define FLD_DIF_BPF_COEFF_16 0x1FFF0000 #define FLD_DIF_BPF_COEFF_16 0x1FFF0000
...@@ -384,7 +381,7 @@ typedef enum{ ...@@ -384,7 +381,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_17 0x00001FFF #define FLD_DIF_BPF_COEFF_17 0x00001FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF1819 (DIRECT_IF_REVB_BASE + 0x0000006C) /* Reg Size 32 */ #define DIF_BPF_COEFF1819 (DIRECT_IF_REVB_BASE + 0x0000006C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:29] */ /* Reserved [31:29] */
#define FLD_DIF_BPF_COEFF_18 0x1FFF0000 #define FLD_DIF_BPF_COEFF_18 0x1FFF0000
...@@ -392,7 +389,7 @@ typedef enum{ ...@@ -392,7 +389,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_19 0x00001FFF #define FLD_DIF_BPF_COEFF_19 0x00001FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF2021 (DIRECT_IF_REVB_BASE + 0x00000070) /* Reg Size 32 */ #define DIF_BPF_COEFF2021 (DIRECT_IF_REVB_BASE + 0x00000070) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:29] */ /* Reserved [31:29] */
#define FLD_DIF_BPF_COEFF_20 0x1FFF0000 #define FLD_DIF_BPF_COEFF_20 0x1FFF0000
...@@ -400,7 +397,7 @@ typedef enum{ ...@@ -400,7 +397,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_21 0x00003FFF #define FLD_DIF_BPF_COEFF_21 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF2223 (DIRECT_IF_REVB_BASE + 0x00000074) /* Reg Size 32 */ #define DIF_BPF_COEFF2223 (DIRECT_IF_REVB_BASE + 0x00000074) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_22 0x3FFF0000 #define FLD_DIF_BPF_COEFF_22 0x3FFF0000
...@@ -408,7 +405,7 @@ typedef enum{ ...@@ -408,7 +405,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_23 0x00003FFF #define FLD_DIF_BPF_COEFF_23 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF2425 (DIRECT_IF_REVB_BASE + 0x00000078) /* Reg Size 32 */ #define DIF_BPF_COEFF2425 (DIRECT_IF_REVB_BASE + 0x00000078) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_24 0x3FFF0000 #define FLD_DIF_BPF_COEFF_24 0x3FFF0000
...@@ -416,7 +413,7 @@ typedef enum{ ...@@ -416,7 +413,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_25 0x00003FFF #define FLD_DIF_BPF_COEFF_25 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF2627 (DIRECT_IF_REVB_BASE + 0x0000007C) /* Reg Size 32 */ #define DIF_BPF_COEFF2627 (DIRECT_IF_REVB_BASE + 0x0000007C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_26 0x3FFF0000 #define FLD_DIF_BPF_COEFF_26 0x3FFF0000
...@@ -424,7 +421,7 @@ typedef enum{ ...@@ -424,7 +421,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_27 0x00003FFF #define FLD_DIF_BPF_COEFF_27 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF2829 (DIRECT_IF_REVB_BASE + 0x00000080) /* Reg Size 32 */ #define DIF_BPF_COEFF2829 (DIRECT_IF_REVB_BASE + 0x00000080) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_28 0x3FFF0000 #define FLD_DIF_BPF_COEFF_28 0x3FFF0000
...@@ -432,7 +429,7 @@ typedef enum{ ...@@ -432,7 +429,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_29 0x00003FFF #define FLD_DIF_BPF_COEFF_29 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF3031 (DIRECT_IF_REVB_BASE + 0x00000084) /* Reg Size 32 */ #define DIF_BPF_COEFF3031 (DIRECT_IF_REVB_BASE + 0x00000084) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_30 0x3FFF0000 #define FLD_DIF_BPF_COEFF_30 0x3FFF0000
...@@ -440,7 +437,7 @@ typedef enum{ ...@@ -440,7 +437,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_31 0x00003FFF #define FLD_DIF_BPF_COEFF_31 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF3233 (DIRECT_IF_REVB_BASE + 0x00000088) /* Reg Size 32 */ #define DIF_BPF_COEFF3233 (DIRECT_IF_REVB_BASE + 0x00000088) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_32 0x3FFF0000 #define FLD_DIF_BPF_COEFF_32 0x3FFF0000
...@@ -448,7 +445,7 @@ typedef enum{ ...@@ -448,7 +445,7 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_33 0x00003FFF #define FLD_DIF_BPF_COEFF_33 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF3435 (DIRECT_IF_REVB_BASE + 0x0000008C) /* Reg Size 32 */ #define DIF_BPF_COEFF3435 (DIRECT_IF_REVB_BASE + 0x0000008C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_34 0x3FFF0000 #define FLD_DIF_BPF_COEFF_34 0x3FFF0000
...@@ -456,20 +453,20 @@ typedef enum{ ...@@ -456,20 +453,20 @@ typedef enum{
#define FLD_DIF_BPF_COEFF_35 0x00003FFF #define FLD_DIF_BPF_COEFF_35 0x00003FFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_BPF_COEFF36 (DIRECT_IF_REVB_BASE + 0x00000090) /* Reg Size 32 */ #define DIF_BPF_COEFF36 (DIRECT_IF_REVB_BASE + 0x00000090) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:30] */ /* Reserved [31:30] */
#define FLD_DIF_BPF_COEFF_36 0x3FFF0000 #define FLD_DIF_BPF_COEFF_36 0x3FFF0000
/* Reserved [15:0] */ /* Reserved [15:0] */
/*****************************************************************************/ /*****************************************************************************/
#define DIF_RPT_VARIANCE (DIRECT_IF_REVB_BASE + 0x00000094) /* Reg Size 32 */ #define DIF_RPT_VARIANCE (DIRECT_IF_REVB_BASE + 0x00000094) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:20] */ /* Reserved [31:20] */
#define FLD_DIF_RPT_VARIANCE 0x000FFFFF #define FLD_DIF_RPT_VARIANCE 0x000FFFFF
/*****************************************************************************/ /*****************************************************************************/
#define DIF_SOFT_RST_CTRL_REVB (DIRECT_IF_REVB_BASE + 0x00000098) /* Reg Size 32 */ #define DIF_SOFT_RST_CTRL_REVB (DIRECT_IF_REVB_BASE + 0x00000098) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:8] */ /* Reserved [31:8] */
#define FLD_DIF_DIF_SOFT_RST 0x00000080 #define FLD_DIF_DIF_SOFT_RST 0x00000080
...@@ -482,10 +479,9 @@ typedef enum{ ...@@ -482,10 +479,9 @@ typedef enum{
#define FLD_DIF_PLL_RST_MSK 0x00000001 #define FLD_DIF_PLL_RST_MSK 0x00000001
/*****************************************************************************/ /*****************************************************************************/
#define DIF_PLL_FREQ_ERR (DIRECT_IF_REVB_BASE + 0x0000009C) /* Reg Size 32 */ #define DIF_PLL_FREQ_ERR (DIRECT_IF_REVB_BASE + 0x0000009C) /* Reg Size 32 */
/*****************************************************************************/ /*****************************************************************************/
/* Reserved [31:25] */ /* Reserved [31:25] */
#define FLD_DIF_CTL_IP 0x01FFFFFF #define FLD_DIF_CTL_IP 0x01FFFFFF
#endif #endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
cx231xx-core.c - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx-core.c - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
/* #define ENABLE_DEBUG_ISOC_FRAMES */ /* #define ENABLE_DEBUG_ISOC_FRAMES */
static unsigned int core_debug; static unsigned int core_debug;
module_param(core_debug,int,0644); module_param(core_debug, int, 0644);
MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
#define cx231xx_coredbg(fmt, arg...) do {\ #define cx231xx_coredbg(fmt, arg...) do {\
if (core_debug) \ if (core_debug) \
...@@ -41,8 +41,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); ...@@ -41,8 +41,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
dev->name, __func__ , ##arg); } while (0) dev->name, __func__ , ##arg); } while (0)
static unsigned int reg_debug; static unsigned int reg_debug;
module_param(reg_debug,int,0644); module_param(reg_debug, int, 0644);
MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
#define cx231xx_regdbg(fmt, arg...) do {\ #define cx231xx_regdbg(fmt, arg...) do {\
if (reg_debug) \ if (reg_debug) \
...@@ -59,8 +59,6 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); ...@@ -59,8 +59,6 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
printk(KERN_INFO "%s %s :"fmt, \ printk(KERN_INFO "%s %s :"fmt, \
dev->name, __func__ , ##arg); } while (0) dev->name, __func__ , ##arg); } while (0)
/************************************************************************************ /************************************************************************************
* Device control list functions * * Device control list functions *
*************************************************************************************/ *************************************************************************************/
...@@ -69,8 +67,7 @@ static LIST_HEAD(cx231xx_devlist); ...@@ -69,8 +67,7 @@ static LIST_HEAD(cx231xx_devlist);
static DEFINE_MUTEX(cx231xx_devlist_mutex); static DEFINE_MUTEX(cx231xx_devlist_mutex);
struct cx231xx *cx231xx_get_device(int minor, struct cx231xx *cx231xx_get_device(int minor,
enum v4l2_buf_type *fh_type, enum v4l2_buf_type *fh_type, int *has_radio)
int *has_radio)
{ {
struct cx231xx *h, *dev = NULL; struct cx231xx *h, *dev = NULL;
...@@ -85,8 +82,7 @@ struct cx231xx *cx231xx_get_device(int minor, ...@@ -85,8 +82,7 @@ struct cx231xx *cx231xx_get_device(int minor,
dev = h; dev = h;
*fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
} }
if (h->radio_dev && if (h->radio_dev && h->radio_dev->minor == minor) {
h->radio_dev->minor == minor) {
dev = h; dev = h;
*has_radio = 1; *has_radio = 1;
} }
...@@ -115,9 +111,6 @@ void cx231xx_add_into_devlist(struct cx231xx *dev) ...@@ -115,9 +111,6 @@ void cx231xx_add_into_devlist(struct cx231xx *dev)
mutex_unlock(&cx231xx_devlist_mutex); mutex_unlock(&cx231xx_devlist_mutex);
}; };
static LIST_HEAD(cx231xx_extension_devlist); static LIST_HEAD(cx231xx_extension_devlist);
static DEFINE_MUTEX(cx231xx_extension_devlist_lock); static DEFINE_MUTEX(cx231xx_extension_devlist_lock);
...@@ -137,6 +130,7 @@ int cx231xx_register_extension(struct cx231xx_ops *ops) ...@@ -137,6 +130,7 @@ int cx231xx_register_extension(struct cx231xx_ops *ops)
mutex_unlock(&cx231xx_devlist_mutex); mutex_unlock(&cx231xx_devlist_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL(cx231xx_register_extension); EXPORT_SYMBOL(cx231xx_register_extension);
void cx231xx_unregister_extension(struct cx231xx_ops *ops) void cx231xx_unregister_extension(struct cx231xx_ops *ops)
...@@ -155,8 +149,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops) ...@@ -155,8 +149,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops)
mutex_unlock(&cx231xx_extension_devlist_lock); mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex); mutex_unlock(&cx231xx_devlist_mutex);
} }
EXPORT_SYMBOL(cx231xx_unregister_extension);
EXPORT_SYMBOL(cx231xx_unregister_extension);
void cx231xx_init_extension(struct cx231xx *dev) void cx231xx_init_extension(struct cx231xx *dev)
{ {
...@@ -190,78 +184,82 @@ void cx231xx_close_extension(struct cx231xx *dev) ...@@ -190,78 +184,82 @@ void cx231xx_close_extension(struct cx231xx *dev)
* U S B related functions * * U S B related functions *
*************************************************************************************/ *************************************************************************************/
int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
struct cx231xx_i2c_xfer_data *req_data) struct cx231xx_i2c_xfer_data *req_data)
{ {
int status = 0; int status = 0;
struct cx231xx *dev = i2c_bus->dev; struct cx231xx *dev = i2c_bus->dev;
VENDOR_REQUEST_IN ven_req; VENDOR_REQUEST_IN ven_req;
u8 saddr_len = 0; u8 saddr_len = 0;
u8 _i2c_period = 0; u8 _i2c_period = 0;
u8 _i2c_nostop = 0; u8 _i2c_nostop = 0;
u8 _i2c_reserve = 0; u8 _i2c_reserve = 0;
/* Get the I2C period, nostop and reserve parameters */ /* Get the I2C period, nostop and reserve parameters */
_i2c_period = i2c_bus->i2c_period; _i2c_period = i2c_bus->i2c_period;
_i2c_nostop = i2c_bus->i2c_nostop; _i2c_nostop = i2c_bus->i2c_nostop;
_i2c_reserve = i2c_bus->i2c_reserve; _i2c_reserve = i2c_bus->i2c_reserve;
saddr_len = req_data->saddr_len; saddr_len = req_data->saddr_len;
/* Set wValue */ /* Set wValue */
if(saddr_len == 1) /* need check saddr_len == 0 */ if (saddr_len == 1) /* need check saddr_len == 0 */
ven_req.wValue = req_data->dev_addr<<9|_i2c_period<<4|saddr_len<<2| ven_req.wValue =
_i2c_nostop<<1|I2C_SYNC|_i2c_reserve<<6; req_data->
else dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
ven_req.wValue = req_data->dev_addr<<9|_i2c_period<<4|saddr_len<<2| _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
_i2c_nostop<<1|I2C_SYNC|_i2c_reserve<<6; else
ven_req.wValue =
/* set channel number */ req_data->
if(req_data->direction & I2C_M_RD) dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
ven_req.bRequest = i2c_bus->nr + 4; /* channel number, for read, _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
spec required channel_num +4 */
else /* set channel number */
ven_req.bRequest = i2c_bus->nr; /* channel number, */ if (req_data->direction & I2C_M_RD)
ven_req.bRequest = i2c_bus->nr + 4; /* channel number, for read,
/* set index value */ spec required channel_num +4 */
switch(saddr_len){ else
case 0: ven_req.bRequest = i2c_bus->nr; /* channel number, */
ven_req.wIndex = 0; /* need check */
break; /* set index value */
case 1: switch (saddr_len) {
ven_req.wIndex = (req_data->saddr_dat & 0xff); case 0:
break; ven_req.wIndex = 0; /* need check */
case 2: break;
ven_req.wIndex = req_data->saddr_dat; case 1:
break; ven_req.wIndex = (req_data->saddr_dat & 0xff);
} break;
case 2:
/* set wLength value */ ven_req.wIndex = req_data->saddr_dat;
ven_req.wLength = req_data->buf_size; break;
}
/* set bData value */
ven_req.bData = 0; /* set wLength value */
ven_req.wLength = req_data->buf_size;
/* set the direction */
if(req_data->direction){ /* set bData value */
ven_req.direction = USB_DIR_IN; ven_req.bData = 0;
memset(req_data->p_buffer, 0x00, ven_req.wLength);
} /* set the direction */
else if (req_data->direction) {
ven_req.direction = USB_DIR_OUT; ven_req.direction = USB_DIR_IN;
memset(req_data->p_buffer, 0x00, ven_req.wLength);
/* set the buffer for read / write */ } else
ven_req.pBuff = req_data->p_buffer; ven_req.direction = USB_DIR_OUT;
/* set the buffer for read / write */
ven_req.pBuff = req_data->p_buffer;
/* call common vendor command request */
status = cx231xx_send_vendor_cmd(dev, &ven_req);
if (status < 0) { /* call common vendor command request */
cx231xx_info("UsbInterface::sendCommand, output buffer failed with status -%d\n", status); status = cx231xx_send_vendor_cmd(dev, &ven_req);
} if (status < 0) {
cx231xx_info
return status; ("UsbInterface::sendCommand, output buffer failed with status -%d\n",
status);
}
return status;
} }
EXPORT_SYMBOL_GPL(cx231xx_send_usb_command); EXPORT_SYMBOL_GPL(cx231xx_send_usb_command);
...@@ -270,9 +268,9 @@ EXPORT_SYMBOL_GPL(cx231xx_send_usb_command); ...@@ -270,9 +268,9 @@ EXPORT_SYMBOL_GPL(cx231xx_send_usb_command);
* reads data from the usb device specifying bRequest and wValue * reads data from the usb device specifying bRequest and wValue
*/ */
int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
char *buf, int len) char *buf, int len)
{ {
u8 val = 0; u8 val = 0;
int ret; int ret;
int pipe = usb_rcvctrlpipe(dev->udev, 0); int pipe = usb_rcvctrlpipe(dev->udev, 0);
...@@ -282,35 +280,33 @@ int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, ...@@ -282,35 +280,33 @@ int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
if (len > URB_MAX_CTRL_SIZE) if (len > URB_MAX_CTRL_SIZE)
return -EINVAL; return -EINVAL;
switch(len) switch (len) {
{ case 1:
case 1: val = ENABLE_ONE_BYTE;
val = ENABLE_ONE_BYTE; break;
break; case 2:
case 2: val = ENABLE_TWE_BYTE;
val = ENABLE_TWE_BYTE; break;
break; case 3:
case 3: val = ENABLE_THREE_BYTE;
val = ENABLE_THREE_BYTE; break;
break; case 4:
case 4: val = ENABLE_FOUR_BYTE;
val = ENABLE_FOUR_BYTE; break;
break; default:
default: val = 0xFF; /* invalid option */
val = 0xFF; /* invalid option */ }
}
if (val == 0xFF)
if(val == 0xFF) return -EINVAL;
return -EINVAL;
if (reg_debug) { if (reg_debug) {
cx231xx_isocdbg("(pipe 0x%08x): " cx231xx_isocdbg("(pipe 0x%08x): "
"IN: %02x %02x %02x %02x %02x %02x %02x %02x ", "IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
pipe, pipe,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
req, 0, val, req, 0, val,
reg & 0xff, reg >> 8, reg & 0xff, reg >> 8, len & 0xff, len >> 8);
len & 0xff, len >> 8);
} }
/* mutex_lock(&dev->ctrl_urb_lock); */ /* mutex_lock(&dev->ctrl_urb_lock); */
...@@ -340,10 +336,9 @@ int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, ...@@ -340,10 +336,9 @@ int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
return ret; return ret;
} }
int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN * ven_req)
int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req)
{ {
int ret; int ret;
int pipe = 0; int pipe = 0;
if (dev->state & DEV_DISCONNECTED) if (dev->state & DEV_DISCONNECTED)
...@@ -352,32 +347,34 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req) ...@@ -352,32 +347,34 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req)
if ((ven_req->wLength > URB_MAX_CTRL_SIZE)) if ((ven_req->wLength > URB_MAX_CTRL_SIZE))
return -EINVAL; return -EINVAL;
if(ven_req->direction) if (ven_req->direction)
pipe = usb_rcvctrlpipe(dev->udev, 0); pipe = usb_rcvctrlpipe(dev->udev, 0);
else else
pipe = usb_sndctrlpipe(dev->udev, 0); pipe = usb_sndctrlpipe(dev->udev, 0);
if (reg_debug) { if (reg_debug) {
int byte; int byte;
cx231xx_isocdbg("(pipe 0x%08x): " cx231xx_isocdbg("(pipe 0x%08x): "
"OUT: %02x %02x %02x %04x %04x %04x >>>", "OUT: %02x %02x %02x %04x %04x %04x >>>",
pipe, pipe,
ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ven_req->
ven_req->bRequest, 0, ven_req->wValue, direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
ven_req->wIndex, ven_req->bRequest, 0, ven_req->wValue,
ven_req->wLength); ven_req->wIndex, ven_req->wLength);
for (byte = 0; byte < ven_req->wLength; byte++) for (byte = 0; byte < ven_req->wLength; byte++)
cx231xx_isocdbg(" %02x", (unsigned char)ven_req->pBuff[byte]); cx231xx_isocdbg(" %02x",
(unsigned char)ven_req->pBuff[byte]);
cx231xx_isocdbg("\n"); cx231xx_isocdbg("\n");
} }
/* mutex_lock(&dev->ctrl_urb_lock); */ /* mutex_lock(&dev->ctrl_urb_lock); */
ret = usb_control_msg(dev->udev, pipe, ven_req->bRequest, ret = usb_control_msg(dev->udev, pipe, ven_req->bRequest,
ven_req->direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ven_req->
ven_req->wValue, ven_req->wIndex, ven_req->pBuff, ven_req->wLength, HZ); direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
ven_req->wValue, ven_req->wIndex, ven_req->pBuff,
ven_req->wLength, HZ);
/* mutex_unlock(&dev->ctrl_urb_lock); */ /* mutex_unlock(&dev->ctrl_urb_lock); */
return ret; return ret;
...@@ -388,9 +385,9 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req) ...@@ -388,9 +385,9 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req)
* sends data to the usb device, specifying bRequest * sends data to the usb device, specifying bRequest
*/ */
int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf, int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
int len) int len)
{ {
u8 val = 0; u8 val = 0;
int ret; int ret;
int pipe = usb_sndctrlpipe(dev->udev, 0); int pipe = usb_sndctrlpipe(dev->udev, 0);
...@@ -400,37 +397,35 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf, ...@@ -400,37 +397,35 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
return -EINVAL; return -EINVAL;
switch(len) switch (len) {
{ case 1:
case 1: val = ENABLE_ONE_BYTE;
val = ENABLE_ONE_BYTE; break;
break; case 2:
case 2: val = ENABLE_TWE_BYTE;
val = ENABLE_TWE_BYTE; break;
break; case 3:
case 3: val = ENABLE_THREE_BYTE;
val = ENABLE_THREE_BYTE; break;
break; case 4:
case 4: val = ENABLE_FOUR_BYTE;
val = ENABLE_FOUR_BYTE; break;
break; default:
default: val = 0xFF; /* invalid option */
val = 0xFF; /* invalid option */ }
}
if (val == 0xFF)
if(val == 0xFF) return -EINVAL;
return -EINVAL;
if (reg_debug) { if (reg_debug) {
int byte; int byte;
cx231xx_isocdbg("(pipe 0x%08x): " cx231xx_isocdbg("(pipe 0x%08x): "
"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
pipe, pipe,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR |
req, 0, val, USB_RECIP_DEVICE, req, 0, val, reg & 0xff,
reg & 0xff, reg >> 8, reg >> 8, len & 0xff, len >> 8);
len & 0xff, len >> 8);
for (byte = 0; byte < len; byte++) for (byte = 0; byte < len; byte++)
cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]); cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
...@@ -447,7 +442,6 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf, ...@@ -447,7 +442,6 @@ int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
return ret; return ret;
} }
/************************************************************************************ /************************************************************************************
* USB Alternate Setting functions * * USB Alternate Setting functions *
*************************************************************************************/ *************************************************************************************/
...@@ -456,7 +450,7 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) ...@@ -456,7 +450,7 @@ int cx231xx_set_video_alternate(struct cx231xx *dev)
{ {
int errCode, prev_alt = dev->video_mode.alt; int errCode, prev_alt = dev->video_mode.alt;
unsigned int min_pkt_size = dev->width * 2 + 4; unsigned int min_pkt_size = dev->width * 2 + 4;
u32 usb_interface_index = 0; u32 usb_interface_index = 0;
/* When image size is bigger than a certain value, /* When image size is bigger than a certain value,
the frame size should be increased, otherwise, only the frame size should be increased, otherwise, only
...@@ -465,35 +459,44 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) ...@@ -465,35 +459,44 @@ int cx231xx_set_video_alternate(struct cx231xx *dev)
if (dev->width * 2 * dev->height > 720 * 240 * 2) if (dev->width * 2 * dev->height > 720 * 240 * 2)
min_pkt_size *= 2; min_pkt_size *= 2;
if(dev->width > 360) { if (dev->width > 360) {
/* resolutions: 720,704,640 */ /* resolutions: 720,704,640 */
dev->video_mode.alt = 3; dev->video_mode.alt = 3;
} else if(dev->width > 180) { } else if (dev->width > 180) {
/* resolutions: 360,352,320,240 */ /* resolutions: 360,352,320,240 */
dev->video_mode.alt = 2; dev->video_mode.alt = 2;
} else if(dev->width > 0) { } else if (dev->width > 0) {
/* resolutions: 180,176,160,128,88 */ /* resolutions: 180,176,160,128,88 */
dev->video_mode.alt = 1; dev->video_mode.alt = 1;
} else { } else {
/* Change to alt0 BULK to release USB bandwidth */ /* Change to alt0 BULK to release USB bandwidth */
dev->video_mode.alt = 0; dev->video_mode.alt = 0;
} }
/* Get the correct video interface Index */ /* Get the correct video interface Index */
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.video_index+1; usb_interface_index =
dev->current_pcb_config.hs_config_info[0].interface_info.
video_index + 1;
if (dev->video_mode.alt != prev_alt) { if (dev->video_mode.alt != prev_alt) {
cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
min_pkt_size, dev->video_mode.alt); min_pkt_size, dev->video_mode.alt);
dev->video_mode.max_pkt_size = dev->video_mode.alt_max_pkt_size[dev->video_mode.alt]; dev->video_mode.max_pkt_size =
dev->video_mode.alt_max_pkt_size[dev->video_mode.alt];
cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
dev->video_mode.alt, dev->video_mode.max_pkt_size); dev->video_mode.alt,
cx231xx_info(" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n", dev->video_mode.max_pkt_size);
dev->video_mode.alt, dev->video_mode.max_pkt_size, usb_interface_index); cx231xx_info
errCode = usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); (" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n",
dev->video_mode.alt, dev->video_mode.max_pkt_size,
usb_interface_index);
errCode =
usb_set_interface(dev->udev, usb_interface_index,
dev->video_mode.alt);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("cannot change alternate number to %d (error=%i)\n", cx231xx_errdev
dev->video_mode.alt, errCode); ("cannot change alternate number to %d (error=%i)\n",
dev->video_mode.alt, errCode);
return errCode; return errCode;
} }
} }
...@@ -502,68 +505,92 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) ...@@ -502,68 +505,92 @@ int cx231xx_set_video_alternate(struct cx231xx *dev)
int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
{ {
int status = 0; int status = 0;
u32 usb_interface_index = 0; u32 usb_interface_index = 0;
u32 max_pkt_size = 0; u32 max_pkt_size = 0;
switch(index) { switch (index) {
case INDEX_TS1: case INDEX_TS1:
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index+1; usb_interface_index =
dev->video_mode.alt = alt; dev->current_pcb_config.hs_config_info[0].interface_info.
if(dev->ts1_mode.alt_max_pkt_size != NULL) ts1_index + 1;
max_pkt_size = dev->ts1_mode.max_pkt_size = dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt]; dev->video_mode.alt = alt;
break; if (dev->ts1_mode.alt_max_pkt_size != NULL)
case INDEX_TS2: max_pkt_size = dev->ts1_mode.max_pkt_size =
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.ts2_index+1; dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt];
break; break;
case INDEX_AUDIO: case INDEX_TS2:
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.audio_index+1; usb_interface_index =
dev->adev.alt = alt; dev->current_pcb_config.hs_config_info[0].interface_info.
if( dev->adev.alt_max_pkt_size != NULL) ts2_index + 1;
max_pkt_size = dev->adev.max_pkt_size = dev->adev.alt_max_pkt_size[dev->adev.alt]; break;
break; case INDEX_AUDIO:
case INDEX_VIDEO: usb_interface_index =
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.video_index+1; dev->current_pcb_config.hs_config_info[0].interface_info.
dev->video_mode.alt = alt; audio_index + 1;
if(dev->video_mode.alt_max_pkt_size != NULL) dev->adev.alt = alt;
max_pkt_size = dev->video_mode.max_pkt_size = dev->video_mode.alt_max_pkt_size[dev->video_mode.alt]; if (dev->adev.alt_max_pkt_size != NULL)
break; max_pkt_size = dev->adev.max_pkt_size =
case INDEX_VANC: dev->adev.alt_max_pkt_size[dev->adev.alt];
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index+1; break;
dev->vbi_mode.alt = alt; case INDEX_VIDEO:
if(dev->vbi_mode.alt_max_pkt_size != NULL) usb_interface_index =
max_pkt_size = dev->vbi_mode.max_pkt_size = dev->vbi_mode.alt_max_pkt_size[dev->vbi_mode.alt]; dev->current_pcb_config.hs_config_info[0].interface_info.
break; video_index + 1;
case INDEX_HANC: dev->video_mode.alt = alt;
usb_interface_index = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index+1; if (dev->video_mode.alt_max_pkt_size != NULL)
dev->sliced_cc_mode.alt = alt; max_pkt_size = dev->video_mode.max_pkt_size =
if(dev->sliced_cc_mode.alt_max_pkt_size != NULL) dev->video_mode.alt_max_pkt_size[dev->video_mode.
max_pkt_size = dev->sliced_cc_mode.max_pkt_size = dev->sliced_cc_mode.alt_max_pkt_size[dev->sliced_cc_mode.alt]; alt];
break; break;
default: case INDEX_VANC:
break; usb_interface_index =
} dev->current_pcb_config.hs_config_info[0].interface_info.
vanc_index + 1;
if(alt > 0 && max_pkt_size == 0 ) { dev->vbi_mode.alt = alt;
cx231xx_errdev("cannot change interface %d alternate number to %d : Max. Pkt size is ZERO\n", if (dev->vbi_mode.alt_max_pkt_size != NULL)
usb_interface_index, alt); max_pkt_size = dev->vbi_mode.max_pkt_size =
return -1; dev->vbi_mode.alt_max_pkt_size[dev->vbi_mode.alt];
} break;
case INDEX_HANC:
cx231xx_info(" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n", usb_interface_index =
alt, max_pkt_size, usb_interface_index); dev->current_pcb_config.hs_config_info[0].interface_info.
hanc_index + 1;
if(usb_interface_index > 0 ) { dev->sliced_cc_mode.alt = alt;
status = usb_set_interface(dev->udev, usb_interface_index, alt); if (dev->sliced_cc_mode.alt_max_pkt_size != NULL)
max_pkt_size = dev->sliced_cc_mode.max_pkt_size =
dev->sliced_cc_mode.alt_max_pkt_size[dev->
sliced_cc_mode.
alt];
break;
default:
break;
}
if (alt > 0 && max_pkt_size == 0) {
cx231xx_errdev
("cannot change interface %d alternate number to %d : Max. Pkt size is ZERO\n",
usb_interface_index, alt);
return -1;
}
cx231xx_info
(" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n",
alt, max_pkt_size, usb_interface_index);
if (usb_interface_index > 0) {
status = usb_set_interface(dev->udev, usb_interface_index, alt);
if (status < 0) { if (status < 0) {
cx231xx_errdev("cannot change interface %d alternate number to %d (error=%i)\n", cx231xx_errdev
usb_interface_index, alt, status); ("cannot change interface %d alternate number to %d (error=%i)\n",
usb_interface_index, alt, status);
return status; return status;
} }
} }
return status; return status;
} }
EXPORT_SYMBOL_GPL(cx231xx_set_alt_setting); EXPORT_SYMBOL_GPL(cx231xx_set_alt_setting);
int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio) int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio)
...@@ -575,10 +602,9 @@ int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio) ...@@ -575,10 +602,9 @@ int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio)
/* Send GPIO reset sequences specified at board entry */ /* Send GPIO reset sequences specified at board entry */
while (gpio->sleep >= 0) { while (gpio->sleep >= 0) {
rc = cx231xx_set_gpio_value(dev, gpio->bit, rc = cx231xx_set_gpio_value(dev, gpio->bit, gpio->val);
gpio->val); if (rc < 0)
if (rc < 0) return rc;
return rc;
if (gpio->sleep > 0) if (gpio->sleep > 0)
msleep(gpio->sleep); msleep(gpio->sleep);
...@@ -594,7 +620,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) ...@@ -594,7 +620,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
return 0; return 0;
if (set_mode == CX231XX_SUSPEND) { if (set_mode == CX231XX_SUSPEND) {
/* Set the chip in power saving mode */ /* Set the chip in power saving mode */
dev->mode = set_mode; dev->mode = set_mode;
} }
...@@ -604,13 +630,14 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) ...@@ -604,13 +630,14 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
dev->mode = set_mode; dev->mode = set_mode;
if (dev->mode == CX231XX_DIGITAL_MODE) { if (dev->mode == CX231XX_DIGITAL_MODE) {
/* Set Digital power mode */ /* Set Digital power mode */
} else { } else {
/* Set Analog Power mode*/ /* Set Analog Power mode */
} }
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(cx231xx_set_mode); EXPORT_SYMBOL_GPL(cx231xx_set_mode);
/************************************************************************************ /************************************************************************************
...@@ -622,23 +649,23 @@ EXPORT_SYMBOL_GPL(cx231xx_set_mode); ...@@ -622,23 +649,23 @@ EXPORT_SYMBOL_GPL(cx231xx_set_mode);
*/ */
static void cx231xx_irq_callback(struct urb *urb) static void cx231xx_irq_callback(struct urb *urb)
{ {
struct cx231xx_dmaqueue *dma_q = urb->context; struct cx231xx_dmaqueue *dma_q = urb->context;
struct cx231xx_video_mode *vmode = container_of(dma_q, struct cx231xx_video_mode, vidq); struct cx231xx_video_mode *vmode =
struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode); container_of(dma_q, struct cx231xx_video_mode, vidq);
struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
int rc, i; int rc, i;
switch (urb->status) {
switch (urb->status) { case 0: /* success */
case 0: /* success */ case -ETIMEDOUT: /* NAK */
case -ETIMEDOUT: /* NAK */ break;
break; case -ECONNRESET: /* kill */
case -ECONNRESET: /* kill */ case -ENOENT:
case -ENOENT: case -ESHUTDOWN:
case -ESHUTDOWN: return;
return; default: /* error */
default: /* error */ cx231xx_isocdbg("urb completition error %d.\n", urb->status);
cx231xx_isocdbg("urb completition error %d.\n", urb->status); break;
break;
} }
/* Copy data from URB */ /* Copy data from URB */
...@@ -656,7 +683,7 @@ static void cx231xx_irq_callback(struct urb *urb) ...@@ -656,7 +683,7 @@ static void cx231xx_irq_callback(struct urb *urb)
urb->status = usb_submit_urb(urb, GFP_ATOMIC); urb->status = usb_submit_urb(urb, GFP_ATOMIC);
if (urb->status) { if (urb->status) {
cx231xx_isocdbg("urb resubmit failed (error=%i)\n", cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
urb->status); urb->status);
} }
} }
...@@ -674,16 +701,17 @@ void cx231xx_uninit_isoc(struct cx231xx *dev) ...@@ -674,16 +701,17 @@ void cx231xx_uninit_isoc(struct cx231xx *dev)
for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
urb = dev->video_mode.isoc_ctl.urb[i]; urb = dev->video_mode.isoc_ctl.urb[i];
if (urb) { if (urb) {
if (!irqs_disabled()) if (!irqs_disabled())
usb_kill_urb(urb); usb_kill_urb(urb);
else else
usb_unlink_urb(urb); usb_unlink_urb(urb);
if (dev->video_mode.isoc_ctl.transfer_buffer[i]) { if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
usb_buffer_free(dev->udev, usb_buffer_free(dev->udev,
urb->transfer_buffer_length, urb->transfer_buffer_length,
dev->video_mode.isoc_ctl.transfer_buffer[i], dev->video_mode.isoc_ctl.
urb->transfer_dma); transfer_buffer[i],
urb->transfer_dma);
} }
usb_free_urb(urb); usb_free_urb(urb);
dev->video_mode.isoc_ctl.urb[i] = NULL; dev->video_mode.isoc_ctl.urb[i] = NULL;
...@@ -700,14 +728,15 @@ void cx231xx_uninit_isoc(struct cx231xx *dev) ...@@ -700,14 +728,15 @@ void cx231xx_uninit_isoc(struct cx231xx *dev)
cx231xx_capture_start(dev, 0, Raw_Video); cx231xx_capture_start(dev, 0, Raw_Video);
} }
EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc); EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc);
/* /*
* Allocate URBs and start IRQ * Allocate URBs and start IRQ
*/ */
int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
int num_bufs, int max_pkt_size, int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct cx231xx *dev, struct urb *urb)) int (*isoc_copy) (struct cx231xx * dev, struct urb * urb))
{ {
struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq; struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
int i; int i;
...@@ -718,36 +747,36 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, ...@@ -718,36 +747,36 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
cx231xx_isocdbg("cx231xx: called cx231xx_prepare_isoc\n"); cx231xx_isocdbg("cx231xx: called cx231xx_prepare_isoc\n");
dev->video_input = dev->video_input > 2?2:dev->video_input; dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
cx231xx_info("Setting Video mux to %d\n",dev->video_input);
video_mux(dev, dev->video_input);
cx231xx_info("Setting Video mux to %d\n", dev->video_input);
video_mux(dev, dev->video_input);
/* De-allocates all pending stuff */ /* De-allocates all pending stuff */
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
dev->video_mode.isoc_ctl.isoc_copy = isoc_copy; dev->video_mode.isoc_ctl.isoc_copy = isoc_copy;
dev->video_mode.isoc_ctl.num_bufs = num_bufs; dev->video_mode.isoc_ctl.num_bufs = num_bufs;
dma_q->pos = 0; dma_q->pos = 0;
dma_q->is_partial_line = 0; dma_q->is_partial_line = 0;
dma_q->last_sav = 0; dma_q->last_sav = 0;
dma_q->current_field = -1; dma_q->current_field = -1;
dma_q->field1_done = 0; dma_q->field1_done = 0;
dma_q->lines_per_field = dev->height/2; dma_q->lines_per_field = dev->height / 2;
dma_q->bytes_left_in_line = dev->width << 1; dma_q->bytes_left_in_line = dev->width << 1;
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
for(i = 0; i < 8 ; i++) for (i = 0; i < 8; i++)
dma_q->partial_buf[i] = 0; dma_q->partial_buf[i] = 0;
dev->video_mode.isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); dev->video_mode.isoc_ctl.urb =
kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
if (!dev->video_mode.isoc_ctl.urb) { if (!dev->video_mode.isoc_ctl.urb) {
cx231xx_errdev("cannot alloc memory for usb buffers\n"); cx231xx_errdev("cannot alloc memory for usb buffers\n");
return -ENOMEM; return -ENOMEM;
} }
dev->video_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, dev->video_mode.isoc_ctl.transfer_buffer =
GFP_KERNEL); kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
if (!dev->video_mode.isoc_ctl.transfer_buffer) { if (!dev->video_mode.isoc_ctl.transfer_buffer) {
cx231xx_errdev("cannot allocate memory for usbtransfer\n"); cx231xx_errdev("cannot allocate memory for usbtransfer\n");
kfree(dev->video_mode.isoc_ctl.urb); kfree(dev->video_mode.isoc_ctl.urb);
...@@ -769,23 +798,25 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, ...@@ -769,23 +798,25 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
} }
dev->video_mode.isoc_ctl.urb[i] = urb; dev->video_mode.isoc_ctl.urb[i] = urb;
dev->video_mode.isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev, dev->video_mode.isoc_ctl.transfer_buffer[i] =
sb_size, GFP_KERNEL, &urb->transfer_dma); usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,
&urb->transfer_dma);
if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
cx231xx_err("unable to allocate %i bytes for transfer" cx231xx_err("unable to allocate %i bytes for transfer"
" buffer %i%s\n", " buffer %i%s\n",
sb_size, i, sb_size, i,
in_interrupt()?" while in int":""); in_interrupt()? " while in int" : "");
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
return -ENOMEM; return -ENOMEM;
} }
memset(dev->video_mode.isoc_ctl.transfer_buffer[i], 0, sb_size); memset(dev->video_mode.isoc_ctl.transfer_buffer[i], 0, sb_size);
pipe = usb_rcvisocpipe(dev->udev, dev->video_mode.end_point_addr); pipe =
usb_rcvisocpipe(dev->udev, dev->video_mode.end_point_addr);
usb_fill_int_urb(urb, dev->udev, pipe, usb_fill_int_urb(urb, dev->udev, pipe,
dev->video_mode.isoc_ctl.transfer_buffer[i], sb_size, dev->video_mode.isoc_ctl.transfer_buffer[i],
cx231xx_irq_callback, dma_q, 1); sb_size, cx231xx_irq_callback, dma_q, 1);
urb->number_of_packets = max_packets; urb->number_of_packets = max_packets;
urb->transfer_flags = URB_ISO_ASAP; urb->transfer_flags = URB_ISO_ASAP;
...@@ -794,29 +825,30 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, ...@@ -794,29 +825,30 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
for (j = 0; j < max_packets; j++) { for (j = 0; j < max_packets; j++) {
urb->iso_frame_desc[j].offset = k; urb->iso_frame_desc[j].offset = k;
urb->iso_frame_desc[j].length = urb->iso_frame_desc[j].length =
dev->video_mode.isoc_ctl.max_pkt_size; dev->video_mode.isoc_ctl.max_pkt_size;
k += dev->video_mode.isoc_ctl.max_pkt_size; k += dev->video_mode.isoc_ctl.max_pkt_size;
} }
} }
init_waitqueue_head(&dma_q->wq); init_waitqueue_head(&dma_q->wq);
/* submit urbs and enables IRQ */ /* submit urbs and enables IRQ */
for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i], GFP_ATOMIC); rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i],
GFP_ATOMIC);
if (rc) { if (rc) {
cx231xx_err("submit of urb %i failed (error=%i)\n", i, cx231xx_err("submit of urb %i failed (error=%i)\n", i,
rc); rc);
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
return rc; return rc;
} }
} }
cx231xx_capture_start(dev, 1, Raw_Video); cx231xx_capture_start(dev, 1, Raw_Video);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(cx231xx_init_isoc); EXPORT_SYMBOL_GPL(cx231xx_init_isoc);
/************************************************************************************ /************************************************************************************
...@@ -824,171 +856,176 @@ EXPORT_SYMBOL_GPL(cx231xx_init_isoc); ...@@ -824,171 +856,176 @@ EXPORT_SYMBOL_GPL(cx231xx_init_isoc);
*************************************************************************************/ *************************************************************************************/
int cx231xx_dev_init(struct cx231xx *dev) int cx231xx_dev_init(struct cx231xx *dev)
{ {
int errCode = 0; int errCode = 0;
/* Initialize I2C bus */ /* Initialize I2C bus */
/* External Master 1 Bus */ /* External Master 1 Bus */
dev->i2c_bus[0].nr = 0; dev->i2c_bus[0].nr = 0;
dev->i2c_bus[0].dev = dev; dev->i2c_bus[0].dev = dev;
dev->i2c_bus[0].i2c_period = I2C_SPEED_1M; /* 1MHz */ dev->i2c_bus[0].i2c_period = I2C_SPEED_1M; /* 1MHz */
dev->i2c_bus[0].i2c_nostop = 0; dev->i2c_bus[0].i2c_nostop = 0;
dev->i2c_bus[0].i2c_reserve = 0; dev->i2c_bus[0].i2c_reserve = 0;
/* External Master 2 Bus */ /* External Master 2 Bus */
dev->i2c_bus[1].nr = 1; dev->i2c_bus[1].nr = 1;
dev->i2c_bus[1].dev = dev; dev->i2c_bus[1].dev = dev;
dev->i2c_bus[1].i2c_period = I2C_SPEED_1M; /* 1MHz */ dev->i2c_bus[1].i2c_period = I2C_SPEED_1M; /* 1MHz */
dev->i2c_bus[1].i2c_nostop = 0; dev->i2c_bus[1].i2c_nostop = 0;
dev->i2c_bus[1].i2c_reserve = 0; dev->i2c_bus[1].i2c_reserve = 0;
/* Internal Master 3 Bus */ /* Internal Master 3 Bus */
dev->i2c_bus[2].nr = 2; dev->i2c_bus[2].nr = 2;
dev->i2c_bus[2].dev = dev; dev->i2c_bus[2].dev = dev;
dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */ dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */
dev->i2c_bus[2].i2c_nostop = 0; dev->i2c_bus[2].i2c_nostop = 0;
dev->i2c_bus[2].i2c_reserve = 0; dev->i2c_bus[2].i2c_reserve = 0;
/* register I2C buses */ /* register I2C buses */
cx231xx_i2c_register(&dev->i2c_bus[0]); cx231xx_i2c_register(&dev->i2c_bus[0]);
cx231xx_i2c_register(&dev->i2c_bus[1]); cx231xx_i2c_register(&dev->i2c_bus[1]);
cx231xx_i2c_register(&dev->i2c_bus[2]); cx231xx_i2c_register(&dev->i2c_bus[2]);
/* init hardware */ /* init hardware */
/* Note : with out calling set power mode function, colibri can not be set up correctly */ /* Note : with out calling set power mode function, colibri can not be set up correctly */
errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_set_power_mode : Failed to set Power - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_set_power_mode : Failed to set Power - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
/* initialize Colibri block */ /* initialize Colibri block */
errCode = cx231xx_colibri_init_super_block(dev, 0x23c); errCode = cx231xx_colibri_init_super_block(dev, 0x23c);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_colibri init super block - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_colibri init super block - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
errCode = cx231xx_colibri_init_channels(dev); errCode = cx231xx_colibri_init_channels(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_colibri init channels - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_colibri init channels - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
/* Set DIF in By pass mode */ /* Set DIF in By pass mode */
errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
/* flatiron related functions */ /* flatiron related functions */
errCode = cx231xx_flatiron_initialize(dev); errCode = cx231xx_flatiron_initialize(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_flatiron initialize - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_flatiron initialize - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
/* init control pins */ /* init control pins */
errCode = cx231xx_init_ctrl_pin_status(dev); errCode = cx231xx_init_ctrl_pin_status(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n", cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n",
__func__, errCode); __func__, errCode);
return errCode; return errCode;
} }
/* set AGC mode to Analog */ /* set AGC mode to Analog */
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", cx231xx_errdev
__func__, errCode); ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n",
__func__, errCode);
return errCode; return errCode;
} }
/* set all alternate settings to zero initially */ /* set all alternate settings to zero initially */
cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
cx231xx_set_alt_setting(dev, INDEX_VANC, 0); cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
cx231xx_set_alt_setting(dev, INDEX_HANC, 0); cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
if(dev->board.has_dvb) if (dev->board.has_dvb)
cx231xx_set_alt_setting(dev, INDEX_TS1, 0); cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
/* set the I2C master port to 3 on channel 1 */ /* set the I2C master port to 3 on channel 1 */
errCode = cx231xx_enable_i2c_for_tuner(dev, I2C_3); errCode = cx231xx_enable_i2c_for_tuner(dev, I2C_3);
return errCode; return errCode;
} }
EXPORT_SYMBOL_GPL(cx231xx_dev_init); EXPORT_SYMBOL_GPL(cx231xx_dev_init);
void cx231xx_dev_uninit(struct cx231xx *dev) void cx231xx_dev_uninit(struct cx231xx *dev)
{ {
/* Un Initialize I2C bus */ /* Un Initialize I2C bus */
cx231xx_i2c_unregister(&dev->i2c_bus[2]); cx231xx_i2c_unregister(&dev->i2c_bus[2]);
cx231xx_i2c_unregister(&dev->i2c_bus[1]); cx231xx_i2c_unregister(&dev->i2c_bus[1]);
cx231xx_i2c_unregister(&dev->i2c_bus[0]); cx231xx_i2c_unregister(&dev->i2c_bus[0]);
} }
EXPORT_SYMBOL_GPL(cx231xx_dev_uninit);
EXPORT_SYMBOL_GPL(cx231xx_dev_uninit);
/************************************************************************************ /************************************************************************************
* G P I O related functions * * G P I O related functions *
*************************************************************************************/ *************************************************************************************/
int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8* gpio_val, int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val,
u8 len, u8 request, u8 direction) u8 len, u8 request, u8 direction)
{ {
int status = 0; int status = 0;
VENDOR_REQUEST_IN ven_req; VENDOR_REQUEST_IN ven_req;
/* Set wValue */ /* Set wValue */
ven_req.wValue = (u16)(gpio_bit>>16 & 0xffff); ven_req.wValue = (u16) (gpio_bit >> 16 & 0xffff);
/* set request */ /* set request */
if(!request){ if (!request) {
if(direction) if (direction)
ven_req.bRequest = VRT_GET_GPIO; /* 0x8 gpio */ ven_req.bRequest = VRT_GET_GPIO; /* 0x8 gpio */
else else
ven_req.bRequest = VRT_SET_GPIO; /* 0x9 gpio */ ven_req.bRequest = VRT_SET_GPIO; /* 0x9 gpio */
} } else {
else { if (direction)
if(direction) ven_req.bRequest = VRT_GET_GPIE; /* 0xa gpie */
ven_req.bRequest = VRT_GET_GPIE; /* 0xa gpie */ else
else ven_req.bRequest = VRT_SET_GPIE; /* 0xb gpie */
ven_req.bRequest = VRT_SET_GPIE; /* 0xb gpie */ }
}
/* set index value */
ven_req.wIndex = (u16)(gpio_bit & 0xffff);
/* set wLength value */
ven_req.wLength = len;
/* set bData value */
ven_req.bData = 0;
/* set the buffer for read / write */
ven_req.pBuff = gpio_val;
/* set the direction */ /* set index value */
if(direction){ ven_req.wIndex = (u16) (gpio_bit & 0xffff);
ven_req.direction = USB_DIR_IN;
memset(ven_req.pBuff, 0x00, ven_req.wLength);
}
else
ven_req.direction = USB_DIR_OUT;
/* set wLength value */
ven_req.wLength = len;
/* set bData value */
ven_req.bData = 0;
/* call common vendor command request */ /* set the buffer for read / write */
status = cx231xx_send_vendor_cmd(dev, &ven_req); ven_req.pBuff = gpio_val;
if (status < 0)
{ /* set the direction */
cx231xx_info("UsbInterface::sendCommand, output buffer failed with status -%d\n", status); if (direction) {
} ven_req.direction = USB_DIR_IN;
memset(ven_req.pBuff, 0x00, ven_req.wLength);
} else
ven_req.direction = USB_DIR_OUT;
/* call common vendor command request */
status = cx231xx_send_vendor_cmd(dev, &ven_req);
if (status < 0) {
cx231xx_info
("UsbInterface::sendCommand, output buffer failed with status -%d\n",
status);
}
return status; return status;
} }
EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd); EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd);
...@@ -998,170 +1035,177 @@ EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd); ...@@ -998,170 +1035,177 @@ EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd);
*************************************************************************************/ *************************************************************************************/
int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode) int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode)
{ {
u8 value[4] = {0x0, 0x0, 0x0, 0x0}; u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
u32 tmp =0; u32 tmp = 0;
int status = 0; int status = 0;
status = cx231xx_read_ctrl_reg(dev,VRT_GET_REGISTER, address,value,4); status =
if(status < 0) cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, address, value, 4);
return status; if (status < 0)
return status;
tmp = *((u32 *)value); tmp = *((u32 *) value);
tmp |= mode; tmp |= mode;
value[0]=(u8) tmp; value[0] = (u8) tmp;
value[1]=(u8)(tmp>>8); value[1] = (u8) (tmp >> 8);
value[2]=(u8)(tmp>>16); value[2] = (u8) (tmp >> 16);
value[3]=(u8)(tmp>>24); value[3] = (u8) (tmp >> 24);
status = cx231xx_write_ctrl_reg(dev,VRT_SET_REGISTER, address,value,4); status =
cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, address, value, 4);
return status; return status;
} }
/************************************************************************************* /*************************************************************************************
* I 2 C Internal C O N T R O L functions * * I 2 C Internal C O N T R O L functions *
*************************************************************************************/ *************************************************************************************/
int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
u8 saddr_len, u32 *data, u8 data_len) u8 saddr_len, u32 * data, u8 data_len)
{ {
int status = 0; int status = 0;
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
u8 value[4] ={0,0,0,0}; u8 value[4] = { 0, 0, 0, 0 };
if(saddr_len == 0) if (saddr_len == 0)
saddr = 0; saddr = 0;
else if(saddr_len == 0) else if (saddr_len == 0)
saddr &= 0xff; saddr &= 0xff;
/* prepare xfer_data struct */ /* prepare xfer_data struct */
req_data.dev_addr = dev_addr >> 1; req_data.dev_addr = dev_addr >> 1;
req_data.direction = I2C_M_RD; req_data.direction = I2C_M_RD;
req_data.saddr_len = saddr_len; req_data.saddr_len = saddr_len;
req_data.saddr_dat = saddr; req_data.saddr_dat = saddr;
req_data.buf_size = data_len; req_data.buf_size = data_len;
req_data.p_buffer = (u8*)value; req_data.p_buffer = (u8 *) value;
/* usb send command */ /* usb send command */
status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data); status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
if(status >= 0) if (status >= 0) {
{ /* Copy the data read back to main buffer */
/* Copy the data read back to main buffer */ if (data_len == 1)
if(data_len == 1) *data = value[0];
*data = value[0]; else
else *data =
*data = value[0] | value[1] << 8 | value[2] << 16 | value[3] << 24; value[0] | value[1] << 8 | value[2] << 16 | value[3]
} << 24;
}
return status;
return status;
} }
int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr, int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
u8 saddr_len, u32 data, u8 data_len) u8 saddr_len, u32 data, u8 data_len)
{ {
int status = 0; int status = 0;
u8 value[4] ={0,0,0,0}; u8 value[4] = { 0, 0, 0, 0 };
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
value[0]=(u8)data; value[0] = (u8) data;
value[1]=(u8)(data>>8); value[1] = (u8) (data >> 8);
value[2]=(u8)(data>>16); value[2] = (u8) (data >> 16);
value[3]=(u8)(data>>24); value[3] = (u8) (data >> 24);
if(saddr_len == 0) if (saddr_len == 0)
saddr = 0; saddr = 0;
else if(saddr_len == 0) else if (saddr_len == 0)
saddr &= 0xff; saddr &= 0xff;
/* prepare xfer_data struct */ /* prepare xfer_data struct */
req_data.dev_addr = dev_addr >> 1; req_data.dev_addr = dev_addr >> 1;
req_data.direction = 0; req_data.direction = 0;
req_data.saddr_len = saddr_len; req_data.saddr_len = saddr_len;
req_data.saddr_dat = saddr; req_data.saddr_dat = saddr;
req_data.buf_size = data_len; req_data.buf_size = data_len;
req_data.p_buffer = value; req_data.p_buffer = value;
/* usb send command */ /* usb send command */
status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data); status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
return status; return status;
} }
int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size, u16 register_address, int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
u8 bit_start,u8 bit_end, u32 value) u16 register_address, u8 bit_start, u8 bit_end,
u32 value)
{ {
int status = 0; int status = 0;
u32 tmp; u32 tmp;
u32 mask = 0; u32 mask = 0;
int i; int i;
if (bit_start>(size-1) || bit_end>(size-1)) { if (bit_start > (size - 1) || bit_end > (size - 1)) {
return -1; return -1;
} }
if (size==8){
status = cx231xx_read_i2c_data(dev, dev_addr, register_address, 2, &tmp, 1);
} else {
status = cx231xx_read_i2c_data(dev, dev_addr, register_address, 2, &tmp, 4);
}
if (status < 0) {
return status;
}
mask = 1<<bit_end;
for (i=bit_end; i>bit_start&&i>0; i--) {
mask = mask + (1<<(i-1));
}
value <<= bit_start;
if (size==8)
{
tmp &= ~mask;
tmp |= value;
tmp &= 0xff;
status = cx231xx_write_i2c_data(dev, dev_addr, register_address, 2, tmp, 1);
}
else
{
tmp &= ~mask;
tmp |= value;
status = cx231xx_write_i2c_data(dev, dev_addr, register_address, 2, tmp, 4);
}
return status;
}
if (size == 8) {
status =
cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
&tmp, 1);
} else {
status =
cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
&tmp, 4);
}
if (status < 0) {
return status;
}
mask = 1 << bit_end;
for (i = bit_end; i > bit_start && i > 0; i--) {
mask = mask + (1 << (i - 1));
}
value <<= bit_start;
if (size == 8) {
tmp &= ~mask;
tmp |= value;
tmp &= 0xff;
status =
cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
tmp, 1);
} else {
tmp &= ~mask;
tmp |= value;
status =
cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
tmp, 4);
}
return status;
}
int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr, int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
u16 saddr, u32 mask, u32 value) u16 saddr, u32 mask, u32 value)
{ {
u32 temp; u32 temp;
int status = 0; int status = 0;
status = cx231xx_read_i2c_data(dev, dev_addr, saddr, 2, &temp, 4); status = cx231xx_read_i2c_data(dev, dev_addr, saddr, 2, &temp, 4);
if(status < 0) if (status < 0)
return status; return status;
temp &= ~mask; temp &= ~mask;
temp |= value; temp |= value;
status = cx231xx_write_i2c_data(dev, dev_addr, saddr, 2, temp, 4); status = cx231xx_write_i2c_data(dev, dev_addr, saddr, 2, temp, 4);
return status; return status;
} }
u32 cx231xx_set_field(u32 field_mask, u32 data) u32 cx231xx_set_field(u32 field_mask, u32 data)
{ {
u32 temp; u32 temp;
for (temp = field_mask; (temp & 1) == 0; temp >>= 1) { for (temp = field_mask; (temp & 1) == 0; temp >>= 1) {
data <<= 1; data <<= 1;
} }
return data; return data;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
DVB device driver for cx231xx DVB device driver for cx231xx
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "xc5000.h" #include "xc5000.h"
#include "dvb_dummy_fe.h" #include "dvb_dummy_fe.h"
MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -50,24 +49,22 @@ if (debug >= level) \ ...@@ -50,24 +49,22 @@ if (debug >= level) \
#define CX231XX_DVB_MAX_PACKETS 64 #define CX231XX_DVB_MAX_PACKETS 64
struct cx231xx_dvb { struct cx231xx_dvb {
struct dvb_frontend *frontend; struct dvb_frontend *frontend;
/* feed count management */ /* feed count management */
struct mutex lock; struct mutex lock;
int nfeeds; int nfeeds;
/* general boilerplate stuff */ /* general boilerplate stuff */
struct dvb_adapter adapter; struct dvb_adapter adapter;
struct dvb_demux demux; struct dvb_demux demux;
struct dmxdev dmxdev; struct dmxdev dmxdev;
struct dmx_frontend fe_hw; struct dmx_frontend fe_hw;
struct dmx_frontend fe_mem; struct dmx_frontend fe_mem;
struct dvb_net net; struct dvb_net net;
}; };
static inline void print_err_status(struct cx231xx *dev, int packet, int status)
static inline void print_err_status(struct cx231xx *dev,
int packet, int status)
{ {
char *errmsg = "Unknown"; char *errmsg = "Unknown";
...@@ -149,8 +146,8 @@ static int start_streaming(struct cx231xx_dvb *dvb) ...@@ -149,8 +146,8 @@ static int start_streaming(struct cx231xx_dvb *dvb)
return rc; return rc;
return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
CX231XX_DVB_NUM_BUFS, CX231XX_DVB_MAX_PACKETSIZE, CX231XX_DVB_NUM_BUFS,
dvb_isoc_copy); CX231XX_DVB_MAX_PACKETSIZE, dvb_isoc_copy);
} }
static int stop_streaming(struct cx231xx_dvb *dvb) static int stop_streaming(struct cx231xx_dvb *dvb)
...@@ -166,7 +163,7 @@ static int stop_streaming(struct cx231xx_dvb *dvb) ...@@ -166,7 +163,7 @@ static int stop_streaming(struct cx231xx_dvb *dvb)
static int start_feed(struct dvb_demux_feed *feed) static int start_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct cx231xx_dvb *dvb = demux->priv; struct cx231xx_dvb *dvb = demux->priv;
int rc, ret; int rc, ret;
...@@ -189,7 +186,7 @@ static int start_feed(struct dvb_demux_feed *feed) ...@@ -189,7 +186,7 @@ static int start_feed(struct dvb_demux_feed *feed)
static int stop_feed(struct dvb_demux_feed *feed) static int stop_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct cx231xx_dvb *dvb = demux->priv; struct cx231xx_dvb *dvb = demux->priv;
int err = 0; int err = 0;
...@@ -203,8 +200,6 @@ static int stop_feed(struct dvb_demux_feed *feed) ...@@ -203,8 +200,6 @@ static int stop_feed(struct dvb_demux_feed *feed)
return err; return err;
} }
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
{ {
...@@ -218,13 +213,11 @@ static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) ...@@ -218,13 +213,11 @@ static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static struct xc5000_config cnxt_rde250_tunerconfig = { static struct xc5000_config cnxt_rde250_tunerconfig = {
.i2c_address = 0x61, .i2c_address = 0x61,
.if_khz = 5380, .if_khz = 5380,
}; };
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#if 0 #if 0
static int attach_xc5000(u8 addr, struct cx231xx *dev) static int attach_xc5000(u8 addr, struct cx231xx *dev)
...@@ -234,13 +227,12 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) ...@@ -234,13 +227,12 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev)
struct xc5000_config cfg; struct xc5000_config cfg;
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap; cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap;
cfg.i2c_addr = addr; cfg.i2c_addr = addr;
if (!dev->dvb->frontend) { if (!dev->dvb->frontend) {
printk(KERN_ERR "%s/2: dvb frontend not attached. " printk(KERN_ERR "%s/2: dvb frontend not attached. "
"Can't attach xc5000\n", "Can't attach xc5000\n", dev->name);
dev->name);
return -EINVAL; return -EINVAL;
} }
...@@ -258,65 +250,65 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) ...@@ -258,65 +250,65 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev)
} }
#endif #endif
int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq ) int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
{ {
int status = 0; int status = 0;
if( (dev->dvb != NULL) && (dev->dvb->frontend != NULL) ){ if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
if(dops->set_analog_params != NULL) { if (dops->set_analog_params != NULL) {
struct analog_parameters params; struct analog_parameters params;
params.frequency = freq; params.frequency = freq;
params.std = dev->norm; params.std = dev->norm;
params.mode = 0 ; /* 0- Air; 1 - cable */ params.mode = 0; /* 0- Air; 1 - cable */
/*params.audmode = ; */ /*params.audmode = ; */
/* Set the analog parameters to set the frequency */
cx231xx_info("Setting Frequency for XC5000\n");
dops->set_analog_params(dev->dvb->frontend, &params);
}
/* Set the analog parameters to set the frequency */
cx231xx_info("Setting Frequency for XC5000\n");
dops->set_analog_params(dev->dvb->frontend, &params);
} }
}
return status; return status;
} }
int cx231xx_reset_analog_tuner(struct cx231xx *dev) int cx231xx_reset_analog_tuner(struct cx231xx *dev)
{ {
int status = 0; int status = 0;
if( (dev->dvb != NULL) && (dev->dvb->frontend != NULL) ){ if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
if(dops->init != NULL && !dev->xc_fw_load_done) { if (dops->init != NULL && !dev->xc_fw_load_done) {
cx231xx_info("Reloading firmware for XC5000\n"); cx231xx_info("Reloading firmware for XC5000\n");
status = dops->init(dev->dvb->frontend); status = dops->init(dev->dvb->frontend);
if(status == 0 ) { if (status == 0) {
dev->xc_fw_load_done = 1; dev->xc_fw_load_done = 1;
cx231xx_info("XC5000 firmware download completed\n"); cx231xx_info
} else { ("XC5000 firmware download completed\n");
dev->xc_fw_load_done = 0; } else {
cx231xx_info("XC5000 firmware download failed !!!\n"); dev->xc_fw_load_done = 0;
} cx231xx_info
("XC5000 firmware download failed !!!\n");
} }
} }
}
return status; return status;
} }
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static int register_dvb(struct cx231xx_dvb *dvb, static int register_dvb(struct cx231xx_dvb *dvb,
struct module *module, struct module *module,
struct cx231xx *dev, struct cx231xx *dev, struct device *device)
struct device *device)
{ {
int result; int result;
...@@ -326,7 +318,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -326,7 +318,8 @@ static int register_dvb(struct cx231xx_dvb *dvb,
result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
adapter_nr); adapter_nr);
if (result < 0) { if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", printk(KERN_WARNING
"%s: dvb_register_adapter failed (errno = %d)\n",
dev->name, result); dev->name, result);
goto fail_adapter; goto fail_adapter;
} }
...@@ -339,20 +332,21 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -339,20 +332,21 @@ static int register_dvb(struct cx231xx_dvb *dvb,
/* register frontend */ /* register frontend */
result = dvb_register_frontend(&dvb->adapter, dvb->frontend); result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
if (result < 0) { if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", printk(KERN_WARNING
"%s: dvb_register_frontend failed (errno = %d)\n",
dev->name, result); dev->name, result);
goto fail_frontend; goto fail_frontend;
} }
/* register demux stuff */ /* register demux stuff */
dvb->demux.dmx.capabilities = dvb->demux.dmx.capabilities =
DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_TS_FILTERING | DMX_SECTION_FILTERING |
DMX_MEMORY_BASED_FILTERING; DMX_MEMORY_BASED_FILTERING;
dvb->demux.priv = dvb; dvb->demux.priv = dvb;
dvb->demux.filternum = 256; dvb->demux.filternum = 256;
dvb->demux.feednum = 256; dvb->demux.feednum = 256;
dvb->demux.start_feed = start_feed; dvb->demux.start_feed = start_feed;
dvb->demux.stop_feed = stop_feed; dvb->demux.stop_feed = stop_feed;
result = dvb_dmx_init(&dvb->demux); result = dvb_dmx_init(&dvb->demux);
if (result < 0) { if (result < 0) {
...@@ -361,8 +355,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -361,8 +355,8 @@ static int register_dvb(struct cx231xx_dvb *dvb,
goto fail_dmx; goto fail_dmx;
} }
dvb->dmxdev.filternum = 256; dvb->dmxdev.filternum = 256;
dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.demux = &dvb->demux.dmx;
dvb->dmxdev.capabilities = 0; dvb->dmxdev.capabilities = 0;
result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
if (result < 0) { if (result < 0) {
...@@ -374,7 +368,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -374,7 +368,8 @@ static int register_dvb(struct cx231xx_dvb *dvb,
dvb->fe_hw.source = DMX_FRONTEND_0; dvb->fe_hw.source = DMX_FRONTEND_0;
result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
if (result < 0) { if (result < 0) {
printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", printk(KERN_WARNING
"%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
dev->name, result); dev->name, result);
goto fail_fe_hw; goto fail_fe_hw;
} }
...@@ -382,15 +377,17 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -382,15 +377,17 @@ static int register_dvb(struct cx231xx_dvb *dvb,
dvb->fe_mem.source = DMX_MEMORY_FE; dvb->fe_mem.source = DMX_MEMORY_FE;
result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
if (result < 0) { if (result < 0) {
printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", printk(KERN_WARNING
"%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
dev->name, result); dev->name, result);
goto fail_fe_mem; goto fail_fe_mem;
} }
result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
if (result < 0) { if (result < 0) {
printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", printk(KERN_WARNING
dev->name, result); "%s: connect_frontend failed (errno = %d)\n", dev->name,
result);
goto fail_fe_conn; goto fail_fe_conn;
} }
...@@ -398,20 +395,20 @@ static int register_dvb(struct cx231xx_dvb *dvb, ...@@ -398,20 +395,20 @@ static int register_dvb(struct cx231xx_dvb *dvb,
dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
return 0; return 0;
fail_fe_conn: fail_fe_conn:
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
fail_fe_mem: fail_fe_mem:
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
fail_fe_hw: fail_fe_hw:
dvb_dmxdev_release(&dvb->dmxdev); dvb_dmxdev_release(&dvb->dmxdev);
fail_dmxdev: fail_dmxdev:
dvb_dmx_release(&dvb->demux); dvb_dmx_release(&dvb->demux);
fail_dmx: fail_dmx:
dvb_unregister_frontend(dvb->frontend); dvb_unregister_frontend(dvb->frontend);
fail_frontend: fail_frontend:
dvb_frontend_detach(dvb->frontend); dvb_frontend_detach(dvb->frontend);
dvb_unregister_adapter(&dvb->adapter); dvb_unregister_adapter(&dvb->adapter);
fail_adapter: fail_adapter:
return result; return result;
} }
...@@ -427,7 +424,6 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) ...@@ -427,7 +424,6 @@ static void unregister_dvb(struct cx231xx_dvb *dvb)
dvb_unregister_adapter(&dvb->adapter); dvb_unregister_adapter(&dvb->adapter);
} }
static int dvb_init(struct cx231xx *dev) static int dvb_init(struct cx231xx *dev)
{ {
int result = 0; int result = 0;
...@@ -446,71 +442,70 @@ static int dvb_init(struct cx231xx *dev) ...@@ -446,71 +442,70 @@ static int dvb_init(struct cx231xx *dev)
} }
dev->dvb = dvb; dev->dvb = dvb;
dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
/* init frontend */ /* init frontend */
switch (dev->model) { switch (dev->model) {
case CX231XX_BOARD_CNXT_RDE_250: case CX231XX_BOARD_CNXT_RDE_250:
/* dev->dvb->frontend = dvb_attach(s5h1411_attach, /* dev->dvb->frontend = dvb_attach(s5h1411_attach,
&dvico_s5h1411_config, &dvico_s5h1411_config,
&dev->i2c_bus[1].i2c_adap);*/ &dev->i2c_bus[1].i2c_adap); */
dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
if(dev->dvb->frontend == NULL) { if (dev->dvb->frontend == NULL) {
printk(DRIVER_NAME ": Failed to attach dummy front end\n"); printk(DRIVER_NAME
result = -EINVAL; ": Failed to attach dummy front end\n");
goto out_free; result = -EINVAL;
} goto out_free;
}
/* define general-purpose callback pointer */
dvb->frontend->callback = cx231xx_tuner_callback; /* define general-purpose callback pointer */
dvb->frontend->callback = cx231xx_tuner_callback;
if(dvb_attach(xc5000_attach, dev->dvb->frontend,
&dev->i2c_bus[1].i2c_adap, if (dvb_attach(xc5000_attach, dev->dvb->frontend,
&cnxt_rde250_tunerconfig) < 0) { &dev->i2c_bus[1].i2c_adap,
result = -EINVAL; &cnxt_rde250_tunerconfig) < 0) {
goto out_free; result = -EINVAL;
} goto out_free;
}
break;
case CX231XX_BOARD_CNXT_RDU_250: break;
case CX231XX_BOARD_CNXT_RDU_250:
dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
if(dev->dvb->frontend == NULL) {
printk(DRIVER_NAME ": Failed to attach dummy front end\n"); if (dev->dvb->frontend == NULL) {
result = -EINVAL; printk(DRIVER_NAME
goto out_free; ": Failed to attach dummy front end\n");
} result = -EINVAL;
goto out_free;
/* define general-purpose callback pointer */ }
dvb->frontend->callback = cx231xx_tuner_callback;
/* define general-purpose callback pointer */
if(dvb_attach(xc5000_attach, dev->dvb->frontend, dvb->frontend->callback = cx231xx_tuner_callback;
&dev->i2c_bus[1].i2c_adap,
&cnxt_rde250_tunerconfig) < 0) { if (dvb_attach(xc5000_attach, dev->dvb->frontend,
result = -EINVAL; &dev->i2c_bus[1].i2c_adap,
goto out_free; &cnxt_rde250_tunerconfig) < 0) {
} result = -EINVAL;
break; goto out_free;
}
break;
default: default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
" isn't supported yet\n", " isn't supported yet\n", dev->name);
dev->name);
break; break;
} }
if (NULL == dvb->frontend) { if (NULL == dvb->frontend) {
printk(KERN_ERR printk(KERN_ERR
"%s/2: frontend initialization failed\n", "%s/2: frontend initialization failed\n", dev->name);
dev->name);
result = -EINVAL; result = -EINVAL;
goto out_free; goto out_free;
} }
/* register everything */ /* register everything */
result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
...@@ -521,7 +516,7 @@ static int dvb_init(struct cx231xx *dev) ...@@ -521,7 +516,7 @@ static int dvb_init(struct cx231xx *dev)
printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
return 0; return 0;
out_free: out_free:
cx231xx_set_mode(dev, CX231XX_SUSPEND); cx231xx_set_mode(dev, CX231XX_SUSPEND);
kfree(dvb); kfree(dvb);
dev->dvb = NULL; dev->dvb = NULL;
...@@ -544,7 +539,7 @@ static int dvb_fini(struct cx231xx *dev) ...@@ -544,7 +539,7 @@ static int dvb_fini(struct cx231xx *dev)
} }
static struct cx231xx_ops dvb_ops = { static struct cx231xx_ops dvb_ops = {
.id = CX231XX_DVB, .id = CX231XX_DVB,
.name = "Cx231xx dvb Extension", .name = "Cx231xx dvb Extension",
.init = dvb_init, .init = dvb_init,
.fini = dvb_fini, .fini = dvb_fini,
...@@ -562,4 +557,3 @@ static void __exit cx231xx_dvb_unregister(void) ...@@ -562,4 +557,3 @@ static void __exit cx231xx_dvb_unregister(void)
module_init(cx231xx_dvb_register); module_init(cx231xx_dvb_register);
module_exit(cx231xx_dvb_unregister); module_exit(cx231xx_dvb_unregister);
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
Based on Cx23885 driver Based on Cx23885 driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "cx231xx.h" #include "cx231xx.h"
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
static unsigned int i2c_scan; static unsigned int i2c_scan;
...@@ -40,7 +39,6 @@ static unsigned int i2c_debug; ...@@ -40,7 +39,6 @@ static unsigned int i2c_debug;
module_param(i2c_debug, int, 0644); module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
#define dprintk1(lvl, fmt, args...) \ #define dprintk1(lvl, fmt, args...) \
do { \ do { \
if (i2c_debug >= lvl) { \ if (i2c_debug >= lvl) { \
...@@ -56,116 +54,119 @@ do { \ ...@@ -56,116 +54,119 @@ do { \
} \ } \
} while (0) } while (0)
/* /*
* cx231xx_i2c_send_bytes() * cx231xx_i2c_send_bytes()
*/ */
int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg) const struct i2c_msg *msg)
{ {
struct cx231xx_i2c *bus = i2c_adap->algo_data; struct cx231xx_i2c *bus = i2c_adap->algo_data;
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
int status = 0; int status = 0;
u16 size = 0; u16 size = 0;
u8 loop = 0; u8 loop = 0;
u8 saddr_len = 1; u8 saddr_len = 1;
u8 *buf_ptr = NULL; u8 *buf_ptr = NULL;
u16 saddr = 0; u16 saddr = 0;
u8 need_gpio = 0; u8 need_gpio = 0;
if ((bus->nr == 1) && (msg->addr == 0x61)
if( (bus->nr ==1) && (msg->addr == 0x61) && (dev->tuner_type == TUNER_XC5000) ) { && (dev->tuner_type == TUNER_XC5000)) {
size = msg->len; size = msg->len;
if( size == 2 ) { /* register write sub addr*/ if (size == 2) { /* register write sub addr */
/* Just writing sub address will cause problem to XC5000 /* Just writing sub address will cause problem to XC5000
So ignore the request */ So ignore the request */
return 0; return 0;
} else if( size == 4 ) { /* register write with sub addr*/ } else if (size == 4) { /* register write with sub addr */
if(msg->len >= 2 ) if (msg->len >= 2)
saddr = msg->buf[0] << 8 | msg->buf[1]; saddr = msg->buf[0] << 8 | msg->buf[1];
else if ( msg->len == 1 ) else if (msg->len == 1)
saddr = msg->buf[0]; saddr = msg->buf[0];
switch(saddr) { switch (saddr) {
case 0x0000: /* start tuner calibration mode */ case 0x0000: /* start tuner calibration mode */
need_gpio = 1; need_gpio = 1;
dev->xc_fw_load_done = 1; /* FW Loading is done */ dev->xc_fw_load_done = 1; /* FW Loading is done */
break; break;
case 0x000D: /* Set signal source */ case 0x000D: /* Set signal source */
case 0x0001: /* Set TV standard - Video */ case 0x0001: /* Set TV standard - Video */
case 0x0002: /* Set TV standard - Audio */ case 0x0002: /* Set TV standard - Audio */
case 0x0003: /* Set RF Frequency */ case 0x0003: /* Set RF Frequency */
need_gpio = 1; need_gpio = 1;
break; break;
default: default:
if(dev->xc_fw_load_done) if (dev->xc_fw_load_done)
need_gpio = 1; need_gpio = 1;
break; break;
} }
if(need_gpio ) { if (need_gpio) {
dprintk1(1, " GPIO W R I T E : addr 0x%x, len %d, saddr 0x%x\n", dprintk1(1,
msg->addr, msg->len, saddr); " GPIO W R I T E : addr 0x%x, len %d, saddr 0x%x\n",
msg->addr, msg->len, saddr);
return dev->cx231xx_gpio_i2c_write(dev, msg->addr, msg->buf, msg->len);
} return dev->cx231xx_gpio_i2c_write(dev,
msg->addr,
} msg->buf,
msg->len);
/* special case for Xc5000 tuner case */ }
saddr_len = 1;
}
/* adjust the length to correct length */
size -= saddr_len; /* special case for Xc5000 tuner case */
buf_ptr = (u8*) (msg->buf + 1 ); saddr_len = 1;
do { /* adjust the length to correct length */
/* prepare xfer_data struct */ size -= saddr_len;
req_data.dev_addr = msg->addr; buf_ptr = (u8 *) (msg->buf + 1);
req_data.direction = msg->flags;
req_data.saddr_len = saddr_len; do {
req_data.saddr_dat = msg->buf[0]; /* prepare xfer_data struct */
req_data.buf_size = size > 16 ? 16: size; req_data.dev_addr = msg->addr;
req_data.p_buffer = (u8*)(buf_ptr + loop * 16); req_data.direction = msg->flags;
req_data.saddr_len = saddr_len;
bus->i2c_nostop = (size > 16) ? 1: 0; req_data.saddr_dat = msg->buf[0];
bus->i2c_reserve = (loop == 0) ? 0: 1; req_data.buf_size = size > 16 ? 16 : size;
req_data.p_buffer = (u8 *) (buf_ptr + loop * 16);
/* usb send command */
status = dev->cx231xx_send_usb_command(bus, &req_data); bus->i2c_nostop = (size > 16) ? 1 : 0;
loop++; bus->i2c_reserve = (loop == 0) ? 0 : 1;
if( size >= 16 ) /* usb send command */
size -= 16; status = dev->cx231xx_send_usb_command(bus, &req_data);
else loop++;
size = 0;
if (size >= 16)
}while( size > 0 ); size -= 16;
else
bus->i2c_nostop = 0; size = 0;
bus->i2c_reserve = 0;
} while (size > 0);
} else { /* regular case */
bus->i2c_nostop = 0;
/* prepare xfer_data struct */ bus->i2c_reserve = 0;
req_data.dev_addr = msg->addr;
req_data.direction = msg->flags; } else { /* regular case */
req_data.saddr_len = 0;
req_data.saddr_dat = 0; /* prepare xfer_data struct */
req_data.buf_size = msg->len; req_data.dev_addr = msg->addr;
req_data.p_buffer = msg->buf; req_data.direction = msg->flags;
req_data.saddr_len = 0;
/* usb send command */ req_data.saddr_dat = 0;
status = dev->cx231xx_send_usb_command(bus, &req_data); req_data.buf_size = msg->len;
} req_data.p_buffer = msg->buf;
return status < 0 ? status: 0; /* usb send command */
status = dev->cx231xx_send_usb_command(bus, &req_data);
}
return status < 0 ? status : 0;
} }
/* /*
...@@ -173,75 +174,85 @@ int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, ...@@ -173,75 +174,85 @@ int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
* read a byte from the i2c device * read a byte from the i2c device
*/ */
static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap, static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg) const struct i2c_msg *msg)
{ {
struct cx231xx_i2c *bus = i2c_adap->algo_data; struct cx231xx_i2c *bus = i2c_adap->algo_data;
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
int status = 0; int status = 0;
u16 saddr = 0; u16 saddr = 0;
u8 need_gpio = 0; u8 need_gpio = 0;
if((bus->nr ==1) && (msg->addr == 0x61) && dev->tuner_type == TUNER_XC5000) { if ((bus->nr == 1) && (msg->addr == 0x61)
&& dev->tuner_type == TUNER_XC5000) {
if(msg->len == 2 )
saddr = msg->buf[0] << 8 | msg->buf[1]; if (msg->len == 2)
else if ( msg->len == 1 ) saddr = msg->buf[0] << 8 | msg->buf[1];
saddr = msg->buf[0]; else if (msg->len == 1)
saddr = msg->buf[0];
if( dev->xc_fw_load_done) {
if (dev->xc_fw_load_done) {
switch(saddr) {
case 0x0009: /* BUSY check */ switch (saddr) {
dprintk1(1, " GPIO R E A D : Special case BUSY check \n"); case 0x0009: /* BUSY check */
/* Try to read BUSY register, just set it to zero */ dprintk1(1,
msg->buf[0] = 0; " GPIO R E A D : Special case BUSY check \n");
if(msg->len == 2 ) /* Try to read BUSY register, just set it to zero */
msg->buf[1] = 0; msg->buf[0] = 0;
return 0; if (msg->len == 2)
case 0x0004: /* read Lock status */ msg->buf[1] = 0;
need_gpio = 1; return 0;
break; case 0x0004: /* read Lock status */
need_gpio = 1;
} break;
if(need_gpio) { }
/* this is a special case to handle Xceive tuner clock stretch issue
with gpio based I2C interface */ if (need_gpio) {
dprintk1(1, " GPIO R E A D : addr 0x%x, len %d, saddr 0x%x\n", /* this is a special case to handle Xceive tuner clock stretch issue
msg->addr, msg->len, msg->buf[0] << 8| msg->buf[1]); with gpio based I2C interface */
status = dev->cx231xx_gpio_i2c_write(dev, msg->addr, msg->buf, msg->len); dprintk1(1,
status = dev->cx231xx_gpio_i2c_read(dev, msg->addr, msg->buf, msg->len); " GPIO R E A D : addr 0x%x, len %d, saddr 0x%x\n",
return status; msg->addr, msg->len,
} msg->buf[0] << 8 | msg->buf[1]);
} status =
dev->cx231xx_gpio_i2c_write(dev, msg->addr,
/* prepare xfer_data struct */ msg->buf,
req_data.dev_addr = msg->addr; msg->len);
req_data.direction = msg->flags; status =
req_data.saddr_len = msg->len; dev->cx231xx_gpio_i2c_read(dev, msg->addr,
req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1]; msg->buf,
req_data.buf_size = msg->len; msg->len);
req_data.p_buffer = msg->buf; return status;
}
/* usb send command */ }
status = dev->cx231xx_send_usb_command(bus, &req_data);
/* prepare xfer_data struct */
} else { req_data.dev_addr = msg->addr;
req_data.direction = msg->flags;
/* prepare xfer_data struct */ req_data.saddr_len = msg->len;
req_data.dev_addr = msg->addr; req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1];
req_data.direction = msg->flags; req_data.buf_size = msg->len;
req_data.saddr_len = 0; req_data.p_buffer = msg->buf;
req_data.saddr_dat = 0;
req_data.buf_size = msg->len; /* usb send command */
req_data.p_buffer = msg->buf; status = dev->cx231xx_send_usb_command(bus, &req_data);
/* usb send command */ } else {
status = dev->cx231xx_send_usb_command(bus, &req_data);
} /* prepare xfer_data struct */
req_data.dev_addr = msg->addr;
return status < 0 ? status: 0; req_data.direction = msg->flags;
req_data.saddr_len = 0;
req_data.saddr_dat = 0;
req_data.buf_size = msg->len;
req_data.p_buffer = msg->buf;
/* usb send command */
status = dev->cx231xx_send_usb_command(bus, &req_data);
}
return status < 0 ? status : 0;
} }
/* /*
...@@ -249,56 +260,65 @@ static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap, ...@@ -249,56 +260,65 @@ static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
* read a byte from the i2c device * read a byte from the i2c device
*/ */
static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap, static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg1, const struct i2c_msg *msg2) const struct i2c_msg *msg1,
const struct i2c_msg *msg2)
{ {
struct cx231xx_i2c *bus = i2c_adap->algo_data; struct cx231xx_i2c *bus = i2c_adap->algo_data;
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
int status = 0; int status = 0;
u16 saddr = 0; u16 saddr = 0;
u8 need_gpio = 0; u8 need_gpio = 0;
if(msg1->len == 2 ) if (msg1->len == 2)
saddr = msg1->buf[0] << 8 | msg1->buf[1]; saddr = msg1->buf[0] << 8 | msg1->buf[1];
else if ( msg1->len == 1 ) else if (msg1->len == 1)
saddr = msg1->buf[0]; saddr = msg1->buf[0];
if ( (bus->nr ==1) && (msg2->addr == 0x61) && dev->tuner_type == TUNER_XC5000) { if ((bus->nr == 1) && (msg2->addr == 0x61)
&& dev->tuner_type == TUNER_XC5000) {
if( (msg2->len < 16) ) {
if ((msg2->len < 16)) {
dprintk1(1, " i2c_read : addr 0x%x, len %d, subaddr 0x%x, leng %d\n",
msg2->addr, msg2->len, saddr, msg1->len); dprintk1(1,
" i2c_read : addr 0x%x, len %d, subaddr 0x%x, leng %d\n",
switch(saddr) { msg2->addr, msg2->len, saddr, msg1->len);
case 0x0008: /* read FW load status */
need_gpio = 1; switch (saddr) {
break; case 0x0008: /* read FW load status */
case 0x0004: /* read Lock status */ need_gpio = 1;
need_gpio = 1; break;
break; case 0x0004: /* read Lock status */
} need_gpio = 1;
break;
if(need_gpio ) { }
status = dev->cx231xx_gpio_i2c_write(dev, msg1->addr, msg1->buf, msg1->len);
status = dev->cx231xx_gpio_i2c_read(dev, msg2->addr, msg2->buf, msg2->len); if (need_gpio) {
return status; status =
} dev->cx231xx_gpio_i2c_write(dev, msg1->addr,
} msg1->buf,
} msg1->len);
status =
/* prepare xfer_data struct */ dev->cx231xx_gpio_i2c_read(dev, msg2->addr,
req_data.dev_addr = msg2->addr; msg2->buf,
req_data.direction = msg2->flags; msg2->len);
req_data.saddr_len = msg1->len; return status;
req_data.saddr_dat = saddr; }
req_data.buf_size = msg2->len; }
req_data.p_buffer = msg2->buf; }
/* usb send command */ /* prepare xfer_data struct */
status = dev->cx231xx_send_usb_command(bus, &req_data); req_data.dev_addr = msg2->addr;
req_data.direction = msg2->flags;
return status < 0 ? status: 0; req_data.saddr_len = msg1->len;
req_data.saddr_dat = saddr;
req_data.buf_size = msg2->len;
req_data.p_buffer = msg2->buf;
/* usb send command */
status = dev->cx231xx_send_usb_command(bus, &req_data);
return status < 0 ? status : 0;
} }
/* /*
...@@ -306,25 +326,25 @@ static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap, ...@@ -306,25 +326,25 @@ static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
* check if there is a i2c_device at the supplied address * check if there is a i2c_device at the supplied address
*/ */
static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg) const struct i2c_msg *msg)
{ {
struct cx231xx_i2c *bus = i2c_adap->algo_data; struct cx231xx_i2c *bus = i2c_adap->algo_data;
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
struct cx231xx_i2c_xfer_data req_data; struct cx231xx_i2c_xfer_data req_data;
int status = 0; int status = 0;
/* prepare xfer_data struct */ /* prepare xfer_data struct */
req_data.dev_addr = msg->addr; req_data.dev_addr = msg->addr;
req_data.direction = msg->flags; req_data.direction = msg->flags;
req_data.saddr_len = 0; req_data.saddr_len = 0;
req_data.saddr_dat = 0; req_data.saddr_dat = 0;
req_data.buf_size = 0; req_data.buf_size = 0;
req_data.p_buffer = NULL; req_data.p_buffer = NULL;
/* usb send command */ /* usb send command */
status = dev->cx231xx_send_usb_command(bus, &req_data); status = dev->cx231xx_send_usb_command(bus, &req_data);
return status < 0 ? status: 0; return status < 0 ? status : 0;
} }
/* /*
...@@ -332,7 +352,7 @@ static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, ...@@ -332,7 +352,7 @@ static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap,
* the main i2c transfer function * the main i2c transfer function
*/ */
static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msgs[], int num) struct i2c_msg msgs[], int num)
{ {
struct cx231xx_i2c *bus = i2c_adap->algo_data; struct cx231xx_i2c *bus = i2c_adap->algo_data;
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
...@@ -348,7 +368,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -348,7 +368,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
dprintk2(2, "%s %s addr=%x len=%d:", dprintk2(2, "%s %s addr=%x len=%d:",
(msgs[i].flags & I2C_M_RD) ? "read" : "write", (msgs[i].flags & I2C_M_RD) ? "read" : "write",
i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
if (!msgs[i].len) { /* no len: check only for device presence */ if (!msgs[i].len) { /* no len: check only for device presence */
rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]); rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]);
if (rc < 0) { if (rc < 0) {
dprintk2(2, " no device\n"); dprintk2(2, " no device\n");
...@@ -363,21 +383,24 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -363,21 +383,24 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
printk(" %02x", msgs[i].buf[byte]); printk(" %02x", msgs[i].buf[byte]);
} }
} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
msgs[i].addr == msgs[i + 1].addr && (msgs[i].len <= 2) && (bus->nr < 2)) { msgs[i].addr == msgs[i + 1].addr
&& (msgs[i].len <= 2) && (bus->nr < 2)) {
/* read bytes */ /* read bytes */
rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, &msgs[i], &msgs[i+1]); rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
&msgs[i],
&msgs[i + 1]);
if (i2c_debug >= 2) { if (i2c_debug >= 2) {
for (byte = 0; byte < msgs[i].len; byte++) for (byte = 0; byte < msgs[i].len; byte++)
printk(" %02x", msgs[i].buf[byte]); printk(" %02x", msgs[i].buf[byte]);
} }
i++; i++;
} else { } else {
/* write bytes */ /* write bytes */
if (i2c_debug >= 2) { if (i2c_debug >= 2) {
for (byte = 0; byte < msgs[i].len; byte++) for (byte = 0; byte < msgs[i].len; byte++)
printk(" %02x", msgs[i].buf[byte]); printk(" %02x", msgs[i].buf[byte]);
} }
rc = cx231xx_i2c_send_bytes(i2c_adap,&msgs[i]); rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]);
} }
if (rc < 0) if (rc < 0)
goto err; goto err;
...@@ -386,7 +409,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -386,7 +409,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
return num; return num;
err: err:
dprintk2(2, " ERROR: %i\n", rc); dprintk2(2, " ERROR: %i\n", rc);
return rc; return rc;
} }
...@@ -408,7 +431,7 @@ static u32 functionality(struct i2c_adapter *adap) ...@@ -408,7 +431,7 @@ static u32 functionality(struct i2c_adapter *adap)
*/ */
static int attach_inform(struct i2c_client *client) static int attach_inform(struct i2c_client *client)
{ {
struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter); struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
switch (client->addr << 1) { switch (client->addr << 1) {
...@@ -422,16 +445,16 @@ static int attach_inform(struct i2c_client *client) ...@@ -422,16 +445,16 @@ static int attach_inform(struct i2c_client *client)
dprintk1(1, "attach_inform: eeprom detected.\n"); dprintk1(1, "attach_inform: eeprom detected.\n");
break; break;
case 0x60: case 0x60:
dprintk1(1, "attach_inform: Colibri detected.\n"); dprintk1(1, "attach_inform: Colibri detected.\n");
break;
case 0x8e:
{
struct IR_i2c *ir = i2c_get_clientdata(client);
dprintk1(1, "attach_inform: IR detected (%s).\n",
ir->phys);
cx231xx_set_ir(dev, ir);
break; break;
} case 0x8e:
{
struct IR_i2c *ir = i2c_get_clientdata(client);
dprintk1(1, "attach_inform: IR detected (%s).\n",
ir->phys);
cx231xx_set_ir(dev, ir);
break;
}
case 0x80: case 0x80:
case 0x88: case 0x88:
dprintk1(1, "attach_inform: Hammerhead detected.\n"); dprintk1(1, "attach_inform: Hammerhead detected.\n");
...@@ -442,7 +465,7 @@ static int attach_inform(struct i2c_client *client) ...@@ -442,7 +465,7 @@ static int attach_inform(struct i2c_client *client)
dev->tuner_addr = client->addr; dev->tuner_addr = client->addr;
dprintk1(1, "attach inform: detected I2C address %x\n", dprintk1(1, "attach inform: detected I2C address %x\n",
client->addr << 1); client->addr << 1);
} }
return 0; return 0;
...@@ -454,9 +477,8 @@ static int detach_inform(struct i2c_client *client) ...@@ -454,9 +477,8 @@ static int detach_inform(struct i2c_client *client)
return 0; return 0;
} }
static struct i2c_algorithm cx231xx_algo = { static struct i2c_algorithm cx231xx_algo = {
.master_xfer = cx231xx_i2c_xfer, .master_xfer = cx231xx_i2c_xfer,
.functionality = functionality, .functionality = functionality,
}; };
...@@ -466,7 +488,7 @@ static struct i2c_adapter cx231xx_adap_template = { ...@@ -466,7 +488,7 @@ static struct i2c_adapter cx231xx_adap_template = {
.name = "cx231xx", .name = "cx231xx",
.id = I2C_HW_B_CX231XX, .id = I2C_HW_B_CX231XX,
.algo = &cx231xx_algo, .algo = &cx231xx_algo,
.client_register = attach_inform, .client_register = attach_inform,
.client_unregister = detach_inform, .client_unregister = detach_inform,
}; };
...@@ -483,9 +505,9 @@ static struct i2c_client cx231xx_client_template = { ...@@ -483,9 +505,9 @@ static struct i2c_client cx231xx_client_template = {
static char *i2c_devs[128] = { static char *i2c_devs[128] = {
[0x60 >> 1] = "colibri", [0x60 >> 1] = "colibri",
[0x88 >> 1] = "hammerhead", [0x88 >> 1] = "hammerhead",
[0x8e >> 1] = "CIR", [0x8e >> 1] = "CIR",
[0x32 >> 1] = "GeminiIII", [0x32 >> 1] = "GeminiIII",
[0x02 >> 1] = "Aquarius", [0x02 >> 1] = "Aquarius",
[0xa0 >> 1] = "eeprom", [0xa0 >> 1] = "eeprom",
[0xc0 >> 1] = "tuner/XC3028", [0xc0 >> 1] = "tuner/XC3028",
[0xc2 >> 1] = "tuner/XC5000", [0xc2 >> 1] = "tuner/XC5000",
...@@ -500,23 +522,25 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c) ...@@ -500,23 +522,25 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c)
unsigned char buf; unsigned char buf;
int i, rc; int i, rc;
cx231xx_info(": Checking for I2C devices ..\n"); cx231xx_info(": Checking for I2C devices ..\n");
for (i = 0; i < 128; i++) { for (i = 0; i < 128; i++) {
c->addr = i; c->addr = i;
rc = i2c_master_recv(c, &buf, 0); rc = i2c_master_recv(c, &buf, 0);
if (rc < 0) if (rc < 0)
continue; continue;
cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n",
dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); dev->name, i << 1,
i2c_devs[i] ? i2c_devs[i] : "???");
} }
cx231xx_info(": Completed Checking for I2C devices.\n"); cx231xx_info(": Completed Checking for I2C devices.\n");
} }
/* /*
* cx231xx_i2c_call_clients() * cx231xx_i2c_call_clients()
* send commands to all attached i2c devices * send commands to all attached i2c devices
*/ */
void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd, void *arg) void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd,
void *arg)
{ {
/* struct cx231xx *dev = bus->dev; */ /* struct cx231xx *dev = bus->dev; */
...@@ -530,23 +554,20 @@ void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd, void *a ...@@ -530,23 +554,20 @@ void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd, void *a
*/ */
int cx231xx_i2c_register(struct cx231xx_i2c *bus) int cx231xx_i2c_register(struct cx231xx_i2c *bus)
{ {
struct cx231xx *dev = bus->dev; struct cx231xx *dev = bus->dev;
BUG_ON(!dev->cx231xx_send_usb_command); BUG_ON(!dev->cx231xx_send_usb_command);
cx231xx_info("%s(bus = %d)\n", __func__, bus->nr); cx231xx_info("%s(bus = %d)\n", __func__, bus->nr);
memcpy(&bus->i2c_adap, &cx231xx_adap_template, memcpy(&bus->i2c_adap, &cx231xx_adap_template, sizeof(bus->i2c_adap));
sizeof(bus->i2c_adap)); memcpy(&bus->i2c_algo, &cx231xx_algo, sizeof(bus->i2c_algo));
memcpy(&bus->i2c_algo, &cx231xx_algo,
sizeof(bus->i2c_algo));
memcpy(&bus->i2c_client, &cx231xx_client_template, memcpy(&bus->i2c_client, &cx231xx_client_template,
sizeof(bus->i2c_client)); sizeof(bus->i2c_client));
bus->i2c_adap.dev.parent = &dev->udev->dev; bus->i2c_adap.dev.parent = &dev->udev->dev;
strlcpy(bus->i2c_adap.name, bus->dev->name, strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
sizeof(bus->i2c_adap.name));
bus->i2c_algo.data = bus; bus->i2c_algo.data = bus;
bus->i2c_adap.algo_data = bus; bus->i2c_adap.algo_data = bus;
...@@ -561,7 +582,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) ...@@ -561,7 +582,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus)
cx231xx_do_i2c_scan(dev, &bus->i2c_client); cx231xx_do_i2c_scan(dev, &bus->i2c_client);
} else } else
cx231xx_warn("%s: i2c bus %d register FAILED\n", cx231xx_warn("%s: i2c bus %d register FAILED\n",
dev->name, bus->nr); dev->name, bus->nr);
return bus->i2c_rc; return bus->i2c_rc;
} }
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
handle cx231xx IR remotes via linux kernel input layer. handle cx231xx IR remotes via linux kernel input layer.
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
< This is a place holder for IR now.> < This is a place holder for IR now.>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "cx231xx.h" #include "cx231xx.h"
static unsigned int ir_debug; static unsigned int ir_debug;
module_param(ir_debug, int, 0644); module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
...@@ -71,11 +70,9 @@ struct cx231xx_IR { ...@@ -71,11 +70,9 @@ struct cx231xx_IR {
unsigned int last_readcount; unsigned int last_readcount;
unsigned int repeat_interval; unsigned int repeat_interval;
int (*get_key)(struct cx231xx_IR *, struct cx231xx_ir_poll_result *); int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *);
}; };
/********************************************************** /**********************************************************
Polling code for cx231xx Polling code for cx231xx
**********************************************************/ **********************************************************/
...@@ -187,17 +184,16 @@ int cx231xx_ir_init(struct cx231xx *dev) ...@@ -187,17 +184,16 @@ int cx231xx_ir_init(struct cx231xx *dev)
/* Setup the proper handler based on the chip */ /* Setup the proper handler based on the chip */
switch (dev->chip_id) { switch (dev->chip_id) {
default: default:
printk("Unrecognized cx231xx chip id: IR not supported\n"); printk("Unrecognized cx231xx chip id: IR not supported\n");
goto err_out_free; goto err_out_free;
} }
/* This is how often we ask the chip for IR information */ /* This is how often we ask the chip for IR information */
ir->polling = 100; /* ms */ ir->polling = 100; /* ms */
/* init input device */ /* init input device */
snprintf(ir->name, sizeof(ir->name), "cx231xx IR (%s)", snprintf(ir->name, sizeof(ir->name), "cx231xx IR (%s)", dev->name);
dev->name);
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys));
...@@ -223,10 +219,10 @@ int cx231xx_ir_init(struct cx231xx *dev) ...@@ -223,10 +219,10 @@ int cx231xx_ir_init(struct cx231xx *dev)
goto err_out_stop; goto err_out_stop;
return 0; return 0;
err_out_stop: err_out_stop:
cx231xx_ir_stop(ir); cx231xx_ir_stop(ir);
dev->ir = NULL; dev->ir = NULL;
err_out_free: err_out_free:
input_free_device(input_dev); input_free_device(input_dev);
kfree(ir); kfree(ir);
return err; return err;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define _CX231XX_REG_H #define _CX231XX_REG_H
/***************************************************************************** /*****************************************************************************
* VBI codes * * VBI codes *
*****************************************************************************/ *****************************************************************************/
#define SAV_ACTIVE_VIDEO_FIELD1 0x80 #define SAV_ACTIVE_VIDEO_FIELD1 0x80
...@@ -37,16 +37,16 @@ ...@@ -37,16 +37,16 @@
#define SAV_VBLANK_FIELD2 0xE0 #define SAV_VBLANK_FIELD2 0xE0
#define EAV_VBLANK_FIELD2 0xF0 #define EAV_VBLANK_FIELD2 0xF0
#define SAV_VBI_FIELD1 0x20 #define SAV_VBI_FIELD1 0x20
#define EAV_VBI_FIELD1 0x30 #define EAV_VBI_FIELD1 0x30
#define SAV_VBI_FIELD2 0x60 #define SAV_VBI_FIELD2 0x60
#define EAV_VBI_FIELD2 0x70 #define EAV_VBI_FIELD2 0x70
/*****************************************************************************/ /*****************************************************************************/
/* Audio ADC Registers */ /* Audio ADC Registers */
#define CH_PWR_CTRL1 0x0000000E #define CH_PWR_CTRL1 0x0000000E
#define CH_PWR_CTRL2 0x0000000F #define CH_PWR_CTRL2 0x0000000F
/*****************************************************************************/ /*****************************************************************************/
#define HOST_REG1 0x000 #define HOST_REG1 0x000
...@@ -60,7 +60,6 @@ ...@@ -60,7 +60,6 @@
/*****************************************************************************/ /*****************************************************************************/
#define HOST_REG2 0x001 #define HOST_REG2 0x001
/*****************************************************************************/ /*****************************************************************************/
#define HOST_REG3 0x002 #define HOST_REG3 0x002
...@@ -231,7 +230,6 @@ ...@@ -231,7 +230,6 @@
/* Reserved [3:1] */ /* Reserved [3:1] */
#define FLD_CIR_TEST_DIS 0x00000001 #define FLD_CIR_TEST_DIS 0x00000001
/*****************************************************************************/ /*****************************************************************************/
#define TEST_CTRL2 0x148 #define TEST_CTRL2 0x148
#define FLD_TSXCLK_POL_CTL 0x80000000 #define FLD_TSXCLK_POL_CTL 0x80000000
...@@ -257,7 +255,6 @@ ...@@ -257,7 +255,6 @@
#define FLD_FLTRN_BIST_TST_DONE 0x00000008 #define FLD_FLTRN_BIST_TST_DONE 0x00000008
#define FLD_VID_BIST_TST_DONE 0x00000007 #define FLD_VID_BIST_TST_DONE 0x00000007
/*****************************************************************************/ /*****************************************************************************/
/* DirectIF registers definition have been moved to DIF_reg.h */ /* DirectIF registers definition have been moved to DIF_reg.h */
/*****************************************************************************/ /*****************************************************************************/
...@@ -268,7 +265,7 @@ ...@@ -268,7 +265,7 @@
#define FLD_AFD_FORCE_PAL 0x04000000 #define FLD_AFD_FORCE_PAL 0x04000000
#define FLD_AFD_PALM_SEL 0x03000000 #define FLD_AFD_PALM_SEL 0x03000000
#define FLD_CKILL_MODE 0x00300000 #define FLD_CKILL_MODE 0x00300000
#define FLD_COMB_NOTCH_MODE 0x00c00000 /* bit[19:18] */ #define FLD_COMB_NOTCH_MODE 0x00c00000 /* bit[19:18] */
#define FLD_CLR_LOCK_STAT 0x00020000 #define FLD_CLR_LOCK_STAT 0x00020000
#define FLD_FAST_LOCK_MD 0x00010000 #define FLD_FAST_LOCK_MD 0x00010000
#define FLD_WCEN 0x00008000 #define FLD_WCEN 0x00008000
...@@ -662,7 +659,6 @@ ...@@ -662,7 +659,6 @@
#define FLD_PLL_KI 0x00FF0000 #define FLD_PLL_KI 0x00FF0000
#define FLD_PLL_MAX_OFFSET 0x0000FFFF #define FLD_PLL_MAX_OFFSET 0x0000FFFF
/*****************************************************************************/ /*****************************************************************************/
#define HTL_CTRL 0x498 #define HTL_CTRL 0x498
/* Reserved [31:24] */ /* Reserved [31:24] */
...@@ -771,13 +767,12 @@ ...@@ -771,13 +767,12 @@
#define FLD_FIELD_PHASE_LIMIT 0x000000F0 #define FLD_FIELD_PHASE_LIMIT 0x000000F0
#define FLD_HEAD_SW_DET_LIMIT 0x0000000F #define FLD_HEAD_SW_DET_LIMIT 0x0000000F
/*****************************************************************************/ /*****************************************************************************/
#define DL_CTL 0x800 #define DL_CTL 0x800
#define DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */ #define DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
#define DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */ #define DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
#define DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */ #define DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
#define DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */ #define DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
/* Reserved [31:5] */ /* Reserved [31:5] */
#define FLD_START_8051 0x10000000 #define FLD_START_8051 0x10000000
#define FLD_DL_ENABLE 0x08000000 #define FLD_DL_ENABLE 0x08000000
...@@ -795,8 +790,8 @@ ...@@ -795,8 +790,8 @@
#define AUD_BUILD_NUM 0x806 #define AUD_BUILD_NUM 0x806
#define AUD_VER_NUM 0x807 #define AUD_VER_NUM 0x807
#define STD_DET_CTL 0x808 #define STD_DET_CTL 0x808
#define STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */ #define STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
#define STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */ #define STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
#define FLD_SPARE_CTL0 0xFF000000 #define FLD_SPARE_CTL0 0xFF000000
#define FLD_DIS_DBX 0x00800000 #define FLD_DIS_DBX 0x00800000
#define FLD_DIS_BTSC 0x00400000 #define FLD_DIS_BTSC 0x00400000
...@@ -1424,7 +1419,6 @@ ...@@ -1424,7 +1419,6 @@
#define FLD_I2S_OUT_WS_SEL 0x00000020 #define FLD_I2S_OUT_WS_SEL 0x00000020
#define FLD_I2S_OUT_BCN_DEL 0x0000001F #define FLD_I2S_OUT_BCN_DEL 0x0000001F
/*****************************************************************************/ /*****************************************************************************/
#define AC97_CTL 0x91C #define AC97_CTL 0x91C
/* Reserved [31:26] */ /* Reserved [31:26] */
...@@ -1437,7 +1431,6 @@ ...@@ -1437,7 +1431,6 @@
/* Reserved [7:1] */ /* Reserved [7:1] */
#define FLD_AC97_SHUTDOWN 0x00000001 #define FLD_AC97_SHUTDOWN 0x00000001
/* Cx231xx redefine */ /* Cx231xx redefine */
#define QPSK_IAGC_CTL1 0x94c #define QPSK_IAGC_CTL1 0x94c
#define QPSK_IAGC_CTL2 0x950 #define QPSK_IAGC_CTL2 0x950
...@@ -1450,7 +1443,6 @@ ...@@ -1450,7 +1443,6 @@
#define QPSK_EQ_CTL 0x96c #define QPSK_EQ_CTL 0x96c
#define QPSK_LOCK_CTL 0x970 #define QPSK_LOCK_CTL 0x970
/*****************************************************************************/ /*****************************************************************************/
#define FM1_DFT_CTL 0x9A8 #define FM1_DFT_CTL 0x9A8
#define FLD_FM1_DFT_THRESHOLD 0xFFFF0000 #define FLD_FM1_DFT_THRESHOLD 0xFFFF0000
...@@ -1494,8 +1486,6 @@ ...@@ -1494,8 +1486,6 @@
/* Reserved [15:6] */ /* Reserved [15:6] */
#define FLD_AFE_VGA_OUT 0x0000003F #define FLD_AFE_VGA_OUT 0x0000003F
/*****************************************************************************/ /*****************************************************************************/
#define MTS_GAIN_STATUS 0x9BC #define MTS_GAIN_STATUS 0x9BC
/* Reserved [31:14] */ /* Reserved [31:14] */
...@@ -1538,19 +1528,18 @@ ...@@ -1538,19 +1528,18 @@
#define VID_FMT_SECAM 12 #define VID_FMT_SECAM 12
#define VID_FMT_SECAM_60 13 #define VID_FMT_SECAM_60 13
#define INPUT_MODE_CVBS_0 0 /* INPUT_MODE_VALUE(0) */ #define INPUT_MODE_CVBS_0 0 /* INPUT_MODE_VALUE(0) */
#define INPUT_MODE_YC_1 1 /* INPUT_MODE_VALUE(1) */ #define INPUT_MODE_YC_1 1 /* INPUT_MODE_VALUE(1) */
#define INPUT_MODE_YC2_2 2 /* INPUT_MODE_VALUE(2) */ #define INPUT_MODE_YC2_2 2 /* INPUT_MODE_VALUE(2) */
#define INPUT_MODE_YUV_3 3 /* INPUT_MODE_VALUE(3) */ #define INPUT_MODE_YUV_3 3 /* INPUT_MODE_VALUE(3) */
#define LUMA_LPF_LOW_BANDPASS 0 /* 0.6Mhz lowpass filter bandwidth */ #define LUMA_LPF_LOW_BANDPASS 0 /* 0.6Mhz lowpass filter bandwidth */
#define LUMA_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz lowpass filter bandwidth */ #define LUMA_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz lowpass filter bandwidth */
#define LUMA_LPF_HIGH_BANDPASS 2 /* 1.5Mhz lowpass filter bandwidth */ #define LUMA_LPF_HIGH_BANDPASS 2 /* 1.5Mhz lowpass filter bandwidth */
#define UV_LPF_LOW_BANDPASS 0 /* 0.6Mhz lowpass filter bandwidth */ #define UV_LPF_LOW_BANDPASS 0 /* 0.6Mhz lowpass filter bandwidth */
#define UV_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz lowpass filter bandwidth */ #define UV_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz lowpass filter bandwidth */
#define UV_LPF_HIGH_BANDPASS 2 /* 1.5Mhz lowpass filter bandwidth */ #define UV_LPF_HIGH_BANDPASS 2 /* 1.5Mhz lowpass filter bandwidth */
#define TWO_TAP_FILT 0 #define TWO_TAP_FILT 0
#define THREE_TAP_FILT 1 #define THREE_TAP_FILT 1
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
cx231xx_vbi.c - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx_vbi.c - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on cx88 driver Based on cx88 driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -39,8 +39,7 @@ ...@@ -39,8 +39,7 @@
#include "cx231xx.h" #include "cx231xx.h"
#include "cx231xx-vbi.h" #include "cx231xx-vbi.h"
static inline void print_err_status(struct cx231xx *dev, static inline void print_err_status(struct cx231xx *dev, int packet, int status)
int packet, int status)
{ {
char *errmsg = "Unknown"; char *errmsg = "Unknown";
...@@ -71,10 +70,11 @@ static inline void print_err_status(struct cx231xx *dev, ...@@ -71,10 +70,11 @@ static inline void print_err_status(struct cx231xx *dev,
break; break;
} }
if (packet < 0) { if (packet < 0) {
cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status, errmsg); cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status,
errmsg);
} else { } else {
cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n", cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n",
packet, status, errmsg); packet, status, errmsg);
} }
} }
...@@ -83,12 +83,12 @@ static inline void print_err_status(struct cx231xx *dev, ...@@ -83,12 +83,12 @@ static inline void print_err_status(struct cx231xx *dev,
*/ */
static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
{ {
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
struct cx231xx_dmaqueue *dma_q = urb->context; struct cx231xx_dmaqueue *dma_q = urb->context;
int rc = 1; int rc = 1;
unsigned char *p_buffer; unsigned char *p_buffer;
u32 bytes_parsed = 0, buffer_size = 0; u32 bytes_parsed = 0, buffer_size = 0;
u8 sav_eav = 0; u8 sav_eav = 0;
if (!dev) if (!dev)
return 0; return 0;
...@@ -104,60 +104,58 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) ...@@ -104,60 +104,58 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
buf = dev->vbi_mode.isoc_ctl.buf; buf = dev->vbi_mode.isoc_ctl.buf;
/* get buffer pointer and length */ /* get buffer pointer and length */
p_buffer = urb->transfer_buffer; p_buffer = urb->transfer_buffer;
buffer_size = urb->actual_length; buffer_size = urb->actual_length;
if (buffer_size > 0) { if (buffer_size > 0) {
bytes_parsed = 0; bytes_parsed = 0;
if(dma_q->is_partial_line) { if (dma_q->is_partial_line) {
/* Handle the case where we were working on a partial line */ /* Handle the case where we were working on a partial line */
sav_eav = dma_q->last_sav; sav_eav = dma_q->last_sav;
} else { } else {
/* Check for a SAV/EAV overlapping the buffer boundary */ /* Check for a SAV/EAV overlapping the buffer boundary */
sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer, dma_q->partial_buf, &bytes_parsed); sav_eav =
} cx231xx_find_boundary_SAV_EAV(p_buffer,
dma_q->partial_buf,
sav_eav &= 0xF0; &bytes_parsed);
/* Get the first line if we have some portion of an SAV/EAV from the last buffer }
or a partial line */
if(sav_eav) { sav_eav &= 0xF0;
bytes_parsed += cx231xx_get_vbi_line(dev, dma_q, /* Get the first line if we have some portion of an SAV/EAV from the last buffer
sav_eav, /* SAV/EAV */ or a partial line */
p_buffer + bytes_parsed, /* p_buffer */ if (sav_eav) {
buffer_size - bytes_parsed); /* buffer size */ bytes_parsed += cx231xx_get_vbi_line(dev, dma_q, sav_eav, /* SAV/EAV */
} p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed); /* buffer size */
/* Now parse data that is completely in this buffer */ }
dma_q->is_partial_line = 0;
/* Now parse data that is completely in this buffer */
while(bytes_parsed < buffer_size) dma_q->is_partial_line = 0;
{
u32 bytes_used = 0; while (bytes_parsed < buffer_size) {
u32 bytes_used = 0;
sav_eav = cx231xx_find_next_SAV_EAV(
p_buffer + bytes_parsed, /* p_buffer */ sav_eav = cx231xx_find_next_SAV_EAV(p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed, /* buffer size */ buffer_size - bytes_parsed, /* buffer size */
&bytes_used); /* Receives bytes used to get SAV/EAV */ &bytes_used); /* Receives bytes used to get SAV/EAV */
bytes_parsed += bytes_used; bytes_parsed += bytes_used;
sav_eav &= 0xF0; sav_eav &= 0xF0;
if(sav_eav && (bytes_parsed < buffer_size)) if (sav_eav && (bytes_parsed < buffer_size)) {
{ bytes_parsed += cx231xx_get_vbi_line(dev, dma_q, sav_eav, /* SAV/EAV */
bytes_parsed += cx231xx_get_vbi_line(dev, dma_q, p_buffer + bytes_parsed, /* p_buffer */
sav_eav, /* SAV/EAV */ buffer_size - bytes_parsed); /* buffer size */
p_buffer + bytes_parsed, /* p_buffer */ }
buffer_size - bytes_parsed); /* buffer size */ }
}
} /* Save the last four bytes of the buffer so we can check the buffer boundary
condition next time */
/* Save the last four bytes of the buffer so we can check the buffer boundary memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
condition next time */ bytes_parsed = 0;
memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
bytes_parsed = 0;
} }
return rc; return rc;
...@@ -168,25 +166,26 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) ...@@ -168,25 +166,26 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
static int static int
vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
u32 height = 0; u32 height = 0;
height = ((dev->norm & V4L2_STD_625_50) ? height = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES) ; PAL_VBI_LINES : NTSC_VBI_LINES);
*size = ( dev->width * height * 2); *size = (dev->width * height * 2);
if (0 == *count) if (0 == *count)
*count = CX231XX_DEF_VBI_BUF; *count = CX231XX_DEF_VBI_BUF;
if (*count < CX231XX_MIN_BUF) if (*count < CX231XX_MIN_BUF)
*count = CX231XX_MIN_BUF; *count = CX231XX_MIN_BUF;
/* call VBI setup if required */ /* call VBI setup if required */
/* cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f); /* cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f);
*/ */
return 0; return 0;
} }
...@@ -194,8 +193,8 @@ vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *s ...@@ -194,8 +193,8 @@ vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *s
/* This is called *without* dev->slock held; please keep it that way */ /* This is called *without* dev->slock held; please keep it that way */
static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
unsigned long flags = 0; unsigned long flags = 0;
if (in_interrupt()) if (in_interrupt())
BUG(); BUG();
...@@ -208,7 +207,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) ...@@ -208,7 +207,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
This should be safe; by the time we get here, the buffer isn't This should be safe; by the time we get here, the buffer isn't
queued anymore. If we ever start marking the buffers as queued anymore. If we ever start marking the buffers as
VIDEOBUF_ACTIVE, it won't be, though. VIDEOBUF_ACTIVE, it won't be, though.
*/ */
spin_lock_irqsave(&dev->vbi_mode.slock, flags); spin_lock_irqsave(&dev->vbi_mode.slock, flags);
if (dev->vbi_mode.isoc_ctl.buf == buf) if (dev->vbi_mode.isoc_ctl.buf == buf)
dev->vbi_mode.isoc_ctl.buf = NULL; dev->vbi_mode.isoc_ctl.buf = NULL;
...@@ -220,25 +219,26 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) ...@@ -220,25 +219,26 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
static int static int
vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
enum v4l2_field field) enum v4l2_field field)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
struct cx231xx *dev = fh->dev; container_of(vb, struct cx231xx_buffer, vb);
int rc = 0, urb_init = 0; struct cx231xx *dev = fh->dev;
u32 height = 0; int rc = 0, urb_init = 0;
u32 height = 0;
height = ((dev->norm & V4L2_STD_625_50) ? height = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES) ; PAL_VBI_LINES : NTSC_VBI_LINES);
buf->vb.size = ( (dev->width << 1) * height ); buf->vb.size = ((dev->width << 1) * height);
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL; return -EINVAL;
buf->vb.width = dev->width; buf->vb.width = dev->width;
buf->vb.height = height; buf->vb.height = height;
buf->vb.field = field; buf->vb.field = field;
buf->vb.field = V4L2_FIELD_SEQ_TB; buf->vb.field = V4L2_FIELD_SEQ_TB;
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
rc = videobuf_iolock(vq, &buf->vb, NULL); rc = videobuf_iolock(vq, &buf->vb, NULL);
...@@ -251,8 +251,9 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, ...@@ -251,8 +251,9 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
if (urb_init) { if (urb_init) {
rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS, rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
CX231XX_NUM_VBI_BUFS, dev->vbi_mode.alt_max_pkt_size[0], CX231XX_NUM_VBI_BUFS,
cx231xx_isoc_vbi_copy); dev->vbi_mode.alt_max_pkt_size[0],
cx231xx_isoc_vbi_copy);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
} }
...@@ -260,7 +261,7 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, ...@@ -260,7 +261,7 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
buf->vb.state = VIDEOBUF_PREPARED; buf->vb.state = VIDEOBUF_PREPARED;
return 0; return 0;
fail: fail:
free_buffer(vq, buf); free_buffer(vq, buf);
return rc; return rc;
} }
...@@ -268,10 +269,11 @@ fail: ...@@ -268,10 +269,11 @@ fail:
static void static void
vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{ {
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
struct cx231xx_fh *fh = vq->priv_data; container_of(vb, struct cx231xx_buffer, vb);
struct cx231xx *dev = fh->dev; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq; struct cx231xx *dev = fh->dev;
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
buf->vb.state = VIDEOBUF_QUEUED; buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->vb.queue, &vidq->active); list_add_tail(&buf->vb.queue, &vidq->active);
...@@ -279,29 +281,27 @@ vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) ...@@ -279,29 +281,27 @@ vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
} }
static void vbi_buffer_release(struct videobuf_queue *vq, static void vbi_buffer_release(struct videobuf_queue *vq,
struct videobuf_buffer *vb) struct videobuf_buffer *vb)
{ {
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
/* container_of(vb, struct cx231xx_buffer, vb);
struct cx231xx_fh *fh = vq->priv_data; /*
struct cx231xx *dev = (struct cx231xx *)fh->dev; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = (struct cx231xx *)fh->dev;
cx231xx_info(DRIVER_NAME "cx231xx: called vbi_buffer_release\n"); cx231xx_info(DRIVER_NAME "cx231xx: called vbi_buffer_release\n");
*/ */
free_buffer(vq, buf); free_buffer(vq, buf);
} }
struct videobuf_queue_ops cx231xx_vbi_qops = { struct videobuf_queue_ops cx231xx_vbi_qops = {
.buf_setup = vbi_buffer_setup, .buf_setup = vbi_buffer_setup,
.buf_prepare = vbi_buffer_prepare, .buf_prepare = vbi_buffer_prepare,
.buf_queue = vbi_buffer_queue, .buf_queue = vbi_buffer_queue,
.buf_release = vbi_buffer_release, .buf_release = vbi_buffer_release,
}; };
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
URB control URB control
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
...@@ -311,23 +311,24 @@ struct videobuf_queue_ops cx231xx_vbi_qops = { ...@@ -311,23 +311,24 @@ struct videobuf_queue_ops cx231xx_vbi_qops = {
*/ */
static void cx231xx_irq_vbi_callback(struct urb *urb) static void cx231xx_irq_vbi_callback(struct urb *urb)
{ {
struct cx231xx_dmaqueue *dma_q = urb->context; struct cx231xx_dmaqueue *dma_q = urb->context;
struct cx231xx_video_mode *vmode = container_of(dma_q, struct cx231xx_video_mode, vidq); struct cx231xx_video_mode *vmode =
struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode); container_of(dma_q, struct cx231xx_video_mode, vidq);
struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
int rc; int rc;
switch (urb->status) {
switch (urb->status) { case 0: /* success */
case 0: /* success */ case -ETIMEDOUT: /* NAK */
case -ETIMEDOUT: /* NAK */ break;
break; case -ECONNRESET: /* kill */
case -ECONNRESET: /* kill */ case -ENOENT:
case -ENOENT: case -ESHUTDOWN:
case -ESHUTDOWN: return;
return; default: /* error */
default: /* error */ cx231xx_err(DRIVER_NAME "urb completition error %d.\n",
cx231xx_err(DRIVER_NAME "urb completition error %d.\n", urb->status); urb->status);
break; break;
} }
/* Copy data from URB */ /* Copy data from URB */
...@@ -341,7 +342,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) ...@@ -341,7 +342,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb)
urb->status = usb_submit_urb(urb, GFP_ATOMIC); urb->status = usb_submit_urb(urb, GFP_ATOMIC);
if (urb->status) { if (urb->status) {
cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n", cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n",
urb->status); urb->status);
} }
} }
...@@ -353,21 +354,23 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) ...@@ -353,21 +354,23 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
struct urb *urb; struct urb *urb;
int i; int i;
cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n"); cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n");
dev->vbi_mode.isoc_ctl.nfields = -1; dev->vbi_mode.isoc_ctl.nfields = -1;
for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) { for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
urb = dev->vbi_mode.isoc_ctl.urb[i]; urb = dev->vbi_mode.isoc_ctl.urb[i];
if (urb) { if (urb) {
if (!irqs_disabled()) if (!irqs_disabled())
usb_kill_urb(urb); usb_kill_urb(urb);
else else
usb_unlink_urb(urb); usb_unlink_urb(urb);
if (dev->vbi_mode.isoc_ctl.transfer_buffer[i]) { if (dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
kfree(dev->vbi_mode.isoc_ctl.transfer_buffer[i]); kfree(dev->vbi_mode.isoc_ctl.
dev->vbi_mode.isoc_ctl.transfer_buffer[i] = NULL; transfer_buffer[i]);
dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
NULL;
} }
usb_free_urb(urb); usb_free_urb(urb);
dev->vbi_mode.isoc_ctl.urb[i] = NULL; dev->vbi_mode.isoc_ctl.urb[i] = NULL;
...@@ -384,14 +387,16 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) ...@@ -384,14 +387,16 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
cx231xx_capture_start(dev, 0, Vbi); cx231xx_capture_start(dev, 0, Vbi);
} }
EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc); EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc);
/* /*
* Allocate URBs and start IRQ * Allocate URBs and start IRQ
*/ */
int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
int num_bufs, int max_pkt_size, int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct cx231xx *dev, struct urb *urb)) int (*isoc_copy) (struct cx231xx * dev,
struct urb * urb))
{ {
struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq; struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq;
int i; int i;
...@@ -404,31 +409,33 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, ...@@ -404,31 +409,33 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
/* De-allocates all pending stuff */ /* De-allocates all pending stuff */
cx231xx_uninit_vbi_isoc(dev); cx231xx_uninit_vbi_isoc(dev);
/* clear if any halt */ /* clear if any halt */
usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr)); usb_clear_halt(dev->udev,
usb_rcvbulkpipe(dev->udev,
dev->vbi_mode.end_point_addr));
dev->vbi_mode.isoc_ctl.isoc_copy = isoc_copy; dev->vbi_mode.isoc_ctl.isoc_copy = isoc_copy;
dev->vbi_mode.isoc_ctl.num_bufs = num_bufs; dev->vbi_mode.isoc_ctl.num_bufs = num_bufs;
dma_q->pos = 0; dma_q->pos = 0;
dma_q->is_partial_line = 0; dma_q->is_partial_line = 0;
dma_q->last_sav = 0; dma_q->last_sav = 0;
dma_q->current_field = -1; dma_q->current_field = -1;
dma_q->bytes_left_in_line = dev->width << 1; dma_q->bytes_left_in_line = dev->width << 1;
dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ? dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES) ; PAL_VBI_LINES : NTSC_VBI_LINES);
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
for(i = 0; i < 8 ; i++) for (i = 0; i < 8; i++)
dma_q->partial_buf[i] = 0; dma_q->partial_buf[i] = 0;
dev->vbi_mode.isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); dev->vbi_mode.isoc_ctl.urb =
kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
if (!dev->vbi_mode.isoc_ctl.urb) { if (!dev->vbi_mode.isoc_ctl.urb) {
cx231xx_errdev("cannot alloc memory for usb buffers\n"); cx231xx_errdev("cannot alloc memory for usb buffers\n");
return -ENOMEM; return -ENOMEM;
} }
dev->vbi_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, dev->vbi_mode.isoc_ctl.transfer_buffer =
GFP_KERNEL); kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
if (!dev->vbi_mode.isoc_ctl.transfer_buffer) { if (!dev->vbi_mode.isoc_ctl.transfer_buffer) {
cx231xx_errdev("cannot allocate memory for usbtransfer\n"); cx231xx_errdev("cannot allocate memory for usbtransfer\n");
kfree(dev->vbi_mode.isoc_ctl.urb); kfree(dev->vbi_mode.isoc_ctl.urb);
...@@ -445,27 +452,29 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, ...@@ -445,27 +452,29 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
urb = usb_alloc_urb(0, GFP_KERNEL); urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) { if (!urb) {
cx231xx_err(DRIVER_NAME ": cannot alloc isoc_ctl.urb %i\n", i); cx231xx_err(DRIVER_NAME
": cannot alloc isoc_ctl.urb %i\n", i);
cx231xx_uninit_vbi_isoc(dev); cx231xx_uninit_vbi_isoc(dev);
return -ENOMEM; return -ENOMEM;
} }
dev->vbi_mode.isoc_ctl.urb[i] = urb; dev->vbi_mode.isoc_ctl.urb[i] = urb;
urb->transfer_flags = 0; urb->transfer_flags = 0;
dev->vbi_mode.isoc_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
kzalloc(sb_size, GFP_KERNEL);
if (!dev->vbi_mode.isoc_ctl.transfer_buffer[i]) { if (!dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
cx231xx_err(DRIVER_NAME ": unable to allocate %i bytes for transfer" cx231xx_err(DRIVER_NAME
" buffer %i%s\n", ": unable to allocate %i bytes for transfer"
sb_size, i, " buffer %i%s\n", sb_size, i,
in_interrupt()?" while in int":""); in_interrupt()? " while in int" : "");
cx231xx_uninit_vbi_isoc(dev); cx231xx_uninit_vbi_isoc(dev);
return -ENOMEM; return -ENOMEM;
} }
pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr); pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr);
usb_fill_bulk_urb(urb, dev->udev, pipe, usb_fill_bulk_urb(urb, dev->udev, pipe,
dev->vbi_mode.isoc_ctl.transfer_buffer[i], sb_size, dev->vbi_mode.isoc_ctl.transfer_buffer[i],
cx231xx_irq_vbi_callback, dma_q); sb_size, cx231xx_irq_vbi_callback, dma_q);
} }
init_waitqueue_head(&dma_q->wq); init_waitqueue_head(&dma_q->wq);
...@@ -474,55 +483,58 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, ...@@ -474,55 +483,58 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) { for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
rc = usb_submit_urb(dev->vbi_mode.isoc_ctl.urb[i], GFP_ATOMIC); rc = usb_submit_urb(dev->vbi_mode.isoc_ctl.urb[i], GFP_ATOMIC);
if (rc) { if (rc) {
cx231xx_err(DRIVER_NAME ": submit of urb %i failed (error=%i)\n", i, cx231xx_err(DRIVER_NAME
rc); ": submit of urb %i failed (error=%i)\n", i,
rc);
cx231xx_uninit_vbi_isoc(dev); cx231xx_uninit_vbi_isoc(dev);
return rc; return rc;
} }
} }
cx231xx_capture_start(dev, 1, Vbi); cx231xx_capture_start(dev, 1, Vbi);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(cx231xx_init_vbi_isoc);
EXPORT_SYMBOL_GPL(cx231xx_init_vbi_isoc);
u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_get_vbi_line(struct cx231xx * dev, struct cx231xx_dmaqueue * dma_q,
u8 sav_eav, u8 *p_buffer, u32 buffer_size) u8 sav_eav, u8 * p_buffer, u32 buffer_size)
{ {
u32 bytes_copied = 0; u32 bytes_copied = 0;
int current_field = -1; int current_field = -1;
switch(sav_eav) { switch (sav_eav) {
case SAV_VBI_FIELD1: case SAV_VBI_FIELD1:
current_field = 1; current_field = 1;
break; break;
case SAV_VBI_FIELD2: case SAV_VBI_FIELD2:
current_field = 2; current_field = 2;
break; break;
default: default:
break; break;
} }
if(current_field < 0 ) if (current_field < 0)
return bytes_copied; return bytes_copied;
dma_q->last_sav = sav_eav; dma_q->last_sav = sav_eav;
bytes_copied = cx231xx_copy_vbi_line(dev, dma_q, p_buffer, buffer_size, current_field); bytes_copied =
cx231xx_copy_vbi_line(dev, dma_q, p_buffer, buffer_size,
current_field);
return bytes_copied; return bytes_copied;
} }
/* /*
* Announces that a buffer were filled and request the next * Announces that a buffer were filled and request the next
*/ */
static inline void vbi_buffer_filled(struct cx231xx *dev, static inline void vbi_buffer_filled(struct cx231xx *dev,
struct cx231xx_dmaqueue *dma_q, struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer *buf) struct cx231xx_buffer *buf)
{ {
/* Advice that buffer was filled */ /* Advice that buffer was filled */
/* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */ /* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */
...@@ -537,80 +549,83 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, ...@@ -537,80 +549,83 @@ static inline void vbi_buffer_filled(struct cx231xx *dev,
wake_up(&buf->vb.done); wake_up(&buf->vb.done);
} }
u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_line, u32 length, int field_number) u8 * p_line, u32 length, int field_number)
{ {
u32 bytes_to_copy; u32 bytes_to_copy;
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
u32 _line_size = dev->width * 2; u32 _line_size = dev->width * 2;
if( dma_q->current_field != field_number ) { if (dma_q->current_field != field_number) {
cx231xx_reset_vbi_buffer(dev, dma_q); cx231xx_reset_vbi_buffer(dev, dma_q);
} }
/* get the buffer pointer */ /* get the buffer pointer */
buf = dev->vbi_mode.isoc_ctl.buf; buf = dev->vbi_mode.isoc_ctl.buf;
/* Remember the field number for next time */ /* Remember the field number for next time */
dma_q->current_field = field_number; dma_q->current_field = field_number;
bytes_to_copy = dma_q->bytes_left_in_line; bytes_to_copy = dma_q->bytes_left_in_line;
if(bytes_to_copy > length) if (bytes_to_copy > length)
bytes_to_copy = length; bytes_to_copy = length;
if(dma_q->lines_completed >= dma_q->lines_per_field) { if (dma_q->lines_completed >= dma_q->lines_per_field) {
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->bytes_left_in_line -= bytes_to_copy;
dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ? 0 : 1; dma_q->is_partial_line =
return 0; (dma_q->bytes_left_in_line == 0) ? 0 : 1;
} return 0;
}
dma_q->is_partial_line = 1; dma_q->is_partial_line = 1;
/* If we don't have a buffer, just return the number of bytes we would /* If we don't have a buffer, just return the number of bytes we would
have copied if we had a buffer. */ have copied if we had a buffer. */
if(!buf) { if (!buf) {
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->bytes_left_in_line -= bytes_to_copy;
dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ? 0 : 1; dma_q->is_partial_line =
return bytes_to_copy; (dma_q->bytes_left_in_line == 0) ? 0 : 1;
} return bytes_to_copy;
}
/* copy the data to video buffer */ /* copy the data to video buffer */
cx231xx_do_vbi_copy(dev, dma_q, p_line, bytes_to_copy); cx231xx_do_vbi_copy(dev, dma_q, p_line, bytes_to_copy);
dma_q->pos += bytes_to_copy; dma_q->pos += bytes_to_copy;
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->bytes_left_in_line -= bytes_to_copy;
if(dma_q->bytes_left_in_line == 0) { if (dma_q->bytes_left_in_line == 0) {
dma_q->bytes_left_in_line = _line_size; dma_q->bytes_left_in_line = _line_size;
dma_q->lines_completed++; dma_q->lines_completed++;
dma_q->is_partial_line = 0; dma_q->is_partial_line = 0;
if(cx231xx_is_vbi_buffer_done(dev, dma_q) && buf ) { if (cx231xx_is_vbi_buffer_done(dev, dma_q) && buf) {
vbi_buffer_filled(dev, dma_q, buf); vbi_buffer_filled(dev, dma_q, buf);
dma_q->pos = 0; dma_q->pos = 0;
buf = NULL; buf = NULL;
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
} }
} }
return bytes_to_copy; return bytes_to_copy;
} }
/* /*
* video-buf generic routine to get the next available buffer * video-buf generic routine to get the next available buffer
*/ */
static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer **buf) struct cx231xx_buffer **buf)
{ {
struct cx231xx_video_mode *vmode = container_of(dma_q, struct cx231xx_video_mode, vidq); struct cx231xx_video_mode *vmode =
struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode); container_of(dma_q, struct cx231xx_video_mode, vidq);
struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
char *outp; char *outp;
if (list_empty(&dma_q->active)) { if (list_empty(&dma_q->active)) {
cx231xx_err(DRIVER_NAME ": No active queue to serve\n"); cx231xx_err(DRIVER_NAME ": No active queue to serve\n");
dev->vbi_mode.isoc_ctl.buf = NULL; dev->vbi_mode.isoc_ctl.buf = NULL;
*buf = NULL; *buf = NULL;
return; return;
...@@ -628,66 +643,70 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, ...@@ -628,66 +643,70 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
return; return;
} }
void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
void cx231xx_reset_vbi_buffer(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q) struct cx231xx_dmaqueue *dma_q)
{ {
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
buf = dev->vbi_mode.isoc_ctl.buf; buf = dev->vbi_mode.isoc_ctl.buf;
if(buf == NULL) { if (buf == NULL) {
/* first try to get the buffer */ /* first try to get the buffer */
get_next_vbi_buf(dma_q, &buf); get_next_vbi_buf(dma_q, &buf);
dma_q->pos = 0; dma_q->pos = 0;
dma_q->current_field = -1; dma_q->current_field = -1;
} }
dma_q->bytes_left_in_line = dev->width << 1; dma_q->bytes_left_in_line = dev->width << 1;
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
} }
int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_buffer, u32 bytes_to_copy) u8 * p_buffer, u32 bytes_to_copy)
{ {
u8 *p_out_buffer = NULL; u8 *p_out_buffer = NULL;
u32 current_line_bytes_copied = 0; u32 current_line_bytes_copied = 0;
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
u32 _line_size = dev->width << 1; u32 _line_size = dev->width << 1;
void *startwrite; void *startwrite;
int offset, lencopy; int offset, lencopy;
buf = dev->vbi_mode.isoc_ctl.buf; buf = dev->vbi_mode.isoc_ctl.buf;
if (buf == NULL) { if (buf == NULL) {
return -1; return -1;
} }
p_out_buffer = videobuf_to_vmalloc(&buf->vb); p_out_buffer = videobuf_to_vmalloc(&buf->vb);
if(dma_q->bytes_left_in_line != _line_size ) { if (dma_q->bytes_left_in_line != _line_size) {
current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line; current_line_bytes_copied =
} _line_size - dma_q->bytes_left_in_line;
}
offset = ( dma_q->lines_completed * _line_size ) + current_line_bytes_copied; offset =
(dma_q->lines_completed * _line_size) + current_line_bytes_copied;
/* prepare destination address */ /* prepare destination address */
startwrite = p_out_buffer + offset; startwrite = p_out_buffer + offset;
lencopy = dma_q->bytes_left_in_line > bytes_to_copy ? bytes_to_copy : dma_q->bytes_left_in_line; lencopy =
dma_q->bytes_left_in_line >
bytes_to_copy ? bytes_to_copy : dma_q->bytes_left_in_line;
memcpy(startwrite, p_buffer, lencopy); memcpy(startwrite, p_buffer, lencopy);
return 0; return 0;
} }
u8 cx231xx_is_vbi_buffer_done(struct cx231xx * dev,
u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,struct cx231xx_dmaqueue *dma_q) struct cx231xx_dmaqueue * dma_q)
{ {
u32 height = 0; u32 height = 0;
height = ((dev->norm & V4L2_STD_625_50) ? height = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES) ; PAL_VBI_LINES : NTSC_VBI_LINES);
return (dma_q->lines_completed == height)?1:0; return (dma_q->lines_completed == height) ? 1 : 0;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
cx231xx_vbi.h - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx_vbi.h - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on cx88 driver Based on cx88 driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -24,8 +24,7 @@ ...@@ -24,8 +24,7 @@
extern struct videobuf_queue_ops cx231xx_vbi_qops; extern struct videobuf_queue_ops cx231xx_vbi_qops;
#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
#define NTSC_VBI_END_LINE 21 #define NTSC_VBI_END_LINE 21
#define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1) #define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1)
...@@ -41,21 +40,24 @@ extern struct videobuf_queue_ops cx231xx_vbi_qops; ...@@ -41,21 +40,24 @@ extern struct videobuf_queue_ops cx231xx_vbi_qops;
/* stream functions */ /* stream functions */
int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
int num_bufs, int max_pkt_size, int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct cx231xx *dev, struct urb *urb)); int (*isoc_copy) (struct cx231xx * dev,
struct urb * urb));
void cx231xx_uninit_vbi_isoc(struct cx231xx *dev); void cx231xx_uninit_vbi_isoc(struct cx231xx *dev);
/* vbi data copy functions */ /* vbi data copy functions */
u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 sav_eav, u8 *p_buffer, u32 buffer_size); u8 sav_eav, u8 * p_buffer, u32 buffer_size);
u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_line, u32 length, int field_number); u8 * p_line, u32 length, int field_number);
void cx231xx_reset_vbi_buffer(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q); void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
struct cx231xx_dmaqueue *dma_q);
int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_buffer, u32 bytes_to_copy); u8 * p_buffer, u32 bytes_to_copy);
u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,struct cx231xx_dmaqueue *dma_q); u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
struct cx231xx_dmaqueue *dma_q);
#endif #endif
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
cx231xx-video.c - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx-video.c - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
Based on cx23885 driver Based on cx23885 driver
Based on cx88 driver Based on cx88 driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -44,11 +43,9 @@ ...@@ -44,11 +43,9 @@
#include "cx231xx.h" #include "cx231xx.h"
#include "cx231xx-vbi.h" #include "cx231xx-vbi.h"
#define DRIVER_AUTHOR "Srinivasa Deevi <srinivasa.deevi@conexant.com>" #define DRIVER_AUTHOR "Srinivasa Deevi <srinivasa.deevi@conexant.com>"
#define DRIVER_DESC "Conexant cx231xx based USB video device driver" #define DRIVER_DESC "Conexant cx231xx based USB video device driver"
#define cx231xx_videodbg(fmt, arg...) do {\ #define cx231xx_videodbg(fmt, arg...) do {\
if (video_debug) \ if (video_debug) \
printk(KERN_INFO "%s %s :"fmt, \ printk(KERN_INFO "%s %s :"fmt, \
...@@ -70,138 +67,133 @@ MODULE_AUTHOR(DRIVER_AUTHOR); ...@@ -70,138 +67,133 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC); MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
module_param_array(card, int, NULL, 0444); module_param_array(card, int, NULL, 0444);
module_param_array(video_nr, int, NULL, 0444); module_param_array(video_nr, int, NULL, 0444);
module_param_array(vbi_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444);
module_param_array(radio_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444);
MODULE_PARM_DESC(card, "card type"); MODULE_PARM_DESC(card, "card type");
MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(video_nr, "video device numbers");
MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
MODULE_PARM_DESC(radio_nr, "radio device numbers"); MODULE_PARM_DESC(radio_nr, "radio device numbers");
static unsigned int video_debug; static unsigned int video_debug;
module_param(video_debug, int, 0644); module_param(video_debug, int, 0644);
MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
/* supported video standards */ /* supported video standards */
static struct cx231xx_fmt format[] = { static struct cx231xx_fmt format[] = {
{ {
.name = "16bpp YUY2, 4:2:2, packed", .name = "16bpp YUY2, 4:2:2, packed",
.fourcc = V4L2_PIX_FMT_YUYV, .fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16, .depth = 16,
.reg = 0, .reg = 0,
}, },
}; };
/* supported controls */ /* supported controls */
/* Common to all boards */ /* Common to all boards */
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
static const struct v4l2_queryctrl no_ctl = { static const struct v4l2_queryctrl no_ctl = {
.name = "42", .name = "42",
.flags = V4L2_CTRL_FLAG_DISABLED, .flags = V4L2_CTRL_FLAG_DISABLED,
}; };
static struct cx231xx_ctrl cx231xx_ctls[] = { static struct cx231xx_ctrl cx231xx_ctls[] = {
/* --- video --- */ /* --- video --- */
{ {
.v = { .v = {
.id = V4L2_CID_BRIGHTNESS, .id = V4L2_CID_BRIGHTNESS,
.name = "Brightness", .name = "Brightness",
.minimum = 0x00, .minimum = 0x00,
.maximum = 0xff, .maximum = 0xff,
.step = 1, .step = 1,
.default_value = 0x7f, .default_value = 0x7f,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
}, },
.off = 128, .off = 128,
.reg = LUMA_CTRL, .reg = LUMA_CTRL,
.mask = 0x00ff, .mask = 0x00ff,
.shift = 0, .shift = 0,
}, { }, {
.v = { .v = {
.id = V4L2_CID_CONTRAST, .id = V4L2_CID_CONTRAST,
.name = "Contrast", .name = "Contrast",
.minimum = 0, .minimum = 0,
.maximum = 0xff, .maximum = 0xff,
.step = 1, .step = 1,
.default_value = 0x3f, .default_value = 0x3f,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
}, },
.off = 0, .off = 0,
.reg = LUMA_CTRL, .reg = LUMA_CTRL,
.mask = 0xff00, .mask = 0xff00,
.shift = 8, .shift = 8,
}, { }, {
.v = { .v = {
.id = V4L2_CID_HUE, .id = V4L2_CID_HUE,
.name = "Hue", .name = "Hue",
.minimum = 0, .minimum = 0,
.maximum = 0xff, .maximum = 0xff,
.step = 1, .step = 1,
.default_value = 0x7f, .default_value = 0x7f,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
}, },
.off = 128, .off = 128,
.reg = CHROMA_CTRL, .reg = CHROMA_CTRL,
.mask = 0xff0000, .mask = 0xff0000,
.shift = 16, .shift = 16,
}, { }, {
/* strictly, this only describes only U saturation. /* strictly, this only describes only U saturation.
* V saturation is handled specially through code. * V saturation is handled specially through code.
*/ */
.v = { .v = {
.id = V4L2_CID_SATURATION, .id = V4L2_CID_SATURATION,
.name = "Saturation", .name = "Saturation",
.minimum = 0, .minimum = 0,
.maximum = 0xff, .maximum = 0xff,
.step = 1, .step = 1,
.default_value = 0x7f, .default_value = 0x7f,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
}, },
.off = 0, .off = 0,
.reg = CHROMA_CTRL, .reg = CHROMA_CTRL,
.mask = 0x00ff, .mask = 0x00ff,
.shift = 0, .shift = 0,
}, { }, {
/* --- audio --- */ /* --- audio --- */
.v = { .v = {
.id = V4L2_CID_AUDIO_MUTE, .id = V4L2_CID_AUDIO_MUTE,
.name = "Mute", .name = "Mute",
.minimum = 0, .minimum = 0,
.maximum = 1, .maximum = 1,
.default_value = 1, .default_value = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN, .type = V4L2_CTRL_TYPE_BOOLEAN,
}, },
.reg = PATH1_CTL1, .reg = PATH1_CTL1,
.mask = (0x1f << 24), .mask = (0x1f << 24),
.shift = 24, .shift = 24,
}, { }, {
.v = { .v = {
.id = V4L2_CID_AUDIO_VOLUME, .id = V4L2_CID_AUDIO_VOLUME,
.name = "Volume", .name = "Volume",
.minimum = 0, .minimum = 0,
.maximum = 0x3f, .maximum = 0x3f,
.step = 1, .step = 1,
.default_value = 0x3f, .default_value = 0x3f,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
}, },
.reg = PATH1_VOL_CTL, .reg = PATH1_VOL_CTL,
.mask = 0xff, .mask = 0xff,
.shift = 0, .shift = 0,
} }
}; };
static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls); static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls);
...@@ -224,7 +216,6 @@ static const u32 *ctrl_classes[] = { ...@@ -224,7 +216,6 @@ static const u32 *ctrl_classes[] = {
NULL NULL
}; };
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
Video buffer and parser functions Video buffer and parser functions
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
...@@ -233,8 +224,8 @@ static const u32 *ctrl_classes[] = { ...@@ -233,8 +224,8 @@ static const u32 *ctrl_classes[] = {
* Announces that a buffer were filled and request the next * Announces that a buffer were filled and request the next
*/ */
static inline void buffer_filled(struct cx231xx *dev, static inline void buffer_filled(struct cx231xx *dev,
struct cx231xx_dmaqueue *dma_q, struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer *buf) struct cx231xx_buffer *buf)
{ {
/* Advice that buffer was filled */ /* Advice that buffer was filled */
cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
...@@ -248,9 +239,7 @@ static inline void buffer_filled(struct cx231xx *dev, ...@@ -248,9 +239,7 @@ static inline void buffer_filled(struct cx231xx *dev,
wake_up(&buf->vb.done); wake_up(&buf->vb.done);
} }
static inline void print_err_status(struct cx231xx *dev, int packet, int status)
static inline void print_err_status(struct cx231xx *dev,
int packet, int status)
{ {
char *errmsg = "Unknown"; char *errmsg = "Unknown";
...@@ -281,10 +270,10 @@ static inline void print_err_status(struct cx231xx *dev, ...@@ -281,10 +270,10 @@ static inline void print_err_status(struct cx231xx *dev,
break; break;
} }
if (packet < 0) { if (packet < 0) {
cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg); cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg);
} else { } else {
cx231xx_isocdbg("URB packet %d, status %d [%s].\n", cx231xx_isocdbg("URB packet %d, status %d [%s].\n",
packet, status, errmsg); packet, status, errmsg);
} }
} }
...@@ -292,14 +281,14 @@ static inline void print_err_status(struct cx231xx *dev, ...@@ -292,14 +281,14 @@ static inline void print_err_status(struct cx231xx *dev,
* video-buf generic routine to get the next available buffer * video-buf generic routine to get the next available buffer
*/ */
static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer **buf) struct cx231xx_buffer **buf)
{ {
struct cx231xx_video_mode *vmode = container_of(dma_q, struct cx231xx_video_mode, vidq); struct cx231xx_video_mode *vmode =
struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode); container_of(dma_q, struct cx231xx_video_mode, vidq);
struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
char *outp; char *outp;
if (list_empty(&dma_q->active)) { if (list_empty(&dma_q->active)) {
cx231xx_isocdbg("No active queue to serve\n"); cx231xx_isocdbg("No active queue to serve\n");
dev->video_mode.isoc_ctl.buf = NULL; dev->video_mode.isoc_ctl.buf = NULL;
...@@ -324,13 +313,13 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, ...@@ -324,13 +313,13 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
*/ */
static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
{ {
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
struct cx231xx_dmaqueue *dma_q = urb->context; struct cx231xx_dmaqueue *dma_q = urb->context;
unsigned char *outp = NULL; unsigned char *outp = NULL;
int i, rc = 1; int i, rc = 1;
unsigned char *p_buffer; unsigned char *p_buffer;
u32 bytes_parsed = 0, buffer_size = 0; u32 bytes_parsed = 0, buffer_size = 0;
u8 sav_eav = 0; u8 sav_eav = 0;
if (!dev) if (!dev)
return 0; return 0;
...@@ -357,342 +346,347 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) ...@@ -357,342 +346,347 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
continue; continue;
} }
if (urb->iso_frame_desc[i].actual_length <= 0) { if (urb->iso_frame_desc[i].actual_length <= 0) {
/* cx231xx_isocdbg("packet %d is empty",i); - spammy */ /* cx231xx_isocdbg("packet %d is empty",i); - spammy */
continue; continue;
} }
if (urb->iso_frame_desc[i].actual_length > if (urb->iso_frame_desc[i].actual_length >
dev->video_mode.max_pkt_size) { dev->video_mode.max_pkt_size) {
cx231xx_isocdbg("packet bigger than packet size"); cx231xx_isocdbg("packet bigger than packet size");
continue; continue;
} }
/* get buffer pointer and length */ /* get buffer pointer and length */
p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset; p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
buffer_size = urb->iso_frame_desc[i].actual_length; buffer_size = urb->iso_frame_desc[i].actual_length;
bytes_parsed = 0; bytes_parsed = 0;
if(dma_q->is_partial_line) if (dma_q->is_partial_line) {
{ /* Handle the case where we were working on a partial line */
/* Handle the case where we were working on a partial line */ sav_eav = dma_q->last_sav;
sav_eav = dma_q->last_sav; } else {
} else { /* Check for a SAV/EAV overlapping the buffer boundary */
/* Check for a SAV/EAV overlapping the buffer boundary */ sav_eav =
sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer, dma_q->partial_buf, &bytes_parsed); cx231xx_find_boundary_SAV_EAV(p_buffer,
} dma_q->partial_buf,
&bytes_parsed);
sav_eav &= 0xF0; }
/* Get the first line if we have some portion of an SAV/EAV from the last buffer
or a partial line */
if(sav_eav) {
bytes_parsed += cx231xx_get_video_line(dev, dma_q,
sav_eav, /* SAV/EAV */
p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed); /* buffer size */
}
/* Now parse data that is completely in this buffer */
/* dma_q->is_partial_line = 0; */
while(bytes_parsed < buffer_size)
{
u32 bytes_used = 0;
sav_eav = cx231xx_find_next_SAV_EAV(
p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed, /* buffer size */
&bytes_used); /* Receives bytes used to get SAV/EAV */
bytes_parsed += bytes_used;
sav_eav &= 0xF0;
if(sav_eav && (bytes_parsed < buffer_size))
{
bytes_parsed += cx231xx_get_video_line(dev, dma_q,
sav_eav, /* SAV/EAV */
p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed); /* buffer size */
}
}
/* Save the last four bytes of the buffer so we can check the buffer boundary
condition next time */
memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
bytes_parsed = 0;
} sav_eav &= 0xF0;
return rc; /* Get the first line if we have some portion of an SAV/EAV from the last buffer
} or a partial line */
if (sav_eav) {
bytes_parsed += cx231xx_get_video_line(dev, dma_q, sav_eav, /* SAV/EAV */
p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed); /* buffer size */
}
u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf, u32 *p_bytes_used) /* Now parse data that is completely in this buffer */
{ /* dma_q->is_partial_line = 0; */
u32 bytes_used;
u8 boundary_bytes[8];
u8 sav_eav = 0;
*p_bytes_used = 0; while (bytes_parsed < buffer_size) {
u32 bytes_used = 0;
/* Create an array of the last 4 bytes of the last buffer and the first sav_eav = cx231xx_find_next_SAV_EAV(p_buffer + bytes_parsed, /* p_buffer */
4 bytes of the current buffer. */ buffer_size - bytes_parsed, /* buffer size */
&bytes_used); /* Receives bytes used to get SAV/EAV */
memcpy(boundary_bytes, partial_buf, 4); bytes_parsed += bytes_used;
memcpy(boundary_bytes + 4, p_buffer, 4);
/* Check for the SAV/EAV in the boundary buffer */ sav_eav &= 0xF0;
sav_eav = cx231xx_find_next_SAV_EAV((u8*)&boundary_bytes, 8, &bytes_used); if (sav_eav && (bytes_parsed < buffer_size)) {
bytes_parsed += cx231xx_get_video_line(dev, dma_q, sav_eav, /* SAV/EAV */
p_buffer + bytes_parsed, /* p_buffer */
buffer_size - bytes_parsed); /* buffer size */
}
}
if(sav_eav) { /* Save the last four bytes of the buffer so we can check the buffer boundary
/* found a boundary SAV/EAV. Updates the bytes used to reflect condition next time */
only those used in the new buffer */ memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
*p_bytes_used = bytes_used - 4; bytes_parsed = 0;
}
return sav_eav; }
return rc;
} }
u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used) u8 cx231xx_find_boundary_SAV_EAV(u8 * p_buffer, u8 * partial_buf,
u32 * p_bytes_used)
{ {
u32 i; u32 bytes_used;
u8 sav_eav = 0; u8 boundary_bytes[8];
u8 sav_eav = 0;
*p_bytes_used = 0;
/* Don't search if the buffer size is less than 4. It causes a page fault since /* Create an array of the last 4 bytes of the last buffer and the first
buffer_size - 4 evaluates to a large number in that case. */ 4 bytes of the current buffer. */
if(buffer_size < 4) {
*p_bytes_used = buffer_size;
return 0;
}
for(i = 0;i < (buffer_size - 3); i++) { memcpy(boundary_bytes, partial_buf, 4);
memcpy(boundary_bytes + 4, p_buffer, 4);
if((p_buffer[i] == 0xFF) && /* Check for the SAV/EAV in the boundary buffer */
(p_buffer[i+1] == 0x00) && sav_eav =
(p_buffer[i+2] == 0x00)) { cx231xx_find_next_SAV_EAV((u8 *) & boundary_bytes, 8, &bytes_used);
*p_bytes_used = i+4; if (sav_eav) {
sav_eav = p_buffer[i+3]; /* found a boundary SAV/EAV. Updates the bytes used to reflect
return sav_eav; only those used in the new buffer */
} *p_bytes_used = bytes_used - 4;
} }
*p_bytes_used = buffer_size; return sav_eav;
return 0;
} }
u8 cx231xx_find_next_SAV_EAV(u8 * p_buffer, u32 buffer_size, u32 * p_bytes_used)
{
u32 i;
u8 sav_eav = 0;
/* Don't search if the buffer size is less than 4. It causes a page fault since
buffer_size - 4 evaluates to a large number in that case. */
if (buffer_size < 4) {
*p_bytes_used = buffer_size;
return 0;
}
for (i = 0; i < (buffer_size - 3); i++) {
u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, if ((p_buffer[i] == 0xFF) &&
u8 sav_eav, u8 *p_buffer, u32 buffer_size) (p_buffer[i + 1] == 0x00) && (p_buffer[i + 2] == 0x00)) {
{
u32 bytes_copied = 0;
int current_field = -1;
*p_bytes_used = i + 4;
sav_eav = p_buffer[i + 3];
return sav_eav;
}
}
switch(sav_eav) { *p_bytes_used = buffer_size;
case SAV_ACTIVE_VIDEO_FIELD1: return 0;
/* looking for skipped line which occurred in PAL 720x480 mode. In this case, }
there will be no active data contained between the SAV and EAV */
if ( (buffer_size > 3) &&
(p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
( (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) || (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
(p_buffer[3] == EAV_VBLANK_FIELD1) || (p_buffer[3] == EAV_VBLANK_FIELD2)
)
)
{
return bytes_copied;
}
current_field = 1;
break;
case SAV_ACTIVE_VIDEO_FIELD2: u32 cx231xx_get_video_line(struct cx231xx * dev,
/* looking for skipped line which occurred in PAL 720x480 mode. In this case, struct cx231xx_dmaqueue * dma_q, u8 sav_eav,
there will be no active data contained between the SAV and EAV */ u8 * p_buffer, u32 buffer_size)
if ( (buffer_size > 3) && {
(p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) && u32 bytes_copied = 0;
( (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) || (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) || int current_field = -1;
(p_buffer[3] == EAV_VBLANK_FIELD1) || (p_buffer[3] == EAV_VBLANK_FIELD2)
) switch (sav_eav) {
) case SAV_ACTIVE_VIDEO_FIELD1:
{ /* looking for skipped line which occurred in PAL 720x480 mode. In this case,
return bytes_copied; there will be no active data contained between the SAV and EAV */
} if ((buffer_size > 3) &&
current_field = 2; (p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00)
break; && (p_buffer[2] == 0x00)
} && ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1)
|| (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2)
|| (p_buffer[3] == EAV_VBLANK_FIELD1)
|| (p_buffer[3] == EAV_VBLANK_FIELD2)
)
) {
return bytes_copied;
}
current_field = 1;
break;
dma_q->last_sav = sav_eav; case SAV_ACTIVE_VIDEO_FIELD2:
/* looking for skipped line which occurred in PAL 720x480 mode. In this case,
there will be no active data contained between the SAV and EAV */
if ((buffer_size > 3) &&
(p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00)
&& (p_buffer[2] == 0x00)
&& ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1)
|| (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2)
|| (p_buffer[3] == EAV_VBLANK_FIELD1)
|| (p_buffer[3] == EAV_VBLANK_FIELD2)
)
) {
return bytes_copied;
}
current_field = 2;
break;
}
bytes_copied = cx231xx_copy_video_line(dev, dma_q, p_buffer, buffer_size, current_field); dma_q->last_sav = sav_eav;
return bytes_copied; bytes_copied =
cx231xx_copy_video_line(dev, dma_q, p_buffer, buffer_size,
current_field);
return bytes_copied;
} }
u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_copy_video_line(struct cx231xx * dev,
u8 *p_line, u32 length, int field_number) struct cx231xx_dmaqueue * dma_q, u8 * p_line,
u32 length, int field_number)
{ {
u32 bytes_to_copy; u32 bytes_to_copy;
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
u32 _line_size = dev->width * 2; u32 _line_size = dev->width * 2;
if( dma_q->current_field != field_number ) {
cx231xx_reset_video_buffer(dev, dma_q);
}
/* get the buffer pointer */ if (dma_q->current_field != field_number) {
buf = dev->video_mode.isoc_ctl.buf; cx231xx_reset_video_buffer(dev, dma_q);
}
/* Remember the field number for next time */ /* get the buffer pointer */
dma_q->current_field = field_number; buf = dev->video_mode.isoc_ctl.buf;
bytes_to_copy = dma_q->bytes_left_in_line; /* Remember the field number for next time */
if(bytes_to_copy > length) dma_q->current_field = field_number;
bytes_to_copy = length;
bytes_to_copy = dma_q->bytes_left_in_line;
if (bytes_to_copy > length)
bytes_to_copy = length;
if(dma_q->lines_completed >= dma_q->lines_per_field) { if (dma_q->lines_completed >= dma_q->lines_per_field) {
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->bytes_left_in_line -= bytes_to_copy;
dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ? 0 : 1; dma_q->is_partial_line =
return 0; (dma_q->bytes_left_in_line == 0) ? 0 : 1;
} return 0;
}
dma_q->is_partial_line = 1; dma_q->is_partial_line = 1;
/* If we don't have a buffer, just return the number of bytes we would /* If we don't have a buffer, just return the number of bytes we would
have copied if we had a buffer. */ have copied if we had a buffer. */
if(!buf) if (!buf) {
{ dma_q->bytes_left_in_line -= bytes_to_copy;
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->is_partial_line =
dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ? 0 : 1; (dma_q->bytes_left_in_line == 0) ? 0 : 1;
return bytes_to_copy; return bytes_to_copy;
} }
/* copy the data to video buffer */ /* copy the data to video buffer */
cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy); cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy);
dma_q->pos += bytes_to_copy; dma_q->pos += bytes_to_copy;
dma_q->bytes_left_in_line -= bytes_to_copy; dma_q->bytes_left_in_line -= bytes_to_copy;
if(dma_q->bytes_left_in_line == 0) { if (dma_q->bytes_left_in_line == 0) {
dma_q->bytes_left_in_line = _line_size; dma_q->bytes_left_in_line = _line_size;
dma_q->lines_completed++; dma_q->lines_completed++;
dma_q->is_partial_line = 0; dma_q->is_partial_line = 0;
if(cx231xx_is_buffer_done(dev, dma_q) && buf) { if (cx231xx_is_buffer_done(dev, dma_q) && buf) {
buffer_filled(dev, dma_q, buf); buffer_filled(dev, dma_q, buf);
dma_q->pos = 0; dma_q->pos = 0;
buf = NULL; buf = NULL;
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
} }
} }
return bytes_to_copy; return bytes_to_copy;
} }
void cx231xx_reset_video_buffer(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q) void cx231xx_reset_video_buffer(struct cx231xx *dev,
struct cx231xx_dmaqueue *dma_q)
{ {
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
/* handle the switch from field 1 to field 2 */ /* handle the switch from field 1 to field 2 */
if(dma_q->current_field == 1) { if (dma_q->current_field == 1) {
if(dma_q->lines_completed >= dma_q->lines_per_field ) { if (dma_q->lines_completed >= dma_q->lines_per_field) {
dma_q->field1_done = 1; dma_q->field1_done = 1;
} else { } else {
dma_q->field1_done = 0; dma_q->field1_done = 0;
} }
} }
buf = dev->video_mode.isoc_ctl.buf; buf = dev->video_mode.isoc_ctl.buf;
if(buf == NULL) { if (buf == NULL) {
u8* outp = NULL; u8 *outp = NULL;
/* first try to get the buffer */ /* first try to get the buffer */
get_next_buf(dma_q, &buf); get_next_buf(dma_q, &buf);
if(buf) if (buf)
outp = videobuf_to_vmalloc(&buf->vb); outp = videobuf_to_vmalloc(&buf->vb);
dma_q->pos = 0; dma_q->pos = 0;
dma_q->field1_done = 0; dma_q->field1_done = 0;
dma_q->current_field = -1; dma_q->current_field = -1;
} }
/* reset the counters */ /* reset the counters */
dma_q->bytes_left_in_line = dev->width << 1; dma_q->bytes_left_in_line = dev->width << 1;
dma_q->lines_completed = 0; dma_q->lines_completed = 0;
} }
int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_buffer, u32 bytes_to_copy) u8 * p_buffer, u32 bytes_to_copy)
{ {
u8 *p_out_buffer = NULL; u8 *p_out_buffer = NULL;
u32 current_line_bytes_copied = 0; u32 current_line_bytes_copied = 0;
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
u32 _line_size = dev->width << 1; u32 _line_size = dev->width << 1;
void *startwrite; void *startwrite;
int offset, lencopy; int offset, lencopy;
buf = dev->video_mode.isoc_ctl.buf; buf = dev->video_mode.isoc_ctl.buf;
if (buf == NULL) if (buf == NULL)
return -1; return -1;
p_out_buffer = videobuf_to_vmalloc(&buf->vb); p_out_buffer = videobuf_to_vmalloc(&buf->vb);
current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line; current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line;
/* Offset field 2 one line from the top of the buffer */ /* Offset field 2 one line from the top of the buffer */
offset = (dma_q->current_field == 1)? 0: _line_size; offset = (dma_q->current_field == 1) ? 0 : _line_size;
/* Offset for field 2 */ /* Offset for field 2 */
startwrite = p_out_buffer + offset; startwrite = p_out_buffer + offset;
/* lines already completed in the current field */ /* lines already completed in the current field */
startwrite += (dma_q->lines_completed * _line_size * 2); startwrite += (dma_q->lines_completed * _line_size * 2);
/* bytes already completed in the current line */ /* bytes already completed in the current line */
startwrite += current_line_bytes_copied; startwrite += current_line_bytes_copied;
lencopy = dma_q->bytes_left_in_line > bytes_to_copy ? bytes_to_copy : dma_q->bytes_left_in_line; lencopy =
dma_q->bytes_left_in_line >
bytes_to_copy ? bytes_to_copy : dma_q->bytes_left_in_line;
if( (u8*)(startwrite +lencopy) > (u8*)(p_out_buffer+ buf->vb.size) ) { if ((u8 *) (startwrite + lencopy) >
return 0; (u8 *) (p_out_buffer + buf->vb.size)) {
} return 0;
}
/* The below copies the UYVY data straight into video buffer */ /* The below copies the UYVY data straight into video buffer */
cx231xx_swab( (u16*)p_buffer, (u16*)startwrite, (u16)lencopy); cx231xx_swab((u16 *) p_buffer, (u16 *) startwrite, (u16) lencopy);
return 0; return 0;
} }
void cx231xx_swab(u16 *from, u16 *to, u16 len) void cx231xx_swab(u16 * from, u16 * to, u16 len)
{ {
u16 i; u16 i;
if( len <= 0) if (len <= 0)
return; return;
for(i = 0; i < len/2; i++) { for (i = 0; i < len / 2; i++) {
to[i] = (from[i] << 8) | (from[i] >> 8); to[i] = (from[i] << 8) | (from[i] >> 8);
} }
} }
u8 cx231xx_is_buffer_done(struct cx231xx *dev,struct cx231xx_dmaqueue *dma_q) u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q)
{ {
u8 buffer_complete = 0; u8 buffer_complete = 0;
/* Dual field stream */ /* Dual field stream */
buffer_complete = buffer_complete =
((dma_q->current_field == 2) && ((dma_q->current_field == 2) &&
(dma_q->lines_completed >= dma_q->lines_per_field) && (dma_q->lines_completed >= dma_q->lines_per_field) &&
dma_q->field1_done); dma_q->field1_done);
return buffer_complete; return buffer_complete;
} }
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
Videobuf operations Videobuf operations
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
...@@ -701,10 +695,11 @@ static int ...@@ -701,10 +695,11 @@ static int
buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
struct v4l2_frequency f; struct v4l2_frequency f;
*size = ( fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; *size =
(fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
if (0 == *count) if (0 == *count)
*count = CX231XX_DEF_BUF; *count = CX231XX_DEF_BUF;
...@@ -714,7 +709,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) ...@@ -714,7 +709,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
/* Ask tuner to go to analog mode */ /* Ask tuner to go to analog mode */
memset(&f, 0, sizeof(f)); memset(&f, 0, sizeof(f));
f.frequency = dev->ctl_freq; f.frequency = dev->ctl_freq;
f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, &f);
...@@ -724,8 +719,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) ...@@ -724,8 +719,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
/* This is called *without* dev->slock held; please keep it that way */ /* This is called *without* dev->slock held; please keep it that way */
static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
unsigned long flags = 0; unsigned long flags = 0;
if (in_interrupt()) if (in_interrupt())
BUG(); BUG();
...@@ -738,7 +733,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) ...@@ -738,7 +733,7 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
This should be safe; by the time we get here, the buffer isn't This should be safe; by the time we get here, the buffer isn't
queued anymore. If we ever start marking the buffers as queued anymore. If we ever start marking the buffers as
VIDEOBUF_ACTIVE, it won't be, though. VIDEOBUF_ACTIVE, it won't be, though.
*/ */
spin_lock_irqsave(&dev->video_mode.slock, flags); spin_lock_irqsave(&dev->video_mode.slock, flags);
if (dev->video_mode.isoc_ctl.buf == buf) if (dev->video_mode.isoc_ctl.buf == buf)
dev->video_mode.isoc_ctl.buf = NULL; dev->video_mode.isoc_ctl.buf = NULL;
...@@ -750,22 +745,24 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) ...@@ -750,22 +745,24 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
static int static int
buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
enum v4l2_field field) enum v4l2_field field)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
struct cx231xx *dev = fh->dev; container_of(vb, struct cx231xx_buffer, vb);
int rc = 0, urb_init = 0; struct cx231xx *dev = fh->dev;
int rc = 0, urb_init = 0;
/* The only currently supported format is 16 bits/pixel */ /* The only currently supported format is 16 bits/pixel */
buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; buf->vb.size =
(fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL; return -EINVAL;
buf->vb.width = dev->width; buf->vb.width = dev->width;
buf->vb.height = dev->height; buf->vb.height = dev->height;
buf->vb.field = field; buf->vb.field = field;
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
rc = videobuf_iolock(vq, &buf->vb, NULL); rc = videobuf_iolock(vq, &buf->vb, NULL);
...@@ -778,8 +775,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, ...@@ -778,8 +775,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
if (urb_init) { if (urb_init) {
rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
CX231XX_NUM_BUFS, dev->video_mode.max_pkt_size, CX231XX_NUM_BUFS,
cx231xx_isoc_copy); dev->video_mode.max_pkt_size,
cx231xx_isoc_copy);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
} }
...@@ -787,18 +785,18 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, ...@@ -787,18 +785,18 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
buf->vb.state = VIDEOBUF_PREPARED; buf->vb.state = VIDEOBUF_PREPARED;
return 0; return 0;
fail: fail:
free_buffer(vq, buf); free_buffer(vq, buf);
return rc; return rc;
} }
static void static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{ {
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
struct cx231xx_fh *fh = vq->priv_data; container_of(vb, struct cx231xx_buffer, vb);
struct cx231xx *dev = fh->dev; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; struct cx231xx *dev = fh->dev;
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
buf->vb.state = VIDEOBUF_QUEUED; buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->vb.queue, &vidq->active); list_add_tail(&buf->vb.queue, &vidq->active);
...@@ -806,11 +804,12 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) ...@@ -806,11 +804,12 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
} }
static void buffer_release(struct videobuf_queue *vq, static void buffer_release(struct videobuf_queue *vq,
struct videobuf_buffer *vb) struct videobuf_buffer *vb)
{ {
struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_buffer *buf =
struct cx231xx_fh *fh = vq->priv_data; container_of(vb, struct cx231xx_buffer, vb);
struct cx231xx *dev = (struct cx231xx *)fh->dev; struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = (struct cx231xx *)fh->dev;
cx231xx_isocdbg("cx231xx: called buffer_release\n"); cx231xx_isocdbg("cx231xx: called buffer_release\n");
...@@ -818,15 +817,14 @@ static void buffer_release(struct videobuf_queue *vq, ...@@ -818,15 +817,14 @@ static void buffer_release(struct videobuf_queue *vq,
} }
static struct videobuf_queue_ops cx231xx_video_qops = { static struct videobuf_queue_ops cx231xx_video_qops = {
.buf_setup = buffer_setup, .buf_setup = buffer_setup,
.buf_prepare = buffer_prepare, .buf_prepare = buffer_prepare,
.buf_queue = buffer_queue, .buf_queue = buffer_queue,
.buf_release = buffer_release, .buf_release = buffer_release,
}; };
/********************* v4l2 interface **************************************/ /********************* v4l2 interface **************************************/
void video_mux(struct cx231xx *dev, int index) void video_mux(struct cx231xx *dev, int index)
{ {
...@@ -837,40 +835,41 @@ void video_mux(struct cx231xx *dev, int index) ...@@ -837,40 +835,41 @@ void video_mux(struct cx231xx *dev, int index)
dev->video_input = index; dev->video_input = index;
dev->ctl_ainput = INPUT(index)->amux; dev->ctl_ainput = INPUT(index)->amux;
cx231xx_set_video_input_mux(dev,index); cx231xx_set_video_input_mux(dev, index);
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_INT_S_VIDEO_ROUTING, &route); cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_INT_S_VIDEO_ROUTING,
&route);
cx231xx_set_audio_input(dev, dev->ctl_ainput ); cx231xx_set_audio_input(dev, dev->ctl_ainput);
cx231xx_info("video_mux : %d\n", index); cx231xx_info("video_mux : %d\n", index);
/* do mode control overrides if required */ /* do mode control overrides if required */
cx231xx_do_mode_ctrl_overrides(dev); cx231xx_do_mode_ctrl_overrides(dev);
} }
/* Usage lock check functions */ /* Usage lock check functions */
static int res_get(struct cx231xx_fh *fh) static int res_get(struct cx231xx_fh *fh)
{ {
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc = 0; int rc = 0;
/* This instance already has stream_on */ /* This instance already has stream_on */
if (fh->stream_on) if (fh->stream_on)
return rc; return rc;
if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (dev->stream_on) if (dev->stream_on)
return -EBUSY; return -EBUSY;
dev->stream_on = 1; dev->stream_on = 1;
} else if(fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
if (dev->vbi_stream_on) if (dev->vbi_stream_on)
return -EBUSY; return -EBUSY;
dev->vbi_stream_on = 1; dev->vbi_stream_on = 1;
} else } else
return -EINVAL; return -EINVAL;
fh->stream_on = 1; fh->stream_on = 1;
return rc; return rc;
} }
...@@ -882,14 +881,14 @@ static int res_check(struct cx231xx_fh *fh) ...@@ -882,14 +881,14 @@ static int res_check(struct cx231xx_fh *fh)
static void res_free(struct cx231xx_fh *fh) static void res_free(struct cx231xx_fh *fh)
{ {
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
fh->stream_on = 0; fh->stream_on = 0;
if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
dev->stream_on = 0; dev->stream_on = 0;
if(fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
dev->vbi_stream_on = 0; dev->vbi_stream_on = 0;
} }
static int check_dev(struct cx231xx *dev) static int check_dev(struct cx231xx *dev)
...@@ -901,18 +900,18 @@ static int check_dev(struct cx231xx *dev) ...@@ -901,18 +900,18 @@ static int check_dev(struct cx231xx *dev)
if (dev->state & DEV_MISCONFIGURED) { if (dev->state & DEV_MISCONFIGURED) {
cx231xx_errdev("v4l2 ioctl: device is misconfigured; " cx231xx_errdev("v4l2 ioctl: device is misconfigured; "
"close and open it again\n"); "close and open it again\n");
return -EIO; return -EIO;
} }
return 0; return 0;
} }
void get_scale(struct cx231xx *dev, void get_scale(struct cx231xx *dev,
unsigned int width, unsigned int height, unsigned int width, unsigned int height,
unsigned int *hscale, unsigned int *vscale) unsigned int *hscale, unsigned int *vscale)
{ {
unsigned int maxw = norm_maxw(dev); unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev); unsigned int maxh = norm_maxh(dev);
*hscale = (((unsigned long)maxw) << 12) / width - 4096L; *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
if (*hscale >= 0x4000) if (*hscale >= 0x4000)
...@@ -922,8 +921,8 @@ void get_scale(struct cx231xx *dev, ...@@ -922,8 +921,8 @@ void get_scale(struct cx231xx *dev,
if (*vscale >= 0x4000) if (*vscale >= 0x4000)
*vscale = 0x3fff; *vscale = 0x3fff;
dev->hscale = *hscale; dev->hscale = *hscale;
dev->vscale = *vscale; dev->vscale = *vscale;
} }
...@@ -932,10 +931,10 @@ void get_scale(struct cx231xx *dev, ...@@ -932,10 +931,10 @@ void get_scale(struct cx231xx *dev,
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
...@@ -943,7 +942,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, ...@@ -943,7 +942,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.height = dev->height; f->fmt.pix.height = dev->height;
f->fmt.pix.pixelformat = dev->format->fourcc;; f->fmt.pix.pixelformat = dev->format->fourcc;;
f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;; f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;;
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.field = V4L2_FIELD_INTERLACED; f->fmt.pix.field = V4L2_FIELD_INTERLACED;
...@@ -964,21 +963,21 @@ static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc) ...@@ -964,21 +963,21 @@ static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc)
} }
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int width = f->fmt.pix.width; int width = f->fmt.pix.width;
int height = f->fmt.pix.height; int height = f->fmt.pix.height;
unsigned int maxw = norm_maxw(dev); unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev); unsigned int maxh = norm_maxh(dev);
unsigned int hscale, vscale; unsigned int hscale, vscale;
struct cx231xx_fmt *fmt; struct cx231xx_fmt *fmt;
fmt = format_by_fourcc(f->fmt.pix.pixelformat); fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (!fmt) { if (!fmt) {
cx231xx_videodbg("Fourcc format (%08x) invalid.\n", cx231xx_videodbg("Fourcc format (%08x) invalid.\n",
f->fmt.pix.pixelformat); f->fmt.pix.pixelformat);
return -EINVAL; return -EINVAL;
} }
...@@ -1013,23 +1012,22 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, ...@@ -1013,23 +1012,22 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
} }
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
struct cx231xx_fmt *fmt; struct cx231xx_fmt *fmt;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
vidioc_try_fmt_vid_cap(file, priv, f); vidioc_try_fmt_vid_cap(file, priv, f);
fmt = format_by_fourcc(f->fmt.pix.pixelformat); fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (!fmt) { if (!fmt) {
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
...@@ -1050,23 +1048,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -1050,23 +1048,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
/* set new image size */ /* set new image size */
dev->width = f->fmt.pix.width; dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height; dev->height = f->fmt.pix.height;
dev->format = fmt; dev->format = fmt;
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_S_FMT, f); cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_S_FMT, f);
/* Set the correct alternate setting for this resolution */ /* Set the correct alternate setting for this resolution */
cx231xx_resolution_set(dev); cx231xx_resolution_set(dev);
out: out:
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return rc; return rc;
} }
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id * id)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
*id = dev->norm; *id = dev->norm;
return 0; return 0;
...@@ -1074,21 +1072,20 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) ...@@ -1074,21 +1072,20 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
struct v4l2_format f; struct v4l2_format f;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm); cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
dev->norm = *norm; dev->norm = *norm;
/* Adjusts width/height, if needed */ /* Adjusts width/height, if needed */
f.fmt.pix.width = dev->width; f.fmt.pix.width = dev->width;
f.fmt.pix.height = dev->height; f.fmt.pix.height = dev->height;
...@@ -1103,29 +1100,29 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) ...@@ -1103,29 +1100,29 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
cx231xx_resolution_set(dev); cx231xx_resolution_set(dev);
/* do mode control overrides */ /* do mode control overrides */
cx231xx_do_mode_ctrl_overrides(dev); cx231xx_do_mode_ctrl_overrides(dev);
return 0; return 0;
} }
static const char *iname[] = { static const char *iname[] = {
[CX231XX_VMUX_COMPOSITE1] = "Composite1", [CX231XX_VMUX_COMPOSITE1] = "Composite1",
[CX231XX_VMUX_SVIDEO] = "S-Video", [CX231XX_VMUX_SVIDEO] = "S-Video",
[CX231XX_VMUX_TELEVISION] = "Television", [CX231XX_VMUX_TELEVISION] = "Television",
[CX231XX_VMUX_CABLE] = "Cable TV", [CX231XX_VMUX_CABLE] = "Cable TV",
[CX231XX_VMUX_DVB] = "DVB", [CX231XX_VMUX_DVB] = "DVB",
[CX231XX_VMUX_DEBUG] = "for debug only", [CX231XX_VMUX_DEBUG] = "for debug only",
}; };
static int vidioc_enum_input(struct file *file, void *priv, static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i) struct v4l2_input *i)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
unsigned int n; unsigned int n;
n = i->index; n = i->index;
if (n >= MAX_CX231XX_INPUT) if (n >= MAX_CX231XX_INPUT)
...@@ -1139,7 +1136,7 @@ static int vidioc_enum_input(struct file *file, void *priv, ...@@ -1139,7 +1136,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
strcpy(i->name, iname[INPUT(n)->type]); strcpy(i->name, iname[INPUT(n)->type]);
if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) || if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||
(CX231XX_VMUX_CABLE == INPUT(n)->type)) (CX231XX_VMUX_CABLE == INPUT(n)->type))
i->type = V4L2_INPUT_TYPE_TUNER; i->type = V4L2_INPUT_TYPE_TUNER;
i->std = dev->vdev->tvnorms; i->std = dev->vdev->tvnorms;
...@@ -1149,8 +1146,8 @@ static int vidioc_enum_input(struct file *file, void *priv, ...@@ -1149,8 +1146,8 @@ static int vidioc_enum_input(struct file *file, void *priv,
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
*i = dev->video_input; *i = dev->video_input;
...@@ -1159,9 +1156,9 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) ...@@ -1159,9 +1156,9 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *file, void *priv, unsigned int i) static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1182,8 +1179,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) ...@@ -1182,8 +1179,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
switch (a->index) { switch (a->index) {
case CX231XX_AMUX_VIDEO: case CX231XX_AMUX_VIDEO:
...@@ -1204,35 +1201,34 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) ...@@ -1204,35 +1201,34 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int status = 0; int status = 0;
/* Doesn't allow manual routing */ /* Doesn't allow manual routing */
if (a->index != dev->ctl_ainput) if (a->index != dev->ctl_ainput)
return -EINVAL; return -EINVAL;
dev->ctl_ainput = INPUT(a->index)->amux; dev->ctl_ainput = INPUT(a->index)->amux;
status = cx231xx_set_audio_input(dev, dev->ctl_ainput); status = cx231xx_set_audio_input(dev, dev->ctl_ainput);
return status; return status;
} }
static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc) struct v4l2_queryctrl *qc)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int id = qc->id; int id = qc->id;
int i; int i;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
qc->id = v4l2_ctrl_next(ctrl_classes, qc->id); qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
if (unlikely(qc->id == 0)) if (unlikely(qc->id == 0))
return -EINVAL; return -EINVAL;
...@@ -1240,8 +1236,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, ...@@ -1240,8 +1236,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
qc->id = id; qc->id = id;
if (qc->id < V4L2_CID_BASE || if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1)
qc->id >= V4L2_CID_LASTP1)
return -EINVAL; return -EINVAL;
for (i = 0; i < CX231XX_CTLS; i++) for (i = 0; i < CX231XX_CTLS; i++)
...@@ -1255,7 +1250,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, ...@@ -1255,7 +1250,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
*qc = cx231xx_ctls[i].v; *qc = cx231xx_ctls[i].v;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_QUERYCTRL, qc); cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_QUERYCTRL, qc);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
if (qc->type) if (qc->type)
...@@ -1265,11 +1260,11 @@ static int vidioc_queryctrl(struct file *file, void *priv, ...@@ -1265,11 +1260,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
} }
static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl) struct v4l2_control *ctrl)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1284,11 +1279,11 @@ static int vidioc_g_ctrl(struct file *file, void *priv, ...@@ -1284,11 +1279,11 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
} }
static int vidioc_s_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl) struct v4l2_control *ctrl)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1302,12 +1297,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv, ...@@ -1302,12 +1297,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return rc; return rc;
} }
static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct v4l2_tuner *t)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1318,20 +1312,19 @@ static int vidioc_g_tuner(struct file *file, void *priv, ...@@ -1318,20 +1312,19 @@ static int vidioc_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Tuner"); strcpy(t->name, "Tuner");
t->type = V4L2_TUNER_ANALOG_TV; t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM; t->capability = V4L2_TUNER_CAP_NORM;
t->rangehigh = 0xffffffffUL; t->rangehigh = 0xffffffffUL;
t->signal = 0xffff ; /* LOCKED */ t->signal = 0xffff; /* LOCKED */
return 0; return 0;
} }
static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct v4l2_tuner *t)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1350,28 +1343,28 @@ static int vidioc_s_tuner(struct file *file, void *priv, ...@@ -1350,28 +1343,28 @@ static int vidioc_s_tuner(struct file *file, void *priv,
} }
static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f) struct v4l2_frequency *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->ctl_freq; f->frequency = dev->ctl_freq;
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return 0; return 0;
} }
static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f) struct v4l2_frequency *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1385,106 +1378,121 @@ static int vidioc_s_frequency(struct file *file, void *priv, ...@@ -1385,106 +1378,121 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
return -EINVAL; return -EINVAL;
/* set pre channel change settings in DIF first */ /* set pre channel change settings in DIF first */
rc = cx231xx_tuner_pre_channel_change(dev); rc = cx231xx_tuner_pre_channel_change(dev);
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency; dev->ctl_freq = f->frequency;
if(dev->tuner_type == TUNER_XC5000) { if (dev->tuner_type == TUNER_XC5000) {
if( dev->cx231xx_set_analog_freq != NULL ) { if (dev->cx231xx_set_analog_freq != NULL) {
dev->cx231xx_set_analog_freq(dev, f->frequency ); dev->cx231xx_set_analog_freq(dev, f->frequency);
} }
} else { } else {
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY,
f);
} }
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
/* set post channel change settings in DIF first */ /* set post channel change settings in DIF first */
rc = cx231xx_tuner_post_channel_change(dev); rc = cx231xx_tuner_post_channel_change(dev);
cx231xx_info("Set New FREQUENCY to %d\n",f->frequency); cx231xx_info("Set New FREQUENCY to %d\n", f->frequency);
return rc; return rc;
} }
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
/* /*
-R, --list-registers=type=<host/i2cdrv/i2caddr>,chip=<chip>[,min=<addr>,max=<addr>] -R, --list-registers=type=<host/i2cdrv/i2caddr>,chip=<chip>[,min=<addr>,max=<addr>]
dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER] dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
-r, --set-register=type=<host/i2cdrv/i2caddr>,chip=<chip>,reg=<addr>,val=<val> -r, --set-register=type=<host/i2cdrv/i2caddr>,chip=<chip>,reg=<addr>,val=<val>
set the register [VIDIOC_DBG_S_REGISTER] set the register [VIDIOC_DBG_S_REGISTER]
if type == host, then <chip> is the hosts chip ID (default 0) if type == host, then <chip> is the hosts chip ID (default 0)
if type == i2cdrv (default), then <chip> is the I2C driver name or ID if type == i2cdrv (default), then <chip> is the I2C driver name or ID
if type == i2caddr, then <chip> is the 7-bit I2C address if type == i2caddr, then <chip> is the 7-bit I2C address
*/ */
static int vidioc_g_register(struct file *file, void *priv, static int vidioc_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg) struct v4l2_dbg_register *reg)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int ret = 0; int ret = 0;
u8 value[4] ={0,0,0,0}; u8 value[4] = { 0, 0, 0, 0 };
u32 data = 0; u32 data = 0;
switch (reg->match.type) { switch (reg->match.type) {
case V4L2_CHIP_MATCH_HOST: case V4L2_CHIP_MATCH_HOST:
switch(reg->match.addr) { switch (reg->match.addr) {
case 0: /* Cx231xx - internal registers */ case 0: /* Cx231xx - internal registers */
ret = cx231xx_read_ctrl_reg(dev,VRT_GET_REGISTER, (u16) reg->reg, value, 4); ret =
reg->val = value[0] | value[1] << 8 | value[2] << 16 | value[3] << 24; cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
break; (u16) reg->reg, value, 4);
case 1: /* Colibri - read byte */ reg->val =
ret = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS, (u16) reg->reg, 2, &data, 1); value[0] | value[1] << 8 | value[2] << 16 | value[3]
reg->val = le32_to_cpu(data & 0xff); << 24;
break; break;
case 14: /* Colibri - read dword */ case 1: /* Colibri - read byte */
ret = cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS, (u16) reg->reg, 2, &data, 4); ret =
reg->val = le32_to_cpu(data); cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
break; (u16) reg->reg, 2, &data, 1);
case 2: /* Hammerhead - read byte */ reg->val = le32_to_cpu(data & 0xff);
ret = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, (u16) reg->reg, 2, &data, 1); break;
reg->val = le32_to_cpu(data & 0xff); case 14: /* Colibri - read dword */
break; ret =
case 24: /* Hammerhead - read dword */ cx231xx_read_i2c_data(dev, Colibri_DEVICE_ADDRESS,
ret = cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, (u16) reg->reg, 2, &data, 4); (u16) reg->reg, 2, &data, 4);
reg->val = le32_to_cpu(data); reg->val = le32_to_cpu(data);
break; break;
case 3: /* flatiron - read byte */ case 2: /* Hammerhead - read byte */
ret = cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS, (u16) reg->reg, 1, &data, 1); ret =
reg->val = le32_to_cpu(data & 0xff); cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
break; (u16) reg->reg, 2, &data, 1);
case 34: /* flatiron - read dword */ reg->val = le32_to_cpu(data & 0xff);
ret = cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS, (u16) reg->reg, 1, &data, 4); break;
reg->val = le32_to_cpu(data); case 24: /* Hammerhead - read dword */
break; ret =
} cx231xx_read_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS,
return ret < 0?ret:0; (u16) reg->reg, 2, &data, 4);
reg->val = le32_to_cpu(data);
case V4L2_CHIP_MATCH_I2C_DRIVER: break;
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_DBG_G_REGISTER, reg); case 3: /* flatiron - read byte */
return 0; ret =
case V4L2_CHIP_MATCH_I2C_ADDR: cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
/* Not supported yet */ (u16) reg->reg, 1, &data, 1);
return -EINVAL; reg->val = le32_to_cpu(data & 0xff);
default: break;
if (!v4l2_chip_match_host(&reg->match)) case 34: /* flatiron - read dword */
return -EINVAL; ret =
} cx231xx_read_i2c_data(dev, Flatrion_DEVICE_ADDRESS,
(u16) reg->reg, 1, &data, 4);
reg->val = le32_to_cpu(data);
break;
}
return ret < 0 ? ret : 0;
case V4L2_CHIP_MATCH_I2C_DRIVER:
cx231xx_i2c_call_clients(&dev->i2c_bus[0],
VIDIOC_DBG_G_REGISTER, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
return -EINVAL;
default:
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
}
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_DBG_G_REGISTER, reg); cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_DBG_G_REGISTER, reg);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return ret; return ret;
} }
...@@ -1492,70 +1500,97 @@ static int vidioc_g_register(struct file *file, void *priv, ...@@ -1492,70 +1500,97 @@ static int vidioc_g_register(struct file *file, void *priv,
static int vidioc_s_register(struct file *file, void *priv, static int vidioc_s_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg) struct v4l2_dbg_register *reg)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int ret = 0; int ret = 0;
__le64 buf; __le64 buf;
u32 value; u32 value;
u8 data[4] ={0,0,0,0}; u8 data[4] = { 0, 0, 0, 0 };
buf = cpu_to_le64(reg->val); buf = cpu_to_le64(reg->val);
switch (reg->match.type) { switch (reg->match.type) {
case V4L2_CHIP_MATCH_HOST: case V4L2_CHIP_MATCH_HOST:
{ {
value = (u32) buf & 0xffffffff; value = (u32) buf & 0xffffffff;
switch(reg->match.addr) { switch (reg->match.addr) {
case 0: /* cx231xx internal registers */ case 0: /* cx231xx internal registers */
data[0]=(u8)value; data[0] = (u8) value;
data[1]=(u8)(value>>8); data[1] = (u8) (value >> 8);
data[2]=(u8)(value>>16); data[2] = (u8) (value >> 16);
data[3]=(u8)(value>>24); data[3] = (u8) (value >> 24);
ret = cx231xx_write_ctrl_reg(dev,VRT_SET_REGISTER, (u16) reg->reg, data, 4); ret =
break; cx231xx_write_ctrl_reg(dev,
case 1: /* Colibri - read byte */ VRT_SET_REGISTER,
ret = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS, (u16) reg->reg, 2, value, 1); (u16) reg->reg, data,
break; 4);
case 14: /* Colibri - read dword */ break;
ret = cx231xx_write_i2c_data(dev, Colibri_DEVICE_ADDRESS, (u16) reg->reg, 2, value, 4); case 1: /* Colibri - read byte */
break; ret =
case 2: /* Hammerhead - read byte */ cx231xx_write_i2c_data(dev,
ret = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, (u16) reg->reg, 2, value, 1); Colibri_DEVICE_ADDRESS,
break; (u16) reg->reg, 2,
case 24: /* Hammerhead - read dword */ value, 1);
ret = cx231xx_write_i2c_data(dev, HAMMERHEAD_I2C_ADDRESS, (u16) reg->reg, 2, value, 4); break;
break; case 14: /* Colibri - read dword */
case 3: /* flatiron - read byte */ ret =
ret = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS, (u16) reg->reg, 1, value, 1); cx231xx_write_i2c_data(dev,
break; Colibri_DEVICE_ADDRESS,
case 34: /* flatiron - read dword */ (u16) reg->reg, 2,
ret = cx231xx_write_i2c_data(dev, Flatrion_DEVICE_ADDRESS, (u16) reg->reg, 1, value, 4); value, 4);
break; break;
} case 2: /* Hammerhead - read byte */
} ret =
return ret < 0?ret:0; cx231xx_write_i2c_data(dev,
HAMMERHEAD_I2C_ADDRESS,
default: (u16) reg->reg, 2,
break; value, 1);
} break;
case 24: /* Hammerhead - read dword */
ret =
cx231xx_write_i2c_data(dev,
HAMMERHEAD_I2C_ADDRESS,
(u16) reg->reg, 2,
value, 4);
break;
case 3: /* flatiron - read byte */
ret =
cx231xx_write_i2c_data(dev,
Flatrion_DEVICE_ADDRESS,
(u16) reg->reg, 1,
value, 1);
break;
case 34: /* flatiron - read dword */
ret =
cx231xx_write_i2c_data(dev,
Flatrion_DEVICE_ADDRESS,
(u16) reg->reg, 1,
value, 4);
break;
}
}
return ret < 0 ? ret : 0;
default:
break;
}
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_DBG_S_REGISTER, reg); cx231xx_i2c_call_clients(&dev->i2c_bus[0], VIDIOC_DBG_S_REGISTER, reg);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return ret; return ret;
} }
#endif #endif
static int vidioc_cropcap(struct file *file, void *priv, static int vidioc_cropcap(struct file *file, void *priv,
struct v4l2_cropcap *cc) struct v4l2_cropcap *cc)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL; return -EINVAL;
...@@ -1572,17 +1607,17 @@ static int vidioc_cropcap(struct file *file, void *priv, ...@@ -1572,17 +1607,17 @@ static int vidioc_cropcap(struct file *file, void *priv,
} }
static int vidioc_streamon(struct file *file, void *priv, static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
rc = res_get(fh); rc = res_get(fh);
if (likely(rc >= 0)) if (likely(rc >= 0))
...@@ -1594,52 +1629,51 @@ static int vidioc_streamon(struct file *file, void *priv, ...@@ -1594,52 +1629,51 @@ static int vidioc_streamon(struct file *file, void *priv,
} }
static int vidioc_streamoff(struct file *file, void *priv, static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
if ( (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) ) (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
return -EINVAL; return -EINVAL;
if (type != fh->type) if (type != fh->type)
return -EINVAL; return -EINVAL;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
videobuf_streamoff(&fh->vb_vidq); videobuf_streamoff(&fh->vb_vidq);
res_free(fh); res_free(fh);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return 0; return 0;
} }
static int vidioc_querycap(struct file *file, void *priv, static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
strlcpy(cap->driver, "cx231xx", sizeof(cap->driver)); strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
sizeof(cap->bus_info));
cap->version = CX231XX_VERSION_CODE; cap->version = CX231XX_VERSION_CODE;
cap->capabilities = cap->capabilities = V4L2_CAP_VBI_CAPTURE |
V4L2_CAP_VBI_CAPTURE |
#if 0 #if 0
V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE |
#endif #endif
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_AUDIO | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
if (dev->tuner_type != TUNER_ABSENT) if (dev->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER; cap->capabilities |= V4L2_CAP_TUNER;
...@@ -1647,10 +1681,10 @@ static int vidioc_querycap(struct file *file, void *priv, ...@@ -1647,10 +1681,10 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0; return 0;
} }
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f) struct v4l2_fmtdesc *f)
{ {
if (unlikely(f->index >= ARRAY_SIZE(format))) if (unlikely(f->index >= ARRAY_SIZE(format)))
return -EINVAL; return -EINVAL;
strlcpy(f->description, format[f->index].name, sizeof(f->description)); strlcpy(f->description, format[f->index].name, sizeof(f->description));
...@@ -1661,11 +1695,11 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, ...@@ -1661,11 +1695,11 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
/* Sliced VBI ioctls */ /* Sliced VBI ioctls */
static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1685,11 +1719,11 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, ...@@ -1685,11 +1719,11 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
} }
static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1705,26 +1739,25 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, ...@@ -1705,26 +1739,25 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
return 0; return 0;
} }
/* RAW VBI ioctls */ /* RAW VBI ioctls */
static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
35468950:28636363; 35468950 : 28636363;
f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
f->fmt.vbi.offset = 64 * 4; f->fmt.vbi.offset = 64 * 4;
f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_START_LINE : NTSC_VBI_START_LINE; PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES; PAL_VBI_LINES : NTSC_VBI_LINES;
f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_START_LINE+312 : NTSC_VBI_START_LINE + 263; PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
return 0; return 0;
...@@ -1732,29 +1765,29 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, ...@@ -1732,29 +1765,29 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
} }
static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
if (dev->vbi_stream_on && !fh->stream_on) { if (dev->vbi_stream_on && !fh->stream_on) {
cx231xx_errdev("%s device in use by another fh\n", __func__); cx231xx_errdev("%s device in use by another fh\n", __func__);
return -EBUSY; return -EBUSY;
} }
f->type = V4L2_BUF_TYPE_VBI_CAPTURE; f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
35468950:28636363; 35468950 : 28636363;
f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
f->fmt.vbi.offset = 244; f->fmt.vbi.offset = 244;
f->fmt.vbi.flags = 0; f->fmt.vbi.flags = 0;
f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_START_LINE : NTSC_VBI_START_LINE; PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES; PAL_VBI_LINES : NTSC_VBI_LINES;
f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ? f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
PAL_VBI_START_LINE+312 : NTSC_VBI_START_LINE + 263; PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
return 0; return 0;
...@@ -1764,9 +1797,9 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, ...@@ -1764,9 +1797,9 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,
static int vidioc_reqbufs(struct file *file, void *priv, static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *rb) struct v4l2_requestbuffers *rb)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1775,12 +1808,11 @@ static int vidioc_reqbufs(struct file *file, void *priv, ...@@ -1775,12 +1808,11 @@ static int vidioc_reqbufs(struct file *file, void *priv,
return (videobuf_reqbufs(&fh->vb_vidq, rb)); return (videobuf_reqbufs(&fh->vb_vidq, rb));
} }
static int vidioc_querybuf(struct file *file, void *priv, static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b)
struct v4l2_buffer *b)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1791,9 +1823,9 @@ static int vidioc_querybuf(struct file *file, void *priv, ...@@ -1791,9 +1823,9 @@ static int vidioc_querybuf(struct file *file, void *priv,
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
...@@ -1804,33 +1836,31 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) ...@@ -1804,33 +1836,31 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
return (videobuf_dqbuf(&fh->vb_vidq, b, return (videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK));
file->f_flags & O_NONBLOCK));
} }
#ifdef CONFIG_VIDEO_V4L1_COMPAT #ifdef CONFIG_VIDEO_V4L1_COMPAT
static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
{ {
struct cx231xx_fh *fh = priv; struct cx231xx_fh *fh = priv;
return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
} }
#endif #endif
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* RADIO ESPECIFIC IOCTLS */ /* RADIO ESPECIFIC IOCTLS */
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
static int radio_querycap(struct file *file, void *priv, static int radio_querycap(struct file *file, void *priv,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
...@@ -1844,8 +1874,7 @@ static int radio_querycap(struct file *file, void *priv, ...@@ -1844,8 +1874,7 @@ static int radio_querycap(struct file *file, void *priv,
return 0; return 0;
} }
static int radio_g_tuner(struct file *file, void *priv, static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct v4l2_tuner *t)
{ {
struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
...@@ -1855,15 +1884,14 @@ static int radio_g_tuner(struct file *file, void *priv, ...@@ -1855,15 +1884,14 @@ static int radio_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Radio"); strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO; t->type = V4L2_TUNER_RADIO;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return 0; return 0;
} }
static int radio_enum_input(struct file *file, void *priv, static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i)
struct v4l2_input *i)
{ {
if (i->index != 0) if (i->index != 0)
return -EINVAL; return -EINVAL;
...@@ -1882,23 +1910,21 @@ static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a) ...@@ -1882,23 +1910,21 @@ static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0; return 0;
} }
static int radio_s_tuner(struct file *file, void *priv, static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct v4l2_tuner *t)
{ {
struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
if (0 != t->index) if (0 != t->index)
return -EINVAL; return -EINVAL;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_TUNER, t); cx231xx_i2c_call_clients(&dev->i2c_bus[1], VIDIOC_S_TUNER, t);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return 0; return 0;
} }
static int radio_s_audio(struct file *file, void *fh, static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
struct v4l2_audio *a)
{ {
return 0; return 0;
} }
...@@ -1913,8 +1939,7 @@ static int radio_queryctrl(struct file *file, void *priv, ...@@ -1913,8 +1939,7 @@ static int radio_queryctrl(struct file *file, void *priv,
{ {
int i; int i;
if (c->id < V4L2_CID_BASE || if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
c->id >= V4L2_CID_LASTP1)
return -EINVAL; return -EINVAL;
if (c->id == V4L2_CID_AUDIO_MUTE) { if (c->id == V4L2_CID_AUDIO_MUTE) {
for (i = 0; i < CX231XX_CTLS; i++) for (i = 0; i < CX231XX_CTLS; i++)
...@@ -1932,25 +1957,26 @@ static int radio_queryctrl(struct file *file, void *priv, ...@@ -1932,25 +1957,26 @@ static int radio_queryctrl(struct file *file, void *priv,
*/ */
static int cx231xx_v4l2_open(struct file *filp) static int cx231xx_v4l2_open(struct file *filp)
{ {
int minor = video_devdata(filp)->minor; int minor = video_devdata(filp)->minor;
int errCode = 0, radio = 0; int errCode = 0, radio = 0;
struct cx231xx *dev = NULL; struct cx231xx *dev = NULL;
struct cx231xx_fh *fh; struct cx231xx_fh *fh;
enum v4l2_buf_type fh_type = 0; enum v4l2_buf_type fh_type = 0;
dev = cx231xx_get_device(minor, &fh_type, &radio); dev = cx231xx_get_device(minor, &fh_type, &radio);
if (NULL == dev) if (NULL == dev)
return -ENODEV; return -ENODEV;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
cx231xx_videodbg("open minor=%d type=%s users=%d\n", cx231xx_videodbg("open minor=%d type=%s users=%d\n",
minor, v4l2_type_names[fh_type], dev->users); minor, v4l2_type_names[fh_type], dev->users);
#if 0 #if 0
errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
if (errCode < 0) { if (errCode < 0) {
cx231xx_errdev("Device locked on digital mode. Can't open analog\n"); cx231xx_errdev
("Device locked on digital mode. Can't open analog\n");
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return -EBUSY; return -EBUSY;
} }
...@@ -1973,25 +1999,24 @@ static int cx231xx_v4l2_open(struct file *filp) ...@@ -1973,25 +1999,24 @@ static int cx231xx_v4l2_open(struct file *filp)
dev->hscale = 0; dev->hscale = 0;
dev->vscale = 0; dev->vscale = 0;
/* Power up in Analog TV mode */
/* Power up in Analog TV mode */ cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
#if 0 #if 0
cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
#endif #endif
cx231xx_resolution_set(dev); cx231xx_resolution_set(dev);
/* set video alternate setting */ /* set video alternate setting */
cx231xx_set_video_alternate(dev); cx231xx_set_video_alternate(dev);
/* Needed, since GPIO might have disabled power of /* Needed, since GPIO might have disabled power of
some i2c device */ some i2c device */
cx231xx_config_i2c(dev); cx231xx_config_i2c(dev);
/* device needs to be initialized before isoc transfer */ /* device needs to be initialized before isoc transfer */
dev->video_input = dev->video_input > 2 ? 2: dev->video_input; dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
video_mux(dev, dev->video_input ); video_mux(dev, dev->video_input);
} }
if (fh->radio) { if (fh->radio) {
...@@ -1999,26 +2024,25 @@ static int cx231xx_v4l2_open(struct file *filp) ...@@ -1999,26 +2024,25 @@ static int cx231xx_v4l2_open(struct file *filp)
/* cx231xx_start_radio(dev); */ /* cx231xx_start_radio(dev); */
cx231xx_i2c_call_clients(&dev->i2c_bus[1], AUDC_SET_RADIO, NULL); cx231xx_i2c_call_clients(&dev->i2c_bus[1], AUDC_SET_RADIO,
NULL);
} }
dev->users++; dev->users++;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops, videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops, NULL, &dev->video_mode.slock, fh->type, V4L2_FIELD_INTERLACED, /* V4L2_FIELD_SEQ_TB, */
NULL, &dev->video_mode.slock, fh->type, V4L2_FIELD_INTERLACED, /* V4L2_FIELD_SEQ_TB, */ sizeof(struct cx231xx_buffer), fh);
sizeof(struct cx231xx_buffer), fh); }
}
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
/* Set the required alternate setting VBI interface works in Bulk mode only */ /* Set the required alternate setting VBI interface works in Bulk mode only */
cx231xx_set_alt_setting(dev, INDEX_VANC, 0); cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, NULL, &dev->vbi_mode.slock, fh->type, V4L2_FIELD_SEQ_TB, /* V4L2_FIELD_INTERLACED, */
NULL, &dev->vbi_mode.slock, fh->type, V4L2_FIELD_SEQ_TB, /* V4L2_FIELD_INTERLACED, */ sizeof(struct cx231xx_buffer), fh);
sizeof(struct cx231xx_buffer), fh); }
}
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
...@@ -2044,7 +2068,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) ...@@ -2044,7 +2068,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
} }
if (dev->vbi_dev) { if (dev->vbi_dev) {
cx231xx_info("V4L2 device /dev/vbi%d deregistered\n", cx231xx_info("V4L2 device /dev/vbi%d deregistered\n",
dev->vbi_dev->num); dev->vbi_dev->num);
if (-1 != dev->vbi_dev->minor) if (-1 != dev->vbi_dev->minor)
video_unregister_device(dev->vbi_dev); video_unregister_device(dev->vbi_dev);
else else
...@@ -2053,7 +2077,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) ...@@ -2053,7 +2077,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
} }
if (dev->vdev) { if (dev->vdev) {
cx231xx_info("V4L2 device /dev/video%d deregistered\n", cx231xx_info("V4L2 device /dev/video%d deregistered\n",
dev->vdev->num); dev->vdev->num);
if (-1 != dev->vdev->minor) if (-1 != dev->vdev->minor)
video_unregister_device(dev->vdev); video_unregister_device(dev->vdev);
else else
...@@ -2069,44 +2093,44 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) ...@@ -2069,44 +2093,44 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
*/ */
static int cx231xx_v4l2_close(struct file *filp) static int cx231xx_v4l2_close(struct file *filp)
{ {
struct cx231xx_fh *fh = filp->private_data; struct cx231xx_fh *fh = filp->private_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
cx231xx_videodbg("users=%d\n", dev->users); cx231xx_videodbg("users=%d\n", dev->users);
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
if (res_check(fh)) if (res_check(fh))
res_free(fh); res_free(fh);
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
videobuf_stop(&fh->vb_vidq); videobuf_stop(&fh->vb_vidq);
videobuf_mmap_free(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq);
/* the device is already disconnect, /* the device is already disconnect,
free the remaining resources */ free the remaining resources */
if (dev->state & DEV_DISCONNECTED) { if (dev->state & DEV_DISCONNECTED) {
cx231xx_release_resources(dev); cx231xx_release_resources(dev);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
kfree(dev); kfree(dev);
return 0; return 0;
} }
/* do this before setting alternate! */ /* do this before setting alternate! */
cx231xx_uninit_vbi_isoc(dev); cx231xx_uninit_vbi_isoc(dev);
/* set alternate 0 */ /* set alternate 0 */
if( !dev->vbi_or_sliced_cc_mode) { if (!dev->vbi_or_sliced_cc_mode) {
cx231xx_set_alt_setting(dev, INDEX_VANC, 0); cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
} else { } else {
cx231xx_set_alt_setting(dev, INDEX_HANC, 0); cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
} }
kfree(fh); kfree(fh);
dev->users--; dev->users--;
wake_up_interruptible_nr(&dev->open, 1); wake_up_interruptible_nr(&dev->open, 1);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return 0; return 0;
} }
if (dev->users == 1) { if (dev->users == 1) {
...@@ -2122,8 +2146,9 @@ static int cx231xx_v4l2_close(struct file *filp) ...@@ -2122,8 +2146,9 @@ static int cx231xx_v4l2_close(struct file *filp)
return 0; return 0;
} }
/* Save some power by putting tuner to sleep */ /* Save some power by putting tuner to sleep */
cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_STANDBY, NULL); cx231xx_i2c_call_clients(&dev->i2c_bus[1], TUNER_SET_STANDBY,
NULL);
/* do this before setting alternate! */ /* do this before setting alternate! */
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
...@@ -2144,8 +2169,8 @@ static int cx231xx_v4l2_close(struct file *filp) ...@@ -2144,8 +2169,8 @@ static int cx231xx_v4l2_close(struct file *filp)
* will allocate buffers when called for the first time * will allocate buffers when called for the first time
*/ */
static ssize_t static ssize_t
cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, cx231xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
loff_t *pos) loff_t * pos)
{ {
struct cx231xx_fh *fh = filp->private_data; struct cx231xx_fh *fh = filp->private_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
...@@ -2155,8 +2180,8 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, ...@@ -2155,8 +2180,8 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
if (rc < 0) if (rc < 0)
return rc; return rc;
if ( (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
(fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) ) { (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
rc = res_get(fh); rc = res_get(fh);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
...@@ -2165,7 +2190,7 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, ...@@ -2165,7 +2190,7 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
return rc; return rc;
return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK); filp->f_flags & O_NONBLOCK);
} }
return 0; return 0;
} }
...@@ -2191,10 +2216,10 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait) ...@@ -2191,10 +2216,10 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait)
if (unlikely(rc < 0)) if (unlikely(rc < 0))
return POLLERR; return POLLERR;
if ( (V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
(V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) ) (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))
return videobuf_poll_stream(filp, &fh->vb_vidq, wait); return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
else else
return POLLERR; return POLLERR;
} }
...@@ -2203,15 +2228,15 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait) ...@@ -2203,15 +2228,15 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait)
*/ */
static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
{ {
struct cx231xx_fh *fh = filp->private_data; struct cx231xx_fh *fh = filp->private_data;
struct cx231xx *dev = fh->dev; struct cx231xx *dev = fh->dev;
int rc; int rc;
rc = check_dev(dev); rc = check_dev(dev);
if (rc < 0) if (rc < 0)
return rc; return rc;
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
rc = res_get(fh); rc = res_get(fh);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
...@@ -2221,114 +2246,112 @@ static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -2221,114 +2246,112 @@ static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start, (unsigned long)vma->vm_start,
(unsigned long)vma->vm_end-(unsigned long)vma->vm_start, (unsigned long)vma->vm_end -
rc); (unsigned long)vma->vm_start, rc);
return rc; return rc;
} }
static const struct v4l2_file_operations cx231xx_v4l_fops = { static const struct v4l2_file_operations cx231xx_v4l_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = cx231xx_v4l2_open, .open = cx231xx_v4l2_open,
.release = cx231xx_v4l2_close, .release = cx231xx_v4l2_close,
.read = cx231xx_v4l2_read, .read = cx231xx_v4l2_read,
.poll = cx231xx_v4l2_poll, .poll = cx231xx_v4l2_poll,
.mmap = cx231xx_v4l2_mmap, .mmap = cx231xx_v4l2_mmap,
.ioctl = video_ioctl2, .ioctl = video_ioctl2,
}; };
static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap, .vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
.vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
.vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
.vidioc_g_audio = vidioc_g_audio, .vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio, .vidioc_s_audio = vidioc_s_audio,
.vidioc_cropcap = vidioc_cropcap, .vidioc_cropcap = vidioc_cropcap,
.vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
.vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
.vidioc_reqbufs = vidioc_reqbufs, .vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf, .vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf, .vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf, .vidioc_dqbuf = vidioc_dqbuf,
.vidioc_s_std = vidioc_s_std, .vidioc_s_std = vidioc_s_std,
.vidioc_g_std = vidioc_g_std, .vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input, .vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input, .vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input, .vidioc_s_input = vidioc_s_input,
.vidioc_queryctrl = vidioc_queryctrl, .vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon, .vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff, .vidioc_streamoff = vidioc_streamoff,
.vidioc_g_tuner = vidioc_g_tuner, .vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner, .vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency, .vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency, .vidioc_s_frequency = vidioc_s_frequency,
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register, .vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register, .vidioc_s_register = vidioc_s_register,
#endif #endif
#ifdef CONFIG_VIDEO_V4L1_COMPAT #ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidiocgmbuf, .vidiocgmbuf = vidiocgmbuf,
#endif #endif
}; };
static struct video_device cx231xx_vbi_template; static struct video_device cx231xx_vbi_template;
static const struct video_device cx231xx_video_template = { static const struct video_device cx231xx_video_template = {
.fops = &cx231xx_v4l_fops, .fops = &cx231xx_v4l_fops,
.release = video_device_release, .release = video_device_release,
.ioctl_ops = &video_ioctl_ops, .ioctl_ops = &video_ioctl_ops,
.minor = -1, .minor = -1,
.tvnorms = V4L2_STD_ALL, .tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL, .current_norm = V4L2_STD_PAL,
}; };
static const struct v4l2_file_operations radio_fops = { static const struct v4l2_file_operations radio_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = cx231xx_v4l2_open, .open = cx231xx_v4l2_open,
.release = cx231xx_v4l2_close, .release = cx231xx_v4l2_close,
.ioctl = video_ioctl2, .ioctl = video_ioctl2,
}; };
static const struct v4l2_ioctl_ops radio_ioctl_ops = { static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap, .vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner, .vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input, .vidioc_enum_input = radio_enum_input,
.vidioc_g_audio = radio_g_audio, .vidioc_g_audio = radio_g_audio,
.vidioc_s_tuner = radio_s_tuner, .vidioc_s_tuner = radio_s_tuner,
.vidioc_s_audio = radio_s_audio, .vidioc_s_audio = radio_s_audio,
.vidioc_s_input = radio_s_input, .vidioc_s_input = radio_s_input,
.vidioc_queryctrl = radio_queryctrl, .vidioc_queryctrl = radio_queryctrl,
.vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_frequency = vidioc_g_frequency, .vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency, .vidioc_s_frequency = vidioc_s_frequency,
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register, .vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register, .vidioc_s_register = vidioc_s_register,
#endif #endif
}; };
static struct video_device cx231xx_radio_template = { static struct video_device cx231xx_radio_template = {
.name = "cx231xx-radio", .name = "cx231xx-radio",
.fops = &radio_fops, .fops = &radio_fops,
.ioctl_ops = &radio_ioctl_ops, .ioctl_ops = &radio_ioctl_ops,
.minor = -1, .minor = -1,
}; };
/******************************** usb interface ******************************/ /******************************** usb interface ******************************/
static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, const struct video_device
static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, *template, const char *type_name)
const struct video_device *template,
const char *type_name)
{ {
struct video_device *vfd; struct video_device *vfd;
...@@ -2336,13 +2359,12 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, ...@@ -2336,13 +2359,12 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
if (NULL == vfd) if (NULL == vfd)
return NULL; return NULL;
*vfd = *template; *vfd = *template;
vfd->minor = -1; vfd->minor = -1;
vfd->parent = &dev->udev->dev; vfd->parent = &dev->udev->dev;
vfd->release = video_device_release; vfd->release = video_device_release;
vfd->debug = video_debug; vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s", snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
dev->name, type_name);
return vfd; return vfd;
} }
...@@ -2351,15 +2373,16 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ...@@ -2351,15 +2373,16 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
{ {
int ret; int ret;
cx231xx_info("%s()\n", __func__); cx231xx_info("%s()\n", __func__);
cx231xx_info("%s: v4l2 driver version %d.%d.%d\n", cx231xx_info("%s: v4l2 driver version %d.%d.%d\n",
dev->name, dev->name,
(CX231XX_VERSION_CODE >> 16) & 0xff, (CX231XX_VERSION_CODE >> 16) & 0xff,
(CX231XX_VERSION_CODE >> 8) & 0xff, CX231XX_VERSION_CODE & 0xff); (CX231XX_VERSION_CODE >> 8) & 0xff,
CX231XX_VERSION_CODE & 0xff);
/* set default norm */ /* set default norm */
/*dev->norm = cx231xx_video_template.current_norm;*/ /*dev->norm = cx231xx_video_template.current_norm; */
dev->width = norm_maxw(dev); dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev); dev->height = norm_maxh(dev);
dev->interlaced = 0; dev->interlaced = 0;
...@@ -2375,7 +2398,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ...@@ -2375,7 +2398,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
dev->volume = 0x1f; dev->volume = 0x1f;
/* enable vbi capturing */ /* enable vbi capturing */
/* write code here... */ /* write code here... */
/* allocate and fill video video_device struct */ /* allocate and fill video video_device struct */
dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video");
...@@ -2386,37 +2409,38 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ...@@ -2386,37 +2409,38 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
/* register v4l2 video video_device */ /* register v4l2 video video_device */
ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
video_nr[dev->devno]); video_nr[dev->devno]);
if (ret) { if (ret) {
cx231xx_errdev("unable to register video device (error=%i).\n", ret); cx231xx_errdev("unable to register video device (error=%i).\n",
ret);
return ret; return ret;
} }
cx231xx_info("%s/0: registered device video%d [v4l2]\n", cx231xx_info("%s/0: registered device video%d [v4l2]\n",
dev->name, dev->vdev->num); dev->name, dev->vdev->num);
/* Initialize VBI template */
memcpy( &cx231xx_vbi_template, &cx231xx_video_template,
sizeof(cx231xx_vbi_template) );
strcpy(cx231xx_vbi_template.name,"cx231xx-vbi");
/* Initialize VBI template */
memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
sizeof(cx231xx_vbi_template));
strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");
/* Allocate and fill vbi video_device struct */ /* Allocate and fill vbi video_device struct */
dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi");
/* register v4l2 vbi video_device */ /* register v4l2 vbi video_device */
ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]); vbi_nr[dev->devno]);
if (ret < 0) { if (ret < 0) {
cx231xx_errdev("unable to register vbi device\n"); cx231xx_errdev("unable to register vbi device\n");
return ret; return ret;
} }
cx231xx_info("%s/0: registered device vbi%d\n", cx231xx_info("%s/0: registered device vbi%d\n",
dev->name, dev->vbi_dev->num); dev->name, dev->vbi_dev->num);
if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio"); dev->radio_dev =
cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio");
if (!dev->radio_dev) { if (!dev->radio_dev) {
cx231xx_errdev("cannot allocate video_device.\n"); cx231xx_errdev("cannot allocate video_device.\n");
return -ENODEV; return -ENODEV;
...@@ -2428,13 +2452,11 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ...@@ -2428,13 +2452,11 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
return ret; return ret;
} }
cx231xx_info("Registered radio device as /dev/radio%d\n", cx231xx_info("Registered radio device as /dev/radio%d\n",
dev->radio_dev->num); dev->radio_dev->num);
} }
cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
dev->vdev->num, dev->vbi_dev->num); dev->vdev->num, dev->vbi_dev->num);
return 0; return 0;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
cx231xx.h - driver for Conexant Cx23100/101/102 USB video capture devices cx231xx.h - driver for Conexant Cx23100/101/102 USB video capture devices
Copyright (C) 2008 <srinivasa.deevi at conexant dot com> Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
Based on em28xx driver Based on em28xx driver
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
/* Params for validated field */ /* Params for validated field */
#define CX231XX_BOARD_NOT_VALIDATED 1 #define CX231XX_BOARD_NOT_VALIDATED 1
#define CX231XX_BOARD_VALIDATED 0 #define CX231XX_BOARD_VALIDATED 0
/* maximum number of cx231xx boards */ /* maximum number of cx231xx boards */
#define CX231XX_MAXBOARDS 8 #define CX231XX_MAXBOARDS 8
...@@ -82,17 +82,14 @@ ...@@ -82,17 +82,14 @@
*/ */
#define CX231XX_NUM_PACKETS 40 #define CX231XX_NUM_PACKETS 40
/* default alternate; 0 means choose the best */ /* default alternate; 0 means choose the best */
#define CX231XX_PINOUT 0 #define CX231XX_PINOUT 0
#define CX231XX_INTERLACED_DEFAULT 1 #define CX231XX_INTERLACED_DEFAULT 1
/* time to wait when stopping the isoc transfer */ /* time to wait when stopping the isoc transfer */
#define CX231XX_URB_TIMEOUT msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS) #define CX231XX_URB_TIMEOUT msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS)
enum cx231xx_mode { enum cx231xx_mode {
CX231XX_SUSPEND, CX231XX_SUSPEND,
CX231XX_ANALOG_MODE, CX231XX_ANALOG_MODE,
...@@ -113,47 +110,45 @@ enum cx231xx_stream_state { ...@@ -113,47 +110,45 @@ enum cx231xx_stream_state {
struct cx231xx; struct cx231xx;
struct cx231xx_usb_isoc_ctl { struct cx231xx_usb_isoc_ctl {
/* max packet size of isoc transaction */ /* max packet size of isoc transaction */
int max_pkt_size; int max_pkt_size;
/* number of allocated urbs */ /* number of allocated urbs */
int num_bufs; int num_bufs;
/* urb for isoc transfers */ /* urb for isoc transfers */
struct urb **urb; struct urb **urb;
/* transfer buffers for isoc transfer */ /* transfer buffers for isoc transfer */
char **transfer_buffer; char **transfer_buffer;
/* Last buffer command and region */ /* Last buffer command and region */
u8 cmd; u8 cmd;
int pos, size, pktsize; int pos, size, pktsize;
/* Last field: ODD or EVEN? */ /* Last field: ODD or EVEN? */
int field; int field;
/* Stores incomplete commands */ /* Stores incomplete commands */
u32 tmp_buf; u32 tmp_buf;
int tmp_buf_len; int tmp_buf_len;
/* Stores already requested buffers */ /* Stores already requested buffers */
struct cx231xx_buffer *buf; struct cx231xx_buffer *buf;
/* Stores the number of received fields */ /* Stores the number of received fields */
int nfields; int nfields;
/* isoc urb callback */ /* isoc urb callback */
int (*isoc_copy) (struct cx231xx *dev, struct urb *urb); int (*isoc_copy) (struct cx231xx * dev, struct urb * urb);
}; };
struct cx231xx_fmt { struct cx231xx_fmt {
char *name; char *name;
u32 fourcc; /* v4l2 format id */ u32 fourcc; /* v4l2 format id */
int depth; int depth;
int reg; int reg;
}; };
/* buffer for one video frame */ /* buffer for one video frame */
...@@ -167,24 +162,23 @@ struct cx231xx_buffer { ...@@ -167,24 +162,23 @@ struct cx231xx_buffer {
}; };
struct cx231xx_dmaqueue { struct cx231xx_dmaqueue {
struct list_head active; struct list_head active;
struct list_head queued; struct list_head queued;
wait_queue_head_t wq; wait_queue_head_t wq;
/* Counters to control buffer fill */ /* Counters to control buffer fill */
int pos; int pos;
u8 is_partial_line; u8 is_partial_line;
u8 partial_buf[8]; u8 partial_buf[8];
u8 last_sav; u8 last_sav;
int current_field; int current_field;
u32 bytes_left_in_line; u32 bytes_left_in_line;
u32 lines_completed; u32 lines_completed;
u8 field1_done; u8 field1_done;
u32 lines_per_field; u32 lines_per_field;
}; };
/* inputs */ /* inputs */
#define MAX_CX231XX_INPUT 4 #define MAX_CX231XX_INPUT 4
...@@ -193,35 +187,35 @@ enum cx231xx_itype { ...@@ -193,35 +187,35 @@ enum cx231xx_itype {
CX231XX_VMUX_COMPOSITE1 = 1, CX231XX_VMUX_COMPOSITE1 = 1,
CX231XX_VMUX_SVIDEO, CX231XX_VMUX_SVIDEO,
CX231XX_VMUX_TELEVISION, CX231XX_VMUX_TELEVISION,
CX231XX_VMUX_CABLE, CX231XX_VMUX_CABLE,
CX231XX_RADIO, CX231XX_RADIO,
CX231XX_VMUX_DVB, CX231XX_VMUX_DVB,
CX231XX_VMUX_DEBUG CX231XX_VMUX_DEBUG
}; };
enum cx231xx_v_input { enum cx231xx_v_input {
CX231XX_VIN_1_1 = 0x1, CX231XX_VIN_1_1 = 0x1,
CX231XX_VIN_2_1, CX231XX_VIN_2_1,
CX231XX_VIN_3_1, CX231XX_VIN_3_1,
CX231XX_VIN_4_1, CX231XX_VIN_4_1,
CX231XX_VIN_1_2 = 0x01, CX231XX_VIN_1_2 = 0x01,
CX231XX_VIN_2_2, CX231XX_VIN_2_2,
CX231XX_VIN_3_2, CX231XX_VIN_3_2,
CX231XX_VIN_1_3 = 0x1, CX231XX_VIN_1_3 = 0x1,
CX231XX_VIN_2_3, CX231XX_VIN_2_3,
CX231XX_VIN_3_3, CX231XX_VIN_3_3,
}; };
/* cx231xx has two audio inputs: tuner and line in */ /* cx231xx has two audio inputs: tuner and line in */
enum cx231xx_amux { enum cx231xx_amux {
/* This is the only entry for cx231xx tuner input */ /* This is the only entry for cx231xx tuner input */
CX231XX_AMUX_VIDEO, /* cx231xx tuner*/ CX231XX_AMUX_VIDEO, /* cx231xx tuner */
CX231XX_AMUX_LINE_IN, /* Line In */ CX231XX_AMUX_LINE_IN, /* Line In */
}; };
struct cx231xx_reg_seq { struct cx231xx_reg_seq {
unsigned char bit; unsigned char bit;
unsigned char val; unsigned char val;
int sleep; int sleep;
}; };
...@@ -239,41 +233,40 @@ enum cx231xx_decoder { ...@@ -239,41 +233,40 @@ enum cx231xx_decoder {
CX231XX_AVDECODER CX231XX_AVDECODER
}; };
typedef enum _I2C_MASTER_PORT typedef enum _I2C_MASTER_PORT {
{ I2C_0 = 0,
I2C_0 =0, I2C_1 = 1,
I2C_1 =1, I2C_2 = 2,
I2C_2 =2, I2C_3 = 3
I2C_3 =3 } CX231XX_I2C_MASTER_PORT;
}CX231XX_I2C_MASTER_PORT;
struct cx231xx_board { struct cx231xx_board {
char *name; char *name;
int vchannels; int vchannels;
int tuner_type; int tuner_type;
int tuner_addr; int tuner_addr;
v4l2_std_id norm; /* tv norm */ v4l2_std_id norm; /* tv norm */
/* demod related */ /* demod related */
int demod_addr; int demod_addr;
u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */ u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */
/* GPIO Pins */ /* GPIO Pins */
struct cx231xx_reg_seq *dvb_gpio; struct cx231xx_reg_seq *dvb_gpio;
struct cx231xx_reg_seq *suspend_gpio; struct cx231xx_reg_seq *suspend_gpio;
struct cx231xx_reg_seq *tuner_gpio; struct cx231xx_reg_seq *tuner_gpio;
u8 tuner_sif_gpio; u8 tuner_sif_gpio;
u8 tuner_scl_gpio; u8 tuner_scl_gpio;
u8 tuner_sda_gpio; u8 tuner_sda_gpio;
/* PIN ctrl */ /* PIN ctrl */
u32 ctl_pin_status_mask; u32 ctl_pin_status_mask;
u8 agc_analog_digital_select_gpio; u8 agc_analog_digital_select_gpio;
u32 gpio_pin_status_mask; u32 gpio_pin_status_mask;
/* i2c masters */ /* i2c masters */
u8 tuner_i2c_master; u8 tuner_i2c_master;
u8 demod_i2c_master; u8 demod_i2c_master;
unsigned int max_range_640_480:1; unsigned int max_range_640_480:1;
unsigned int has_dvb:1; unsigned int has_dvb:1;
...@@ -283,9 +276,9 @@ struct cx231xx_board { ...@@ -283,9 +276,9 @@ struct cx231xx_board {
enum cx231xx_decoder decoder; enum cx231xx_decoder decoder;
struct cx231xx_input input[MAX_CX231XX_INPUT]; struct cx231xx_input input[MAX_CX231XX_INPUT];
struct cx231xx_input radio; struct cx231xx_input radio;
IR_KEYTAB_TYPE *ir_codes; IR_KEYTAB_TYPE *ir_codes;
}; };
/* device states */ /* device states */
...@@ -295,22 +288,20 @@ enum cx231xx_dev_state { ...@@ -295,22 +288,20 @@ enum cx231xx_dev_state {
DEV_MISCONFIGURED = 0x04, DEV_MISCONFIGURED = 0x04,
}; };
enum AFE_MODE enum AFE_MODE {
{ AFE_MODE_LOW_IF,
AFE_MODE_LOW_IF, AFE_MODE_BASEBAND,
AFE_MODE_BASEBAND, AFE_MODE_EU_HI_IF,
AFE_MODE_EU_HI_IF, AFE_MODE_US_HI_IF,
AFE_MODE_US_HI_IF, AFE_MODE_JAPAN_HI_IF
AFE_MODE_JAPAN_HI_IF
}; };
enum AUDIO_INPUT enum AUDIO_INPUT {
{ AUDIO_INPUT_MUTE,
AUDIO_INPUT_MUTE, AUDIO_INPUT_LINE,
AUDIO_INPUT_LINE, AUDIO_INPUT_TUNER_TV,
AUDIO_INPUT_TUNER_TV, AUDIO_INPUT_SPDIF,
AUDIO_INPUT_SPDIF, AUDIO_INPUT_TUNER_FM
AUDIO_INPUT_TUNER_FM
}; };
#define CX231XX_AUDIO_BUFS 5 #define CX231XX_AUDIO_BUFS 5
...@@ -319,7 +310,6 @@ enum AUDIO_INPUT ...@@ -319,7 +310,6 @@ enum AUDIO_INPUT
#define CX231XX_STOP_AUDIO 0 #define CX231XX_STOP_AUDIO 0
#define CX231XX_START_AUDIO 1 #define CX231XX_START_AUDIO 1
/* cx231xx extensions */ /* cx231xx extensions */
#define CX231XX_AUDIO 0x10 #define CX231XX_AUDIO 0x10
#define CX231XX_DVB 0x20 #define CX231XX_DVB 0x20
...@@ -330,169 +320,167 @@ struct cx231xx_audio { ...@@ -330,169 +320,167 @@ struct cx231xx_audio {
struct urb *urb[CX231XX_AUDIO_BUFS]; struct urb *urb[CX231XX_AUDIO_BUFS];
struct usb_device *udev; struct usb_device *udev;
unsigned int capture_transfer_done; unsigned int capture_transfer_done;
struct snd_pcm_substream *capture_pcm_substream; struct snd_pcm_substream *capture_pcm_substream;
unsigned int hwptr_done_capture; unsigned int hwptr_done_capture;
struct snd_card *sndcard; struct snd_card *sndcard;
int users, shutdown; int users, shutdown;
enum cx231xx_stream_state capture_stream; enum cx231xx_stream_state capture_stream;
spinlock_t slock; spinlock_t slock;
int alt; /* alternate */ int alt; /* alternate */
int max_pkt_size; /* max packet size of isoc transaction */ int max_pkt_size; /* max packet size of isoc transaction */
int num_alt; /* Number of alternative settings */ int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
u16 end_point_addr; u16 end_point_addr;
}; };
struct cx231xx; struct cx231xx;
struct cx231xx_fh { struct cx231xx_fh {
struct cx231xx *dev; struct cx231xx *dev;
unsigned int stream_on:1; /* Locks streams */ unsigned int stream_on:1; /* Locks streams */
int radio; int radio;
struct videobuf_queue vb_vidq; struct videobuf_queue vb_vidq;
enum v4l2_buf_type type; enum v4l2_buf_type type;
}; };
/**********************************************************************************/ /**********************************************************************************/
/* set/get i2c */ /* set/get i2c */
#define I2C_SPEED_1M 0x0 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ #define I2C_SPEED_1M 0x0 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
#define I2C_SPEED_400K 0x1 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ #define I2C_SPEED_400K 0x1 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
#define I2C_SPEED_100K 0x2 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ #define I2C_SPEED_100K 0x2 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
#define I2C_SPEED_5M 0x3 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ #define I2C_SPEED_5M 0x3 /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
#define I2C_STOP 0x0 /* 0-- STOP transaction */ #define I2C_STOP 0x0 /* 0-- STOP transaction */
#define I2C_NOSTOP 0x1 /* 1-- do not transmit STOP at end of transaction */ #define I2C_NOSTOP 0x1 /* 1-- do not transmit STOP at end of transaction */
#define I2C_SYNC 0x1 /* 1--alllow slave to insert clock wait states */ #define I2C_SYNC 0x1 /* 1--alllow slave to insert clock wait states */
struct cx231xx_i2c { struct cx231xx_i2c {
struct cx231xx *dev; struct cx231xx *dev;
int nr; int nr;
/* i2c i/o */ /* i2c i/o */
struct i2c_adapter i2c_adap; struct i2c_adapter i2c_adap;
struct i2c_algo_bit_data i2c_algo; struct i2c_algo_bit_data i2c_algo;
struct i2c_client i2c_client; struct i2c_client i2c_client;
u32 i2c_rc; u32 i2c_rc;
/* different settings for each bus */ /* different settings for each bus */
u8 i2c_period; u8 i2c_period;
u8 i2c_nostop; u8 i2c_nostop;
u8 i2c_reserve; u8 i2c_reserve;
}; };
struct cx231xx_i2c_xfer_data{ struct cx231xx_i2c_xfer_data {
u8 dev_addr; u8 dev_addr;
u8 direction; /* 1 - IN, 0 - OUT */ u8 direction; /* 1 - IN, 0 - OUT */
u8 saddr_len; /* sub address len */ u8 saddr_len; /* sub address len */
u16 saddr_dat; /* sub addr data */ u16 saddr_dat; /* sub addr data */
u8 buf_size; /* buffer size */ u8 buf_size; /* buffer size */
u8* p_buffer; /* pointer to the buffer */ u8 *p_buffer; /* pointer to the buffer */
}; };
typedef struct _VENDOR_REQUEST_IN typedef struct _VENDOR_REQUEST_IN {
{ u8 bRequest;
u8 bRequest; u16 wValue;
u16 wValue; u16 wIndex;
u16 wIndex; u16 wLength;
u16 wLength; u8 direction;
u8 direction; u8 bData;
u8 bData; u8 *pBuff;
u8 *pBuff;
} VENDOR_REQUEST_IN, *PVENDOR_REQUEST_IN; } VENDOR_REQUEST_IN, *PVENDOR_REQUEST_IN;
struct cx231xx_ctrl { struct cx231xx_ctrl {
struct v4l2_queryctrl v; struct v4l2_queryctrl v;
u32 off; u32 off;
u32 reg; u32 reg;
u32 mask; u32 mask;
u32 shift; u32 shift;
}; };
typedef enum{ typedef enum {
Raw_Video = 0, Raw_Video = 0,
Audio, Audio,
Vbi, /* VANC */ Vbi, /* VANC */
Sliced_cc, /* HANC */ Sliced_cc, /* HANC */
TS1_serial_mode, TS1_serial_mode,
TS2, TS2,
TS1_parallel_mode TS1_parallel_mode
}TRANSFER_TYPE; } TRANSFER_TYPE;
struct cx231xx_video_mode { struct cx231xx_video_mode {
/* Isoc control struct */ /* Isoc control struct */
struct cx231xx_dmaqueue vidq; struct cx231xx_dmaqueue vidq;
struct cx231xx_usb_isoc_ctl isoc_ctl; struct cx231xx_usb_isoc_ctl isoc_ctl;
spinlock_t slock; spinlock_t slock;
/* usb transfer */ /* usb transfer */
int alt; /* alternate */ int alt; /* alternate */
int max_pkt_size; /* max packet size of isoc transaction */ int max_pkt_size; /* max packet size of isoc transaction */
int num_alt; /* Number of alternative settings */ int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
u16 end_point_addr; u16 end_point_addr;
}; };
/* main device struct */ /* main device struct */
struct cx231xx { struct cx231xx {
/* generic device properties */ /* generic device properties */
char name[30]; /* name (including minor) of the device */ char name[30]; /* name (including minor) of the device */
int model; /* index in the device_data struct */ int model; /* index in the device_data struct */
int devno; /* marks the number of this device */ int devno; /* marks the number of this device */
struct cx231xx_board board; struct cx231xx_board board;
unsigned int stream_on:1; /* Locks streams */ unsigned int stream_on:1; /* Locks streams */
unsigned int vbi_stream_on:1; /* Locks streams for VBI */ unsigned int vbi_stream_on:1; /* Locks streams for VBI */
unsigned int has_audio_class:1; unsigned int has_audio_class:1;
unsigned int has_alsa_audio:1; unsigned int has_alsa_audio:1;
struct cx231xx_fmt *format; struct cx231xx_fmt *format;
struct cx231xx_IR *ir; struct cx231xx_IR *ir;
struct list_head devlist; struct list_head devlist;
int tuner_type; /* type of the tuner */ int tuner_type; /* type of the tuner */
int tuner_addr; /* tuner address */ int tuner_addr; /* tuner address */
/* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
struct cx231xx_i2c i2c_bus[3]; struct cx231xx_i2c i2c_bus[3];
unsigned int xc_fw_load_done:1; unsigned int xc_fw_load_done:1;
struct mutex gpio_i2c_lock; struct mutex gpio_i2c_lock;
/* video for linux */ /* video for linux */
int users; /* user count for exclusive use */ int users; /* user count for exclusive use */
struct video_device *vdev; /* video for linux device struct */ struct video_device *vdev; /* video for linux device struct */
v4l2_std_id norm; /* selected tv norm */ v4l2_std_id norm; /* selected tv norm */
int ctl_freq; /* selected frequency */ int ctl_freq; /* selected frequency */
unsigned int ctl_ainput; /* selected audio input */ unsigned int ctl_ainput; /* selected audio input */
int mute; int mute;
int volume; int volume;
/* frame properties */ /* frame properties */
int width; /* current frame width */ int width; /* current frame width */
int height; /* current frame height */ int height; /* current frame height */
unsigned hscale; /* horizontal scale factor (see datasheet) */ unsigned hscale; /* horizontal scale factor (see datasheet) */
unsigned vscale; /* vertical scale factor (see datasheet) */ unsigned vscale; /* vertical scale factor (see datasheet) */
int interlaced; /* 1=interlace fileds, 0=just top fileds */ int interlaced; /* 1=interlace fileds, 0=just top fileds */
struct cx231xx_audio adev; struct cx231xx_audio adev;
/* states */ /* states */
enum cx231xx_dev_state state; enum cx231xx_dev_state state;
struct work_struct request_module_wk; struct work_struct request_module_wk;
/* locks */ /* locks */
struct mutex lock; struct mutex lock;
struct mutex ctrl_urb_lock; /* protects urb_buf */ struct mutex ctrl_urb_lock; /* protects urb_buf */
struct list_head inqueue, outqueue; struct list_head inqueue, outqueue;
wait_queue_head_t open, wait_frame, wait_stream; wait_queue_head_t open, wait_frame, wait_stream;
struct video_device *vbi_dev; struct video_device *vbi_dev;
...@@ -500,54 +488,56 @@ struct cx231xx { ...@@ -500,54 +488,56 @@ struct cx231xx {
unsigned char eedata[256]; unsigned char eedata[256];
struct cx231xx_video_mode video_mode; struct cx231xx_video_mode video_mode;
struct cx231xx_video_mode vbi_mode; struct cx231xx_video_mode vbi_mode;
struct cx231xx_video_mode sliced_cc_mode; struct cx231xx_video_mode sliced_cc_mode;
struct cx231xx_video_mode ts1_mode; struct cx231xx_video_mode ts1_mode;
struct usb_device *udev; /* the usb device */
char urb_buf[URB_MAX_CTRL_SIZE];/* urb control msg buffer */
struct usb_device *udev; /* the usb device */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
/* helper funcs that call usb_control_msg */ /* helper funcs that call usb_control_msg */
int (*cx231xx_read_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg, int (*cx231xx_read_ctrl_reg) (struct cx231xx * dev, u8 req, u16 reg,
char *buf, int len);
int (*cx231xx_write_ctrl_reg)(struct cx231xx *dev, u8 req, u16 reg,
char *buf, int len); char *buf, int len);
int (*cx231xx_send_usb_command)(struct cx231xx_i2c *i2c_bus, int (*cx231xx_write_ctrl_reg) (struct cx231xx * dev, u8 req, u16 reg,
struct cx231xx_i2c_xfer_data *req_data); char *buf, int len);
int (*cx231xx_gpio_i2c_read)(struct cx231xx *dev, u8 dev_addr, u8 *buf ,u8 len); int (*cx231xx_send_usb_command) (struct cx231xx_i2c * i2c_bus,
int (*cx231xx_gpio_i2c_write)(struct cx231xx *dev, u8 dev_addr, u8 *buf ,u8 len); struct cx231xx_i2c_xfer_data *
req_data);
int (*cx231xx_set_analog_freq)(struct cx231xx *dev, u32 freq ) ; int (*cx231xx_gpio_i2c_read) (struct cx231xx * dev, u8 dev_addr,
int (*cx231xx_reset_analog_tuner)(struct cx231xx *dev) ; u8 * buf, u8 len);
int (*cx231xx_gpio_i2c_write) (struct cx231xx * dev, u8 dev_addr,
u8 * buf, u8 len);
int (*cx231xx_set_analog_freq) (struct cx231xx * dev, u32 freq);
int (*cx231xx_reset_analog_tuner) (struct cx231xx * dev);
enum cx231xx_mode mode; enum cx231xx_mode mode;
struct cx231xx_dvb *dvb; struct cx231xx_dvb *dvb;
/* Cx231xx supported PCB config's */ /* Cx231xx supported PCB config's */
struct pcb_config current_pcb_config; struct pcb_config current_pcb_config;
u8 current_scenario_idx; u8 current_scenario_idx;
u8 interface_count; u8 interface_count;
u8 max_iad_interface_count; u8 max_iad_interface_count;
/* GPIO related register direction and values */ /* GPIO related register direction and values */
u32 gpio_dir; u32 gpio_dir;
u32 gpio_val; u32 gpio_val;
/* Power Modes */ /* Power Modes */
int power_mode; int power_mode;
/* colibri parameters */ /* colibri parameters */
enum AFE_MODE colibri_mode; enum AFE_MODE colibri_mode;
u32 colibri_ref_count; u32 colibri_ref_count;
/* video related parameters */ /* video related parameters */
u32 video_input; u32 video_input;
u32 active_mode; u32 active_mode;
u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */ u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */
enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */ enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */
}; };
...@@ -555,29 +545,31 @@ struct cx231xx_ops { ...@@ -555,29 +545,31 @@ struct cx231xx_ops {
struct list_head next; struct list_head next;
char *name; char *name;
int id; int id;
int (*init)(struct cx231xx *); int (*init) (struct cx231xx *);
int (*fini)(struct cx231xx *); int (*fini) (struct cx231xx *);
}; };
/* call back functions in dvb module */ /* call back functions in dvb module */
int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq ) ; int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq);
int cx231xx_reset_analog_tuner(struct cx231xx *dev) ; int cx231xx_reset_analog_tuner(struct cx231xx *dev);
/* Provided by cx231xx-i2c.c */ /* Provided by cx231xx-i2c.c */
void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd, void *arg); void cx231xx_i2c_call_clients(struct cx231xx_i2c *bus, unsigned int cmd,
void *arg);
void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c); void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c);
int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_register(struct cx231xx_i2c *bus);
int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus);
/* Internal block control functions */ /* Internal block control functions */
int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr,
u16 saddr, u8 saddr_len, u32 *data, u8 data_len); u16 saddr, u8 saddr_len, u32 * data, u8 data_len);
int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr,
u16 saddr, u8 saddr_len, u32 data, u8 data_len); u16 saddr, u8 saddr_len, u32 data, u8 data_len);
int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size, u16 register_address, int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
u8 bit_start,u8 bit_end, u32 value); u16 register_address, u8 bit_start, u8 bit_end,
u32 value);
int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr, int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
u16 saddr, u32 mask, u32 value); u16 saddr, u32 mask, u32 value);
u32 cx231xx_set_field(u32 field_mask, u32 data); u32 cx231xx_set_field(u32 field_mask, u32 data);
/* Colibri related functions */ /* Colibri related functions */
...@@ -596,23 +588,26 @@ int cx231xx_flatiron_set_audio_input(struct cx231xx *dev, u8 audio_input); ...@@ -596,23 +588,26 @@ int cx231xx_flatiron_set_audio_input(struct cx231xx *dev, u8 audio_input);
/* DIF related functions */ /* DIF related functions */
int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode, int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
u32 function_mode, u32 standard); u32 function_mode, u32 standard);
int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard); int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard);
int cx231xx_tuner_pre_channel_change(struct cx231xx *dev); int cx231xx_tuner_pre_channel_change(struct cx231xx *dev);
int cx231xx_tuner_post_channel_change(struct cx231xx *dev); int cx231xx_tuner_post_channel_change(struct cx231xx *dev);
/* video parser functions */ /* video parser functions */
u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used); u8 cx231xx_find_next_SAV_EAV(u8 * p_buffer, u32 buffer_size,
u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf, u32 *p_bytes_used); u32 * p_bytes_used);
u8 cx231xx_find_boundary_SAV_EAV(u8 * p_buffer, u8 * partial_buf,
u32 * p_bytes_used);
int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u8 *p_buffer, u32 bytes_to_copy); u8 * p_buffer, u32 bytes_to_copy);
void cx231xx_reset_video_buffer(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q); void cx231xx_reset_video_buffer(struct cx231xx *dev,
u8 cx231xx_is_buffer_done(struct cx231xx *dev,struct cx231xx_dmaqueue *dma_q); struct cx231xx_dmaqueue *dma_q);
u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q);
u8 *p_line, u32 length, int field_number); u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u8 * p_line, u32 length, int field_number);
u8 sav_eav, u8 *p_buffer, u32 buffer_size); u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
void cx231xx_swab(u16 *from, u16 *to, u16 len); u8 sav_eav, u8 * p_buffer, u32 buffer_size);
void cx231xx_swab(u16 * from, u16 * to, u16 len);
/* Provided by cx231xx-core.c */ /* Provided by cx231xx-core.c */
...@@ -622,46 +617,49 @@ void cx231xx_release_buffers(struct cx231xx *dev); ...@@ -622,46 +617,49 @@ void cx231xx_release_buffers(struct cx231xx *dev);
/* read from control pipe */ /* read from control pipe */
int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
char *buf, int len); char *buf, int len);
/* write to control pipe */ /* write to control pipe */
int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
char *buf, int len); char *buf, int len);
int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode); int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode);
int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN *ven_req); int cx231xx_send_vendor_cmd(struct cx231xx *dev, VENDOR_REQUEST_IN * ven_req);
int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
struct cx231xx_i2c_xfer_data *req_data); struct cx231xx_i2c_xfer_data *req_data);
/* Gpio related functions */ /* Gpio related functions */
int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8* gpio_val, int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val,
u8 len, u8 request, u8 direction); u8 len, u8 request, u8 direction);
int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8* gpio_val); int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val);
int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8* gpio_val); int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val);
int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value); int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value);
int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number, int pin_value); int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number,
int pin_value);
int cx231xx_gpio_i2c_start(struct cx231xx *dev); int cx231xx_gpio_i2c_start(struct cx231xx *dev);
int cx231xx_gpio_i2c_end(struct cx231xx *dev); int cx231xx_gpio_i2c_end(struct cx231xx *dev);
int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data); int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data);
int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf); int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf);
int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev); int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev);
int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev); int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev);
int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev); int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev);
int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf ,u8 len); int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len);
int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf ,u8 len); int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len);
/* audio related functions */ /* audio related functions */
int cx231xx_set_audio_decoder_input(struct cx231xx *dev, enum AUDIO_INPUT audio_input); int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
enum AUDIO_INPUT audio_input);
int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type); int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
int cx231xx_resolution_set(struct cx231xx *dev); int cx231xx_resolution_set(struct cx231xx *dev);
int cx231xx_set_video_alternate(struct cx231xx *dev); int cx231xx_set_video_alternate(struct cx231xx *dev);
int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt); int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
int num_bufs, int max_pkt_size, int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct cx231xx *dev, struct urb *urb)); int (*isoc_copy) (struct cx231xx * dev,
struct urb * urb));
void cx231xx_uninit_isoc(struct cx231xx *dev); void cx231xx_uninit_isoc(struct cx231xx *dev);
int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode); int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode);
int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio); int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio);
...@@ -673,7 +671,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev); ...@@ -673,7 +671,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev);
void cx231xx_remove_from_devlist(struct cx231xx *dev); void cx231xx_remove_from_devlist(struct cx231xx *dev);
void cx231xx_add_into_devlist(struct cx231xx *dev); void cx231xx_add_into_devlist(struct cx231xx *dev);
struct cx231xx *cx231xx_get_device(int minor, struct cx231xx *cx231xx_get_device(int minor,
enum v4l2_buf_type *fh_type, int *has_radio); enum v4l2_buf_type *fh_type, int *has_radio);
void cx231xx_init_extension(struct cx231xx *dev); void cx231xx_init_extension(struct cx231xx *dev);
void cx231xx_close_extension(struct cx231xx *dev); void cx231xx_close_extension(struct cx231xx *dev);
...@@ -695,7 +693,8 @@ int cx231xx_power_suspend(struct cx231xx *dev); ...@@ -695,7 +693,8 @@ int cx231xx_power_suspend(struct cx231xx *dev);
/* chip specific control functions */ /* chip specific control functions */
int cx231xx_init_ctrl_pin_status(struct cx231xx *dev); int cx231xx_init_ctrl_pin_status(struct cx231xx *dev);
int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, u8 analog_or_digital); int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
u8 analog_or_digital);
int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex); int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex);
/* video audio decoder related functions */ /* video audio decoder related functions */
...@@ -705,8 +704,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input); ...@@ -705,8 +704,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev); int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
int cx231xx_set_audio_input(struct cx231xx *dev, u8 input); int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
void get_scale(struct cx231xx *dev, void get_scale(struct cx231xx *dev,
unsigned int width, unsigned int height, unsigned int width, unsigned int height,
unsigned int *hscale, unsigned int *vscale); unsigned int *hscale, unsigned int *vscale);
/* Provided by cx231xx-video.c */ /* Provided by cx231xx-video.c */
int cx231xx_register_extension(struct cx231xx_ops *dev); int cx231xx_register_extension(struct cx231xx_ops *dev);
...@@ -743,7 +742,6 @@ int cx231xx_ir_fini(struct cx231xx *dev); ...@@ -743,7 +742,6 @@ int cx231xx_ir_fini(struct cx231xx *dev);
printk(KERN_WARNING "%s: "fmt,\ printk(KERN_WARNING "%s: "fmt,\
dev->name , ##arg); } while (0) dev->name , ##arg); } while (0)
static inline unsigned int norm_maxw(struct cx231xx *dev) static inline unsigned int norm_maxw(struct cx231xx *dev)
{ {
if (dev->board.max_range_640_480) if (dev->board.max_range_640_480)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment