提交 64fbf444 编写于 作者: P Palash Bandyopadhyay 提交者: Mauro Carvalho Chehab

[media] cx231xx: Added support for Carraera, Shelby, RDx_253S and VIDEO_GRABBER

Added support for new cx231xx boards - Carraera, Shelby, RDx_253S and
VIDEO_GRABBER.

[mchehab@redhat.com: Fix a merge conflict with BKL removal patches]
Signed-off-by: NPalash Bandyopadhyay <palash.bandyopadhyay@conexant.com>
Signed-off-by: NDevin Heitmueller <dheitmueller@hauppauge.com>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 47b75ec1
cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \ cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \
cx231xx-avcore.o cx231xx-pcb-cfg.o cx231xx-vbi.o cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
cx231xx-alsa-objs := cx231xx-audio.o cx231xx-alsa-objs := cx231xx-audio.o
......
此差异已折叠。
...@@ -75,6 +75,30 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) ...@@ -75,6 +75,30 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
return 0; return 0;
} }
static int cx231xx_bulk_audio_deinit(struct cx231xx *dev)
{
int i;
dprintk("Stopping bulk\n");
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
if (dev->adev.urb[i]) {
if (!irqs_disabled())
usb_kill_urb(dev->adev.urb[i]);
else
usb_unlink_urb(dev->adev.urb[i]);
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
kfree(dev->adev.transfer_buffer[i]);
dev->adev.transfer_buffer[i] = NULL;
}
}
return 0;
}
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;
...@@ -158,14 +182,92 @@ static void cx231xx_audio_isocirq(struct urb *urb) ...@@ -158,14 +182,92 @@ static void cx231xx_audio_isocirq(struct urb *urb)
return; return;
} }
static void cx231xx_audio_bulkirq(struct urb *urb)
{
struct cx231xx *dev = urb->context;
unsigned int oldptr;
int period_elapsed = 0;
int status;
unsigned char *cp;
unsigned int stride;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
switch (urb->status) {
case 0: /* success */
case -ETIMEDOUT: /* NAK */
break;
case -ECONNRESET: /* kill */
case -ENOENT:
case -ESHUTDOWN:
return;
default: /* error */
dprintk("urb completition error %d.\n", urb->status);
break;
}
if (dev->adev.capture_pcm_substream) {
substream = dev->adev.capture_pcm_substream;
runtime = substream->runtime;
stride = runtime->frame_bits >> 3;
if (1) {
int length = urb->actual_length /
stride;
cp = (unsigned char *)urb->transfer_buffer;
oldptr = dev->adev.hwptr_done_capture;
if (oldptr + length >= runtime->buffer_size) {
unsigned int cnt;
cnt = runtime->buffer_size - oldptr;
memcpy(runtime->dma_area + oldptr * stride, cp,
cnt * stride);
memcpy(runtime->dma_area, cp + cnt * stride,
length * stride - cnt * stride);
} else {
memcpy(runtime->dma_area + oldptr * stride, cp,
length * stride);
}
snd_pcm_stream_lock(substream);
dev->adev.hwptr_done_capture += length;
if (dev->adev.hwptr_done_capture >=
runtime->buffer_size)
dev->adev.hwptr_done_capture -=
runtime->buffer_size;
dev->adev.capture_transfer_done += length;
if (dev->adev.capture_transfer_done >=
runtime->period_size) {
dev->adev.capture_transfer_done -=
runtime->period_size;
period_elapsed = 1;
}
snd_pcm_stream_unlock(substream);
}
if (period_elapsed)
snd_pcm_period_elapsed(substream);
}
urb->status = 0;
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status < 0) {
cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
status);
}
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 ISO AUDIO transfers\n", __func__);
sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; sb_size = CX231XX_ISO_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;
...@@ -176,7 +278,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -176,7 +278,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
return -ENOMEM; return -ENOMEM;
memset(dev->adev.transfer_buffer[i], 0x80, sb_size); memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC);
if (!urb) { if (!urb) {
cx231xx_errdev("usb_alloc_urb failed!\n"); cx231xx_errdev("usb_alloc_urb failed!\n");
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
...@@ -194,10 +296,10 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -194,10 +296,10 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->transfer_buffer = dev->adev.transfer_buffer[i];
urb->interval = 1; urb->interval = 1;
urb->complete = cx231xx_audio_isocirq; urb->complete = cx231xx_audio_isocirq;
urb->number_of_packets = CX231XX_NUM_AUDIO_PACKETS; urb->number_of_packets = CX231XX_ISO_NUM_AUDIO_PACKETS;
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_ISO_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 = dev->adev.max_pkt_size; urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
...@@ -216,6 +318,59 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -216,6 +318,59 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
return errCode; return errCode;
} }
static int cx231xx_init_audio_bulk(struct cx231xx *dev)
{
int i, errCode;
int sb_size;
cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__);
sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
struct urb *urb;
int j;
dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
if (!dev->adev.transfer_buffer[i])
return -ENOMEM;
memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
if (!urb) {
cx231xx_errdev("usb_alloc_urb failed!\n");
for (j = 0; j < i; j++) {
usb_free_urb(dev->adev.urb[j]);
kfree(dev->adev.transfer_buffer[j]);
}
return -ENOMEM;
}
urb->dev = dev->udev;
urb->context = dev;
urb->pipe = usb_rcvbulkpipe(dev->udev,
dev->adev.end_point_addr);
urb->transfer_flags = 0;
urb->transfer_buffer = dev->adev.transfer_buffer[i];
urb->complete = cx231xx_audio_bulkirq;
urb->transfer_buffer_length = sb_size;
dev->adev.urb[i] = urb;
}
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
if (errCode < 0) {
cx231xx_bulk_audio_deinit(dev);
return errCode;
}
}
return errCode;
}
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) ?
...@@ -225,7 +380,12 @@ static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg) ...@@ -225,7 +380,12 @@ static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg)
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); if (is_fw_load(dev) == 0)
cx25840_call(dev, core, load_fw);
if (dev->USE_ISO)
cx231xx_init_audio_isoc(dev);
else
cx231xx_init_audio_bulk(dev);
} else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
dev->adev.capture_stream = STREAM_OFF; dev->adev.capture_stream = STREAM_OFF;
cx231xx_isoc_audio_deinit(dev); cx231xx_isoc_audio_deinit(dev);
...@@ -300,7 +460,10 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ...@@ -300,7 +460,10 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
/* set alternate setting for audio interface */ /* set alternate setting for audio interface */
/* 1 - 48000 samples per sec */ /* 1 - 48000 samples per sec */
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1); if (dev->USE_ISO)
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1);
else
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
if (ret < 0) { if (ret < 0) {
cx231xx_errdev("failed to set alternate setting !\n"); cx231xx_errdev("failed to set alternate setting !\n");
...@@ -330,6 +493,9 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) ...@@ -330,6 +493,9 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
dprintk("closing device\n"); dprintk("closing device\n");
/* inform hardware to start streaming */
ret = cx231xx_capture_start(dev, 0, Audio);
/* set alternate setting for audio interface */ /* set alternate setting for audio interface */
/* 1 - 48000 samples per sec */ /* 1 - 48000 samples per sec */
ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
...@@ -339,9 +505,6 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) ...@@ -339,9 +505,6 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
return ret; return ret;
} }
/* inform hardware to start streaming */
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--;
...@@ -391,6 +554,11 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) ...@@ -391,6 +554,11 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
static int snd_cx231xx_prepare(struct snd_pcm_substream *substream) static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
{ {
struct cx231xx *dev = snd_pcm_substream_chip(substream);
dev->adev.hwptr_done_capture = 0;
dev->adev.capture_transfer_done = 0;
return 0; return 0;
} }
...@@ -495,6 +663,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) ...@@ -495,6 +663,7 @@ static int cx231xx_audio_init(struct cx231xx *dev)
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");
snd_card_set_dev(card, &dev->udev->dev);
strcpy(card->driver, "Cx231xx-Audio"); strcpy(card->driver, "Cx231xx-Audio");
strcpy(card->shortname, "Cx231xx Audio"); strcpy(card->shortname, "Cx231xx Audio");
strcpy(card->longname, "Conexant cx231xx Audio"); strcpy(card->longname, "Conexant cx231xx Audio");
......
...@@ -41,6 +41,10 @@ static int tuner = -1; ...@@ -41,6 +41,10 @@ static int tuner = -1;
module_param(tuner, int, 0444); module_param(tuner, int, 0444);
MODULE_PARM_DESC(tuner, "tuner type"); MODULE_PARM_DESC(tuner, "tuner type");
static int transfer_mode = 1;
module_param(transfer_mode, int, 0444);
MODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)");
static unsigned int disable_ir; static unsigned int disable_ir;
module_param(disable_ir, int, 0444); module_param(disable_ir, int, 0444);
MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
...@@ -86,8 +90,8 @@ struct cx231xx_board cx231xx_boards[] = { ...@@ -86,8 +90,8 @@ struct cx231xx_board cx231xx_boards[] = {
} }
}, },
}, },
[CX231XX_BOARD_CNXT_RDE_250] = { [CX231XX_BOARD_CNXT_CARRAERA] = {
.name = "Conexant Hybrid TV - RDE250", .name = "Conexant Hybrid TV - CARRAERA",
.tuner_type = TUNER_XC5000, .tuner_type = TUNER_XC5000,
.tuner_addr = 0x61, .tuner_addr = 0x61,
.tuner_gpio = RDE250_XCV_TUNER, .tuner_gpio = RDE250_XCV_TUNER,
...@@ -125,9 +129,8 @@ struct cx231xx_board cx231xx_boards[] = { ...@@ -125,9 +129,8 @@ struct cx231xx_board cx231xx_boards[] = {
} }
}, },
}, },
[CX231XX_BOARD_CNXT_SHELBY] = {
[CX231XX_BOARD_CNXT_RDU_250] = { .name = "Conexant Hybrid TV - SHELBY",
.name = "Conexant Hybrid TV - RDU250",
.tuner_type = TUNER_XC5000, .tuner_type = TUNER_XC5000,
.tuner_addr = 0x61, .tuner_addr = 0x61,
.tuner_gpio = RDE250_XCV_TUNER, .tuner_gpio = RDE250_XCV_TUNER,
...@@ -165,6 +168,183 @@ struct cx231xx_board cx231xx_boards[] = { ...@@ -165,6 +168,183 @@ struct cx231xx_board cx231xx_boards[] = {
} }
}, },
}, },
[CX231XX_BOARD_CNXT_RDE_253S] = {
.name = "Conexant Hybrid TV - RDE253S",
.tuner_type = TUNER_NXP_TDA18271,
.tuner_addr = 0x60,
.tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x1c,
.gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1,
.demod_i2c_master = 2,
.has_dvb = 1,
.demod_addr = 0x02,
.norm = V4L2_STD_PAL,
.input = {{
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}
},
},
[CX231XX_BOARD_CNXT_RDU_253S] = {
.name = "Conexant Hybrid TV - RDU253S",
.tuner_type = TUNER_NXP_TDA18271,
.tuner_addr = 0x60,
.tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x1c,
.gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1,
.demod_i2c_master = 2,
.has_dvb = 1,
.demod_addr = 0x02,
.norm = V4L2_STD_PAL,
.input = {{
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}
},
},
[CX231XX_BOARD_CNXT_VIDEO_GRABBER] = {
.name = "Conexant VIDEO GRABBER",
.tuner_type = TUNER_NXP_TDA18271,
.tuner_addr = 0x60,
.tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x1c,
.gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1,
.demod_i2c_master = 2,
.has_dvb = 0,
.demod_addr = 0x02,
.norm = V4L2_STD_PAL,
.input = {{
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
.gpio = NULL,
}, {
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
.gpio = NULL,
}
},
},
[CX231XX_BOARD_CNXT_RDE_250] = {
.name = "Conexant Hybrid TV - rde 250",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
.tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x0c,
.gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1,
.demod_i2c_master = 2,
.has_dvb = 1,
.demod_addr = 0x02,
.norm = V4L2_STD_PAL,
.input = {{
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_VIDEO,
.gpio = NULL,
}
},
},
[CX231XX_BOARD_CNXT_RDU_250] = {
.name = "Conexant Hybrid TV - RDU 250",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
.tuner_gpio = RDE250_XCV_TUNER,
.tuner_sif_gpio = 0x05,
.tuner_scl_gpio = 0x1a,
.tuner_sda_gpio = 0x1b,
.decoder = CX231XX_AVDECODER,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
.agc_analog_digital_select_gpio = 0x0c,
.gpio_pin_status_mask = 0x4001000,
.tuner_i2c_master = 1,
.demod_i2c_master = 2,
.has_dvb = 1,
.demod_addr = 0x32,
.norm = V4L2_STD_NTSC,
.input = {{
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_VIDEO,
.gpio = NULL,
}
},
},
}; };
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
...@@ -173,8 +353,18 @@ struct usb_device_id cx231xx_id_table[] = { ...@@ -173,8 +353,18 @@ struct usb_device_id cx231xx_id_table[] = {
{USB_DEVICE(0x0572, 0x5A3C), {USB_DEVICE(0x0572, 0x5A3C),
.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_CARRAERA},
{USB_DEVICE(0x0572, 0x58A1), {USB_DEVICE(0x0572, 0x58A1),
.driver_info = CX231XX_BOARD_CNXT_SHELBY},
{USB_DEVICE(0x0572, 0x58A4),
.driver_info = CX231XX_BOARD_CNXT_RDE_253S},
{USB_DEVICE(0x0572, 0x58A5),
.driver_info = CX231XX_BOARD_CNXT_RDU_253S},
{USB_DEVICE(0x0572, 0x58A6),
.driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER},
{USB_DEVICE(0x0572, 0x589E),
.driver_info = CX231XX_BOARD_CNXT_RDE_250},
{USB_DEVICE(0x0572, 0x58A0),
.driver_info = CX231XX_BOARD_CNXT_RDU_250}, .driver_info = CX231XX_BOARD_CNXT_RDU_250},
{USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
.driver_info = CX231XX_BOARD_UNKNOWN}, .driver_info = CX231XX_BOARD_UNKNOWN},
...@@ -212,6 +402,23 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) ...@@ -212,6 +402,23 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
} }
EXPORT_SYMBOL_GPL(cx231xx_tuner_callback); EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
void cx231xx_reset_out(struct cx231xx *dev)
{
cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
msleep(200);
cx231xx_set_gpio_value(dev, CX23417_RESET, 0);
msleep(200);
cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
}
void cx231xx_enable_OSC(struct cx231xx *dev)
{
cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1);
}
void cx231xx_sleep_s5h1432(struct cx231xx *dev)
{
cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0);
}
static inline void cx231xx_set_model(struct cx231xx *dev) static inline void cx231xx_set_model(struct cx231xx *dev)
{ {
memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board)); memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board));
...@@ -235,9 +442,6 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) ...@@ -235,9 +442,6 @@ void cx231xx_pre_card_setup(struct cx231xx *dev)
cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
/* request some modules if any required */ /* request some modules if any required */
/* reset the Tuner */
cx231xx_gpio_set(dev, dev->board.tuner_gpio);
} }
/* set the mode to Analog mode initially */ /* set the mode to Analog mode initially */
...@@ -297,10 +501,20 @@ void cx231xx_register_i2c_ir(struct cx231xx *dev) ...@@ -297,10 +501,20 @@ void cx231xx_register_i2c_ir(struct cx231xx *dev)
/* detect & configure */ /* detect & configure */
switch (dev->model) { switch (dev->model) {
case CX231XX_BOARD_CNXT_CARRAERA:
break;
case CX231XX_BOARD_CNXT_RDE_250: case CX231XX_BOARD_CNXT_RDE_250:
break; break;
case CX231XX_BOARD_CNXT_SHELBY:
break;
case CX231XX_BOARD_CNXT_RDU_250: case CX231XX_BOARD_CNXT_RDU_250:
break; break;
case CX231XX_BOARD_CNXT_RDE_253S:
break;
case CX231XX_BOARD_CNXT_RDU_253S:
break;
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
break;
default: default:
break; break;
} }
...@@ -326,14 +540,38 @@ void cx231xx_card_setup(struct cx231xx *dev) ...@@ -326,14 +540,38 @@ void cx231xx_card_setup(struct cx231xx *dev)
} }
if (dev->board.tuner_type != TUNER_ABSENT) { switch (dev->model) {
dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, case CX231XX_BOARD_CNXT_CARRAERA:
&dev->i2c_bus[1].i2c_adap, case CX231XX_BOARD_CNXT_RDE_250:
"tuner", "tuner", 0xc2 >> 1, NULL); case CX231XX_BOARD_CNXT_SHELBY:
if (dev->sd_tuner == NULL) case CX231XX_BOARD_CNXT_RDU_250:
cx231xx_info("tuner subdev registration failure\n"); if (dev->board.tuner_type != TUNER_ABSENT) {
dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
cx231xx_config_tuner(dev); &dev->i2c_bus[1].i2c_adap,
"tuner", "tuner", 0xc2 >> 1, NULL);
if (dev->sd_tuner == NULL)
cx231xx_info(
"tuner subdev registration failure\n");
cx231xx_config_tuner(dev);
}
break;
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
if (dev->board.tuner_type != TUNER_ABSENT) {
dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[1].i2c_adap,
"tuner", "tuner", 0xc0 >> 1, NULL);
if (dev->sd_tuner == NULL)
cx231xx_info(
"tuner subdev registration failure\n");
cx231xx_config_tuner(dev);
}
break;
default:
break;
} }
cx231xx_config_tuner(dev); cx231xx_config_tuner(dev);
...@@ -409,6 +647,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -409,6 +647,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *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);
mutex_init(&dev->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);
...@@ -427,6 +666,12 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -427,6 +666,12 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
/* 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);
/*To workaround error number=-71 on EP0 for VideoGrabber,
need set alt here.*/
if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
}
/* Cx231xx pre card setup */ /* Cx231xx pre card setup */
cx231xx_pre_card_setup(dev); cx231xx_pre_card_setup(dev);
...@@ -442,6 +687,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -442,6 +687,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
/* register i2c bus */ /* register i2c bus */
errCode = cx231xx_dev_init(dev); errCode = cx231xx_dev_init(dev);
if (errCode < 0) { if (errCode < 0) {
cx231xx_dev_uninit(dev);
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;
...@@ -480,9 +726,17 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev, ...@@ -480,9 +726,17 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
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);
printk(KERN_INFO "attach 417 %d\n", dev->model);
if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
if (cx231xx_417_register(dev) < 0) {
printk(KERN_ERR
"%s() Failed to register 417 on VID_B\n",
__func__);
}
}
retval = cx231xx_register_analog_devices(dev); retval = cx231xx_register_analog_devices(dev);
if (retval < 0) { if (retval < 0) {
cx231xx_release_resources(dev); cx231xx_release_resources(dev);
...@@ -552,8 +806,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -552,8 +806,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_devused |= 1 << nr; cx231xx_devused |= 1 << nr;
if (nr >= CX231XX_MAXBOARDS) { if (nr >= CX231XX_MAXBOARDS) {
cx231xx_err(DRIVER_NAME ": Supports only %i cx231xx boards.\n", cx231xx_err(DRIVER_NAME
CX231XX_MAXBOARDS); ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS);
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
return -ENOMEM; return -ENOMEM;
} }
...@@ -578,6 +832,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -578,6 +832,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
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;
atomic_set(&dev->devlist_count, 0);
/* 0 - vbi ; 1 -sliced cc mode */ /* 0 - vbi ; 1 -sliced cc mode */
dev->vbi_or_sliced_cc_mode = 0; dev->vbi_or_sliced_cc_mode = 0;
...@@ -591,6 +846,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -591,6 +846,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
/* store the current interface */ /* store the current interface */
lif = interface; lif = interface;
/*mode_tv: digital=1 or analog=0*/
dev->mode_tv = 0;
dev->USE_ISO = transfer_mode;
switch (udev->speed) { switch (udev->speed) {
case USB_SPEED_LOW: case USB_SPEED_LOW:
speed = "1.5"; speed = "1.5";
...@@ -645,7 +905,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -645,7 +905,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
* set skip interface, for all interfaces but * set skip interface, for all interfaces but
* interface 1 and the last one * interface 1 and the last one
*/ */
if ((ifnum != 1) && ((dev->interface_count - 1) if ((ifnum != 1) && ((ifnum)
!= dev->max_iad_interface_count)) != dev->max_iad_interface_count))
skip_interface = 1; skip_interface = 1;
...@@ -667,7 +927,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -667,7 +927,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
/* 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);
if ((dev->interface_count - 1) != dev->max_iad_interface_count) if ((ifnum) != dev->max_iad_interface_count)
return 0; return 0;
/* /*
...@@ -680,15 +940,18 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -680,15 +940,18 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_errdev("v4l2_device_register failed\n"); cx231xx_errdev("v4l2_device_register failed\n");
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
kfree(dev); kfree(dev);
dev = NULL;
return -EIO; return -EIO;
} }
/* 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);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
dev = NULL;
usb_set_intfdata(lif, NULL);
return retval; return retval;
} }
...@@ -711,6 +974,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -711,6 +974,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
dev = NULL;
return -ENOMEM; return -ENOMEM;
} }
...@@ -744,6 +1008,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -744,6 +1008,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
dev = NULL;
return -ENOMEM; return -ENOMEM;
} }
...@@ -778,6 +1043,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -778,6 +1043,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
dev = NULL;
return -ENOMEM; return -ENOMEM;
} }
...@@ -813,6 +1079,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -813,6 +1079,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_devused &= ~(1 << nr); cx231xx_devused &= ~(1 << nr);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
dev = NULL;
return -ENOMEM; return -ENOMEM;
} }
...@@ -827,6 +1094,15 @@ static int cx231xx_usb_probe(struct usb_interface *interface, ...@@ -827,6 +1094,15 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
} }
} }
if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
cx231xx_enable_OSC(dev);
cx231xx_reset_out(dev);
cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
}
if (dev->model == CX231XX_BOARD_CNXT_RDE_253S)
cx231xx_sleep_s5h1432(dev);
/* load other modules required */ /* load other modules required */
request_modules(dev); request_modules(dev);
...@@ -867,7 +1143,10 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -867,7 +1143,10 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
video_device_node_name(dev->vdev)); video_device_node_name(dev->vdev));
dev->state |= DEV_MISCONFIGURED; dev->state |= DEV_MISCONFIGURED;
cx231xx_uninit_isoc(dev); if (dev->USE_ISO)
cx231xx_uninit_isoc(dev);
else
cx231xx_uninit_bulk(dev);
dev->state |= DEV_DISCONNECTED; dev->state |= DEV_DISCONNECTED;
wake_up_interruptible(&dev->wait_frame); wake_up_interruptible(&dev->wait_frame);
wake_up_interruptible(&dev->wait_stream); wake_up_interruptible(&dev->wait_stream);
...@@ -886,6 +1165,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -886,6 +1165,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
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);
dev = NULL;
} }
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define CIR_CAR_REG 0x38 #define CIR_CAR_REG 0x38
#define CIR_OT_CFG1 0x40 #define CIR_OT_CFG1 0x40
#define CIR_OT_CFG2 0x44 #define CIR_OT_CFG2 0x44
#define GBULK_BIT_EN 0x68
#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 */
......
此差异已折叠。
...@@ -359,7 +359,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -359,7 +359,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
if (num <= 0) if (num <= 0)
return 0; return 0;
mutex_lock(&dev->i2c_lock);
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
addr = msgs[i].addr >> 1; addr = msgs[i].addr >> 1;
...@@ -372,6 +372,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -372,6 +372,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
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");
mutex_lock(&dev->i2c_lock);
return rc; return rc;
} }
...@@ -384,7 +385,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -384,7 +385,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
} 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].addr == msgs[i + 1].addr
&& (msgs[i].len <= 2) && (bus->nr < 2)) { && (msgs[i].len <= 2) && (bus->nr < 3)) {
/* read bytes */ /* read bytes */
rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
&msgs[i], &msgs[i],
...@@ -407,10 +408,11 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -407,10 +408,11 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
if (i2c_debug >= 2) if (i2c_debug >= 2)
printk("\n"); printk("\n");
} }
mutex_unlock(&dev->i2c_lock);
return num; return num;
err: err:
dprintk2(2, " ERROR: %i\n", rc); dprintk2(2, " ERROR: %i\n", rc);
mutex_unlock(&dev->i2c_lock);
return rc; return rc;
} }
......
...@@ -61,6 +61,7 @@ struct cx231xx_ir_poll_result { ...@@ -61,6 +61,7 @@ struct cx231xx_ir_poll_result {
struct cx231xx_IR { struct cx231xx_IR {
struct cx231xx *dev; struct cx231xx *dev;
struct input_dev *input; struct input_dev *input;
struct ir_input_state ir;
char name[32]; char name[32];
char phys[32]; char phys[32];
...@@ -68,7 +69,9 @@ struct cx231xx_IR { ...@@ -68,7 +69,9 @@ struct cx231xx_IR {
int polling; int polling;
struct work_struct work; struct work_struct work;
struct timer_list timer; struct timer_list timer;
unsigned int last_toggle:1;
unsigned int last_readcount; unsigned int last_readcount;
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 *);
}; };
...@@ -80,6 +83,7 @@ struct cx231xx_IR { ...@@ -80,6 +83,7 @@ struct cx231xx_IR {
static void cx231xx_ir_handle_key(struct cx231xx_IR *ir) static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
{ {
int result; int result;
int do_sendkey = 0;
struct cx231xx_ir_poll_result poll_result; struct cx231xx_ir_poll_result poll_result;
/* read the registers containing the IR status */ /* read the registers containing the IR status */
...@@ -93,23 +97,44 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir) ...@@ -93,23 +97,44 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
poll_result.toggle_bit, poll_result.read_count, poll_result.toggle_bit, poll_result.read_count,
ir->last_readcount, poll_result.rc_data[0]); ir->last_readcount, poll_result.rc_data[0]);
if (poll_result.read_count > 0 && if (ir->dev->chip_id == CHIP_ID_EM2874) {
poll_result.read_count != ir->last_readcount)
ir_keydown(ir->input,
poll_result.rc_data[0],
poll_result.toggle_bit);
if (ir->dev->chip_id == CHIP_ID_EM2874)
/* The em2874 clears the readcount field every time the /* The em2874 clears the readcount field every time the
register is read. The em2860/2880 datasheet says that it register is read. The em2860/2880 datasheet says that it
is supposed to clear the readcount, but it doesn't. So with is supposed to clear the readcount, but it doesn't. So with
the em2874, we are looking for a non-zero read count as the em2874, we are looking for a non-zero read count as
opposed to a readcount that is incrementing */ opposed to a readcount that is incrementing */
ir->last_readcount = 0; ir->last_readcount = 0;
else }
ir->last_readcount = poll_result.read_count;
if (poll_result.read_count == 0) {
/* The button has not been pressed since the last read */
} else if (ir->last_toggle != poll_result.toggle_bit) {
/* A button has been pressed */
dprintk("button has been pressed\n");
ir->last_toggle = poll_result.toggle_bit;
ir->repeat_interval = 0;
do_sendkey = 1;
} else if (poll_result.toggle_bit == ir->last_toggle &&
poll_result.read_count > 0 &&
poll_result.read_count != ir->last_readcount) {
/* The button is still being held down */
dprintk("button being held down\n");
/* Debouncer for first keypress */
if (ir->repeat_interval++ > 9) {
/* Start repeating after 1 second */
do_sendkey = 1;
}
}
if (do_sendkey) {
dprintk("sending keypress\n");
ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
ir_input_nokey(ir->input, &ir->ir);
} }
ir->last_readcount = poll_result.read_count;
return;
} }
static void ir_timer(unsigned long data) static void ir_timer(unsigned long data)
...@@ -175,6 +200,10 @@ int cx231xx_ir_init(struct cx231xx *dev) ...@@ -175,6 +200,10 @@ int cx231xx_ir_init(struct cx231xx *dev)
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));
err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
if (err < 0)
goto err_out_free;
input_dev->name = ir->name; input_dev->name = ir->name;
input_dev->phys = ir->phys; input_dev->phys = ir->phys;
input_dev->id.bustype = BUS_USB; input_dev->id.bustype = BUS_USB;
...@@ -190,7 +219,7 @@ int cx231xx_ir_init(struct cx231xx *dev) ...@@ -190,7 +219,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
cx231xx_ir_start(ir); cx231xx_ir_start(ir);
/* all done */ /* all done */
err = __ir_input_register(ir->input, dev->board.ir_codes, err = ir_input_register(ir->input, dev->board.ir_codes,
NULL, MODULE_NAME); NULL, MODULE_NAME);
if (err) if (err)
goto err_out_stop; goto err_out_stop;
......
...@@ -41,7 +41,7 @@ extern struct videobuf_queue_ops cx231xx_vbi_qops; ...@@ -41,7 +41,7 @@ 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, int (*bulk_copy) (struct cx231xx *dev,
struct urb *urb)); struct urb *urb));
void cx231xx_uninit_vbi_isoc(struct cx231xx *dev); void cx231xx_uninit_vbi_isoc(struct cx231xx *dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册