diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 8 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 456 |
2 files changed, 315 insertions, 149 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 2dee1bf73577..1b249897c9fb 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -265,9 +265,13 @@ config DVB_USB_DW2102 | |||
265 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | 265 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE |
266 | select DVB_MT312 if !DVB_FE_CUSTOMISE | 266 | select DVB_MT312 if !DVB_FE_CUSTOMISE |
267 | select DVB_ZL10039 if !DVB_FE_CUSTOMISE | 267 | select DVB_ZL10039 if !DVB_FE_CUSTOMISE |
268 | select DVB_DS3000 if !DVB_FE_CUSTOMISE | ||
269 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
270 | select DVB_STV6110 if !DVB_FE_CUSTOMISE | ||
271 | select DVB_STV0900 if !DVB_FE_CUSTOMISE | ||
268 | help | 272 | help |
269 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers | 273 | Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0 |
270 | and the TeVii S650, S630. | 274 | receivers. |
271 | 275 | ||
272 | config DVB_USB_CINERGY_T2 | 276 | config DVB_USB_CINERGY_T2 |
273 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" | 277 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 5bb9479d154e..64132c0cf80d 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -20,6 +20,11 @@ | |||
20 | #include "tda1002x.h" | 20 | #include "tda1002x.h" |
21 | #include "mt312.h" | 21 | #include "mt312.h" |
22 | #include "zl10039.h" | 22 | #include "zl10039.h" |
23 | #include "ds3000.h" | ||
24 | #include "stv0900.h" | ||
25 | #include "stv6110.h" | ||
26 | #include "stb6100.h" | ||
27 | #include "stb6100_proc.h" | ||
23 | 28 | ||
24 | #ifndef USB_PID_DW2102 | 29 | #ifndef USB_PID_DW2102 |
25 | #define USB_PID_DW2102 0x2102 | 30 | #define USB_PID_DW2102 0x2102 |
@@ -37,12 +42,20 @@ | |||
37 | #define USB_PID_CINERGY_S 0x0064 | 42 | #define USB_PID_CINERGY_S 0x0064 |
38 | #endif | 43 | #endif |
39 | 44 | ||
45 | #ifndef USB_PID_TEVII_S630 | ||
46 | #define USB_PID_TEVII_S630 0xd630 | ||
47 | #endif | ||
48 | |||
40 | #ifndef USB_PID_TEVII_S650 | 49 | #ifndef USB_PID_TEVII_S650 |
41 | #define USB_PID_TEVII_S650 0xd650 | 50 | #define USB_PID_TEVII_S650 0xd650 |
42 | #endif | 51 | #endif |
43 | 52 | ||
44 | #ifndef USB_PID_TEVII_S630 | 53 | #ifndef USB_PID_TEVII_S660 |
45 | #define USB_PID_TEVII_S630 0xd630 | 54 | #define USB_PID_TEVII_S660 0xd660 |
55 | #endif | ||
56 | |||
57 | #ifndef USB_PID_PROF_1100 | ||
58 | #define USB_PID_PROF_1100 0xb012 | ||
46 | #endif | 59 | #endif |
47 | 60 | ||
48 | #define DW210X_READ_MSG 0 | 61 | #define DW210X_READ_MSG 0 |
@@ -55,6 +68,10 @@ | |||
55 | #define DW2102_VOLTAGE_CTRL (0x1800) | 68 | #define DW2102_VOLTAGE_CTRL (0x1800) |
56 | #define DW2102_RC_QUERY (0x1a00) | 69 | #define DW2102_RC_QUERY (0x1a00) |
57 | 70 | ||
71 | #define err_str "did not find the firmware file. (%s) " \ | ||
72 | "Please see linux/Documentation/dvb/ for more details " \ | ||
73 | "on firmware-problems." | ||
74 | |||
58 | struct dvb_usb_rc_keys_table { | 75 | struct dvb_usb_rc_keys_table { |
59 | struct dvb_usb_rc_key *rc_keys; | 76 | struct dvb_usb_rc_key *rc_keys; |
60 | int rc_keys_size; | 77 | int rc_keys_size; |
@@ -71,6 +88,12 @@ static int ir_keymap; | |||
71 | module_param_named(keymap, ir_keymap, int, 0644); | 88 | module_param_named(keymap, ir_keymap, int, 0644); |
72 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | 89 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); |
73 | 90 | ||
91 | /* demod probe */ | ||
92 | static int demod_probe = 1; | ||
93 | module_param_named(demod, demod_probe, int, 0644); | ||
94 | MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 " | ||
95 | "4=stv0903+stb6100(or-able))."); | ||
96 | |||
74 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 97 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
75 | 98 | ||
76 | static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, | 99 | static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, |
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, | |||
183 | switch (num) { | 206 | switch (num) { |
184 | case 2: | 207 | case 2: |
185 | /* read si2109 register by number */ | 208 | /* read si2109 register by number */ |
186 | buf6[0] = 0xd0; | 209 | buf6[0] = msg[0].addr << 1; |
187 | buf6[1] = msg[0].len; | 210 | buf6[1] = msg[0].len; |
188 | buf6[2] = msg[0].buf[0]; | 211 | buf6[2] = msg[0].buf[0]; |
189 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 212 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, | |||
198 | switch (msg[0].addr) { | 221 | switch (msg[0].addr) { |
199 | case 0x68: | 222 | case 0x68: |
200 | /* write to si2109 register */ | 223 | /* write to si2109 register */ |
201 | buf6[0] = 0xd0; | 224 | buf6[0] = msg[0].addr << 1; |
202 | buf6[1] = msg[0].len; | 225 | buf6[1] = msg[0].len; |
203 | memcpy(buf6 + 2, msg[0].buf, msg[0].len); | 226 | memcpy(buf6 + 2, msg[0].buf, msg[0].len); |
204 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, | 227 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, |
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
239 | /* read */ | 262 | /* read */ |
240 | /* first write first register number */ | 263 | /* first write first register number */ |
241 | u8 ibuf[msg[1].len + 2], obuf[3]; | 264 | u8 ibuf[msg[1].len + 2], obuf[3]; |
242 | obuf[0] = 0xd0; | 265 | obuf[0] = msg[0].addr << 1; |
243 | obuf[1] = msg[0].len; | 266 | obuf[1] = msg[0].len; |
244 | obuf[2] = msg[0].buf[0]; | 267 | obuf[2] = msg[0].buf[0]; |
245 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 268 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
256 | case 0x68: { | 279 | case 0x68: { |
257 | /* write to register */ | 280 | /* write to register */ |
258 | u8 obuf[msg[0].len + 2]; | 281 | u8 obuf[msg[0].len + 2]; |
259 | obuf[0] = 0xd0; | 282 | obuf[0] = msg[0].addr << 1; |
260 | obuf[1] = msg[0].len; | 283 | obuf[1] = msg[0].len; |
261 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | 284 | memcpy(obuf + 2, msg[0].buf, msg[0].len); |
262 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 285 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
266 | case 0x61: { | 289 | case 0x61: { |
267 | /* write to tuner */ | 290 | /* write to tuner */ |
268 | u8 obuf[msg[0].len + 2]; | 291 | u8 obuf[msg[0].len + 2]; |
269 | obuf[0] = 0xc2; | 292 | obuf[0] = msg[0].addr << 1; |
270 | obuf[1] = msg[0].len; | 293 | obuf[1] = msg[0].len; |
271 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | 294 | memcpy(obuf + 2, msg[0].buf, msg[0].len); |
272 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 295 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i | |||
301 | { | 324 | { |
302 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 325 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
303 | int ret = 0; | 326 | int ret = 0; |
304 | int len, i; | 327 | int len, i, j; |
305 | 328 | ||
306 | if (!d) | 329 | if (!d) |
307 | return -ENODEV; | 330 | return -ENODEV; |
308 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 331 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
309 | return -EAGAIN; | 332 | return -EAGAIN; |
310 | 333 | ||
311 | switch (num) { | 334 | for (j = 0; j < num; j++) { |
312 | case 2: { | 335 | switch (msg[j].addr) { |
313 | /* read */ | ||
314 | /* first write first register number */ | ||
315 | u8 ibuf[msg[1].len + 2], obuf[3]; | ||
316 | obuf[0] = 0xaa; | ||
317 | obuf[1] = msg[0].len; | ||
318 | obuf[2] = msg[0].buf[0]; | ||
319 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
320 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
321 | /* second read registers */ | ||
322 | ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0, | ||
323 | ibuf, msg[1].len + 2, DW210X_READ_MSG); | ||
324 | memcpy(msg[1].buf, ibuf + 2, msg[1].len); | ||
325 | |||
326 | break; | ||
327 | } | ||
328 | case 1: | ||
329 | switch (msg[0].addr) { | ||
330 | case 0x55: { | ||
331 | if (msg[0].buf[0] == 0xf7) { | ||
332 | /* firmware */ | ||
333 | /* Write in small blocks */ | ||
334 | u8 obuf[19]; | ||
335 | obuf[0] = 0xaa; | ||
336 | obuf[1] = 0x11; | ||
337 | obuf[2] = 0xf7; | ||
338 | len = msg[0].len - 1; | ||
339 | i = 1; | ||
340 | do { | ||
341 | memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); | ||
342 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
343 | obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG); | ||
344 | i += 16; | ||
345 | len -= 16; | ||
346 | } while (len > 0); | ||
347 | } else { | ||
348 | /* write to register */ | ||
349 | u8 obuf[msg[0].len + 2]; | ||
350 | obuf[0] = 0xaa; | ||
351 | obuf[1] = msg[0].len; | ||
352 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
353 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
354 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
355 | } | ||
356 | break; | ||
357 | } | ||
358 | case(DW2102_RC_QUERY): { | 336 | case(DW2102_RC_QUERY): { |
359 | u8 ibuf[2]; | 337 | u8 ibuf[2]; |
360 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | 338 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, |
361 | ibuf, 2, DW210X_READ_MSG); | 339 | ibuf, 2, DW210X_READ_MSG); |
362 | memcpy(msg[0].buf, ibuf , 2); | 340 | memcpy(msg[j].buf, ibuf , 2); |
363 | break; | 341 | break; |
364 | } | 342 | } |
365 | case(DW2102_VOLTAGE_CTRL): { | 343 | case(DW2102_VOLTAGE_CTRL): { |
366 | u8 obuf[2]; | 344 | u8 obuf[2]; |
367 | obuf[0] = 0x30; | 345 | obuf[0] = 0x30; |
368 | obuf[1] = msg[0].buf[0]; | 346 | obuf[1] = msg[j].buf[0]; |
369 | ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, | 347 | ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, |
370 | obuf, 2, DW210X_WRITE_MSG); | 348 | obuf, 2, DW210X_WRITE_MSG); |
371 | break; | 349 | break; |
372 | } | 350 | } |
351 | /*case 0x55: cx24116 | ||
352 | case 0x6a: stv0903 | ||
353 | case 0x68: ds3000, stv0903 | ||
354 | case 0x60: ts2020, stv6110, stb6100 */ | ||
355 | default: { | ||
356 | if (msg[j].flags == I2C_M_RD) { | ||
357 | /* read registers */ | ||
358 | u8 ibuf[msg[j].len + 2]; | ||
359 | ret = dw210x_op_rw(d->udev, 0xc3, | ||
360 | (msg[j].addr << 1) + 1, 0, | ||
361 | ibuf, msg[j].len + 2, | ||
362 | DW210X_READ_MSG); | ||
363 | memcpy(msg[j].buf, ibuf + 2, msg[j].len); | ||
364 | mdelay(10); | ||
365 | } else if (((msg[j].buf[0] == 0xb0) && | ||
366 | (msg[j].addr == 0x68)) || | ||
367 | ((msg[j].buf[0] == 0xf7) && | ||
368 | (msg[j].addr == 0x55))) { | ||
369 | /* write firmware */ | ||
370 | u8 obuf[19]; | ||
371 | obuf[0] = msg[j].addr << 1; | ||
372 | obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len); | ||
373 | obuf[2] = msg[j].buf[0]; | ||
374 | len = msg[j].len - 1; | ||
375 | i = 1; | ||
376 | do { | ||
377 | memcpy(obuf + 3, msg[j].buf + i, | ||
378 | (len > 16 ? 16 : len)); | ||
379 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
380 | obuf, (len > 16 ? 16 : len) + 3, | ||
381 | DW210X_WRITE_MSG); | ||
382 | i += 16; | ||
383 | len -= 16; | ||
384 | } while (len > 0); | ||
385 | } else { | ||
386 | /* write registers */ | ||
387 | u8 obuf[msg[j].len + 2]; | ||
388 | obuf[0] = msg[j].addr << 1; | ||
389 | obuf[1] = msg[j].len; | ||
390 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||
391 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
392 | obuf, msg[j].len + 2, | ||
393 | DW210X_WRITE_MSG); | ||
394 | } | ||
395 | break; | ||
396 | } | ||
373 | } | 397 | } |
374 | 398 | ||
375 | break; | ||
376 | } | 399 | } |
377 | 400 | ||
378 | mutex_unlock(&d->i2c_mutex); | 401 | mutex_unlock(&d->i2c_mutex); |
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
442 | return num; | 465 | return num; |
443 | } | 466 | } |
444 | 467 | ||
445 | static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | 468 | static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
446 | int num) | 469 | int num) |
447 | { | 470 | { |
448 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 471 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
449 | int ret = 0; | 472 | int ret = 0; |
473 | int len, i, j; | ||
450 | 474 | ||
451 | if (!d) | 475 | if (!d) |
452 | return -ENODEV; | 476 | return -ENODEV; |
453 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 477 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
454 | return -EAGAIN; | 478 | return -EAGAIN; |
455 | 479 | ||
456 | switch (num) { | 480 | for (j = 0; j < num; j++) { |
457 | case 2: { /* read */ | 481 | switch (msg[j].addr) { |
458 | u8 ibuf[msg[1].len], obuf[3]; | ||
459 | obuf[0] = msg[1].len; | ||
460 | obuf[1] = (msg[0].addr << 1); | ||
461 | obuf[2] = msg[0].buf[0]; | ||
462 | |||
463 | ret = dw210x_op_rw(d->udev, 0x90, 0, 0, | ||
464 | obuf, 3, DW210X_WRITE_MSG); | ||
465 | msleep(5); | ||
466 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
467 | ibuf, msg[1].len, DW210X_READ_MSG); | ||
468 | memcpy(msg[1].buf, ibuf, msg[1].len); | ||
469 | break; | ||
470 | } | ||
471 | case 1: | ||
472 | switch (msg[0].addr) { | ||
473 | case 0x60: | ||
474 | case 0x0e: { | ||
475 | /* write to zl10313, zl10039 register, */ | ||
476 | u8 obuf[msg[0].len + 2]; | ||
477 | obuf[0] = msg[0].len + 1; | ||
478 | obuf[1] = (msg[0].addr << 1); | ||
479 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
480 | ret = dw210x_op_rw(d->udev, 0x80, 0, 0, | ||
481 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
482 | break; | ||
483 | } | ||
484 | case (DW2102_RC_QUERY): { | 482 | case (DW2102_RC_QUERY): { |
485 | u8 ibuf[4]; | 483 | u8 ibuf[4]; |
486 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | 484 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, |
487 | ibuf, 4, DW210X_READ_MSG); | 485 | ibuf, 4, DW210X_READ_MSG); |
488 | msg[0].buf[0] = ibuf[3]; | 486 | memcpy(msg[j].buf, ibuf + 1, 2); |
489 | break; | 487 | break; |
490 | } | 488 | } |
491 | case (DW2102_VOLTAGE_CTRL): { | 489 | case (DW2102_VOLTAGE_CTRL): { |
492 | u8 obuf[2]; | 490 | u8 obuf[2]; |
493 | obuf[0] = 0x03; | 491 | obuf[0] = 3; |
494 | obuf[1] = msg[0].buf[0]; | 492 | obuf[1] = msg[j].buf[0]; |
495 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | 493 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, |
496 | obuf, 2, DW210X_WRITE_MSG); | 494 | obuf, 2, DW210X_WRITE_MSG); |
497 | break; | 495 | break; |
498 | } | 496 | } |
497 | /*case 0x55: cx24116 | ||
498 | case 0x6a: stv0903 | ||
499 | case 0x68: ds3000, stv0903 | ||
500 | case 0x60: ts2020, stv6110, stb6100 | ||
501 | case 0xa0: eeprom */ | ||
502 | default: { | ||
503 | if (msg[j].flags == I2C_M_RD) { | ||
504 | /* read registers */ | ||
505 | u8 ibuf[msg[j].len]; | ||
506 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
507 | ibuf, msg[j].len, | ||
508 | DW210X_READ_MSG); | ||
509 | memcpy(msg[j].buf, ibuf, msg[j].len); | ||
510 | break; | ||
511 | } else if ((msg[j].buf[0] == 0xb0) && | ||
512 | (msg[j].addr == 0x68)) { | ||
513 | /* write firmware */ | ||
514 | u8 obuf[19]; | ||
515 | obuf[0] = (msg[j].len > 16 ? | ||
516 | 18 : msg[j].len + 1); | ||
517 | obuf[1] = msg[j].addr << 1; | ||
518 | obuf[2] = msg[j].buf[0]; | ||
519 | len = msg[j].len - 1; | ||
520 | i = 1; | ||
521 | do { | ||
522 | memcpy(obuf + 3, msg[j].buf + i, | ||
523 | (len > 16 ? 16 : len)); | ||
524 | ret = dw210x_op_rw(d->udev, 0x80, 0, 0, | ||
525 | obuf, (len > 16 ? 16 : len) + 3, | ||
526 | DW210X_WRITE_MSG); | ||
527 | i += 16; | ||
528 | len -= 16; | ||
529 | } while (len > 0); | ||
530 | } else { | ||
531 | /* write registers */ | ||
532 | u8 obuf[msg[j].len + 2]; | ||
533 | obuf[0] = msg[j].len + 1; | ||
534 | obuf[1] = (msg[j].addr << 1); | ||
535 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||
536 | ret = dw210x_op_rw(d->udev, | ||
537 | (num > 1 ? 0x90 : 0x80), 0, 0, | ||
538 | obuf, msg[j].len + 2, | ||
539 | DW210X_WRITE_MSG); | ||
540 | break; | ||
541 | } | ||
542 | break; | ||
543 | } | ||
499 | } | 544 | } |
500 | 545 | ||
501 | break; | 546 | msleep(3); |
502 | } | 547 | } |
503 | 548 | ||
504 | mutex_unlock(&d->i2c_mutex); | 549 | mutex_unlock(&d->i2c_mutex); |
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = { | |||
535 | .functionality = dw210x_i2c_func, | 580 | .functionality = dw210x_i2c_func, |
536 | }; | 581 | }; |
537 | 582 | ||
538 | static struct i2c_algorithm s630_i2c_algo = { | 583 | static struct i2c_algorithm s6x0_i2c_algo = { |
539 | .master_xfer = s630_i2c_transfer, | 584 | .master_xfer = s6x0_i2c_transfer, |
540 | .functionality = dw210x_i2c_func, | 585 | .functionality = dw210x_i2c_func, |
541 | }; | 586 | }; |
542 | 587 | ||
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
564 | return 0; | 609 | return 0; |
565 | }; | 610 | }; |
566 | 611 | ||
567 | static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 612 | static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
568 | { | 613 | { |
569 | int i, ret; | 614 | int i, ret; |
570 | u8 buf[3], eeprom[256], eepromline[16]; | 615 | u8 ibuf[] = { 0 }, obuf[] = { 0 }; |
616 | u8 eeprom[256], eepromline[16]; | ||
617 | struct i2c_msg msg[] = { | ||
618 | { | ||
619 | .addr = 0xa0 >> 1, | ||
620 | .flags = 0, | ||
621 | .buf = obuf, | ||
622 | .len = 1, | ||
623 | }, { | ||
624 | .addr = 0xa0 >> 1, | ||
625 | .flags = I2C_M_RD, | ||
626 | .buf = ibuf, | ||
627 | .len = 1, | ||
628 | } | ||
629 | }; | ||
571 | 630 | ||
572 | for (i = 0; i < 256; i++) { | 631 | for (i = 0; i < 256; i++) { |
573 | buf[0] = 1; | 632 | obuf[0] = i; |
574 | buf[1] = 0xa0; | 633 | ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); |
575 | buf[2] = i; | 634 | if (ret != 2) { |
576 | ret = dw210x_op_rw(d->udev, 0x90, 0, 0, | ||
577 | buf, 3, DW210X_WRITE_MSG); | ||
578 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
579 | buf, 1, DW210X_READ_MSG); | ||
580 | if (ret < 0) { | ||
581 | err("read eeprom failed."); | 635 | err("read eeprom failed."); |
582 | return -1; | 636 | return -1; |
583 | } else { | 637 | } else { |
584 | eepromline[i % 16] = buf[0]; | 638 | eepromline[i % 16] = ibuf[0]; |
585 | eeprom[i] = buf[0]; | 639 | eeprom[i] = ibuf[0]; |
586 | } | 640 | } |
587 | 641 | ||
588 | if ((i % 16) == 15) { | 642 | if ((i % 16) == 15) { |
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config = { | |||
644 | .demod_address = 0x0e, | 698 | .demod_address = 0x0e, |
645 | }; | 699 | }; |
646 | 700 | ||
701 | static struct ds3000_config dw2104_ds3000_config = { | ||
702 | .demod_address = 0x68, | ||
703 | }; | ||
704 | |||
705 | static struct stv0900_config dw2104a_stv0900_config = { | ||
706 | .demod_address = 0x6a, | ||
707 | .demod_mode = 0, | ||
708 | .xtal = 27000000, | ||
709 | .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ | ||
710 | .diseqc_mode = 2,/* 2/3 PWM */ | ||
711 | .tun1_maddress = 0,/* 0x60 */ | ||
712 | .tun1_adc = 0,/* 2 Vpp */ | ||
713 | .path1_mode = 3, | ||
714 | }; | ||
715 | |||
716 | static struct stb6100_config dw2104a_stb6100_config = { | ||
717 | .tuner_address = 0x60, | ||
718 | .refclock = 27000000, | ||
719 | }; | ||
720 | |||
721 | static struct stv0900_config dw2104_stv0900_config = { | ||
722 | .demod_address = 0x68, | ||
723 | .demod_mode = 0, | ||
724 | .xtal = 8000000, | ||
725 | .clkmode = 3, | ||
726 | .diseqc_mode = 2, | ||
727 | .tun1_maddress = 0, | ||
728 | .tun1_adc = 1,/* 1 Vpp */ | ||
729 | .path1_mode = 3, | ||
730 | }; | ||
731 | |||
732 | static struct stv6110_config dw2104_stv6110_config = { | ||
733 | .i2c_address = 0x60, | ||
734 | .mclk = 16000000, | ||
735 | .clk_div = 1, | ||
736 | }; | ||
737 | |||
647 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 738 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
648 | { | 739 | { |
649 | if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, | 740 | struct dvb_tuner_ops *tuner_ops = NULL; |
650 | &d->dev->i2c_adap)) != NULL) { | 741 | |
742 | if (demod_probe & 4) { | ||
743 | d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, | ||
744 | &d->dev->i2c_adap, 0); | ||
745 | if (d->fe != NULL) { | ||
746 | if (dvb_attach(stb6100_attach, d->fe, | ||
747 | &dw2104a_stb6100_config, | ||
748 | &d->dev->i2c_adap)) { | ||
749 | tuner_ops = &d->fe->ops.tuner_ops; | ||
750 | tuner_ops->set_frequency = stb6100_set_freq; | ||
751 | tuner_ops->get_frequency = stb6100_get_freq; | ||
752 | tuner_ops->set_bandwidth = stb6100_set_bandw; | ||
753 | tuner_ops->get_bandwidth = stb6100_get_bandw; | ||
754 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
755 | info("Attached STV0900+STB6100!\n"); | ||
756 | return 0; | ||
757 | } | ||
758 | } | ||
759 | } | ||
760 | |||
761 | if (demod_probe & 2) { | ||
762 | d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, | ||
763 | &d->dev->i2c_adap, 0); | ||
764 | if (d->fe != NULL) { | ||
765 | if (dvb_attach(stv6110_attach, d->fe, | ||
766 | &dw2104_stv6110_config, | ||
767 | &d->dev->i2c_adap)) { | ||
768 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
769 | info("Attached STV0900+STV6110A!\n"); | ||
770 | return 0; | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | if (demod_probe & 1) { | ||
776 | d->fe = dvb_attach(cx24116_attach, &dw2104_config, | ||
777 | &d->dev->i2c_adap); | ||
778 | if (d->fe != NULL) { | ||
779 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
780 | info("Attached cx24116!\n"); | ||
781 | return 0; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | ||
786 | &d->dev->i2c_adap); | ||
787 | if (d->fe != NULL) { | ||
651 | d->fe->ops.set_voltage = dw210x_set_voltage; | 788 | d->fe->ops.set_voltage = dw210x_set_voltage; |
652 | info("Attached cx24116!\n"); | 789 | info("Attached DS3000!\n"); |
653 | return 0; | 790 | return 0; |
654 | } | 791 | } |
792 | |||
655 | return -EIO; | 793 | return -EIO; |
656 | } | 794 | } |
657 | 795 | ||
658 | static struct dvb_usb_device_properties dw2102_properties; | 796 | static struct dvb_usb_device_properties dw2102_properties; |
659 | static struct dvb_usb_device_properties dw2104_properties; | 797 | static struct dvb_usb_device_properties dw2104_properties; |
798 | static struct dvb_usb_device_properties s6x0_properties; | ||
660 | 799 | ||
661 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 800 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) |
662 | { | 801 | { |
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | |||
670 | return 0; | 809 | return 0; |
671 | } | 810 | } |
672 | } | 811 | } |
812 | |||
673 | if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { | 813 | if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { |
674 | /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ | ||
675 | d->fe = dvb_attach(stv0288_attach, &earda_config, | 814 | d->fe = dvb_attach(stv0288_attach, &earda_config, |
676 | &d->dev->i2c_adap); | 815 | &d->dev->i2c_adap); |
677 | if (d->fe != NULL) { | 816 | if (d->fe != NULL) { |
678 | d->fe->ops.set_voltage = dw210x_set_voltage; | 817 | if (dvb_attach(stb6000_attach, d->fe, 0x61, |
679 | info("Attached stv0288!\n"); | 818 | &d->dev->i2c_adap)) { |
680 | return 0; | 819 | d->fe->ops.set_voltage = dw210x_set_voltage; |
820 | info("Attached stv0288!\n"); | ||
821 | return 0; | ||
822 | } | ||
681 | } | 823 | } |
682 | } | 824 | } |
683 | 825 | ||
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) | |||
705 | return -EIO; | 847 | return -EIO; |
706 | } | 848 | } |
707 | 849 | ||
708 | static int s630_frontend_attach(struct dvb_usb_adapter *d) | 850 | static int s6x0_frontend_attach(struct dvb_usb_adapter *d) |
709 | { | 851 | { |
710 | d->fe = dvb_attach(mt312_attach, &zl313_config, | 852 | d->fe = dvb_attach(mt312_attach, &zl313_config, |
711 | &d->dev->i2c_adap); | 853 | &d->dev->i2c_adap); |
854 | if (d->fe != NULL) { | ||
855 | if (dvb_attach(zl10039_attach, d->fe, 0x60, | ||
856 | &d->dev->i2c_adap)) { | ||
857 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
858 | info("Attached zl100313+zl10039!\n"); | ||
859 | return 0; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | d->fe = dvb_attach(stv0288_attach, &earda_config, | ||
864 | &d->dev->i2c_adap); | ||
865 | if (d->fe != NULL) { | ||
866 | if (dvb_attach(stb6000_attach, d->fe, 0x61, | ||
867 | &d->dev->i2c_adap)) { | ||
868 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
869 | info("Attached stv0288+stb6000!\n"); | ||
870 | return 0; | ||
871 | } | ||
872 | } | ||
873 | |||
874 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | ||
875 | &d->dev->i2c_adap); | ||
712 | if (d->fe != NULL) { | 876 | if (d->fe != NULL) { |
713 | d->fe->ops.set_voltage = dw210x_set_voltage; | 877 | d->fe->ops.set_voltage = dw210x_set_voltage; |
714 | info("Attached zl10313!\n"); | 878 | info("Attached ds3000+ds2020!\n"); |
715 | return 0; | 879 | return 0; |
716 | } | 880 | } |
881 | |||
717 | return -EIO; | 882 | return -EIO; |
718 | } | 883 | } |
719 | 884 | ||
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | |||
724 | return 0; | 889 | return 0; |
725 | } | 890 | } |
726 | 891 | ||
727 | static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) | ||
728 | { | ||
729 | dvb_attach(stb6000_attach, adap->fe, 0x61, | ||
730 | &adap->dev->i2c_adap); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | 892 | static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) |
736 | { | 893 | { |
737 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 894 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | |||
740 | return 0; | 897 | return 0; |
741 | } | 898 | } |
742 | 899 | ||
743 | static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap) | ||
744 | { | ||
745 | dvb_attach(zl10039_attach, adap->fe, 0x60, | ||
746 | &adap->dev->i2c_adap); | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { | 900 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { |
752 | { 0xf80a, KEY_Q }, /*power*/ | 901 | { 0xf80a, KEY_Q }, /*power*/ |
753 | { 0xf80c, KEY_M }, /*mute*/ | 902 | { 0xf80c, KEY_M }, /*mute*/ |
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = { | |||
922 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, | 1071 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, |
923 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, | 1072 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, |
924 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, | 1073 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, |
1074 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | ||
1075 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | ||
925 | { } | 1076 | { } |
926 | }; | 1077 | }; |
927 | 1078 | ||
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
935 | u8 reset; | 1086 | u8 reset; |
936 | u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; | 1087 | u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; |
937 | const struct firmware *fw; | 1088 | const struct firmware *fw; |
938 | const char *filename = "dvb-usb-dw2101.fw"; | 1089 | const char *fw_2101 = "dvb-usb-dw2101.fw"; |
939 | 1090 | ||
940 | switch (dev->descriptor.idProduct) { | 1091 | switch (dev->descriptor.idProduct) { |
941 | case 0x2101: | 1092 | case 0x2101: |
942 | ret = request_firmware(&fw, filename, &dev->dev); | 1093 | ret = request_firmware(&fw, fw_2101, &dev->dev); |
943 | if (ret != 0) { | 1094 | if (ret != 0) { |
944 | err("did not find the firmware file. (%s) " | 1095 | err(err_str, fw_2101); |
945 | "Please see linux/Documentation/dvb/ for more details " | ||
946 | "on firmware-problems.", filename); | ||
947 | return ret; | 1096 | return ret; |
948 | } | 1097 | } |
949 | break; | 1098 | break; |
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
983 | } | 1132 | } |
984 | /* init registers */ | 1133 | /* init registers */ |
985 | switch (dev->descriptor.idProduct) { | 1134 | switch (dev->descriptor.idProduct) { |
1135 | case USB_PID_PROF_1100: | ||
1136 | s6x0_properties.rc_key_map = tbs_rc_keys; | ||
1137 | s6x0_properties.rc_key_map_size = | ||
1138 | ARRAY_SIZE(tbs_rc_keys); | ||
1139 | break; | ||
986 | case USB_PID_TEVII_S650: | 1140 | case USB_PID_TEVII_S650: |
987 | dw2104_properties.rc_key_map = tevii_rc_keys; | 1141 | dw2104_properties.rc_key_map = tevii_rc_keys; |
988 | dw2104_properties.rc_key_map_size = | 1142 | dw2104_properties.rc_key_map_size = |
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
1021 | DW210X_READ_MSG); | 1175 | DW210X_READ_MSG); |
1022 | if (reset16[2] == 0x11) { | 1176 | if (reset16[2] == 0x11) { |
1023 | dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; | 1177 | dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; |
1024 | dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach; | ||
1025 | break; | 1178 | break; |
1026 | } | 1179 | } |
1027 | } | 1180 | } |
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = { | |||
1184 | } | 1337 | } |
1185 | }; | 1338 | }; |
1186 | 1339 | ||
1187 | static struct dvb_usb_device_properties s630_properties = { | 1340 | static struct dvb_usb_device_properties s6x0_properties = { |
1188 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1341 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1189 | .usb_ctrl = DEVICE_SPECIFIC, | 1342 | .usb_ctrl = DEVICE_SPECIFIC, |
1190 | .firmware = "dvb-usb-s630.fw", | 1343 | .firmware = "dvb-usb-s630.fw", |
1191 | .no_reconnect = 1, | 1344 | .no_reconnect = 1, |
1192 | 1345 | ||
1193 | .i2c_algo = &s630_i2c_algo, | 1346 | .i2c_algo = &s6x0_i2c_algo, |
1194 | .rc_key_map = tevii_rc_keys, | 1347 | .rc_key_map = tevii_rc_keys, |
1195 | .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), | 1348 | .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), |
1196 | .rc_interval = 150, | 1349 | .rc_interval = 150, |
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = { | |||
1199 | .generic_bulk_ctrl_endpoint = 0x81, | 1352 | .generic_bulk_ctrl_endpoint = 0x81, |
1200 | .num_adapters = 1, | 1353 | .num_adapters = 1, |
1201 | .download_firmware = dw2102_load_firmware, | 1354 | .download_firmware = dw2102_load_firmware, |
1202 | .read_mac_address = s630_read_mac_address, | 1355 | .read_mac_address = s6x0_read_mac_address, |
1203 | .adapter = { | 1356 | .adapter = { |
1204 | { | 1357 | { |
1205 | .frontend_attach = s630_frontend_attach, | 1358 | .frontend_attach = s6x0_frontend_attach, |
1206 | .streaming_ctrl = NULL, | 1359 | .streaming_ctrl = NULL, |
1207 | .tuner_attach = s630_zl10039_tuner_attach, | 1360 | .tuner_attach = NULL, |
1208 | .stream = { | 1361 | .stream = { |
1209 | .type = USB_BULK, | 1362 | .type = USB_BULK, |
1210 | .count = 8, | 1363 | .count = 8, |
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = { | |||
1217 | }, | 1370 | }, |
1218 | } | 1371 | } |
1219 | }, | 1372 | }, |
1220 | .num_device_descs = 1, | 1373 | .num_device_descs = 3, |
1221 | .devices = { | 1374 | .devices = { |
1222 | {"TeVii S630 USB", | 1375 | {"TeVii S630 USB", |
1223 | {&dw2102_table[6], NULL}, | 1376 | {&dw2102_table[6], NULL}, |
1224 | {NULL}, | 1377 | {NULL}, |
1225 | }, | 1378 | }, |
1379 | {"Prof 1100 USB ", | ||
1380 | {&dw2102_table[7], NULL}, | ||
1381 | {NULL}, | ||
1382 | }, | ||
1383 | {"TeVii S660 USB", | ||
1384 | {&dw2102_table[8], NULL}, | ||
1385 | {NULL}, | ||
1386 | }, | ||
1226 | } | 1387 | } |
1227 | }; | 1388 | }; |
1228 | 1389 | ||
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1235 | THIS_MODULE, NULL, adapter_nr) || | 1396 | THIS_MODULE, NULL, adapter_nr) || |
1236 | 0 == dvb_usb_device_init(intf, &dw3101_properties, | 1397 | 0 == dvb_usb_device_init(intf, &dw3101_properties, |
1237 | THIS_MODULE, NULL, adapter_nr) || | 1398 | THIS_MODULE, NULL, adapter_nr) || |
1238 | 0 == dvb_usb_device_init(intf, &s630_properties, | 1399 | 0 == dvb_usb_device_init(intf, &s6x0_properties, |
1239 | THIS_MODULE, NULL, adapter_nr)) { | 1400 | THIS_MODULE, NULL, adapter_nr)) |
1240 | return 0; | 1401 | return 0; |
1241 | } | 1402 | |
1242 | return -ENODEV; | 1403 | return -ENODEV; |
1243 | } | 1404 | } |
1244 | 1405 | ||
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit); | |||
1269 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1430 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
1270 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1431 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1271 | " DVB-C 3101 USB2.0," | 1432 | " DVB-C 3101 USB2.0," |
1272 | " TeVii S600, S630, S650 USB2.0 devices"); | 1433 | " TeVii S600, S630, S650, S660 USB2.0," |
1434 | " Prof 1100 USB2.0 devices"); | ||
1273 | MODULE_VERSION("0.1"); | 1435 | MODULE_VERSION("0.1"); |
1274 | MODULE_LICENSE("GPL"); | 1436 | MODULE_LICENSE("GPL"); |