aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/m920x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb/m920x.c')
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c127
1 files changed, 82 insertions, 45 deletions
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index c546ddeda5d4..a956bc503a4c 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -22,6 +22,8 @@ static int dvb_usb_m920x_debug;
22module_param_named(debug,dvb_usb_m920x_debug, int, 0644); 22module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); 23MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
24 24
25static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
26
25static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, 27static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
26 u16 index, void *data, int size) 28 u16 index, void *data, int size)
27{ 29{
@@ -57,7 +59,8 @@ static inline int m920x_write(struct usb_device *udev, u8 request,
57 59
58static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) 60static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
59{ 61{
60 int ret = 0; 62 int ret = 0, i, epi, flags = 0;
63 int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
61 64
62 /* Remote controller init. */ 65 /* Remote controller init. */
63 if (d->props.rc_query) { 66 if (d->props.rc_query) {
@@ -76,9 +79,51 @@ static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
76 deb("Initialising remote control success\n"); 79 deb("Initialising remote control success\n");
77 } 80 }
78 81
82 for (i = 0; i < d->props.num_adapters; i++)
83 flags |= d->adapter[i].props.caps;
84
85 /* Some devices(Dposh) might crash if we attempt touch at all. */
86 if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
87 for (i = 0; i < d->props.num_adapters; i++) {
88 epi = d->adapter[i].props.stream.endpoint - 0x81;
89
90 if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
91 printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
92 return -EINVAL;
93 }
94
95 adap_enabled[epi] = 1;
96 }
97
98 for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
99 if (adap_enabled[i])
100 continue;
101
102 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
103 return ret;
104
105 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
106 return ret;
107 }
108 }
109
79 return ret; 110 return ret;
80} 111}
81 112
113static int m920x_init_ep(struct usb_interface *intf)
114{
115 struct usb_device *udev = interface_to_usbdev(intf);
116 struct usb_host_interface *alt;
117
118 if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
119 deb("No alt found!\n");
120 return -ENODEV;
121 }
122
123 return usb_set_interface(udev, alt->desc.bInterfaceNumber,
124 alt->desc.bAlternateSetting);
125}
126
82static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 127static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
83{ 128{
84 struct m920x_state *m = d->priv; 129 struct m920x_state *m = d->priv;
@@ -211,8 +256,7 @@ static struct i2c_algorithm m920x_i2c_algo = {
211}; 256};
212 257
213/* pid filter */ 258/* pid filter */
214static int m920x_set_filter(struct dvb_usb_adapter *adap, 259static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
215 int type, int idx, int pid)
216{ 260{
217 int ret = 0; 261 int ret = 0;
218 262
@@ -221,10 +265,10 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap,
221 265
222 pid |= 0x8000; 266 pid |= 0x8000;
223 267
224 if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) 268 if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
225 return ret; 269 return ret;
226 270
227 if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) 271 if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
228 return ret; 272 return ret;
229 273
230 return ret; 274 return ret;
@@ -233,40 +277,35 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap,
233static int m920x_update_filters(struct dvb_usb_adapter *adap) 277static int m920x_update_filters(struct dvb_usb_adapter *adap)
234{ 278{
235 struct m920x_state *m = adap->dev->priv; 279 struct m920x_state *m = adap->dev->priv;
236 int enabled = m->filtering_enabled; 280 int enabled = m->filtering_enabled[adap->id];
237 int i, ret = 0, filter = 0; 281 int i, ret = 0, filter = 0;
282 int ep = adap->props.stream.endpoint;
238 283
239 for (i = 0; i < M9206_MAX_FILTERS; i++) 284 for (i = 0; i < M9206_MAX_FILTERS; i++)
240 if (m->filters[i] == 8192) 285 if (m->filters[adap->id][i] == 8192)
241 enabled = 0; 286 enabled = 0;
242 287
243 /* Disable all filters */ 288 /* Disable all filters */
244 if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0) 289 if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
245 return ret; 290 return ret;
246 291
247 for (i = 0; i < M9206_MAX_FILTERS; i++) 292 for (i = 0; i < M9206_MAX_FILTERS; i++)
248 if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0) 293 if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
249 return ret; 294 return ret;
250 295
251 if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0)
252 return ret;
253
254 /* Set */ 296 /* Set */
255 if (enabled) { 297 if (enabled) {
256 for (i = 0; i < M9206_MAX_FILTERS; i++) { 298 for (i = 0; i < M9206_MAX_FILTERS; i++) {
257 if (m->filters[i] == 0) 299 if (m->filters[adap->id][i] == 0)
258 continue; 300 continue;
259 301
260 if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) 302 if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
261 return ret; 303 return ret;
262 304
263 filter++; 305 filter++;
264 } 306 }
265 } 307 }
266 308
267 if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
268 return ret;
269
270 return ret; 309 return ret;
271} 310}
272 311
@@ -274,7 +313,7 @@ static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
274{ 313{
275 struct m920x_state *m = adap->dev->priv; 314 struct m920x_state *m = adap->dev->priv;
276 315
277 m->filtering_enabled = onoff ? 1 : 0; 316 m->filtering_enabled[adap->id] = onoff ? 1 : 0;
278 317
279 return m920x_update_filters(adap); 318 return m920x_update_filters(adap);
280} 319}
@@ -283,7 +322,7 @@ static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in
283{ 322{
284 struct m920x_state *m = adap->dev->priv; 323 struct m920x_state *m = adap->dev->priv;
285 324
286 m->filters[index] = onoff ? pid : 0; 325 m->filters[adap->id][index] = onoff ? pid : 0;
287 326
288 return m920x_update_filters(adap); 327 return m920x_update_filters(adap);
289} 328}
@@ -368,6 +407,7 @@ static int m920x_identify_state(struct usb_device *udev,
368/* demod configurations */ 407/* demod configurations */
369static int m920x_mt352_demod_init(struct dvb_frontend *fe) 408static int m920x_mt352_demod_init(struct dvb_frontend *fe)
370{ 409{
410 int ret;
371 u8 config[] = { CONFIG, 0x3d }; 411 u8 config[] = { CONFIG, 0x3d };
372 u8 clock[] = { CLOCK_CTL, 0x30 }; 412 u8 clock[] = { CLOCK_CTL, 0x30 };
373 u8 reset[] = { RESET, 0x80 }; 413 u8 reset[] = { RESET, 0x80 };
@@ -377,17 +417,25 @@ static int m920x_mt352_demod_init(struct dvb_frontend *fe)
377 u8 unk1[] = { 0x93, 0x1a }; 417 u8 unk1[] = { 0x93, 0x1a };
378 u8 unk2[] = { 0xb5, 0x7a }; 418 u8 unk2[] = { 0xb5, 0x7a };
379 419
380 mt352_write(fe, config, ARRAY_SIZE(config));
381 mt352_write(fe, clock, ARRAY_SIZE(clock));
382 mt352_write(fe, reset, ARRAY_SIZE(reset));
383 mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl));
384 mt352_write(fe, agc, ARRAY_SIZE(agc));
385 mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc));
386 mt352_write(fe, unk1, ARRAY_SIZE(unk1));
387 mt352_write(fe, unk2, ARRAY_SIZE(unk2));
388
389 deb("Demod init!\n"); 420 deb("Demod init!\n");
390 421
422 if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
423 return ret;
424 if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
425 return ret;
426 if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
427 return ret;
428 if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
429 return ret;
430 if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
431 return ret;
432 if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
433 return ret;
434 if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
435 return ret;
436 if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
437 return ret;
438
391 return 0; 439 return 0;
392} 440}
393 441
@@ -558,8 +606,7 @@ static struct dvb_usb_device_properties dposh_properties;
558static int m920x_probe(struct usb_interface *intf, 606static int m920x_probe(struct usb_interface *intf,
559 const struct usb_device_id *id) 607 const struct usb_device_id *id)
560{ 608{
561 struct dvb_usb_device *d; 609 struct dvb_usb_device *d = NULL;
562 struct usb_host_interface *alt;
563 int ret; 610 int ret;
564 struct m920x_inits *rc_init_seq = NULL; 611 struct m920x_inits *rc_init_seq = NULL;
565 int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; 612 int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
@@ -604,23 +651,13 @@ static int m920x_probe(struct usb_interface *intf,
604 * tvwalkertwin_properties already configured both 651 * tvwalkertwin_properties already configured both
605 * tuners, so there is nothing for us to do here 652 * tuners, so there is nothing for us to do here
606 */ 653 */
607
608 return -ENODEV;
609 } 654 }
610 655
611 found: 656 found:
612 alt = usb_altnum_to_altsetting(intf, 1); 657 if ((ret = m920x_init_ep(intf)) < 0)
613 if (alt == NULL) {
614 deb("No alt found!\n");
615 return -ENODEV;
616 }
617
618 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
619 alt->desc.bAlternateSetting);
620 if (ret < 0)
621 return ret; 658 return ret;
622 659
623 if ((ret = m920x_init(d, rc_init_seq)) != 0) 660 if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
624 return ret; 661 return ret;
625 662
626 return ret; 663 return ret;
@@ -737,9 +774,9 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
737 * 774 *
738 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A 775 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
739 * TDA10046 #0 is located at i2c address 0x08 776 * TDA10046 #0 is located at i2c address 0x08
740 * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working) 777 * TDA10046 #1 is located at i2c address 0x0b
741 * TDA8275A #0 is located at i2c address 0x60 778 * TDA8275A #0 is located at i2c address 0x60
742 * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working) 779 * TDA8275A #1 is located at i2c address 0x61
743 */ 780 */
744static struct dvb_usb_device_properties tvwalkertwin_properties = { 781static struct dvb_usb_device_properties tvwalkertwin_properties = {
745 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 782 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
@@ -756,7 +793,7 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = {
756 .size_of_priv = sizeof(struct m920x_state), 793 .size_of_priv = sizeof(struct m920x_state),
757 794
758 .identify_state = m920x_identify_state, 795 .identify_state = m920x_identify_state,
759 .num_adapters = 1, 796 .num_adapters = 2,
760 .adapter = {{ 797 .adapter = {{
761 .caps = DVB_USB_ADAP_HAS_PID_FILTER | 798 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
762 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 799 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,