summaryrefslogtreecommitdiff
path: root/drivers/staging/tm6000/tm6000-cards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tm6000/tm6000-cards.c')
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c381
1 files changed, 339 insertions, 42 deletions
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 146c7e8..a69c82e 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -54,6 +54,11 @@
#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
#define TM5600_BOARD_TERRATEC_GRABSTER 16
+#define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
+ (model == TM5600_BOARD_GENERIC) || \
+ (model == TM6000_BOARD_GENERIC) || \
+ (model == TM6010_BOARD_GENERIC))
+
#define TM6000_MAXBOARDS 16
static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -64,10 +69,11 @@ static unsigned long tm6000_devused;
struct tm6000_board {
char *name;
+ char eename[16]; /* EEPROM name */
+ unsigned eename_size; /* size of EEPROM name */
+ unsigned eename_pos; /* Position where it appears at ROM */
struct tm6000_capabilities caps;
- enum tm6000_inaudio aradio;
- enum tm6000_inaudio avideo;
enum tm6000_devtype type; /* variant of the chipset */
int tuner_type; /* type of the tuner */
@@ -76,6 +82,9 @@ struct tm6000_board {
struct tm6000_gpio gpio;
+ struct tm6000_input vinput[3];
+ struct tm6000_input rinput;
+
char *ir_codes;
};
@@ -83,11 +92,26 @@ struct tm6000_board tm6000_boards[] = {
[TM6000_BOARD_UNKNOWN] = {
.name = "Unknown tm6000 video grabber",
.caps = {
- .has_tuner = 1,
+ .has_tuner = 1,
+ .has_eeprom = 1,
},
.gpio = {
.tuner_reset = TM6000_GPIO_1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM5600_BOARD_GENERIC] = {
.name = "Generic tm5600 board",
@@ -96,10 +120,25 @@ struct tm6000_board tm6000_boards[] = {
.tuner_addr = 0xc2 >> 1,
.caps = {
.has_tuner = 1,
+ .has_eeprom = 1,
},
.gpio = {
.tuner_reset = TM6000_GPIO_1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6000_BOARD_GENERIC] = {
.name = "Generic tm6000 board",
@@ -107,11 +146,25 @@ struct tm6000_board tm6000_boards[] = {
.tuner_addr = 0xc2 >> 1,
.caps = {
.has_tuner = 1,
- .has_dvb = 1,
+ .has_eeprom = 1,
},
.gpio = {
.tuner_reset = TM6000_GPIO_1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6010_BOARD_GENERIC] = {
.name = "Generic tm6010 board",
@@ -135,10 +188,27 @@ struct tm6000_board tm6000_boards[] = {
.dvb_led = TM6010_GPIO_5,
.ir = TM6010_GPIO_0,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM5600_BOARD_10MOONS_UT821] = {
.name = "10Moons UT 821",
.tuner_type = TUNER_XC2028,
+ .eename = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b},
+ .eename_size = 14,
+ .eename_pos = 0x14,
.type = TM5600,
.tuner_addr = 0xc2 >> 1,
.caps = {
@@ -148,6 +218,20 @@ struct tm6000_board tm6000_boards[] = {
.gpio = {
.tuner_reset = TM6000_GPIO_1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM5600_BOARD_10MOONS_UT330] = {
.name = "10Moons UT 330",
@@ -159,6 +243,20 @@ struct tm6000_board tm6000_boards[] = {
.has_zl10353 = 0,
.has_eeprom = 1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6000_BOARD_ADSTECH_DUAL_TV] = {
.name = "ADSTECH Dual TV USB",
@@ -171,6 +269,20 @@ struct tm6000_board tm6000_boards[] = {
.has_zl10353 = 1,
.has_eeprom = 1,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6000_BOARD_FREECOM_AND_SIMILAR] = {
.name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
@@ -187,6 +299,20 @@ struct tm6000_board tm6000_boards[] = {
.gpio = {
.tuner_reset = TM6000_GPIO_4,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = {
.name = "ADSTECH Mini Dual TV USB",
@@ -202,9 +328,26 @@ struct tm6000_board tm6000_boards[] = {
.gpio = {
.tuner_reset = TM6000_GPIO_4,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6010_BOARD_HAUPPAUGE_900H] = {
.name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
+ .eename = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 },
+ .eename_size = 14,
+ .eename_pos = 0x42,
.tuner_type = TUNER_XC2028, /* has a XC3028 */
.tuner_addr = 0xc2 >> 1,
.demod_addr = 0x1e >> 1,
@@ -225,6 +368,20 @@ struct tm6000_board tm6000_boards[] = {
.dvb_led = TM6010_GPIO_5,
.ir = TM6010_GPIO_0,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6010_BOARD_BEHOLD_WANDER] = {
.name = "Beholder Wander DVB-T/TV/FM USB2.0",
@@ -232,43 +389,73 @@ struct tm6000_board tm6000_boards[] = {
.tuner_addr = 0xc2 >> 1,
.demod_addr = 0x1e >> 1,
.type = TM6010,
- .avideo = TM6000_AIP_SIF1,
- .aradio = TM6000_AIP_LINE1,
.caps = {
.has_tuner = 1,
.has_dvb = 1,
.has_zl10353 = 1,
.has_eeprom = 1,
.has_remote = 1,
- .has_input_comp = 1,
- .has_input_svid = 1,
+ .has_radio = 1.
},
.gpio = {
.tuner_reset = TM6010_GPIO_0,
.demod_reset = TM6010_GPIO_1,
.power_led = TM6010_GPIO_6,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
+ .rinput = {
+ .type = TM6000_INPUT_RADIO,
+ .amux = TM6000_AMUX_ADC1,
+ },
},
[TM6010_BOARD_BEHOLD_VOYAGER] = {
.name = "Beholder Voyager TV/FM USB2.0",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0xc2 >> 1,
.type = TM6010,
- .avideo = TM6000_AIP_SIF1,
- .aradio = TM6000_AIP_LINE1,
.caps = {
.has_tuner = 1,
.has_dvb = 0,
.has_zl10353 = 0,
.has_eeprom = 1,
.has_remote = 1,
- .has_input_comp = 1,
- .has_input_svid = 1,
+ .has_radio = 1,
},
.gpio = {
.tuner_reset = TM6010_GPIO_0,
.power_led = TM6010_GPIO_6,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
+ .rinput = {
+ .type = TM6000_INPUT_RADIO,
+ .amux = TM6000_AMUX_ADC1,
+ },
},
[TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
.name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
@@ -293,11 +480,39 @@ struct tm6000_board tm6000_boards[] = {
.ir = TM6010_GPIO_0,
},
.ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM5600_BOARD_TERRATEC_GRABSTER] = {
.name = "Terratec Grabster AV 150/250 MX",
.type = TM5600,
.tuner_type = TUNER_ABSENT,
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_ADC1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6010_BOARD_TWINHAN_TU501] = {
.name = "Twinhan TU501(704D1)",
@@ -321,6 +536,20 @@ struct tm6000_board tm6000_boards[] = {
.dvb_led = TM6010_GPIO_5,
.ir = TM6010_GPIO_0,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ }, {
+ .type = TM6000_INPUT_COMPOSITE1,
+ .vmux = TM6000_VMUX_VIDEO_A,
+ .amux = TM6000_AMUX_ADC2,
+ }, {
+ .type = TM6000_INPUT_SVIDEO,
+ .vmux = TM6000_VMUX_VIDEO_AB,
+ .amux = TM6000_AMUX_ADC2,
+ },
+ },
},
[TM6010_BOARD_BEHOLD_WANDER_LITE] = {
.name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
@@ -328,49 +557,63 @@ struct tm6000_board tm6000_boards[] = {
.tuner_addr = 0xc2 >> 1,
.demod_addr = 0x1e >> 1,
.type = TM6010,
- .avideo = TM6000_AIP_SIF1,
- .aradio = TM6000_AIP_LINE1,
.caps = {
.has_tuner = 1,
.has_dvb = 1,
.has_zl10353 = 1,
.has_eeprom = 1,
.has_remote = 0,
- .has_input_comp = 0,
- .has_input_svid = 0,
+ .has_radio = 1,
},
.gpio = {
.tuner_reset = TM6010_GPIO_0,
.demod_reset = TM6010_GPIO_1,
.power_led = TM6010_GPIO_6,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ },
+ },
+ .rinput = {
+ .type = TM6000_INPUT_RADIO,
+ .amux = TM6000_AMUX_ADC1,
+ },
},
[TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
.name = "Beholder Voyager Lite TV/FM USB2.0",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0xc2 >> 1,
.type = TM6010,
- .avideo = TM6000_AIP_SIF1,
- .aradio = TM6000_AIP_LINE1,
.caps = {
.has_tuner = 1,
.has_dvb = 0,
.has_zl10353 = 0,
.has_eeprom = 1,
.has_remote = 0,
- .has_input_comp = 0,
- .has_input_svid = 0,
+ .has_radio = 1,
},
.gpio = {
.tuner_reset = TM6010_GPIO_0,
.power_led = TM6010_GPIO_6,
},
+ .vinput = { {
+ .type = TM6000_INPUT_TV,
+ .vmux = TM6000_VMUX_VIDEO_B,
+ .amux = TM6000_AMUX_SIF1,
+ },
+ },
+ .rinput = {
+ .type = TM6000_INPUT_RADIO,
+ .amux = TM6000_AMUX_ADC1,
+ },
},
};
/* table of devices that work with this driver */
struct usb_device_id tm6000_id_table[] = {
- { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_10MOONS_UT821 },
+ { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
{ USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
{ USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
{ USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
@@ -679,12 +922,8 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
memset(&ctl, 0, sizeof(ctl));
- ctl.input1 = 1;
- ctl.read_not_reliable = 0;
- ctl.msleep = 10;
ctl.demod = XC3028_FE_ZARLINK456;
- ctl.vhfbw7 = 1;
- ctl.uhfbw8 = 1;
+
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
@@ -729,16 +968,10 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
}
}
-static int tm6000_init_dev(struct tm6000_core *dev)
+static int fill_board_specific_data(struct tm6000_core *dev)
{
- struct v4l2_frequency f;
- int rc = 0;
-
- mutex_init(&dev->lock);
-
- mutex_lock(&dev->lock);
+ int rc;
- /* Initializa board-specific data */
dev->dev_type = tm6000_boards[dev->model].type;
dev->tuner_type = tm6000_boards[dev->model].tuner_type;
dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
@@ -751,21 +984,85 @@ static int tm6000_init_dev(struct tm6000_core *dev)
dev->caps = tm6000_boards[dev->model].caps;
- dev->avideo = tm6000_boards[dev->model].avideo;
- dev->aradio = tm6000_boards[dev->model].aradio;
+ dev->vinput[0] = tm6000_boards[dev->model].vinput[0];
+ dev->vinput[1] = tm6000_boards[dev->model].vinput[1];
+ dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
+ dev->rinput = tm6000_boards[dev->model].rinput;
+
/* initialize hardware */
rc = tm6000_init(dev);
if (rc < 0)
- goto err;
+ return rc;
rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
if (rc < 0)
- goto err;
+ return rc;
- /* register i2c bus */
- rc = tm6000_i2c_register(dev);
- if (rc < 0)
- goto err;
+ return rc;
+}
+
+
+static void use_alternative_detection_method(struct tm6000_core *dev)
+{
+ int i, model = -1;
+
+ if (!dev->eedata_size)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) {
+ if (!tm6000_boards[i].eename_size)
+ continue;
+ if (dev->eedata_size < tm6000_boards[i].eename_pos +
+ tm6000_boards[i].eename_size)
+ continue;
+
+ if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos],
+ tm6000_boards[i].eename,
+ tm6000_boards[i].eename_size)) {
+ model = i;
+ break;
+ }
+ }
+ if (model < 0) {
+ printk(KERN_INFO "Device has eeprom but is currently unknown\n");
+ return;
+ }
+
+ dev->model = model;
+
+ printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n",
+ tm6000_boards[model].name, model);
+}
+
+static int tm6000_init_dev(struct tm6000_core *dev)
+{
+ struct v4l2_frequency f;
+ int rc = 0;
+
+ mutex_init(&dev->lock);
+ mutex_lock(&dev->lock);
+
+ if (!is_generic(dev->model)) {
+ rc = fill_board_specific_data(dev);
+ if (rc < 0)
+ goto err;
+
+ /* register i2c bus */
+ rc = tm6000_i2c_register(dev);
+ if (rc < 0)
+ goto err;
+ } else {
+ /* register i2c bus */
+ rc = tm6000_i2c_register(dev);
+ if (rc < 0)
+ goto err;
+
+ use_alternative_detection_method(dev);
+
+ rc = fill_board_specific_data(dev);
+ if (rc < 0)
+ goto err;
+ }
/* Default values for STD and resolutions */
dev->width = 720;