18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci cx231xx-cards.c - driver for Conexant Cx23100/101/102 48c2ecf20Sopenharmony_ci USB video capture devices 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci Copyright (C) 2008 <srinivasa.deevi at conexant dot com> 78c2ecf20Sopenharmony_ci Based on em28xx driver 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "cx231xx.h" 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/slab.h> 158c2ecf20Sopenharmony_ci#include <linux/delay.h> 168c2ecf20Sopenharmony_ci#include <linux/i2c.h> 178c2ecf20Sopenharmony_ci#include <media/tuner.h> 188c2ecf20Sopenharmony_ci#include <media/tveeprom.h> 198c2ecf20Sopenharmony_ci#include <media/v4l2-common.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <media/drv-intf/cx25840.h> 228c2ecf20Sopenharmony_ci#include <media/dvb-usb-ids.h> 238c2ecf20Sopenharmony_ci#include "xc5000.h" 248c2ecf20Sopenharmony_ci#include "tda18271.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic int tuner = -1; 288c2ecf20Sopenharmony_cimodule_param(tuner, int, 0444); 298c2ecf20Sopenharmony_ciMODULE_PARM_DESC(tuner, "tuner type"); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic int transfer_mode = 1; 328c2ecf20Sopenharmony_cimodule_param(transfer_mode, int, 0444); 338c2ecf20Sopenharmony_ciMODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)"); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic unsigned int disable_ir; 368c2ecf20Sopenharmony_cimodule_param(disable_ir, int, 0444); 378c2ecf20Sopenharmony_ciMODULE_PARM_DESC(disable_ir, "disable infrared remote support"); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */ 408c2ecf20Sopenharmony_cistatic unsigned long cx231xx_devused; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* 438c2ecf20Sopenharmony_ci * Reset sequences for analog/digital modes 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic struct cx231xx_reg_seq RDE250_XCV_TUNER[] = { 478c2ecf20Sopenharmony_ci {0x03, 0x01, 10}, 488c2ecf20Sopenharmony_ci {0x03, 0x00, 30}, 498c2ecf20Sopenharmony_ci {0x03, 0x01, 10}, 508c2ecf20Sopenharmony_ci {-1, -1, -1}, 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* 548c2ecf20Sopenharmony_ci * Board definitions 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_cistruct cx231xx_board cx231xx_boards[] = { 578c2ecf20Sopenharmony_ci [CX231XX_BOARD_UNKNOWN] = { 588c2ecf20Sopenharmony_ci .name = "Unknown CX231xx video grabber", 598c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 608c2ecf20Sopenharmony_ci .input = {{ 618c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 628c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 638c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 648c2ecf20Sopenharmony_ci .gpio = NULL, 658c2ecf20Sopenharmony_ci }, { 668c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 678c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 688c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 698c2ecf20Sopenharmony_ci .gpio = NULL, 708c2ecf20Sopenharmony_ci }, { 718c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 728c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 738c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 748c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 758c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 768c2ecf20Sopenharmony_ci .gpio = NULL, 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci }, 798c2ecf20Sopenharmony_ci }, 808c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_CARRAERA] = { 818c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - CARRAERA", 828c2ecf20Sopenharmony_ci .tuner_type = TUNER_XC5000, 838c2ecf20Sopenharmony_ci .tuner_addr = 0x61, 848c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 858c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 868c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 878c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 888c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 898c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 908c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 918c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 928c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 938c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 948c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 958c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 968c2ecf20Sopenharmony_ci .has_dvb = 1, 978c2ecf20Sopenharmony_ci .demod_addr = 0x02, 988c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci .input = {{ 1018c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 1028c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 1038c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 1048c2ecf20Sopenharmony_ci .gpio = NULL, 1058c2ecf20Sopenharmony_ci }, { 1068c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 1078c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 1088c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1098c2ecf20Sopenharmony_ci .gpio = NULL, 1108c2ecf20Sopenharmony_ci }, { 1118c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 1128c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 1138c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 1148c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 1158c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1168c2ecf20Sopenharmony_ci .gpio = NULL, 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci }, 1198c2ecf20Sopenharmony_ci }, 1208c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_SHELBY] = { 1218c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - SHELBY", 1228c2ecf20Sopenharmony_ci .tuner_type = TUNER_XC5000, 1238c2ecf20Sopenharmony_ci .tuner_addr = 0x61, 1248c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 1258c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 1268c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 1278c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 1288c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 1298c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 1308c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 1318c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 1328c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 1338c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 1348c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 1358c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 1368c2ecf20Sopenharmony_ci .has_dvb = 1, 1378c2ecf20Sopenharmony_ci .demod_addr = 0x32, 1388c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci .input = {{ 1418c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 1428c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 1438c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 1448c2ecf20Sopenharmony_ci .gpio = NULL, 1458c2ecf20Sopenharmony_ci }, { 1468c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 1478c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 1488c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1498c2ecf20Sopenharmony_ci .gpio = NULL, 1508c2ecf20Sopenharmony_ci }, { 1518c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 1528c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 1538c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 1548c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 1558c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1568c2ecf20Sopenharmony_ci .gpio = NULL, 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci }, 1598c2ecf20Sopenharmony_ci }, 1608c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_RDE_253S] = { 1618c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - RDE253S", 1628c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 1638c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 1648c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 1658c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 1668c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 1678c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 1688c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 1698c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 1708c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 1718c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 1728c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 1738c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 1748c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 1758c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 1768c2ecf20Sopenharmony_ci .has_dvb = 1, 1778c2ecf20Sopenharmony_ci .demod_addr = 0x02, 1788c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci .input = {{ 1818c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 1828c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 1838c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 1848c2ecf20Sopenharmony_ci .gpio = NULL, 1858c2ecf20Sopenharmony_ci }, { 1868c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 1878c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 1888c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1898c2ecf20Sopenharmony_ci .gpio = NULL, 1908c2ecf20Sopenharmony_ci }, { 1918c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 1928c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 1938c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 1948c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 1958c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 1968c2ecf20Sopenharmony_ci .gpio = NULL, 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci }, 1998c2ecf20Sopenharmony_ci }, 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_RDU_253S] = { 2028c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - RDU253S", 2038c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 2048c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 2058c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 2068c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 2078c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 2088c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 2098c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 2108c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 2118c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 2128c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 2138c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 2148c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 2158c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 2168c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 2178c2ecf20Sopenharmony_ci .has_dvb = 1, 2188c2ecf20Sopenharmony_ci .demod_addr = 0x02, 2198c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci .input = {{ 2228c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 2238c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 2248c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 2258c2ecf20Sopenharmony_ci .gpio = NULL, 2268c2ecf20Sopenharmony_ci }, { 2278c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 2288c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 2298c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 2308c2ecf20Sopenharmony_ci .gpio = NULL, 2318c2ecf20Sopenharmony_ci }, { 2328c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 2338c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 2348c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 2358c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 2368c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 2378c2ecf20Sopenharmony_ci .gpio = NULL, 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci }, 2408c2ecf20Sopenharmony_ci }, 2418c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_VIDEO_GRABBER] = { 2428c2ecf20Sopenharmony_ci .name = "Conexant VIDEO GRABBER", 2438c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 2448c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 2458c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 2468c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 2478c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 2488c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 2498c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 2508c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 2518c2ecf20Sopenharmony_ci .external_av = 1, 2528c2ecf20Sopenharmony_ci /* Actually, it has a 417, but it isn't working correctly. 2538c2ecf20Sopenharmony_ci * So set to 0 for now until someone can manage to get this 2548c2ecf20Sopenharmony_ci * to work reliably. */ 2558c2ecf20Sopenharmony_ci .has_417 = 0, 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci .input = {{ 2588c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 2598c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 2608c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 2618c2ecf20Sopenharmony_ci .gpio = NULL, 2628c2ecf20Sopenharmony_ci }, { 2638c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 2648c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 2658c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 2668c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 2678c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 2688c2ecf20Sopenharmony_ci .gpio = NULL, 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci }, 2718c2ecf20Sopenharmony_ci }, 2728c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_RDE_250] = { 2738c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - rde 250", 2748c2ecf20Sopenharmony_ci .tuner_type = TUNER_XC5000, 2758c2ecf20Sopenharmony_ci .tuner_addr = 0x61, 2768c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 2778c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 2788c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 2798c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 2808c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 2818c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 2828c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 2838c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 2848c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 2858c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 2868c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 2878c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 2888c2ecf20Sopenharmony_ci .has_dvb = 1, 2898c2ecf20Sopenharmony_ci .demod_addr = 0x02, 2908c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci .input = {{ 2938c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 2948c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 2958c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 2968c2ecf20Sopenharmony_ci .gpio = NULL, 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci }, 2998c2ecf20Sopenharmony_ci }, 3008c2ecf20Sopenharmony_ci [CX231XX_BOARD_CNXT_RDU_250] = { 3018c2ecf20Sopenharmony_ci .name = "Conexant Hybrid TV - RDU 250", 3028c2ecf20Sopenharmony_ci .tuner_type = TUNER_XC5000, 3038c2ecf20Sopenharmony_ci .tuner_addr = 0x61, 3048c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 3058c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 3068c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 3078c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 3088c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 3098c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 3108c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 3118c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 3128c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 3138c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 3148c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 3158c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_2, 3168c2ecf20Sopenharmony_ci .has_dvb = 1, 3178c2ecf20Sopenharmony_ci .demod_addr = 0x32, 3188c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci .input = {{ 3218c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 3228c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 3238c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 3248c2ecf20Sopenharmony_ci .gpio = NULL, 3258c2ecf20Sopenharmony_ci } 3268c2ecf20Sopenharmony_ci }, 3278c2ecf20Sopenharmony_ci }, 3288c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_EXETER] = { 3298c2ecf20Sopenharmony_ci .name = "Hauppauge EXETER", 3308c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 3318c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 3328c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 3338c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 3348c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 3358c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 3368c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 3378c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 3388c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 3398c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 3408c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 3418c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 3428c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_1, 3438c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_1, 3448c2ecf20Sopenharmony_ci .has_dvb = 1, 3458c2ecf20Sopenharmony_ci .demod_addr = 0x0e, 3468c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci .input = {{ 3498c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 3508c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 3518c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 3528c2ecf20Sopenharmony_ci .gpio = NULL, 3538c2ecf20Sopenharmony_ci }, { 3548c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 3558c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 3568c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 3578c2ecf20Sopenharmony_ci .gpio = NULL, 3588c2ecf20Sopenharmony_ci }, { 3598c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 3608c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 3618c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 3628c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 3638c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 3648c2ecf20Sopenharmony_ci .gpio = NULL, 3658c2ecf20Sopenharmony_ci } }, 3668c2ecf20Sopenharmony_ci }, 3678c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = { 3688c2ecf20Sopenharmony_ci .name = "Hauppauge USB Live 2", 3698c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 3708c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 3718c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 3728c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 3738c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 3748c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 3758c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 3768c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 3778c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 3788c2ecf20Sopenharmony_ci .external_av = 1, 3798c2ecf20Sopenharmony_ci .input = {{ 3808c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 3818c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 3828c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 3838c2ecf20Sopenharmony_ci .gpio = NULL, 3848c2ecf20Sopenharmony_ci }, { 3858c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 3868c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 3878c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 3888c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 3898c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 3908c2ecf20Sopenharmony_ci .gpio = NULL, 3918c2ecf20Sopenharmony_ci } }, 3928c2ecf20Sopenharmony_ci }, 3938c2ecf20Sopenharmony_ci [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = { 3948c2ecf20Sopenharmony_ci .name = "Kworld UB430 USB Hybrid", 3958c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 3968c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 3978c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 3988c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 3998c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 4008c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 4018c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */ 4028c2ecf20Sopenharmony_ci .tuner_sif_gpio = -1, 4038c2ecf20Sopenharmony_ci .tuner_scl_gpio = -1, 4048c2ecf20Sopenharmony_ci .tuner_sda_gpio = -1, 4058c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 4068c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_2, 4078c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 4088c2ecf20Sopenharmony_ci .ir_i2c_master = I2C_2, 4098c2ecf20Sopenharmony_ci .has_dvb = 1, 4108c2ecf20Sopenharmony_ci .demod_addr = 0x10, 4118c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL_M, 4128c2ecf20Sopenharmony_ci .input = {{ 4138c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 4148c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 4158c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 4168c2ecf20Sopenharmony_ci .gpio = NULL, 4178c2ecf20Sopenharmony_ci }, { 4188c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 4198c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 4208c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 4218c2ecf20Sopenharmony_ci .gpio = NULL, 4228c2ecf20Sopenharmony_ci }, { 4238c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 4248c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 4258c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 4268c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 4278c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 4288c2ecf20Sopenharmony_ci .gpio = NULL, 4298c2ecf20Sopenharmony_ci } }, 4308c2ecf20Sopenharmony_ci }, 4318c2ecf20Sopenharmony_ci [CX231XX_BOARD_KWORLD_UB445_USB_HYBRID] = { 4328c2ecf20Sopenharmony_ci .name = "Kworld UB445 USB Hybrid", 4338c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 4348c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 4358c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 4368c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 4378c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 4388c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 4398c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */ 4408c2ecf20Sopenharmony_ci .tuner_sif_gpio = -1, 4418c2ecf20Sopenharmony_ci .tuner_scl_gpio = -1, 4428c2ecf20Sopenharmony_ci .tuner_sda_gpio = -1, 4438c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 4448c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_2, 4458c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 4468c2ecf20Sopenharmony_ci .ir_i2c_master = I2C_2, 4478c2ecf20Sopenharmony_ci .has_dvb = 1, 4488c2ecf20Sopenharmony_ci .demod_addr = 0x10, 4498c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC_M, 4508c2ecf20Sopenharmony_ci .input = {{ 4518c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 4528c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 4538c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 4548c2ecf20Sopenharmony_ci .gpio = NULL, 4558c2ecf20Sopenharmony_ci }, { 4568c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 4578c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 4588c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 4598c2ecf20Sopenharmony_ci .gpio = NULL, 4608c2ecf20Sopenharmony_ci }, { 4618c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 4628c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 4638c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 4648c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 4658c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 4668c2ecf20Sopenharmony_ci .gpio = NULL, 4678c2ecf20Sopenharmony_ci } }, 4688c2ecf20Sopenharmony_ci }, 4698c2ecf20Sopenharmony_ci [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 4708c2ecf20Sopenharmony_ci .name = "Pixelview PlayTV USB Hybrid", 4718c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 4728c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 4738c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 4748c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 4758c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 4768c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 4778c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 4788c2ecf20Sopenharmony_ci .tuner_sif_gpio = -1, 4798c2ecf20Sopenharmony_ci .tuner_scl_gpio = -1, 4808c2ecf20Sopenharmony_ci .tuner_sda_gpio = -1, 4818c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 4828c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_2, 4838c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 4848c2ecf20Sopenharmony_ci .ir_i2c_master = I2C_2, 4858c2ecf20Sopenharmony_ci .rc_map_name = RC_MAP_PIXELVIEW_002T, 4868c2ecf20Sopenharmony_ci .has_dvb = 1, 4878c2ecf20Sopenharmony_ci .demod_addr = 0x10, 4888c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL_M, 4898c2ecf20Sopenharmony_ci .input = {{ 4908c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 4918c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 4928c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 4938c2ecf20Sopenharmony_ci .gpio = NULL, 4948c2ecf20Sopenharmony_ci }, { 4958c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 4968c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 4978c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 4988c2ecf20Sopenharmony_ci .gpio = NULL, 4998c2ecf20Sopenharmony_ci }, { 5008c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 5018c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 5028c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 5038c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 5048c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5058c2ecf20Sopenharmony_ci .gpio = NULL, 5068c2ecf20Sopenharmony_ci } }, 5078c2ecf20Sopenharmony_ci }, 5088c2ecf20Sopenharmony_ci [CX231XX_BOARD_PV_XCAPTURE_USB] = { 5098c2ecf20Sopenharmony_ci .name = "Pixelview Xcapture USB", 5108c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 5118c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 5128c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 5138c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 5148c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 5158c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 5168c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 5178c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 5188c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 5198c2ecf20Sopenharmony_ci .external_av = 1, 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci .input = {{ 5228c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 5238c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 5248c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5258c2ecf20Sopenharmony_ci .gpio = NULL, 5268c2ecf20Sopenharmony_ci }, { 5278c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 5288c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 5298c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 5308c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 5318c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5328c2ecf20Sopenharmony_ci .gpio = NULL, 5338c2ecf20Sopenharmony_ci } 5348c2ecf20Sopenharmony_ci }, 5358c2ecf20Sopenharmony_ci }, 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci [CX231XX_BOARD_ICONBIT_U100] = { 5388c2ecf20Sopenharmony_ci .name = "Iconbit Analog Stick U100 FM", 5398c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 5408c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 5418c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 5428c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 5438c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 5448c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1C, 5458c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci .input = {{ 5488c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 5498c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 5508c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5518c2ecf20Sopenharmony_ci .gpio = NULL, 5528c2ecf20Sopenharmony_ci }, { 5538c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 5548c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 5558c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 5568c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 5578c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5588c2ecf20Sopenharmony_ci .gpio = NULL, 5598c2ecf20Sopenharmony_ci } }, 5608c2ecf20Sopenharmony_ci }, 5618c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL] = { 5628c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV USB2 FM (PAL)", 5638c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 5648c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 5658c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 5668c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 5678c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 5688c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 5698c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 5708c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 5718c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 5728c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 5738c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 5748c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 5758c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci .input = {{ 5788c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 5798c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 5808c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 5818c2ecf20Sopenharmony_ci .gpio = NULL, 5828c2ecf20Sopenharmony_ci }, { 5838c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 5848c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 5858c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5868c2ecf20Sopenharmony_ci .gpio = NULL, 5878c2ecf20Sopenharmony_ci }, { 5888c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 5898c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 5908c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 5918c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 5928c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 5938c2ecf20Sopenharmony_ci .gpio = NULL, 5948c2ecf20Sopenharmony_ci } }, 5958c2ecf20Sopenharmony_ci }, 5968c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC] = { 5978c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV USB2 FM (NTSC)", 5988c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 5998c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 6008c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 6018c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 6028c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 6038c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 6048c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 6058c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 6068c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 6078c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 6088c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 6098c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 6108c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci .input = {{ 6138c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 6148c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 6158c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 6168c2ecf20Sopenharmony_ci .gpio = NULL, 6178c2ecf20Sopenharmony_ci }, { 6188c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 6198c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 6208c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6218c2ecf20Sopenharmony_ci .gpio = NULL, 6228c2ecf20Sopenharmony_ci }, { 6238c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 6248c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 6258c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 6268c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 6278c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6288c2ecf20Sopenharmony_ci .gpio = NULL, 6298c2ecf20Sopenharmony_ci } }, 6308c2ecf20Sopenharmony_ci }, 6318c2ecf20Sopenharmony_ci [CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2] = { 6328c2ecf20Sopenharmony_ci .name = "Elgato Video Capture V2", 6338c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 6348c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 6358c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 6368c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 6378c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 6388c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 6398c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 6408c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 6418c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 6428c2ecf20Sopenharmony_ci .external_av = 1, 6438c2ecf20Sopenharmony_ci .input = {{ 6448c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 6458c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 6468c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6478c2ecf20Sopenharmony_ci .gpio = NULL, 6488c2ecf20Sopenharmony_ci }, { 6498c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 6508c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 6518c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 6528c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 6538c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6548c2ecf20Sopenharmony_ci .gpio = NULL, 6558c2ecf20Sopenharmony_ci } }, 6568c2ecf20Sopenharmony_ci }, 6578c2ecf20Sopenharmony_ci [CX231XX_BOARD_OTG102] = { 6588c2ecf20Sopenharmony_ci .name = "Geniatech OTG102", 6598c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 6608c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 6618c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 6628c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 6638c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 6648c2ecf20Sopenharmony_ci /* According with PV CxPlrCAP.inf file */ 6658c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 6668c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 6678c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 6688c2ecf20Sopenharmony_ci .external_av = 1, 6698c2ecf20Sopenharmony_ci /*.has_417 = 1, */ 6708c2ecf20Sopenharmony_ci /* This board is believed to have a hardware encoding chip 6718c2ecf20Sopenharmony_ci * supporting mpeg1/2/4, but as the 417 is apparently not 6728c2ecf20Sopenharmony_ci * working for the reference board it is not here either. */ 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci .input = {{ 6758c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 6768c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 6778c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6788c2ecf20Sopenharmony_ci .gpio = NULL, 6798c2ecf20Sopenharmony_ci }, { 6808c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 6818c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 6828c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 6838c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 6848c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6858c2ecf20Sopenharmony_ci .gpio = NULL, 6868c2ecf20Sopenharmony_ci } 6878c2ecf20Sopenharmony_ci }, 6888c2ecf20Sopenharmony_ci }, 6898c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx] = { 6908c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV 930C-HD (1113xx) / HVR-900H (111xxx) / PCTV QuatroStick 521e", 6918c2ecf20Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 6928c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 6938c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 6948c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 6958c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 6968c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 6978c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 6988c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 6998c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 7008c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 7018c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 7028c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 7038c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 7048c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 7058c2ecf20Sopenharmony_ci .has_dvb = 1, 7068c2ecf20Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 7078c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci .input = {{ 7108c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 7118c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 7128c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 7138c2ecf20Sopenharmony_ci .gpio = NULL, 7148c2ecf20Sopenharmony_ci }, { 7158c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 7168c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 7178c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7188c2ecf20Sopenharmony_ci .gpio = NULL, 7198c2ecf20Sopenharmony_ci }, { 7208c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 7218c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 7228c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 7238c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 7248c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7258c2ecf20Sopenharmony_ci .gpio = NULL, 7268c2ecf20Sopenharmony_ci } }, 7278c2ecf20Sopenharmony_ci }, 7288c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx] = { 7298c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV 930C-HD (1114xx) / HVR-901H (1114xx) / PCTV QuatroStick 522e", 7308c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 7318c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 7328c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 7338c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 7348c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 7358c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 7368c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 7378c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 7388c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 7398c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 7408c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 7418c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 7428c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 7438c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 7448c2ecf20Sopenharmony_ci .has_dvb = 1, 7458c2ecf20Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 7468c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci .input = {{ 7498c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 7508c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 7518c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 7528c2ecf20Sopenharmony_ci .gpio = NULL, 7538c2ecf20Sopenharmony_ci }, { 7548c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 7558c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 7568c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7578c2ecf20Sopenharmony_ci .gpio = NULL, 7588c2ecf20Sopenharmony_ci }, { 7598c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 7608c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 7618c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 7628c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 7638c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7648c2ecf20Sopenharmony_ci .gpio = NULL, 7658c2ecf20Sopenharmony_ci } }, 7668c2ecf20Sopenharmony_ci }, 7678c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_955Q] = { 7688c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV-HVR-955Q (111401)", 7698c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 7708c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 7718c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 7728c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 7738c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 7748c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 7758c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 7768c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 7778c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 7788c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 7798c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 7808c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 7818c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 7828c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 7838c2ecf20Sopenharmony_ci .has_dvb = 1, 7848c2ecf20Sopenharmony_ci .demod_addr = 0x59, /* 0xb2 >> 1 */ 7858c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci .input = {{ 7888c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 7898c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 7908c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 7918c2ecf20Sopenharmony_ci .gpio = NULL, 7928c2ecf20Sopenharmony_ci }, { 7938c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 7948c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 7958c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7968c2ecf20Sopenharmony_ci .gpio = NULL, 7978c2ecf20Sopenharmony_ci }, { 7988c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 7998c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 8008c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 8018c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 8028c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8038c2ecf20Sopenharmony_ci .gpio = NULL, 8048c2ecf20Sopenharmony_ci } }, 8058c2ecf20Sopenharmony_ci }, 8068c2ecf20Sopenharmony_ci [CX231XX_BOARD_TERRATEC_GRABBY] = { 8078c2ecf20Sopenharmony_ci .name = "Terratec Grabby", 8088c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 8098c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 8108c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 8118c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 8128c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 8138c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 8148c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 8158c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 8168c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 8178c2ecf20Sopenharmony_ci .external_av = 1, 8188c2ecf20Sopenharmony_ci .input = {{ 8198c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 8208c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 8218c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8228c2ecf20Sopenharmony_ci .gpio = NULL, 8238c2ecf20Sopenharmony_ci }, { 8248c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 8258c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 8268c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 8278c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 8288c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8298c2ecf20Sopenharmony_ci .gpio = NULL, 8308c2ecf20Sopenharmony_ci } }, 8318c2ecf20Sopenharmony_ci }, 8328c2ecf20Sopenharmony_ci [CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD] = { 8338c2ecf20Sopenharmony_ci .name = "Evromedia USB Full Hybrid Full HD", 8348c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 8358c2ecf20Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 8368c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 8378c2ecf20Sopenharmony_ci .has_dvb = 1, 8388c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 8398c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 8408c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 8418c2ecf20Sopenharmony_ci .tuner_addr = 0x60, /* 0xc0 >> 1 */ 8428c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_2, 8438c2ecf20Sopenharmony_ci .input = {{ 8448c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 8458c2ecf20Sopenharmony_ci .vmux = 0, 8468c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 8478c2ecf20Sopenharmony_ci }, { 8488c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 8498c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 8508c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8518c2ecf20Sopenharmony_ci }, { 8528c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 8538c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 8548c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 8558c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 8568c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8578c2ecf20Sopenharmony_ci } }, 8588c2ecf20Sopenharmony_ci }, 8598c2ecf20Sopenharmony_ci [CX231XX_BOARD_ASTROMETA_T2HYBRID] = { 8608c2ecf20Sopenharmony_ci .name = "Astrometa T2hybrid", 8618c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 8628c2ecf20Sopenharmony_ci .has_dvb = 1, 8638c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 8648c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 8658c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x01, 8668c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xffffffc4, 8678c2ecf20Sopenharmony_ci .demod_addr = 0x18, /* 0x30 >> 1 */ 8688c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_1, 8698c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0xa, 8708c2ecf20Sopenharmony_ci .norm = V4L2_STD_NTSC, 8718c2ecf20Sopenharmony_ci .tuner_addr = 0x3a, /* 0x74 >> 1 */ 8728c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 8738c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 8748c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 8758c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 8768c2ecf20Sopenharmony_ci .input = {{ 8778c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 8788c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1, 8798c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 8808c2ecf20Sopenharmony_ci }, { 8818c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 8828c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 8838c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 8848c2ecf20Sopenharmony_ci }, 8858c2ecf20Sopenharmony_ci }, 8868c2ecf20Sopenharmony_ci }, 8878c2ecf20Sopenharmony_ci [CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO] = { 8888c2ecf20Sopenharmony_ci .name = "The Imaging Source DFG/USB2pro", 8898c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 8908c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 8918c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 8928c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 8938c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 8948c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 8958c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 8968c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 8978c2ecf20Sopenharmony_ci .no_alt_vanc = 1, 8988c2ecf20Sopenharmony_ci .external_av = 1, 8998c2ecf20Sopenharmony_ci .input = {{ 9008c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 9018c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1, 9028c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9038c2ecf20Sopenharmony_ci .gpio = NULL, 9048c2ecf20Sopenharmony_ci }, { 9058c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 9068c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1 | 9078c2ecf20Sopenharmony_ci (CX231XX_VIN_2_2 << 8) | 9088c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 9098c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9108c2ecf20Sopenharmony_ci .gpio = NULL, 9118c2ecf20Sopenharmony_ci } }, 9128c2ecf20Sopenharmony_ci }, 9138c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_935C] = { 9148c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV-HVR-935C", 9158c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 9168c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 9178c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 9188c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 9198c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 9208c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 9218c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 9228c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 9238c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 9248c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 9258c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 9268c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 9278c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 9288c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 9298c2ecf20Sopenharmony_ci .has_dvb = 1, 9308c2ecf20Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 9318c2ecf20Sopenharmony_ci .norm = V4L2_STD_PAL, 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci .input = {{ 9348c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 9358c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 9368c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 9378c2ecf20Sopenharmony_ci .gpio = NULL, 9388c2ecf20Sopenharmony_ci }, { 9398c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 9408c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 9418c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9428c2ecf20Sopenharmony_ci .gpio = NULL, 9438c2ecf20Sopenharmony_ci }, { 9448c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 9458c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 9468c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 9478c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 9488c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9498c2ecf20Sopenharmony_ci .gpio = NULL, 9508c2ecf20Sopenharmony_ci } }, 9518c2ecf20Sopenharmony_ci }, 9528c2ecf20Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_975] = { 9538c2ecf20Sopenharmony_ci .name = "Hauppauge WinTV-HVR-975", 9548c2ecf20Sopenharmony_ci .tuner_type = TUNER_ABSENT, 9558c2ecf20Sopenharmony_ci .tuner_addr = 0x60, 9568c2ecf20Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 9578c2ecf20Sopenharmony_ci .tuner_sif_gpio = 0x05, 9588c2ecf20Sopenharmony_ci .tuner_scl_gpio = 0x1a, 9598c2ecf20Sopenharmony_ci .tuner_sda_gpio = 0x1b, 9608c2ecf20Sopenharmony_ci .decoder = CX231XX_AVDECODER, 9618c2ecf20Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 9628c2ecf20Sopenharmony_ci .demod_xfer_mode = 0, 9638c2ecf20Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 9648c2ecf20Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 9658c2ecf20Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 9668c2ecf20Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 9678c2ecf20Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 9688c2ecf20Sopenharmony_ci .has_dvb = 1, 9698c2ecf20Sopenharmony_ci .demod_addr = 0x59, /* 0xb2 >> 1 */ 9708c2ecf20Sopenharmony_ci .demod_addr2 = 0x64, /* 0xc8 >> 1 */ 9718c2ecf20Sopenharmony_ci .norm = V4L2_STD_ALL, 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci .input = {{ 9748c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 9758c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 9768c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 9778c2ecf20Sopenharmony_ci .gpio = NULL, 9788c2ecf20Sopenharmony_ci }, { 9798c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 9808c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 9818c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9828c2ecf20Sopenharmony_ci .gpio = NULL, 9838c2ecf20Sopenharmony_ci }, { 9848c2ecf20Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 9858c2ecf20Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 9868c2ecf20Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 9878c2ecf20Sopenharmony_ci CX25840_SVIDEO_ON, 9888c2ecf20Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 9898c2ecf20Sopenharmony_ci .gpio = NULL, 9908c2ecf20Sopenharmony_ci } }, 9918c2ecf20Sopenharmony_ci }, 9928c2ecf20Sopenharmony_ci}; 9938c2ecf20Sopenharmony_ciconst unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci/* table of devices that work with this driver */ 9968c2ecf20Sopenharmony_cistruct usb_device_id cx231xx_id_table[] = { 9978c2ecf20Sopenharmony_ci {USB_DEVICE(0x1D19, 0x6109), 9988c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 9998c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x5A3C), 10008c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_UNKNOWN}, 10018c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A2), 10028c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_CARRAERA}, 10038c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A1), 10048c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_SHELBY}, 10058c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A4), 10068c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDE_253S}, 10078c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A5), 10088c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDU_253S}, 10098c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A6), 10108c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, 10118c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x589E), 10128c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDE_250}, 10138c2ecf20Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A0), 10148c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDU_250}, 10158c2ecf20Sopenharmony_ci /* AverMedia DVD EZMaker 7 */ 10168c2ecf20Sopenharmony_ci {USB_DEVICE(0x07ca, 0xc039), 10178c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, 10188c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb110), 10198c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL}, 10208c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb111), 10218c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, 10228c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb120), 10238c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, 10248c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb123), 10258c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, 10268c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb124), 10278c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, 10288c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb151), 10298c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_935C}, 10308c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb150), 10318c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_975}, 10328c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb130), 10338c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 10348c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb131), 10358c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 10368c2ecf20Sopenharmony_ci /* Hauppauge WinTV-HVR-900-H */ 10378c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb138), 10388c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 10398c2ecf20Sopenharmony_ci /* Hauppauge WinTV-HVR-901-H */ 10408c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb139), 10418c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 10428c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xb140), 10438c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, 10448c2ecf20Sopenharmony_ci {USB_DEVICE(0x2040, 0xc200), 10458c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, 10468c2ecf20Sopenharmony_ci /* PCTV QuatroStick 521e */ 10478c2ecf20Sopenharmony_ci {USB_DEVICE(0x2013, 0x0259), 10488c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 10498c2ecf20Sopenharmony_ci /* PCTV QuatroStick 522e */ 10508c2ecf20Sopenharmony_ci {USB_DEVICE(0x2013, 0x025e), 10518c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 10528c2ecf20Sopenharmony_ci {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), 10538c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 10548c2ecf20Sopenharmony_ci {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014), 10558c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 10568c2ecf20Sopenharmony_ci {USB_DEVICE(0x1b80, 0xe424), 10578c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID}, 10588c2ecf20Sopenharmony_ci {USB_DEVICE(0x1b80, 0xe421), 10598c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_KWORLD_UB445_USB_HYBRID}, 10608c2ecf20Sopenharmony_ci {USB_DEVICE(0x1f4d, 0x0237), 10618c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_ICONBIT_U100}, 10628c2ecf20Sopenharmony_ci {USB_DEVICE(0x0fd9, 0x0037), 10638c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2}, 10648c2ecf20Sopenharmony_ci {USB_DEVICE(0x1f4d, 0x0102), 10658c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_OTG102}, 10668c2ecf20Sopenharmony_ci {USB_DEVICE(USB_VID_TERRATEC, 0x00a6), 10678c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_TERRATEC_GRABBY}, 10688c2ecf20Sopenharmony_ci {USB_DEVICE(0x1b80, 0xd3b2), 10698c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD}, 10708c2ecf20Sopenharmony_ci {USB_DEVICE(0x15f4, 0x0135), 10718c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_ASTROMETA_T2HYBRID}, 10728c2ecf20Sopenharmony_ci {USB_DEVICE(0x199e, 0x8002), 10738c2ecf20Sopenharmony_ci .driver_info = CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO}, 10748c2ecf20Sopenharmony_ci {}, 10758c2ecf20Sopenharmony_ci}; 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, cx231xx_id_table); 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci/* cx231xx_tuner_callback 10808c2ecf20Sopenharmony_ci * will be used to reset XC5000 tuner using GPIO pin 10818c2ecf20Sopenharmony_ci */ 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ciint cx231xx_tuner_callback(void *ptr, int component, int command, int arg) 10848c2ecf20Sopenharmony_ci{ 10858c2ecf20Sopenharmony_ci int rc = 0; 10868c2ecf20Sopenharmony_ci struct cx231xx *dev = ptr; 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci if (dev->tuner_type == TUNER_XC5000) { 10898c2ecf20Sopenharmony_ci if (command == XC5000_TUNER_RESET) { 10908c2ecf20Sopenharmony_ci dev_dbg(dev->dev, 10918c2ecf20Sopenharmony_ci "Tuner CB: RESET: cmd %d : tuner type %d\n", 10928c2ecf20Sopenharmony_ci command, dev->tuner_type); 10938c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 10948c2ecf20Sopenharmony_ci 1); 10958c2ecf20Sopenharmony_ci msleep(10); 10968c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 10978c2ecf20Sopenharmony_ci 0); 10988c2ecf20Sopenharmony_ci msleep(330); 10998c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 11008c2ecf20Sopenharmony_ci 1); 11018c2ecf20Sopenharmony_ci msleep(10); 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci } else if (dev->tuner_type == TUNER_NXP_TDA18271) { 11048c2ecf20Sopenharmony_ci switch (command) { 11058c2ecf20Sopenharmony_ci case TDA18271_CALLBACK_CMD_AGC_ENABLE: 11068c2ecf20Sopenharmony_ci if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID) 11078c2ecf20Sopenharmony_ci rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg); 11088c2ecf20Sopenharmony_ci break; 11098c2ecf20Sopenharmony_ci default: 11108c2ecf20Sopenharmony_ci rc = -EINVAL; 11118c2ecf20Sopenharmony_ci break; 11128c2ecf20Sopenharmony_ci } 11138c2ecf20Sopenharmony_ci } 11148c2ecf20Sopenharmony_ci return rc; 11158c2ecf20Sopenharmony_ci} 11168c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(cx231xx_tuner_callback); 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_cistatic void cx231xx_reset_out(struct cx231xx *dev) 11198c2ecf20Sopenharmony_ci{ 11208c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 1); 11218c2ecf20Sopenharmony_ci msleep(200); 11228c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 0); 11238c2ecf20Sopenharmony_ci msleep(200); 11248c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 1); 11258c2ecf20Sopenharmony_ci} 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_cistatic void cx231xx_enable_OSC(struct cx231xx *dev) 11288c2ecf20Sopenharmony_ci{ 11298c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1); 11308c2ecf20Sopenharmony_ci} 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_cistatic void cx231xx_sleep_s5h1432(struct cx231xx *dev) 11338c2ecf20Sopenharmony_ci{ 11348c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0); 11358c2ecf20Sopenharmony_ci} 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_cistatic inline void cx231xx_set_model(struct cx231xx *dev) 11388c2ecf20Sopenharmony_ci{ 11398c2ecf20Sopenharmony_ci dev->board = cx231xx_boards[dev->model]; 11408c2ecf20Sopenharmony_ci} 11418c2ecf20Sopenharmony_ci 11428c2ecf20Sopenharmony_ci/* Since cx231xx_pre_card_setup() requires a proper dev->model, 11438c2ecf20Sopenharmony_ci * this won't work for boards with generic PCI IDs 11448c2ecf20Sopenharmony_ci */ 11458c2ecf20Sopenharmony_civoid cx231xx_pre_card_setup(struct cx231xx *dev) 11468c2ecf20Sopenharmony_ci{ 11478c2ecf20Sopenharmony_ci dev_info(dev->dev, "Identified as %s (card=%d)\n", 11488c2ecf20Sopenharmony_ci dev->board.name, dev->model); 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci if (CX231XX_BOARD_ASTROMETA_T2HYBRID == dev->model) { 11518c2ecf20Sopenharmony_ci /* turn on demodulator chip */ 11528c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, 0x03, 0x01); 11538c2ecf20Sopenharmony_ci } 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_ci /* set the direction for GPIO pins */ 11568c2ecf20Sopenharmony_ci if (dev->board.tuner_gpio) { 11578c2ecf20Sopenharmony_ci cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); 11588c2ecf20Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); 11598c2ecf20Sopenharmony_ci } 11608c2ecf20Sopenharmony_ci if (dev->board.tuner_sif_gpio >= 0) 11618c2ecf20Sopenharmony_ci cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); 11628c2ecf20Sopenharmony_ci 11638c2ecf20Sopenharmony_ci /* request some modules if any required */ 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci /* set the mode to Analog mode initially */ 11668c2ecf20Sopenharmony_ci cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci /* Unlock device */ 11698c2ecf20Sopenharmony_ci /* cx231xx_set_mode(dev, CX231XX_SUSPEND); */ 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci} 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_cistatic void cx231xx_config_tuner(struct cx231xx *dev) 11748c2ecf20Sopenharmony_ci{ 11758c2ecf20Sopenharmony_ci struct tuner_setup tun_setup; 11768c2ecf20Sopenharmony_ci struct v4l2_frequency f; 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci if (dev->tuner_type == TUNER_ABSENT) 11798c2ecf20Sopenharmony_ci return; 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; 11828c2ecf20Sopenharmony_ci tun_setup.type = dev->tuner_type; 11838c2ecf20Sopenharmony_ci tun_setup.addr = dev->tuner_addr; 11848c2ecf20Sopenharmony_ci tun_setup.tuner_callback = cx231xx_tuner_callback; 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci tuner_call(dev, tuner, s_type_addr, &tun_setup); 11878c2ecf20Sopenharmony_ci 11888c2ecf20Sopenharmony_ci#if 0 11898c2ecf20Sopenharmony_ci if (tun_setup.type == TUNER_XC5000) { 11908c2ecf20Sopenharmony_ci static struct xc2028_ctrl ctrl = { 11918c2ecf20Sopenharmony_ci .fname = XC5000_DEFAULT_FIRMWARE, 11928c2ecf20Sopenharmony_ci .max_len = 64, 11938c2ecf20Sopenharmony_ci .demod = 0; 11948c2ecf20Sopenharmony_ci }; 11958c2ecf20Sopenharmony_ci struct v4l2_priv_tun_config cfg = { 11968c2ecf20Sopenharmony_ci .tuner = dev->tuner_type, 11978c2ecf20Sopenharmony_ci .priv = &ctrl, 11988c2ecf20Sopenharmony_ci }; 11998c2ecf20Sopenharmony_ci tuner_call(dev, tuner, s_config, &cfg); 12008c2ecf20Sopenharmony_ci } 12018c2ecf20Sopenharmony_ci#endif 12028c2ecf20Sopenharmony_ci /* configure tuner */ 12038c2ecf20Sopenharmony_ci f.tuner = 0; 12048c2ecf20Sopenharmony_ci f.type = V4L2_TUNER_ANALOG_TV; 12058c2ecf20Sopenharmony_ci f.frequency = 9076; /* just a magic number */ 12068c2ecf20Sopenharmony_ci dev->ctl_freq = f.frequency; 12078c2ecf20Sopenharmony_ci call_all(dev, tuner, s_frequency, &f); 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci} 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_cistatic int read_eeprom(struct cx231xx *dev, struct i2c_client *client, 12128c2ecf20Sopenharmony_ci u8 *eedata, int len) 12138c2ecf20Sopenharmony_ci{ 12148c2ecf20Sopenharmony_ci int ret; 12158c2ecf20Sopenharmony_ci u8 start_offset = 0; 12168c2ecf20Sopenharmony_ci int len_todo = len; 12178c2ecf20Sopenharmony_ci u8 *eedata_cur = eedata; 12188c2ecf20Sopenharmony_ci int i; 12198c2ecf20Sopenharmony_ci struct i2c_msg msg_write = { .addr = client->addr, .flags = 0, 12208c2ecf20Sopenharmony_ci .buf = &start_offset, .len = 1 }; 12218c2ecf20Sopenharmony_ci struct i2c_msg msg_read = { .addr = client->addr, .flags = I2C_M_RD }; 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci /* start reading at offset 0 */ 12248c2ecf20Sopenharmony_ci ret = i2c_transfer(client->adapter, &msg_write, 1); 12258c2ecf20Sopenharmony_ci if (ret < 0) { 12268c2ecf20Sopenharmony_ci dev_err(dev->dev, "Can't read eeprom\n"); 12278c2ecf20Sopenharmony_ci return ret; 12288c2ecf20Sopenharmony_ci } 12298c2ecf20Sopenharmony_ci 12308c2ecf20Sopenharmony_ci while (len_todo > 0) { 12318c2ecf20Sopenharmony_ci msg_read.len = (len_todo > 64) ? 64 : len_todo; 12328c2ecf20Sopenharmony_ci msg_read.buf = eedata_cur; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci ret = i2c_transfer(client->adapter, &msg_read, 1); 12358c2ecf20Sopenharmony_ci if (ret < 0) { 12368c2ecf20Sopenharmony_ci dev_err(dev->dev, "Can't read eeprom\n"); 12378c2ecf20Sopenharmony_ci return ret; 12388c2ecf20Sopenharmony_ci } 12398c2ecf20Sopenharmony_ci eedata_cur += msg_read.len; 12408c2ecf20Sopenharmony_ci len_todo -= msg_read.len; 12418c2ecf20Sopenharmony_ci } 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci for (i = 0; i + 15 < len; i += 16) 12448c2ecf20Sopenharmony_ci dev_dbg(dev->dev, "i2c eeprom %02x: %*ph\n", 12458c2ecf20Sopenharmony_ci i, 16, &eedata[i]); 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci return 0; 12488c2ecf20Sopenharmony_ci} 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_civoid cx231xx_card_setup(struct cx231xx *dev) 12518c2ecf20Sopenharmony_ci{ 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci cx231xx_set_model(dev); 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_ci dev->tuner_type = cx231xx_boards[dev->model].tuner_type; 12568c2ecf20Sopenharmony_ci if (cx231xx_boards[dev->model].tuner_addr) 12578c2ecf20Sopenharmony_ci dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr; 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_ci /* request some modules */ 12608c2ecf20Sopenharmony_ci if (dev->board.decoder == CX231XX_AVDECODER) { 12618c2ecf20Sopenharmony_ci dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 12628c2ecf20Sopenharmony_ci cx231xx_get_i2c_adap(dev, I2C_0), 12638c2ecf20Sopenharmony_ci "cx25840", 0x88 >> 1, NULL); 12648c2ecf20Sopenharmony_ci if (dev->sd_cx25840 == NULL) 12658c2ecf20Sopenharmony_ci dev_err(dev->dev, 12668c2ecf20Sopenharmony_ci "cx25840 subdev registration failure\n"); 12678c2ecf20Sopenharmony_ci cx25840_call(dev, core, load_fw); 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci } 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_ci /* Initialize the tuner */ 12728c2ecf20Sopenharmony_ci if (dev->board.tuner_type != TUNER_ABSENT) { 12738c2ecf20Sopenharmony_ci struct i2c_adapter *tuner_i2c = cx231xx_get_i2c_adap(dev, 12748c2ecf20Sopenharmony_ci dev->board.tuner_i2c_master); 12758c2ecf20Sopenharmony_ci dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, 12768c2ecf20Sopenharmony_ci tuner_i2c, 12778c2ecf20Sopenharmony_ci "tuner", 12788c2ecf20Sopenharmony_ci dev->tuner_addr, NULL); 12798c2ecf20Sopenharmony_ci if (dev->sd_tuner == NULL) 12808c2ecf20Sopenharmony_ci dev_err(dev->dev, 12818c2ecf20Sopenharmony_ci "tuner subdev registration failure\n"); 12828c2ecf20Sopenharmony_ci else 12838c2ecf20Sopenharmony_ci cx231xx_config_tuner(dev); 12848c2ecf20Sopenharmony_ci } 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci switch (dev->model) { 12878c2ecf20Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: 12888c2ecf20Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: 12898c2ecf20Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_955Q: 12908c2ecf20Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_935C: 12918c2ecf20Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_975: 12928c2ecf20Sopenharmony_ci { 12938c2ecf20Sopenharmony_ci struct eeprom { 12948c2ecf20Sopenharmony_ci struct tveeprom tvee; 12958c2ecf20Sopenharmony_ci u8 eeprom[256]; 12968c2ecf20Sopenharmony_ci struct i2c_client client; 12978c2ecf20Sopenharmony_ci }; 12988c2ecf20Sopenharmony_ci struct eeprom *e = kzalloc(sizeof(*e), GFP_KERNEL); 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci if (e == NULL) { 13018c2ecf20Sopenharmony_ci dev_err(dev->dev, 13028c2ecf20Sopenharmony_ci "failed to allocate memory to read eeprom\n"); 13038c2ecf20Sopenharmony_ci break; 13048c2ecf20Sopenharmony_ci } 13058c2ecf20Sopenharmony_ci e->client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); 13068c2ecf20Sopenharmony_ci e->client.addr = 0xa0 >> 1; 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_ci read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom)); 13098c2ecf20Sopenharmony_ci tveeprom_hauppauge_analog(&e->tvee, e->eeprom + 0xc0); 13108c2ecf20Sopenharmony_ci kfree(e); 13118c2ecf20Sopenharmony_ci break; 13128c2ecf20Sopenharmony_ci } 13138c2ecf20Sopenharmony_ci } 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci} 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci/* 13188c2ecf20Sopenharmony_ci * cx231xx_config() 13198c2ecf20Sopenharmony_ci * inits registers with sane defaults 13208c2ecf20Sopenharmony_ci */ 13218c2ecf20Sopenharmony_ciint cx231xx_config(struct cx231xx *dev) 13228c2ecf20Sopenharmony_ci{ 13238c2ecf20Sopenharmony_ci /* TBD need to add cx231xx specific code */ 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci return 0; 13268c2ecf20Sopenharmony_ci} 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci/* 13298c2ecf20Sopenharmony_ci * cx231xx_config_i2c() 13308c2ecf20Sopenharmony_ci * configure i2c attached devices 13318c2ecf20Sopenharmony_ci */ 13328c2ecf20Sopenharmony_civoid cx231xx_config_i2c(struct cx231xx *dev) 13338c2ecf20Sopenharmony_ci{ 13348c2ecf20Sopenharmony_ci /* u32 input = INPUT(dev->video_input)->vmux; */ 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_ci call_all(dev, video, s_stream, 1); 13378c2ecf20Sopenharmony_ci} 13388c2ecf20Sopenharmony_ci 13398c2ecf20Sopenharmony_cistatic void cx231xx_unregister_media_device(struct cx231xx *dev) 13408c2ecf20Sopenharmony_ci{ 13418c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 13428c2ecf20Sopenharmony_ci if (dev->media_dev) { 13438c2ecf20Sopenharmony_ci media_device_unregister(dev->media_dev); 13448c2ecf20Sopenharmony_ci media_device_cleanup(dev->media_dev); 13458c2ecf20Sopenharmony_ci kfree(dev->media_dev); 13468c2ecf20Sopenharmony_ci dev->media_dev = NULL; 13478c2ecf20Sopenharmony_ci } 13488c2ecf20Sopenharmony_ci#endif 13498c2ecf20Sopenharmony_ci} 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_ci/* 13528c2ecf20Sopenharmony_ci * cx231xx_realease_resources() 13538c2ecf20Sopenharmony_ci * unregisters the v4l2,i2c and usb devices 13548c2ecf20Sopenharmony_ci * called when the device gets disconnected or at module unload 13558c2ecf20Sopenharmony_ci*/ 13568c2ecf20Sopenharmony_civoid cx231xx_release_resources(struct cx231xx *dev) 13578c2ecf20Sopenharmony_ci{ 13588c2ecf20Sopenharmony_ci cx231xx_ir_exit(dev); 13598c2ecf20Sopenharmony_ci 13608c2ecf20Sopenharmony_ci cx231xx_release_analog_resources(dev); 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci cx231xx_remove_from_devlist(dev); 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_ci /* Release I2C buses */ 13658c2ecf20Sopenharmony_ci cx231xx_dev_uninit(dev); 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci /* delete v4l2 device */ 13688c2ecf20Sopenharmony_ci v4l2_device_unregister(&dev->v4l2_dev); 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci cx231xx_unregister_media_device(dev); 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci usb_put_dev(dev->udev); 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci /* Mark device as unused */ 13758c2ecf20Sopenharmony_ci clear_bit(dev->devno, &cx231xx_devused); 13768c2ecf20Sopenharmony_ci} 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_cistatic int cx231xx_media_device_init(struct cx231xx *dev, 13798c2ecf20Sopenharmony_ci struct usb_device *udev) 13808c2ecf20Sopenharmony_ci{ 13818c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 13828c2ecf20Sopenharmony_ci struct media_device *mdev; 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 13858c2ecf20Sopenharmony_ci if (!mdev) 13868c2ecf20Sopenharmony_ci return -ENOMEM; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci media_device_usb_init(mdev, udev, dev->board.name); 13898c2ecf20Sopenharmony_ci 13908c2ecf20Sopenharmony_ci dev->media_dev = mdev; 13918c2ecf20Sopenharmony_ci#endif 13928c2ecf20Sopenharmony_ci return 0; 13938c2ecf20Sopenharmony_ci} 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci/* 13968c2ecf20Sopenharmony_ci * cx231xx_init_dev() 13978c2ecf20Sopenharmony_ci * allocates and inits the device structs, registers i2c bus and v4l device 13988c2ecf20Sopenharmony_ci */ 13998c2ecf20Sopenharmony_cistatic int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, 14008c2ecf20Sopenharmony_ci int minor) 14018c2ecf20Sopenharmony_ci{ 14028c2ecf20Sopenharmony_ci int retval = -ENOMEM; 14038c2ecf20Sopenharmony_ci unsigned int maxh, maxw; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci dev->udev = udev; 14068c2ecf20Sopenharmony_ci mutex_init(&dev->lock); 14078c2ecf20Sopenharmony_ci mutex_init(&dev->ctrl_urb_lock); 14088c2ecf20Sopenharmony_ci mutex_init(&dev->gpio_i2c_lock); 14098c2ecf20Sopenharmony_ci mutex_init(&dev->i2c_lock); 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci spin_lock_init(&dev->video_mode.slock); 14128c2ecf20Sopenharmony_ci spin_lock_init(&dev->vbi_mode.slock); 14138c2ecf20Sopenharmony_ci spin_lock_init(&dev->sliced_cc_mode.slock); 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci init_waitqueue_head(&dev->open); 14168c2ecf20Sopenharmony_ci init_waitqueue_head(&dev->wait_frame); 14178c2ecf20Sopenharmony_ci init_waitqueue_head(&dev->wait_stream); 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg; 14208c2ecf20Sopenharmony_ci dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg; 14218c2ecf20Sopenharmony_ci dev->cx231xx_send_usb_command = cx231xx_send_usb_command; 14228c2ecf20Sopenharmony_ci dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read; 14238c2ecf20Sopenharmony_ci dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write; 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci /* Query cx231xx to find what pcb config it is related to */ 14268c2ecf20Sopenharmony_ci retval = initialize_cx231xx(dev); 14278c2ecf20Sopenharmony_ci if (retval < 0) { 14288c2ecf20Sopenharmony_ci dev_err(dev->dev, "Failed to read PCB config\n"); 14298c2ecf20Sopenharmony_ci return retval; 14308c2ecf20Sopenharmony_ci } 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci /*To workaround error number=-71 on EP0 for VideoGrabber, 14338c2ecf20Sopenharmony_ci need set alt here.*/ 14348c2ecf20Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 14358c2ecf20Sopenharmony_ci dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) { 14368c2ecf20Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); 14378c2ecf20Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VANC, 1); 14388c2ecf20Sopenharmony_ci } 14398c2ecf20Sopenharmony_ci /* Cx231xx pre card setup */ 14408c2ecf20Sopenharmony_ci cx231xx_pre_card_setup(dev); 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci retval = cx231xx_config(dev); 14438c2ecf20Sopenharmony_ci if (retval) { 14448c2ecf20Sopenharmony_ci dev_err(dev->dev, "error configuring device\n"); 14458c2ecf20Sopenharmony_ci return -ENOMEM; 14468c2ecf20Sopenharmony_ci } 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_ci /* set default norm */ 14498c2ecf20Sopenharmony_ci dev->norm = dev->board.norm; 14508c2ecf20Sopenharmony_ci 14518c2ecf20Sopenharmony_ci /* register i2c bus */ 14528c2ecf20Sopenharmony_ci retval = cx231xx_dev_init(dev); 14538c2ecf20Sopenharmony_ci if (retval) { 14548c2ecf20Sopenharmony_ci dev_err(dev->dev, 14558c2ecf20Sopenharmony_ci "%s: cx231xx_i2c_register - errCode [%d]!\n", 14568c2ecf20Sopenharmony_ci __func__, retval); 14578c2ecf20Sopenharmony_ci goto err_dev_init; 14588c2ecf20Sopenharmony_ci } 14598c2ecf20Sopenharmony_ci 14608c2ecf20Sopenharmony_ci /* Do board specific init */ 14618c2ecf20Sopenharmony_ci cx231xx_card_setup(dev); 14628c2ecf20Sopenharmony_ci 14638c2ecf20Sopenharmony_ci /* configure the device */ 14648c2ecf20Sopenharmony_ci cx231xx_config_i2c(dev); 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci maxw = norm_maxw(dev); 14678c2ecf20Sopenharmony_ci maxh = norm_maxh(dev); 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci /* set default image size */ 14708c2ecf20Sopenharmony_ci dev->width = maxw; 14718c2ecf20Sopenharmony_ci dev->height = maxh; 14728c2ecf20Sopenharmony_ci dev->interlaced = 0; 14738c2ecf20Sopenharmony_ci dev->video_input = 0; 14748c2ecf20Sopenharmony_ci 14758c2ecf20Sopenharmony_ci retval = cx231xx_config(dev); 14768c2ecf20Sopenharmony_ci if (retval) { 14778c2ecf20Sopenharmony_ci dev_err(dev->dev, "%s: cx231xx_config - errCode [%d]!\n", 14788c2ecf20Sopenharmony_ci __func__, retval); 14798c2ecf20Sopenharmony_ci goto err_dev_init; 14808c2ecf20Sopenharmony_ci } 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci /* init video dma queue */ 14838c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev->video_mode.vidq.active); 14848c2ecf20Sopenharmony_ci 14858c2ecf20Sopenharmony_ci /* init vbi dma queue */ 14868c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev->vbi_mode.vidq.active); 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci /* Reset other chips required if they are tied up with GPIO pins */ 14898c2ecf20Sopenharmony_ci cx231xx_add_into_devlist(dev); 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci if (dev->board.has_417) { 14928c2ecf20Sopenharmony_ci dev_info(dev->dev, "attach 417 %d\n", dev->model); 14938c2ecf20Sopenharmony_ci if (cx231xx_417_register(dev) < 0) { 14948c2ecf20Sopenharmony_ci dev_err(dev->dev, 14958c2ecf20Sopenharmony_ci "%s() Failed to register 417 on VID_B\n", 14968c2ecf20Sopenharmony_ci __func__); 14978c2ecf20Sopenharmony_ci } 14988c2ecf20Sopenharmony_ci } 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci retval = cx231xx_register_analog_devices(dev); 15018c2ecf20Sopenharmony_ci if (retval) 15028c2ecf20Sopenharmony_ci goto err_analog; 15038c2ecf20Sopenharmony_ci 15048c2ecf20Sopenharmony_ci cx231xx_ir_init(dev); 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci cx231xx_init_extension(dev); 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci return 0; 15098c2ecf20Sopenharmony_cierr_analog: 15108c2ecf20Sopenharmony_ci cx231xx_unregister_media_device(dev); 15118c2ecf20Sopenharmony_ci cx231xx_release_analog_resources(dev); 15128c2ecf20Sopenharmony_ci cx231xx_remove_from_devlist(dev); 15138c2ecf20Sopenharmony_cierr_dev_init: 15148c2ecf20Sopenharmony_ci cx231xx_dev_uninit(dev); 15158c2ecf20Sopenharmony_ci return retval; 15168c2ecf20Sopenharmony_ci} 15178c2ecf20Sopenharmony_ci 15188c2ecf20Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE) 15198c2ecf20Sopenharmony_cistatic void request_module_async(struct work_struct *work) 15208c2ecf20Sopenharmony_ci{ 15218c2ecf20Sopenharmony_ci struct cx231xx *dev = container_of(work, 15228c2ecf20Sopenharmony_ci struct cx231xx, request_module_wk); 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ci if (dev->has_alsa_audio) 15258c2ecf20Sopenharmony_ci request_module("cx231xx-alsa"); 15268c2ecf20Sopenharmony_ci 15278c2ecf20Sopenharmony_ci if (dev->board.has_dvb) 15288c2ecf20Sopenharmony_ci request_module("cx231xx-dvb"); 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci} 15318c2ecf20Sopenharmony_ci 15328c2ecf20Sopenharmony_cistatic void request_modules(struct cx231xx *dev) 15338c2ecf20Sopenharmony_ci{ 15348c2ecf20Sopenharmony_ci INIT_WORK(&dev->request_module_wk, request_module_async); 15358c2ecf20Sopenharmony_ci schedule_work(&dev->request_module_wk); 15368c2ecf20Sopenharmony_ci} 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_cistatic void flush_request_modules(struct cx231xx *dev) 15398c2ecf20Sopenharmony_ci{ 15408c2ecf20Sopenharmony_ci flush_work(&dev->request_module_wk); 15418c2ecf20Sopenharmony_ci} 15428c2ecf20Sopenharmony_ci#else 15438c2ecf20Sopenharmony_ci#define request_modules(dev) 15448c2ecf20Sopenharmony_ci#define flush_request_modules(dev) 15458c2ecf20Sopenharmony_ci#endif /* CONFIG_MODULES */ 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_cistatic int cx231xx_init_v4l2(struct cx231xx *dev, 15488c2ecf20Sopenharmony_ci struct usb_device *udev, 15498c2ecf20Sopenharmony_ci struct usb_interface *interface, 15508c2ecf20Sopenharmony_ci int isoc_pipe) 15518c2ecf20Sopenharmony_ci{ 15528c2ecf20Sopenharmony_ci struct usb_interface *uif; 15538c2ecf20Sopenharmony_ci int i, idx; 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci /* Video Init */ 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci /* compute alternate max packet sizes for video */ 15588c2ecf20Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; 15598c2ecf20Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 15608c2ecf20Sopenharmony_ci dev_err(dev->dev, 15618c2ecf20Sopenharmony_ci "Video PCB interface #%d doesn't exist\n", idx); 15628c2ecf20Sopenharmony_ci return -ENODEV; 15638c2ecf20Sopenharmony_ci } 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci uif = udev->actconfig->interface[idx]; 15668c2ecf20Sopenharmony_ci 15678c2ecf20Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 15688c2ecf20Sopenharmony_ci return -ENODEV; 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_ci dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; 15718c2ecf20Sopenharmony_ci dev->video_mode.num_alt = uif->num_altsetting; 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_ci dev_info(dev->dev, 15748c2ecf20Sopenharmony_ci "video EndPoint Addr 0x%x, Alternate settings: %i\n", 15758c2ecf20Sopenharmony_ci dev->video_mode.end_point_addr, 15768c2ecf20Sopenharmony_ci dev->video_mode.num_alt); 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_ci dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); 15798c2ecf20Sopenharmony_ci if (dev->video_mode.alt_max_pkt_size == NULL) 15808c2ecf20Sopenharmony_ci return -ENOMEM; 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci for (i = 0; i < dev->video_mode.num_alt; i++) { 15838c2ecf20Sopenharmony_ci u16 tmp; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 15868c2ecf20Sopenharmony_ci return -ENODEV; 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); 15898c2ecf20Sopenharmony_ci dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 15908c2ecf20Sopenharmony_ci dev_dbg(dev->dev, 15918c2ecf20Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 15928c2ecf20Sopenharmony_ci dev->video_mode.alt_max_pkt_size[i]); 15938c2ecf20Sopenharmony_ci } 15948c2ecf20Sopenharmony_ci 15958c2ecf20Sopenharmony_ci /* VBI Init */ 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; 15988c2ecf20Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 15998c2ecf20Sopenharmony_ci dev_err(dev->dev, 16008c2ecf20Sopenharmony_ci "VBI PCB interface #%d doesn't exist\n", idx); 16018c2ecf20Sopenharmony_ci return -ENODEV; 16028c2ecf20Sopenharmony_ci } 16038c2ecf20Sopenharmony_ci uif = udev->actconfig->interface[idx]; 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 16068c2ecf20Sopenharmony_ci return -ENODEV; 16078c2ecf20Sopenharmony_ci 16088c2ecf20Sopenharmony_ci dev->vbi_mode.end_point_addr = 16098c2ecf20Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe].desc. 16108c2ecf20Sopenharmony_ci bEndpointAddress; 16118c2ecf20Sopenharmony_ci 16128c2ecf20Sopenharmony_ci dev->vbi_mode.num_alt = uif->num_altsetting; 16138c2ecf20Sopenharmony_ci dev_info(dev->dev, 16148c2ecf20Sopenharmony_ci "VBI EndPoint Addr 0x%x, Alternate settings: %i\n", 16158c2ecf20Sopenharmony_ci dev->vbi_mode.end_point_addr, 16168c2ecf20Sopenharmony_ci dev->vbi_mode.num_alt); 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci /* compute alternate max packet sizes for vbi */ 16198c2ecf20Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); 16208c2ecf20Sopenharmony_ci if (dev->vbi_mode.alt_max_pkt_size == NULL) 16218c2ecf20Sopenharmony_ci return -ENOMEM; 16228c2ecf20Sopenharmony_ci 16238c2ecf20Sopenharmony_ci for (i = 0; i < dev->vbi_mode.num_alt; i++) { 16248c2ecf20Sopenharmony_ci u16 tmp; 16258c2ecf20Sopenharmony_ci 16268c2ecf20Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 16278c2ecf20Sopenharmony_ci return -ENODEV; 16288c2ecf20Sopenharmony_ci 16298c2ecf20Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 16308c2ecf20Sopenharmony_ci desc.wMaxPacketSize); 16318c2ecf20Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size[i] = 16328c2ecf20Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 16338c2ecf20Sopenharmony_ci dev_dbg(dev->dev, 16348c2ecf20Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 16358c2ecf20Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size[i]); 16368c2ecf20Sopenharmony_ci } 16378c2ecf20Sopenharmony_ci 16388c2ecf20Sopenharmony_ci /* Sliced CC VBI init */ 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ci /* compute alternate max packet sizes for sliced CC */ 16418c2ecf20Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; 16428c2ecf20Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 16438c2ecf20Sopenharmony_ci dev_err(dev->dev, 16448c2ecf20Sopenharmony_ci "Sliced CC PCB interface #%d doesn't exist\n", idx); 16458c2ecf20Sopenharmony_ci return -ENODEV; 16468c2ecf20Sopenharmony_ci } 16478c2ecf20Sopenharmony_ci uif = udev->actconfig->interface[idx]; 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 16508c2ecf20Sopenharmony_ci return -ENODEV; 16518c2ecf20Sopenharmony_ci 16528c2ecf20Sopenharmony_ci dev->sliced_cc_mode.end_point_addr = 16538c2ecf20Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe].desc. 16548c2ecf20Sopenharmony_ci bEndpointAddress; 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci dev->sliced_cc_mode.num_alt = uif->num_altsetting; 16578c2ecf20Sopenharmony_ci dev_info(dev->dev, 16588c2ecf20Sopenharmony_ci "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", 16598c2ecf20Sopenharmony_ci dev->sliced_cc_mode.end_point_addr, 16608c2ecf20Sopenharmony_ci dev->sliced_cc_mode.num_alt); 16618c2ecf20Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); 16628c2ecf20Sopenharmony_ci if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) 16638c2ecf20Sopenharmony_ci return -ENOMEM; 16648c2ecf20Sopenharmony_ci 16658c2ecf20Sopenharmony_ci for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { 16668c2ecf20Sopenharmony_ci u16 tmp; 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 16698c2ecf20Sopenharmony_ci return -ENODEV; 16708c2ecf20Sopenharmony_ci 16718c2ecf20Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 16728c2ecf20Sopenharmony_ci desc.wMaxPacketSize); 16738c2ecf20Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size[i] = 16748c2ecf20Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 16758c2ecf20Sopenharmony_ci dev_dbg(dev->dev, 16768c2ecf20Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 16778c2ecf20Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size[i]); 16788c2ecf20Sopenharmony_ci } 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci return 0; 16818c2ecf20Sopenharmony_ci} 16828c2ecf20Sopenharmony_ci 16838c2ecf20Sopenharmony_ci/* 16848c2ecf20Sopenharmony_ci * cx231xx_usb_probe() 16858c2ecf20Sopenharmony_ci * checks for supported devices 16868c2ecf20Sopenharmony_ci */ 16878c2ecf20Sopenharmony_cistatic int cx231xx_usb_probe(struct usb_interface *interface, 16888c2ecf20Sopenharmony_ci const struct usb_device_id *id) 16898c2ecf20Sopenharmony_ci{ 16908c2ecf20Sopenharmony_ci struct usb_device *udev; 16918c2ecf20Sopenharmony_ci struct device *d = &interface->dev; 16928c2ecf20Sopenharmony_ci struct usb_interface *uif; 16938c2ecf20Sopenharmony_ci struct cx231xx *dev = NULL; 16948c2ecf20Sopenharmony_ci int retval = -ENODEV; 16958c2ecf20Sopenharmony_ci int nr = 0, ifnum; 16968c2ecf20Sopenharmony_ci int i, isoc_pipe = 0; 16978c2ecf20Sopenharmony_ci char *speed; 16988c2ecf20Sopenharmony_ci u8 idx; 16998c2ecf20Sopenharmony_ci struct usb_interface_assoc_descriptor *assoc_desc; 17008c2ecf20Sopenharmony_ci 17018c2ecf20Sopenharmony_ci ifnum = interface->altsetting[0].desc.bInterfaceNumber; 17028c2ecf20Sopenharmony_ci 17038c2ecf20Sopenharmony_ci /* 17048c2ecf20Sopenharmony_ci * Interface number 0 - IR interface (handled by mceusb driver) 17058c2ecf20Sopenharmony_ci * Interface number 1 - AV interface (handled by this driver) 17068c2ecf20Sopenharmony_ci */ 17078c2ecf20Sopenharmony_ci if (ifnum != 1) 17088c2ecf20Sopenharmony_ci return -ENODEV; 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci /* Check to see next free device and mark as used */ 17118c2ecf20Sopenharmony_ci do { 17128c2ecf20Sopenharmony_ci nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); 17138c2ecf20Sopenharmony_ci if (nr >= CX231XX_MAXBOARDS) { 17148c2ecf20Sopenharmony_ci /* No free device slots */ 17158c2ecf20Sopenharmony_ci dev_err(d, 17168c2ecf20Sopenharmony_ci "Supports only %i devices.\n", 17178c2ecf20Sopenharmony_ci CX231XX_MAXBOARDS); 17188c2ecf20Sopenharmony_ci return -ENOMEM; 17198c2ecf20Sopenharmony_ci } 17208c2ecf20Sopenharmony_ci } while (test_and_set_bit(nr, &cx231xx_devused)); 17218c2ecf20Sopenharmony_ci 17228c2ecf20Sopenharmony_ci udev = usb_get_dev(interface_to_usbdev(interface)); 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci /* allocate memory for our device state and initialize it */ 17258c2ecf20Sopenharmony_ci dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); 17268c2ecf20Sopenharmony_ci if (dev == NULL) { 17278c2ecf20Sopenharmony_ci retval = -ENOMEM; 17288c2ecf20Sopenharmony_ci goto err_if; 17298c2ecf20Sopenharmony_ci } 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci snprintf(dev->name, 29, "cx231xx #%d", nr); 17328c2ecf20Sopenharmony_ci dev->devno = nr; 17338c2ecf20Sopenharmony_ci dev->model = id->driver_info; 17348c2ecf20Sopenharmony_ci dev->video_mode.alt = -1; 17358c2ecf20Sopenharmony_ci dev->dev = d; 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_ci cx231xx_set_model(dev); 17388c2ecf20Sopenharmony_ci 17398c2ecf20Sopenharmony_ci dev->interface_count++; 17408c2ecf20Sopenharmony_ci /* reset gpio dir and value */ 17418c2ecf20Sopenharmony_ci dev->gpio_dir = 0; 17428c2ecf20Sopenharmony_ci dev->gpio_val = 0; 17438c2ecf20Sopenharmony_ci dev->xc_fw_load_done = 0; 17448c2ecf20Sopenharmony_ci dev->has_alsa_audio = 1; 17458c2ecf20Sopenharmony_ci dev->power_mode = -1; 17468c2ecf20Sopenharmony_ci atomic_set(&dev->devlist_count, 0); 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_ci /* 0 - vbi ; 1 -sliced cc mode */ 17498c2ecf20Sopenharmony_ci dev->vbi_or_sliced_cc_mode = 0; 17508c2ecf20Sopenharmony_ci 17518c2ecf20Sopenharmony_ci /* get maximum no.of IAD interfaces */ 17528c2ecf20Sopenharmony_ci dev->max_iad_interface_count = udev->config->desc.bNumInterfaces; 17538c2ecf20Sopenharmony_ci 17548c2ecf20Sopenharmony_ci /* init CIR module TBD */ 17558c2ecf20Sopenharmony_ci 17568c2ecf20Sopenharmony_ci /*mode_tv: digital=1 or analog=0*/ 17578c2ecf20Sopenharmony_ci dev->mode_tv = 0; 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci dev->USE_ISO = transfer_mode; 17608c2ecf20Sopenharmony_ci 17618c2ecf20Sopenharmony_ci switch (udev->speed) { 17628c2ecf20Sopenharmony_ci case USB_SPEED_LOW: 17638c2ecf20Sopenharmony_ci speed = "1.5"; 17648c2ecf20Sopenharmony_ci break; 17658c2ecf20Sopenharmony_ci case USB_SPEED_UNKNOWN: 17668c2ecf20Sopenharmony_ci case USB_SPEED_FULL: 17678c2ecf20Sopenharmony_ci speed = "12"; 17688c2ecf20Sopenharmony_ci break; 17698c2ecf20Sopenharmony_ci case USB_SPEED_HIGH: 17708c2ecf20Sopenharmony_ci speed = "480"; 17718c2ecf20Sopenharmony_ci break; 17728c2ecf20Sopenharmony_ci default: 17738c2ecf20Sopenharmony_ci speed = "unknown"; 17748c2ecf20Sopenharmony_ci } 17758c2ecf20Sopenharmony_ci 17768c2ecf20Sopenharmony_ci dev_info(d, 17778c2ecf20Sopenharmony_ci "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", 17788c2ecf20Sopenharmony_ci udev->manufacturer ? udev->manufacturer : "", 17798c2ecf20Sopenharmony_ci udev->product ? udev->product : "", 17808c2ecf20Sopenharmony_ci speed, 17818c2ecf20Sopenharmony_ci le16_to_cpu(udev->descriptor.idVendor), 17828c2ecf20Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct), 17838c2ecf20Sopenharmony_ci dev->max_iad_interface_count); 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_ci /* increment interface count */ 17868c2ecf20Sopenharmony_ci dev->interface_count++; 17878c2ecf20Sopenharmony_ci 17888c2ecf20Sopenharmony_ci /* get device number */ 17898c2ecf20Sopenharmony_ci nr = dev->devno; 17908c2ecf20Sopenharmony_ci 17918c2ecf20Sopenharmony_ci assoc_desc = udev->actconfig->intf_assoc[0]; 17928c2ecf20Sopenharmony_ci if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) { 17938c2ecf20Sopenharmony_ci dev_err(d, "Not found matching IAD interface\n"); 17948c2ecf20Sopenharmony_ci retval = -ENODEV; 17958c2ecf20Sopenharmony_ci goto err_if; 17968c2ecf20Sopenharmony_ci } 17978c2ecf20Sopenharmony_ci 17988c2ecf20Sopenharmony_ci dev_dbg(d, "registering interface %d\n", ifnum); 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ci /* save our data pointer in this interface device */ 18018c2ecf20Sopenharmony_ci usb_set_intfdata(interface, dev); 18028c2ecf20Sopenharmony_ci 18038c2ecf20Sopenharmony_ci /* Initialize the media controller */ 18048c2ecf20Sopenharmony_ci retval = cx231xx_media_device_init(dev, udev); 18058c2ecf20Sopenharmony_ci if (retval) { 18068c2ecf20Sopenharmony_ci dev_err(d, "cx231xx_media_device_init failed\n"); 18078c2ecf20Sopenharmony_ci goto err_media_init; 18088c2ecf20Sopenharmony_ci } 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_ci /* Create v4l2 device */ 18118c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 18128c2ecf20Sopenharmony_ci dev->v4l2_dev.mdev = dev->media_dev; 18138c2ecf20Sopenharmony_ci#endif 18148c2ecf20Sopenharmony_ci retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); 18158c2ecf20Sopenharmony_ci if (retval) { 18168c2ecf20Sopenharmony_ci dev_err(d, "v4l2_device_register failed\n"); 18178c2ecf20Sopenharmony_ci goto err_v4l2; 18188c2ecf20Sopenharmony_ci } 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci /* allocate device struct */ 18218c2ecf20Sopenharmony_ci retval = cx231xx_init_dev(dev, udev, nr); 18228c2ecf20Sopenharmony_ci if (retval) 18238c2ecf20Sopenharmony_ci goto err_init; 18248c2ecf20Sopenharmony_ci 18258c2ecf20Sopenharmony_ci retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe); 18268c2ecf20Sopenharmony_ci if (retval) 18278c2ecf20Sopenharmony_ci goto err_init; 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci if (dev->current_pcb_config.ts1_source != 0xff) { 18308c2ecf20Sopenharmony_ci /* compute alternate max packet sizes for TS1 */ 18318c2ecf20Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; 18328c2ecf20Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 18338c2ecf20Sopenharmony_ci dev_err(d, "TS1 PCB interface #%d doesn't exist\n", 18348c2ecf20Sopenharmony_ci idx); 18358c2ecf20Sopenharmony_ci retval = -ENODEV; 18368c2ecf20Sopenharmony_ci goto err_video_alt; 18378c2ecf20Sopenharmony_ci } 18388c2ecf20Sopenharmony_ci uif = udev->actconfig->interface[idx]; 18398c2ecf20Sopenharmony_ci 18408c2ecf20Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) { 18418c2ecf20Sopenharmony_ci retval = -ENODEV; 18428c2ecf20Sopenharmony_ci goto err_video_alt; 18438c2ecf20Sopenharmony_ci } 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci dev->ts1_mode.end_point_addr = 18468c2ecf20Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe]. 18478c2ecf20Sopenharmony_ci desc.bEndpointAddress; 18488c2ecf20Sopenharmony_ci 18498c2ecf20Sopenharmony_ci dev->ts1_mode.num_alt = uif->num_altsetting; 18508c2ecf20Sopenharmony_ci dev_info(d, 18518c2ecf20Sopenharmony_ci "TS EndPoint Addr 0x%x, Alternate settings: %i\n", 18528c2ecf20Sopenharmony_ci dev->ts1_mode.end_point_addr, 18538c2ecf20Sopenharmony_ci dev->ts1_mode.num_alt); 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_ci dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); 18568c2ecf20Sopenharmony_ci if (dev->ts1_mode.alt_max_pkt_size == NULL) { 18578c2ecf20Sopenharmony_ci retval = -ENOMEM; 18588c2ecf20Sopenharmony_ci goto err_video_alt; 18598c2ecf20Sopenharmony_ci } 18608c2ecf20Sopenharmony_ci 18618c2ecf20Sopenharmony_ci for (i = 0; i < dev->ts1_mode.num_alt; i++) { 18628c2ecf20Sopenharmony_ci u16 tmp; 18638c2ecf20Sopenharmony_ci 18648c2ecf20Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) { 18658c2ecf20Sopenharmony_ci retval = -ENODEV; 18668c2ecf20Sopenharmony_ci goto err_video_alt; 18678c2ecf20Sopenharmony_ci } 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i]. 18708c2ecf20Sopenharmony_ci endpoint[isoc_pipe].desc. 18718c2ecf20Sopenharmony_ci wMaxPacketSize); 18728c2ecf20Sopenharmony_ci dev->ts1_mode.alt_max_pkt_size[i] = 18738c2ecf20Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 18748c2ecf20Sopenharmony_ci dev_dbg(d, "Alternate setting %i, max size= %i\n", 18758c2ecf20Sopenharmony_ci i, dev->ts1_mode.alt_max_pkt_size[i]); 18768c2ecf20Sopenharmony_ci } 18778c2ecf20Sopenharmony_ci } 18788c2ecf20Sopenharmony_ci 18798c2ecf20Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 18808c2ecf20Sopenharmony_ci cx231xx_enable_OSC(dev); 18818c2ecf20Sopenharmony_ci cx231xx_reset_out(dev); 18828c2ecf20Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); 18838c2ecf20Sopenharmony_ci } 18848c2ecf20Sopenharmony_ci 18858c2ecf20Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_RDE_253S) 18868c2ecf20Sopenharmony_ci cx231xx_sleep_s5h1432(dev); 18878c2ecf20Sopenharmony_ci 18888c2ecf20Sopenharmony_ci /* load other modules required */ 18898c2ecf20Sopenharmony_ci request_modules(dev); 18908c2ecf20Sopenharmony_ci 18918c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 18928c2ecf20Sopenharmony_ci /* Init entities at the Media Controller */ 18938c2ecf20Sopenharmony_ci cx231xx_v4l2_create_entities(dev); 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_ci retval = v4l2_mc_create_media_graph(dev->media_dev); 18968c2ecf20Sopenharmony_ci if (!retval) 18978c2ecf20Sopenharmony_ci retval = media_device_register(dev->media_dev); 18988c2ecf20Sopenharmony_ci#endif 18998c2ecf20Sopenharmony_ci if (retval < 0) 19008c2ecf20Sopenharmony_ci cx231xx_release_resources(dev); 19018c2ecf20Sopenharmony_ci return retval; 19028c2ecf20Sopenharmony_ci 19038c2ecf20Sopenharmony_cierr_video_alt: 19048c2ecf20Sopenharmony_ci /* cx231xx_uninit_dev: */ 19058c2ecf20Sopenharmony_ci cx231xx_close_extension(dev); 19068c2ecf20Sopenharmony_ci cx231xx_ir_exit(dev); 19078c2ecf20Sopenharmony_ci cx231xx_release_analog_resources(dev); 19088c2ecf20Sopenharmony_ci cx231xx_417_unregister(dev); 19098c2ecf20Sopenharmony_ci cx231xx_remove_from_devlist(dev); 19108c2ecf20Sopenharmony_ci cx231xx_dev_uninit(dev); 19118c2ecf20Sopenharmony_cierr_init: 19128c2ecf20Sopenharmony_ci v4l2_device_unregister(&dev->v4l2_dev); 19138c2ecf20Sopenharmony_cierr_v4l2: 19148c2ecf20Sopenharmony_ci cx231xx_unregister_media_device(dev); 19158c2ecf20Sopenharmony_cierr_media_init: 19168c2ecf20Sopenharmony_ci usb_set_intfdata(interface, NULL); 19178c2ecf20Sopenharmony_cierr_if: 19188c2ecf20Sopenharmony_ci usb_put_dev(udev); 19198c2ecf20Sopenharmony_ci clear_bit(nr, &cx231xx_devused); 19208c2ecf20Sopenharmony_ci return retval; 19218c2ecf20Sopenharmony_ci} 19228c2ecf20Sopenharmony_ci 19238c2ecf20Sopenharmony_ci/* 19248c2ecf20Sopenharmony_ci * cx231xx_usb_disconnect() 19258c2ecf20Sopenharmony_ci * called when the device gets disconnected 19268c2ecf20Sopenharmony_ci * video device will be unregistered on v4l2_close in case it is still open 19278c2ecf20Sopenharmony_ci */ 19288c2ecf20Sopenharmony_cistatic void cx231xx_usb_disconnect(struct usb_interface *interface) 19298c2ecf20Sopenharmony_ci{ 19308c2ecf20Sopenharmony_ci struct cx231xx *dev; 19318c2ecf20Sopenharmony_ci 19328c2ecf20Sopenharmony_ci dev = usb_get_intfdata(interface); 19338c2ecf20Sopenharmony_ci usb_set_intfdata(interface, NULL); 19348c2ecf20Sopenharmony_ci 19358c2ecf20Sopenharmony_ci if (!dev) 19368c2ecf20Sopenharmony_ci return; 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci if (!dev->udev) 19398c2ecf20Sopenharmony_ci return; 19408c2ecf20Sopenharmony_ci 19418c2ecf20Sopenharmony_ci dev->state |= DEV_DISCONNECTED; 19428c2ecf20Sopenharmony_ci 19438c2ecf20Sopenharmony_ci flush_request_modules(dev); 19448c2ecf20Sopenharmony_ci 19458c2ecf20Sopenharmony_ci /* wait until all current v4l2 io is finished then deallocate 19468c2ecf20Sopenharmony_ci resources */ 19478c2ecf20Sopenharmony_ci mutex_lock(&dev->lock); 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_ci wake_up_interruptible_all(&dev->open); 19508c2ecf20Sopenharmony_ci 19518c2ecf20Sopenharmony_ci if (dev->users) { 19528c2ecf20Sopenharmony_ci dev_warn(dev->dev, 19538c2ecf20Sopenharmony_ci "device %s is open! Deregistration and memory deallocation are deferred on close.\n", 19548c2ecf20Sopenharmony_ci video_device_node_name(&dev->vdev)); 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_ci /* Even having users, it is safe to remove the RC i2c driver */ 19578c2ecf20Sopenharmony_ci cx231xx_ir_exit(dev); 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_ci if (dev->USE_ISO) 19608c2ecf20Sopenharmony_ci cx231xx_uninit_isoc(dev); 19618c2ecf20Sopenharmony_ci else 19628c2ecf20Sopenharmony_ci cx231xx_uninit_bulk(dev); 19638c2ecf20Sopenharmony_ci wake_up_interruptible(&dev->wait_frame); 19648c2ecf20Sopenharmony_ci wake_up_interruptible(&dev->wait_stream); 19658c2ecf20Sopenharmony_ci } else { 19668c2ecf20Sopenharmony_ci } 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_ci cx231xx_close_extension(dev); 19698c2ecf20Sopenharmony_ci 19708c2ecf20Sopenharmony_ci mutex_unlock(&dev->lock); 19718c2ecf20Sopenharmony_ci 19728c2ecf20Sopenharmony_ci if (!dev->users) 19738c2ecf20Sopenharmony_ci cx231xx_release_resources(dev); 19748c2ecf20Sopenharmony_ci} 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_cistatic struct usb_driver cx231xx_usb_driver = { 19778c2ecf20Sopenharmony_ci .name = "cx231xx", 19788c2ecf20Sopenharmony_ci .probe = cx231xx_usb_probe, 19798c2ecf20Sopenharmony_ci .disconnect = cx231xx_usb_disconnect, 19808c2ecf20Sopenharmony_ci .id_table = cx231xx_id_table, 19818c2ecf20Sopenharmony_ci}; 19828c2ecf20Sopenharmony_ci 19838c2ecf20Sopenharmony_cimodule_usb_driver(cx231xx_usb_driver); 1984