diff options
author | Palash Bandyopadhyay <palash.bandyopadhyay@conexant.com> | 2010-07-06 17:12:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:17:10 -0400 |
commit | 64fbf44455260684fa5bfdd3121af3d0ef0b48dd (patch) | |
tree | 3e823c84d187b8de0731cd0b703b341abd92350e /drivers/media/video/cx231xx/cx231xx-dvb.c | |
parent | 47b75ec14653f12f9fd6fd76bfd5891ba35e1e79 (diff) |
[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: Palash Bandyopadhyay <palash.bandyopadhyay@conexant.com>
Signed-off-by: Devin Heitmueller <dheitmueller@hauppauge.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx231xx/cx231xx-dvb.c')
-rw-r--r-- | drivers/media/video/cx231xx/cx231xx-dvb.c | 185 |
1 files changed, 165 insertions, 20 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c index 4ea3776b39fb..130794b971ce 100644 --- a/drivers/media/video/cx231xx/cx231xx-dvb.c +++ b/drivers/media/video/cx231xx/cx231xx-dvb.c | |||
@@ -29,6 +29,9 @@ | |||
29 | 29 | ||
30 | #include "xc5000.h" | 30 | #include "xc5000.h" |
31 | #include "dvb_dummy_fe.h" | 31 | #include "dvb_dummy_fe.h" |
32 | #include "s5h1432.h" | ||
33 | #include "tda18271.h" | ||
34 | #include "s5h1411.h" | ||
32 | 35 | ||
33 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); | 36 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); |
34 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); | 37 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); |
@@ -65,6 +68,48 @@ struct cx231xx_dvb { | |||
65 | struct dvb_net net; | 68 | struct dvb_net net; |
66 | }; | 69 | }; |
67 | 70 | ||
71 | static struct s5h1432_config dvico_s5h1432_config = { | ||
72 | .output_mode = S5H1432_SERIAL_OUTPUT, | ||
73 | .gpio = S5H1432_GPIO_ON, | ||
74 | .qam_if = S5H1432_IF_4000, | ||
75 | .vsb_if = S5H1432_IF_4000, | ||
76 | .inversion = S5H1432_INVERSION_OFF, | ||
77 | .status_mode = S5H1432_DEMODLOCKING, | ||
78 | .mpeg_timing = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
79 | }; | ||
80 | |||
81 | static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { | ||
82 | .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4, | ||
83 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
84 | .dvbt_7 = { .if_freq = 4000, .agc_mode = 3, .std = 5, | ||
85 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
86 | .dvbt_8 = { .if_freq = 4000, .agc_mode = 3, .std = 6, | ||
87 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
88 | }; | ||
89 | |||
90 | static struct tda18271_config cnxt_rde253s_tunerconfig = { | ||
91 | .std_map = &cnxt_rde253s_tda18271_std_map, | ||
92 | .gate = TDA18271_GATE_ANALOG, | ||
93 | }; | ||
94 | |||
95 | static struct s5h1411_config tda18271_s5h1411_config = { | ||
96 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
97 | .gpio = S5H1411_GPIO_OFF, | ||
98 | .vsb_if = S5H1411_IF_3250, | ||
99 | .qam_if = S5H1411_IF_4000, | ||
100 | .inversion = S5H1411_INVERSION_ON, | ||
101 | .status_mode = S5H1411_DEMODLOCKING, | ||
102 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
103 | }; | ||
104 | static struct s5h1411_config xc5000_s5h1411_config = { | ||
105 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
106 | .gpio = S5H1411_GPIO_OFF, | ||
107 | .vsb_if = S5H1411_IF_3250, | ||
108 | .qam_if = S5H1411_IF_3250, | ||
109 | .inversion = S5H1411_INVERSION_OFF, | ||
110 | .status_mode = S5H1411_DEMODLOCKING, | ||
111 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
112 | }; | ||
68 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) | 113 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) |
69 | { | 114 | { |
70 | char *errmsg = "Unknown"; | 115 | char *errmsg = "Unknown"; |
@@ -128,34 +173,81 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb) | |||
128 | continue; | 173 | continue; |
129 | } | 174 | } |
130 | 175 | ||
131 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + | 176 | dvb_dmx_swfilter(&dev->dvb->demux, |
132 | urb->iso_frame_desc[i].offset, | 177 | urb->transfer_buffer + |
133 | urb->iso_frame_desc[i].actual_length); | 178 | urb->iso_frame_desc[i].offset, |
179 | urb->iso_frame_desc[i].actual_length); | ||
134 | } | 180 | } |
135 | 181 | ||
136 | return 0; | 182 | return 0; |
137 | } | 183 | } |
138 | 184 | ||
185 | static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | if (!dev) | ||
190 | return 0; | ||
191 | |||
192 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
193 | return 0; | ||
194 | |||
195 | if (urb->status < 0) { | ||
196 | print_err_status(dev, -1, urb->status); | ||
197 | if (urb->status == -ENOENT) | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* Feed the transport payload into the kernel demux */ | ||
202 | dvb_dmx_swfilter(&dev->dvb->demux, | ||
203 | urb->transfer_buffer, urb->actual_length); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
139 | static int start_streaming(struct cx231xx_dvb *dvb) | 208 | static int start_streaming(struct cx231xx_dvb *dvb) |
140 | { | 209 | { |
141 | int rc; | 210 | int rc; |
142 | struct cx231xx *dev = dvb->adapter.priv; | 211 | struct cx231xx *dev = dvb->adapter.priv; |
143 | 212 | ||
144 | usb_set_interface(dev->udev, 0, 1); | 213 | if (dev->USE_ISO) { |
145 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | 214 | cx231xx_info("DVB transfer mode is ISO.\n"); |
146 | if (rc < 0) | 215 | mutex_lock(&dev->i2c_lock); |
147 | return rc; | 216 | cx231xx_enable_i2c_for_tuner(dev, I2C_1); |
217 | cx231xx_set_alt_setting(dev, INDEX_TS1, 4); | ||
218 | cx231xx_enable_i2c_for_tuner(dev, I2C_3); | ||
219 | mutex_unlock(&dev->i2c_lock); | ||
220 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
221 | if (rc < 0) | ||
222 | return rc; | ||
223 | dev->mode_tv = 1; | ||
224 | return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, | ||
225 | CX231XX_DVB_NUM_BUFS, | ||
226 | dev->ts1_mode.max_pkt_size, | ||
227 | dvb_isoc_copy); | ||
228 | } else { | ||
229 | cx231xx_info("DVB transfer mode is BULK.\n"); | ||
230 | cx231xx_set_alt_setting(dev, INDEX_TS1, 0); | ||
231 | rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | ||
232 | if (rc < 0) | ||
233 | return rc; | ||
234 | dev->mode_tv = 1; | ||
235 | return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS, | ||
236 | CX231XX_DVB_NUM_BUFS, | ||
237 | dev->ts1_mode.max_pkt_size, | ||
238 | dvb_bulk_copy); | ||
239 | } | ||
148 | 240 | ||
149 | return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, | ||
150 | CX231XX_DVB_NUM_BUFS, | ||
151 | CX231XX_DVB_MAX_PACKETSIZE, dvb_isoc_copy); | ||
152 | } | 241 | } |
153 | 242 | ||
154 | static int stop_streaming(struct cx231xx_dvb *dvb) | 243 | static int stop_streaming(struct cx231xx_dvb *dvb) |
155 | { | 244 | { |
156 | struct cx231xx *dev = dvb->adapter.priv; | 245 | struct cx231xx *dev = dvb->adapter.priv; |
157 | 246 | ||
158 | cx231xx_uninit_isoc(dev); | 247 | if (dev->USE_ISO) |
248 | cx231xx_uninit_isoc(dev); | ||
249 | else | ||
250 | cx231xx_uninit_bulk(dev); | ||
159 | 251 | ||
160 | cx231xx_set_mode(dev, CX231XX_SUSPEND); | 252 | cx231xx_set_mode(dev, CX231XX_SUSPEND); |
161 | 253 | ||
@@ -216,7 +308,11 @@ static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | |||
216 | 308 | ||
217 | static struct xc5000_config cnxt_rde250_tunerconfig = { | 309 | static struct xc5000_config cnxt_rde250_tunerconfig = { |
218 | .i2c_address = 0x61, | 310 | .i2c_address = 0x61, |
219 | .if_khz = 5380, | 311 | .if_khz = 4000, |
312 | }; | ||
313 | static struct xc5000_config cnxt_rdu250_tunerconfig = { | ||
314 | .i2c_address = 0x61, | ||
315 | .if_khz = 3250, | ||
220 | }; | 316 | }; |
221 | 317 | ||
222 | /* ------------------------------------------------------------------ */ | 318 | /* ------------------------------------------------------------------ */ |
@@ -268,7 +364,6 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) | |||
268 | /*params.audmode = ; */ | 364 | /*params.audmode = ; */ |
269 | 365 | ||
270 | /* Set the analog parameters to set the frequency */ | 366 | /* Set the analog parameters to set the frequency */ |
271 | cx231xx_info("Setting Frequency for XC5000\n"); | ||
272 | dops->set_analog_params(dev->dvb->frontend, ¶ms); | 367 | dops->set_analog_params(dev->dvb->frontend, ¶ms); |
273 | } | 368 | } |
274 | 369 | ||
@@ -446,18 +541,19 @@ static int dvb_init(struct cx231xx *dev) | |||
446 | dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; | 541 | dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; |
447 | 542 | ||
448 | cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); | 543 | cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); |
544 | cx231xx_demod_reset(dev); | ||
449 | /* init frontend */ | 545 | /* init frontend */ |
450 | switch (dev->model) { | 546 | switch (dev->model) { |
547 | case CX231XX_BOARD_CNXT_CARRAERA: | ||
451 | case CX231XX_BOARD_CNXT_RDE_250: | 548 | case CX231XX_BOARD_CNXT_RDE_250: |
452 | 549 | ||
453 | /* dev->dvb->frontend = dvb_attach(s5h1411_attach, | 550 | dev->dvb->frontend = dvb_attach(s5h1432_attach, |
454 | &dvico_s5h1411_config, | 551 | &dvico_s5h1432_config, |
455 | &dev->i2c_bus[1].i2c_adap); */ | 552 | &dev->i2c_bus[2].i2c_adap); |
456 | dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); | ||
457 | 553 | ||
458 | if (dev->dvb->frontend == NULL) { | 554 | if (dev->dvb->frontend == NULL) { |
459 | printk(DRIVER_NAME | 555 | printk(DRIVER_NAME |
460 | ": Failed to attach dummy front end\n"); | 556 | ": Failed to attach s5h1432 front end\n"); |
461 | result = -EINVAL; | 557 | result = -EINVAL; |
462 | goto out_free; | 558 | goto out_free; |
463 | } | 559 | } |
@@ -473,9 +569,12 @@ static int dvb_init(struct cx231xx *dev) | |||
473 | } | 569 | } |
474 | 570 | ||
475 | break; | 571 | break; |
572 | case CX231XX_BOARD_CNXT_SHELBY: | ||
476 | case CX231XX_BOARD_CNXT_RDU_250: | 573 | case CX231XX_BOARD_CNXT_RDU_250: |
477 | 574 | ||
478 | dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); | 575 | dev->dvb->frontend = dvb_attach(s5h1411_attach, |
576 | &xc5000_s5h1411_config, | ||
577 | &dev->i2c_bus[2].i2c_adap); | ||
479 | 578 | ||
480 | if (dev->dvb->frontend == NULL) { | 579 | if (dev->dvb->frontend == NULL) { |
481 | printk(DRIVER_NAME | 580 | printk(DRIVER_NAME |
@@ -489,7 +588,53 @@ static int dvb_init(struct cx231xx *dev) | |||
489 | 588 | ||
490 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, | 589 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, |
491 | &dev->i2c_bus[1].i2c_adap, | 590 | &dev->i2c_bus[1].i2c_adap, |
492 | &cnxt_rde250_tunerconfig)) { | 591 | &cnxt_rdu250_tunerconfig)) { |
592 | result = -EINVAL; | ||
593 | goto out_free; | ||
594 | } | ||
595 | break; | ||
596 | case CX231XX_BOARD_CNXT_RDE_253S: | ||
597 | |||
598 | dev->dvb->frontend = dvb_attach(s5h1432_attach, | ||
599 | &dvico_s5h1432_config, | ||
600 | &dev->i2c_bus[2].i2c_adap); | ||
601 | |||
602 | if (dev->dvb->frontend == NULL) { | ||
603 | printk(DRIVER_NAME | ||
604 | ": Failed to attach s5h1432 front end\n"); | ||
605 | result = -EINVAL; | ||
606 | goto out_free; | ||
607 | } | ||
608 | |||
609 | /* define general-purpose callback pointer */ | ||
610 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
611 | |||
612 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
613 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
614 | &cnxt_rde253s_tunerconfig)) { | ||
615 | result = -EINVAL; | ||
616 | goto out_free; | ||
617 | } | ||
618 | break; | ||
619 | case CX231XX_BOARD_CNXT_RDU_253S: | ||
620 | |||
621 | dev->dvb->frontend = dvb_attach(s5h1411_attach, | ||
622 | &tda18271_s5h1411_config, | ||
623 | &dev->i2c_bus[2].i2c_adap); | ||
624 | |||
625 | if (dev->dvb->frontend == NULL) { | ||
626 | printk(DRIVER_NAME | ||
627 | ": Failed to attach dummy front end\n"); | ||
628 | result = -EINVAL; | ||
629 | goto out_free; | ||
630 | } | ||
631 | |||
632 | /* define general-purpose callback pointer */ | ||
633 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
634 | |||
635 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | ||
636 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
637 | &cnxt_rde253s_tunerconfig)) { | ||
493 | result = -EINVAL; | 638 | result = -EINVAL; |
494 | goto out_free; | 639 | goto out_free; |
495 | } | 640 | } |