diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 8 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/a800.c | 8 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 67 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_core.c | 47 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_devices.c | 1381 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/digitv.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 7 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 590 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/lmedm04.c | 235 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/opera1.c | 33 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/technisat-usb2.c | 807 |
16 files changed, 2877 insertions, 318 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3d48ba019342..fe4f894183ff 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -358,3 +358,11 @@ config DVB_USB_LME2510 | |||
358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE | 358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE |
359 | help | 359 | help |
360 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . | 360 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . |
361 | |||
362 | config DVB_USB_TECHNISAT_USB2 | ||
363 | tristate "Technisat DVB-S/S2 USB2.0 support" | ||
364 | depends on DVB_USB | ||
365 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
366 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
367 | help | ||
368 | Say Y here to support the Technisat USB2 DVB-S/S2 device | ||
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 5b1d12f2d591..4bac13da0c39 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o | |||
91 | dvb-usb-lmedm04-objs = lmedm04.o | 91 | dvb-usb-lmedm04-objs = lmedm04.o |
92 | obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o | 92 | obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o |
93 | 93 | ||
94 | dvb-usb-technisat-usb2-objs = technisat-usb2.o | ||
95 | obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o | ||
96 | |||
94 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 97 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
95 | # due to tuner-xc3028 | 98 | # due to tuner-xc3028 |
96 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 99 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index 53b93a4b6f8a..f8e9bf116f21 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c | |||
@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr | |||
38 | } | 38 | } |
39 | 39 | ||
40 | static struct rc_map_table rc_map_a800_table[] = { | 40 | static struct rc_map_table rc_map_a800_table[] = { |
41 | { 0x0201, KEY_PROG1 }, /* SOURCE */ | 41 | { 0x0201, KEY_MODE }, /* SOURCE */ |
42 | { 0x0200, KEY_POWER }, /* POWER */ | 42 | { 0x0200, KEY_POWER2 }, /* POWER */ |
43 | { 0x0205, KEY_1 }, /* 1 */ | 43 | { 0x0205, KEY_1 }, /* 1 */ |
44 | { 0x0206, KEY_2 }, /* 2 */ | 44 | { 0x0206, KEY_2 }, /* 2 */ |
45 | { 0x0207, KEY_3 }, /* 3 */ | 45 | { 0x0207, KEY_3 }, /* 3 */ |
@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = { | |||
52 | { 0x0212, KEY_LEFT }, /* L / DISPLAY */ | 52 | { 0x0212, KEY_LEFT }, /* L / DISPLAY */ |
53 | { 0x0211, KEY_0 }, /* 0 */ | 53 | { 0x0211, KEY_0 }, /* 0 */ |
54 | { 0x0213, KEY_RIGHT }, /* R / CH RTN */ | 54 | { 0x0213, KEY_RIGHT }, /* R / CH RTN */ |
55 | { 0x0217, KEY_PROG2 }, /* SNAP SHOT */ | 55 | { 0x0217, KEY_CAMERA }, /* SNAP SHOT */ |
56 | { 0x0210, KEY_PROG3 }, /* 16-CH PREV */ | 56 | { 0x0210, KEY_LAST }, /* 16-CH PREV */ |
57 | { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ | 57 | { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ |
58 | { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ | 58 | { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ |
59 | { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ | 59 | { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 8671ca362c81..100ebc37e99e 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -479,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) | |||
479 | ret = af9015_set_reg_bit(d, 0xd50b, 0); | 479 | ret = af9015_set_reg_bit(d, 0xd50b, 0); |
480 | else | 480 | else |
481 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); | 481 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); |
482 | |||
482 | error: | 483 | error: |
483 | if (ret) | 484 | if (ret) |
484 | err("endpoint init failed:%d", ret); | 485 | err("endpoint init failed:%d", ret); |
@@ -611,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d) | |||
611 | int ret; | 612 | int ret; |
612 | deb_info("%s:\n", __func__); | 613 | deb_info("%s:\n", __func__); |
613 | 614 | ||
615 | /* init RC canary */ | ||
616 | ret = af9015_write_reg(d, 0x98e9, 0xff); | ||
617 | if (ret) | ||
618 | goto error; | ||
619 | |||
614 | ret = af9015_init_endpoint(d); | 620 | ret = af9015_init_endpoint(d); |
615 | if (ret) | 621 | if (ret) |
616 | goto error; | 622 | goto error; |
@@ -659,9 +665,8 @@ error: | |||
659 | static int af9015_download_firmware(struct usb_device *udev, | 665 | static int af9015_download_firmware(struct usb_device *udev, |
660 | const struct firmware *fw) | 666 | const struct firmware *fw) |
661 | { | 667 | { |
662 | int i, len, packets, remainder, ret; | 668 | int i, len, remaining, ret; |
663 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; | 669 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; |
664 | u16 addr = 0x5100; /* firmware start address */ | ||
665 | u16 checksum = 0; | 670 | u16 checksum = 0; |
666 | 671 | ||
667 | deb_info("%s:\n", __func__); | 672 | deb_info("%s:\n", __func__); |
@@ -673,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev, | |||
673 | af9015_config.firmware_size = fw->size; | 678 | af9015_config.firmware_size = fw->size; |
674 | af9015_config.firmware_checksum = checksum; | 679 | af9015_config.firmware_checksum = checksum; |
675 | 680 | ||
676 | #define FW_PACKET_MAX_DATA 55 | 681 | #define FW_ADDR 0x5100 /* firmware start address */ |
677 | 682 | #define LEN_MAX 55 /* max packet size */ | |
678 | packets = fw->size / FW_PACKET_MAX_DATA; | 683 | for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { |
679 | remainder = fw->size % FW_PACKET_MAX_DATA; | 684 | len = remaining; |
680 | len = FW_PACKET_MAX_DATA; | 685 | if (len > LEN_MAX) |
681 | for (i = 0; i <= packets; i++) { | 686 | len = LEN_MAX; |
682 | if (i == packets) /* set size of the last packet */ | ||
683 | len = remainder; | ||
684 | 687 | ||
685 | req.data_len = len; | 688 | req.data_len = len; |
686 | req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); | 689 | req.data = (u8 *) &fw->data[fw->size - remaining]; |
687 | req.addr = addr; | 690 | req.addr = FW_ADDR + fw->size - remaining; |
688 | addr += FW_PACKET_MAX_DATA; | ||
689 | 691 | ||
690 | ret = af9015_rw_udev(udev, &req); | 692 | ret = af9015_rw_udev(udev, &req); |
691 | if (ret) { | 693 | if (ret) { |
692 | err("firmware download failed at packet %d with " \ | 694 | err("firmware download failed:%d", ret); |
693 | "code %d", i, ret); | ||
694 | goto error; | 695 | goto error; |
695 | } | 696 | } |
696 | } | 697 | } |
@@ -738,6 +739,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { | |||
738 | }; | 739 | }; |
739 | 740 | ||
740 | static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { | 741 | static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { |
742 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC, | ||
743 | RC_MAP_TERRATEC_SLIM_2 }, | ||
741 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, | 744 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, |
742 | RC_MAP_TERRATEC_SLIM }, | 745 | RC_MAP_TERRATEC_SLIM }, |
743 | { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, | 746 | { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, |
@@ -1016,22 +1019,38 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1016 | { | 1019 | { |
1017 | struct af9015_state *priv = d->priv; | 1020 | struct af9015_state *priv = d->priv; |
1018 | int ret; | 1021 | int ret; |
1019 | u8 buf[16]; | 1022 | u8 buf[17]; |
1020 | 1023 | ||
1021 | /* read registers needed to detect remote controller code */ | 1024 | /* read registers needed to detect remote controller code */ |
1022 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | 1025 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); |
1023 | if (ret) | 1026 | if (ret) |
1024 | goto error; | 1027 | goto error; |
1025 | 1028 | ||
1026 | if (buf[14] || buf[15]) { | 1029 | /* If any of these are non-zero, assume invalid data */ |
1030 | if (buf[1] || buf[2] || buf[3]) | ||
1031 | return ret; | ||
1032 | |||
1033 | /* Check for repeat of previous code */ | ||
1034 | if ((priv->rc_repeat != buf[6] || buf[0]) && | ||
1035 | !memcmp(&buf[12], priv->rc_last, 4)) { | ||
1036 | deb_rc("%s: key repeated\n", __func__); | ||
1037 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1038 | priv->rc_repeat = buf[6]; | ||
1039 | return ret; | ||
1040 | } | ||
1041 | |||
1042 | /* Only process key if canary killed */ | ||
1043 | if (buf[16] != 0xff && buf[0] != 0x01) { | ||
1027 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, | 1044 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1028 | buf[12], buf[13], buf[14], buf[15]); | 1045 | buf[12], buf[13], buf[14], buf[15]); |
1029 | 1046 | ||
1030 | /* clean IR code from mem */ | 1047 | /* Reset the canary */ |
1031 | ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); | 1048 | ret = af9015_write_reg(d, 0x98e9, 0xff); |
1032 | if (ret) | 1049 | if (ret) |
1033 | goto error; | 1050 | goto error; |
1034 | 1051 | ||
1052 | /* Remember this key */ | ||
1053 | memcpy(priv->rc_last, &buf[12], 4); | ||
1035 | if (buf[14] == (u8) ~buf[15]) { | 1054 | if (buf[14] == (u8) ~buf[15]) { |
1036 | if (buf[12] == (u8) ~buf[13]) { | 1055 | if (buf[12] == (u8) ~buf[13]) { |
1037 | /* NEC */ | 1056 | /* NEC */ |
@@ -1041,15 +1060,17 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1041 | priv->rc_keycode = buf[12] << 16 | | 1060 | priv->rc_keycode = buf[12] << 16 | |
1042 | buf[13] << 8 | buf[14]; | 1061 | buf[13] << 8 | buf[14]; |
1043 | } | 1062 | } |
1044 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1045 | } else { | 1063 | } else { |
1046 | priv->rc_keycode = 0; /* clear just for sure */ | 1064 | /* 32 bit NEC */ |
1065 | priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | | ||
1066 | buf[14] << 8 | buf[15]; | ||
1047 | } | 1067 | } |
1048 | } else if (priv->rc_repeat != buf[6] || buf[0]) { | ||
1049 | deb_rc("%s: key repeated\n", __func__); | ||
1050 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | 1068 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); |
1051 | } else { | 1069 | } else { |
1052 | deb_rc("%s: no key press\n", __func__); | 1070 | deb_rc("%s: no key press\n", __func__); |
1071 | /* Invalidate last keypress */ | ||
1072 | /* Not really needed, but helps with debug */ | ||
1073 | priv->rc_last[2] = priv->rc_last[3]; | ||
1053 | } | 1074 | } |
1054 | 1075 | ||
1055 | priv->rc_repeat = buf[6]; | 1076 | priv->rc_repeat = buf[6]; |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index f20cfa6ed690..beb3004f00ba 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
@@ -102,6 +102,7 @@ struct af9015_state { | |||
102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ | 102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ |
103 | u8 rc_repeat; | 103 | u8 rc_repeat; |
104 | u32 rc_keycode; | 104 | u32 rc_keycode; |
105 | u8 rc_last[4]; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct af9015_config { | 108 | struct af9015_config { |
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 3537d65c04bc..b2a87f2c2c3e 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug; | |||
32 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) | 32 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) |
33 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) | 33 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) |
34 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) | 34 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) |
35 | #define REQUEST_SET_I2C_PARAM 0x10 | ||
35 | #define REQUEST_SET_RC 0x11 | 36 | #define REQUEST_SET_RC 0x11 |
36 | #define REQUEST_NEW_I2C_READ 0x12 | 37 | #define REQUEST_NEW_I2C_READ 0x12 |
37 | #define REQUEST_NEW_I2C_WRITE 0x13 | 38 | #define REQUEST_NEW_I2C_WRITE 0x13 |
@@ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo; | |||
61 | extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | 62 | extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, |
62 | struct dvb_usb_device_description **desc, int *cold); | 63 | struct dvb_usb_device_description **desc, int *cold); |
63 | extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); | 64 | extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); |
65 | extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz); | ||
64 | 66 | ||
65 | extern int dib0700_device_count; | 67 | extern int dib0700_device_count; |
66 | extern int dvb_usb_dib0700_ir_proto; | 68 | extern int dvb_usb_dib0700_ir_proto; |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 98ffb40728e3..b79af68c54ae 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
186 | msg[i].len, | 186 | msg[i].len, |
187 | USB_CTRL_GET_TIMEOUT); | 187 | USB_CTRL_GET_TIMEOUT); |
188 | if (result < 0) { | 188 | if (result < 0) { |
189 | err("i2c read error (status = %d)\n", result); | 189 | deb_info("i2c read error (status = %d)\n", result); |
190 | break; | 190 | break; |
191 | } | 191 | } |
192 | 192 | ||
@@ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
215 | 0, 0, buf, msg[i].len + 4, | 215 | 0, 0, buf, msg[i].len + 4, |
216 | USB_CTRL_GET_TIMEOUT); | 216 | USB_CTRL_GET_TIMEOUT); |
217 | if (result < 0) { | 217 | if (result < 0) { |
218 | err("i2c write error (status = %d)\n", result); | 218 | deb_info("i2c write error (status = %d)\n", result); |
219 | break; | 219 | break; |
220 | } | 220 | } |
221 | } | 221 | } |
@@ -328,6 +328,31 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, | |||
328 | return dib0700_ctrl_wr(d, b, 10); | 328 | return dib0700_ctrl_wr(d, b, 10); |
329 | } | 329 | } |
330 | 330 | ||
331 | int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) | ||
332 | { | ||
333 | u16 divider; | ||
334 | u8 b[8]; | ||
335 | |||
336 | if (scl_kHz == 0) | ||
337 | return -EINVAL; | ||
338 | |||
339 | b[0] = REQUEST_SET_I2C_PARAM; | ||
340 | divider = (u16) (30000 / scl_kHz); | ||
341 | b[2] = (u8) (divider >> 8); | ||
342 | b[3] = (u8) (divider & 0xff); | ||
343 | divider = (u16) (72000 / scl_kHz); | ||
344 | b[4] = (u8) (divider >> 8); | ||
345 | b[5] = (u8) (divider & 0xff); | ||
346 | divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ | ||
347 | b[6] = (u8) (divider >> 8); | ||
348 | b[7] = (u8) (divider & 0xff); | ||
349 | |||
350 | deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", | ||
351 | (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); | ||
352 | return dib0700_ctrl_wr(d, b, 8); | ||
353 | } | ||
354 | |||
355 | |||
331 | int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) | 356 | int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) |
332 | { | 357 | { |
333 | switch (clk_MHz) { | 358 | switch (clk_MHz) { |
@@ -459,10 +484,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
459 | 484 | ||
460 | deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); | 485 | deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); |
461 | 486 | ||
462 | if (onoff) | 487 | st->channel_state &= ~0x3; |
463 | st->channel_state |= 1 << adap->id; | 488 | if ((adap->stream.props.endpoint != 2) |
464 | else | 489 | && (adap->stream.props.endpoint != 3)) { |
465 | st->channel_state &= ~(1 << adap->id); | 490 | deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint); |
491 | if (onoff) | ||
492 | st->channel_state |= 1 << (adap->id); | ||
493 | else | ||
494 | st->channel_state |= 1 << ~(adap->id); | ||
495 | } else { | ||
496 | if (onoff) | ||
497 | st->channel_state |= 1 << (adap->stream.props.endpoint-2); | ||
498 | else | ||
499 | st->channel_state |= 1 << (3-adap->stream.props.endpoint); | ||
500 | } | ||
466 | 501 | ||
467 | b[2] |= st->channel_state; | 502 | b[2] |= st->channel_state; |
468 | 503 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 193cdb77b76a..97af266d7f1d 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "dib7000m.h" | 12 | #include "dib7000m.h" |
13 | #include "dib7000p.h" | 13 | #include "dib7000p.h" |
14 | #include "dib8000.h" | 14 | #include "dib8000.h" |
15 | #include "dib9000.h" | ||
15 | #include "mt2060.h" | 16 | #include "mt2060.h" |
16 | #include "mt2266.h" | 17 | #include "mt2266.h" |
17 | #include "tuner-xc2028.h" | 18 | #include "tuner-xc2028.h" |
@@ -29,6 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif | |||
29 | 30 | ||
30 | struct dib0700_adapter_state { | 31 | struct dib0700_adapter_state { |
31 | int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); | 32 | int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); |
33 | const struct firmware *frontend_firmware; | ||
32 | }; | 34 | }; |
33 | 35 | ||
34 | /* Hauppauge Nova-T 500 (aka Bristol) | 36 | /* Hauppauge Nova-T 500 (aka Bristol) |
@@ -1243,13 +1245,13 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) | |||
1243 | static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, | 1245 | static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, |
1244 | u16 pid, int onoff) | 1246 | u16 pid, int onoff) |
1245 | { | 1247 | { |
1246 | return dib8000_pid_filter(adapter->fe, index, pid, onoff); | 1248 | return dib8000_pid_filter(adapter->fe, index, pid, onoff); |
1247 | } | 1249 | } |
1248 | 1250 | ||
1249 | static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, | 1251 | static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, |
1250 | int onoff) | 1252 | int onoff) |
1251 | { | 1253 | { |
1252 | return dib8000_pid_filter_ctrl(adapter->fe, onoff); | 1254 | return dib8000_pid_filter_ctrl(adapter->fe, onoff); |
1253 | } | 1255 | } |
1254 | 1256 | ||
1255 | /* STK807x */ | 1257 | /* STK807x */ |
@@ -1321,11 +1323,11 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) | |||
1321 | 1323 | ||
1322 | /* STK8096GP */ | 1324 | /* STK8096GP */ |
1323 | struct dibx000_agc_config dib8090_agc_config[2] = { | 1325 | struct dibx000_agc_config dib8090_agc_config[2] = { |
1324 | { | 1326 | { |
1325 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | 1327 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, |
1326 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, | 1328 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, |
1327 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | 1329 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, |
1328 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | 1330 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ |
1329 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | 1331 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
1330 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | 1332 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), |
1331 | 1333 | ||
@@ -1362,12 +1364,12 @@ struct dibx000_agc_config dib8090_agc_config[2] = { | |||
1362 | 51, | 1364 | 51, |
1363 | 1365 | ||
1364 | 0, | 1366 | 0, |
1365 | }, | 1367 | }, |
1366 | { | 1368 | { |
1367 | BAND_CBAND, | 1369 | BAND_CBAND, |
1368 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, | 1370 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, |
1369 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | 1371 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, |
1370 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | 1372 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ |
1371 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | 1373 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
1372 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | 1374 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), |
1373 | 1375 | ||
@@ -1404,135 +1406,153 @@ struct dibx000_agc_config dib8090_agc_config[2] = { | |||
1404 | 51, | 1406 | 51, |
1405 | 1407 | ||
1406 | 0, | 1408 | 0, |
1407 | } | 1409 | } |
1408 | }; | 1410 | }; |
1409 | 1411 | ||
1410 | static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { | 1412 | static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { |
1411 | 54000, 13500, | 1413 | 54000, 13500, |
1412 | 1, 18, 3, 1, 0, | 1414 | 1, 18, 3, 1, 0, |
1413 | 0, 0, 1, 1, 2, | 1415 | 0, 0, 1, 1, 2, |
1414 | (3 << 14) | (1 << 12) | (599 << 0), | 1416 | (3 << 14) | (1 << 12) | (599 << 0), |
1415 | (0 << 25) | 0, | 1417 | (0 << 25) | 0, |
1416 | 20199727, | 1418 | 20199727, |
1417 | 12000000, | 1419 | 12000000, |
1418 | }; | 1420 | }; |
1419 | 1421 | ||
1420 | static int dib8090_get_adc_power(struct dvb_frontend *fe) | 1422 | static int dib8090_get_adc_power(struct dvb_frontend *fe) |
1421 | { | 1423 | { |
1422 | return dib8000_get_adc_power(fe, 1); | 1424 | return dib8000_get_adc_power(fe, 1); |
1423 | } | 1425 | } |
1424 | 1426 | ||
1425 | static struct dib8000_config dib809x_dib8000_config = { | 1427 | static struct dib8000_config dib809x_dib8000_config[2] = { |
1426 | .output_mpeg2_in_188_bytes = 1, | 1428 | { |
1427 | 1429 | .output_mpeg2_in_188_bytes = 1, | |
1428 | .agc_config_count = 2, | 1430 | |
1429 | .agc = dib8090_agc_config, | 1431 | .agc_config_count = 2, |
1430 | .agc_control = dib0090_dcc_freq, | 1432 | .agc = dib8090_agc_config, |
1431 | .pll = &dib8090_pll_config_12mhz, | 1433 | .agc_control = dib0090_dcc_freq, |
1432 | .tuner_is_baseband = 1, | 1434 | .pll = &dib8090_pll_config_12mhz, |
1433 | 1435 | .tuner_is_baseband = 1, | |
1434 | .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, | 1436 | |
1435 | .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, | 1437 | .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, |
1436 | .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, | 1438 | .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, |
1437 | 1439 | .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, | |
1438 | .hostbus_diversity = 1, | 1440 | |
1439 | .div_cfg = 0x31, | 1441 | .hostbus_diversity = 1, |
1440 | .output_mode = OUTMODE_MPEG2_FIFO, | 1442 | .div_cfg = 0x31, |
1441 | .drives = 0x2d98, | 1443 | .output_mode = OUTMODE_MPEG2_FIFO, |
1442 | .diversity_delay = 144, | 1444 | .drives = 0x2d98, |
1443 | .refclksel = 3, | 1445 | .diversity_delay = 48, |
1446 | .refclksel = 3, | ||
1447 | }, { | ||
1448 | .output_mpeg2_in_188_bytes = 1, | ||
1449 | |||
1450 | .agc_config_count = 2, | ||
1451 | .agc = dib8090_agc_config, | ||
1452 | .agc_control = dib0090_dcc_freq, | ||
1453 | .pll = &dib8090_pll_config_12mhz, | ||
1454 | .tuner_is_baseband = 1, | ||
1455 | |||
1456 | .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, | ||
1457 | .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, | ||
1458 | .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, | ||
1459 | |||
1460 | .hostbus_diversity = 1, | ||
1461 | .div_cfg = 0x31, | ||
1462 | .output_mode = OUTMODE_DIVERSITY, | ||
1463 | .drives = 0x2d08, | ||
1464 | .diversity_delay = 1, | ||
1465 | .refclksel = 3, | ||
1466 | } | ||
1467 | }; | ||
1468 | |||
1469 | static struct dib0090_wbd_slope dib8090_wbd_table[] = { | ||
1470 | /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */ | ||
1471 | { 120, 0, 500, 0, 500, 4 }, /* CBAND */ | ||
1472 | { 170, 0, 450, 0, 450, 4 }, /* CBAND */ | ||
1473 | { 380, 48, 373, 28, 259, 6 }, /* VHF */ | ||
1474 | { 860, 34, 700, 36, 616, 6 }, /* high UHF */ | ||
1475 | { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */ | ||
1444 | }; | 1476 | }; |
1445 | 1477 | ||
1446 | static struct dib0090_config dib809x_dib0090_config = { | 1478 | static struct dib0090_config dib809x_dib0090_config = { |
1447 | .io.pll_bypass = 1, | 1479 | .io.pll_bypass = 1, |
1448 | .io.pll_range = 1, | 1480 | .io.pll_range = 1, |
1449 | .io.pll_prediv = 1, | 1481 | .io.pll_prediv = 1, |
1450 | .io.pll_loopdiv = 20, | 1482 | .io.pll_loopdiv = 20, |
1451 | .io.adc_clock_ratio = 8, | 1483 | .io.adc_clock_ratio = 8, |
1452 | .io.pll_int_loop_filt = 0, | 1484 | .io.pll_int_loop_filt = 0, |
1453 | .io.clock_khz = 12000, | 1485 | .io.clock_khz = 12000, |
1454 | .reset = dib80xx_tuner_reset, | 1486 | .reset = dib80xx_tuner_reset, |
1455 | .sleep = dib80xx_tuner_sleep, | 1487 | .sleep = dib80xx_tuner_sleep, |
1456 | .clkouttobamse = 1, | 1488 | .clkouttobamse = 1, |
1457 | .analog_output = 1, | 1489 | .analog_output = 1, |
1458 | .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, | 1490 | .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, |
1459 | .wbd_vhf_offset = 100, | 1491 | .use_pwm_agc = 1, |
1460 | .wbd_cband_offset = 450, | 1492 | .clkoutdrive = 1, |
1461 | .use_pwm_agc = 1, | 1493 | .get_adc_power = dib8090_get_adc_power, |
1462 | .clkoutdrive = 1, | 1494 | .freq_offset_khz_uhf = -63, |
1463 | .get_adc_power = dib8090_get_adc_power, | ||
1464 | .freq_offset_khz_uhf = 0, | ||
1465 | .freq_offset_khz_vhf = -143, | 1495 | .freq_offset_khz_vhf = -143, |
1496 | .wbd = dib8090_wbd_table, | ||
1497 | .fref_clock_ratio = 6, | ||
1466 | }; | 1498 | }; |
1467 | 1499 | ||
1468 | static int dib8096_set_param_override(struct dvb_frontend *fe, | 1500 | static int dib8096_set_param_override(struct dvb_frontend *fe, |
1469 | struct dvb_frontend_parameters *fep) | 1501 | struct dvb_frontend_parameters *fep) |
1470 | { | 1502 | { |
1471 | struct dvb_usb_adapter *adap = fe->dvb->priv; | 1503 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
1472 | struct dib0700_adapter_state *state = adap->priv; | 1504 | struct dib0700_adapter_state *state = adap->priv; |
1473 | u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); | 1505 | u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); |
1474 | u16 offset; | 1506 | u16 target; |
1475 | int ret = 0; | 1507 | int ret = 0; |
1476 | enum frontend_tune_state tune_state = CT_SHUTDOWN; | 1508 | enum frontend_tune_state tune_state = CT_SHUTDOWN; |
1477 | u16 ltgain, rf_gain_limit; | 1509 | u16 ltgain, rf_gain_limit; |
1478 | 1510 | ||
1479 | ret = state->set_param_save(fe, fep); | 1511 | ret = state->set_param_save(fe, fep); |
1480 | if (ret < 0) | 1512 | if (ret < 0) |
1481 | return ret; | 1513 | return ret; |
1482 | 1514 | ||
1483 | switch (band) { | 1515 | target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; |
1484 | case BAND_VHF: | 1516 | dib8000_set_wbd_ref(fe, target); |
1485 | offset = 100; | 1517 | |
1486 | break; | 1518 | |
1487 | case BAND_UHF: | 1519 | if (band == BAND_CBAND) { |
1488 | offset = 550; | 1520 | deb_info("tuning in CBAND - soft-AGC startup\n"); |
1489 | break; | 1521 | dib0090_set_tune_state(fe, CT_AGC_START); |
1490 | default: | 1522 | do { |
1491 | offset = 0; | 1523 | ret = dib0090_gain_control(fe); |
1492 | break; | 1524 | msleep(ret); |
1493 | } | 1525 | tune_state = dib0090_get_tune_state(fe); |
1494 | offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; | 1526 | if (tune_state == CT_AGC_STEP_0) |
1495 | dib8000_set_wbd_ref(fe, offset); | 1527 | dib8000_set_gpio(fe, 6, 0, 1); |
1496 | 1528 | else if (tune_state == CT_AGC_STEP_1) { | |
1497 | 1529 | dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); | |
1498 | if (band == BAND_CBAND) { | 1530 | if (rf_gain_limit == 0) |
1499 | deb_info("tuning in CBAND - soft-AGC startup\n"); | 1531 | dib8000_set_gpio(fe, 6, 0, 0); |
1500 | /* TODO specific wbd target for dib0090 - needed for startup ? */ | 1532 | } |
1501 | dib0090_set_tune_state(fe, CT_AGC_START); | 1533 | } while (tune_state < CT_AGC_STOP); |
1502 | do { | 1534 | dib0090_pwm_gain_reset(fe); |
1503 | ret = dib0090_gain_control(fe); | 1535 | dib8000_pwm_agc_reset(fe); |
1504 | msleep(ret); | 1536 | dib8000_set_tune_state(fe, CT_DEMOD_START); |
1505 | tune_state = dib0090_get_tune_state(fe); | 1537 | } else { |
1506 | if (tune_state == CT_AGC_STEP_0) | 1538 | deb_info("not tuning in CBAND - standard AGC startup\n"); |
1507 | dib8000_set_gpio(fe, 6, 0, 1); | 1539 | dib0090_pwm_gain_reset(fe); |
1508 | else if (tune_state == CT_AGC_STEP_1) { | 1540 | } |
1509 | dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); | ||
1510 | if (rf_gain_limit == 0) | ||
1511 | dib8000_set_gpio(fe, 6, 0, 0); | ||
1512 | } | ||
1513 | } while (tune_state < CT_AGC_STOP); | ||
1514 | dib0090_pwm_gain_reset(fe); | ||
1515 | dib8000_pwm_agc_reset(fe); | ||
1516 | dib8000_set_tune_state(fe, CT_DEMOD_START); | ||
1517 | } else { | ||
1518 | deb_info("not tuning in CBAND - standard AGC startup\n"); | ||
1519 | dib0090_pwm_gain_reset(fe); | ||
1520 | } | ||
1521 | 1541 | ||
1522 | return 0; | 1542 | return 0; |
1523 | } | 1543 | } |
1524 | 1544 | ||
1525 | static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) | 1545 | static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) |
1526 | { | 1546 | { |
1527 | struct dib0700_adapter_state *st = adap->priv; | 1547 | struct dib0700_adapter_state *st = adap->priv; |
1528 | struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | 1548 | struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); |
1529 | 1549 | ||
1530 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) | 1550 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) |
1531 | return -ENODEV; | 1551 | return -ENODEV; |
1532 | 1552 | ||
1533 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | 1553 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; |
1534 | adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; | 1554 | adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; |
1535 | return 0; | 1555 | return 0; |
1536 | } | 1556 | } |
1537 | 1557 | ||
1538 | static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) | 1558 | static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) |
@@ -1554,11 +1574,931 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) | |||
1554 | 1574 | ||
1555 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); | 1575 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); |
1556 | 1576 | ||
1557 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); | 1577 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); |
1578 | |||
1579 | return adap->fe == NULL ? -ENODEV : 0; | ||
1580 | } | ||
1581 | |||
1582 | static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap) | ||
1583 | { | ||
1584 | struct dib0700_adapter_state *st = adap->priv; | ||
1585 | struct i2c_adapter *tun_i2c; | ||
1586 | struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1); | ||
1587 | |||
1588 | if (fe_slave) { | ||
1589 | tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); | ||
1590 | if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL) | ||
1591 | return -ENODEV; | ||
1592 | fe_slave->dvb = adap->fe->dvb; | ||
1593 | fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override; | ||
1594 | } | ||
1595 | tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | ||
1596 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) | ||
1597 | return -ENODEV; | ||
1598 | |||
1599 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | ||
1600 | adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; | ||
1601 | |||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1605 | static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) | ||
1606 | { | ||
1607 | struct dvb_frontend *fe_slave; | ||
1608 | |||
1609 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); | ||
1610 | msleep(20); | ||
1611 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
1612 | msleep(1000); | ||
1613 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
1614 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
1615 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
1616 | |||
1617 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
1618 | |||
1619 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
1620 | |||
1621 | msleep(20); | ||
1622 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
1623 | msleep(20); | ||
1624 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
1625 | |||
1626 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); | ||
1627 | |||
1628 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); | ||
1629 | if (adap->fe == NULL) | ||
1630 | return -ENODEV; | ||
1631 | |||
1632 | fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); | ||
1633 | dib8000_set_slave_frontend(adap->fe, fe_slave); | ||
1634 | |||
1635 | return fe_slave == NULL ? -ENODEV : 0; | ||
1636 | } | ||
1637 | |||
1638 | /* STK9090M */ | ||
1639 | static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) | ||
1640 | { | ||
1641 | return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff); | ||
1642 | } | ||
1643 | |||
1644 | static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) | ||
1645 | { | ||
1646 | return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff); | ||
1647 | } | ||
1648 | |||
1649 | static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff) | ||
1650 | { | ||
1651 | return dib9000_set_gpio(fe, 5, 0, !onoff); | ||
1652 | } | ||
1653 | |||
1654 | static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
1655 | { | ||
1656 | return dib9000_set_gpio(fe, 0, 0, onoff); | ||
1657 | } | ||
1658 | |||
1659 | static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len) | ||
1660 | { | ||
1661 | u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 }; | ||
1662 | u8 rb[2]; | ||
1663 | struct i2c_msg msg[2] = { | ||
1664 | {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2}, | ||
1665 | {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, | ||
1666 | }; | ||
1667 | u8 index_data; | ||
1668 | |||
1669 | dibx000_i2c_set_speed(i2c, 250); | ||
1670 | |||
1671 | if (i2c_transfer(i2c, msg, 2) != 2) | ||
1672 | return -EIO; | ||
1673 | |||
1674 | switch (rb[0] << 8 | rb[1]) { | ||
1675 | case 0: | ||
1676 | deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n"); | ||
1677 | return -EIO; | ||
1678 | case 1: | ||
1679 | deb_info("Found DiB0170 rev2"); | ||
1680 | break; | ||
1681 | case 2: | ||
1682 | deb_info("Found DiB0190 rev2"); | ||
1683 | break; | ||
1684 | default: | ||
1685 | deb_info("DiB01x0 not found"); | ||
1686 | return -EIO; | ||
1687 | } | ||
1688 | |||
1689 | for (index_data = 0; index_data < len; index_data += 2) { | ||
1690 | wb[2] = (data[index_data + 1] >> 8) & 0xff; | ||
1691 | wb[3] = (data[index_data + 1]) & 0xff; | ||
1692 | |||
1693 | if (data[index_data] == 0) { | ||
1694 | wb[0] = (data[index_data] >> 8) & 0xff; | ||
1695 | wb[1] = (data[index_data]) & 0xff; | ||
1696 | msg[0].len = 2; | ||
1697 | if (i2c_transfer(i2c, msg, 2) != 2) | ||
1698 | return -EIO; | ||
1699 | wb[2] |= rb[0]; | ||
1700 | wb[3] |= rb[1] & ~(3 << 4); | ||
1701 | } | ||
1702 | |||
1703 | wb[0] = (data[index_data] >> 8)&0xff; | ||
1704 | wb[1] = (data[index_data])&0xff; | ||
1705 | msg[0].len = 4; | ||
1706 | if (i2c_transfer(i2c, &msg[0], 1) != 1) | ||
1707 | return -EIO; | ||
1708 | } | ||
1709 | return 0; | ||
1710 | } | ||
1711 | |||
1712 | static struct dib9000_config stk9090m_config = { | ||
1713 | .output_mpeg2_in_188_bytes = 1, | ||
1714 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
1715 | .vcxo_timer = 279620, | ||
1716 | .timing_frequency = 20452225, | ||
1717 | .demod_clock_khz = 60000, | ||
1718 | .xtal_clock_khz = 30000, | ||
1719 | .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), | ||
1720 | .subband = { | ||
1721 | 2, | ||
1722 | { | ||
1723 | { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */ | ||
1724 | { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */ | ||
1725 | { 0 }, | ||
1726 | }, | ||
1727 | }, | ||
1728 | .gpio_function = { | ||
1729 | { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 }, | ||
1730 | { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 }, | ||
1731 | }, | ||
1732 | }; | ||
1733 | |||
1734 | static struct dib9000_config nim9090md_config[2] = { | ||
1735 | { | ||
1736 | .output_mpeg2_in_188_bytes = 1, | ||
1737 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
1738 | .vcxo_timer = 279620, | ||
1739 | .timing_frequency = 20452225, | ||
1740 | .demod_clock_khz = 60000, | ||
1741 | .xtal_clock_khz = 30000, | ||
1742 | .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), | ||
1743 | }, { | ||
1744 | .output_mpeg2_in_188_bytes = 1, | ||
1745 | .output_mode = OUTMODE_DIVERSITY, | ||
1746 | .vcxo_timer = 279620, | ||
1747 | .timing_frequency = 20452225, | ||
1748 | .demod_clock_khz = 60000, | ||
1749 | .xtal_clock_khz = 30000, | ||
1750 | .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0), | ||
1751 | .subband = { | ||
1752 | 2, | ||
1753 | { | ||
1754 | { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */ | ||
1755 | { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */ | ||
1756 | { 0 }, | ||
1757 | }, | ||
1758 | }, | ||
1759 | .gpio_function = { | ||
1760 | { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 }, | ||
1761 | { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 }, | ||
1762 | }, | ||
1763 | } | ||
1764 | }; | ||
1765 | |||
1766 | static struct dib0090_config dib9090_dib0090_config = { | ||
1767 | .io.pll_bypass = 0, | ||
1768 | .io.pll_range = 1, | ||
1769 | .io.pll_prediv = 1, | ||
1770 | .io.pll_loopdiv = 8, | ||
1771 | .io.adc_clock_ratio = 8, | ||
1772 | .io.pll_int_loop_filt = 0, | ||
1773 | .io.clock_khz = 30000, | ||
1774 | .reset = dib90x0_tuner_reset, | ||
1775 | .sleep = dib90x0_tuner_sleep, | ||
1776 | .clkouttobamse = 0, | ||
1777 | .analog_output = 0, | ||
1778 | .use_pwm_agc = 0, | ||
1779 | .clkoutdrive = 0, | ||
1780 | .freq_offset_khz_uhf = 0, | ||
1781 | .freq_offset_khz_vhf = 0, | ||
1782 | }; | ||
1783 | |||
1784 | static struct dib0090_config nim9090md_dib0090_config[2] = { | ||
1785 | { | ||
1786 | .io.pll_bypass = 0, | ||
1787 | .io.pll_range = 1, | ||
1788 | .io.pll_prediv = 1, | ||
1789 | .io.pll_loopdiv = 8, | ||
1790 | .io.adc_clock_ratio = 8, | ||
1791 | .io.pll_int_loop_filt = 0, | ||
1792 | .io.clock_khz = 30000, | ||
1793 | .reset = dib90x0_tuner_reset, | ||
1794 | .sleep = dib90x0_tuner_sleep, | ||
1795 | .clkouttobamse = 1, | ||
1796 | .analog_output = 0, | ||
1797 | .use_pwm_agc = 0, | ||
1798 | .clkoutdrive = 0, | ||
1799 | .freq_offset_khz_uhf = 0, | ||
1800 | .freq_offset_khz_vhf = 0, | ||
1801 | }, { | ||
1802 | .io.pll_bypass = 0, | ||
1803 | .io.pll_range = 1, | ||
1804 | .io.pll_prediv = 1, | ||
1805 | .io.pll_loopdiv = 8, | ||
1806 | .io.adc_clock_ratio = 8, | ||
1807 | .io.pll_int_loop_filt = 0, | ||
1808 | .io.clock_khz = 30000, | ||
1809 | .reset = dib90x0_tuner_reset, | ||
1810 | .sleep = dib90x0_tuner_sleep, | ||
1811 | .clkouttobamse = 0, | ||
1812 | .analog_output = 0, | ||
1813 | .use_pwm_agc = 0, | ||
1814 | .clkoutdrive = 0, | ||
1815 | .freq_offset_khz_uhf = 0, | ||
1816 | .freq_offset_khz_vhf = 0, | ||
1817 | } | ||
1818 | }; | ||
1819 | |||
1820 | |||
1821 | static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) | ||
1822 | { | ||
1823 | struct dib0700_adapter_state *state = adap->priv; | ||
1824 | struct dib0700_state *st = adap->dev->priv; | ||
1825 | u32 fw_version; | ||
1826 | |||
1827 | /* Make use of the new i2c functions from FW 1.20 */ | ||
1828 | dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); | ||
1829 | if (fw_version >= 0x10200) | ||
1830 | st->fw_use_new_i2c_api = 1; | ||
1831 | dib0700_set_i2c_speed(adap->dev, 340); | ||
1832 | |||
1833 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
1834 | msleep(20); | ||
1835 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
1836 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
1837 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
1838 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
1839 | |||
1840 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
1841 | |||
1842 | msleep(20); | ||
1843 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
1844 | msleep(20); | ||
1845 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
1846 | |||
1847 | dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); | ||
1848 | |||
1849 | if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { | ||
1850 | deb_info("%s: Upload failed. (file not found?)\n", __func__); | ||
1851 | return -ENODEV; | ||
1852 | } else { | ||
1853 | deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); | ||
1854 | } | ||
1855 | stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; | ||
1856 | stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; | ||
1857 | |||
1858 | adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); | ||
1859 | |||
1860 | return adap->fe == NULL ? -ENODEV : 0; | ||
1861 | } | ||
1862 | |||
1863 | static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) | ||
1864 | { | ||
1865 | struct dib0700_adapter_state *state = adap->priv; | ||
1866 | struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe); | ||
1867 | u16 data_dib190[10] = { | ||
1868 | 1, 0x1374, | ||
1869 | 2, 0x01a2, | ||
1870 | 7, 0x0020, | ||
1871 | 0, 0x00ef, | ||
1872 | 8, 0x0486, | ||
1873 | }; | ||
1874 | |||
1875 | if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL) | ||
1876 | return -ENODEV; | ||
1877 | i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); | ||
1878 | if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) | ||
1879 | return -ENODEV; | ||
1880 | dib0700_set_i2c_speed(adap->dev, 2000); | ||
1881 | if (dib9000_firmware_post_pll_init(adap->fe) < 0) | ||
1882 | return -ENODEV; | ||
1883 | release_firmware(state->frontend_firmware); | ||
1884 | return 0; | ||
1885 | } | ||
1886 | |||
1887 | static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) | ||
1888 | { | ||
1889 | struct dib0700_adapter_state *state = adap->priv; | ||
1890 | struct dib0700_state *st = adap->dev->priv; | ||
1891 | struct i2c_adapter *i2c; | ||
1892 | struct dvb_frontend *fe_slave; | ||
1893 | u32 fw_version; | ||
1894 | |||
1895 | /* Make use of the new i2c functions from FW 1.20 */ | ||
1896 | dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL); | ||
1897 | if (fw_version >= 0x10200) | ||
1898 | st->fw_use_new_i2c_api = 1; | ||
1899 | dib0700_set_i2c_speed(adap->dev, 340); | ||
1900 | |||
1901 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
1902 | msleep(20); | ||
1903 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
1904 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
1905 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
1906 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
1907 | |||
1908 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
1909 | |||
1910 | msleep(20); | ||
1911 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
1912 | msleep(20); | ||
1913 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
1914 | |||
1915 | if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { | ||
1916 | deb_info("%s: Upload failed. (file not found?)\n", __func__); | ||
1917 | return -EIO; | ||
1918 | } else { | ||
1919 | deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); | ||
1920 | } | ||
1921 | nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; | ||
1922 | nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; | ||
1923 | nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size; | ||
1924 | nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data; | ||
1925 | |||
1926 | dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80); | ||
1927 | adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); | ||
1928 | |||
1929 | if (adap->fe == NULL) | ||
1930 | return -ENODEV; | ||
1931 | |||
1932 | i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); | ||
1933 | dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82); | ||
1934 | |||
1935 | fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]); | ||
1936 | dib9000_set_slave_frontend(adap->fe, fe_slave); | ||
1937 | |||
1938 | return fe_slave == NULL ? -ENODEV : 0; | ||
1939 | } | ||
1940 | |||
1941 | static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) | ||
1942 | { | ||
1943 | struct dib0700_adapter_state *state = adap->priv; | ||
1944 | struct i2c_adapter *i2c; | ||
1945 | struct dvb_frontend *fe_slave; | ||
1946 | u16 data_dib190[10] = { | ||
1947 | 1, 0x5374, | ||
1948 | 2, 0x01ae, | ||
1949 | 7, 0x0020, | ||
1950 | 0, 0x00ef, | ||
1951 | 8, 0x0406, | ||
1952 | }; | ||
1953 | i2c = dib9000_get_tuner_interface(adap->fe); | ||
1954 | if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL) | ||
1955 | return -ENODEV; | ||
1956 | i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); | ||
1957 | if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) | ||
1958 | return -ENODEV; | ||
1959 | dib0700_set_i2c_speed(adap->dev, 2000); | ||
1960 | if (dib9000_firmware_post_pll_init(adap->fe) < 0) | ||
1961 | return -ENODEV; | ||
1962 | |||
1963 | fe_slave = dib9000_get_slave_frontend(adap->fe, 1); | ||
1964 | if (fe_slave != NULL) { | ||
1965 | i2c = dib9000_get_component_bus_interface(adap->fe); | ||
1966 | dib9000_set_i2c_adapter(fe_slave, i2c); | ||
1967 | |||
1968 | i2c = dib9000_get_tuner_interface(fe_slave); | ||
1969 | if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) | ||
1970 | return -ENODEV; | ||
1971 | fe_slave->dvb = adap->fe->dvb; | ||
1972 | dib9000_fw_set_component_bus_speed(adap->fe, 2000); | ||
1973 | if (dib9000_firmware_post_pll_init(fe_slave) < 0) | ||
1974 | return -ENODEV; | ||
1975 | } | ||
1976 | release_firmware(state->frontend_firmware); | ||
1977 | |||
1978 | return 0; | ||
1979 | } | ||
1980 | |||
1981 | /* NIM7090 */ | ||
1982 | struct dib7090p_best_adc { | ||
1983 | u32 timf; | ||
1984 | u32 pll_loopdiv; | ||
1985 | u32 pll_prediv; | ||
1986 | }; | ||
1987 | |||
1988 | static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc) | ||
1989 | { | ||
1990 | u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1; | ||
1991 | |||
1992 | u16 xtal = 12000; | ||
1993 | u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */ | ||
1994 | u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */ | ||
1995 | u32 fdem_max = 76000; | ||
1996 | u32 fdem_min = 69500; | ||
1997 | u32 fcp = 0, fs = 0, fdem = 0; | ||
1998 | u32 harmonic_id = 0; | ||
1999 | |||
2000 | adc->pll_loopdiv = loopdiv; | ||
2001 | adc->pll_prediv = prediv; | ||
2002 | adc->timf = 0; | ||
2003 | |||
2004 | deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min); | ||
2005 | |||
2006 | /* Find Min and Max prediv */ | ||
2007 | while ((xtal/max_prediv) >= fcp_min) | ||
2008 | max_prediv++; | ||
2009 | |||
2010 | max_prediv--; | ||
2011 | min_prediv = max_prediv; | ||
2012 | while ((xtal/min_prediv) <= fcp_max) { | ||
2013 | min_prediv--; | ||
2014 | if (min_prediv == 1) | ||
2015 | break; | ||
2016 | } | ||
2017 | deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv); | ||
2018 | |||
2019 | min_prediv = 2; | ||
2020 | |||
2021 | for (prediv = min_prediv ; prediv < max_prediv; prediv++) { | ||
2022 | fcp = xtal / prediv; | ||
2023 | if (fcp > fcp_min && fcp < fcp_max) { | ||
2024 | for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) { | ||
2025 | fdem = ((xtal/prediv) * loopdiv); | ||
2026 | fs = fdem / 4; | ||
2027 | /* test min/max system restrictions */ | ||
2028 | |||
2029 | if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) { | ||
2030 | spur = 0; | ||
2031 | /* test fs harmonics positions */ | ||
2032 | for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) { | ||
2033 | if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) { | ||
2034 | spur = 1; | ||
2035 | break; | ||
2036 | } | ||
2037 | } | ||
2038 | |||
2039 | if (!spur) { | ||
2040 | adc->pll_loopdiv = loopdiv; | ||
2041 | adc->pll_prediv = prediv; | ||
2042 | adc->timf = 2396745143UL/fdem*(1 << 9); | ||
2043 | adc->timf += ((2396745143UL%fdem) << 9)/fdem; | ||
2044 | deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf); | ||
2045 | break; | ||
2046 | } | ||
2047 | } | ||
2048 | } | ||
2049 | } | ||
2050 | if (!spur) | ||
2051 | break; | ||
2052 | } | ||
2053 | |||
2054 | |||
2055 | if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0) | ||
2056 | return -EINVAL; | ||
2057 | else | ||
2058 | return 0; | ||
2059 | } | ||
2060 | |||
2061 | static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | ||
2062 | { | ||
2063 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
2064 | struct dib0700_adapter_state *state = adap->priv; | ||
2065 | struct dibx000_bandwidth_config pll; | ||
2066 | u16 target; | ||
2067 | struct dib7090p_best_adc adc; | ||
2068 | int ret; | ||
2069 | |||
2070 | ret = state->set_param_save(fe, fep); | ||
2071 | if (ret < 0) | ||
2072 | return ret; | ||
2073 | |||
2074 | memset(&pll, 0, sizeof(struct dibx000_bandwidth_config)); | ||
2075 | dib0090_pwm_gain_reset(fe); | ||
2076 | target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2; | ||
2077 | dib7000p_set_wbd_ref(fe, target); | ||
2078 | |||
2079 | if (dib7090p_get_best_sampling(fe, &adc) == 0) { | ||
2080 | pll.pll_ratio = adc.pll_loopdiv; | ||
2081 | pll.pll_prediv = adc.pll_prediv; | ||
2082 | |||
2083 | dib7000p_update_pll(fe, &pll); | ||
2084 | dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf); | ||
2085 | } | ||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | static struct dib0090_wbd_slope dib7090_wbd_table[] = { | ||
2090 | { 380, 81, 850, 64, 540, 4}, | ||
2091 | { 860, 51, 866, 21, 375, 4}, | ||
2092 | {1700, 0, 250, 0, 100, 6}, | ||
2093 | {2600, 0, 250, 0, 100, 6}, | ||
2094 | { 0xFFFF, 0, 0, 0, 0, 0}, | ||
2095 | }; | ||
2096 | |||
2097 | struct dibx000_agc_config dib7090_agc_config[2] = { | ||
2098 | { | ||
2099 | .band_caps = BAND_UHF, | ||
2100 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, | ||
2101 | * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | ||
2102 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | ||
2103 | |||
2104 | .inv_gain = 687, | ||
2105 | .time_stabiliz = 10, | ||
2106 | |||
2107 | .alpha_level = 0, | ||
2108 | .thlock = 118, | ||
2109 | |||
2110 | .wbd_inv = 0, | ||
2111 | .wbd_ref = 1200, | ||
2112 | .wbd_sel = 3, | ||
2113 | .wbd_alpha = 5, | ||
2114 | |||
2115 | .agc1_max = 65535, | ||
2116 | .agc1_min = 0, | ||
2117 | |||
2118 | .agc2_max = 65535, | ||
2119 | .agc2_min = 0, | ||
2120 | |||
2121 | .agc1_pt1 = 0, | ||
2122 | .agc1_pt2 = 32, | ||
2123 | .agc1_pt3 = 114, | ||
2124 | .agc1_slope1 = 143, | ||
2125 | .agc1_slope2 = 144, | ||
2126 | .agc2_pt1 = 114, | ||
2127 | .agc2_pt2 = 227, | ||
2128 | .agc2_slope1 = 116, | ||
2129 | .agc2_slope2 = 117, | ||
2130 | |||
2131 | .alpha_mant = 18, | ||
2132 | .alpha_exp = 0, | ||
2133 | .beta_mant = 20, | ||
2134 | .beta_exp = 59, | ||
2135 | |||
2136 | .perform_agc_softsplit = 0, | ||
2137 | } , { | ||
2138 | .band_caps = BAND_FM | BAND_VHF | BAND_CBAND, | ||
2139 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, | ||
2140 | * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | ||
2141 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | ||
2142 | |||
2143 | .inv_gain = 732, | ||
2144 | .time_stabiliz = 10, | ||
2145 | |||
2146 | .alpha_level = 0, | ||
2147 | .thlock = 118, | ||
2148 | |||
2149 | .wbd_inv = 0, | ||
2150 | .wbd_ref = 1200, | ||
2151 | .wbd_sel = 3, | ||
2152 | .wbd_alpha = 5, | ||
2153 | |||
2154 | .agc1_max = 65535, | ||
2155 | .agc1_min = 0, | ||
2156 | |||
2157 | .agc2_max = 65535, | ||
2158 | .agc2_min = 0, | ||
2159 | |||
2160 | .agc1_pt1 = 0, | ||
2161 | .agc1_pt2 = 0, | ||
2162 | .agc1_pt3 = 98, | ||
2163 | .agc1_slope1 = 0, | ||
2164 | .agc1_slope2 = 167, | ||
2165 | .agc1_pt1 = 98, | ||
2166 | .agc2_pt2 = 255, | ||
2167 | .agc2_slope1 = 104, | ||
2168 | .agc2_slope2 = 0, | ||
2169 | |||
2170 | .alpha_mant = 18, | ||
2171 | .alpha_exp = 0, | ||
2172 | .beta_mant = 20, | ||
2173 | .beta_exp = 59, | ||
2174 | |||
2175 | .perform_agc_softsplit = 0, | ||
2176 | } | ||
2177 | }; | ||
2178 | |||
2179 | static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = { | ||
2180 | 60000, 15000, | ||
2181 | 1, 5, 0, 0, 0, | ||
2182 | 0, 0, 1, 1, 2, | ||
2183 | (3 << 14) | (1 << 12) | (524 << 0), | ||
2184 | (0 << 25) | 0, | ||
2185 | 20452225, | ||
2186 | 15000000, | ||
2187 | }; | ||
2188 | |||
2189 | static struct dib7000p_config nim7090_dib7000p_config = { | ||
2190 | .output_mpeg2_in_188_bytes = 1, | ||
2191 | .hostbus_diversity = 1, | ||
2192 | .tuner_is_baseband = 1, | ||
2193 | .update_lna = NULL, | ||
2194 | |||
2195 | .agc_config_count = 2, | ||
2196 | .agc = dib7090_agc_config, | ||
2197 | |||
2198 | .bw = &dib7090_clock_config_12_mhz, | ||
2199 | |||
2200 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
2201 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
2202 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
2203 | |||
2204 | .pwm_freq_div = 0, | ||
2205 | |||
2206 | .agc_control = dib7090_agc_restart, | ||
2207 | |||
2208 | .spur_protect = 0, | ||
2209 | .disable_sample_and_hold = 0, | ||
2210 | .enable_current_mirror = 0, | ||
2211 | .diversity_delay = 0, | ||
2212 | |||
2213 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
2214 | .enMpegOutput = 1, | ||
2215 | }; | ||
2216 | |||
2217 | static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = { | ||
2218 | { | ||
2219 | .output_mpeg2_in_188_bytes = 1, | ||
2220 | .hostbus_diversity = 1, | ||
2221 | .tuner_is_baseband = 1, | ||
2222 | .update_lna = NULL, | ||
2223 | |||
2224 | .agc_config_count = 2, | ||
2225 | .agc = dib7090_agc_config, | ||
2226 | |||
2227 | .bw = &dib7090_clock_config_12_mhz, | ||
2228 | |||
2229 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
2230 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
2231 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
2232 | |||
2233 | .pwm_freq_div = 0, | ||
2234 | |||
2235 | .agc_control = dib7090_agc_restart, | ||
2236 | |||
2237 | .spur_protect = 0, | ||
2238 | .disable_sample_and_hold = 0, | ||
2239 | .enable_current_mirror = 0, | ||
2240 | .diversity_delay = 0, | ||
2241 | |||
2242 | .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, | ||
2243 | .default_i2c_addr = 0x90, | ||
2244 | .enMpegOutput = 1, | ||
2245 | }, { | ||
2246 | .output_mpeg2_in_188_bytes = 1, | ||
2247 | .hostbus_diversity = 1, | ||
2248 | .tuner_is_baseband = 1, | ||
2249 | .update_lna = NULL, | ||
2250 | |||
2251 | .agc_config_count = 2, | ||
2252 | .agc = dib7090_agc_config, | ||
2253 | |||
2254 | .bw = &dib7090_clock_config_12_mhz, | ||
2255 | |||
2256 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
2257 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
2258 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
2259 | |||
2260 | .pwm_freq_div = 0, | ||
2261 | |||
2262 | .agc_control = dib7090_agc_restart, | ||
2263 | |||
2264 | .spur_protect = 0, | ||
2265 | .disable_sample_and_hold = 0, | ||
2266 | .enable_current_mirror = 0, | ||
2267 | .diversity_delay = 0, | ||
2268 | |||
2269 | .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, | ||
2270 | .default_i2c_addr = 0x92, | ||
2271 | .enMpegOutput = 0, | ||
2272 | } | ||
2273 | }; | ||
2274 | |||
2275 | static const struct dib0090_config nim7090_dib0090_config = { | ||
2276 | .io.clock_khz = 12000, | ||
2277 | .io.pll_bypass = 0, | ||
2278 | .io.pll_range = 0, | ||
2279 | .io.pll_prediv = 3, | ||
2280 | .io.pll_loopdiv = 6, | ||
2281 | .io.adc_clock_ratio = 0, | ||
2282 | .io.pll_int_loop_filt = 0, | ||
2283 | .reset = dib7090_tuner_sleep, | ||
2284 | .sleep = dib7090_tuner_sleep, | ||
2285 | |||
2286 | .freq_offset_khz_uhf = 0, | ||
2287 | .freq_offset_khz_vhf = 0, | ||
2288 | |||
2289 | .get_adc_power = dib7090_get_adc_power, | ||
2290 | |||
2291 | .clkouttobamse = 1, | ||
2292 | .analog_output = 0, | ||
2293 | |||
2294 | .wbd_vhf_offset = 0, | ||
2295 | .wbd_cband_offset = 0, | ||
2296 | .use_pwm_agc = 1, | ||
2297 | .clkoutdrive = 0, | ||
2298 | |||
2299 | .fref_clock_ratio = 0, | ||
2300 | |||
2301 | .wbd = dib7090_wbd_table, | ||
2302 | |||
2303 | .ls_cfg_pad_drv = 0, | ||
2304 | .data_tx_drv = 0, | ||
2305 | .low_if = NULL, | ||
2306 | .in_soc = 1, | ||
2307 | }; | ||
2308 | |||
2309 | static const struct dib0090_config tfe7090pvr_dib0090_config[2] = { | ||
2310 | { | ||
2311 | .io.clock_khz = 12000, | ||
2312 | .io.pll_bypass = 0, | ||
2313 | .io.pll_range = 0, | ||
2314 | .io.pll_prediv = 3, | ||
2315 | .io.pll_loopdiv = 6, | ||
2316 | .io.adc_clock_ratio = 0, | ||
2317 | .io.pll_int_loop_filt = 0, | ||
2318 | .reset = dib7090_tuner_sleep, | ||
2319 | .sleep = dib7090_tuner_sleep, | ||
2320 | |||
2321 | .freq_offset_khz_uhf = 50, | ||
2322 | .freq_offset_khz_vhf = 70, | ||
2323 | |||
2324 | .get_adc_power = dib7090_get_adc_power, | ||
2325 | |||
2326 | .clkouttobamse = 1, | ||
2327 | .analog_output = 0, | ||
2328 | |||
2329 | .wbd_vhf_offset = 0, | ||
2330 | .wbd_cband_offset = 0, | ||
2331 | .use_pwm_agc = 1, | ||
2332 | .clkoutdrive = 0, | ||
2333 | |||
2334 | .fref_clock_ratio = 0, | ||
2335 | |||
2336 | .wbd = dib7090_wbd_table, | ||
2337 | |||
2338 | .ls_cfg_pad_drv = 0, | ||
2339 | .data_tx_drv = 0, | ||
2340 | .low_if = NULL, | ||
2341 | .in_soc = 1, | ||
2342 | }, { | ||
2343 | .io.clock_khz = 12000, | ||
2344 | .io.pll_bypass = 0, | ||
2345 | .io.pll_range = 0, | ||
2346 | .io.pll_prediv = 3, | ||
2347 | .io.pll_loopdiv = 6, | ||
2348 | .io.adc_clock_ratio = 0, | ||
2349 | .io.pll_int_loop_filt = 0, | ||
2350 | .reset = dib7090_tuner_sleep, | ||
2351 | .sleep = dib7090_tuner_sleep, | ||
2352 | |||
2353 | .freq_offset_khz_uhf = -50, | ||
2354 | .freq_offset_khz_vhf = -70, | ||
2355 | |||
2356 | .get_adc_power = dib7090_get_adc_power, | ||
2357 | |||
2358 | .clkouttobamse = 1, | ||
2359 | .analog_output = 0, | ||
2360 | |||
2361 | .wbd_vhf_offset = 0, | ||
2362 | .wbd_cband_offset = 0, | ||
2363 | .use_pwm_agc = 1, | ||
2364 | .clkoutdrive = 0, | ||
2365 | |||
2366 | .fref_clock_ratio = 0, | ||
2367 | |||
2368 | .wbd = dib7090_wbd_table, | ||
2369 | |||
2370 | .ls_cfg_pad_drv = 0, | ||
2371 | .data_tx_drv = 0, | ||
2372 | .low_if = NULL, | ||
2373 | .in_soc = 1, | ||
2374 | } | ||
2375 | }; | ||
2376 | |||
2377 | static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) | ||
2378 | { | ||
2379 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
2380 | msleep(20); | ||
2381 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
2382 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
2383 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
2384 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
2385 | |||
2386 | msleep(20); | ||
2387 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
2388 | msleep(20); | ||
2389 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
2390 | |||
2391 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { | ||
2392 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); | ||
2393 | return -ENODEV; | ||
2394 | } | ||
2395 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); | ||
1558 | 2396 | ||
1559 | return adap->fe == NULL ? -ENODEV : 0; | 2397 | return adap->fe == NULL ? -ENODEV : 0; |
1560 | } | 2398 | } |
1561 | 2399 | ||
2400 | static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) | ||
2401 | { | ||
2402 | struct dib0700_adapter_state *st = adap->priv; | ||
2403 | struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); | ||
2404 | |||
2405 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL) | ||
2406 | return -ENODEV; | ||
2407 | |||
2408 | dib7000p_set_gpio(adap->fe, 8, 0, 1); | ||
2409 | |||
2410 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | ||
2411 | adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; | ||
2412 | return 0; | ||
2413 | } | ||
2414 | |||
2415 | static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) | ||
2416 | { | ||
2417 | struct dib0700_state *st = adap->dev->priv; | ||
2418 | |||
2419 | /* The TFE7090 requires the dib0700 to not be in master mode */ | ||
2420 | st->disable_streaming_master_mode = 1; | ||
2421 | |||
2422 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
2423 | msleep(20); | ||
2424 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
2425 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
2426 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
2427 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
2428 | |||
2429 | msleep(20); | ||
2430 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
2431 | msleep(20); | ||
2432 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
2433 | |||
2434 | /* initialize IC 0 */ | ||
2435 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { | ||
2436 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); | ||
2437 | return -ENODEV; | ||
2438 | } | ||
2439 | |||
2440 | dib0700_set_i2c_speed(adap->dev, 340); | ||
2441 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); | ||
2442 | |||
2443 | dib7090_slave_reset(adap->fe); | ||
2444 | |||
2445 | if (adap->fe == NULL) | ||
2446 | return -ENODEV; | ||
2447 | |||
2448 | return 0; | ||
2449 | } | ||
2450 | |||
2451 | static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) | ||
2452 | { | ||
2453 | struct i2c_adapter *i2c; | ||
2454 | |||
2455 | if (adap->dev->adapter[0].fe == NULL) { | ||
2456 | err("the master dib7090 has to be initialized first"); | ||
2457 | return -ENODEV; /* the master device has not been initialized */ | ||
2458 | } | ||
2459 | |||
2460 | i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); | ||
2461 | if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { | ||
2462 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); | ||
2463 | return -ENODEV; | ||
2464 | } | ||
2465 | |||
2466 | adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); | ||
2467 | dib0700_set_i2c_speed(adap->dev, 200); | ||
2468 | |||
2469 | return adap->fe == NULL ? -ENODEV : 0; | ||
2470 | } | ||
2471 | |||
2472 | static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) | ||
2473 | { | ||
2474 | struct dib0700_adapter_state *st = adap->priv; | ||
2475 | struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); | ||
2476 | |||
2477 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) | ||
2478 | return -ENODEV; | ||
2479 | |||
2480 | dib7000p_set_gpio(adap->fe, 8, 0, 1); | ||
2481 | |||
2482 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | ||
2483 | adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; | ||
2484 | return 0; | ||
2485 | } | ||
2486 | |||
2487 | static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) | ||
2488 | { | ||
2489 | struct dib0700_adapter_state *st = adap->priv; | ||
2490 | struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); | ||
2491 | |||
2492 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) | ||
2493 | return -ENODEV; | ||
2494 | |||
2495 | dib7000p_set_gpio(adap->fe, 8, 0, 1); | ||
2496 | |||
2497 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | ||
2498 | adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; | ||
2499 | return 0; | ||
2500 | } | ||
2501 | |||
1562 | /* STK7070PD */ | 2502 | /* STK7070PD */ |
1563 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { | 2503 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { |
1564 | { | 2504 | { |
@@ -1856,6 +2796,12 @@ struct usb_device_id dib0700_usb_id_table[] = { | |||
1856 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, | 2796 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, |
1857 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, | 2797 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, |
1858 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) }, | 2798 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) }, |
2799 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) }, | ||
2800 | /* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) }, | ||
2801 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) }, | ||
2802 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) }, | ||
2803 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, | ||
2804 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) }, | ||
1859 | { 0 } /* Terminating entry */ | 2805 | { 0 } /* Terminating entry */ |
1860 | }; | 2806 | }; |
1861 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); | 2807 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); |
@@ -2465,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2465 | }, | 3411 | }, |
2466 | }, | 3412 | }, |
2467 | 3413 | ||
2468 | .num_device_descs = 2, | 3414 | .num_device_descs = 3, |
2469 | .devices = { | 3415 | .devices = { |
2470 | { "DiBcom STK7770P reference design", | 3416 | { "DiBcom STK7770P reference design", |
2471 | { &dib0700_usb_id_table[59], NULL }, | 3417 | { &dib0700_usb_id_table[59], NULL }, |
@@ -2477,6 +3423,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2477 | &dib0700_usb_id_table[60], NULL}, | 3423 | &dib0700_usb_id_table[60], NULL}, |
2478 | { NULL }, | 3424 | { NULL }, |
2479 | }, | 3425 | }, |
3426 | { "TechniSat AirStar TeleStick 2", | ||
3427 | { &dib0700_usb_id_table[74], NULL }, | ||
3428 | { NULL }, | ||
3429 | }, | ||
2480 | }, | 3430 | }, |
2481 | 3431 | ||
2482 | .rc.core = { | 3432 | .rc.core = { |
@@ -2619,6 +3569,205 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2619 | RC_TYPE_NEC, | 3569 | RC_TYPE_NEC, |
2620 | .change_protocol = dib0700_change_protocol, | 3570 | .change_protocol = dib0700_change_protocol, |
2621 | }, | 3571 | }, |
3572 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3573 | .num_adapters = 1, | ||
3574 | .adapter = { | ||
3575 | { | ||
3576 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3577 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3578 | .pid_filter_count = 32, | ||
3579 | .pid_filter = dib90x0_pid_filter, | ||
3580 | .pid_filter_ctrl = dib90x0_pid_filter_ctrl, | ||
3581 | .frontend_attach = stk9090m_frontend_attach, | ||
3582 | .tuner_attach = dib9090_tuner_attach, | ||
3583 | |||
3584 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3585 | |||
3586 | .size_of_priv = | ||
3587 | sizeof(struct dib0700_adapter_state), | ||
3588 | }, | ||
3589 | }, | ||
3590 | |||
3591 | .num_device_descs = 1, | ||
3592 | .devices = { | ||
3593 | { "DiBcom STK9090M reference design", | ||
3594 | { &dib0700_usb_id_table[69], NULL }, | ||
3595 | { NULL }, | ||
3596 | }, | ||
3597 | }, | ||
3598 | |||
3599 | .rc.core = { | ||
3600 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3601 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3602 | .module_name = "dib0700", | ||
3603 | .rc_query = dib0700_rc_query_old_firmware, | ||
3604 | .allowed_protos = RC_TYPE_RC5 | | ||
3605 | RC_TYPE_RC6 | | ||
3606 | RC_TYPE_NEC, | ||
3607 | .change_protocol = dib0700_change_protocol, | ||
3608 | }, | ||
3609 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3610 | .num_adapters = 1, | ||
3611 | .adapter = { | ||
3612 | { | ||
3613 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3614 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3615 | .pid_filter_count = 32, | ||
3616 | .pid_filter = stk80xx_pid_filter, | ||
3617 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, | ||
3618 | .frontend_attach = nim8096md_frontend_attach, | ||
3619 | .tuner_attach = nim8096md_tuner_attach, | ||
3620 | |||
3621 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3622 | |||
3623 | .size_of_priv = | ||
3624 | sizeof(struct dib0700_adapter_state), | ||
3625 | }, | ||
3626 | }, | ||
3627 | |||
3628 | .num_device_descs = 1, | ||
3629 | .devices = { | ||
3630 | { "DiBcom NIM8096MD reference design", | ||
3631 | { &dib0700_usb_id_table[70], NULL }, | ||
3632 | { NULL }, | ||
3633 | }, | ||
3634 | }, | ||
3635 | |||
3636 | .rc.core = { | ||
3637 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3638 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3639 | .module_name = "dib0700", | ||
3640 | .rc_query = dib0700_rc_query_old_firmware, | ||
3641 | .allowed_protos = RC_TYPE_RC5 | | ||
3642 | RC_TYPE_RC6 | | ||
3643 | RC_TYPE_NEC, | ||
3644 | .change_protocol = dib0700_change_protocol, | ||
3645 | }, | ||
3646 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3647 | .num_adapters = 1, | ||
3648 | .adapter = { | ||
3649 | { | ||
3650 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3651 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3652 | .pid_filter_count = 32, | ||
3653 | .pid_filter = dib90x0_pid_filter, | ||
3654 | .pid_filter_ctrl = dib90x0_pid_filter_ctrl, | ||
3655 | .frontend_attach = nim9090md_frontend_attach, | ||
3656 | .tuner_attach = nim9090md_tuner_attach, | ||
3657 | |||
3658 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3659 | |||
3660 | .size_of_priv = | ||
3661 | sizeof(struct dib0700_adapter_state), | ||
3662 | }, | ||
3663 | }, | ||
3664 | |||
3665 | .num_device_descs = 1, | ||
3666 | .devices = { | ||
3667 | { "DiBcom NIM9090MD reference design", | ||
3668 | { &dib0700_usb_id_table[71], NULL }, | ||
3669 | { NULL }, | ||
3670 | }, | ||
3671 | }, | ||
3672 | |||
3673 | .rc.core = { | ||
3674 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3675 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3676 | .module_name = "dib0700", | ||
3677 | .rc_query = dib0700_rc_query_old_firmware, | ||
3678 | .allowed_protos = RC_TYPE_RC5 | | ||
3679 | RC_TYPE_RC6 | | ||
3680 | RC_TYPE_NEC, | ||
3681 | .change_protocol = dib0700_change_protocol, | ||
3682 | }, | ||
3683 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3684 | .num_adapters = 1, | ||
3685 | .adapter = { | ||
3686 | { | ||
3687 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3688 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3689 | .pid_filter_count = 32, | ||
3690 | .pid_filter = stk70x0p_pid_filter, | ||
3691 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
3692 | .frontend_attach = nim7090_frontend_attach, | ||
3693 | .tuner_attach = nim7090_tuner_attach, | ||
3694 | |||
3695 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3696 | |||
3697 | .size_of_priv = | ||
3698 | sizeof(struct dib0700_adapter_state), | ||
3699 | }, | ||
3700 | }, | ||
3701 | |||
3702 | .num_device_descs = 1, | ||
3703 | .devices = { | ||
3704 | { "DiBcom NIM7090 reference design", | ||
3705 | { &dib0700_usb_id_table[72], NULL }, | ||
3706 | { NULL }, | ||
3707 | }, | ||
3708 | }, | ||
3709 | |||
3710 | .rc.core = { | ||
3711 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3712 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3713 | .module_name = "dib0700", | ||
3714 | .rc_query = dib0700_rc_query_old_firmware, | ||
3715 | .allowed_protos = RC_TYPE_RC5 | | ||
3716 | RC_TYPE_RC6 | | ||
3717 | RC_TYPE_NEC, | ||
3718 | .change_protocol = dib0700_change_protocol, | ||
3719 | }, | ||
3720 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3721 | .num_adapters = 2, | ||
3722 | .adapter = { | ||
3723 | { | ||
3724 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3725 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3726 | .pid_filter_count = 32, | ||
3727 | .pid_filter = stk70x0p_pid_filter, | ||
3728 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
3729 | .frontend_attach = tfe7090pvr_frontend0_attach, | ||
3730 | .tuner_attach = tfe7090pvr_tuner0_attach, | ||
3731 | |||
3732 | DIB0700_DEFAULT_STREAMING_CONFIG(0x03), | ||
3733 | |||
3734 | .size_of_priv = | ||
3735 | sizeof(struct dib0700_adapter_state), | ||
3736 | }, | ||
3737 | { | ||
3738 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
3739 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3740 | .pid_filter_count = 32, | ||
3741 | .pid_filter = stk70x0p_pid_filter, | ||
3742 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
3743 | .frontend_attach = tfe7090pvr_frontend1_attach, | ||
3744 | .tuner_attach = tfe7090pvr_tuner1_attach, | ||
3745 | |||
3746 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3747 | |||
3748 | .size_of_priv = | ||
3749 | sizeof(struct dib0700_adapter_state), | ||
3750 | }, | ||
3751 | }, | ||
3752 | |||
3753 | .num_device_descs = 1, | ||
3754 | .devices = { | ||
3755 | { "DiBcom TFE7090PVR reference design", | ||
3756 | { &dib0700_usb_id_table[73], NULL }, | ||
3757 | { NULL }, | ||
3758 | }, | ||
3759 | }, | ||
3760 | |||
3761 | .rc.core = { | ||
3762 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3763 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3764 | .module_name = "dib0700", | ||
3765 | .rc_query = dib0700_rc_query_old_firmware, | ||
3766 | .allowed_protos = RC_TYPE_RC5 | | ||
3767 | RC_TYPE_RC6 | | ||
3768 | RC_TYPE_NEC, | ||
3769 | .change_protocol = dib0700_change_protocol, | ||
3770 | }, | ||
2622 | }, | 3771 | }, |
2623 | }; | 3772 | }; |
2624 | 3773 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f2dbce7edb3b..f6344cdd360f 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = { | |||
176 | { 0xaf59, KEY_AUX }, | 176 | { 0xaf59, KEY_AUX }, |
177 | { 0x5f5a, KEY_DVD }, | 177 | { 0x5f5a, KEY_DVD }, |
178 | { 0x6f5a, KEY_POWER }, | 178 | { 0x6f5a, KEY_POWER }, |
179 | { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */ | 179 | { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */ |
180 | { 0xaf5a, KEY_AUDIO }, | 180 | { 0xaf5a, KEY_AUDIO }, |
181 | { 0x5f65, KEY_INFO }, | 181 | { 0x5f65, KEY_INFO }, |
182 | { 0x6f65, KEY_F13 }, /* 16:9 */ | 182 | { 0x6f65, KEY_F13 }, /* 16:9 */ |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 1a6310b61923..3a8b7446b7b0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -106,8 +106,13 @@ | |||
106 | #define USB_PID_DIBCOM_STK807XP 0x1f90 | 106 | #define USB_PID_DIBCOM_STK807XP 0x1f90 |
107 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 | 107 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 |
108 | #define USB_PID_DIBCOM_STK8096GP 0x1fa0 | 108 | #define USB_PID_DIBCOM_STK8096GP 0x1fa0 |
109 | #define USB_PID_DIBCOM_NIM8096MD 0x1fa8 | ||
109 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 | 110 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 |
110 | #define USB_PID_DIBCOM_STK7770P 0x1e80 | 111 | #define USB_PID_DIBCOM_STK7770P 0x1e80 |
112 | #define USB_PID_DIBCOM_NIM7090 0x1bb2 | ||
113 | #define USB_PID_DIBCOM_TFE7090PVR 0x1bb4 | ||
114 | #define USB_PID_DIBCOM_NIM9090M 0x2383 | ||
115 | #define USB_PID_DIBCOM_NIM9090MD 0x2384 | ||
111 | #define USB_PID_DPOSH_M9206_COLD 0x9206 | 116 | #define USB_PID_DPOSH_M9206_COLD 0x9206 |
112 | #define USB_PID_DPOSH_M9206_WARM 0xa090 | 117 | #define USB_PID_DPOSH_M9206_WARM 0xa090 |
113 | #define USB_PID_E3C_EC168 0x1689 | 118 | #define USB_PID_E3C_EC168 0x1689 |
@@ -312,4 +317,6 @@ | |||
312 | #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac | 317 | #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac |
313 | #define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 | 318 | #define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 |
314 | #define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 | 319 | #define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 |
320 | #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004 | ||
321 | #define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500 | ||
315 | #endif | 322 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index b2b9415d874d..41bacff24960 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -273,7 +273,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | |||
273 | dev->map_name = d->props.rc.core.rc_codes; | 273 | dev->map_name = d->props.rc.core.rc_codes; |
274 | dev->change_protocol = d->props.rc.core.change_protocol; | 274 | dev->change_protocol = d->props.rc.core.change_protocol; |
275 | dev->allowed_protos = d->props.rc.core.allowed_protos; | 275 | dev->allowed_protos = d->props.rc.core.allowed_protos; |
276 | dev->driver_type = RC_DRIVER_SCANCODE; | 276 | dev->driver_type = d->props.rc.core.driver_type; |
277 | usb_to_input_id(d->udev, &dev->input_id); | 277 | usb_to_input_id(d->udev, &dev->input_id); |
278 | dev->input_name = "IR-receiver inside an USB DVB receiver"; | 278 | dev->input_name = "IR-receiver inside an USB DVB receiver"; |
279 | dev->input_phys = d->rc_phys; | 279 | dev->input_phys = d->rc_phys; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 65fa9268e7f7..76a80968482a 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -181,6 +181,7 @@ struct dvb_rc_legacy { | |||
181 | * @rc_codes: name of rc codes table | 181 | * @rc_codes: name of rc codes table |
182 | * @protocol: type of protocol(s) currently used by the driver | 182 | * @protocol: type of protocol(s) currently used by the driver |
183 | * @allowed_protos: protocol(s) supported by the driver | 183 | * @allowed_protos: protocol(s) supported by the driver |
184 | * @driver_type: Used to point if a device supports raw mode | ||
184 | * @change_protocol: callback to change protocol | 185 | * @change_protocol: callback to change protocol |
185 | * @rc_query: called to query an event event. | 186 | * @rc_query: called to query an event event. |
186 | * @rc_interval: time in ms between two queries. | 187 | * @rc_interval: time in ms between two queries. |
@@ -190,6 +191,7 @@ struct dvb_rc { | |||
190 | char *rc_codes; | 191 | char *rc_codes; |
191 | u64 protocol; | 192 | u64 protocol; |
192 | u64 allowed_protos; | 193 | u64 allowed_protos; |
194 | enum rc_driver_type driver_type; | ||
193 | int (*change_protocol)(struct rc_dev *dev, u64 rc_type); | 195 | int (*change_protocol)(struct rc_dev *dev, u64 rc_type); |
194 | char *module_name; | 196 | char *module_name; |
195 | int (*rc_query) (struct dvb_usb_device *d); | 197 | int (*rc_query) (struct dvb_usb_device *d); |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 2c307ba0d28b..f5b9da18f611 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1,15 +1,16 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the | 1 | /* DVB USB framework compliant Linux driver for the |
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | 2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, |
3 | * TeVii S600, S630, S650, | 3 | * TeVii S600, S630, S650, S660, S480, |
4 | * Prof 1100, 7500 Cards | 4 | * Prof 1100, 7500, |
5 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) | 5 | * Geniatech SU3000 Cards |
6 | * | 6 | * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by) |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * |
8 | * under the terms of the GNU General Public License as published by the | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * Free Software Foundation, version 2. | 9 | * under the terms of the GNU General Public License as published by the |
10 | * | 10 | * Free Software Foundation, version 2. |
11 | * see Documentation/dvb/README.dvb-usb for more information | 11 | * |
12 | */ | 12 | * see Documentation/dvb/README.dvb-usb for more information |
13 | */ | ||
13 | #include "dw2102.h" | 14 | #include "dw2102.h" |
14 | #include "si21xx.h" | 15 | #include "si21xx.h" |
15 | #include "stv0299.h" | 16 | #include "stv0299.h" |
@@ -55,6 +56,14 @@ | |||
55 | #define USB_PID_TEVII_S660 0xd660 | 56 | #define USB_PID_TEVII_S660 0xd660 |
56 | #endif | 57 | #endif |
57 | 58 | ||
59 | #ifndef USB_PID_TEVII_S480_1 | ||
60 | #define USB_PID_TEVII_S480_1 0xd481 | ||
61 | #endif | ||
62 | |||
63 | #ifndef USB_PID_TEVII_S480_2 | ||
64 | #define USB_PID_TEVII_S480_2 0xd482 | ||
65 | #endif | ||
66 | |||
58 | #ifndef USB_PID_PROF_1100 | 67 | #ifndef USB_PID_PROF_1100 |
59 | #define USB_PID_PROF_1100 0xb012 | 68 | #define USB_PID_PROF_1100 0xb012 |
60 | #endif | 69 | #endif |
@@ -67,7 +76,9 @@ | |||
67 | #define REG_21_SYMBOLRATE_BYTE2 0x21 | 76 | #define REG_21_SYMBOLRATE_BYTE2 0x21 |
68 | /* on my own*/ | 77 | /* on my own*/ |
69 | #define DW2102_VOLTAGE_CTRL (0x1800) | 78 | #define DW2102_VOLTAGE_CTRL (0x1800) |
79 | #define SU3000_STREAM_CTRL (0x1900) | ||
70 | #define DW2102_RC_QUERY (0x1a00) | 80 | #define DW2102_RC_QUERY (0x1a00) |
81 | #define DW2102_LED_CTRL (0x1b00) | ||
71 | 82 | ||
72 | #define err_str "did not find the firmware file. (%s) " \ | 83 | #define err_str "did not find the firmware file. (%s) " \ |
73 | "Please see linux/Documentation/dvb/ for more details " \ | 84 | "Please see linux/Documentation/dvb/ for more details " \ |
@@ -78,6 +89,14 @@ struct rc_map_dvb_usb_table_table { | |||
78 | int rc_keys_size; | 89 | int rc_keys_size; |
79 | }; | 90 | }; |
80 | 91 | ||
92 | struct su3000_state { | ||
93 | u8 initialized; | ||
94 | }; | ||
95 | |||
96 | struct s6x0_state { | ||
97 | int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); | ||
98 | }; | ||
99 | |||
81 | /* debug */ | 100 | /* debug */ |
82 | static int dvb_usb_dw2102_debug; | 101 | static int dvb_usb_dw2102_debug; |
83 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | 102 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); |
@@ -87,7 +106,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." | |||
87 | /* keymaps */ | 106 | /* keymaps */ |
88 | static int ir_keymap; | 107 | static int ir_keymap; |
89 | module_param_named(keymap, ir_keymap, int, 0644); | 108 | module_param_named(keymap, ir_keymap, int, 0644); |
90 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | 109 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..." |
110 | " 256=none"); | ||
91 | 111 | ||
92 | /* demod probe */ | 112 | /* demod probe */ |
93 | static int demod_probe = 1; | 113 | static int demod_probe = 1; |
@@ -136,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
136 | /* read stv0299 register */ | 156 | /* read stv0299 register */ |
137 | value = msg[0].buf[0];/* register */ | 157 | value = msg[0].buf[0];/* register */ |
138 | for (i = 0; i < msg[1].len; i++) { | 158 | for (i = 0; i < msg[1].len; i++) { |
139 | value = value + i; | 159 | ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0, |
140 | ret = dw210x_op_rw(d->udev, 0xb5, value, 0, | ||
141 | buf6, 2, DW210X_READ_MSG); | 160 | buf6, 2, DW210X_READ_MSG); |
142 | msg[1].buf[i] = buf6[0]; | 161 | msg[1].buf[i] = buf6[0]; |
143 | } | 162 | } |
@@ -483,10 +502,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
483 | for (j = 0; j < num; j++) { | 502 | for (j = 0; j < num; j++) { |
484 | switch (msg[j].addr) { | 503 | switch (msg[j].addr) { |
485 | case (DW2102_RC_QUERY): { | 504 | case (DW2102_RC_QUERY): { |
486 | u8 ibuf[4]; | 505 | u8 ibuf[5]; |
487 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | 506 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, |
488 | ibuf, 4, DW210X_READ_MSG); | 507 | ibuf, 5, DW210X_READ_MSG); |
489 | memcpy(msg[j].buf, ibuf + 1, 2); | 508 | memcpy(msg[j].buf, ibuf + 3, 2); |
490 | break; | 509 | break; |
491 | } | 510 | } |
492 | case (DW2102_VOLTAGE_CTRL): { | 511 | case (DW2102_VOLTAGE_CTRL): { |
@@ -502,6 +521,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
502 | obuf, 2, DW210X_WRITE_MSG); | 521 | obuf, 2, DW210X_WRITE_MSG); |
503 | break; | 522 | break; |
504 | } | 523 | } |
524 | case (DW2102_LED_CTRL): { | ||
525 | u8 obuf[2]; | ||
526 | |||
527 | obuf[0] = 5; | ||
528 | obuf[1] = msg[j].buf[0]; | ||
529 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | ||
530 | obuf, 2, DW210X_WRITE_MSG); | ||
531 | break; | ||
532 | } | ||
505 | /*case 0x55: cx24116 | 533 | /*case 0x55: cx24116 |
506 | case 0x6a: stv0903 | 534 | case 0x6a: stv0903 |
507 | case 0x68: ds3000, stv0903 | 535 | case 0x68: ds3000, stv0903 |
@@ -535,14 +563,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
535 | i += 16; | 563 | i += 16; |
536 | len -= 16; | 564 | len -= 16; |
537 | } while (len > 0); | 565 | } while (len > 0); |
538 | } else if ((udev->descriptor.idProduct == 0x7500) | 566 | } else if (j < (num - 1)) { |
539 | && (j < (num - 1))) { | ||
540 | /* write register addr before read */ | 567 | /* write register addr before read */ |
541 | u8 obuf[msg[j].len + 2]; | 568 | u8 obuf[msg[j].len + 2]; |
542 | obuf[0] = msg[j + 1].len; | 569 | obuf[0] = msg[j + 1].len; |
543 | obuf[1] = (msg[j].addr << 1); | 570 | obuf[1] = (msg[j].addr << 1); |
544 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | 571 | memcpy(obuf + 2, msg[j].buf, msg[j].len); |
545 | ret = dw210x_op_rw(d->udev, 0x92, 0, 0, | 572 | ret = dw210x_op_rw(d->udev, |
573 | udev->descriptor.idProduct == | ||
574 | 0x7500 ? 0x92 : 0x90, 0, 0, | ||
546 | obuf, msg[j].len + 2, | 575 | obuf, msg[j].len + 2, |
547 | DW210X_WRITE_MSG); | 576 | DW210X_WRITE_MSG); |
548 | break; | 577 | break; |
@@ -552,8 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
552 | obuf[0] = msg[j].len + 1; | 581 | obuf[0] = msg[j].len + 1; |
553 | obuf[1] = (msg[j].addr << 1); | 582 | obuf[1] = (msg[j].addr << 1); |
554 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | 583 | memcpy(obuf + 2, msg[j].buf, msg[j].len); |
555 | ret = dw210x_op_rw(d->udev, | 584 | ret = dw210x_op_rw(d->udev, 0x80, 0, 0, |
556 | (num > 1 ? 0x90 : 0x80), 0, 0, | ||
557 | obuf, msg[j].len + 2, | 585 | obuf, msg[j].len + 2, |
558 | DW210X_WRITE_MSG); | 586 | DW210X_WRITE_MSG); |
559 | break; | 587 | break; |
@@ -561,14 +589,76 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
561 | break; | 589 | break; |
562 | } | 590 | } |
563 | } | 591 | } |
564 | |||
565 | msleep(3); | ||
566 | } | 592 | } |
567 | 593 | ||
568 | mutex_unlock(&d->i2c_mutex); | 594 | mutex_unlock(&d->i2c_mutex); |
569 | return num; | 595 | return num; |
570 | } | 596 | } |
571 | 597 | ||
598 | static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
599 | int num) | ||
600 | { | ||
601 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
602 | u8 obuf[0x40], ibuf[0x40]; | ||
603 | |||
604 | if (!d) | ||
605 | return -ENODEV; | ||
606 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
607 | return -EAGAIN; | ||
608 | |||
609 | switch (num) { | ||
610 | case 1: | ||
611 | switch (msg[0].addr) { | ||
612 | case SU3000_STREAM_CTRL: | ||
613 | obuf[0] = msg[0].buf[0] + 0x36; | ||
614 | obuf[1] = 3; | ||
615 | obuf[2] = 0; | ||
616 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0) | ||
617 | err("i2c transfer failed."); | ||
618 | break; | ||
619 | case DW2102_RC_QUERY: | ||
620 | obuf[0] = 0x10; | ||
621 | if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0) | ||
622 | err("i2c transfer failed."); | ||
623 | msg[0].buf[1] = ibuf[0]; | ||
624 | msg[0].buf[0] = ibuf[1]; | ||
625 | break; | ||
626 | default: | ||
627 | /* always i2c write*/ | ||
628 | obuf[0] = 0x08; | ||
629 | obuf[1] = msg[0].addr; | ||
630 | obuf[2] = msg[0].len; | ||
631 | |||
632 | memcpy(&obuf[3], msg[0].buf, msg[0].len); | ||
633 | |||
634 | if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3, | ||
635 | ibuf, 1, 0) < 0) | ||
636 | err("i2c transfer failed."); | ||
637 | |||
638 | } | ||
639 | break; | ||
640 | case 2: | ||
641 | /* always i2c read */ | ||
642 | obuf[0] = 0x09; | ||
643 | obuf[1] = msg[0].len; | ||
644 | obuf[2] = msg[1].len; | ||
645 | obuf[3] = msg[0].addr; | ||
646 | memcpy(&obuf[4], msg[0].buf, msg[0].len); | ||
647 | |||
648 | if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4, | ||
649 | ibuf, msg[1].len + 1, 0) < 0) | ||
650 | err("i2c transfer failed."); | ||
651 | |||
652 | memcpy(msg[1].buf, &ibuf[1], msg[1].len); | ||
653 | break; | ||
654 | default: | ||
655 | warn("more than 2 i2c messages at a time is not handled yet."); | ||
656 | break; | ||
657 | } | ||
658 | mutex_unlock(&d->i2c_mutex); | ||
659 | return num; | ||
660 | } | ||
661 | |||
572 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | 662 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) |
573 | { | 663 | { |
574 | return I2C_FUNC_I2C; | 664 | return I2C_FUNC_I2C; |
@@ -604,6 +694,11 @@ static struct i2c_algorithm s6x0_i2c_algo = { | |||
604 | .functionality = dw210x_i2c_func, | 694 | .functionality = dw210x_i2c_func, |
605 | }; | 695 | }; |
606 | 696 | ||
697 | static struct i2c_algorithm su3000_i2c_algo = { | ||
698 | .master_xfer = su3000_i2c_transfer, | ||
699 | .functionality = dw210x_i2c_func, | ||
700 | }; | ||
701 | |||
607 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 702 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
608 | { | 703 | { |
609 | int i; | 704 | int i; |
@@ -668,6 +763,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
668 | return 0; | 763 | return 0; |
669 | }; | 764 | }; |
670 | 765 | ||
766 | static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
767 | { | ||
768 | static u8 command_start[] = {0x00}; | ||
769 | static u8 command_stop[] = {0x01}; | ||
770 | struct i2c_msg msg = { | ||
771 | .addr = SU3000_STREAM_CTRL, | ||
772 | .flags = 0, | ||
773 | .buf = onoff ? command_start : command_stop, | ||
774 | .len = 1 | ||
775 | }; | ||
776 | |||
777 | i2c_transfer(&adap->dev->i2c_adap, &msg, 1); | ||
778 | |||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | static int su3000_power_ctrl(struct dvb_usb_device *d, int i) | ||
783 | { | ||
784 | struct su3000_state *state = (struct su3000_state *)d->priv; | ||
785 | u8 obuf[] = {0xde, 0}; | ||
786 | |||
787 | info("%s: %d, initialized %d\n", __func__, i, state->initialized); | ||
788 | |||
789 | if (i && !state->initialized) { | ||
790 | state->initialized = 1; | ||
791 | /* reset board */ | ||
792 | dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0); | ||
793 | } | ||
794 | |||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||
799 | { | ||
800 | int i; | ||
801 | u8 obuf[] = { 0x1f, 0xf0 }; | ||
802 | u8 ibuf[] = { 0 }; | ||
803 | struct i2c_msg msg[] = { | ||
804 | { | ||
805 | .addr = 0x51, | ||
806 | .flags = 0, | ||
807 | .buf = obuf, | ||
808 | .len = 2, | ||
809 | }, { | ||
810 | .addr = 0x51, | ||
811 | .flags = I2C_M_RD, | ||
812 | .buf = ibuf, | ||
813 | .len = 1, | ||
814 | |||
815 | } | ||
816 | }; | ||
817 | |||
818 | for (i = 0; i < 6; i++) { | ||
819 | obuf[1] = 0xf0 + i; | ||
820 | if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) | ||
821 | break; | ||
822 | else | ||
823 | mac[i] = ibuf[0]; | ||
824 | |||
825 | debug_dump(mac, 6, printk); | ||
826 | } | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int su3000_identify_state(struct usb_device *udev, | ||
832 | struct dvb_usb_device_properties *props, | ||
833 | struct dvb_usb_device_description **desc, | ||
834 | int *cold) | ||
835 | { | ||
836 | info("%s\n", __func__); | ||
837 | |||
838 | *cold = 0; | ||
839 | return 0; | ||
840 | } | ||
841 | |||
671 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 842 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
672 | { | 843 | { |
673 | static u8 command_13v[] = {0x00, 0x01}; | 844 | static u8 command_13v[] = {0x00, 0x01}; |
@@ -692,6 +863,37 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
692 | return 0; | 863 | return 0; |
693 | } | 864 | } |
694 | 865 | ||
866 | static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
867 | { | ||
868 | struct dvb_usb_adapter *d = | ||
869 | (struct dvb_usb_adapter *)(fe->dvb->priv); | ||
870 | struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | ||
871 | |||
872 | dw210x_set_voltage(fe, voltage); | ||
873 | if (st->old_set_voltage) | ||
874 | st->old_set_voltage(fe, voltage); | ||
875 | |||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) | ||
880 | { | ||
881 | static u8 led_off[] = { 0 }; | ||
882 | static u8 led_on[] = { 1 }; | ||
883 | struct i2c_msg msg = { | ||
884 | .addr = DW2102_LED_CTRL, | ||
885 | .flags = 0, | ||
886 | .buf = led_off, | ||
887 | .len = 1 | ||
888 | }; | ||
889 | struct dvb_usb_adapter *udev_adap = | ||
890 | (struct dvb_usb_adapter *)(fe->dvb->priv); | ||
891 | |||
892 | if (offon) | ||
893 | msg.buf = led_on; | ||
894 | i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); | ||
895 | } | ||
896 | |||
695 | static struct stv0299_config sharp_z0194a_config = { | 897 | static struct stv0299_config sharp_z0194a_config = { |
696 | .demod_address = 0x68, | 898 | .demod_address = 0x68, |
697 | .inittab = sharp_z0194a_inittab, | 899 | .inittab = sharp_z0194a_inittab, |
@@ -771,6 +973,12 @@ static struct stv0900_config prof_7500_stv0900_config = { | |||
771 | .tun1_adc = 0,/* 2 Vpp */ | 973 | .tun1_adc = 0,/* 2 Vpp */ |
772 | .path1_mode = 3, | 974 | .path1_mode = 3, |
773 | .tun1_type = 3, | 975 | .tun1_type = 3, |
976 | .set_lock_led = dw210x_led_ctrl, | ||
977 | }; | ||
978 | |||
979 | static struct ds3000_config su3000_ds3000_config = { | ||
980 | .demod_address = 0x68, | ||
981 | .ci_mode = 1, | ||
774 | }; | 982 | }; |
775 | 983 | ||
776 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 984 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
@@ -885,7 +1093,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) | |||
885 | return -EIO; | 1093 | return -EIO; |
886 | } | 1094 | } |
887 | 1095 | ||
888 | static int s6x0_frontend_attach(struct dvb_usb_adapter *d) | 1096 | static int zl100313_frontend_attach(struct dvb_usb_adapter *d) |
889 | { | 1097 | { |
890 | d->fe = dvb_attach(mt312_attach, &zl313_config, | 1098 | d->fe = dvb_attach(mt312_attach, &zl313_config, |
891 | &d->dev->i2c_adap); | 1099 | &d->dev->i2c_adap); |
@@ -898,41 +1106,108 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d) | |||
898 | } | 1106 | } |
899 | } | 1107 | } |
900 | 1108 | ||
1109 | return -EIO; | ||
1110 | } | ||
1111 | |||
1112 | static int stv0288_frontend_attach(struct dvb_usb_adapter *d) | ||
1113 | { | ||
1114 | u8 obuf[] = {7, 1}; | ||
1115 | |||
901 | d->fe = dvb_attach(stv0288_attach, &earda_config, | 1116 | d->fe = dvb_attach(stv0288_attach, &earda_config, |
902 | &d->dev->i2c_adap); | 1117 | &d->dev->i2c_adap); |
903 | if (d->fe != NULL) { | 1118 | |
904 | if (dvb_attach(stb6000_attach, d->fe, 0x61, | 1119 | if (d->fe == NULL) |
905 | &d->dev->i2c_adap)) { | 1120 | return -EIO; |
906 | d->fe->ops.set_voltage = dw210x_set_voltage; | 1121 | |
907 | info("Attached stv0288+stb6000!\n"); | 1122 | if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap)) |
908 | return 0; | 1123 | return -EIO; |
909 | } | 1124 | |
910 | } | 1125 | d->fe->ops.set_voltage = dw210x_set_voltage; |
1126 | |||
1127 | dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||
1128 | |||
1129 | info("Attached stv0288+stb6000!\n"); | ||
1130 | |||
1131 | return 0; | ||
1132 | |||
1133 | } | ||
1134 | |||
1135 | static int ds3000_frontend_attach(struct dvb_usb_adapter *d) | ||
1136 | { | ||
1137 | struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | ||
1138 | u8 obuf[] = {7, 1}; | ||
911 | 1139 | ||
912 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | 1140 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, |
913 | &d->dev->i2c_adap); | 1141 | &d->dev->i2c_adap); |
914 | if (d->fe != NULL) { | ||
915 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
916 | info("Attached ds3000+ds2020!\n"); | ||
917 | return 0; | ||
918 | } | ||
919 | 1142 | ||
920 | return -EIO; | 1143 | if (d->fe == NULL) |
1144 | return -EIO; | ||
1145 | |||
1146 | st->old_set_voltage = d->fe->ops.set_voltage; | ||
1147 | d->fe->ops.set_voltage = s660_set_voltage; | ||
1148 | |||
1149 | dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||
1150 | |||
1151 | info("Attached ds3000+ds2020!\n"); | ||
1152 | |||
1153 | return 0; | ||
921 | } | 1154 | } |
922 | 1155 | ||
923 | static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) | 1156 | static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) |
924 | { | 1157 | { |
1158 | u8 obuf[] = {7, 1}; | ||
1159 | |||
925 | d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, | 1160 | d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, |
926 | &d->dev->i2c_adap, 0); | 1161 | &d->dev->i2c_adap, 0); |
927 | if (d->fe == NULL) | 1162 | if (d->fe == NULL) |
928 | return -EIO; | 1163 | return -EIO; |
1164 | |||
929 | d->fe->ops.set_voltage = dw210x_set_voltage; | 1165 | d->fe->ops.set_voltage = dw210x_set_voltage; |
930 | 1166 | ||
1167 | dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||
1168 | |||
931 | info("Attached STV0900+STB6100A!\n"); | 1169 | info("Attached STV0900+STB6100A!\n"); |
932 | 1170 | ||
933 | return 0; | 1171 | return 0; |
934 | } | 1172 | } |
935 | 1173 | ||
1174 | static int su3000_frontend_attach(struct dvb_usb_adapter *d) | ||
1175 | { | ||
1176 | u8 obuf[3] = { 0xe, 0x80, 0 }; | ||
1177 | u8 ibuf[] = { 0 }; | ||
1178 | |||
1179 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1180 | err("command 0x0e transfer failed."); | ||
1181 | |||
1182 | obuf[0] = 0xe; | ||
1183 | obuf[1] = 0x83; | ||
1184 | obuf[2] = 0; | ||
1185 | |||
1186 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1187 | err("command 0x0e transfer failed."); | ||
1188 | |||
1189 | obuf[0] = 0xe; | ||
1190 | obuf[1] = 0x83; | ||
1191 | obuf[2] = 1; | ||
1192 | |||
1193 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1194 | err("command 0x0e transfer failed."); | ||
1195 | |||
1196 | obuf[0] = 0x51; | ||
1197 | |||
1198 | if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | ||
1199 | err("command 0x51 transfer failed."); | ||
1200 | |||
1201 | d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, | ||
1202 | &d->dev->i2c_adap); | ||
1203 | if (d->fe == NULL) | ||
1204 | return -EIO; | ||
1205 | |||
1206 | info("Attached DS3000!\n"); | ||
1207 | |||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
936 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 1211 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) |
937 | { | 1212 | { |
938 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 1213 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -949,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | |||
949 | } | 1224 | } |
950 | 1225 | ||
951 | static struct rc_map_table rc_map_dw210x_table[] = { | 1226 | static struct rc_map_table rc_map_dw210x_table[] = { |
952 | { 0xf80a, KEY_Q }, /*power*/ | 1227 | { 0xf80a, KEY_POWER2 }, /*power*/ |
953 | { 0xf80c, KEY_M }, /*mute*/ | 1228 | { 0xf80c, KEY_MUTE }, /*mute*/ |
954 | { 0xf811, KEY_1 }, | 1229 | { 0xf811, KEY_1 }, |
955 | { 0xf812, KEY_2 }, | 1230 | { 0xf812, KEY_2 }, |
956 | { 0xf813, KEY_3 }, | 1231 | { 0xf813, KEY_3 }, |
@@ -961,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = { | |||
961 | { 0xf818, KEY_8 }, | 1236 | { 0xf818, KEY_8 }, |
962 | { 0xf819, KEY_9 }, | 1237 | { 0xf819, KEY_9 }, |
963 | { 0xf810, KEY_0 }, | 1238 | { 0xf810, KEY_0 }, |
964 | { 0xf81c, KEY_PAGEUP }, /*ch+*/ | 1239 | { 0xf81c, KEY_CHANNELUP }, /*ch+*/ |
965 | { 0xf80f, KEY_PAGEDOWN }, /*ch-*/ | 1240 | { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/ |
966 | { 0xf81a, KEY_O }, /*vol+*/ | 1241 | { 0xf81a, KEY_VOLUMEUP }, /*vol+*/ |
967 | { 0xf80e, KEY_Z }, /*vol-*/ | 1242 | { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/ |
968 | { 0xf804, KEY_R }, /*rec*/ | 1243 | { 0xf804, KEY_RECORD }, /*rec*/ |
969 | { 0xf809, KEY_D }, /*fav*/ | 1244 | { 0xf809, KEY_FAVORITES }, /*fav*/ |
970 | { 0xf808, KEY_BACKSPACE }, /*rewind*/ | 1245 | { 0xf808, KEY_REWIND }, /*rewind*/ |
971 | { 0xf807, KEY_A }, /*fast*/ | 1246 | { 0xf807, KEY_FASTFORWARD }, /*fast*/ |
972 | { 0xf80b, KEY_P }, /*pause*/ | 1247 | { 0xf80b, KEY_PAUSE }, /*pause*/ |
973 | { 0xf802, KEY_ESC }, /*cancel*/ | 1248 | { 0xf802, KEY_ESC }, /*cancel*/ |
974 | { 0xf803, KEY_G }, /*tab*/ | 1249 | { 0xf803, KEY_TAB }, /*tab*/ |
975 | { 0xf800, KEY_UP }, /*up*/ | 1250 | { 0xf800, KEY_UP }, /*up*/ |
976 | { 0xf81f, KEY_ENTER }, /*ok*/ | 1251 | { 0xf81f, KEY_OK }, /*ok*/ |
977 | { 0xf801, KEY_DOWN }, /*down*/ | 1252 | { 0xf801, KEY_DOWN }, /*down*/ |
978 | { 0xf805, KEY_C }, /*cap*/ | 1253 | { 0xf805, KEY_CAMERA }, /*cap*/ |
979 | { 0xf806, KEY_S }, /*stop*/ | 1254 | { 0xf806, KEY_STOP }, /*stop*/ |
980 | { 0xf840, KEY_F }, /*full*/ | 1255 | { 0xf840, KEY_ZOOM }, /*full*/ |
981 | { 0xf81e, KEY_W }, /*tvmode*/ | 1256 | { 0xf81e, KEY_TV }, /*tvmode*/ |
982 | { 0xf81b, KEY_B }, /*recall*/ | 1257 | { 0xf81b, KEY_LAST }, /*recall*/ |
983 | }; | 1258 | }; |
984 | 1259 | ||
985 | static struct rc_map_table rc_map_tevii_table[] = { | 1260 | static struct rc_map_table rc_map_tevii_table[] = { |
@@ -1067,10 +1342,49 @@ static struct rc_map_table rc_map_tbs_table[] = { | |||
1067 | { 0xf89b, KEY_MODE } | 1342 | { 0xf89b, KEY_MODE } |
1068 | }; | 1343 | }; |
1069 | 1344 | ||
1345 | static struct rc_map_table rc_map_su3000_table[] = { | ||
1346 | { 0x25, KEY_POWER }, /* right-bottom Red */ | ||
1347 | { 0x0a, KEY_MUTE }, /* -/-- */ | ||
1348 | { 0x01, KEY_1 }, | ||
1349 | { 0x02, KEY_2 }, | ||
1350 | { 0x03, KEY_3 }, | ||
1351 | { 0x04, KEY_4 }, | ||
1352 | { 0x05, KEY_5 }, | ||
1353 | { 0x06, KEY_6 }, | ||
1354 | { 0x07, KEY_7 }, | ||
1355 | { 0x08, KEY_8 }, | ||
1356 | { 0x09, KEY_9 }, | ||
1357 | { 0x00, KEY_0 }, | ||
1358 | { 0x20, KEY_UP }, /* CH+ */ | ||
1359 | { 0x21, KEY_DOWN }, /* CH+ */ | ||
1360 | { 0x12, KEY_VOLUMEUP }, /* Brightness Up */ | ||
1361 | { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */ | ||
1362 | { 0x1f, KEY_RECORD }, | ||
1363 | { 0x17, KEY_PLAY }, | ||
1364 | { 0x16, KEY_PAUSE }, | ||
1365 | { 0x0b, KEY_STOP }, | ||
1366 | { 0x27, KEY_FASTFORWARD },/* >> */ | ||
1367 | { 0x26, KEY_REWIND }, /* << */ | ||
1368 | { 0x0d, KEY_OK }, /* Mute */ | ||
1369 | { 0x11, KEY_LEFT }, /* VOL- */ | ||
1370 | { 0x10, KEY_RIGHT }, /* VOL+ */ | ||
1371 | { 0x29, KEY_BACK }, /* button under 9 */ | ||
1372 | { 0x2c, KEY_MENU }, /* TTX */ | ||
1373 | { 0x2b, KEY_EPG }, /* EPG */ | ||
1374 | { 0x1e, KEY_RED }, /* OSD */ | ||
1375 | { 0x0e, KEY_GREEN }, /* Window */ | ||
1376 | { 0x2d, KEY_YELLOW }, /* button under << */ | ||
1377 | { 0x0f, KEY_BLUE }, /* bottom yellow button */ | ||
1378 | { 0x14, KEY_AUDIO }, /* Snapshot */ | ||
1379 | { 0x38, KEY_TV }, /* TV/Radio */ | ||
1380 | { 0x0c, KEY_ESC } /* upper Red buttton */ | ||
1381 | }; | ||
1382 | |||
1070 | static struct rc_map_dvb_usb_table_table keys_tables[] = { | 1383 | static struct rc_map_dvb_usb_table_table keys_tables[] = { |
1071 | { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, | 1384 | { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, |
1072 | { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, | 1385 | { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, |
1073 | { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, | 1386 | { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, |
1387 | { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) }, | ||
1074 | }; | 1388 | }; |
1075 | 1389 | ||
1076 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 1390 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
@@ -1089,7 +1403,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
1089 | if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { | 1403 | if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { |
1090 | keymap = keys_tables[ir_keymap - 1].rc_keys ; | 1404 | keymap = keys_tables[ir_keymap - 1].rc_keys ; |
1091 | keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; | 1405 | keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; |
1092 | } | 1406 | } else if (ir_keymap > ARRAY_SIZE(keys_tables)) |
1407 | return 0; /* none */ | ||
1093 | 1408 | ||
1094 | *state = REMOTE_NO_KEY_PRESSED; | 1409 | *state = REMOTE_NO_KEY_PRESSED; |
1095 | if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { | 1410 | if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { |
@@ -1125,6 +1440,11 @@ static struct usb_device_id dw2102_table[] = { | |||
1125 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | 1440 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, |
1126 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | 1441 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, |
1127 | {USB_DEVICE(0x3034, 0x7500)}, | 1442 | {USB_DEVICE(0x3034, 0x7500)}, |
1443 | {USB_DEVICE(0x1f4d, 0x3000)}, | ||
1444 | {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, | ||
1445 | {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, | ||
1446 | {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, | ||
1447 | {USB_DEVICE(0x1f4d, 0x3100)}, | ||
1128 | { } | 1448 | { } |
1129 | }; | 1449 | }; |
1130 | 1450 | ||
@@ -1184,11 +1504,6 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
1184 | } | 1504 | } |
1185 | /* init registers */ | 1505 | /* init registers */ |
1186 | switch (dev->descriptor.idProduct) { | 1506 | switch (dev->descriptor.idProduct) { |
1187 | case USB_PID_PROF_1100: | ||
1188 | s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table; | ||
1189 | s6x0_properties.rc.legacy.rc_map_size = | ||
1190 | ARRAY_SIZE(rc_map_tbs_table); | ||
1191 | break; | ||
1192 | case USB_PID_TEVII_S650: | 1507 | case USB_PID_TEVII_S650: |
1193 | dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; | 1508 | dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; |
1194 | dw2104_properties.rc.legacy.rc_map_size = | 1509 | dw2104_properties.rc.legacy.rc_map_size = |
@@ -1271,8 +1586,6 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
1271 | .adapter = { | 1586 | .adapter = { |
1272 | { | 1587 | { |
1273 | .frontend_attach = dw2102_frontend_attach, | 1588 | .frontend_attach = dw2102_frontend_attach, |
1274 | .streaming_ctrl = NULL, | ||
1275 | .tuner_attach = NULL, | ||
1276 | .stream = { | 1589 | .stream = { |
1277 | .type = USB_BULK, | 1590 | .type = USB_BULK, |
1278 | .count = 8, | 1591 | .count = 8, |
@@ -1324,8 +1637,6 @@ static struct dvb_usb_device_properties dw2104_properties = { | |||
1324 | .adapter = { | 1637 | .adapter = { |
1325 | { | 1638 | { |
1326 | .frontend_attach = dw2104_frontend_attach, | 1639 | .frontend_attach = dw2104_frontend_attach, |
1327 | .streaming_ctrl = NULL, | ||
1328 | /*.tuner_attach = dw2104_tuner_attach,*/ | ||
1329 | .stream = { | 1640 | .stream = { |
1330 | .type = USB_BULK, | 1641 | .type = USB_BULK, |
1331 | .count = 8, | 1642 | .count = 8, |
@@ -1373,7 +1684,6 @@ static struct dvb_usb_device_properties dw3101_properties = { | |||
1373 | .adapter = { | 1684 | .adapter = { |
1374 | { | 1685 | { |
1375 | .frontend_attach = dw3101_frontend_attach, | 1686 | .frontend_attach = dw3101_frontend_attach, |
1376 | .streaming_ctrl = NULL, | ||
1377 | .tuner_attach = dw3101_tuner_attach, | 1687 | .tuner_attach = dw3101_tuner_attach, |
1378 | .stream = { | 1688 | .stream = { |
1379 | .type = USB_BULK, | 1689 | .type = USB_BULK, |
@@ -1399,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = { | |||
1399 | static struct dvb_usb_device_properties s6x0_properties = { | 1709 | static struct dvb_usb_device_properties s6x0_properties = { |
1400 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1710 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1401 | .usb_ctrl = DEVICE_SPECIFIC, | 1711 | .usb_ctrl = DEVICE_SPECIFIC, |
1712 | .size_of_priv = sizeof(struct s6x0_state), | ||
1402 | .firmware = "dvb-usb-s630.fw", | 1713 | .firmware = "dvb-usb-s630.fw", |
1403 | .no_reconnect = 1, | 1714 | .no_reconnect = 1, |
1404 | 1715 | ||
@@ -1416,9 +1727,7 @@ static struct dvb_usb_device_properties s6x0_properties = { | |||
1416 | .read_mac_address = s6x0_read_mac_address, | 1727 | .read_mac_address = s6x0_read_mac_address, |
1417 | .adapter = { | 1728 | .adapter = { |
1418 | { | 1729 | { |
1419 | .frontend_attach = s6x0_frontend_attach, | 1730 | .frontend_attach = zl100313_frontend_attach, |
1420 | .streaming_ctrl = NULL, | ||
1421 | .tuner_attach = NULL, | ||
1422 | .stream = { | 1731 | .stream = { |
1423 | .type = USB_BULK, | 1732 | .type = USB_BULK, |
1424 | .count = 8, | 1733 | .count = 8, |
@@ -1431,23 +1740,41 @@ static struct dvb_usb_device_properties s6x0_properties = { | |||
1431 | }, | 1740 | }, |
1432 | } | 1741 | } |
1433 | }, | 1742 | }, |
1434 | .num_device_descs = 3, | 1743 | .num_device_descs = 1, |
1435 | .devices = { | 1744 | .devices = { |
1436 | {"TeVii S630 USB", | 1745 | {"TeVii S630 USB", |
1437 | {&dw2102_table[6], NULL}, | 1746 | {&dw2102_table[6], NULL}, |
1438 | {NULL}, | 1747 | {NULL}, |
1439 | }, | 1748 | }, |
1440 | {"Prof 1100 USB ", | ||
1441 | {&dw2102_table[7], NULL}, | ||
1442 | {NULL}, | ||
1443 | }, | ||
1444 | {"TeVii S660 USB", | ||
1445 | {&dw2102_table[8], NULL}, | ||
1446 | {NULL}, | ||
1447 | }, | ||
1448 | } | 1749 | } |
1449 | }; | 1750 | }; |
1450 | 1751 | ||
1752 | struct dvb_usb_device_properties *p1100; | ||
1753 | static struct dvb_usb_device_description d1100 = { | ||
1754 | "Prof 1100 USB ", | ||
1755 | {&dw2102_table[7], NULL}, | ||
1756 | {NULL}, | ||
1757 | }; | ||
1758 | |||
1759 | struct dvb_usb_device_properties *s660; | ||
1760 | static struct dvb_usb_device_description d660 = { | ||
1761 | "TeVii S660 USB", | ||
1762 | {&dw2102_table[8], NULL}, | ||
1763 | {NULL}, | ||
1764 | }; | ||
1765 | |||
1766 | static struct dvb_usb_device_description d480_1 = { | ||
1767 | "TeVii S480.1 USB", | ||
1768 | {&dw2102_table[12], NULL}, | ||
1769 | {NULL}, | ||
1770 | }; | ||
1771 | |||
1772 | static struct dvb_usb_device_description d480_2 = { | ||
1773 | "TeVii S480.2 USB", | ||
1774 | {&dw2102_table[13], NULL}, | ||
1775 | {NULL}, | ||
1776 | }; | ||
1777 | |||
1451 | struct dvb_usb_device_properties *p7500; | 1778 | struct dvb_usb_device_properties *p7500; |
1452 | static struct dvb_usb_device_description d7500 = { | 1779 | static struct dvb_usb_device_description d7500 = { |
1453 | "Prof 7500 USB DVB-S2", | 1780 | "Prof 7500 USB DVB-S2", |
@@ -1455,17 +1782,97 @@ static struct dvb_usb_device_description d7500 = { | |||
1455 | {NULL}, | 1782 | {NULL}, |
1456 | }; | 1783 | }; |
1457 | 1784 | ||
1785 | static struct dvb_usb_device_properties su3000_properties = { | ||
1786 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1787 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1788 | .size_of_priv = sizeof(struct su3000_state), | ||
1789 | .power_ctrl = su3000_power_ctrl, | ||
1790 | .num_adapters = 1, | ||
1791 | .identify_state = su3000_identify_state, | ||
1792 | .i2c_algo = &su3000_i2c_algo, | ||
1793 | |||
1794 | .rc.legacy = { | ||
1795 | .rc_map_table = rc_map_su3000_table, | ||
1796 | .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), | ||
1797 | .rc_interval = 150, | ||
1798 | .rc_query = dw2102_rc_query, | ||
1799 | }, | ||
1800 | |||
1801 | .read_mac_address = su3000_read_mac_address, | ||
1802 | |||
1803 | .generic_bulk_ctrl_endpoint = 0x01, | ||
1804 | |||
1805 | .adapter = { | ||
1806 | { | ||
1807 | .streaming_ctrl = su3000_streaming_ctrl, | ||
1808 | .frontend_attach = su3000_frontend_attach, | ||
1809 | .stream = { | ||
1810 | .type = USB_BULK, | ||
1811 | .count = 8, | ||
1812 | .endpoint = 0x82, | ||
1813 | .u = { | ||
1814 | .bulk = { | ||
1815 | .buffersize = 4096, | ||
1816 | } | ||
1817 | } | ||
1818 | } | ||
1819 | } | ||
1820 | }, | ||
1821 | .num_device_descs = 3, | ||
1822 | .devices = { | ||
1823 | { "SU3000HD DVB-S USB2.0", | ||
1824 | { &dw2102_table[10], NULL }, | ||
1825 | { NULL }, | ||
1826 | }, | ||
1827 | { "Terratec Cinergy S2 USB HD", | ||
1828 | { &dw2102_table[11], NULL }, | ||
1829 | { NULL }, | ||
1830 | }, | ||
1831 | { "X3M TV SPC1400HD PCI", | ||
1832 | { &dw2102_table[14], NULL }, | ||
1833 | { NULL }, | ||
1834 | }, | ||
1835 | } | ||
1836 | }; | ||
1837 | |||
1458 | static int dw2102_probe(struct usb_interface *intf, | 1838 | static int dw2102_probe(struct usb_interface *intf, |
1459 | const struct usb_device_id *id) | 1839 | const struct usb_device_id *id) |
1460 | { | 1840 | { |
1841 | p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1842 | if (!p1100) | ||
1843 | return -ENOMEM; | ||
1844 | /* copy default structure */ | ||
1845 | memcpy(p1100, &s6x0_properties, | ||
1846 | sizeof(struct dvb_usb_device_properties)); | ||
1847 | /* fill only different fields */ | ||
1848 | p1100->firmware = "dvb-usb-p1100.fw"; | ||
1849 | p1100->devices[0] = d1100; | ||
1850 | p1100->rc.legacy.rc_map_table = rc_map_tbs_table; | ||
1851 | p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); | ||
1852 | p1100->adapter->frontend_attach = stv0288_frontend_attach; | ||
1853 | |||
1854 | s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1855 | if (!s660) { | ||
1856 | kfree(p1100); | ||
1857 | return -ENOMEM; | ||
1858 | } | ||
1859 | memcpy(s660, &s6x0_properties, | ||
1860 | sizeof(struct dvb_usb_device_properties)); | ||
1861 | s660->firmware = "dvb-usb-s660.fw"; | ||
1862 | s660->num_device_descs = 3; | ||
1863 | s660->devices[0] = d660; | ||
1864 | s660->devices[1] = d480_1; | ||
1865 | s660->devices[2] = d480_2; | ||
1866 | s660->adapter->frontend_attach = ds3000_frontend_attach; | ||
1461 | 1867 | ||
1462 | p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | 1868 | p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
1463 | if (!p7500) | 1869 | if (!p7500) { |
1870 | kfree(p1100); | ||
1871 | kfree(s660); | ||
1464 | return -ENOMEM; | 1872 | return -ENOMEM; |
1465 | /* copy default structure */ | 1873 | } |
1466 | memcpy(p7500, &s6x0_properties, | 1874 | memcpy(p7500, &s6x0_properties, |
1467 | sizeof(struct dvb_usb_device_properties)); | 1875 | sizeof(struct dvb_usb_device_properties)); |
1468 | /* fill only different fields */ | ||
1469 | p7500->firmware = "dvb-usb-p7500.fw"; | 1876 | p7500->firmware = "dvb-usb-p7500.fw"; |
1470 | p7500->devices[0] = d7500; | 1877 | p7500->devices[0] = d7500; |
1471 | p7500->rc.legacy.rc_map_table = rc_map_tbs_table; | 1878 | p7500->rc.legacy.rc_map_table = rc_map_tbs_table; |
@@ -1480,8 +1887,14 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1480 | THIS_MODULE, NULL, adapter_nr) || | 1887 | THIS_MODULE, NULL, adapter_nr) || |
1481 | 0 == dvb_usb_device_init(intf, &s6x0_properties, | 1888 | 0 == dvb_usb_device_init(intf, &s6x0_properties, |
1482 | THIS_MODULE, NULL, adapter_nr) || | 1889 | THIS_MODULE, NULL, adapter_nr) || |
1890 | 0 == dvb_usb_device_init(intf, p1100, | ||
1891 | THIS_MODULE, NULL, adapter_nr) || | ||
1892 | 0 == dvb_usb_device_init(intf, s660, | ||
1893 | THIS_MODULE, NULL, adapter_nr) || | ||
1483 | 0 == dvb_usb_device_init(intf, p7500, | 1894 | 0 == dvb_usb_device_init(intf, p7500, |
1484 | THIS_MODULE, NULL, adapter_nr)) | 1895 | THIS_MODULE, NULL, adapter_nr) || |
1896 | 0 == dvb_usb_device_init(intf, &su3000_properties, | ||
1897 | THIS_MODULE, NULL, adapter_nr)) | ||
1485 | return 0; | 1898 | return 0; |
1486 | 1899 | ||
1487 | return -ENODEV; | 1900 | return -ENODEV; |
@@ -1514,7 +1927,8 @@ module_exit(dw2102_module_exit); | |||
1514 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1927 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
1515 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1928 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1516 | " DVB-C 3101 USB2.0," | 1929 | " DVB-C 3101 USB2.0," |
1517 | " TeVii S600, S630, S650, S660 USB2.0," | 1930 | " TeVii S600, S630, S650, S660, S480," |
1518 | " Prof 1100, 7500 USB2.0 devices"); | 1931 | " Prof 1100, 7500 USB2.0," |
1932 | " Geniatech SU3000 devices"); | ||
1519 | MODULE_VERSION("0.1"); | 1933 | MODULE_VERSION("0.1"); |
1520 | MODULE_LICENSE("GPL"); | 1934 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 46ccd01a7696..cd26e7c1536a 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c | |||
@@ -2,7 +2,9 @@ | |||
2 | * | 2 | * |
3 | * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 | 3 | * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 |
4 | * LME2510C + LG TDQY-P001F | 4 | * LME2510C + LG TDQY-P001F |
5 | * LME2510C + BS2F7HZ0194 | ||
5 | * LME2510 + LG TDQY-P001F | 6 | * LME2510 + LG TDQY-P001F |
7 | * LME2510 + BS2F7HZ0194 | ||
6 | * | 8 | * |
7 | * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) | 9 | * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) |
8 | * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) | 10 | * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) |
@@ -12,20 +14,22 @@ | |||
12 | * | 14 | * |
13 | * MVB0001F (LME2510C+LGTDQT-P001F) | 15 | * MVB0001F (LME2510C+LGTDQT-P001F) |
14 | * | 16 | * |
17 | * MV0194 (LME2510+SHARP:BS2F7HZ0194) | ||
18 | * SHARP:BS2F7HZ0194 = (STV0299+IX2410) | ||
19 | * | ||
20 | * MVB0194 (LME2510C+SHARP0194) | ||
21 | * | ||
15 | * For firmware see Documentation/dvb/lmedm04.txt | 22 | * For firmware see Documentation/dvb/lmedm04.txt |
16 | * | 23 | * |
17 | * I2C addresses: | 24 | * I2C addresses: |
18 | * 0xd0 - STV0288 - Demodulator | 25 | * 0xd0 - STV0288 - Demodulator |
19 | * 0xc0 - Sharp IX2505V - Tuner | 26 | * 0xc0 - Sharp IX2505V - Tuner |
20 | * --or-- | 27 | * -- |
21 | * 0x1c - TDA10086 - Demodulator | 28 | * 0x1c - TDA10086 - Demodulator |
22 | * 0xc0 - TDA8263 - Tuner | 29 | * 0xc0 - TDA8263 - Tuner |
23 | * | 30 | * -- |
24 | * ***Please Note*** | 31 | * 0xd0 - STV0299 - Demodulator |
25 | * There are other variants of the DM04 | 32 | * 0xc0 - IX2410 - Tuner |
26 | * ***NOT SUPPORTED*** | ||
27 | * MV0194 (LME2510+SHARP0194) | ||
28 | * MVB0194 (LME2510C+SHARP0194) | ||
29 | * | 33 | * |
30 | * | 34 | * |
31 | * VID = 3344 PID LME2510=1122 LME2510C=1120 | 35 | * VID = 3344 PID LME2510=1122 LME2510C=1120 |
@@ -55,6 +59,9 @@ | |||
55 | * | 59 | * |
56 | * QQbox suffers from noise on LNB voltage. | 60 | * QQbox suffers from noise on LNB voltage. |
57 | * | 61 | * |
62 | * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system | ||
63 | * with other tuners. After a cold reset streaming will not start. | ||
64 | * | ||
58 | * PID functions have been removed from this driver version due to | 65 | * PID functions have been removed from this driver version due to |
59 | * problems with different firmware and application versions. | 66 | * problems with different firmware and application versions. |
60 | */ | 67 | */ |
@@ -69,6 +76,9 @@ | |||
69 | #include "tda10086.h" | 76 | #include "tda10086.h" |
70 | #include "stv0288.h" | 77 | #include "stv0288.h" |
71 | #include "ix2505v.h" | 78 | #include "ix2505v.h" |
79 | #include "stv0299.h" | ||
80 | #include "dvb-pll.h" | ||
81 | #include "z0194a.h" | ||
72 | 82 | ||
73 | 83 | ||
74 | 84 | ||
@@ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG"); | |||
96 | 106 | ||
97 | 107 | ||
98 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 108 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
109 | |||
110 | #define TUNER_DEFAULT 0x0 | ||
99 | #define TUNER_LG 0x1 | 111 | #define TUNER_LG 0x1 |
100 | #define TUNER_S7395 0x2 | 112 | #define TUNER_S7395 0x2 |
113 | #define TUNER_S0194 0x3 | ||
101 | 114 | ||
102 | struct lme2510_state { | 115 | struct lme2510_state { |
103 | u8 id; | 116 | u8 id; |
@@ -191,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d) | |||
191 | rbuff, sizeof(rbuff)); | 204 | rbuff, sizeof(rbuff)); |
192 | return ret; | 205 | return ret; |
193 | } | 206 | } |
194 | static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) | 207 | static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress) |
195 | { | 208 | { |
196 | struct dvb_usb_device *d = adap->dev; | 209 | struct dvb_usb_device *d = adap->dev; |
197 | 210 | ||
@@ -237,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb) | |||
237 | case 0xaa: | 250 | case 0xaa: |
238 | debug_data_snipet(1, "INT Remote data snipet in", ibuf); | 251 | debug_data_snipet(1, "INT Remote data snipet in", ibuf); |
239 | lme2510_remote_keypress(adap, | 252 | lme2510_remote_keypress(adap, |
240 | (u16)(ibuf[4]<<8)+ibuf[5]); | 253 | (u32)(ibuf[2] << 24) + (ibuf[3] << 16) + |
254 | (ibuf[4] << 8) + ibuf[5]); | ||
241 | break; | 255 | break; |
242 | case 0xbb: | 256 | case 0xbb: |
243 | switch (st->tuner_config) { | 257 | switch (st->tuner_config) { |
@@ -249,6 +263,7 @@ static void lme2510_int_response(struct urb *lme_urb) | |||
249 | st->time_key = ibuf[7]; | 263 | st->time_key = ibuf[7]; |
250 | break; | 264 | break; |
251 | case TUNER_S7395: | 265 | case TUNER_S7395: |
266 | case TUNER_S0194: | ||
252 | /* Tweak for earlier firmware*/ | 267 | /* Tweak for earlier firmware*/ |
253 | if (ibuf[1] == 0x03) { | 268 | if (ibuf[1] == 0x03) { |
254 | if (ibuf[2] > 1) | 269 | if (ibuf[2] > 1) |
@@ -364,6 +379,18 @@ static int lme2510_msg(struct dvb_usb_device *d, | |||
364 | msleep(5); | 379 | msleep(5); |
365 | } | 380 | } |
366 | break; | 381 | break; |
382 | case TUNER_S0194: | ||
383 | if (wbuf[2] == 0xd0) { | ||
384 | if (wbuf[3] == 0x1b) { | ||
385 | st->signal_lock = rbuf[1]; | ||
386 | if ((st->stream_on & 1) && | ||
387 | (st->signal_lock & 0x8)) { | ||
388 | lme2510_stream_restart(d); | ||
389 | st->i2c_talk_onoff = 0; | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | break; | ||
367 | default: | 394 | default: |
368 | break; | 395 | break; |
369 | } | 396 | } |
@@ -423,6 +450,34 @@ static int lme2510_msg(struct dvb_usb_device *d, | |||
423 | break; | 450 | break; |
424 | } | 451 | } |
425 | break; | 452 | break; |
453 | case TUNER_S0194: | ||
454 | switch (wbuf[3]) { | ||
455 | case 0x18: | ||
456 | rbuf[0] = 0x55; | ||
457 | rbuf[1] = (st->signal_level & 0x80) | ||
458 | ? 0 : (st->signal_level * 2); | ||
459 | break; | ||
460 | case 0x24: | ||
461 | rbuf[0] = 0x55; | ||
462 | rbuf[1] = st->signal_sn; | ||
463 | break; | ||
464 | case 0x1b: | ||
465 | rbuf[0] = 0x55; | ||
466 | rbuf[1] = st->signal_lock; | ||
467 | break; | ||
468 | case 0x19: | ||
469 | case 0x25: | ||
470 | case 0x1e: | ||
471 | case 0x1d: | ||
472 | rbuf[0] = 0x55; | ||
473 | rbuf[1] = 0x00; | ||
474 | break; | ||
475 | default: | ||
476 | lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); | ||
477 | st->i2c_talk_onoff = 1; | ||
478 | break; | ||
479 | } | ||
480 | break; | ||
426 | default: | 481 | default: |
427 | break; | 482 | break; |
428 | } | 483 | } |
@@ -517,17 +572,14 @@ static int lme2510_identify_state(struct usb_device *udev, | |||
517 | struct dvb_usb_device_description **desc, | 572 | struct dvb_usb_device_description **desc, |
518 | int *cold) | 573 | int *cold) |
519 | { | 574 | { |
520 | if (lme2510_return_status(udev) == 0x44) | 575 | *cold = 0; |
521 | *cold = 1; | ||
522 | else | ||
523 | *cold = 0; | ||
524 | return 0; | 576 | return 0; |
525 | } | 577 | } |
526 | 578 | ||
527 | static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | 579 | static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
528 | { | 580 | { |
529 | struct lme2510_state *st = adap->dev->priv; | 581 | struct lme2510_state *st = adap->dev->priv; |
530 | static u8 clear_reg_3[] = LME_CLEAR_PID; | 582 | static u8 clear_reg_3[] = LME_CLEAR_PID; |
531 | static u8 rbuf[1]; | 583 | static u8 rbuf[1]; |
532 | int ret = 0, rlen = sizeof(rbuf); | 584 | int ret = 0, rlen = sizeof(rbuf); |
533 | 585 | ||
@@ -658,9 +710,6 @@ static int lme2510_download_firmware(struct usb_device *dev, | |||
658 | return (ret < 0) ? -ENODEV : 0; | 710 | return (ret < 0) ? -ENODEV : 0; |
659 | } | 711 | } |
660 | 712 | ||
661 | /* Default firmware for LME2510C */ | ||
662 | char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; | ||
663 | |||
664 | static void lme_coldreset(struct usb_device *dev) | 713 | static void lme_coldreset(struct usb_device *dev) |
665 | { | 714 | { |
666 | int ret = 0, len_in; | 715 | int ret = 0, len_in; |
@@ -678,49 +727,83 @@ static void lme_coldreset(struct usb_device *dev) | |||
678 | static int lme_firmware_switch(struct usb_device *udev, int cold) | 727 | static int lme_firmware_switch(struct usb_device *udev, int cold) |
679 | { | 728 | { |
680 | const struct firmware *fw = NULL; | 729 | const struct firmware *fw = NULL; |
681 | char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; | 730 | const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; |
682 | char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; | 731 | const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw"; |
683 | char *firm_msg[] = {"Loading", "Switching to"}; | 732 | const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw"; |
684 | int ret; | 733 | const char fw_lg[] = "dvb-usb-lme2510-lg.fw"; |
734 | const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw"; | ||
735 | const char *fw_lme; | ||
736 | int ret, cold_fw; | ||
685 | 737 | ||
686 | cold = (cold > 0) ? (cold & 1) : 0; | 738 | cold = (cold > 0) ? (cold & 1) : 0; |
687 | 739 | ||
688 | if (udev->descriptor.idProduct == 0x1122) | 740 | cold_fw = !cold; |
689 | return 0; | ||
690 | 741 | ||
691 | switch (dvb_usb_lme2510_firmware) { | 742 | if (udev->descriptor.idProduct == 0x1122) { |
692 | case 0: | 743 | switch (dvb_usb_lme2510_firmware) { |
693 | default: | 744 | default: |
694 | memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); | 745 | dvb_usb_lme2510_firmware = TUNER_S0194; |
695 | ret = request_firmware(&fw, lme_firmware, &udev->dev); | 746 | case TUNER_S0194: |
696 | if (ret == 0) { | 747 | fw_lme = fw_s0194; |
697 | info("FRM %s S7395 Firmware", firm_msg[cold]); | 748 | ret = request_firmware(&fw, fw_lme, &udev->dev); |
749 | if (ret == 0) { | ||
750 | cold = 0;/*lme2510-s0194 cannot cold reset*/ | ||
751 | break; | ||
752 | } | ||
753 | dvb_usb_lme2510_firmware = TUNER_LG; | ||
754 | case TUNER_LG: | ||
755 | fw_lme = fw_lg; | ||
756 | ret = request_firmware(&fw, fw_lme, &udev->dev); | ||
757 | if (ret == 0) | ||
758 | break; | ||
759 | info("FRM No Firmware Found - please install"); | ||
760 | dvb_usb_lme2510_firmware = TUNER_DEFAULT; | ||
761 | cold = 0; | ||
762 | cold_fw = 0; | ||
698 | break; | 763 | break; |
699 | } | 764 | } |
700 | if (cold == 0) | 765 | } else { |
701 | dvb_usb_lme2510_firmware = 1; | 766 | switch (dvb_usb_lme2510_firmware) { |
702 | else | 767 | default: |
768 | dvb_usb_lme2510_firmware = TUNER_S7395; | ||
769 | case TUNER_S7395: | ||
770 | fw_lme = fw_c_s7395; | ||
771 | ret = request_firmware(&fw, fw_lme, &udev->dev); | ||
772 | if (ret == 0) | ||
773 | break; | ||
774 | dvb_usb_lme2510_firmware = TUNER_LG; | ||
775 | case TUNER_LG: | ||
776 | fw_lme = fw_c_lg; | ||
777 | ret = request_firmware(&fw, fw_lme, &udev->dev); | ||
778 | if (ret == 0) | ||
779 | break; | ||
780 | dvb_usb_lme2510_firmware = TUNER_S0194; | ||
781 | case TUNER_S0194: | ||
782 | fw_lme = fw_c_s0194; | ||
783 | ret = request_firmware(&fw, fw_lme, &udev->dev); | ||
784 | if (ret == 0) | ||
785 | break; | ||
786 | info("FRM No Firmware Found - please install"); | ||
787 | dvb_usb_lme2510_firmware = TUNER_DEFAULT; | ||
703 | cold = 0; | 788 | cold = 0; |
704 | case 1: | 789 | cold_fw = 0; |
705 | memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg)); | ||
706 | ret = request_firmware(&fw, lme_firmware, &udev->dev); | ||
707 | if (ret == 0) { | ||
708 | info("FRM %s LG Firmware", firm_msg[cold]); | ||
709 | break; | 790 | break; |
710 | } | 791 | } |
711 | info("FRM No Firmware Found - please install"); | ||
712 | dvb_usb_lme2510_firmware = 0; | ||
713 | cold = 0; | ||
714 | break; | ||
715 | } | 792 | } |
716 | 793 | ||
717 | release_firmware(fw); | 794 | if (cold_fw) { |
795 | info("FRM Loading %s file", fw_lme); | ||
796 | ret = lme2510_download_firmware(udev, fw); | ||
797 | } | ||
718 | 798 | ||
719 | if (cold) { | 799 | if (cold) { |
800 | info("FRM Changing to %s firmware", fw_lme); | ||
720 | lme_coldreset(udev); | 801 | lme_coldreset(udev); |
721 | return -ENODEV; | 802 | return -ENODEV; |
722 | } | 803 | } |
723 | 804 | ||
805 | release_firmware(fw); | ||
806 | |||
724 | return ret; | 807 | return ret; |
725 | } | 808 | } |
726 | 809 | ||
@@ -758,6 +841,18 @@ static struct ix2505v_config lme_tuner = { | |||
758 | .tuner_chargepump = 0x3, | 841 | .tuner_chargepump = 0x3, |
759 | }; | 842 | }; |
760 | 843 | ||
844 | static struct stv0299_config sharp_z0194_config = { | ||
845 | .demod_address = 0xd0, | ||
846 | .inittab = sharp_z0194a_inittab, | ||
847 | .mclk = 88000000UL, | ||
848 | .invert = 0, | ||
849 | .skip_reinit = 0, | ||
850 | .lock_output = STV0299_LOCKOUTPUT_1, | ||
851 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
852 | .min_delay_ms = 100, | ||
853 | .set_symbol_rate = sharp_z0194a_set_symbol_rate, | ||
854 | }; | ||
855 | |||
761 | static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, | 856 | static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, |
762 | fe_sec_voltage_t voltage) | 857 | fe_sec_voltage_t voltage) |
763 | { | 858 | { |
@@ -793,7 +888,8 @@ static int lme_name(struct dvb_usb_adapter *adap) | |||
793 | { | 888 | { |
794 | struct lme2510_state *st = adap->dev->priv; | 889 | struct lme2510_state *st = adap->dev->priv; |
795 | const char *desc = adap->dev->desc->name; | 890 | const char *desc = adap->dev->desc->name; |
796 | char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"}; | 891 | char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", |
892 | " SHARP:BS2F7HZ0194"}; | ||
797 | char *name = adap->fe->ops.info.name; | 893 | char *name = adap->fe->ops.info.name; |
798 | 894 | ||
799 | strlcpy(name, desc, 128); | 895 | strlcpy(name, desc, 128); |
@@ -820,26 +916,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) | |||
820 | st->i2c_tuner_gate_r = 4; | 916 | st->i2c_tuner_gate_r = 4; |
821 | st->i2c_tuner_addr = 0xc0; | 917 | st->i2c_tuner_addr = 0xc0; |
822 | st->tuner_config = TUNER_LG; | 918 | st->tuner_config = TUNER_LG; |
823 | if (dvb_usb_lme2510_firmware != 1) { | 919 | if (dvb_usb_lme2510_firmware != TUNER_LG) { |
824 | dvb_usb_lme2510_firmware = 1; | 920 | dvb_usb_lme2510_firmware = TUNER_LG; |
825 | ret = lme_firmware_switch(adap->dev->udev, 1); | 921 | ret = lme_firmware_switch(adap->dev->udev, 1); |
826 | } else /*stops LG/Sharp multi tuner problems*/ | 922 | } |
827 | dvb_usb_lme2510_firmware = 0; | 923 | goto end; |
924 | } | ||
925 | |||
926 | st->i2c_gate = 4; | ||
927 | adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config, | ||
928 | &adap->dev->i2c_adap); | ||
929 | if (adap->fe) { | ||
930 | info("FE Found Stv0299"); | ||
931 | st->i2c_tuner_gate_w = 4; | ||
932 | st->i2c_tuner_gate_r = 5; | ||
933 | st->i2c_tuner_addr = 0xc0; | ||
934 | st->tuner_config = TUNER_S0194; | ||
935 | if (dvb_usb_lme2510_firmware != TUNER_S0194) { | ||
936 | dvb_usb_lme2510_firmware = TUNER_S0194; | ||
937 | ret = lme_firmware_switch(adap->dev->udev, 1); | ||
938 | } | ||
828 | goto end; | 939 | goto end; |
829 | } | 940 | } |
830 | 941 | ||
831 | st->i2c_gate = 5; | 942 | st->i2c_gate = 5; |
832 | adap->fe = dvb_attach(stv0288_attach, &lme_config, | 943 | adap->fe = dvb_attach(stv0288_attach, &lme_config, |
833 | &adap->dev->i2c_adap); | 944 | &adap->dev->i2c_adap); |
834 | |||
835 | if (adap->fe) { | 945 | if (adap->fe) { |
836 | info("FE Found Stv0288"); | 946 | info("FE Found Stv0288"); |
837 | st->i2c_tuner_gate_w = 4; | 947 | st->i2c_tuner_gate_w = 4; |
838 | st->i2c_tuner_gate_r = 5; | 948 | st->i2c_tuner_gate_r = 5; |
839 | st->i2c_tuner_addr = 0xc0; | 949 | st->i2c_tuner_addr = 0xc0; |
840 | st->tuner_config = TUNER_S7395; | 950 | st->tuner_config = TUNER_S7395; |
841 | if (dvb_usb_lme2510_firmware != 0) { | 951 | if (dvb_usb_lme2510_firmware != TUNER_S7395) { |
842 | dvb_usb_lme2510_firmware = 0; | 952 | dvb_usb_lme2510_firmware = TUNER_S7395; |
843 | ret = lme_firmware_switch(adap->dev->udev, 1); | 953 | ret = lme_firmware_switch(adap->dev->udev, 1); |
844 | } | 954 | } |
845 | } else { | 955 | } else { |
@@ -847,6 +957,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) | |||
847 | return -ENODEV; | 957 | return -ENODEV; |
848 | } | 958 | } |
849 | 959 | ||
960 | |||
850 | end: if (ret) { | 961 | end: if (ret) { |
851 | kfree(adap->fe); | 962 | kfree(adap->fe); |
852 | adap->fe = NULL; | 963 | adap->fe = NULL; |
@@ -855,14 +966,13 @@ end: if (ret) { | |||
855 | 966 | ||
856 | adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; | 967 | adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; |
857 | ret = lme_name(adap); | 968 | ret = lme_name(adap); |
858 | |||
859 | return ret; | 969 | return ret; |
860 | } | 970 | } |
861 | 971 | ||
862 | static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) | 972 | static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) |
863 | { | 973 | { |
864 | struct lme2510_state *st = adap->dev->priv; | 974 | struct lme2510_state *st = adap->dev->priv; |
865 | char *tun_msg[] = {"", "TDA8263", "IX2505V"}; | 975 | char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"}; |
866 | int ret = 0; | 976 | int ret = 0; |
867 | 977 | ||
868 | switch (st->tuner_config) { | 978 | switch (st->tuner_config) { |
@@ -876,6 +986,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) | |||
876 | &adap->dev->i2c_adap)) | 986 | &adap->dev->i2c_adap)) |
877 | ret = st->tuner_config; | 987 | ret = st->tuner_config; |
878 | break; | 988 | break; |
989 | case TUNER_S0194: | ||
990 | if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0, | ||
991 | &adap->dev->i2c_adap, DVB_PLL_OPERA1)) | ||
992 | ret = st->tuner_config; | ||
993 | break; | ||
879 | default: | 994 | default: |
880 | break; | 995 | break; |
881 | } | 996 | } |
@@ -936,7 +1051,10 @@ static int lme2510_probe(struct usb_interface *intf, | |||
936 | return -ENODEV; | 1051 | return -ENODEV; |
937 | } | 1052 | } |
938 | 1053 | ||
939 | lme_firmware_switch(udev, 0); | 1054 | if (lme2510_return_status(udev) == 0x44) { |
1055 | lme_firmware_switch(udev, 0); | ||
1056 | return -ENODEV; | ||
1057 | } | ||
940 | 1058 | ||
941 | if (0 == dvb_usb_device_init(intf, &lme2510_properties, | 1059 | if (0 == dvb_usb_device_init(intf, &lme2510_properties, |
942 | THIS_MODULE, NULL, adapter_nr)) { | 1060 | THIS_MODULE, NULL, adapter_nr)) { |
@@ -964,10 +1082,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table); | |||
964 | 1082 | ||
965 | static struct dvb_usb_device_properties lme2510_properties = { | 1083 | static struct dvb_usb_device_properties lme2510_properties = { |
966 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1084 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
967 | .usb_ctrl = DEVICE_SPECIFIC, | ||
968 | .download_firmware = lme2510_download_firmware, | ||
969 | .firmware = "dvb-usb-lme2510-lg.fw", | ||
970 | |||
971 | .size_of_priv = sizeof(struct lme2510_state), | 1085 | .size_of_priv = sizeof(struct lme2510_state), |
972 | .num_adapters = 1, | 1086 | .num_adapters = 1, |
973 | .adapter = { | 1087 | .adapter = { |
@@ -1004,9 +1118,6 @@ static struct dvb_usb_device_properties lme2510_properties = { | |||
1004 | 1118 | ||
1005 | static struct dvb_usb_device_properties lme2510c_properties = { | 1119 | static struct dvb_usb_device_properties lme2510c_properties = { |
1006 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1120 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1007 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1008 | .download_firmware = lme2510_download_firmware, | ||
1009 | .firmware = (const char *)&lme_firmware, | ||
1010 | .size_of_priv = sizeof(struct lme2510_state), | 1121 | .size_of_priv = sizeof(struct lme2510_state), |
1011 | .num_adapters = 1, | 1122 | .num_adapters = 1, |
1012 | .adapter = { | 1123 | .adapter = { |
@@ -1109,5 +1220,5 @@ module_exit(lme2510_module_exit); | |||
1109 | 1220 | ||
1110 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); | 1221 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); |
1111 | MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); | 1222 | MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); |
1112 | MODULE_VERSION("1.75"); | 1223 | MODULE_VERSION("1.80"); |
1113 | MODULE_LICENSE("GPL"); | 1224 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 1f1b7d6980a5..7e569f4dd80b 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c | |||
@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = { | |||
342 | {0x49b6, KEY_8}, | 342 | {0x49b6, KEY_8}, |
343 | {0x05fa, KEY_9}, | 343 | {0x05fa, KEY_9}, |
344 | {0x45ba, KEY_0}, | 344 | {0x45ba, KEY_0}, |
345 | {0x09f6, KEY_UP}, /*chanup */ | 345 | {0x09f6, KEY_CHANNELUP}, /*chanup */ |
346 | {0x1be5, KEY_DOWN}, /*chandown */ | 346 | {0x1be5, KEY_CHANNELDOWN}, /*chandown */ |
347 | {0x5da3, KEY_LEFT}, /*voldown */ | 347 | {0x5da3, KEY_VOLUMEDOWN}, /*voldown */ |
348 | {0x5fa1, KEY_RIGHT}, /*volup */ | 348 | {0x5fa1, KEY_VOLUMEUP}, /*volup */ |
349 | {0x07f8, KEY_SPACE}, /*tab */ | 349 | {0x07f8, KEY_SPACE}, /*tab */ |
350 | {0x1fe1, KEY_ENTER}, /*play ok */ | 350 | {0x1fe1, KEY_OK}, /*play ok */ |
351 | {0x1be4, KEY_Z}, /*zoom */ | 351 | {0x1be4, KEY_ZOOM}, /*zoom */ |
352 | {0x59a6, KEY_M}, /*mute */ | 352 | {0x59a6, KEY_MUTE}, /*mute */ |
353 | {0x5ba5, KEY_F}, /*tv/f */ | 353 | {0x5ba5, KEY_RADIO}, /*tv/f */ |
354 | {0x19e7, KEY_R}, /*rec */ | 354 | {0x19e7, KEY_RECORD}, /*rec */ |
355 | {0x01fe, KEY_S}, /*Stop */ | 355 | {0x01fe, KEY_STOP}, /*Stop */ |
356 | {0x03fd, KEY_P}, /*pause */ | 356 | {0x03fd, KEY_PAUSE}, /*pause */ |
357 | {0x03fc, KEY_W}, /*<- -> */ | 357 | {0x03fc, KEY_SCREEN}, /*<- -> */ |
358 | {0x07f9, KEY_C}, /*capture */ | 358 | {0x07f9, KEY_CAMERA}, /*capture */ |
359 | {0x47b9, KEY_Q}, /*exit */ | 359 | {0x47b9, KEY_ESC}, /*exit */ |
360 | {0x43bc, KEY_O}, /*power */ | 360 | {0x43bc, KEY_POWER2}, /*power */ |
361 | |||
362 | }; | 361 | }; |
363 | 362 | ||
364 | static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) | 363 | static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) |
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c new file mode 100644 index 000000000000..08f8842ad280 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c | |||
@@ -0,0 +1,807 @@ | |||
1 | /* | ||
2 | * Linux driver for Technisat DVB-S/S2 USB 2.0 device | ||
3 | * | ||
4 | * Copyright (C) 2010 Patrick Boettcher, | ||
5 | * Kernel Labs Inc. PO Box 745, St James, NY 11780 | ||
6 | * | ||
7 | * Development was sponsored by Technisat Digital UK Limited, whose | ||
8 | * registered office is Witan Gate House 500 - 600 Witan Gate West, | ||
9 | * Milton Keynes, MK9 1SH | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation; either version 2 of the | ||
14 | * License, or (at your option) any later version. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND | ||
22 | * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO | ||
23 | * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR | ||
24 | * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER | ||
25 | * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL, | ||
26 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER | ||
27 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
28 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
29 | * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the | ||
30 | * GNU General Public License for more details. | ||
31 | */ | ||
32 | |||
33 | #define DVB_USB_LOG_PREFIX "technisat-usb2" | ||
34 | #include "dvb-usb.h" | ||
35 | |||
36 | #include "stv6110x.h" | ||
37 | #include "stv090x.h" | ||
38 | |||
39 | /* module parameters */ | ||
40 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
41 | |||
42 | static int debug; | ||
43 | module_param(debug, int, 0644); | ||
44 | MODULE_PARM_DESC(debug, | ||
45 | "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \ | ||
46 | DVB_USB_DEBUG_STATUS); | ||
47 | |||
48 | /* disables all LED control command and | ||
49 | * also does not start the signal polling thread */ | ||
50 | static int disable_led_control; | ||
51 | module_param(disable_led_control, int, 0444); | ||
52 | MODULE_PARM_DESC(disable_led_control, | ||
53 | "disable LED control of the device " | ||
54 | "(default: 0 - LED control is active)."); | ||
55 | |||
56 | /* device private data */ | ||
57 | struct technisat_usb2_state { | ||
58 | struct dvb_usb_device *dev; | ||
59 | struct delayed_work green_led_work; | ||
60 | u8 power_state; | ||
61 | |||
62 | u16 last_scan_code; | ||
63 | }; | ||
64 | |||
65 | /* debug print helpers */ | ||
66 | #define deb_info(args...) dprintk(debug, 0x01, args) | ||
67 | #define deb_eeprom(args...) dprintk(debug, 0x02, args) | ||
68 | #define deb_i2c(args...) dprintk(debug, 0x04, args) | ||
69 | #define deb_rc(args...) dprintk(debug, 0x08, args) | ||
70 | |||
71 | /* vendor requests */ | ||
72 | #define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3 | ||
73 | #define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4 | ||
74 | #define GET_VERSION_INFO_VENDOR_REQUEST 0xB5 | ||
75 | #define SET_GREEN_LED_VENDOR_REQUEST 0xB6 | ||
76 | #define SET_RED_LED_VENDOR_REQUEST 0xB7 | ||
77 | #define GET_IR_DATA_VENDOR_REQUEST 0xB8 | ||
78 | #define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9 | ||
79 | #define SET_USB_REENUMERATION 0xBA | ||
80 | |||
81 | /* i2c-access methods */ | ||
82 | #define I2C_SPEED_100KHZ_BIT 0x40 | ||
83 | |||
84 | #define I2C_STATUS_NAK 7 | ||
85 | #define I2C_STATUS_OK 8 | ||
86 | |||
87 | static int technisat_usb2_i2c_access(struct usb_device *udev, | ||
88 | u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen) | ||
89 | { | ||
90 | u8 b[64]; | ||
91 | int ret, actual_length; | ||
92 | |||
93 | deb_i2c("i2c-access: %02x, tx: ", device_addr); | ||
94 | debug_dump(tx, txlen, deb_i2c); | ||
95 | deb_i2c(" "); | ||
96 | |||
97 | if (txlen > 62) { | ||
98 | err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)", | ||
99 | device_addr); | ||
100 | txlen = 62; | ||
101 | } | ||
102 | if (rxlen > 62) { | ||
103 | err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)", | ||
104 | device_addr); | ||
105 | txlen = 62; | ||
106 | } | ||
107 | |||
108 | b[0] = I2C_SPEED_100KHZ_BIT; | ||
109 | b[1] = device_addr << 1; | ||
110 | |||
111 | if (rx != NULL) { | ||
112 | b[0] |= rxlen; | ||
113 | b[1] |= 1; | ||
114 | } | ||
115 | |||
116 | memcpy(&b[2], tx, txlen); | ||
117 | ret = usb_bulk_msg(udev, | ||
118 | usb_sndbulkpipe(udev, 0x01), | ||
119 | b, 2 + txlen, | ||
120 | NULL, 1000); | ||
121 | |||
122 | if (ret < 0) { | ||
123 | err("i2c-error: out failed %02x = %d", device_addr, ret); | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | |||
127 | ret = usb_bulk_msg(udev, | ||
128 | usb_rcvbulkpipe(udev, 0x01), | ||
129 | b, 64, &actual_length, 1000); | ||
130 | if (ret < 0) { | ||
131 | err("i2c-error: in failed %02x = %d", device_addr, ret); | ||
132 | return -ENODEV; | ||
133 | } | ||
134 | |||
135 | if (b[0] != I2C_STATUS_OK) { | ||
136 | err("i2c-error: %02x = %d", device_addr, b[0]); | ||
137 | /* handle tuner-i2c-nak */ | ||
138 | if (!(b[0] == I2C_STATUS_NAK && | ||
139 | device_addr == 0x60 | ||
140 | /* && device_is_technisat_usb2 */)) | ||
141 | return -ENODEV; | ||
142 | } | ||
143 | |||
144 | deb_i2c("status: %d, ", b[0]); | ||
145 | |||
146 | if (rx != NULL) { | ||
147 | memcpy(rx, &b[2], rxlen); | ||
148 | |||
149 | deb_i2c("rx (%d): ", rxlen); | ||
150 | debug_dump(rx, rxlen, deb_i2c); | ||
151 | } | ||
152 | |||
153 | deb_i2c("\n"); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, | ||
159 | int num) | ||
160 | { | ||
161 | int ret = 0, i; | ||
162 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
163 | |||
164 | /* Ensure nobody else hits the i2c bus while we're sending our | ||
165 | sequence of messages, (such as the remote control thread) */ | ||
166 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
167 | return -EAGAIN; | ||
168 | |||
169 | for (i = 0; i < num; i++) { | ||
170 | if (i+1 < num && msg[i+1].flags & I2C_M_RD) { | ||
171 | ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr, | ||
172 | msg[i].buf, msg[i].len, | ||
173 | msg[i+1].buf, msg[i+1].len); | ||
174 | if (ret != 0) | ||
175 | break; | ||
176 | i++; | ||
177 | } else { | ||
178 | ret = technisat_usb2_i2c_access(d->udev, msg[i].addr, | ||
179 | msg[i].buf, msg[i].len, | ||
180 | NULL, 0); | ||
181 | if (ret != 0) | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if (ret == 0) | ||
187 | ret = i; | ||
188 | |||
189 | mutex_unlock(&d->i2c_mutex); | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter) | ||
195 | { | ||
196 | return I2C_FUNC_I2C; | ||
197 | } | ||
198 | |||
199 | static struct i2c_algorithm technisat_usb2_i2c_algo = { | ||
200 | .master_xfer = technisat_usb2_i2c_xfer, | ||
201 | .functionality = technisat_usb2_i2c_func, | ||
202 | }; | ||
203 | |||
204 | #if 0 | ||
205 | static void technisat_usb2_frontend_reset(struct usb_device *udev) | ||
206 | { | ||
207 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
208 | SET_FRONT_END_RESET_VENDOR_REQUEST, | ||
209 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
210 | 10, 0, | ||
211 | NULL, 0, 500); | ||
212 | } | ||
213 | #endif | ||
214 | |||
215 | /* LED control */ | ||
216 | enum technisat_usb2_led_state { | ||
217 | LED_OFF, | ||
218 | LED_BLINK, | ||
219 | LED_ON, | ||
220 | LED_UNDEFINED | ||
221 | }; | ||
222 | |||
223 | static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state) | ||
224 | { | ||
225 | int ret; | ||
226 | |||
227 | u8 led[8] = { | ||
228 | red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, | ||
229 | 0 | ||
230 | }; | ||
231 | |||
232 | if (disable_led_control && state != LED_OFF) | ||
233 | return 0; | ||
234 | |||
235 | switch (state) { | ||
236 | case LED_ON: | ||
237 | led[1] = 0x82; | ||
238 | break; | ||
239 | case LED_BLINK: | ||
240 | led[1] = 0x82; | ||
241 | if (red) { | ||
242 | led[2] = 0x02; | ||
243 | led[3] = 10; | ||
244 | led[4] = 10; | ||
245 | } else { | ||
246 | led[2] = 0xff; | ||
247 | led[3] = 50; | ||
248 | led[4] = 50; | ||
249 | } | ||
250 | led[5] = 1; | ||
251 | break; | ||
252 | |||
253 | default: | ||
254 | case LED_OFF: | ||
255 | led[1] = 0x80; | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
260 | return -EAGAIN; | ||
261 | |||
262 | ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||
263 | red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, | ||
264 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
265 | 0, 0, | ||
266 | led, sizeof(led), 500); | ||
267 | |||
268 | mutex_unlock(&d->i2c_mutex); | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green) | ||
273 | { | ||
274 | int ret; | ||
275 | u8 b = 0; | ||
276 | |||
277 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
278 | return -EAGAIN; | ||
279 | |||
280 | ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||
281 | SET_LED_TIMER_DIVIDER_VENDOR_REQUEST, | ||
282 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
283 | (red << 8) | green, 0, | ||
284 | &b, 1, 500); | ||
285 | |||
286 | mutex_unlock(&d->i2c_mutex); | ||
287 | |||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | static void technisat_usb2_green_led_control(struct work_struct *work) | ||
292 | { | ||
293 | struct technisat_usb2_state *state = | ||
294 | container_of(work, struct technisat_usb2_state, green_led_work.work); | ||
295 | struct dvb_frontend *fe = state->dev->adapter[0].fe; | ||
296 | |||
297 | if (state->power_state == 0) | ||
298 | goto schedule; | ||
299 | |||
300 | if (fe != NULL) { | ||
301 | enum fe_status status; | ||
302 | |||
303 | if (fe->ops.read_status(fe, &status) != 0) | ||
304 | goto schedule; | ||
305 | |||
306 | if (status & FE_HAS_LOCK) { | ||
307 | u32 ber; | ||
308 | |||
309 | if (fe->ops.read_ber(fe, &ber) != 0) | ||
310 | goto schedule; | ||
311 | |||
312 | if (ber > 1000) | ||
313 | technisat_usb2_set_led(state->dev, 0, LED_BLINK); | ||
314 | else | ||
315 | technisat_usb2_set_led(state->dev, 0, LED_ON); | ||
316 | } else | ||
317 | technisat_usb2_set_led(state->dev, 0, LED_OFF); | ||
318 | } | ||
319 | |||
320 | schedule: | ||
321 | schedule_delayed_work(&state->green_led_work, | ||
322 | msecs_to_jiffies(500)); | ||
323 | } | ||
324 | |||
325 | /* method to find out whether the firmware has to be downloaded or not */ | ||
326 | static int technisat_usb2_identify_state(struct usb_device *udev, | ||
327 | struct dvb_usb_device_properties *props, | ||
328 | struct dvb_usb_device_description **desc, int *cold) | ||
329 | { | ||
330 | int ret; | ||
331 | u8 version[3]; | ||
332 | |||
333 | /* first select the interface */ | ||
334 | if (usb_set_interface(udev, 0, 1) != 0) | ||
335 | err("could not set alternate setting to 0"); | ||
336 | else | ||
337 | info("set alternate setting"); | ||
338 | |||
339 | *cold = 0; /* by default do not download a firmware - just in case something is wrong */ | ||
340 | |||
341 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
342 | GET_VERSION_INFO_VENDOR_REQUEST, | ||
343 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
344 | 0, 0, | ||
345 | version, sizeof(version), 500); | ||
346 | |||
347 | if (ret < 0) | ||
348 | *cold = 1; | ||
349 | else { | ||
350 | info("firmware version: %d.%d", version[1], version[2]); | ||
351 | *cold = 0; | ||
352 | } | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | /* power control */ | ||
358 | static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level) | ||
359 | { | ||
360 | struct technisat_usb2_state *state = d->priv; | ||
361 | |||
362 | state->power_state = level; | ||
363 | |||
364 | if (disable_led_control) | ||
365 | return 0; | ||
366 | |||
367 | /* green led is turned off in any case - will be turned on when tuning */ | ||
368 | technisat_usb2_set_led(d, 0, LED_OFF); | ||
369 | /* red led is turned on all the time */ | ||
370 | technisat_usb2_set_led(d, 1, LED_ON); | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | /* mac address reading - from the eeprom */ | ||
375 | #if 0 | ||
376 | static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d) | ||
377 | { | ||
378 | u8 reg; | ||
379 | u8 b[16]; | ||
380 | int i, j; | ||
381 | |||
382 | /* full EEPROM dump */ | ||
383 | for (j = 0; j < 256 * 4; j += 16) { | ||
384 | reg = j; | ||
385 | if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, ®, 1, b, 16) != 0) | ||
386 | break; | ||
387 | |||
388 | deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg); | ||
389 | for (i = 0; i < 16; i++) | ||
390 | deb_eeprom("%02x ", b[i]); | ||
391 | deb_eeprom("\n"); | ||
392 | } | ||
393 | } | ||
394 | #endif | ||
395 | |||
396 | static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length) | ||
397 | { | ||
398 | u8 lrc = 0; | ||
399 | while (--length) | ||
400 | lrc ^= *b++; | ||
401 | return lrc; | ||
402 | } | ||
403 | |||
404 | static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d, | ||
405 | u16 offset, u8 *b, u16 length, u8 tries) | ||
406 | { | ||
407 | u8 bo = offset & 0xff; | ||
408 | struct i2c_msg msg[] = { | ||
409 | { | ||
410 | .addr = 0x50 | ((offset >> 8) & 0x3), | ||
411 | .buf = &bo, | ||
412 | .len = 1 | ||
413 | }, { | ||
414 | .addr = 0x50 | ((offset >> 8) & 0x3), | ||
415 | .flags = I2C_M_RD, | ||
416 | .buf = b, | ||
417 | .len = length | ||
418 | } | ||
419 | }; | ||
420 | |||
421 | while (tries--) { | ||
422 | int status; | ||
423 | |||
424 | if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) | ||
425 | break; | ||
426 | |||
427 | status = | ||
428 | technisat_usb2_calc_lrc(b, length - 1) == b[length - 1]; | ||
429 | |||
430 | if (status) | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | return -EREMOTEIO; | ||
435 | } | ||
436 | |||
437 | #define EEPROM_MAC_START 0x3f8 | ||
438 | #define EEPROM_MAC_TOTAL 8 | ||
439 | static int technisat_usb2_read_mac_address(struct dvb_usb_device *d, | ||
440 | u8 mac[]) | ||
441 | { | ||
442 | u8 buf[EEPROM_MAC_TOTAL]; | ||
443 | |||
444 | if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START, | ||
445 | buf, EEPROM_MAC_TOTAL, 4) != 0) | ||
446 | return -ENODEV; | ||
447 | |||
448 | memcpy(mac, buf, 6); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | /* frontend attach */ | ||
453 | static int technisat_usb2_set_voltage(struct dvb_frontend *fe, | ||
454 | fe_sec_voltage_t voltage) | ||
455 | { | ||
456 | int i; | ||
457 | u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */ | ||
458 | |||
459 | gpio[2] = 1; /* high - voltage ? */ | ||
460 | |||
461 | switch (voltage) { | ||
462 | case SEC_VOLTAGE_13: | ||
463 | gpio[0] = 1; | ||
464 | break; | ||
465 | case SEC_VOLTAGE_18: | ||
466 | gpio[0] = 1; | ||
467 | gpio[1] = 1; | ||
468 | break; | ||
469 | default: | ||
470 | case SEC_VOLTAGE_OFF: | ||
471 | break; | ||
472 | } | ||
473 | |||
474 | for (i = 0; i < 3; i++) | ||
475 | if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0) | ||
476 | return -EREMOTEIO; | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static struct stv090x_config technisat_usb2_stv090x_config = { | ||
481 | .device = STV0903, | ||
482 | .demod_mode = STV090x_SINGLE, | ||
483 | .clk_mode = STV090x_CLK_EXT, | ||
484 | |||
485 | .xtal = 8000000, | ||
486 | .address = 0x68, | ||
487 | |||
488 | .ts1_mode = STV090x_TSMODE_DVBCI, | ||
489 | .ts1_clk = 13400000, | ||
490 | .ts1_tei = 1, | ||
491 | |||
492 | .repeater_level = STV090x_RPTLEVEL_64, | ||
493 | |||
494 | .tuner_bbgain = 6, | ||
495 | }; | ||
496 | |||
497 | static struct stv6110x_config technisat_usb2_stv6110x_config = { | ||
498 | .addr = 0x60, | ||
499 | .refclk = 16000000, | ||
500 | .clk_div = 2, | ||
501 | }; | ||
502 | |||
503 | static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) | ||
504 | { | ||
505 | struct usb_device *udev = a->dev->udev; | ||
506 | int ret; | ||
507 | |||
508 | a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config, | ||
509 | &a->dev->i2c_adap, STV090x_DEMODULATOR_0); | ||
510 | |||
511 | if (a->fe) { | ||
512 | struct stv6110x_devctl *ctl; | ||
513 | |||
514 | ctl = dvb_attach(stv6110x_attach, | ||
515 | a->fe, | ||
516 | &technisat_usb2_stv6110x_config, | ||
517 | &a->dev->i2c_adap); | ||
518 | |||
519 | if (ctl) { | ||
520 | technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init; | ||
521 | technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep; | ||
522 | technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; | ||
523 | technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | ||
524 | technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | ||
525 | technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
526 | technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
527 | technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
528 | technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
529 | technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | ||
530 | technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status; | ||
531 | |||
532 | /* call the init function once to initialize | ||
533 | tuner's clock output divider and demod's | ||
534 | master clock */ | ||
535 | if (a->fe->ops.init) | ||
536 | a->fe->ops.init(a->fe); | ||
537 | |||
538 | if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0) | ||
539 | return -EAGAIN; | ||
540 | |||
541 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
542 | SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST, | ||
543 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
544 | 0, 0, | ||
545 | NULL, 0, 500); | ||
546 | mutex_unlock(&a->dev->i2c_mutex); | ||
547 | |||
548 | if (ret != 0) | ||
549 | err("could not set IF_CLK to external"); | ||
550 | |||
551 | a->fe->ops.set_voltage = technisat_usb2_set_voltage; | ||
552 | |||
553 | /* if everything was successful assign a nice name to the frontend */ | ||
554 | strlcpy(a->fe->ops.info.name, a->dev->desc->name, | ||
555 | sizeof(a->fe->ops.info.name)); | ||
556 | } else { | ||
557 | dvb_frontend_detach(a->fe); | ||
558 | a->fe = NULL; | ||
559 | } | ||
560 | } | ||
561 | |||
562 | technisat_usb2_set_led_timer(a->dev, 1, 1); | ||
563 | |||
564 | return a->fe == NULL ? -ENODEV : 0; | ||
565 | } | ||
566 | |||
567 | /* Remote control */ | ||
568 | |||
569 | /* the device is giving providing raw IR-signals to the host mapping | ||
570 | * it only to one remote control is just the default implementation | ||
571 | */ | ||
572 | #define NOMINAL_IR_BIT_TRANSITION_TIME_US 889 | ||
573 | #define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US) | ||
574 | |||
575 | #define FIRMWARE_CLOCK_TICK 83333 | ||
576 | #define FIRMWARE_CLOCK_DIVISOR 256 | ||
577 | |||
578 | #define IR_PERCENT_TOLERANCE 15 | ||
579 | |||
580 | #define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) | ||
581 | #define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR) | ||
582 | |||
583 | #define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) | ||
584 | #define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR) | ||
585 | |||
586 | #define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||
587 | #define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||
588 | |||
589 | #define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||
590 | #define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||
591 | |||
592 | static int technisat_usb2_get_ir(struct dvb_usb_device *d) | ||
593 | { | ||
594 | u8 buf[62], *b; | ||
595 | int ret; | ||
596 | struct ir_raw_event ev; | ||
597 | |||
598 | buf[0] = GET_IR_DATA_VENDOR_REQUEST; | ||
599 | buf[1] = 0x08; | ||
600 | buf[2] = 0x8f; | ||
601 | buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT; | ||
602 | buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT; | ||
603 | |||
604 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
605 | return -EAGAIN; | ||
606 | ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||
607 | GET_IR_DATA_VENDOR_REQUEST, | ||
608 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
609 | 0, 0, | ||
610 | buf, 5, 500); | ||
611 | if (ret < 0) | ||
612 | goto unlock; | ||
613 | |||
614 | buf[1] = 0; | ||
615 | buf[2] = 0; | ||
616 | ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), | ||
617 | GET_IR_DATA_VENDOR_REQUEST, | ||
618 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
619 | 0x8080, 0, | ||
620 | buf, sizeof(buf), 500); | ||
621 | |||
622 | unlock: | ||
623 | mutex_unlock(&d->i2c_mutex); | ||
624 | |||
625 | if (ret < 0) | ||
626 | return ret; | ||
627 | |||
628 | if (ret == 1) | ||
629 | return 0; /* no key pressed */ | ||
630 | |||
631 | /* decoding */ | ||
632 | b = buf+1; | ||
633 | |||
634 | #if 0 | ||
635 | deb_rc("RC: %d ", ret); | ||
636 | debug_dump(b, ret, deb_rc); | ||
637 | #endif | ||
638 | |||
639 | ev.pulse = 0; | ||
640 | while (1) { | ||
641 | ev.pulse = !ev.pulse; | ||
642 | ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000; | ||
643 | ir_raw_event_store(d->rc_dev, &ev); | ||
644 | |||
645 | b++; | ||
646 | if (*b == 0xff) { | ||
647 | ev.pulse = 0; | ||
648 | ev.duration = 888888*2; | ||
649 | ir_raw_event_store(d->rc_dev, &ev); | ||
650 | break; | ||
651 | } | ||
652 | } | ||
653 | |||
654 | ir_raw_event_handle(d->rc_dev); | ||
655 | |||
656 | return 1; | ||
657 | } | ||
658 | |||
659 | static int technisat_usb2_rc_query(struct dvb_usb_device *d) | ||
660 | { | ||
661 | int ret = technisat_usb2_get_ir(d); | ||
662 | |||
663 | if (ret < 0) | ||
664 | return ret; | ||
665 | |||
666 | if (ret == 0) | ||
667 | return 0; | ||
668 | |||
669 | if (!disable_led_control) | ||
670 | technisat_usb2_set_led(d, 1, LED_BLINK); | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | /* DVB-USB and USB stuff follows */ | ||
676 | static struct usb_device_id technisat_usb2_id_table[] = { | ||
677 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) }, | ||
678 | { 0 } /* Terminating entry */ | ||
679 | }; | ||
680 | |||
681 | /* device description */ | ||
682 | static struct dvb_usb_device_properties technisat_usb2_devices = { | ||
683 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
684 | |||
685 | .usb_ctrl = CYPRESS_FX2, | ||
686 | |||
687 | .identify_state = technisat_usb2_identify_state, | ||
688 | .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw", | ||
689 | |||
690 | .size_of_priv = sizeof(struct technisat_usb2_state), | ||
691 | |||
692 | .i2c_algo = &technisat_usb2_i2c_algo, | ||
693 | |||
694 | .power_ctrl = technisat_usb2_power_ctrl, | ||
695 | .read_mac_address = technisat_usb2_read_mac_address, | ||
696 | |||
697 | .num_adapters = 1, | ||
698 | .adapter = { | ||
699 | { | ||
700 | .frontend_attach = technisat_usb2_frontend_attach, | ||
701 | |||
702 | .stream = { | ||
703 | .type = USB_ISOC, | ||
704 | .count = 8, | ||
705 | .endpoint = 0x2, | ||
706 | .u = { | ||
707 | .isoc = { | ||
708 | .framesperurb = 32, | ||
709 | .framesize = 2048, | ||
710 | .interval = 3, | ||
711 | } | ||
712 | } | ||
713 | }, | ||
714 | |||
715 | .size_of_priv = 0, | ||
716 | }, | ||
717 | }, | ||
718 | |||
719 | .num_device_descs = 1, | ||
720 | .devices = { | ||
721 | { "Technisat SkyStar USB HD (DVB-S/S2)", | ||
722 | { &technisat_usb2_id_table[0], NULL }, | ||
723 | { NULL }, | ||
724 | }, | ||
725 | }, | ||
726 | |||
727 | .rc.core = { | ||
728 | .rc_interval = 100, | ||
729 | .rc_codes = RC_MAP_TECHNISAT_USB2, | ||
730 | .module_name = "technisat-usb2", | ||
731 | .rc_query = technisat_usb2_rc_query, | ||
732 | .allowed_protos = RC_TYPE_ALL, | ||
733 | .driver_type = RC_DRIVER_IR_RAW, | ||
734 | } | ||
735 | }; | ||
736 | |||
737 | static int technisat_usb2_probe(struct usb_interface *intf, | ||
738 | const struct usb_device_id *id) | ||
739 | { | ||
740 | struct dvb_usb_device *dev; | ||
741 | |||
742 | if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE, | ||
743 | &dev, adapter_nr) != 0) | ||
744 | return -ENODEV; | ||
745 | |||
746 | if (dev) { | ||
747 | struct technisat_usb2_state *state = dev->priv; | ||
748 | state->dev = dev; | ||
749 | |||
750 | if (!disable_led_control) { | ||
751 | INIT_DELAYED_WORK(&state->green_led_work, | ||
752 | technisat_usb2_green_led_control); | ||
753 | schedule_delayed_work(&state->green_led_work, | ||
754 | msecs_to_jiffies(500)); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | static void technisat_usb2_disconnect(struct usb_interface *intf) | ||
762 | { | ||
763 | struct dvb_usb_device *dev = usb_get_intfdata(intf); | ||
764 | |||
765 | /* work and stuff was only created when the device is is hot-state */ | ||
766 | if (dev != NULL) { | ||
767 | struct technisat_usb2_state *state = dev->priv; | ||
768 | if (state != NULL) { | ||
769 | cancel_delayed_work_sync(&state->green_led_work); | ||
770 | flush_scheduled_work(); | ||
771 | } | ||
772 | } | ||
773 | |||
774 | dvb_usb_device_exit(intf); | ||
775 | } | ||
776 | |||
777 | static struct usb_driver technisat_usb2_driver = { | ||
778 | .name = "dvb_usb_technisat_usb2", | ||
779 | .probe = technisat_usb2_probe, | ||
780 | .disconnect = technisat_usb2_disconnect, | ||
781 | .id_table = technisat_usb2_id_table, | ||
782 | }; | ||
783 | |||
784 | /* module stuff */ | ||
785 | static int __init technisat_usb2_module_init(void) | ||
786 | { | ||
787 | int result = usb_register(&technisat_usb2_driver); | ||
788 | if (result) { | ||
789 | err("usb_register failed. Code %d", result); | ||
790 | return result; | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | static void __exit technisat_usb2_module_exit(void) | ||
797 | { | ||
798 | usb_deregister(&technisat_usb2_driver); | ||
799 | } | ||
800 | |||
801 | module_init(technisat_usb2_module_init); | ||
802 | module_exit(technisat_usb2_module_exit); | ||
803 | |||
804 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>"); | ||
805 | MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device"); | ||
806 | MODULE_VERSION("1.0"); | ||
807 | MODULE_LICENSE("GPL"); | ||