diff options
| -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"); |
