174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c0d06caSMauro Carvalho Chehab /*
30c0d06caSMauro Carvalho Chehab cx231xx-cards.c - driver for Conexant Cx23100/101/102
40c0d06caSMauro Carvalho Chehab USB video capture devices
50c0d06caSMauro Carvalho Chehab
60c0d06caSMauro Carvalho Chehab Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
70c0d06caSMauro Carvalho Chehab Based on em28xx driver
80c0d06caSMauro Carvalho Chehab
90c0d06caSMauro Carvalho Chehab */
100c0d06caSMauro Carvalho Chehab
11589dadf2SMauro Carvalho Chehab #include "cx231xx.h"
120c0d06caSMauro Carvalho Chehab #include <linux/init.h>
130c0d06caSMauro Carvalho Chehab #include <linux/module.h>
140c0d06caSMauro Carvalho Chehab #include <linux/slab.h>
150c0d06caSMauro Carvalho Chehab #include <linux/delay.h>
160c0d06caSMauro Carvalho Chehab #include <linux/i2c.h>
170c0d06caSMauro Carvalho Chehab #include <media/tuner.h>
180c0d06caSMauro Carvalho Chehab #include <media/tveeprom.h>
190c0d06caSMauro Carvalho Chehab #include <media/v4l2-common.h>
200c0d06caSMauro Carvalho Chehab
21d647f0b7SMauro Carvalho Chehab #include <media/drv-intf/cx25840.h>
22fada1935SMauro Carvalho Chehab #include <media/dvb-usb-ids.h>
230c0d06caSMauro Carvalho Chehab #include "xc5000.h"
240c0d06caSMauro Carvalho Chehab #include "tda18271.h"
250c0d06caSMauro Carvalho Chehab
260c0d06caSMauro Carvalho Chehab
270c0d06caSMauro Carvalho Chehab static int tuner = -1;
280c0d06caSMauro Carvalho Chehab module_param(tuner, int, 0444);
290c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(tuner, "tuner type");
300c0d06caSMauro Carvalho Chehab
310c0d06caSMauro Carvalho Chehab static int transfer_mode = 1;
320c0d06caSMauro Carvalho Chehab module_param(transfer_mode, int, 0444);
330c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)");
340c0d06caSMauro Carvalho Chehab
350c0d06caSMauro Carvalho Chehab static unsigned int disable_ir;
360c0d06caSMauro Carvalho Chehab module_param(disable_ir, int, 0444);
370c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
380c0d06caSMauro Carvalho Chehab
390c0d06caSMauro Carvalho Chehab /* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */
400c0d06caSMauro Carvalho Chehab static unsigned long cx231xx_devused;
410c0d06caSMauro Carvalho Chehab
420c0d06caSMauro Carvalho Chehab /*
430c0d06caSMauro Carvalho Chehab * Reset sequences for analog/digital modes
440c0d06caSMauro Carvalho Chehab */
450c0d06caSMauro Carvalho Chehab
460c0d06caSMauro Carvalho Chehab static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = {
470c0d06caSMauro Carvalho Chehab {0x03, 0x01, 10},
480c0d06caSMauro Carvalho Chehab {0x03, 0x00, 30},
490c0d06caSMauro Carvalho Chehab {0x03, 0x01, 10},
500c0d06caSMauro Carvalho Chehab {-1, -1, -1},
510c0d06caSMauro Carvalho Chehab };
520c0d06caSMauro Carvalho Chehab
530c0d06caSMauro Carvalho Chehab /*
540c0d06caSMauro Carvalho Chehab * Board definitions
550c0d06caSMauro Carvalho Chehab */
560c0d06caSMauro Carvalho Chehab struct cx231xx_board cx231xx_boards[] = {
570c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_UNKNOWN] = {
580c0d06caSMauro Carvalho Chehab .name = "Unknown CX231xx video grabber",
590c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_ABSENT,
600c0d06caSMauro Carvalho Chehab .input = {{
610c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
620c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
630c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
640c0d06caSMauro Carvalho Chehab .gpio = NULL,
650c0d06caSMauro Carvalho Chehab }, {
660c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
670c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
680c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
690c0d06caSMauro Carvalho Chehab .gpio = NULL,
700c0d06caSMauro Carvalho Chehab }, {
710c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
720c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
730c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
740c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
750c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
760c0d06caSMauro Carvalho Chehab .gpio = NULL,
770c0d06caSMauro Carvalho Chehab }
780c0d06caSMauro Carvalho Chehab },
790c0d06caSMauro Carvalho Chehab },
800c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_CARRAERA] = {
810c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - CARRAERA",
820c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_XC5000,
830c0d06caSMauro Carvalho Chehab .tuner_addr = 0x61,
840c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
850c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
860c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
870c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
880c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
890c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
900c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
910c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
920c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
930c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
94b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
95d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
960c0d06caSMauro Carvalho Chehab .has_dvb = 1,
970c0d06caSMauro Carvalho Chehab .demod_addr = 0x02,
980c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
990c0d06caSMauro Carvalho Chehab
1000c0d06caSMauro Carvalho Chehab .input = {{
1010c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
1020c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
1030c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
1040c0d06caSMauro Carvalho Chehab .gpio = NULL,
1050c0d06caSMauro Carvalho Chehab }, {
1060c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
1070c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
1080c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1090c0d06caSMauro Carvalho Chehab .gpio = NULL,
1100c0d06caSMauro Carvalho Chehab }, {
1110c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
1120c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
1130c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
1140c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
1150c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1160c0d06caSMauro Carvalho Chehab .gpio = NULL,
1170c0d06caSMauro Carvalho Chehab }
1180c0d06caSMauro Carvalho Chehab },
1190c0d06caSMauro Carvalho Chehab },
1200c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_SHELBY] = {
1210c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - SHELBY",
1220c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_XC5000,
1230c0d06caSMauro Carvalho Chehab .tuner_addr = 0x61,
1240c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
1250c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
1260c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
1270c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
1280c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
1290c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
1300c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
1310c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
1320c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
1330c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
134b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
135d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
1360c0d06caSMauro Carvalho Chehab .has_dvb = 1,
1370c0d06caSMauro Carvalho Chehab .demod_addr = 0x32,
1380c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
1390c0d06caSMauro Carvalho Chehab
1400c0d06caSMauro Carvalho Chehab .input = {{
1410c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
1420c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
1430c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
1440c0d06caSMauro Carvalho Chehab .gpio = NULL,
1450c0d06caSMauro Carvalho Chehab }, {
1460c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
1470c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
1480c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1490c0d06caSMauro Carvalho Chehab .gpio = NULL,
1500c0d06caSMauro Carvalho Chehab }, {
1510c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
1520c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
1530c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
1540c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
1550c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1560c0d06caSMauro Carvalho Chehab .gpio = NULL,
1570c0d06caSMauro Carvalho Chehab }
1580c0d06caSMauro Carvalho Chehab },
1590c0d06caSMauro Carvalho Chehab },
1600c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_RDE_253S] = {
1610c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - RDE253S",
1620c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
1630c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
1640c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
1650c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
1660c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
1670c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
1680c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
1690c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
1700c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
1710c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
1720c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x1c,
1730c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
174b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
175d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
1760c0d06caSMauro Carvalho Chehab .has_dvb = 1,
1770c0d06caSMauro Carvalho Chehab .demod_addr = 0x02,
1780c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
1790c0d06caSMauro Carvalho Chehab
1800c0d06caSMauro Carvalho Chehab .input = {{
1810c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
1820c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
1830c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
1840c0d06caSMauro Carvalho Chehab .gpio = NULL,
1850c0d06caSMauro Carvalho Chehab }, {
1860c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
1870c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
1880c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1890c0d06caSMauro Carvalho Chehab .gpio = NULL,
1900c0d06caSMauro Carvalho Chehab }, {
1910c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
1920c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
1930c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
1940c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
1950c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
1960c0d06caSMauro Carvalho Chehab .gpio = NULL,
1970c0d06caSMauro Carvalho Chehab }
1980c0d06caSMauro Carvalho Chehab },
1990c0d06caSMauro Carvalho Chehab },
2000c0d06caSMauro Carvalho Chehab
2010c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_RDU_253S] = {
2020c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - RDU253S",
2030c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
2040c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
2050c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
2060c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
2070c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
2080c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
2090c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
2100c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
2110c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
2120c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
2130c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x1c,
2140c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
215b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
216d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
2170c0d06caSMauro Carvalho Chehab .has_dvb = 1,
2180c0d06caSMauro Carvalho Chehab .demod_addr = 0x02,
2190c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
2200c0d06caSMauro Carvalho Chehab
2210c0d06caSMauro Carvalho Chehab .input = {{
2220c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
2230c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
2240c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
2250c0d06caSMauro Carvalho Chehab .gpio = NULL,
2260c0d06caSMauro Carvalho Chehab }, {
2270c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
2280c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
2290c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
2300c0d06caSMauro Carvalho Chehab .gpio = NULL,
2310c0d06caSMauro Carvalho Chehab }, {
2320c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
2330c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
2340c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
2350c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
2360c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
2370c0d06caSMauro Carvalho Chehab .gpio = NULL,
2380c0d06caSMauro Carvalho Chehab }
2390c0d06caSMauro Carvalho Chehab },
2400c0d06caSMauro Carvalho Chehab },
2410c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_VIDEO_GRABBER] = {
2420c0d06caSMauro Carvalho Chehab .name = "Conexant VIDEO GRABBER",
2430c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_ABSENT,
2440c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
2450c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
2460c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
2470c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x1c,
2480c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
2490c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
2500c0d06caSMauro Carvalho Chehab .no_alt_vanc = 1,
2510c0d06caSMauro Carvalho Chehab .external_av = 1,
252b31077a8SHans Verkuil /* Actually, it has a 417, but it isn't working correctly.
253b31077a8SHans Verkuil * So set to 0 for now until someone can manage to get this
254b31077a8SHans Verkuil * to work reliably. */
255b31077a8SHans Verkuil .has_417 = 0,
2560c0d06caSMauro Carvalho Chehab
2570c0d06caSMauro Carvalho Chehab .input = {{
2580c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
2590c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
2600c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
2610c0d06caSMauro Carvalho Chehab .gpio = NULL,
2620c0d06caSMauro Carvalho Chehab }, {
2630c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
2640c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
2650c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
2660c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
2670c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
2680c0d06caSMauro Carvalho Chehab .gpio = NULL,
2690c0d06caSMauro Carvalho Chehab }
2700c0d06caSMauro Carvalho Chehab },
2710c0d06caSMauro Carvalho Chehab },
2720c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_RDE_250] = {
2730c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - rde 250",
2740c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_XC5000,
2750c0d06caSMauro Carvalho Chehab .tuner_addr = 0x61,
2760c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
2770c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
2780c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
2790c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
2800c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
2810c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
2820c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
2830c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
2840c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
2850c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
286b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
287d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
2880c0d06caSMauro Carvalho Chehab .has_dvb = 1,
2890c0d06caSMauro Carvalho Chehab .demod_addr = 0x02,
2900c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
2910c0d06caSMauro Carvalho Chehab
2920c0d06caSMauro Carvalho Chehab .input = {{
2930c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
2940c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
2950c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
2960c0d06caSMauro Carvalho Chehab .gpio = NULL,
2970c0d06caSMauro Carvalho Chehab }
2980c0d06caSMauro Carvalho Chehab },
2990c0d06caSMauro Carvalho Chehab },
3000c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_CNXT_RDU_250] = {
3010c0d06caSMauro Carvalho Chehab .name = "Conexant Hybrid TV - RDU 250",
3020c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_XC5000,
3030c0d06caSMauro Carvalho Chehab .tuner_addr = 0x61,
3040c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
3050c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
3060c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
3070c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
3080c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
3090c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
3100c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
3110c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
3120c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
3130c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
314b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
315d032ca12SMatthias Schwarzott .demod_i2c_master = I2C_2,
3160c0d06caSMauro Carvalho Chehab .has_dvb = 1,
3170c0d06caSMauro Carvalho Chehab .demod_addr = 0x32,
3180c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
3190c0d06caSMauro Carvalho Chehab
3200c0d06caSMauro Carvalho Chehab .input = {{
3210c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
3220c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
3230c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
3240c0d06caSMauro Carvalho Chehab .gpio = NULL,
3250c0d06caSMauro Carvalho Chehab }
3260c0d06caSMauro Carvalho Chehab },
3270c0d06caSMauro Carvalho Chehab },
3280c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_HAUPPAUGE_EXETER] = {
3290c0d06caSMauro Carvalho Chehab .name = "Hauppauge EXETER",
3300c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
3310c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
3320c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
3330c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
3340c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
3350c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
3360c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
3370c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
3380c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
3390c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
3400c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
3410c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
342b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_1,
343599bedb7SMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_1,
3440c0d06caSMauro Carvalho Chehab .has_dvb = 1,
3450c0d06caSMauro Carvalho Chehab .demod_addr = 0x0e,
3460c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
3470c0d06caSMauro Carvalho Chehab
3480c0d06caSMauro Carvalho Chehab .input = {{
3490c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
3500c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
3510c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
3520c0d06caSMauro Carvalho Chehab .gpio = NULL,
3530c0d06caSMauro Carvalho Chehab }, {
3540c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
3550c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
3560c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
3570c0d06caSMauro Carvalho Chehab .gpio = NULL,
3580c0d06caSMauro Carvalho Chehab }, {
3590c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
3600c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
3610c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
3620c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
3630c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
3640c0d06caSMauro Carvalho Chehab .gpio = NULL,
3650c0d06caSMauro Carvalho Chehab } },
3660c0d06caSMauro Carvalho Chehab },
3670c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = {
3680c0d06caSMauro Carvalho Chehab .name = "Hauppauge USB Live 2",
3690c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_ABSENT,
3700c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
3710c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
3720c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
3730c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
3740c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
3750c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
3760c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
3770c0d06caSMauro Carvalho Chehab .no_alt_vanc = 1,
3780c0d06caSMauro Carvalho Chehab .external_av = 1,
3790c0d06caSMauro Carvalho Chehab .input = {{
3800c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
3810c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
3820c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
3830c0d06caSMauro Carvalho Chehab .gpio = NULL,
3840c0d06caSMauro Carvalho Chehab }, {
3850c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
3860c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
3870c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
3880c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
3890c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
3900c0d06caSMauro Carvalho Chehab .gpio = NULL,
3910c0d06caSMauro Carvalho Chehab } },
3920c0d06caSMauro Carvalho Chehab },
3930c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = {
3940c0d06caSMauro Carvalho Chehab .name = "Kworld UB430 USB Hybrid",
3950c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
3960c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
3970c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
3980c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
3990c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
4000c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
4010c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */
4020c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = -1,
4030c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = -1,
4040c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = -1,
4050c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
406d032ca12SMatthias Schwarzott .tuner_i2c_master = I2C_2,
407b9ce9dfdSMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
408d032ca12SMatthias Schwarzott .ir_i2c_master = I2C_2,
4090c0d06caSMauro Carvalho Chehab .has_dvb = 1,
4100c0d06caSMauro Carvalho Chehab .demod_addr = 0x10,
4110c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL_M,
4120c0d06caSMauro Carvalho Chehab .input = {{
4130c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
4140c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
4150c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
4160c0d06caSMauro Carvalho Chehab .gpio = NULL,
4170c0d06caSMauro Carvalho Chehab }, {
4180c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
4190c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
4200c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
4210c0d06caSMauro Carvalho Chehab .gpio = NULL,
4220c0d06caSMauro Carvalho Chehab }, {
4230c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
4240c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
4250c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
4260c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
4270c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
4280c0d06caSMauro Carvalho Chehab .gpio = NULL,
4290c0d06caSMauro Carvalho Chehab } },
4300c0d06caSMauro Carvalho Chehab },
4318b1255a2SJohannes Erdfelt [CX231XX_BOARD_KWORLD_UB445_USB_HYBRID] = {
4328b1255a2SJohannes Erdfelt .name = "Kworld UB445 USB Hybrid",
4338b1255a2SJohannes Erdfelt .tuner_type = TUNER_NXP_TDA18271,
4348b1255a2SJohannes Erdfelt .tuner_addr = 0x60,
4358b1255a2SJohannes Erdfelt .decoder = CX231XX_AVDECODER,
4368b1255a2SJohannes Erdfelt .output_mode = OUT_MODE_VIP11,
4378b1255a2SJohannes Erdfelt .demod_xfer_mode = 0,
4388b1255a2SJohannes Erdfelt .ctl_pin_status_mask = 0xFFFFFFC4,
4398b1255a2SJohannes Erdfelt .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */
4408b1255a2SJohannes Erdfelt .tuner_sif_gpio = -1,
4418b1255a2SJohannes Erdfelt .tuner_scl_gpio = -1,
4428b1255a2SJohannes Erdfelt .tuner_sda_gpio = -1,
4438b1255a2SJohannes Erdfelt .gpio_pin_status_mask = 0x4001000,
444d032ca12SMatthias Schwarzott .tuner_i2c_master = I2C_2,
445b9ce9dfdSMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
446d032ca12SMatthias Schwarzott .ir_i2c_master = I2C_2,
4478b1255a2SJohannes Erdfelt .has_dvb = 1,
4488b1255a2SJohannes Erdfelt .demod_addr = 0x10,
4498b1255a2SJohannes Erdfelt .norm = V4L2_STD_NTSC_M,
4508b1255a2SJohannes Erdfelt .input = {{
4518b1255a2SJohannes Erdfelt .type = CX231XX_VMUX_TELEVISION,
4528b1255a2SJohannes Erdfelt .vmux = CX231XX_VIN_3_1,
4538b1255a2SJohannes Erdfelt .amux = CX231XX_AMUX_VIDEO,
4548b1255a2SJohannes Erdfelt .gpio = NULL,
4558b1255a2SJohannes Erdfelt }, {
4568b1255a2SJohannes Erdfelt .type = CX231XX_VMUX_COMPOSITE1,
4578b1255a2SJohannes Erdfelt .vmux = CX231XX_VIN_2_1,
4588b1255a2SJohannes Erdfelt .amux = CX231XX_AMUX_LINE_IN,
4598b1255a2SJohannes Erdfelt .gpio = NULL,
4608b1255a2SJohannes Erdfelt }, {
4618b1255a2SJohannes Erdfelt .type = CX231XX_VMUX_SVIDEO,
4628b1255a2SJohannes Erdfelt .vmux = CX231XX_VIN_1_1 |
4638b1255a2SJohannes Erdfelt (CX231XX_VIN_1_2 << 8) |
4648b1255a2SJohannes Erdfelt CX25840_SVIDEO_ON,
4658b1255a2SJohannes Erdfelt .amux = CX231XX_AMUX_LINE_IN,
4668b1255a2SJohannes Erdfelt .gpio = NULL,
4678b1255a2SJohannes Erdfelt } },
4688b1255a2SJohannes Erdfelt },
4690c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
4700c0d06caSMauro Carvalho Chehab .name = "Pixelview PlayTV USB Hybrid",
4710c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
4720c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
4730c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
4740c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
4750c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
4760c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
47724b923f0SMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x1c,
4780c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = -1,
4790c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = -1,
4800c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = -1,
4810c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
482d032ca12SMatthias Schwarzott .tuner_i2c_master = I2C_2,
483b9ce9dfdSMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
484d032ca12SMatthias Schwarzott .ir_i2c_master = I2C_2,
4850c0d06caSMauro Carvalho Chehab .rc_map_name = RC_MAP_PIXELVIEW_002T,
4860c0d06caSMauro Carvalho Chehab .has_dvb = 1,
4870c0d06caSMauro Carvalho Chehab .demod_addr = 0x10,
4880c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL_M,
4890c0d06caSMauro Carvalho Chehab .input = {{
4900c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
4910c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
4920c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
4930c0d06caSMauro Carvalho Chehab .gpio = NULL,
4940c0d06caSMauro Carvalho Chehab }, {
4950c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
4960c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
4970c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
4980c0d06caSMauro Carvalho Chehab .gpio = NULL,
4990c0d06caSMauro Carvalho Chehab }, {
5000c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
5010c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
5020c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
5030c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
5040c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5050c0d06caSMauro Carvalho Chehab .gpio = NULL,
5060c0d06caSMauro Carvalho Chehab } },
5070c0d06caSMauro Carvalho Chehab },
5080c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_PV_XCAPTURE_USB] = {
5090c0d06caSMauro Carvalho Chehab .name = "Pixelview Xcapture USB",
5100c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_ABSENT,
5110c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
5120c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
5130c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
5140c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
5150c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
5160c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
5170c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
5180c0d06caSMauro Carvalho Chehab .no_alt_vanc = 1,
5190c0d06caSMauro Carvalho Chehab .external_av = 1,
5200c0d06caSMauro Carvalho Chehab
5210c0d06caSMauro Carvalho Chehab .input = {{
5220c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
5230c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
5240c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5250c0d06caSMauro Carvalho Chehab .gpio = NULL,
5260c0d06caSMauro Carvalho Chehab }, {
5270c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
5280c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
5290c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
5300c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
5310c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5320c0d06caSMauro Carvalho Chehab .gpio = NULL,
5330c0d06caSMauro Carvalho Chehab }
5340c0d06caSMauro Carvalho Chehab },
5350c0d06caSMauro Carvalho Chehab },
5360c0d06caSMauro Carvalho Chehab
5370c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_ICONBIT_U100] = {
5380c0d06caSMauro Carvalho Chehab .name = "Iconbit Analog Stick U100 FM",
5390c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_ABSENT,
5400c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
5410c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
5420c0d06caSMauro Carvalho Chehab .demod_xfer_mode = 0,
5430c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
5440c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x1C,
5450c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
5460c0d06caSMauro Carvalho Chehab
5470c0d06caSMauro Carvalho Chehab .input = {{
5480c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
5490c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
5500c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5510c0d06caSMauro Carvalho Chehab .gpio = NULL,
5520c0d06caSMauro Carvalho Chehab }, {
5530c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
5540c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
5550c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
5560c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
5570c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5580c0d06caSMauro Carvalho Chehab .gpio = NULL,
5590c0d06caSMauro Carvalho Chehab } },
5600c0d06caSMauro Carvalho Chehab },
5610c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL] = {
5620c0d06caSMauro Carvalho Chehab .name = "Hauppauge WinTV USB2 FM (PAL)",
5630c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
5640c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
5650c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
5660c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
5670c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
5680c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
5690c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
5700c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
5710c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
5720c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
5730c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
574b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
5750c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_PAL,
5760c0d06caSMauro Carvalho Chehab
5770c0d06caSMauro Carvalho Chehab .input = {{
5780c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
5790c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
5800c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
5810c0d06caSMauro Carvalho Chehab .gpio = NULL,
5820c0d06caSMauro Carvalho Chehab }, {
5830c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
5840c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
5850c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5860c0d06caSMauro Carvalho Chehab .gpio = NULL,
5870c0d06caSMauro Carvalho Chehab }, {
5880c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
5890c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
5900c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
5910c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
5920c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
5930c0d06caSMauro Carvalho Chehab .gpio = NULL,
5940c0d06caSMauro Carvalho Chehab } },
5950c0d06caSMauro Carvalho Chehab },
5960c0d06caSMauro Carvalho Chehab [CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC] = {
5970c0d06caSMauro Carvalho Chehab .name = "Hauppauge WinTV USB2 FM (NTSC)",
5980c0d06caSMauro Carvalho Chehab .tuner_type = TUNER_NXP_TDA18271,
5990c0d06caSMauro Carvalho Chehab .tuner_addr = 0x60,
6000c0d06caSMauro Carvalho Chehab .tuner_gpio = RDE250_XCV_TUNER,
6010c0d06caSMauro Carvalho Chehab .tuner_sif_gpio = 0x05,
6020c0d06caSMauro Carvalho Chehab .tuner_scl_gpio = 0x1a,
6030c0d06caSMauro Carvalho Chehab .tuner_sda_gpio = 0x1b,
6040c0d06caSMauro Carvalho Chehab .decoder = CX231XX_AVDECODER,
6050c0d06caSMauro Carvalho Chehab .output_mode = OUT_MODE_VIP11,
6060c0d06caSMauro Carvalho Chehab .ctl_pin_status_mask = 0xFFFFFFC4,
6070c0d06caSMauro Carvalho Chehab .agc_analog_digital_select_gpio = 0x0c,
6080c0d06caSMauro Carvalho Chehab .gpio_pin_status_mask = 0x4001000,
609b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
6100c0d06caSMauro Carvalho Chehab .norm = V4L2_STD_NTSC,
6110c0d06caSMauro Carvalho Chehab
6120c0d06caSMauro Carvalho Chehab .input = {{
6130c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_TELEVISION,
6140c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_3_1,
6150c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_VIDEO,
6160c0d06caSMauro Carvalho Chehab .gpio = NULL,
6170c0d06caSMauro Carvalho Chehab }, {
6180c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_COMPOSITE1,
6190c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_2_1,
6200c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
6210c0d06caSMauro Carvalho Chehab .gpio = NULL,
6220c0d06caSMauro Carvalho Chehab }, {
6230c0d06caSMauro Carvalho Chehab .type = CX231XX_VMUX_SVIDEO,
6240c0d06caSMauro Carvalho Chehab .vmux = CX231XX_VIN_1_1 |
6250c0d06caSMauro Carvalho Chehab (CX231XX_VIN_1_2 << 8) |
6260c0d06caSMauro Carvalho Chehab CX25840_SVIDEO_ON,
6270c0d06caSMauro Carvalho Chehab .amux = CX231XX_AMUX_LINE_IN,
6280c0d06caSMauro Carvalho Chehab .gpio = NULL,
6290c0d06caSMauro Carvalho Chehab } },
6300c0d06caSMauro Carvalho Chehab },
63168c97bf3SAlf Høgemark [CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2] = {
63268c97bf3SAlf Høgemark .name = "Elgato Video Capture V2",
63368c97bf3SAlf Høgemark .tuner_type = TUNER_ABSENT,
63468c97bf3SAlf Høgemark .decoder = CX231XX_AVDECODER,
63568c97bf3SAlf Høgemark .output_mode = OUT_MODE_VIP11,
63668c97bf3SAlf Høgemark .demod_xfer_mode = 0,
63768c97bf3SAlf Høgemark .ctl_pin_status_mask = 0xFFFFFFC4,
63868c97bf3SAlf Høgemark .agc_analog_digital_select_gpio = 0x0c,
63968c97bf3SAlf Høgemark .gpio_pin_status_mask = 0x4001000,
64068c97bf3SAlf Høgemark .norm = V4L2_STD_NTSC,
64168c97bf3SAlf Høgemark .no_alt_vanc = 1,
64268c97bf3SAlf Høgemark .external_av = 1,
64368c97bf3SAlf Høgemark .input = {{
64468c97bf3SAlf Høgemark .type = CX231XX_VMUX_COMPOSITE1,
64568c97bf3SAlf Høgemark .vmux = CX231XX_VIN_2_1,
64668c97bf3SAlf Høgemark .amux = CX231XX_AMUX_LINE_IN,
64768c97bf3SAlf Høgemark .gpio = NULL,
64868c97bf3SAlf Høgemark }, {
64968c97bf3SAlf Høgemark .type = CX231XX_VMUX_SVIDEO,
65068c97bf3SAlf Høgemark .vmux = CX231XX_VIN_1_1 |
65168c97bf3SAlf Høgemark (CX231XX_VIN_1_2 << 8) |
65268c97bf3SAlf Høgemark CX25840_SVIDEO_ON,
65368c97bf3SAlf Høgemark .amux = CX231XX_AMUX_LINE_IN,
65468c97bf3SAlf Høgemark .gpio = NULL,
65568c97bf3SAlf Høgemark } },
65668c97bf3SAlf Høgemark },
6573ead1ba3SMatt Gomboc [CX231XX_BOARD_OTG102] = {
6583ead1ba3SMatt Gomboc .name = "Geniatech OTG102",
6593ead1ba3SMatt Gomboc .tuner_type = TUNER_ABSENT,
6603ead1ba3SMatt Gomboc .decoder = CX231XX_AVDECODER,
6613ead1ba3SMatt Gomboc .output_mode = OUT_MODE_VIP11,
6623ead1ba3SMatt Gomboc .ctl_pin_status_mask = 0xFFFFFFC4,
6633ead1ba3SMatt Gomboc .agc_analog_digital_select_gpio = 0x0c,
6643ead1ba3SMatt Gomboc /* According with PV CxPlrCAP.inf file */
6653ead1ba3SMatt Gomboc .gpio_pin_status_mask = 0x4001000,
6663ead1ba3SMatt Gomboc .norm = V4L2_STD_NTSC,
6673ead1ba3SMatt Gomboc .no_alt_vanc = 1,
6683ead1ba3SMatt Gomboc .external_av = 1,
6693ead1ba3SMatt Gomboc /*.has_417 = 1, */
6703ead1ba3SMatt Gomboc /* This board is believed to have a hardware encoding chip
6713ead1ba3SMatt Gomboc * supporting mpeg1/2/4, but as the 417 is apparently not
6723ead1ba3SMatt Gomboc * working for the reference board it is not here either. */
6733ead1ba3SMatt Gomboc
6743ead1ba3SMatt Gomboc .input = {{
6753ead1ba3SMatt Gomboc .type = CX231XX_VMUX_COMPOSITE1,
6763ead1ba3SMatt Gomboc .vmux = CX231XX_VIN_2_1,
6773ead1ba3SMatt Gomboc .amux = CX231XX_AMUX_LINE_IN,
6783ead1ba3SMatt Gomboc .gpio = NULL,
6793ead1ba3SMatt Gomboc }, {
6803ead1ba3SMatt Gomboc .type = CX231XX_VMUX_SVIDEO,
6813ead1ba3SMatt Gomboc .vmux = CX231XX_VIN_1_1 |
6823ead1ba3SMatt Gomboc (CX231XX_VIN_1_2 << 8) |
6833ead1ba3SMatt Gomboc CX25840_SVIDEO_ON,
6843ead1ba3SMatt Gomboc .amux = CX231XX_AMUX_LINE_IN,
6853ead1ba3SMatt Gomboc .gpio = NULL,
6863ead1ba3SMatt Gomboc }
6873ead1ba3SMatt Gomboc },
6883ead1ba3SMatt Gomboc },
689dd2e7dd2SMatthias Schwarzott [CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx] = {
69057cbf3efSMatthias Schwarzott .name = "Hauppauge WinTV 930C-HD (1113xx) / HVR-900H (111xxx) / PCTV QuatroStick 521e",
691dd2e7dd2SMatthias Schwarzott .tuner_type = TUNER_NXP_TDA18271,
692dd2e7dd2SMatthias Schwarzott .tuner_addr = 0x60,
693dd2e7dd2SMatthias Schwarzott .tuner_gpio = RDE250_XCV_TUNER,
694dd2e7dd2SMatthias Schwarzott .tuner_sif_gpio = 0x05,
695dd2e7dd2SMatthias Schwarzott .tuner_scl_gpio = 0x1a,
696dd2e7dd2SMatthias Schwarzott .tuner_sda_gpio = 0x1b,
697dd2e7dd2SMatthias Schwarzott .decoder = CX231XX_AVDECODER,
698dd2e7dd2SMatthias Schwarzott .output_mode = OUT_MODE_VIP11,
699dd2e7dd2SMatthias Schwarzott .demod_xfer_mode = 0,
700dd2e7dd2SMatthias Schwarzott .ctl_pin_status_mask = 0xFFFFFFC4,
701dd2e7dd2SMatthias Schwarzott .agc_analog_digital_select_gpio = 0x0c,
702dd2e7dd2SMatthias Schwarzott .gpio_pin_status_mask = 0x4001000,
703b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
704599bedb7SMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
705dd2e7dd2SMatthias Schwarzott .has_dvb = 1,
706830a57f4SBrad Love .demod_addr = 0x64, /* 0xc8 >> 1 */
707dd2e7dd2SMatthias Schwarzott .norm = V4L2_STD_PAL,
708dd2e7dd2SMatthias Schwarzott
709dd2e7dd2SMatthias Schwarzott .input = {{
710dd2e7dd2SMatthias Schwarzott .type = CX231XX_VMUX_TELEVISION,
711dd2e7dd2SMatthias Schwarzott .vmux = CX231XX_VIN_3_1,
712dd2e7dd2SMatthias Schwarzott .amux = CX231XX_AMUX_VIDEO,
713dd2e7dd2SMatthias Schwarzott .gpio = NULL,
714dd2e7dd2SMatthias Schwarzott }, {
715dd2e7dd2SMatthias Schwarzott .type = CX231XX_VMUX_COMPOSITE1,
716dd2e7dd2SMatthias Schwarzott .vmux = CX231XX_VIN_2_1,
717dd2e7dd2SMatthias Schwarzott .amux = CX231XX_AMUX_LINE_IN,
718dd2e7dd2SMatthias Schwarzott .gpio = NULL,
719dd2e7dd2SMatthias Schwarzott }, {
720dd2e7dd2SMatthias Schwarzott .type = CX231XX_VMUX_SVIDEO,
721dd2e7dd2SMatthias Schwarzott .vmux = CX231XX_VIN_1_1 |
722dd2e7dd2SMatthias Schwarzott (CX231XX_VIN_1_2 << 8) |
723dd2e7dd2SMatthias Schwarzott CX25840_SVIDEO_ON,
724dd2e7dd2SMatthias Schwarzott .amux = CX231XX_AMUX_LINE_IN,
725dd2e7dd2SMatthias Schwarzott .gpio = NULL,
726dd2e7dd2SMatthias Schwarzott } },
727dd2e7dd2SMatthias Schwarzott },
7289e49f7c3SMatthias Schwarzott [CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx] = {
7298618ac4dSMatthias Schwarzott .name = "Hauppauge WinTV 930C-HD (1114xx) / HVR-901H (1114xx) / PCTV QuatroStick 522e",
7309e49f7c3SMatthias Schwarzott .tuner_type = TUNER_ABSENT,
7319e49f7c3SMatthias Schwarzott .tuner_addr = 0x60,
7329e49f7c3SMatthias Schwarzott .tuner_gpio = RDE250_XCV_TUNER,
7339e49f7c3SMatthias Schwarzott .tuner_sif_gpio = 0x05,
7349e49f7c3SMatthias Schwarzott .tuner_scl_gpio = 0x1a,
7359e49f7c3SMatthias Schwarzott .tuner_sda_gpio = 0x1b,
7369e49f7c3SMatthias Schwarzott .decoder = CX231XX_AVDECODER,
7379e49f7c3SMatthias Schwarzott .output_mode = OUT_MODE_VIP11,
7389e49f7c3SMatthias Schwarzott .demod_xfer_mode = 0,
7399e49f7c3SMatthias Schwarzott .ctl_pin_status_mask = 0xFFFFFFC4,
7409e49f7c3SMatthias Schwarzott .agc_analog_digital_select_gpio = 0x0c,
7419e49f7c3SMatthias Schwarzott .gpio_pin_status_mask = 0x4001000,
742b9ce9dfdSMatthias Schwarzott .tuner_i2c_master = I2C_1_MUX_3,
743599bedb7SMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
7449e49f7c3SMatthias Schwarzott .has_dvb = 1,
745830a57f4SBrad Love .demod_addr = 0x64, /* 0xc8 >> 1 */
7469e49f7c3SMatthias Schwarzott .norm = V4L2_STD_PAL,
7479e49f7c3SMatthias Schwarzott
7489e49f7c3SMatthias Schwarzott .input = {{
7499e49f7c3SMatthias Schwarzott .type = CX231XX_VMUX_TELEVISION,
7509e49f7c3SMatthias Schwarzott .vmux = CX231XX_VIN_3_1,
7519e49f7c3SMatthias Schwarzott .amux = CX231XX_AMUX_VIDEO,
7529e49f7c3SMatthias Schwarzott .gpio = NULL,
7539e49f7c3SMatthias Schwarzott }, {
7549e49f7c3SMatthias Schwarzott .type = CX231XX_VMUX_COMPOSITE1,
7559e49f7c3SMatthias Schwarzott .vmux = CX231XX_VIN_2_1,
7569e49f7c3SMatthias Schwarzott .amux = CX231XX_AMUX_LINE_IN,
7579e49f7c3SMatthias Schwarzott .gpio = NULL,
7589e49f7c3SMatthias Schwarzott }, {
7599e49f7c3SMatthias Schwarzott .type = CX231XX_VMUX_SVIDEO,
7609e49f7c3SMatthias Schwarzott .vmux = CX231XX_VIN_1_1 |
7619e49f7c3SMatthias Schwarzott (CX231XX_VIN_1_2 << 8) |
7629e49f7c3SMatthias Schwarzott CX25840_SVIDEO_ON,
7639e49f7c3SMatthias Schwarzott .amux = CX231XX_AMUX_LINE_IN,
7649e49f7c3SMatthias Schwarzott .gpio = NULL,
7659e49f7c3SMatthias Schwarzott } },
7669e49f7c3SMatthias Schwarzott },
767809abdbfSOlli Salonen [CX231XX_BOARD_HAUPPAUGE_955Q] = {
768809abdbfSOlli Salonen .name = "Hauppauge WinTV-HVR-955Q (111401)",
769809abdbfSOlli Salonen .tuner_type = TUNER_ABSENT,
770809abdbfSOlli Salonen .tuner_addr = 0x60,
771809abdbfSOlli Salonen .tuner_gpio = RDE250_XCV_TUNER,
772809abdbfSOlli Salonen .tuner_sif_gpio = 0x05,
773809abdbfSOlli Salonen .tuner_scl_gpio = 0x1a,
774809abdbfSOlli Salonen .tuner_sda_gpio = 0x1b,
775809abdbfSOlli Salonen .decoder = CX231XX_AVDECODER,
776809abdbfSOlli Salonen .output_mode = OUT_MODE_VIP11,
777809abdbfSOlli Salonen .demod_xfer_mode = 0,
778809abdbfSOlli Salonen .ctl_pin_status_mask = 0xFFFFFFC4,
779809abdbfSOlli Salonen .agc_analog_digital_select_gpio = 0x0c,
780809abdbfSOlli Salonen .gpio_pin_status_mask = 0x4001000,
781809abdbfSOlli Salonen .tuner_i2c_master = I2C_1_MUX_3,
782599bedb7SMatthias Schwarzott .demod_i2c_master = I2C_1_MUX_3,
783809abdbfSOlli Salonen .has_dvb = 1,
784830a57f4SBrad Love .demod_addr = 0x59, /* 0xb2 >> 1 */
785809abdbfSOlli Salonen .norm = V4L2_STD_NTSC,
786809abdbfSOlli Salonen
787809abdbfSOlli Salonen .input = {{
788809abdbfSOlli Salonen .type = CX231XX_VMUX_TELEVISION,
789809abdbfSOlli Salonen .vmux = CX231XX_VIN_3_1,
790809abdbfSOlli Salonen .amux = CX231XX_AMUX_VIDEO,
791809abdbfSOlli Salonen .gpio = NULL,
792809abdbfSOlli Salonen }, {
793809abdbfSOlli Salonen .type = CX231XX_VMUX_COMPOSITE1,
794809abdbfSOlli Salonen .vmux = CX231XX_VIN_2_1,
795809abdbfSOlli Salonen .amux = CX231XX_AMUX_LINE_IN,
796809abdbfSOlli Salonen .gpio = NULL,
797809abdbfSOlli Salonen }, {
798809abdbfSOlli Salonen .type = CX231XX_VMUX_SVIDEO,
799809abdbfSOlli Salonen .vmux = CX231XX_VIN_1_1 |
800809abdbfSOlli Salonen (CX231XX_VIN_1_2 << 8) |
801809abdbfSOlli Salonen CX25840_SVIDEO_ON,
802809abdbfSOlli Salonen .amux = CX231XX_AMUX_LINE_IN,
803809abdbfSOlli Salonen .gpio = NULL,
804809abdbfSOlli Salonen } },
805809abdbfSOlli Salonen },
806eee1d06dSTommi Rantala [CX231XX_BOARD_TERRATEC_GRABBY] = {
807eee1d06dSTommi Rantala .name = "Terratec Grabby",
808eee1d06dSTommi Rantala .tuner_type = TUNER_ABSENT,
809eee1d06dSTommi Rantala .decoder = CX231XX_AVDECODER,
810eee1d06dSTommi Rantala .output_mode = OUT_MODE_VIP11,
811eee1d06dSTommi Rantala .demod_xfer_mode = 0,
812eee1d06dSTommi Rantala .ctl_pin_status_mask = 0xFFFFFFC4,
813eee1d06dSTommi Rantala .agc_analog_digital_select_gpio = 0x0c,
814eee1d06dSTommi Rantala .gpio_pin_status_mask = 0x4001000,
815eee1d06dSTommi Rantala .norm = V4L2_STD_PAL,
816eee1d06dSTommi Rantala .no_alt_vanc = 1,
817eee1d06dSTommi Rantala .external_av = 1,
818eee1d06dSTommi Rantala .input = {{
819eee1d06dSTommi Rantala .type = CX231XX_VMUX_COMPOSITE1,
820eee1d06dSTommi Rantala .vmux = CX231XX_VIN_2_1,
821eee1d06dSTommi Rantala .amux = CX231XX_AMUX_LINE_IN,
822eee1d06dSTommi Rantala .gpio = NULL,
823eee1d06dSTommi Rantala }, {
824eee1d06dSTommi Rantala .type = CX231XX_VMUX_SVIDEO,
825eee1d06dSTommi Rantala .vmux = CX231XX_VIN_1_1 |
826eee1d06dSTommi Rantala (CX231XX_VIN_1_2 << 8) |
827eee1d06dSTommi Rantala CX25840_SVIDEO_ON,
828eee1d06dSTommi Rantala .amux = CX231XX_AMUX_LINE_IN,
829eee1d06dSTommi Rantala .gpio = NULL,
830eee1d06dSTommi Rantala } },
831eee1d06dSTommi Rantala },
832a096fd64SOleh Kravchenko [CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD] = {
833a096fd64SOleh Kravchenko .name = "Evromedia USB Full Hybrid Full HD",
834a096fd64SOleh Kravchenko .tuner_type = TUNER_ABSENT,
835a096fd64SOleh Kravchenko .demod_addr = 0x64, /* 0xc8 >> 1 */
836a096fd64SOleh Kravchenko .demod_i2c_master = I2C_1_MUX_3,
837a096fd64SOleh Kravchenko .has_dvb = 1,
8389d377daeSOleh Kravchenko .decoder = CX231XX_AVDECODER,
839a096fd64SOleh Kravchenko .norm = V4L2_STD_PAL,
840a096fd64SOleh Kravchenko .output_mode = OUT_MODE_VIP11,
841a096fd64SOleh Kravchenko .tuner_addr = 0x60, /* 0xc0 >> 1 */
842a096fd64SOleh Kravchenko .tuner_i2c_master = I2C_2,
843a096fd64SOleh Kravchenko .input = {{
844a096fd64SOleh Kravchenko .type = CX231XX_VMUX_TELEVISION,
845a096fd64SOleh Kravchenko .vmux = 0,
846a096fd64SOleh Kravchenko .amux = CX231XX_AMUX_VIDEO,
847a096fd64SOleh Kravchenko }, {
848a096fd64SOleh Kravchenko .type = CX231XX_VMUX_COMPOSITE1,
849a096fd64SOleh Kravchenko .vmux = CX231XX_VIN_2_1,
850a096fd64SOleh Kravchenko .amux = CX231XX_AMUX_LINE_IN,
851a096fd64SOleh Kravchenko }, {
852a096fd64SOleh Kravchenko .type = CX231XX_VMUX_SVIDEO,
853a096fd64SOleh Kravchenko .vmux = CX231XX_VIN_1_1 |
854a096fd64SOleh Kravchenko (CX231XX_VIN_1_2 << 8) |
855a096fd64SOleh Kravchenko CX25840_SVIDEO_ON,
856a096fd64SOleh Kravchenko .amux = CX231XX_AMUX_LINE_IN,
857a096fd64SOleh Kravchenko } },
858a096fd64SOleh Kravchenko },
8590f42b331SOleh Kravchenko [CX231XX_BOARD_ASTROMETA_T2HYBRID] = {
8600f42b331SOleh Kravchenko .name = "Astrometa T2hybrid",
8610f42b331SOleh Kravchenko .tuner_type = TUNER_ABSENT,
8620f42b331SOleh Kravchenko .has_dvb = 1,
8631bfbb885SOleh Kravchenko .decoder = CX231XX_AVDECODER,
8640f42b331SOleh Kravchenko .output_mode = OUT_MODE_VIP11,
8650f42b331SOleh Kravchenko .agc_analog_digital_select_gpio = 0x01,
8660f42b331SOleh Kravchenko .ctl_pin_status_mask = 0xffffffc4,
8670f42b331SOleh Kravchenko .demod_addr = 0x18, /* 0x30 >> 1 */
8680f42b331SOleh Kravchenko .demod_i2c_master = I2C_1_MUX_1,
8690f42b331SOleh Kravchenko .gpio_pin_status_mask = 0xa,
8700f42b331SOleh Kravchenko .norm = V4L2_STD_NTSC,
8710f42b331SOleh Kravchenko .tuner_addr = 0x3a, /* 0x74 >> 1 */
8720f42b331SOleh Kravchenko .tuner_i2c_master = I2C_1_MUX_3,
8730f42b331SOleh Kravchenko .tuner_scl_gpio = 0x1a,
8740f42b331SOleh Kravchenko .tuner_sda_gpio = 0x1b,
8750f42b331SOleh Kravchenko .tuner_sif_gpio = 0x05,
8760f42b331SOleh Kravchenko .input = {{
8770f42b331SOleh Kravchenko .type = CX231XX_VMUX_TELEVISION,
8780f42b331SOleh Kravchenko .vmux = CX231XX_VIN_1_1,
8790f42b331SOleh Kravchenko .amux = CX231XX_AMUX_VIDEO,
8800f42b331SOleh Kravchenko }, {
8810f42b331SOleh Kravchenko .type = CX231XX_VMUX_COMPOSITE1,
8820f42b331SOleh Kravchenko .vmux = CX231XX_VIN_2_1,
8830f42b331SOleh Kravchenko .amux = CX231XX_AMUX_LINE_IN,
8840f42b331SOleh Kravchenko },
8850f42b331SOleh Kravchenko },
8860f42b331SOleh Kravchenko },
887fdda0109SRomain Reignier [CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO] = {
888fdda0109SRomain Reignier .name = "The Imaging Source DFG/USB2pro",
889fdda0109SRomain Reignier .tuner_type = TUNER_ABSENT,
890fdda0109SRomain Reignier .decoder = CX231XX_AVDECODER,
891fdda0109SRomain Reignier .output_mode = OUT_MODE_VIP11,
892fdda0109SRomain Reignier .demod_xfer_mode = 0,
893fdda0109SRomain Reignier .ctl_pin_status_mask = 0xFFFFFFC4,
894fdda0109SRomain Reignier .agc_analog_digital_select_gpio = 0x0c,
895fdda0109SRomain Reignier .gpio_pin_status_mask = 0x4001000,
896fdda0109SRomain Reignier .norm = V4L2_STD_PAL,
897fdda0109SRomain Reignier .no_alt_vanc = 1,
898fdda0109SRomain Reignier .external_av = 1,
899fdda0109SRomain Reignier .input = {{
900fdda0109SRomain Reignier .type = CX231XX_VMUX_COMPOSITE1,
901fdda0109SRomain Reignier .vmux = CX231XX_VIN_1_1,
902fdda0109SRomain Reignier .amux = CX231XX_AMUX_LINE_IN,
903fdda0109SRomain Reignier .gpio = NULL,
904fdda0109SRomain Reignier }, {
905fdda0109SRomain Reignier .type = CX231XX_VMUX_SVIDEO,
906fdda0109SRomain Reignier .vmux = CX231XX_VIN_2_1 |
907fdda0109SRomain Reignier (CX231XX_VIN_2_2 << 8) |
908fdda0109SRomain Reignier CX25840_SVIDEO_ON,
909fdda0109SRomain Reignier .amux = CX231XX_AMUX_LINE_IN,
910fdda0109SRomain Reignier .gpio = NULL,
911fdda0109SRomain Reignier } },
912fdda0109SRomain Reignier },
913c5bef50eSBrad Love [CX231XX_BOARD_HAUPPAUGE_935C] = {
914c5bef50eSBrad Love .name = "Hauppauge WinTV-HVR-935C",
915c5bef50eSBrad Love .tuner_type = TUNER_ABSENT,
916c5bef50eSBrad Love .tuner_addr = 0x60,
917c5bef50eSBrad Love .tuner_gpio = RDE250_XCV_TUNER,
918c5bef50eSBrad Love .tuner_sif_gpio = 0x05,
919c5bef50eSBrad Love .tuner_scl_gpio = 0x1a,
920c5bef50eSBrad Love .tuner_sda_gpio = 0x1b,
921c5bef50eSBrad Love .decoder = CX231XX_AVDECODER,
922c5bef50eSBrad Love .output_mode = OUT_MODE_VIP11,
923c5bef50eSBrad Love .demod_xfer_mode = 0,
924c5bef50eSBrad Love .ctl_pin_status_mask = 0xFFFFFFC4,
925c5bef50eSBrad Love .agc_analog_digital_select_gpio = 0x0c,
926c5bef50eSBrad Love .gpio_pin_status_mask = 0x4001000,
927c5bef50eSBrad Love .tuner_i2c_master = I2C_1_MUX_3,
928c5bef50eSBrad Love .demod_i2c_master = I2C_1_MUX_3,
929c5bef50eSBrad Love .has_dvb = 1,
930c5bef50eSBrad Love .demod_addr = 0x64, /* 0xc8 >> 1 */
931c5bef50eSBrad Love .norm = V4L2_STD_PAL,
932c5bef50eSBrad Love
933c5bef50eSBrad Love .input = {{
934c5bef50eSBrad Love .type = CX231XX_VMUX_TELEVISION,
935c5bef50eSBrad Love .vmux = CX231XX_VIN_3_1,
936c5bef50eSBrad Love .amux = CX231XX_AMUX_VIDEO,
937c5bef50eSBrad Love .gpio = NULL,
938c5bef50eSBrad Love }, {
939c5bef50eSBrad Love .type = CX231XX_VMUX_COMPOSITE1,
940c5bef50eSBrad Love .vmux = CX231XX_VIN_2_1,
941c5bef50eSBrad Love .amux = CX231XX_AMUX_LINE_IN,
942c5bef50eSBrad Love .gpio = NULL,
943c5bef50eSBrad Love }, {
944c5bef50eSBrad Love .type = CX231XX_VMUX_SVIDEO,
945c5bef50eSBrad Love .vmux = CX231XX_VIN_1_1 |
946c5bef50eSBrad Love (CX231XX_VIN_1_2 << 8) |
947c5bef50eSBrad Love CX25840_SVIDEO_ON,
948c5bef50eSBrad Love .amux = CX231XX_AMUX_LINE_IN,
949c5bef50eSBrad Love .gpio = NULL,
950c5bef50eSBrad Love } },
951c5bef50eSBrad Love },
95219fbf1baSBrad Love [CX231XX_BOARD_HAUPPAUGE_975] = {
95319fbf1baSBrad Love .name = "Hauppauge WinTV-HVR-975",
95419fbf1baSBrad Love .tuner_type = TUNER_ABSENT,
95519fbf1baSBrad Love .tuner_addr = 0x60,
95619fbf1baSBrad Love .tuner_gpio = RDE250_XCV_TUNER,
95719fbf1baSBrad Love .tuner_sif_gpio = 0x05,
95819fbf1baSBrad Love .tuner_scl_gpio = 0x1a,
95919fbf1baSBrad Love .tuner_sda_gpio = 0x1b,
96019fbf1baSBrad Love .decoder = CX231XX_AVDECODER,
96119fbf1baSBrad Love .output_mode = OUT_MODE_VIP11,
96219fbf1baSBrad Love .demod_xfer_mode = 0,
96319fbf1baSBrad Love .ctl_pin_status_mask = 0xFFFFFFC4,
96419fbf1baSBrad Love .agc_analog_digital_select_gpio = 0x0c,
96519fbf1baSBrad Love .gpio_pin_status_mask = 0x4001000,
96619fbf1baSBrad Love .tuner_i2c_master = I2C_1_MUX_3,
96719fbf1baSBrad Love .demod_i2c_master = I2C_1_MUX_3,
96819fbf1baSBrad Love .has_dvb = 1,
96919fbf1baSBrad Love .demod_addr = 0x59, /* 0xb2 >> 1 */
970a2c52cd7SBrad Love .demod_addr2 = 0x64, /* 0xc8 >> 1 */
97119fbf1baSBrad Love .norm = V4L2_STD_ALL,
97219fbf1baSBrad Love
97319fbf1baSBrad Love .input = {{
97419fbf1baSBrad Love .type = CX231XX_VMUX_TELEVISION,
97519fbf1baSBrad Love .vmux = CX231XX_VIN_3_1,
97619fbf1baSBrad Love .amux = CX231XX_AMUX_VIDEO,
97719fbf1baSBrad Love .gpio = NULL,
97819fbf1baSBrad Love }, {
97919fbf1baSBrad Love .type = CX231XX_VMUX_COMPOSITE1,
98019fbf1baSBrad Love .vmux = CX231XX_VIN_2_1,
98119fbf1baSBrad Love .amux = CX231XX_AMUX_LINE_IN,
98219fbf1baSBrad Love .gpio = NULL,
98319fbf1baSBrad Love }, {
98419fbf1baSBrad Love .type = CX231XX_VMUX_SVIDEO,
98519fbf1baSBrad Love .vmux = CX231XX_VIN_1_1 |
98619fbf1baSBrad Love (CX231XX_VIN_1_2 << 8) |
98719fbf1baSBrad Love CX25840_SVIDEO_ON,
98819fbf1baSBrad Love .amux = CX231XX_AMUX_LINE_IN,
98919fbf1baSBrad Love .gpio = NULL,
99019fbf1baSBrad Love } },
99119fbf1baSBrad Love },
9920c0d06caSMauro Carvalho Chehab };
9930c0d06caSMauro Carvalho Chehab const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
9940c0d06caSMauro Carvalho Chehab
9950c0d06caSMauro Carvalho Chehab /* table of devices that work with this driver */
9960c0d06caSMauro Carvalho Chehab struct usb_device_id cx231xx_id_table[] = {
997dad4c418SLinks (Markus) {USB_DEVICE(0x1D19, 0x6109),
998dad4c418SLinks (Markus) .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
9990c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x5A3C),
10000c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_UNKNOWN},
10010c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A2),
10020c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_CARRAERA},
10030c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A1),
10040c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_SHELBY},
10050c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A4),
10060c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_RDE_253S},
10070c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A5),
10080c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_RDU_253S},
10090c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A6),
10100c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER},
10110c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x589E),
10120c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_RDE_250},
10130c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x0572, 0x58A0),
10140c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_CNXT_RDU_250},
101529e61d6eSKai-Heng Feng /* AverMedia DVD EZMaker 7 */
101629e61d6eSKai-Heng Feng {USB_DEVICE(0x07ca, 0xc039),
101729e61d6eSKai-Heng Feng .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER},
10180c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x2040, 0xb110),
10190c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL},
10200c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x2040, 0xb111),
10210c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC},
10220c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x2040, 0xb120),
10230c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
1024809abdbfSOlli Salonen {USB_DEVICE(0x2040, 0xb123),
1025809abdbfSOlli Salonen .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q},
1026575f6031SBrad Love {USB_DEVICE(0x2040, 0xb124),
1027575f6031SBrad Love .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q},
1028c5bef50eSBrad Love {USB_DEVICE(0x2040, 0xb151),
1029c5bef50eSBrad Love .driver_info = CX231XX_BOARD_HAUPPAUGE_935C},
103019fbf1baSBrad Love {USB_DEVICE(0x2040, 0xb150),
103119fbf1baSBrad Love .driver_info = CX231XX_BOARD_HAUPPAUGE_975},
1032dd2e7dd2SMatthias Schwarzott {USB_DEVICE(0x2040, 0xb130),
1033dd2e7dd2SMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
10349e49f7c3SMatthias Schwarzott {USB_DEVICE(0x2040, 0xb131),
10359e49f7c3SMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
103657cbf3efSMatthias Schwarzott /* Hauppauge WinTV-HVR-900-H */
103757cbf3efSMatthias Schwarzott {USB_DEVICE(0x2040, 0xb138),
103857cbf3efSMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
10398618ac4dSMatthias Schwarzott /* Hauppauge WinTV-HVR-901-H */
10408618ac4dSMatthias Schwarzott {USB_DEVICE(0x2040, 0xb139),
10418618ac4dSMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
10420c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x2040, 0xb140),
10430c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
10440c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x2040, 0xc200),
10450c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
1046a141a887SMatthias Schwarzott /* PCTV QuatroStick 521e */
1047a141a887SMatthias Schwarzott {USB_DEVICE(0x2013, 0x0259),
1048a141a887SMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
1049140a7987SMatthias Schwarzott /* PCTV QuatroStick 522e */
1050140a7987SMatthias Schwarzott {USB_DEVICE(0x2013, 0x025e),
1051140a7987SMatthias Schwarzott .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
10520c0d06caSMauro Carvalho Chehab {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
10530c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
10540c0d06caSMauro Carvalho Chehab {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
10550c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
10560c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x1b80, 0xe424),
10570c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID},
10588b1255a2SJohannes Erdfelt {USB_DEVICE(0x1b80, 0xe421),
10598b1255a2SJohannes Erdfelt .driver_info = CX231XX_BOARD_KWORLD_UB445_USB_HYBRID},
10600c0d06caSMauro Carvalho Chehab {USB_DEVICE(0x1f4d, 0x0237),
10610c0d06caSMauro Carvalho Chehab .driver_info = CX231XX_BOARD_ICONBIT_U100},
106268c97bf3SAlf Høgemark {USB_DEVICE(0x0fd9, 0x0037),
106368c97bf3SAlf Høgemark .driver_info = CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2},
10643ead1ba3SMatt Gomboc {USB_DEVICE(0x1f4d, 0x0102),
10653ead1ba3SMatt Gomboc .driver_info = CX231XX_BOARD_OTG102},
1066eee1d06dSTommi Rantala {USB_DEVICE(USB_VID_TERRATEC, 0x00a6),
1067eee1d06dSTommi Rantala .driver_info = CX231XX_BOARD_TERRATEC_GRABBY},
1068a096fd64SOleh Kravchenko {USB_DEVICE(0x1b80, 0xd3b2),
1069a096fd64SOleh Kravchenko .driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD},
10700f42b331SOleh Kravchenko {USB_DEVICE(0x15f4, 0x0135),
10710f42b331SOleh Kravchenko .driver_info = CX231XX_BOARD_ASTROMETA_T2HYBRID},
1072fdda0109SRomain Reignier {USB_DEVICE(0x199e, 0x8002),
1073fdda0109SRomain Reignier .driver_info = CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO},
10740c0d06caSMauro Carvalho Chehab {},
10750c0d06caSMauro Carvalho Chehab };
10760c0d06caSMauro Carvalho Chehab
10770c0d06caSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, cx231xx_id_table);
10780c0d06caSMauro Carvalho Chehab
10790c0d06caSMauro Carvalho Chehab /* cx231xx_tuner_callback
10800c0d06caSMauro Carvalho Chehab * will be used to reset XC5000 tuner using GPIO pin
10810c0d06caSMauro Carvalho Chehab */
10820c0d06caSMauro Carvalho Chehab
cx231xx_tuner_callback(void * ptr,int component,int command,int arg)10830c0d06caSMauro Carvalho Chehab int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
10840c0d06caSMauro Carvalho Chehab {
10850c0d06caSMauro Carvalho Chehab int rc = 0;
10860c0d06caSMauro Carvalho Chehab struct cx231xx *dev = ptr;
10870c0d06caSMauro Carvalho Chehab
10880c0d06caSMauro Carvalho Chehab if (dev->tuner_type == TUNER_XC5000) {
10890c0d06caSMauro Carvalho Chehab if (command == XC5000_TUNER_RESET) {
1090336fea92SMauro Carvalho Chehab dev_dbg(dev->dev,
1091b7085c08SMauro Carvalho Chehab "Tuner CB: RESET: cmd %d : tuner type %d\n",
10920c0d06caSMauro Carvalho Chehab command, dev->tuner_type);
10930c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
10940c0d06caSMauro Carvalho Chehab 1);
10950c0d06caSMauro Carvalho Chehab msleep(10);
10960c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
10970c0d06caSMauro Carvalho Chehab 0);
10980c0d06caSMauro Carvalho Chehab msleep(330);
10990c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
11000c0d06caSMauro Carvalho Chehab 1);
11010c0d06caSMauro Carvalho Chehab msleep(10);
11020c0d06caSMauro Carvalho Chehab }
11030c0d06caSMauro Carvalho Chehab } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
11040c0d06caSMauro Carvalho Chehab switch (command) {
11050c0d06caSMauro Carvalho Chehab case TDA18271_CALLBACK_CMD_AGC_ENABLE:
11060c0d06caSMauro Carvalho Chehab if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
11070c0d06caSMauro Carvalho Chehab rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
11080c0d06caSMauro Carvalho Chehab break;
11090c0d06caSMauro Carvalho Chehab default:
11100c0d06caSMauro Carvalho Chehab rc = -EINVAL;
11110c0d06caSMauro Carvalho Chehab break;
11120c0d06caSMauro Carvalho Chehab }
11130c0d06caSMauro Carvalho Chehab }
11140c0d06caSMauro Carvalho Chehab return rc;
11150c0d06caSMauro Carvalho Chehab }
11160c0d06caSMauro Carvalho Chehab EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
11170c0d06caSMauro Carvalho Chehab
cx231xx_reset_out(struct cx231xx * dev)1118d4c06133SMauro Carvalho Chehab static void cx231xx_reset_out(struct cx231xx *dev)
11190c0d06caSMauro Carvalho Chehab {
11200c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
11210c0d06caSMauro Carvalho Chehab msleep(200);
11220c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, CX23417_RESET, 0);
11230c0d06caSMauro Carvalho Chehab msleep(200);
11240c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
11250c0d06caSMauro Carvalho Chehab }
1126d4c06133SMauro Carvalho Chehab
cx231xx_enable_OSC(struct cx231xx * dev)1127d4c06133SMauro Carvalho Chehab static void cx231xx_enable_OSC(struct cx231xx *dev)
11280c0d06caSMauro Carvalho Chehab {
11290c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1);
11300c0d06caSMauro Carvalho Chehab }
1131d4c06133SMauro Carvalho Chehab
cx231xx_sleep_s5h1432(struct cx231xx * dev)1132d4c06133SMauro Carvalho Chehab static void cx231xx_sleep_s5h1432(struct cx231xx *dev)
11330c0d06caSMauro Carvalho Chehab {
11340c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0);
11350c0d06caSMauro Carvalho Chehab }
11360c0d06caSMauro Carvalho Chehab
cx231xx_set_model(struct cx231xx * dev)11370c0d06caSMauro Carvalho Chehab static inline void cx231xx_set_model(struct cx231xx *dev)
11380c0d06caSMauro Carvalho Chehab {
11393724dde9SEzequiel Garcia dev->board = cx231xx_boards[dev->model];
11400c0d06caSMauro Carvalho Chehab }
11410c0d06caSMauro Carvalho Chehab
11420c0d06caSMauro Carvalho Chehab /* Since cx231xx_pre_card_setup() requires a proper dev->model,
11430c0d06caSMauro Carvalho Chehab * this won't work for boards with generic PCI IDs
11440c0d06caSMauro Carvalho Chehab */
cx231xx_pre_card_setup(struct cx231xx * dev)11450c0d06caSMauro Carvalho Chehab void cx231xx_pre_card_setup(struct cx231xx *dev)
11460c0d06caSMauro Carvalho Chehab {
1147336fea92SMauro Carvalho Chehab dev_info(dev->dev, "Identified as %s (card=%d)\n",
11480c0d06caSMauro Carvalho Chehab dev->board.name, dev->model);
11490c0d06caSMauro Carvalho Chehab
11500f42b331SOleh Kravchenko if (CX231XX_BOARD_ASTROMETA_T2HYBRID == dev->model) {
11510f42b331SOleh Kravchenko /* turn on demodulator chip */
11520f42b331SOleh Kravchenko cx231xx_set_gpio_value(dev, 0x03, 0x01);
11530f42b331SOleh Kravchenko }
11540f42b331SOleh Kravchenko
11550c0d06caSMauro Carvalho Chehab /* set the direction for GPIO pins */
11560c0d06caSMauro Carvalho Chehab if (dev->board.tuner_gpio) {
11570c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
11580c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
11590c0d06caSMauro Carvalho Chehab }
11600c0d06caSMauro Carvalho Chehab if (dev->board.tuner_sif_gpio >= 0)
11610c0d06caSMauro Carvalho Chehab cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
11620c0d06caSMauro Carvalho Chehab
11630c0d06caSMauro Carvalho Chehab /* request some modules if any required */
11640c0d06caSMauro Carvalho Chehab
11650c0d06caSMauro Carvalho Chehab /* set the mode to Analog mode initially */
11660c0d06caSMauro Carvalho Chehab cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
11670c0d06caSMauro Carvalho Chehab
11680c0d06caSMauro Carvalho Chehab /* Unlock device */
11690c0d06caSMauro Carvalho Chehab /* cx231xx_set_mode(dev, CX231XX_SUSPEND); */
11700c0d06caSMauro Carvalho Chehab
11710c0d06caSMauro Carvalho Chehab }
11720c0d06caSMauro Carvalho Chehab
cx231xx_config_tuner(struct cx231xx * dev)11730c0d06caSMauro Carvalho Chehab static void cx231xx_config_tuner(struct cx231xx *dev)
11740c0d06caSMauro Carvalho Chehab {
11750c0d06caSMauro Carvalho Chehab struct tuner_setup tun_setup;
11760c0d06caSMauro Carvalho Chehab struct v4l2_frequency f;
11770c0d06caSMauro Carvalho Chehab
11780c0d06caSMauro Carvalho Chehab if (dev->tuner_type == TUNER_ABSENT)
11790c0d06caSMauro Carvalho Chehab return;
11800c0d06caSMauro Carvalho Chehab
11810c0d06caSMauro Carvalho Chehab tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
11820c0d06caSMauro Carvalho Chehab tun_setup.type = dev->tuner_type;
11830c0d06caSMauro Carvalho Chehab tun_setup.addr = dev->tuner_addr;
11840c0d06caSMauro Carvalho Chehab tun_setup.tuner_callback = cx231xx_tuner_callback;
11850c0d06caSMauro Carvalho Chehab
11860c0d06caSMauro Carvalho Chehab tuner_call(dev, tuner, s_type_addr, &tun_setup);
11870c0d06caSMauro Carvalho Chehab
11880c0d06caSMauro Carvalho Chehab #if 0
11890c0d06caSMauro Carvalho Chehab if (tun_setup.type == TUNER_XC5000) {
11900c0d06caSMauro Carvalho Chehab static struct xc2028_ctrl ctrl = {
11910c0d06caSMauro Carvalho Chehab .fname = XC5000_DEFAULT_FIRMWARE,
11920c0d06caSMauro Carvalho Chehab .max_len = 64,
11930c0d06caSMauro Carvalho Chehab .demod = 0;
11940c0d06caSMauro Carvalho Chehab };
11950c0d06caSMauro Carvalho Chehab struct v4l2_priv_tun_config cfg = {
11960c0d06caSMauro Carvalho Chehab .tuner = dev->tuner_type,
11970c0d06caSMauro Carvalho Chehab .priv = &ctrl,
11980c0d06caSMauro Carvalho Chehab };
11990c0d06caSMauro Carvalho Chehab tuner_call(dev, tuner, s_config, &cfg);
12000c0d06caSMauro Carvalho Chehab }
12010c0d06caSMauro Carvalho Chehab #endif
12020c0d06caSMauro Carvalho Chehab /* configure tuner */
12030c0d06caSMauro Carvalho Chehab f.tuner = 0;
12040c0d06caSMauro Carvalho Chehab f.type = V4L2_TUNER_ANALOG_TV;
12050c0d06caSMauro Carvalho Chehab f.frequency = 9076; /* just a magic number */
12060c0d06caSMauro Carvalho Chehab dev->ctl_freq = f.frequency;
12070c0d06caSMauro Carvalho Chehab call_all(dev, tuner, s_frequency, &f);
12080c0d06caSMauro Carvalho Chehab
12090c0d06caSMauro Carvalho Chehab }
12100c0d06caSMauro Carvalho Chehab
read_eeprom(struct cx231xx * dev,struct i2c_client * client,u8 * eedata,int len)12119c672890SMatthias Schwarzott static int read_eeprom(struct cx231xx *dev, struct i2c_client *client,
12129c672890SMatthias Schwarzott u8 *eedata, int len)
1213dd2e7dd2SMatthias Schwarzott {
12149aa4d4eaSMarkus Elfring int ret;
1215dd2e7dd2SMatthias Schwarzott u8 start_offset = 0;
1216dd2e7dd2SMatthias Schwarzott int len_todo = len;
1217dd2e7dd2SMatthias Schwarzott u8 *eedata_cur = eedata;
1218dd2e7dd2SMatthias Schwarzott int i;
12199c672890SMatthias Schwarzott struct i2c_msg msg_write = { .addr = client->addr, .flags = 0,
1220dd2e7dd2SMatthias Schwarzott .buf = &start_offset, .len = 1 };
12219c672890SMatthias Schwarzott struct i2c_msg msg_read = { .addr = client->addr, .flags = I2C_M_RD };
1222dd2e7dd2SMatthias Schwarzott
1223dd2e7dd2SMatthias Schwarzott /* start reading at offset 0 */
12249c672890SMatthias Schwarzott ret = i2c_transfer(client->adapter, &msg_write, 1);
12251f97947cSMauro Carvalho Chehab if (ret < 0) {
1226336fea92SMauro Carvalho Chehab dev_err(dev->dev, "Can't read eeprom\n");
12271f97947cSMauro Carvalho Chehab return ret;
12281f97947cSMauro Carvalho Chehab }
1229dd2e7dd2SMatthias Schwarzott
1230dd2e7dd2SMatthias Schwarzott while (len_todo > 0) {
1231dd2e7dd2SMatthias Schwarzott msg_read.len = (len_todo > 64) ? 64 : len_todo;
1232dd2e7dd2SMatthias Schwarzott msg_read.buf = eedata_cur;
1233dd2e7dd2SMatthias Schwarzott
12349c672890SMatthias Schwarzott ret = i2c_transfer(client->adapter, &msg_read, 1);
12351f97947cSMauro Carvalho Chehab if (ret < 0) {
1236336fea92SMauro Carvalho Chehab dev_err(dev->dev, "Can't read eeprom\n");
12371f97947cSMauro Carvalho Chehab return ret;
12381f97947cSMauro Carvalho Chehab }
1239dd2e7dd2SMatthias Schwarzott eedata_cur += msg_read.len;
1240dd2e7dd2SMatthias Schwarzott len_todo -= msg_read.len;
1241dd2e7dd2SMatthias Schwarzott }
1242dd2e7dd2SMatthias Schwarzott
1243dd2e7dd2SMatthias Schwarzott for (i = 0; i + 15 < len; i += 16)
1244336fea92SMauro Carvalho Chehab dev_dbg(dev->dev, "i2c eeprom %02x: %*ph\n",
1245b7085c08SMauro Carvalho Chehab i, 16, &eedata[i]);
1246dd2e7dd2SMatthias Schwarzott
1247dd2e7dd2SMatthias Schwarzott return 0;
1248dd2e7dd2SMatthias Schwarzott }
1249dd2e7dd2SMatthias Schwarzott
cx231xx_card_setup(struct cx231xx * dev)12500c0d06caSMauro Carvalho Chehab void cx231xx_card_setup(struct cx231xx *dev)
12510c0d06caSMauro Carvalho Chehab {
12520c0d06caSMauro Carvalho Chehab
12530c0d06caSMauro Carvalho Chehab cx231xx_set_model(dev);
12540c0d06caSMauro Carvalho Chehab
12550c0d06caSMauro Carvalho Chehab dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
12560c0d06caSMauro Carvalho Chehab if (cx231xx_boards[dev->model].tuner_addr)
12570c0d06caSMauro Carvalho Chehab dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;
12580c0d06caSMauro Carvalho Chehab
12590c0d06caSMauro Carvalho Chehab /* request some modules */
12600c0d06caSMauro Carvalho Chehab if (dev->board.decoder == CX231XX_AVDECODER) {
12610c0d06caSMauro Carvalho Chehab dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1262c3c3f1aeSMatthias Schwarzott cx231xx_get_i2c_adap(dev, I2C_0),
12630c0d06caSMauro Carvalho Chehab "cx25840", 0x88 >> 1, NULL);
12640c0d06caSMauro Carvalho Chehab if (dev->sd_cx25840 == NULL)
1265336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1266b7085c08SMauro Carvalho Chehab "cx25840 subdev registration failure\n");
12670c0d06caSMauro Carvalho Chehab cx25840_call(dev, core, load_fw);
12680c0d06caSMauro Carvalho Chehab
12690c0d06caSMauro Carvalho Chehab }
12700c0d06caSMauro Carvalho Chehab
12710c0d06caSMauro Carvalho Chehab /* Initialize the tuner */
12720c0d06caSMauro Carvalho Chehab if (dev->board.tuner_type != TUNER_ABSENT) {
1273c3c3f1aeSMatthias Schwarzott struct i2c_adapter *tuner_i2c = cx231xx_get_i2c_adap(dev,
1274c3c3f1aeSMatthias Schwarzott dev->board.tuner_i2c_master);
12750c0d06caSMauro Carvalho Chehab dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1276c3c3f1aeSMatthias Schwarzott tuner_i2c,
12770c0d06caSMauro Carvalho Chehab "tuner",
12780c0d06caSMauro Carvalho Chehab dev->tuner_addr, NULL);
12790c0d06caSMauro Carvalho Chehab if (dev->sd_tuner == NULL)
1280336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1281b7085c08SMauro Carvalho Chehab "tuner subdev registration failure\n");
12820c0d06caSMauro Carvalho Chehab else
12830c0d06caSMauro Carvalho Chehab cx231xx_config_tuner(dev);
12840c0d06caSMauro Carvalho Chehab }
1285dd2e7dd2SMatthias Schwarzott
1286dd2e7dd2SMatthias Schwarzott switch (dev->model) {
1287dd2e7dd2SMatthias Schwarzott case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
12889e49f7c3SMatthias Schwarzott case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
1289809abdbfSOlli Salonen case CX231XX_BOARD_HAUPPAUGE_955Q:
1290c5bef50eSBrad Love case CX231XX_BOARD_HAUPPAUGE_935C:
129119fbf1baSBrad Love case CX231XX_BOARD_HAUPPAUGE_975:
1292dd2e7dd2SMatthias Schwarzott {
12937f3c2e1dSHans Verkuil struct eeprom {
1294dd2e7dd2SMatthias Schwarzott struct tveeprom tvee;
12957f3c2e1dSHans Verkuil u8 eeprom[256];
12969c672890SMatthias Schwarzott struct i2c_client client;
12977f3c2e1dSHans Verkuil };
12987f3c2e1dSHans Verkuil struct eeprom *e = kzalloc(sizeof(*e), GFP_KERNEL);
1299dd2e7dd2SMatthias Schwarzott
13007f3c2e1dSHans Verkuil if (e == NULL) {
13017f3c2e1dSHans Verkuil dev_err(dev->dev,
13027f3c2e1dSHans Verkuil "failed to allocate memory to read eeprom\n");
13037f3c2e1dSHans Verkuil break;
13047f3c2e1dSHans Verkuil }
13057f3c2e1dSHans Verkuil e->client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1);
13067f3c2e1dSHans Verkuil e->client.addr = 0xa0 >> 1;
13079c672890SMatthias Schwarzott
13087f3c2e1dSHans Verkuil read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom));
1309446aba66SMauro Carvalho Chehab tveeprom_hauppauge_analog(&e->tvee, e->eeprom + 0xc0);
13107f3c2e1dSHans Verkuil kfree(e);
1311dd2e7dd2SMatthias Schwarzott break;
1312dd2e7dd2SMatthias Schwarzott }
1313dd2e7dd2SMatthias Schwarzott }
1314dd2e7dd2SMatthias Schwarzott
13150c0d06caSMauro Carvalho Chehab }
13160c0d06caSMauro Carvalho Chehab
13170c0d06caSMauro Carvalho Chehab /*
13180c0d06caSMauro Carvalho Chehab * cx231xx_config()
13190c0d06caSMauro Carvalho Chehab * inits registers with sane defaults
13200c0d06caSMauro Carvalho Chehab */
cx231xx_config(struct cx231xx * dev)13210c0d06caSMauro Carvalho Chehab int cx231xx_config(struct cx231xx *dev)
13220c0d06caSMauro Carvalho Chehab {
13230c0d06caSMauro Carvalho Chehab /* TBD need to add cx231xx specific code */
13240c0d06caSMauro Carvalho Chehab
13250c0d06caSMauro Carvalho Chehab return 0;
13260c0d06caSMauro Carvalho Chehab }
13270c0d06caSMauro Carvalho Chehab
13280c0d06caSMauro Carvalho Chehab /*
13290c0d06caSMauro Carvalho Chehab * cx231xx_config_i2c()
13300c0d06caSMauro Carvalho Chehab * configure i2c attached devices
13310c0d06caSMauro Carvalho Chehab */
cx231xx_config_i2c(struct cx231xx * dev)13320c0d06caSMauro Carvalho Chehab void cx231xx_config_i2c(struct cx231xx *dev)
13330c0d06caSMauro Carvalho Chehab {
13340c0d06caSMauro Carvalho Chehab /* u32 input = INPUT(dev->video_input)->vmux; */
13350c0d06caSMauro Carvalho Chehab
13360c0d06caSMauro Carvalho Chehab call_all(dev, video, s_stream, 1);
13370c0d06caSMauro Carvalho Chehab }
13380c0d06caSMauro Carvalho Chehab
cx231xx_unregister_media_device(struct cx231xx * dev)13391d058bdcSMauro Carvalho Chehab static void cx231xx_unregister_media_device(struct cx231xx *dev)
13401d058bdcSMauro Carvalho Chehab {
13411d058bdcSMauro Carvalho Chehab #ifdef CONFIG_MEDIA_CONTROLLER
13421d058bdcSMauro Carvalho Chehab if (dev->media_dev) {
13431d058bdcSMauro Carvalho Chehab media_device_unregister(dev->media_dev);
13449832e155SJavier Martinez Canillas media_device_cleanup(dev->media_dev);
13451d058bdcSMauro Carvalho Chehab kfree(dev->media_dev);
13461d058bdcSMauro Carvalho Chehab dev->media_dev = NULL;
13471d058bdcSMauro Carvalho Chehab }
13481d058bdcSMauro Carvalho Chehab #endif
13491d058bdcSMauro Carvalho Chehab }
13501d058bdcSMauro Carvalho Chehab
13510c0d06caSMauro Carvalho Chehab /*
13520c0d06caSMauro Carvalho Chehab * cx231xx_realease_resources()
13530c0d06caSMauro Carvalho Chehab * unregisters the v4l2,i2c and usb devices
13546b338c72SGeert Uytterhoeven * called when the device gets disconnected or at module unload
13550c0d06caSMauro Carvalho Chehab */
cx231xx_release_resources(struct cx231xx * dev)13560c0d06caSMauro Carvalho Chehab void cx231xx_release_resources(struct cx231xx *dev)
13570c0d06caSMauro Carvalho Chehab {
13583c59bb47SMauro Carvalho Chehab cx231xx_ir_exit(dev);
13593c59bb47SMauro Carvalho Chehab
13600c0d06caSMauro Carvalho Chehab cx231xx_release_analog_resources(dev);
13610c0d06caSMauro Carvalho Chehab
13620c0d06caSMauro Carvalho Chehab cx231xx_remove_from_devlist(dev);
13630c0d06caSMauro Carvalho Chehab
13640c0d06caSMauro Carvalho Chehab /* Release I2C buses */
13650c0d06caSMauro Carvalho Chehab cx231xx_dev_uninit(dev);
13660c0d06caSMauro Carvalho Chehab
13670c0d06caSMauro Carvalho Chehab /* delete v4l2 device */
13680c0d06caSMauro Carvalho Chehab v4l2_device_unregister(&dev->v4l2_dev);
13690c0d06caSMauro Carvalho Chehab
1370ab232e46SMauro Carvalho Chehab cx231xx_unregister_media_device(dev);
1371ab232e46SMauro Carvalho Chehab
13720c0d06caSMauro Carvalho Chehab usb_put_dev(dev->udev);
13730c0d06caSMauro Carvalho Chehab
13740c0d06caSMauro Carvalho Chehab /* Mark device as unused */
13750c0d06caSMauro Carvalho Chehab clear_bit(dev->devno, &cx231xx_devused);
13760c0d06caSMauro Carvalho Chehab }
13770c0d06caSMauro Carvalho Chehab
cx231xx_media_device_init(struct cx231xx * dev,struct usb_device * udev)13789f806795SMauro Carvalho Chehab static int cx231xx_media_device_init(struct cx231xx *dev,
13791d058bdcSMauro Carvalho Chehab struct usb_device *udev)
13801d058bdcSMauro Carvalho Chehab {
13811d058bdcSMauro Carvalho Chehab #ifdef CONFIG_MEDIA_CONTROLLER
13821d058bdcSMauro Carvalho Chehab struct media_device *mdev;
13831d058bdcSMauro Carvalho Chehab
13846cf5dad1SMauro Carvalho Chehab mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
13851d058bdcSMauro Carvalho Chehab if (!mdev)
13869f806795SMauro Carvalho Chehab return -ENOMEM;
13871d058bdcSMauro Carvalho Chehab
13886cf5dad1SMauro Carvalho Chehab media_device_usb_init(mdev, udev, dev->board.name);
13896cf5dad1SMauro Carvalho Chehab
13901d058bdcSMauro Carvalho Chehab dev->media_dev = mdev;
13911d058bdcSMauro Carvalho Chehab #endif
13929f806795SMauro Carvalho Chehab return 0;
13931d058bdcSMauro Carvalho Chehab }
13941d058bdcSMauro Carvalho Chehab
13950c0d06caSMauro Carvalho Chehab /*
13960c0d06caSMauro Carvalho Chehab * cx231xx_init_dev()
13970c0d06caSMauro Carvalho Chehab * allocates and inits the device structs, registers i2c bus and v4l device
13980c0d06caSMauro Carvalho Chehab */
cx231xx_init_dev(struct cx231xx * dev,struct usb_device * udev,int minor)13990c0d06caSMauro Carvalho Chehab static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
14000c0d06caSMauro Carvalho Chehab int minor)
14010c0d06caSMauro Carvalho Chehab {
14020c0d06caSMauro Carvalho Chehab int retval = -ENOMEM;
14030c0d06caSMauro Carvalho Chehab unsigned int maxh, maxw;
14040c0d06caSMauro Carvalho Chehab
14050c0d06caSMauro Carvalho Chehab dev->udev = udev;
14060c0d06caSMauro Carvalho Chehab mutex_init(&dev->lock);
14070c0d06caSMauro Carvalho Chehab mutex_init(&dev->ctrl_urb_lock);
14080c0d06caSMauro Carvalho Chehab mutex_init(&dev->gpio_i2c_lock);
14090c0d06caSMauro Carvalho Chehab mutex_init(&dev->i2c_lock);
14100c0d06caSMauro Carvalho Chehab
14110c0d06caSMauro Carvalho Chehab spin_lock_init(&dev->video_mode.slock);
14120c0d06caSMauro Carvalho Chehab spin_lock_init(&dev->vbi_mode.slock);
14130c0d06caSMauro Carvalho Chehab spin_lock_init(&dev->sliced_cc_mode.slock);
14140c0d06caSMauro Carvalho Chehab
14150c0d06caSMauro Carvalho Chehab init_waitqueue_head(&dev->open);
14160c0d06caSMauro Carvalho Chehab init_waitqueue_head(&dev->wait_frame);
14170c0d06caSMauro Carvalho Chehab init_waitqueue_head(&dev->wait_stream);
14180c0d06caSMauro Carvalho Chehab
14190c0d06caSMauro Carvalho Chehab dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg;
14200c0d06caSMauro Carvalho Chehab dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg;
14210c0d06caSMauro Carvalho Chehab dev->cx231xx_send_usb_command = cx231xx_send_usb_command;
14220c0d06caSMauro Carvalho Chehab dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read;
14230c0d06caSMauro Carvalho Chehab dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
14240c0d06caSMauro Carvalho Chehab
14250c0d06caSMauro Carvalho Chehab /* Query cx231xx to find what pcb config it is related to */
142652841e5eSMauro Carvalho Chehab retval = initialize_cx231xx(dev);
142752841e5eSMauro Carvalho Chehab if (retval < 0) {
1428336fea92SMauro Carvalho Chehab dev_err(dev->dev, "Failed to read PCB config\n");
142952841e5eSMauro Carvalho Chehab return retval;
143052841e5eSMauro Carvalho Chehab }
14310c0d06caSMauro Carvalho Chehab
14320c0d06caSMauro Carvalho Chehab /*To workaround error number=-71 on EP0 for VideoGrabber,
14330c0d06caSMauro Carvalho Chehab need set alt here.*/
14340c0d06caSMauro Carvalho Chehab if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER ||
14350c0d06caSMauro Carvalho Chehab dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) {
14360c0d06caSMauro Carvalho Chehab cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
14370c0d06caSMauro Carvalho Chehab cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
14380c0d06caSMauro Carvalho Chehab }
14390c0d06caSMauro Carvalho Chehab /* Cx231xx pre card setup */
14400c0d06caSMauro Carvalho Chehab cx231xx_pre_card_setup(dev);
14410c0d06caSMauro Carvalho Chehab
1442256d013aSAlexey Khoroshilov retval = cx231xx_config(dev);
1443256d013aSAlexey Khoroshilov if (retval) {
1444336fea92SMauro Carvalho Chehab dev_err(dev->dev, "error configuring device\n");
14450c0d06caSMauro Carvalho Chehab return -ENOMEM;
14460c0d06caSMauro Carvalho Chehab }
14470c0d06caSMauro Carvalho Chehab
14480c0d06caSMauro Carvalho Chehab /* set default norm */
14490c0d06caSMauro Carvalho Chehab dev->norm = dev->board.norm;
14500c0d06caSMauro Carvalho Chehab
14510c0d06caSMauro Carvalho Chehab /* register i2c bus */
1452256d013aSAlexey Khoroshilov retval = cx231xx_dev_init(dev);
1453256d013aSAlexey Khoroshilov if (retval) {
1454336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1455b7085c08SMauro Carvalho Chehab "%s: cx231xx_i2c_register - errCode [%d]!\n",
1456256d013aSAlexey Khoroshilov __func__, retval);
1457256d013aSAlexey Khoroshilov goto err_dev_init;
14580c0d06caSMauro Carvalho Chehab }
14590c0d06caSMauro Carvalho Chehab
14600c0d06caSMauro Carvalho Chehab /* Do board specific init */
14610c0d06caSMauro Carvalho Chehab cx231xx_card_setup(dev);
14620c0d06caSMauro Carvalho Chehab
14630c0d06caSMauro Carvalho Chehab /* configure the device */
14640c0d06caSMauro Carvalho Chehab cx231xx_config_i2c(dev);
14650c0d06caSMauro Carvalho Chehab
14660c0d06caSMauro Carvalho Chehab maxw = norm_maxw(dev);
14670c0d06caSMauro Carvalho Chehab maxh = norm_maxh(dev);
14680c0d06caSMauro Carvalho Chehab
14690c0d06caSMauro Carvalho Chehab /* set default image size */
14700c0d06caSMauro Carvalho Chehab dev->width = maxw;
14710c0d06caSMauro Carvalho Chehab dev->height = maxh;
14720c0d06caSMauro Carvalho Chehab dev->interlaced = 0;
14730c0d06caSMauro Carvalho Chehab dev->video_input = 0;
14740c0d06caSMauro Carvalho Chehab
1475256d013aSAlexey Khoroshilov retval = cx231xx_config(dev);
1476256d013aSAlexey Khoroshilov if (retval) {
1477336fea92SMauro Carvalho Chehab dev_err(dev->dev, "%s: cx231xx_config - errCode [%d]!\n",
1478256d013aSAlexey Khoroshilov __func__, retval);
1479256d013aSAlexey Khoroshilov goto err_dev_init;
14800c0d06caSMauro Carvalho Chehab }
14810c0d06caSMauro Carvalho Chehab
14827c617138SHans Verkuil /* init video dma queue */
14830c0d06caSMauro Carvalho Chehab INIT_LIST_HEAD(&dev->video_mode.vidq.active);
14840c0d06caSMauro Carvalho Chehab
14857c617138SHans Verkuil /* init vbi dma queue */
14860c0d06caSMauro Carvalho Chehab INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
14870c0d06caSMauro Carvalho Chehab
14880c0d06caSMauro Carvalho Chehab /* Reset other chips required if they are tied up with GPIO pins */
14890c0d06caSMauro Carvalho Chehab cx231xx_add_into_devlist(dev);
14900c0d06caSMauro Carvalho Chehab
14910c0d06caSMauro Carvalho Chehab if (dev->board.has_417) {
1492336fea92SMauro Carvalho Chehab dev_info(dev->dev, "attach 417 %d\n", dev->model);
14930c0d06caSMauro Carvalho Chehab if (cx231xx_417_register(dev) < 0) {
1494336fea92SMauro Carvalho Chehab dev_err(dev->dev,
14950c0d06caSMauro Carvalho Chehab "%s() Failed to register 417 on VID_B\n",
14960c0d06caSMauro Carvalho Chehab __func__);
14970c0d06caSMauro Carvalho Chehab }
14980c0d06caSMauro Carvalho Chehab }
14990c0d06caSMauro Carvalho Chehab
15000c0d06caSMauro Carvalho Chehab retval = cx231xx_register_analog_devices(dev);
15011d058bdcSMauro Carvalho Chehab if (retval)
1502256d013aSAlexey Khoroshilov goto err_analog;
15030c0d06caSMauro Carvalho Chehab
15040c0d06caSMauro Carvalho Chehab cx231xx_ir_init(dev);
15050c0d06caSMauro Carvalho Chehab
15060c0d06caSMauro Carvalho Chehab cx231xx_init_extension(dev);
15070c0d06caSMauro Carvalho Chehab
15080c0d06caSMauro Carvalho Chehab return 0;
1509256d013aSAlexey Khoroshilov err_analog:
15101d058bdcSMauro Carvalho Chehab cx231xx_unregister_media_device(dev);
15111d058bdcSMauro Carvalho Chehab cx231xx_release_analog_resources(dev);
1512256d013aSAlexey Khoroshilov cx231xx_remove_from_devlist(dev);
1513256d013aSAlexey Khoroshilov err_dev_init:
1514256d013aSAlexey Khoroshilov cx231xx_dev_uninit(dev);
1515256d013aSAlexey Khoroshilov return retval;
15160c0d06caSMauro Carvalho Chehab }
15170c0d06caSMauro Carvalho Chehab
15180c0d06caSMauro Carvalho Chehab #if defined(CONFIG_MODULES) && defined(MODULE)
request_module_async(struct work_struct * work)15190c0d06caSMauro Carvalho Chehab static void request_module_async(struct work_struct *work)
15200c0d06caSMauro Carvalho Chehab {
15210c0d06caSMauro Carvalho Chehab struct cx231xx *dev = container_of(work,
15220c0d06caSMauro Carvalho Chehab struct cx231xx, request_module_wk);
15230c0d06caSMauro Carvalho Chehab
15240c0d06caSMauro Carvalho Chehab if (dev->has_alsa_audio)
15250c0d06caSMauro Carvalho Chehab request_module("cx231xx-alsa");
15260c0d06caSMauro Carvalho Chehab
15270c0d06caSMauro Carvalho Chehab if (dev->board.has_dvb)
15280c0d06caSMauro Carvalho Chehab request_module("cx231xx-dvb");
15290c0d06caSMauro Carvalho Chehab
15300c0d06caSMauro Carvalho Chehab }
15310c0d06caSMauro Carvalho Chehab
request_modules(struct cx231xx * dev)15320c0d06caSMauro Carvalho Chehab static void request_modules(struct cx231xx *dev)
15330c0d06caSMauro Carvalho Chehab {
15340c0d06caSMauro Carvalho Chehab INIT_WORK(&dev->request_module_wk, request_module_async);
15350c0d06caSMauro Carvalho Chehab schedule_work(&dev->request_module_wk);
15360c0d06caSMauro Carvalho Chehab }
15370c0d06caSMauro Carvalho Chehab
flush_request_modules(struct cx231xx * dev)15380c0d06caSMauro Carvalho Chehab static void flush_request_modules(struct cx231xx *dev)
15390c0d06caSMauro Carvalho Chehab {
15400b8e74c6SLinus Torvalds flush_work(&dev->request_module_wk);
15410c0d06caSMauro Carvalho Chehab }
15420c0d06caSMauro Carvalho Chehab #else
15430c0d06caSMauro Carvalho Chehab #define request_modules(dev)
15440c0d06caSMauro Carvalho Chehab #define flush_request_modules(dev)
15450c0d06caSMauro Carvalho Chehab #endif /* CONFIG_MODULES */
15460c0d06caSMauro Carvalho Chehab
cx231xx_init_v4l2(struct cx231xx * dev,struct usb_device * udev,struct usb_interface * interface,int isoc_pipe)15474d2a7d35SMauro Carvalho Chehab static int cx231xx_init_v4l2(struct cx231xx *dev,
15484d2a7d35SMauro Carvalho Chehab struct usb_device *udev,
15494d2a7d35SMauro Carvalho Chehab struct usb_interface *interface,
15504d2a7d35SMauro Carvalho Chehab int isoc_pipe)
15514d2a7d35SMauro Carvalho Chehab {
15524d2a7d35SMauro Carvalho Chehab struct usb_interface *uif;
15534d2a7d35SMauro Carvalho Chehab int i, idx;
15544d2a7d35SMauro Carvalho Chehab
15554d2a7d35SMauro Carvalho Chehab /* Video Init */
15564d2a7d35SMauro Carvalho Chehab
15574d2a7d35SMauro Carvalho Chehab /* compute alternate max packet sizes for video */
15584d2a7d35SMauro Carvalho Chehab idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1;
15594d2a7d35SMauro Carvalho Chehab if (idx >= dev->max_iad_interface_count) {
1560336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1561b7085c08SMauro Carvalho Chehab "Video PCB interface #%d doesn't exist\n", idx);
15624d2a7d35SMauro Carvalho Chehab return -ENODEV;
15634d2a7d35SMauro Carvalho Chehab }
15644d2a7d35SMauro Carvalho Chehab
15654d2a7d35SMauro Carvalho Chehab uif = udev->actconfig->interface[idx];
15664d2a7d35SMauro Carvalho Chehab
15670cd273bbSJohan Hovold if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
15680cd273bbSJohan Hovold return -ENODEV;
15690cd273bbSJohan Hovold
15704d2a7d35SMauro Carvalho Chehab dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress;
15714d2a7d35SMauro Carvalho Chehab dev->video_mode.num_alt = uif->num_altsetting;
15724d2a7d35SMauro Carvalho Chehab
1573336fea92SMauro Carvalho Chehab dev_info(dev->dev,
1574b7085c08SMauro Carvalho Chehab "video EndPoint Addr 0x%x, Alternate settings: %i\n",
15754d2a7d35SMauro Carvalho Chehab dev->video_mode.end_point_addr,
15764d2a7d35SMauro Carvalho Chehab dev->video_mode.num_alt);
15774d2a7d35SMauro Carvalho Chehab
15784d2a7d35SMauro Carvalho Chehab dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL);
1579ed0e3729SMauro Carvalho Chehab if (dev->video_mode.alt_max_pkt_size == NULL)
15804d2a7d35SMauro Carvalho Chehab return -ENOMEM;
15814d2a7d35SMauro Carvalho Chehab
15824d2a7d35SMauro Carvalho Chehab for (i = 0; i < dev->video_mode.num_alt; i++) {
15830cd273bbSJohan Hovold u16 tmp;
15840cd273bbSJohan Hovold
15850cd273bbSJohan Hovold if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
15860cd273bbSJohan Hovold return -ENODEV;
15870cd273bbSJohan Hovold
15880cd273bbSJohan Hovold tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
15894d2a7d35SMauro Carvalho Chehab dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1590336fea92SMauro Carvalho Chehab dev_dbg(dev->dev,
1591b7085c08SMauro Carvalho Chehab "Alternate setting %i, max size= %i\n", i,
15924d2a7d35SMauro Carvalho Chehab dev->video_mode.alt_max_pkt_size[i]);
15934d2a7d35SMauro Carvalho Chehab }
15944d2a7d35SMauro Carvalho Chehab
15954d2a7d35SMauro Carvalho Chehab /* VBI Init */
15964d2a7d35SMauro Carvalho Chehab
15974d2a7d35SMauro Carvalho Chehab idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1;
15984d2a7d35SMauro Carvalho Chehab if (idx >= dev->max_iad_interface_count) {
1599336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1600b7085c08SMauro Carvalho Chehab "VBI PCB interface #%d doesn't exist\n", idx);
16014d2a7d35SMauro Carvalho Chehab return -ENODEV;
16024d2a7d35SMauro Carvalho Chehab }
16034d2a7d35SMauro Carvalho Chehab uif = udev->actconfig->interface[idx];
16044d2a7d35SMauro Carvalho Chehab
16050cd273bbSJohan Hovold if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
16060cd273bbSJohan Hovold return -ENODEV;
16070cd273bbSJohan Hovold
16084d2a7d35SMauro Carvalho Chehab dev->vbi_mode.end_point_addr =
16094d2a7d35SMauro Carvalho Chehab uif->altsetting[0].endpoint[isoc_pipe].desc.
16104d2a7d35SMauro Carvalho Chehab bEndpointAddress;
16114d2a7d35SMauro Carvalho Chehab
16124d2a7d35SMauro Carvalho Chehab dev->vbi_mode.num_alt = uif->num_altsetting;
1613336fea92SMauro Carvalho Chehab dev_info(dev->dev,
1614b7085c08SMauro Carvalho Chehab "VBI EndPoint Addr 0x%x, Alternate settings: %i\n",
16154d2a7d35SMauro Carvalho Chehab dev->vbi_mode.end_point_addr,
16164d2a7d35SMauro Carvalho Chehab dev->vbi_mode.num_alt);
16174d2a7d35SMauro Carvalho Chehab
16184d2a7d35SMauro Carvalho Chehab /* compute alternate max packet sizes for vbi */
16194d2a7d35SMauro Carvalho Chehab dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL);
1620ed0e3729SMauro Carvalho Chehab if (dev->vbi_mode.alt_max_pkt_size == NULL)
16214d2a7d35SMauro Carvalho Chehab return -ENOMEM;
16224d2a7d35SMauro Carvalho Chehab
16234d2a7d35SMauro Carvalho Chehab for (i = 0; i < dev->vbi_mode.num_alt; i++) {
16240cd273bbSJohan Hovold u16 tmp;
16250cd273bbSJohan Hovold
16260cd273bbSJohan Hovold if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
16270cd273bbSJohan Hovold return -ENODEV;
16280cd273bbSJohan Hovold
16290cd273bbSJohan Hovold tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
16304d2a7d35SMauro Carvalho Chehab desc.wMaxPacketSize);
16314d2a7d35SMauro Carvalho Chehab dev->vbi_mode.alt_max_pkt_size[i] =
16324d2a7d35SMauro Carvalho Chehab (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1633336fea92SMauro Carvalho Chehab dev_dbg(dev->dev,
1634b7085c08SMauro Carvalho Chehab "Alternate setting %i, max size= %i\n", i,
16354d2a7d35SMauro Carvalho Chehab dev->vbi_mode.alt_max_pkt_size[i]);
16364d2a7d35SMauro Carvalho Chehab }
16374d2a7d35SMauro Carvalho Chehab
16384d2a7d35SMauro Carvalho Chehab /* Sliced CC VBI init */
16394d2a7d35SMauro Carvalho Chehab
16404d2a7d35SMauro Carvalho Chehab /* compute alternate max packet sizes for sliced CC */
16414d2a7d35SMauro Carvalho Chehab idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1;
16424d2a7d35SMauro Carvalho Chehab if (idx >= dev->max_iad_interface_count) {
1643336fea92SMauro Carvalho Chehab dev_err(dev->dev,
1644b7085c08SMauro Carvalho Chehab "Sliced CC PCB interface #%d doesn't exist\n", idx);
16454d2a7d35SMauro Carvalho Chehab return -ENODEV;
16464d2a7d35SMauro Carvalho Chehab }
16474d2a7d35SMauro Carvalho Chehab uif = udev->actconfig->interface[idx];
16484d2a7d35SMauro Carvalho Chehab
16490cd273bbSJohan Hovold if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
16500cd273bbSJohan Hovold return -ENODEV;
16510cd273bbSJohan Hovold
16524d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.end_point_addr =
16534d2a7d35SMauro Carvalho Chehab uif->altsetting[0].endpoint[isoc_pipe].desc.
16544d2a7d35SMauro Carvalho Chehab bEndpointAddress;
16554d2a7d35SMauro Carvalho Chehab
16564d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.num_alt = uif->num_altsetting;
1657336fea92SMauro Carvalho Chehab dev_info(dev->dev,
1658b7085c08SMauro Carvalho Chehab "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n",
16594d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.end_point_addr,
16604d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.num_alt);
16614d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL);
1662ed0e3729SMauro Carvalho Chehab if (dev->sliced_cc_mode.alt_max_pkt_size == NULL)
16634d2a7d35SMauro Carvalho Chehab return -ENOMEM;
16644d2a7d35SMauro Carvalho Chehab
16654d2a7d35SMauro Carvalho Chehab for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
16660cd273bbSJohan Hovold u16 tmp;
16670cd273bbSJohan Hovold
16680cd273bbSJohan Hovold if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
16690cd273bbSJohan Hovold return -ENODEV;
16700cd273bbSJohan Hovold
16710cd273bbSJohan Hovold tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
16724d2a7d35SMauro Carvalho Chehab desc.wMaxPacketSize);
16734d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.alt_max_pkt_size[i] =
16744d2a7d35SMauro Carvalho Chehab (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1675336fea92SMauro Carvalho Chehab dev_dbg(dev->dev,
1676b7085c08SMauro Carvalho Chehab "Alternate setting %i, max size= %i\n", i,
16774d2a7d35SMauro Carvalho Chehab dev->sliced_cc_mode.alt_max_pkt_size[i]);
16784d2a7d35SMauro Carvalho Chehab }
16794d2a7d35SMauro Carvalho Chehab
16804d2a7d35SMauro Carvalho Chehab return 0;
16814d2a7d35SMauro Carvalho Chehab }
16824d2a7d35SMauro Carvalho Chehab
16830c0d06caSMauro Carvalho Chehab /*
16840c0d06caSMauro Carvalho Chehab * cx231xx_usb_probe()
16850c0d06caSMauro Carvalho Chehab * checks for supported devices
16860c0d06caSMauro Carvalho Chehab */
cx231xx_usb_probe(struct usb_interface * interface,const struct usb_device_id * id)16870c0d06caSMauro Carvalho Chehab static int cx231xx_usb_probe(struct usb_interface *interface,
16880c0d06caSMauro Carvalho Chehab const struct usb_device_id *id)
16890c0d06caSMauro Carvalho Chehab {
16900c0d06caSMauro Carvalho Chehab struct usb_device *udev;
1691336fea92SMauro Carvalho Chehab struct device *d = &interface->dev;
16920c0d06caSMauro Carvalho Chehab struct usb_interface *uif;
16930c0d06caSMauro Carvalho Chehab struct cx231xx *dev = NULL;
16940c0d06caSMauro Carvalho Chehab int retval = -ENODEV;
16950c0d06caSMauro Carvalho Chehab int nr = 0, ifnum;
16960c0d06caSMauro Carvalho Chehab int i, isoc_pipe = 0;
16970c0d06caSMauro Carvalho Chehab char *speed;
1698dcb78ac7SMauro Carvalho Chehab u8 idx;
16990c0d06caSMauro Carvalho Chehab struct usb_interface_assoc_descriptor *assoc_desc;
17000c0d06caSMauro Carvalho Chehab
17010c0d06caSMauro Carvalho Chehab ifnum = interface->altsetting[0].desc.bInterfaceNumber;
17020c0d06caSMauro Carvalho Chehab
17030c0d06caSMauro Carvalho Chehab /*
17040c0d06caSMauro Carvalho Chehab * Interface number 0 - IR interface (handled by mceusb driver)
17050c0d06caSMauro Carvalho Chehab * Interface number 1 - AV interface (handled by this driver)
17060c0d06caSMauro Carvalho Chehab */
17070c0d06caSMauro Carvalho Chehab if (ifnum != 1)
17080c0d06caSMauro Carvalho Chehab return -ENODEV;
17090c0d06caSMauro Carvalho Chehab
17100c0d06caSMauro Carvalho Chehab /* Check to see next free device and mark as used */
17110c0d06caSMauro Carvalho Chehab do {
17120c0d06caSMauro Carvalho Chehab nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
17130c0d06caSMauro Carvalho Chehab if (nr >= CX231XX_MAXBOARDS) {
17140c0d06caSMauro Carvalho Chehab /* No free device slots */
1715336fea92SMauro Carvalho Chehab dev_err(d,
1716b7085c08SMauro Carvalho Chehab "Supports only %i devices.\n",
1717b7085c08SMauro Carvalho Chehab CX231XX_MAXBOARDS);
17180c0d06caSMauro Carvalho Chehab return -ENOMEM;
17190c0d06caSMauro Carvalho Chehab }
17200c0d06caSMauro Carvalho Chehab } while (test_and_set_bit(nr, &cx231xx_devused));
17210c0d06caSMauro Carvalho Chehab
17225eeb3014SAlexey Khoroshilov udev = usb_get_dev(interface_to_usbdev(interface));
17235eeb3014SAlexey Khoroshilov
17240c0d06caSMauro Carvalho Chehab /* allocate memory for our device state and initialize it */
1725184a8278SMauro Carvalho Chehab dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL);
17260c0d06caSMauro Carvalho Chehab if (dev == NULL) {
17275eeb3014SAlexey Khoroshilov retval = -ENOMEM;
17285eeb3014SAlexey Khoroshilov goto err_if;
17290c0d06caSMauro Carvalho Chehab }
17300c0d06caSMauro Carvalho Chehab
17310c0d06caSMauro Carvalho Chehab snprintf(dev->name, 29, "cx231xx #%d", nr);
17320c0d06caSMauro Carvalho Chehab dev->devno = nr;
17330c0d06caSMauro Carvalho Chehab dev->model = id->driver_info;
17340c0d06caSMauro Carvalho Chehab dev->video_mode.alt = -1;
1735336fea92SMauro Carvalho Chehab dev->dev = d;
17360c0d06caSMauro Carvalho Chehab
17371d058bdcSMauro Carvalho Chehab cx231xx_set_model(dev);
17381d058bdcSMauro Carvalho Chehab
17390c0d06caSMauro Carvalho Chehab dev->interface_count++;
17400c0d06caSMauro Carvalho Chehab /* reset gpio dir and value */
17410c0d06caSMauro Carvalho Chehab dev->gpio_dir = 0;
17420c0d06caSMauro Carvalho Chehab dev->gpio_val = 0;
17430c0d06caSMauro Carvalho Chehab dev->xc_fw_load_done = 0;
17440c0d06caSMauro Carvalho Chehab dev->has_alsa_audio = 1;
17450c0d06caSMauro Carvalho Chehab dev->power_mode = -1;
17460c0d06caSMauro Carvalho Chehab atomic_set(&dev->devlist_count, 0);
17470c0d06caSMauro Carvalho Chehab
17480c0d06caSMauro Carvalho Chehab /* 0 - vbi ; 1 -sliced cc mode */
17490c0d06caSMauro Carvalho Chehab dev->vbi_or_sliced_cc_mode = 0;
17500c0d06caSMauro Carvalho Chehab
17510c0d06caSMauro Carvalho Chehab /* get maximum no.of IAD interfaces */
1752139d2882SMauro Carvalho Chehab dev->max_iad_interface_count = udev->config->desc.bNumInterfaces;
17530c0d06caSMauro Carvalho Chehab
17540c0d06caSMauro Carvalho Chehab /* init CIR module TBD */
17550c0d06caSMauro Carvalho Chehab
17560c0d06caSMauro Carvalho Chehab /*mode_tv: digital=1 or analog=0*/
17570c0d06caSMauro Carvalho Chehab dev->mode_tv = 0;
17580c0d06caSMauro Carvalho Chehab
17590c0d06caSMauro Carvalho Chehab dev->USE_ISO = transfer_mode;
17600c0d06caSMauro Carvalho Chehab
17610c0d06caSMauro Carvalho Chehab switch (udev->speed) {
17620c0d06caSMauro Carvalho Chehab case USB_SPEED_LOW:
17630c0d06caSMauro Carvalho Chehab speed = "1.5";
17640c0d06caSMauro Carvalho Chehab break;
17650c0d06caSMauro Carvalho Chehab case USB_SPEED_UNKNOWN:
17660c0d06caSMauro Carvalho Chehab case USB_SPEED_FULL:
17670c0d06caSMauro Carvalho Chehab speed = "12";
17680c0d06caSMauro Carvalho Chehab break;
17690c0d06caSMauro Carvalho Chehab case USB_SPEED_HIGH:
17700c0d06caSMauro Carvalho Chehab speed = "480";
17710c0d06caSMauro Carvalho Chehab break;
17720c0d06caSMauro Carvalho Chehab default:
17730c0d06caSMauro Carvalho Chehab speed = "unknown";
17740c0d06caSMauro Carvalho Chehab }
17750c0d06caSMauro Carvalho Chehab
1776336fea92SMauro Carvalho Chehab dev_info(d,
1777b7085c08SMauro Carvalho Chehab "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n",
17780c0d06caSMauro Carvalho Chehab udev->manufacturer ? udev->manufacturer : "",
17790c0d06caSMauro Carvalho Chehab udev->product ? udev->product : "",
17800c0d06caSMauro Carvalho Chehab speed,
17810c0d06caSMauro Carvalho Chehab le16_to_cpu(udev->descriptor.idVendor),
17820c0d06caSMauro Carvalho Chehab le16_to_cpu(udev->descriptor.idProduct),
17830c0d06caSMauro Carvalho Chehab dev->max_iad_interface_count);
17840c0d06caSMauro Carvalho Chehab
17850c0d06caSMauro Carvalho Chehab /* increment interface count */
17860c0d06caSMauro Carvalho Chehab dev->interface_count++;
17870c0d06caSMauro Carvalho Chehab
17880c0d06caSMauro Carvalho Chehab /* get device number */
17890c0d06caSMauro Carvalho Chehab nr = dev->devno;
17900c0d06caSMauro Carvalho Chehab
17910c0d06caSMauro Carvalho Chehab assoc_desc = udev->actconfig->intf_assoc[0];
17926c3b047fSJohan Hovold if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) {
1793336fea92SMauro Carvalho Chehab dev_err(d, "Not found matching IAD interface\n");
1794256d013aSAlexey Khoroshilov retval = -ENODEV;
1795256d013aSAlexey Khoroshilov goto err_if;
17960c0d06caSMauro Carvalho Chehab }
17970c0d06caSMauro Carvalho Chehab
1798336fea92SMauro Carvalho Chehab dev_dbg(d, "registering interface %d\n", ifnum);
17990c0d06caSMauro Carvalho Chehab
18000c0d06caSMauro Carvalho Chehab /* save our data pointer in this interface device */
18010c0d06caSMauro Carvalho Chehab usb_set_intfdata(interface, dev);
18020c0d06caSMauro Carvalho Chehab
18039832e155SJavier Martinez Canillas /* Initialize the media controller */
18049f806795SMauro Carvalho Chehab retval = cx231xx_media_device_init(dev, udev);
18059f806795SMauro Carvalho Chehab if (retval) {
18069f806795SMauro Carvalho Chehab dev_err(d, "cx231xx_media_device_init failed\n");
18079f806795SMauro Carvalho Chehab goto err_media_init;
18089f806795SMauro Carvalho Chehab }
18091d058bdcSMauro Carvalho Chehab
18100c0d06caSMauro Carvalho Chehab /* Create v4l2 device */
181163ba8c75SMauro Carvalho Chehab #ifdef CONFIG_MEDIA_CONTROLLER
18121d058bdcSMauro Carvalho Chehab dev->v4l2_dev.mdev = dev->media_dev;
181363ba8c75SMauro Carvalho Chehab #endif
18140c0d06caSMauro Carvalho Chehab retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
18150c0d06caSMauro Carvalho Chehab if (retval) {
1816336fea92SMauro Carvalho Chehab dev_err(d, "v4l2_device_register failed\n");
1817256d013aSAlexey Khoroshilov goto err_v4l2;
18180c0d06caSMauro Carvalho Chehab }
18194d2a7d35SMauro Carvalho Chehab
18200c0d06caSMauro Carvalho Chehab /* allocate device struct */
18210c0d06caSMauro Carvalho Chehab retval = cx231xx_init_dev(dev, udev, nr);
1822256d013aSAlexey Khoroshilov if (retval)
1823256d013aSAlexey Khoroshilov goto err_init;
18240c0d06caSMauro Carvalho Chehab
18254d2a7d35SMauro Carvalho Chehab retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe);
18264d2a7d35SMauro Carvalho Chehab if (retval)
1827dcb78ac7SMauro Carvalho Chehab goto err_init;
18280c0d06caSMauro Carvalho Chehab
18290c0d06caSMauro Carvalho Chehab if (dev->current_pcb_config.ts1_source != 0xff) {
18300c0d06caSMauro Carvalho Chehab /* compute alternate max packet sizes for TS1 */
1831dcb78ac7SMauro Carvalho Chehab idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1;
1832dcb78ac7SMauro Carvalho Chehab if (idx >= dev->max_iad_interface_count) {
1833336fea92SMauro Carvalho Chehab dev_err(d, "TS1 PCB interface #%d doesn't exist\n",
1834336fea92SMauro Carvalho Chehab idx);
1835dcb78ac7SMauro Carvalho Chehab retval = -ENODEV;
1836184a8278SMauro Carvalho Chehab goto err_video_alt;
1837dcb78ac7SMauro Carvalho Chehab }
1838dcb78ac7SMauro Carvalho Chehab uif = udev->actconfig->interface[idx];
18390c0d06caSMauro Carvalho Chehab
18400cd273bbSJohan Hovold if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
18410cd273bbSJohan Hovold retval = -ENODEV;
18420cd273bbSJohan Hovold goto err_video_alt;
18430cd273bbSJohan Hovold }
18440cd273bbSJohan Hovold
18450c0d06caSMauro Carvalho Chehab dev->ts1_mode.end_point_addr =
184669a11a32SHans Verkuil uif->altsetting[0].endpoint[isoc_pipe].
184769a11a32SHans Verkuil desc.bEndpointAddress;
18480c0d06caSMauro Carvalho Chehab
18490c0d06caSMauro Carvalho Chehab dev->ts1_mode.num_alt = uif->num_altsetting;
1850336fea92SMauro Carvalho Chehab dev_info(d,
1851b7085c08SMauro Carvalho Chehab "TS EndPoint Addr 0x%x, Alternate settings: %i\n",
18520c0d06caSMauro Carvalho Chehab dev->ts1_mode.end_point_addr,
18530c0d06caSMauro Carvalho Chehab dev->ts1_mode.num_alt);
18540c0d06caSMauro Carvalho Chehab
1855184a8278SMauro Carvalho Chehab dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL);
18560c0d06caSMauro Carvalho Chehab if (dev->ts1_mode.alt_max_pkt_size == NULL) {
1857256d013aSAlexey Khoroshilov retval = -ENOMEM;
1858184a8278SMauro Carvalho Chehab goto err_video_alt;
18590c0d06caSMauro Carvalho Chehab }
18600c0d06caSMauro Carvalho Chehab
18610c0d06caSMauro Carvalho Chehab for (i = 0; i < dev->ts1_mode.num_alt; i++) {
18620cd273bbSJohan Hovold u16 tmp;
18630cd273bbSJohan Hovold
18640cd273bbSJohan Hovold if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
18650cd273bbSJohan Hovold retval = -ENODEV;
18660cd273bbSJohan Hovold goto err_video_alt;
18670cd273bbSJohan Hovold }
18680cd273bbSJohan Hovold
18690cd273bbSJohan Hovold tmp = le16_to_cpu(uif->altsetting[i].
18700c0d06caSMauro Carvalho Chehab endpoint[isoc_pipe].desc.
18710c0d06caSMauro Carvalho Chehab wMaxPacketSize);
18720c0d06caSMauro Carvalho Chehab dev->ts1_mode.alt_max_pkt_size[i] =
18730c0d06caSMauro Carvalho Chehab (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1874336fea92SMauro Carvalho Chehab dev_dbg(d, "Alternate setting %i, max size= %i\n",
1875336fea92SMauro Carvalho Chehab i, dev->ts1_mode.alt_max_pkt_size[i]);
18760c0d06caSMauro Carvalho Chehab }
18770c0d06caSMauro Carvalho Chehab }
18780c0d06caSMauro Carvalho Chehab
18790c0d06caSMauro Carvalho Chehab if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) {
18800c0d06caSMauro Carvalho Chehab cx231xx_enable_OSC(dev);
18810c0d06caSMauro Carvalho Chehab cx231xx_reset_out(dev);
18820c0d06caSMauro Carvalho Chehab cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3);
18830c0d06caSMauro Carvalho Chehab }
18840c0d06caSMauro Carvalho Chehab
18850c0d06caSMauro Carvalho Chehab if (dev->model == CX231XX_BOARD_CNXT_RDE_253S)
18860c0d06caSMauro Carvalho Chehab cx231xx_sleep_s5h1432(dev);
18870c0d06caSMauro Carvalho Chehab
18880c0d06caSMauro Carvalho Chehab /* load other modules required */
18890c0d06caSMauro Carvalho Chehab request_modules(dev);
18900c0d06caSMauro Carvalho Chehab
18919832e155SJavier Martinez Canillas #ifdef CONFIG_MEDIA_CONTROLLER
18926168309aSMauro Carvalho Chehab /* Init entities at the Media Controller */
18936168309aSMauro Carvalho Chehab cx231xx_v4l2_create_entities(dev);
18946168309aSMauro Carvalho Chehab
189508f49200SMauro Carvalho Chehab retval = v4l2_mc_create_media_graph(dev->media_dev);
189608f49200SMauro Carvalho Chehab if (!retval)
18979832e155SJavier Martinez Canillas retval = media_device_register(dev->media_dev);
18989832e155SJavier Martinez Canillas #endif
18999832e155SJavier Martinez Canillas if (retval < 0)
19009832e155SJavier Martinez Canillas cx231xx_release_resources(dev);
1901ab232e46SMauro Carvalho Chehab return retval;
19029832e155SJavier Martinez Canillas
1903256d013aSAlexey Khoroshilov err_video_alt:
1904256d013aSAlexey Khoroshilov /* cx231xx_uninit_dev: */
1905256d013aSAlexey Khoroshilov cx231xx_close_extension(dev);
1906256d013aSAlexey Khoroshilov cx231xx_ir_exit(dev);
1907256d013aSAlexey Khoroshilov cx231xx_release_analog_resources(dev);
1908256d013aSAlexey Khoroshilov cx231xx_417_unregister(dev);
1909256d013aSAlexey Khoroshilov cx231xx_remove_from_devlist(dev);
1910256d013aSAlexey Khoroshilov cx231xx_dev_uninit(dev);
1911256d013aSAlexey Khoroshilov err_init:
1912256d013aSAlexey Khoroshilov v4l2_device_unregister(&dev->v4l2_dev);
1913256d013aSAlexey Khoroshilov err_v4l2:
19149f806795SMauro Carvalho Chehab cx231xx_unregister_media_device(dev);
19159f806795SMauro Carvalho Chehab err_media_init:
1916256d013aSAlexey Khoroshilov usb_set_intfdata(interface, NULL);
1917256d013aSAlexey Khoroshilov err_if:
1918256d013aSAlexey Khoroshilov usb_put_dev(udev);
1919b5603a94SMauro Carvalho Chehab clear_bit(nr, &cx231xx_devused);
1920256d013aSAlexey Khoroshilov return retval;
19210c0d06caSMauro Carvalho Chehab }
19220c0d06caSMauro Carvalho Chehab
19230c0d06caSMauro Carvalho Chehab /*
19240c0d06caSMauro Carvalho Chehab * cx231xx_usb_disconnect()
19256b338c72SGeert Uytterhoeven * called when the device gets disconnected
19260c0d06caSMauro Carvalho Chehab * video device will be unregistered on v4l2_close in case it is still open
19270c0d06caSMauro Carvalho Chehab */
cx231xx_usb_disconnect(struct usb_interface * interface)19280c0d06caSMauro Carvalho Chehab static void cx231xx_usb_disconnect(struct usb_interface *interface)
19290c0d06caSMauro Carvalho Chehab {
19300c0d06caSMauro Carvalho Chehab struct cx231xx *dev;
19310c0d06caSMauro Carvalho Chehab
19320c0d06caSMauro Carvalho Chehab dev = usb_get_intfdata(interface);
19330c0d06caSMauro Carvalho Chehab usb_set_intfdata(interface, NULL);
19340c0d06caSMauro Carvalho Chehab
19350c0d06caSMauro Carvalho Chehab if (!dev)
19360c0d06caSMauro Carvalho Chehab return;
19370c0d06caSMauro Carvalho Chehab
19380c0d06caSMauro Carvalho Chehab if (!dev->udev)
19390c0d06caSMauro Carvalho Chehab return;
19400c0d06caSMauro Carvalho Chehab
19410c0d06caSMauro Carvalho Chehab dev->state |= DEV_DISCONNECTED;
19420c0d06caSMauro Carvalho Chehab
19430c0d06caSMauro Carvalho Chehab flush_request_modules(dev);
19440c0d06caSMauro Carvalho Chehab
19450c0d06caSMauro Carvalho Chehab /* wait until all current v4l2 io is finished then deallocate
19460c0d06caSMauro Carvalho Chehab resources */
19470c0d06caSMauro Carvalho Chehab mutex_lock(&dev->lock);
19480c0d06caSMauro Carvalho Chehab
19490c0d06caSMauro Carvalho Chehab wake_up_interruptible_all(&dev->open);
19500c0d06caSMauro Carvalho Chehab
19510c0d06caSMauro Carvalho Chehab if (dev->users) {
1952336fea92SMauro Carvalho Chehab dev_warn(dev->dev,
1953b7085c08SMauro Carvalho Chehab "device %s is open! Deregistration and memory deallocation are deferred on close.\n",
195460acf187SHans Verkuil video_device_node_name(&dev->vdev));
19550c0d06caSMauro Carvalho Chehab
19560c0d06caSMauro Carvalho Chehab /* Even having users, it is safe to remove the RC i2c driver */
19570c0d06caSMauro Carvalho Chehab cx231xx_ir_exit(dev);
19580c0d06caSMauro Carvalho Chehab
19590c0d06caSMauro Carvalho Chehab if (dev->USE_ISO)
19600c0d06caSMauro Carvalho Chehab cx231xx_uninit_isoc(dev);
19610c0d06caSMauro Carvalho Chehab else
19620c0d06caSMauro Carvalho Chehab cx231xx_uninit_bulk(dev);
19630c0d06caSMauro Carvalho Chehab wake_up_interruptible(&dev->wait_frame);
19640c0d06caSMauro Carvalho Chehab wake_up_interruptible(&dev->wait_stream);
19650c0d06caSMauro Carvalho Chehab } else {
19660c0d06caSMauro Carvalho Chehab }
19670c0d06caSMauro Carvalho Chehab
19680c0d06caSMauro Carvalho Chehab cx231xx_close_extension(dev);
19690c0d06caSMauro Carvalho Chehab
19700c0d06caSMauro Carvalho Chehab mutex_unlock(&dev->lock);
19710c0d06caSMauro Carvalho Chehab
19720c0d06caSMauro Carvalho Chehab if (!dev->users)
19730c0d06caSMauro Carvalho Chehab cx231xx_release_resources(dev);
19740c0d06caSMauro Carvalho Chehab }
19750c0d06caSMauro Carvalho Chehab
19760c0d06caSMauro Carvalho Chehab static struct usb_driver cx231xx_usb_driver = {
19770c0d06caSMauro Carvalho Chehab .name = "cx231xx",
19780c0d06caSMauro Carvalho Chehab .probe = cx231xx_usb_probe,
19790c0d06caSMauro Carvalho Chehab .disconnect = cx231xx_usb_disconnect,
19800c0d06caSMauro Carvalho Chehab .id_table = cx231xx_id_table,
19810c0d06caSMauro Carvalho Chehab };
19820c0d06caSMauro Carvalho Chehab
19830c0d06caSMauro Carvalho Chehab module_usb_driver(cx231xx_usb_driver);
1984