aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c8
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c67
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c47
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c1381
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c590
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c235
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c33
-rw-r--r--drivers/media/dvb/dvb-usb/technisat-usb2.c807
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
362config 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
91dvb-usb-lmedm04-objs = lmedm04.o 91dvb-usb-lmedm04-objs = lmedm04.o
92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o 92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
93 93
94dvb-usb-technisat-usb2-objs = technisat-usb2.o
95obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
96
94EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 97EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
95# due to tuner-xc3028 98# due to tuner-xc3028
96EXTRA_CFLAGS += -Idrivers/media/common/tuners 99EXTRA_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
40static struct rc_map_table rc_map_a800_table[] = { 40static 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
482error: 483error:
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:
659static int af9015_download_firmware(struct usb_device *udev, 665static 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
740static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { 741static 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
107struct af9015_config { 108struct 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;
61extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, 62extern 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);
63extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); 64extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
65extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
64 66
65extern int dib0700_device_count; 67extern int dib0700_device_count;
66extern int dvb_usb_dib0700_ir_proto; 68extern 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
331int 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
331int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) 356int 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
30struct dib0700_adapter_state { 31struct 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)
1243static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, 1245static 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
1249static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, 1251static 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 */
1323struct dibx000_agc_config dib8090_agc_config[2] = { 1325struct 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
1410static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { 1412static 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
1420static int dib8090_get_adc_power(struct dvb_frontend *fe) 1422static 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
1425static struct dib8000_config dib809x_dib8000_config = { 1427static 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
1469static 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
1446static struct dib0090_config dib809x_dib0090_config = { 1478static 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
1468static int dib8096_set_param_override(struct dvb_frontend *fe, 1500static 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, &ltgain);
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, &ltgain);
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
1525static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) 1545static 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
1538static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) 1558static 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
1582static 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
1605static 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 */
1639static 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
1644static 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
1649static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1650{
1651 return dib9000_set_gpio(fe, 5, 0, !onoff);
1652}
1653
1654static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1655{
1656 return dib9000_set_gpio(fe, 0, 0, onoff);
1657}
1658
1659static 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
1712static 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
1734static 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
1766static 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
1784static 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
1821static 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
1863static 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
1887static 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
1941static 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 */
1982struct dib7090p_best_adc {
1983 u32 timf;
1984 u32 pll_loopdiv;
1985 u32 pll_prediv;
1986};
1987
1988static 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
2061static 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
2089static 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
2097struct 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
2179static 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
2189static 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
2217static 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
2275static 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
2309static 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
2377static 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
2400static 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
2415static 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
2451static 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
2472static 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
2487static 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 */
1563static struct dib7000p_config stk7070pd_dib7000p_config[2] = { 2503static 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};
1861MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2807MODULE_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
92struct su3000_state {
93 u8 initialized;
94};
95
96struct s6x0_state {
97 int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
98};
99
81/* debug */ 100/* debug */
82static int dvb_usb_dw2102_debug; 101static int dvb_usb_dw2102_debug;
83module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 102module_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 */
88static int ir_keymap; 107static int ir_keymap;
89module_param_named(keymap, ir_keymap, int, 0644); 108module_param_named(keymap, ir_keymap, int, 0644);
90MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); 109MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
110 " 256=none");
91 111
92/* demod probe */ 112/* demod probe */
93static int demod_probe = 1; 113static 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
598static 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
572static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 662static 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
697static struct i2c_algorithm su3000_i2c_algo = {
698 .master_xfer = su3000_i2c_transfer,
699 .functionality = dw210x_i2c_func,
700};
701
607static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 702static 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
766static 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
782static 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
798static 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
831static 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
671static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 842static 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
866static 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
879static 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
695static struct stv0299_config sharp_z0194a_config = { 897static 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
979static struct ds3000_config su3000_ds3000_config = {
980 .demod_address = 0x68,
981 .ci_mode = 1,
774}; 982};
775 983
776static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 984static 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
888static int s6x0_frontend_attach(struct dvb_usb_adapter *d) 1096static 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
1112static 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
1135static 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
923static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) 1156static 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
1174static 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
936static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 1211static 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
951static struct rc_map_table rc_map_dw210x_table[] = { 1226static 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
985static struct rc_map_table rc_map_tevii_table[] = { 1260static 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
1345static 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
1070static struct rc_map_dvb_usb_table_table keys_tables[] = { 1383static 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
1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 1390static 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 = {
1399static struct dvb_usb_device_properties s6x0_properties = { 1709static 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
1752struct dvb_usb_device_properties *p1100;
1753static struct dvb_usb_device_description d1100 = {
1754 "Prof 1100 USB ",
1755 {&dw2102_table[7], NULL},
1756 {NULL},
1757};
1758
1759struct dvb_usb_device_properties *s660;
1760static struct dvb_usb_device_description d660 = {
1761 "TeVii S660 USB",
1762 {&dw2102_table[8], NULL},
1763 {NULL},
1764};
1765
1766static struct dvb_usb_device_description d480_1 = {
1767 "TeVii S480.1 USB",
1768 {&dw2102_table[12], NULL},
1769 {NULL},
1770};
1771
1772static struct dvb_usb_device_description d480_2 = {
1773 "TeVii S480.2 USB",
1774 {&dw2102_table[13], NULL},
1775 {NULL},
1776};
1777
1451struct dvb_usb_device_properties *p7500; 1778struct dvb_usb_device_properties *p7500;
1452static struct dvb_usb_device_description d7500 = { 1779static 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
1785static 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
1458static int dw2102_probe(struct usb_interface *intf, 1838static 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);
1514MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1927MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1515MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1928MODULE_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");
1519MODULE_VERSION("0.1"); 1933MODULE_VERSION("0.1");
1520MODULE_LICENSE("GPL"); 1934MODULE_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
98DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 108DVB_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
102struct lme2510_state { 115struct 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}
194static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) 207static 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
527static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 579static 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 */
662char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw";
663
664static void lme_coldreset(struct usb_device *dev) 713static 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)
678static int lme_firmware_switch(struct usb_device *udev, int cold) 727static 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
844static 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
761static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, 856static 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
850end: if (ret) { 961end: 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
862static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) 972static 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
965static struct dvb_usb_device_properties lme2510_properties = { 1083static 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
1005static struct dvb_usb_device_properties lme2510c_properties = { 1119static 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
1110MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1221MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1111MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1222MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1112MODULE_VERSION("1.75"); 1223MODULE_VERSION("1.80");
1113MODULE_LICENSE("GPL"); 1224MODULE_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
364static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) 363static 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 */
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_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 */
50static int disable_led_control;
51module_param(disable_led_control, int, 0444);
52MODULE_PARM_DESC(disable_led_control,
53 "disable LED control of the device "
54 "(default: 0 - LED control is active).");
55
56/* device private data */
57struct 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
87static 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
158static 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
194static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static 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
205static 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 */
216enum technisat_usb2_led_state {
217 LED_OFF,
218 LED_BLINK,
219 LED_ON,
220 LED_UNDEFINED
221};
222
223static 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
272static 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
291static 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
320schedule:
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 */
326static 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 */
358static 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
376static 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, &reg, 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
396static 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
404static 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
439static 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 */
453static 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
480static 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
497static struct stv6110x_config technisat_usb2_stv6110x_config = {
498 .addr = 0x60,
499 .refclk = 16000000,
500 .clk_div = 2,
501};
502
503static 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
592static 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
622unlock:
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
659static 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 */
676static 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 */
682static 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
737static 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
761static 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
777static 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 */
785static 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
796static void __exit technisat_usb2_module_exit(void)
797{
798 usb_deregister(&technisat_usb2_driver);
799}
800
801module_init(technisat_usb2_module_init);
802module_exit(technisat_usb2_module_exit);
803
804MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
805MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
806MODULE_VERSION("1.0");
807MODULE_LICENSE("GPL");