diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/m920x.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/m920x.c | 127 |
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; | |||
22 | module_param_named(debug,dvb_usb_m920x_debug, int, 0644); | 22 | module_param_named(debug,dvb_usb_m920x_debug, int, 0644); |
23 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | 23 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); |
24 | 24 | ||
25 | static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid); | ||
26 | |||
25 | static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, | 27 | static 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 | ||
58 | static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) | 60 | static 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 | ||
113 | static 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 | |||
82 | static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 127 | static 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 */ |
214 | static int m920x_set_filter(struct dvb_usb_adapter *adap, | 259 | static 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, | |||
233 | static int m920x_update_filters(struct dvb_usb_adapter *adap) | 277 | static 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 */ |
369 | static int m920x_mt352_demod_init(struct dvb_frontend *fe) | 408 | static 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; | |||
558 | static int m920x_probe(struct usb_interface *intf, | 606 | static 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 | */ |
744 | static struct dvb_usb_device_properties tvwalkertwin_properties = { | 781 | static 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, |