diff options
author | Antti Palosaari <crope@iki.fi> | 2011-04-10 16:53:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:27:03 -0400 |
commit | 41f81f686a85af144ad9769a15ef8575b69eee38 (patch) | |
tree | 168b04a46cfc3593989a9680d2e55c11ea690111 | |
parent | 592d9e21f5d875e84d09940eff7bc48812245855 (diff) |
[media] anysee: reimplement demod and tuner attach
Use board ID as base value when selecting correct hardware configuration.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb/dvb-usb/anysee.c | 302 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/anysee.h | 19 |
2 files changed, 233 insertions, 88 deletions
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index d50118ccc105..ff9226e1843d 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -105,6 +105,27 @@ static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val) | |||
105 | return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); | 105 | return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); |
106 | } | 106 | } |
107 | 107 | ||
108 | /* write single register with mask */ | ||
109 | static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val, | ||
110 | u8 mask) | ||
111 | { | ||
112 | int ret; | ||
113 | u8 tmp; | ||
114 | |||
115 | /* no need for read if whole reg is written */ | ||
116 | if (mask != 0xff) { | ||
117 | ret = anysee_read_reg(d, reg, &tmp); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | |||
121 | val &= mask; | ||
122 | tmp &= ~mask; | ||
123 | val |= tmp; | ||
124 | } | ||
125 | |||
126 | return anysee_write_reg(d, reg, val); | ||
127 | } | ||
128 | |||
108 | static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) | 129 | static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) |
109 | { | 130 | { |
110 | u8 buf[] = {CMD_GET_HW_INFO}; | 131 | u8 buf[] = {CMD_GET_HW_INFO}; |
@@ -244,134 +265,241 @@ static struct zl10353_config anysee_zl10353_config = { | |||
244 | .parallel_ts = 1, | 265 | .parallel_ts = 1, |
245 | }; | 266 | }; |
246 | 267 | ||
268 | /* | ||
269 | * New USB device strings: Mfr=1, Product=2, SerialNumber=0 | ||
270 | * Manufacturer: AMT.CO.KR | ||
271 | * | ||
272 | * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=???????? | ||
273 | * PCB: ? | ||
274 | * parts: MT352, DTT7579(?), DNOS404ZH102A NIM | ||
275 | * | ||
276 | * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=???????? | ||
277 | * PCB: ? | ||
278 | * parts: ZL10353, DTT7579(?), DNOS404ZH103A NIM | ||
279 | * | ||
280 | * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee" | ||
281 | * PCB: 507CD (rev1.1) | ||
282 | * parts: ZL10353, DTT7579(?), CST56I01, DNOS404ZH103A NIM | ||
283 | * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe | ||
284 | * IOD[0] ZL10353 1=enabled | ||
285 | * IOA[7] TS 0=enabled | ||
286 | * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not) | ||
287 | * | ||
288 | * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)" | ||
289 | * PCB: 507DC (rev0.2) | ||
290 | * parts: TDA10023, CST56I01, DTOS403IH102B TM | ||
291 | * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe | ||
292 | * IOD[0] TDA10023 1=enabled | ||
293 | * | ||
294 | * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)" | ||
295 | * PCB: 507FA (rev0.4) | ||
296 | * parts: TDA10023, TDA8024, DTOS403IH102B TM | ||
297 | * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff | ||
298 | * IOD[5] TDA10023 1=enabled | ||
299 | * IOE[0] tuner 1=enabled | ||
300 | * | ||
301 | * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)" | ||
302 | * PCB: 507FA (rev1.1) | ||
303 | * parts: ZL10353, TDA10023, TDA8024, DTOS403IH102B TM | ||
304 | * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff | ||
305 | * DVB-C: | ||
306 | * IOD[5] TDA10023 1=enabled | ||
307 | * IOE[0] tuner 1=enabled | ||
308 | * DVB-T: | ||
309 | * IOD[0] ZL10353 1=enabled | ||
310 | * IOE[0] tuner 0=enabled | ||
311 | * tuner is behind ZL10353 I2C-gate | ||
312 | */ | ||
313 | |||
247 | static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | 314 | static int anysee_frontend_attach(struct dvb_usb_adapter *adap) |
248 | { | 315 | { |
249 | int ret; | 316 | int ret; |
250 | struct anysee_state *state = adap->dev->priv; | 317 | struct anysee_state *state = adap->dev->priv; |
251 | u8 hw_info[3]; | 318 | u8 hw_info[3]; |
252 | u8 io_d; /* IO port D */ | ||
253 | 319 | ||
254 | /* check which hardware we have | 320 | /* Check which hardware we have. |
255 | We must do this call two times to get reliable values (hw bug). */ | 321 | * We must do this call two times to get reliable values (hw bug). |
322 | */ | ||
256 | ret = anysee_get_hw_info(adap->dev, hw_info); | 323 | ret = anysee_get_hw_info(adap->dev, hw_info); |
257 | if (ret) | 324 | if (ret) |
258 | return ret; | 325 | goto error; |
326 | |||
259 | ret = anysee_get_hw_info(adap->dev, hw_info); | 327 | ret = anysee_get_hw_info(adap->dev, hw_info); |
260 | if (ret) | 328 | if (ret) |
261 | return ret; | 329 | goto error; |
262 | 330 | ||
263 | /* Meaning of these info bytes are guessed. */ | 331 | /* Meaning of these info bytes are guessed. */ |
264 | info("firmware version:%d.%d hardware id:%d", | 332 | info("firmware version:%d.%d hardware id:%d", |
265 | hw_info[1], hw_info[2], hw_info[0]); | 333 | hw_info[1], hw_info[2], hw_info[0]); |
266 | 334 | ||
267 | ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */ | 335 | state->hw = hw_info[0]; |
268 | if (ret) | ||
269 | return ret; | ||
270 | deb_info("%s: IO port D:%02x\n", __func__, io_d); | ||
271 | |||
272 | /* Select demod using trial and error method. */ | ||
273 | |||
274 | /* Try to attach demodulator in following order: | ||
275 | model demod hw fw | ||
276 | 1. E30 MT352 02 2.1 | ||
277 | 2. E30 ZL10353 02 2.1 | ||
278 | 3. E30 Combo ZL10353 0f 1.2 DVB-T/C combo | ||
279 | 4. E30 Plus ZL10353 06 1.0 | ||
280 | 5. E30C Plus TDA10023 0a 1.0 rev 0.2 | ||
281 | E30C Plus TDA10023 0f 1.2 rev 0.4 | ||
282 | E30 Combo TDA10023 0f 1.2 DVB-T/C combo | ||
283 | */ | ||
284 | |||
285 | /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ | ||
286 | adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config, | ||
287 | &adap->dev->i2c_adap); | ||
288 | if (adap->fe != NULL) { | ||
289 | state->tuner = DVB_PLL_THOMSON_DTT7579; | ||
290 | return 0; | ||
291 | } | ||
292 | 336 | ||
293 | /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ | 337 | switch (state->hw) { |
294 | adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, | 338 | case ANYSEE_HW_02: /* 2 */ |
295 | &adap->dev->i2c_adap); | 339 | /* E30 */ |
296 | if (adap->fe != NULL) { | ||
297 | state->tuner = DVB_PLL_THOMSON_DTT7579; | ||
298 | return 0; | ||
299 | } | ||
300 | 340 | ||
301 | /* for E30 Combo Plus DVB-T demodulator */ | 341 | /* attach demod */ |
302 | if (dvb_usb_anysee_delsys) { | 342 | adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config, |
303 | ret = anysee_write_reg(adap->dev, 0xb0, 0x01); | 343 | &adap->dev->i2c_adap); |
304 | if (ret) | 344 | if (adap->fe) |
305 | return ret; | 345 | break; |
306 | 346 | ||
307 | /* Zarlink ZL10353 DVB-T demod */ | 347 | /* attach demod */ |
308 | adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, | 348 | adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, |
309 | &adap->dev->i2c_adap); | 349 | &adap->dev->i2c_adap); |
310 | if (adap->fe != NULL) { | 350 | if (adap->fe) |
311 | state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; | 351 | break; |
312 | return 0; | ||
313 | } | ||
314 | } | ||
315 | 352 | ||
316 | /* connect demod on IO port D for TDA10023 & ZL10353 */ | 353 | break; |
317 | ret = anysee_write_reg(adap->dev, 0xb0, 0x25); | 354 | case ANYSEE_HW_507CD: /* 6 */ |
318 | if (ret) | 355 | /* E30 Plus */ |
319 | return ret; | ||
320 | 356 | ||
321 | /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ | 357 | /* enable DVB-T demod on IOD[0] */ |
322 | adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, | 358 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); |
323 | &adap->dev->i2c_adap); | 359 | if (ret) |
324 | if (adap->fe != NULL) { | 360 | goto error; |
325 | state->tuner = DVB_PLL_THOMSON_DTT7579; | ||
326 | return 0; | ||
327 | } | ||
328 | 361 | ||
329 | /* IO port E - E30C rev 0.4 board requires this */ | 362 | /* enable transport stream on IOA[7] */ |
330 | ret = anysee_write_reg(adap->dev, 0xb1, 0xa7); | 363 | ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80); |
331 | if (ret) | 364 | if (ret) |
332 | return ret; | 365 | goto error; |
333 | 366 | ||
334 | /* Philips TDA10023 DVB-C demod */ | 367 | /* attach demod */ |
335 | adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, | 368 | adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, |
336 | &adap->dev->i2c_adap, 0x48); | 369 | &adap->dev->i2c_adap); |
337 | if (adap->fe != NULL) { | 370 | if (adap->fe) |
338 | state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; | 371 | break; |
339 | return 0; | ||
340 | } | ||
341 | 372 | ||
342 | /* return IO port D to init value for safe */ | 373 | break; |
343 | ret = anysee_write_reg(adap->dev, 0xb0, io_d); | 374 | case ANYSEE_HW_507DC: /* 10 */ |
344 | if (ret) | 375 | /* E30 C Plus */ |
345 | return ret; | 376 | |
377 | /* enable DVB-C demod on IOD[0] */ | ||
378 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); | ||
379 | if (ret) | ||
380 | goto error; | ||
381 | |||
382 | /* attach demod */ | ||
383 | adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, | ||
384 | &adap->dev->i2c_adap, 0x48); | ||
385 | if (adap->fe) | ||
386 | break; | ||
346 | 387 | ||
347 | err("Unknown Anysee version: %02x %02x %02x. " \ | 388 | break; |
348 | "Please report the <linux-media@vger.kernel.org>.", | 389 | case ANYSEE_HW_507FA: /* 15 */ |
349 | hw_info[0], hw_info[1], hw_info[2]); | 390 | /* E30 Combo Plus */ |
391 | /* E30 C Plus */ | ||
392 | |||
393 | if (dvb_usb_anysee_delsys) { | ||
394 | /* disable DVB-C demod on IOD[5] */ | ||
395 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), | ||
396 | 0x20); | ||
397 | if (ret) | ||
398 | goto error; | ||
399 | |||
400 | /* enable DVB-T demod on IOD[0] */ | ||
401 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), | ||
402 | 0x01); | ||
403 | if (ret) | ||
404 | goto error; | ||
405 | |||
406 | /* attach demod */ | ||
407 | adap->fe = dvb_attach(zl10353_attach, | ||
408 | &anysee_zl10353_config, &adap->dev->i2c_adap); | ||
409 | if (adap->fe) | ||
410 | break; | ||
411 | } else { | ||
412 | /* disable DVB-T demod on IOD[0] */ | ||
413 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), | ||
414 | 0x01); | ||
415 | if (ret) | ||
416 | goto error; | ||
417 | |||
418 | /* enable DVB-C demod on IOD[5] */ | ||
419 | ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), | ||
420 | 0x20); | ||
421 | if (ret) | ||
422 | goto error; | ||
423 | |||
424 | /* attach demod */ | ||
425 | adap->fe = dvb_attach(tda10023_attach, | ||
426 | &anysee_tda10023_config, &adap->dev->i2c_adap, | ||
427 | 0x48); | ||
428 | if (adap->fe) | ||
429 | break; | ||
430 | } | ||
431 | break; | ||
432 | } | ||
350 | 433 | ||
351 | return -ENODEV; | 434 | if (!adap->fe) { |
435 | /* we have no frontend :-( */ | ||
436 | ret = -ENODEV; | ||
437 | err("Unknown Anysee version: %02x %02x %02x. " \ | ||
438 | "Please report the <linux-media@vger.kernel.org>.", | ||
439 | hw_info[0], hw_info[1], hw_info[2]); | ||
440 | } | ||
441 | error: | ||
442 | return ret; | ||
352 | } | 443 | } |
353 | 444 | ||
354 | static int anysee_tuner_attach(struct dvb_usb_adapter *adap) | 445 | static int anysee_tuner_attach(struct dvb_usb_adapter *adap) |
355 | { | 446 | { |
356 | struct anysee_state *state = adap->dev->priv; | 447 | struct anysee_state *state = adap->dev->priv; |
448 | int ret = 0; | ||
357 | deb_info("%s:\n", __func__); | 449 | deb_info("%s:\n", __func__); |
358 | 450 | ||
359 | switch (state->tuner) { | 451 | switch (state->hw) { |
360 | case DVB_PLL_THOMSON_DTT7579: | 452 | case ANYSEE_HW_02: /* 2 */ |
361 | /* Thomson dtt7579 (not sure) PLL inside of: | 453 | /* E30 */ |
362 | Samsung DNOS404ZH102A NIM | 454 | |
363 | Samsung DNOS404ZH103A NIM */ | 455 | /* attach tuner */ |
364 | dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1), | 456 | dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1), |
365 | NULL, DVB_PLL_THOMSON_DTT7579); | 457 | NULL, DVB_PLL_THOMSON_DTT7579); |
366 | break; | 458 | break; |
367 | case DVB_PLL_SAMSUNG_DTOS403IH102A: | 459 | case ANYSEE_HW_507CD: /* 6 */ |
368 | /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */ | 460 | /* E30 Plus */ |
461 | |||
462 | /* attach tuner */ | ||
463 | dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1), | ||
464 | &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); | ||
465 | |||
466 | break; | ||
467 | case ANYSEE_HW_507DC: /* 10 */ | ||
468 | /* E30 C Plus */ | ||
469 | |||
470 | /* attach tuner */ | ||
471 | dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1), | ||
472 | &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); | ||
473 | break; | ||
474 | case ANYSEE_HW_507FA: /* 15 */ | ||
475 | /* E30 Combo Plus */ | ||
476 | /* E30 C Plus */ | ||
477 | |||
478 | if (dvb_usb_anysee_delsys) { | ||
479 | /* enable DVB-T tuner on IOE[0] */ | ||
480 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), | ||
481 | 0x01); | ||
482 | if (ret) | ||
483 | goto error; | ||
484 | } else { | ||
485 | /* enable DVB-C tuner on IOE[0] */ | ||
486 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), | ||
487 | 0x01); | ||
488 | if (ret) | ||
489 | goto error; | ||
490 | } | ||
491 | |||
492 | /* attach tuner */ | ||
369 | dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1), | 493 | dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1), |
370 | &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); | 494 | &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); |
495 | |||
371 | break; | 496 | break; |
497 | default: | ||
498 | ret = -ENODEV; | ||
372 | } | 499 | } |
373 | 500 | ||
374 | return 0; | 501 | error: |
502 | return ret; | ||
375 | } | 503 | } |
376 | 504 | ||
377 | static int anysee_rc_query(struct dvb_usb_device *d) | 505 | static int anysee_rc_query(struct dvb_usb_device *d) |
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 686e06044fcb..0f7b4d48a5c8 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h | |||
@@ -57,10 +57,27 @@ enum cmd { | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct anysee_state { | 59 | struct anysee_state { |
60 | u8 tuner; | 60 | u8 hw; /* PCB ID */ |
61 | u8 seq; | 61 | u8 seq; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #define ANYSEE_HW_02 2 /* E30 */ | ||
65 | #define ANYSEE_HW_507CD 6 /* E30 Plus */ | ||
66 | #define ANYSEE_HW_507DC 10 /* E30 C Plus */ | ||
67 | #define ANYSEE_HW_507SI 11 /* E30 S2 Plus */ | ||
68 | #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ | ||
69 | |||
70 | #define REG_IOA 0x80 /* Port A (bit addressable) */ | ||
71 | #define REG_IOB 0x90 /* Port B (bit addressable) */ | ||
72 | #define REG_IOC 0xa0 /* Port C (bit addressable) */ | ||
73 | #define REG_IOD 0xb0 /* Port D (bit addressable) */ | ||
74 | #define REG_IOE 0xb1 /* Port E (NOT bit addressable) */ | ||
75 | #define REG_OEA 0xb2 /* Port A Output Enable */ | ||
76 | #define REG_OEB 0xb3 /* Port B Output Enable */ | ||
77 | #define REG_OEC 0xb4 /* Port C Output Enable */ | ||
78 | #define REG_OED 0xb5 /* Port D Output Enable */ | ||
79 | #define REG_OEE 0xb6 /* Port E Output Enable */ | ||
80 | |||
64 | #endif | 81 | #endif |
65 | 82 | ||
66 | /*************************************************************************** | 83 | /*************************************************************************** |