162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci cx231xx-cards.c - driver for Conexant Cx23100/101/102 462306a36Sopenharmony_ci USB video capture devices 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci Copyright (C) 2008 <srinivasa.deevi at conexant dot com> 762306a36Sopenharmony_ci Based on em28xx driver 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "cx231xx.h" 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <linux/delay.h> 1662306a36Sopenharmony_ci#include <linux/i2c.h> 1762306a36Sopenharmony_ci#include <media/tuner.h> 1862306a36Sopenharmony_ci#include <media/tveeprom.h> 1962306a36Sopenharmony_ci#include <media/v4l2-common.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <media/drv-intf/cx25840.h> 2262306a36Sopenharmony_ci#include <media/dvb-usb-ids.h> 2362306a36Sopenharmony_ci#include "xc5000.h" 2462306a36Sopenharmony_ci#include "tda18271.h" 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic int tuner = -1; 2862306a36Sopenharmony_cimodule_param(tuner, int, 0444); 2962306a36Sopenharmony_ciMODULE_PARM_DESC(tuner, "tuner type"); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic int transfer_mode = 1; 3262306a36Sopenharmony_cimodule_param(transfer_mode, int, 0444); 3362306a36Sopenharmony_ciMODULE_PARM_DESC(transfer_mode, "transfer mode (1-ISO or 0-BULK)"); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic unsigned int disable_ir; 3662306a36Sopenharmony_cimodule_param(disable_ir, int, 0444); 3762306a36Sopenharmony_ciMODULE_PARM_DESC(disable_ir, "disable infrared remote support"); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */ 4062306a36Sopenharmony_cistatic unsigned long cx231xx_devused; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* 4362306a36Sopenharmony_ci * Reset sequences for analog/digital modes 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic struct cx231xx_reg_seq RDE250_XCV_TUNER[] = { 4762306a36Sopenharmony_ci {0x03, 0x01, 10}, 4862306a36Sopenharmony_ci {0x03, 0x00, 30}, 4962306a36Sopenharmony_ci {0x03, 0x01, 10}, 5062306a36Sopenharmony_ci {-1, -1, -1}, 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * Board definitions 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_cistruct cx231xx_board cx231xx_boards[] = { 5762306a36Sopenharmony_ci [CX231XX_BOARD_UNKNOWN] = { 5862306a36Sopenharmony_ci .name = "Unknown CX231xx video grabber", 5962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 6062306a36Sopenharmony_ci .input = {{ 6162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 6262306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 6362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 6462306a36Sopenharmony_ci .gpio = NULL, 6562306a36Sopenharmony_ci }, { 6662306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 6762306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 6862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 6962306a36Sopenharmony_ci .gpio = NULL, 7062306a36Sopenharmony_ci }, { 7162306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 7262306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 7362306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 7462306a36Sopenharmony_ci CX25840_SVIDEO_ON, 7562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 7662306a36Sopenharmony_ci .gpio = NULL, 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci }, 7962306a36Sopenharmony_ci }, 8062306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_CARRAERA] = { 8162306a36Sopenharmony_ci .name = "Conexant Hybrid TV - CARRAERA", 8262306a36Sopenharmony_ci .tuner_type = TUNER_XC5000, 8362306a36Sopenharmony_ci .tuner_addr = 0x61, 8462306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 8562306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 8662306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 8762306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 8862306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 8962306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 9062306a36Sopenharmony_ci .demod_xfer_mode = 0, 9162306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 9262306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 9362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 9462306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 9562306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 9662306a36Sopenharmony_ci .has_dvb = 1, 9762306a36Sopenharmony_ci .demod_addr = 0x02, 9862306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci .input = {{ 10162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 10262306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 10362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 10462306a36Sopenharmony_ci .gpio = NULL, 10562306a36Sopenharmony_ci }, { 10662306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 10762306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 10862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 10962306a36Sopenharmony_ci .gpio = NULL, 11062306a36Sopenharmony_ci }, { 11162306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 11262306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 11362306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 11462306a36Sopenharmony_ci CX25840_SVIDEO_ON, 11562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 11662306a36Sopenharmony_ci .gpio = NULL, 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci }, 11962306a36Sopenharmony_ci }, 12062306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_SHELBY] = { 12162306a36Sopenharmony_ci .name = "Conexant Hybrid TV - SHELBY", 12262306a36Sopenharmony_ci .tuner_type = TUNER_XC5000, 12362306a36Sopenharmony_ci .tuner_addr = 0x61, 12462306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 12562306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 12662306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 12762306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 12862306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 12962306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 13062306a36Sopenharmony_ci .demod_xfer_mode = 0, 13162306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 13262306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 13362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 13462306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 13562306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 13662306a36Sopenharmony_ci .has_dvb = 1, 13762306a36Sopenharmony_ci .demod_addr = 0x32, 13862306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci .input = {{ 14162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 14262306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 14362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 14462306a36Sopenharmony_ci .gpio = NULL, 14562306a36Sopenharmony_ci }, { 14662306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 14762306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 14862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 14962306a36Sopenharmony_ci .gpio = NULL, 15062306a36Sopenharmony_ci }, { 15162306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 15262306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 15362306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 15462306a36Sopenharmony_ci CX25840_SVIDEO_ON, 15562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 15662306a36Sopenharmony_ci .gpio = NULL, 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci }, 15962306a36Sopenharmony_ci }, 16062306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_RDE_253S] = { 16162306a36Sopenharmony_ci .name = "Conexant Hybrid TV - RDE253S", 16262306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 16362306a36Sopenharmony_ci .tuner_addr = 0x60, 16462306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 16562306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 16662306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 16762306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 16862306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 16962306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 17062306a36Sopenharmony_ci .demod_xfer_mode = 0, 17162306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 17262306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 17362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 17462306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 17562306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 17662306a36Sopenharmony_ci .has_dvb = 1, 17762306a36Sopenharmony_ci .demod_addr = 0x02, 17862306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci .input = {{ 18162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 18262306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 18362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 18462306a36Sopenharmony_ci .gpio = NULL, 18562306a36Sopenharmony_ci }, { 18662306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 18762306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 18862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 18962306a36Sopenharmony_ci .gpio = NULL, 19062306a36Sopenharmony_ci }, { 19162306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 19262306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 19362306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 19462306a36Sopenharmony_ci CX25840_SVIDEO_ON, 19562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 19662306a36Sopenharmony_ci .gpio = NULL, 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci }, 19962306a36Sopenharmony_ci }, 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_RDU_253S] = { 20262306a36Sopenharmony_ci .name = "Conexant Hybrid TV - RDU253S", 20362306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 20462306a36Sopenharmony_ci .tuner_addr = 0x60, 20562306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 20662306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 20762306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 20862306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 20962306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 21062306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 21162306a36Sopenharmony_ci .demod_xfer_mode = 0, 21262306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 21362306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 21462306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 21562306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 21662306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 21762306a36Sopenharmony_ci .has_dvb = 1, 21862306a36Sopenharmony_ci .demod_addr = 0x02, 21962306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci .input = {{ 22262306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 22362306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 22462306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 22562306a36Sopenharmony_ci .gpio = NULL, 22662306a36Sopenharmony_ci }, { 22762306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 22862306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 22962306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 23062306a36Sopenharmony_ci .gpio = NULL, 23162306a36Sopenharmony_ci }, { 23262306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 23362306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 23462306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 23562306a36Sopenharmony_ci CX25840_SVIDEO_ON, 23662306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 23762306a36Sopenharmony_ci .gpio = NULL, 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci }, 24062306a36Sopenharmony_ci }, 24162306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_VIDEO_GRABBER] = { 24262306a36Sopenharmony_ci .name = "Conexant VIDEO GRABBER", 24362306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 24462306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 24562306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 24662306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 24762306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 24862306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 24962306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 25062306a36Sopenharmony_ci .no_alt_vanc = 1, 25162306a36Sopenharmony_ci .external_av = 1, 25262306a36Sopenharmony_ci /* Actually, it has a 417, but it isn't working correctly. 25362306a36Sopenharmony_ci * So set to 0 for now until someone can manage to get this 25462306a36Sopenharmony_ci * to work reliably. */ 25562306a36Sopenharmony_ci .has_417 = 0, 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci .input = {{ 25862306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 25962306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 26062306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 26162306a36Sopenharmony_ci .gpio = NULL, 26262306a36Sopenharmony_ci }, { 26362306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 26462306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 26562306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 26662306a36Sopenharmony_ci CX25840_SVIDEO_ON, 26762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 26862306a36Sopenharmony_ci .gpio = NULL, 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci }, 27162306a36Sopenharmony_ci }, 27262306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_RDE_250] = { 27362306a36Sopenharmony_ci .name = "Conexant Hybrid TV - rde 250", 27462306a36Sopenharmony_ci .tuner_type = TUNER_XC5000, 27562306a36Sopenharmony_ci .tuner_addr = 0x61, 27662306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 27762306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 27862306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 27962306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 28062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 28162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 28262306a36Sopenharmony_ci .demod_xfer_mode = 0, 28362306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 28462306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 28562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 28662306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 28762306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 28862306a36Sopenharmony_ci .has_dvb = 1, 28962306a36Sopenharmony_ci .demod_addr = 0x02, 29062306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci .input = {{ 29362306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 29462306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 29562306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 29662306a36Sopenharmony_ci .gpio = NULL, 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci }, 29962306a36Sopenharmony_ci }, 30062306a36Sopenharmony_ci [CX231XX_BOARD_CNXT_RDU_250] = { 30162306a36Sopenharmony_ci .name = "Conexant Hybrid TV - RDU 250", 30262306a36Sopenharmony_ci .tuner_type = TUNER_XC5000, 30362306a36Sopenharmony_ci .tuner_addr = 0x61, 30462306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 30562306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 30662306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 30762306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 30862306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 30962306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 31062306a36Sopenharmony_ci .demod_xfer_mode = 0, 31162306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 31262306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 31362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 31462306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 31562306a36Sopenharmony_ci .demod_i2c_master = I2C_2, 31662306a36Sopenharmony_ci .has_dvb = 1, 31762306a36Sopenharmony_ci .demod_addr = 0x32, 31862306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci .input = {{ 32162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 32262306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 32362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 32462306a36Sopenharmony_ci .gpio = NULL, 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci }, 32862306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_EXETER] = { 32962306a36Sopenharmony_ci .name = "Hauppauge EXETER", 33062306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 33162306a36Sopenharmony_ci .tuner_addr = 0x60, 33262306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 33362306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 33462306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 33562306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 33662306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 33762306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 33862306a36Sopenharmony_ci .demod_xfer_mode = 0, 33962306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 34062306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 34162306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 34262306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_1, 34362306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_1, 34462306a36Sopenharmony_ci .has_dvb = 1, 34562306a36Sopenharmony_ci .demod_addr = 0x0e, 34662306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci .input = {{ 34962306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 35062306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 35162306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 35262306a36Sopenharmony_ci .gpio = NULL, 35362306a36Sopenharmony_ci }, { 35462306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 35562306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 35662306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 35762306a36Sopenharmony_ci .gpio = NULL, 35862306a36Sopenharmony_ci }, { 35962306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 36062306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 36162306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 36262306a36Sopenharmony_ci CX25840_SVIDEO_ON, 36362306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 36462306a36Sopenharmony_ci .gpio = NULL, 36562306a36Sopenharmony_ci } }, 36662306a36Sopenharmony_ci }, 36762306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = { 36862306a36Sopenharmony_ci .name = "Hauppauge USB Live 2", 36962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 37062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 37162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 37262306a36Sopenharmony_ci .demod_xfer_mode = 0, 37362306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 37462306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 37562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 37662306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 37762306a36Sopenharmony_ci .no_alt_vanc = 1, 37862306a36Sopenharmony_ci .external_av = 1, 37962306a36Sopenharmony_ci .input = {{ 38062306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 38162306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 38262306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 38362306a36Sopenharmony_ci .gpio = NULL, 38462306a36Sopenharmony_ci }, { 38562306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 38662306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 38762306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 38862306a36Sopenharmony_ci CX25840_SVIDEO_ON, 38962306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 39062306a36Sopenharmony_ci .gpio = NULL, 39162306a36Sopenharmony_ci } }, 39262306a36Sopenharmony_ci }, 39362306a36Sopenharmony_ci [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = { 39462306a36Sopenharmony_ci .name = "Kworld UB430 USB Hybrid", 39562306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 39662306a36Sopenharmony_ci .tuner_addr = 0x60, 39762306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 39862306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 39962306a36Sopenharmony_ci .demod_xfer_mode = 0, 40062306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 40162306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */ 40262306a36Sopenharmony_ci .tuner_sif_gpio = -1, 40362306a36Sopenharmony_ci .tuner_scl_gpio = -1, 40462306a36Sopenharmony_ci .tuner_sda_gpio = -1, 40562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 40662306a36Sopenharmony_ci .tuner_i2c_master = I2C_2, 40762306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 40862306a36Sopenharmony_ci .ir_i2c_master = I2C_2, 40962306a36Sopenharmony_ci .has_dvb = 1, 41062306a36Sopenharmony_ci .demod_addr = 0x10, 41162306a36Sopenharmony_ci .norm = V4L2_STD_PAL_M, 41262306a36Sopenharmony_ci .input = {{ 41362306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 41462306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 41562306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 41662306a36Sopenharmony_ci .gpio = NULL, 41762306a36Sopenharmony_ci }, { 41862306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 41962306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 42062306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 42162306a36Sopenharmony_ci .gpio = NULL, 42262306a36Sopenharmony_ci }, { 42362306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 42462306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 42562306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 42662306a36Sopenharmony_ci CX25840_SVIDEO_ON, 42762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 42862306a36Sopenharmony_ci .gpio = NULL, 42962306a36Sopenharmony_ci } }, 43062306a36Sopenharmony_ci }, 43162306a36Sopenharmony_ci [CX231XX_BOARD_KWORLD_UB445_USB_HYBRID] = { 43262306a36Sopenharmony_ci .name = "Kworld UB445 USB Hybrid", 43362306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 43462306a36Sopenharmony_ci .tuner_addr = 0x60, 43562306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 43662306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 43762306a36Sopenharmony_ci .demod_xfer_mode = 0, 43862306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 43962306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */ 44062306a36Sopenharmony_ci .tuner_sif_gpio = -1, 44162306a36Sopenharmony_ci .tuner_scl_gpio = -1, 44262306a36Sopenharmony_ci .tuner_sda_gpio = -1, 44362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 44462306a36Sopenharmony_ci .tuner_i2c_master = I2C_2, 44562306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 44662306a36Sopenharmony_ci .ir_i2c_master = I2C_2, 44762306a36Sopenharmony_ci .has_dvb = 1, 44862306a36Sopenharmony_ci .demod_addr = 0x10, 44962306a36Sopenharmony_ci .norm = V4L2_STD_NTSC_M, 45062306a36Sopenharmony_ci .input = {{ 45162306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 45262306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 45362306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 45462306a36Sopenharmony_ci .gpio = NULL, 45562306a36Sopenharmony_ci }, { 45662306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 45762306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 45862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 45962306a36Sopenharmony_ci .gpio = NULL, 46062306a36Sopenharmony_ci }, { 46162306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 46262306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 46362306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 46462306a36Sopenharmony_ci CX25840_SVIDEO_ON, 46562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 46662306a36Sopenharmony_ci .gpio = NULL, 46762306a36Sopenharmony_ci } }, 46862306a36Sopenharmony_ci }, 46962306a36Sopenharmony_ci [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 47062306a36Sopenharmony_ci .name = "Pixelview PlayTV USB Hybrid", 47162306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 47262306a36Sopenharmony_ci .tuner_addr = 0x60, 47362306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 47462306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 47562306a36Sopenharmony_ci .demod_xfer_mode = 0, 47662306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 47762306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1c, 47862306a36Sopenharmony_ci .tuner_sif_gpio = -1, 47962306a36Sopenharmony_ci .tuner_scl_gpio = -1, 48062306a36Sopenharmony_ci .tuner_sda_gpio = -1, 48162306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 48262306a36Sopenharmony_ci .tuner_i2c_master = I2C_2, 48362306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 48462306a36Sopenharmony_ci .ir_i2c_master = I2C_2, 48562306a36Sopenharmony_ci .rc_map_name = RC_MAP_PIXELVIEW_002T, 48662306a36Sopenharmony_ci .has_dvb = 1, 48762306a36Sopenharmony_ci .demod_addr = 0x10, 48862306a36Sopenharmony_ci .norm = V4L2_STD_PAL_M, 48962306a36Sopenharmony_ci .input = {{ 49062306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 49162306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 49262306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 49362306a36Sopenharmony_ci .gpio = NULL, 49462306a36Sopenharmony_ci }, { 49562306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 49662306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 49762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 49862306a36Sopenharmony_ci .gpio = NULL, 49962306a36Sopenharmony_ci }, { 50062306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 50162306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 50262306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 50362306a36Sopenharmony_ci CX25840_SVIDEO_ON, 50462306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 50562306a36Sopenharmony_ci .gpio = NULL, 50662306a36Sopenharmony_ci } }, 50762306a36Sopenharmony_ci }, 50862306a36Sopenharmony_ci [CX231XX_BOARD_PV_XCAPTURE_USB] = { 50962306a36Sopenharmony_ci .name = "Pixelview Xcapture USB", 51062306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 51162306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 51262306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 51362306a36Sopenharmony_ci .demod_xfer_mode = 0, 51462306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 51562306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 51662306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 51762306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 51862306a36Sopenharmony_ci .no_alt_vanc = 1, 51962306a36Sopenharmony_ci .external_av = 1, 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci .input = {{ 52262306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 52362306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 52462306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 52562306a36Sopenharmony_ci .gpio = NULL, 52662306a36Sopenharmony_ci }, { 52762306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 52862306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 52962306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 53062306a36Sopenharmony_ci CX25840_SVIDEO_ON, 53162306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 53262306a36Sopenharmony_ci .gpio = NULL, 53362306a36Sopenharmony_ci } 53462306a36Sopenharmony_ci }, 53562306a36Sopenharmony_ci }, 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci [CX231XX_BOARD_ICONBIT_U100] = { 53862306a36Sopenharmony_ci .name = "Iconbit Analog Stick U100 FM", 53962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 54062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 54162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 54262306a36Sopenharmony_ci .demod_xfer_mode = 0, 54362306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 54462306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x1C, 54562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci .input = {{ 54862306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 54962306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 55062306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 55162306a36Sopenharmony_ci .gpio = NULL, 55262306a36Sopenharmony_ci }, { 55362306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 55462306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 55562306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 55662306a36Sopenharmony_ci CX25840_SVIDEO_ON, 55762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 55862306a36Sopenharmony_ci .gpio = NULL, 55962306a36Sopenharmony_ci } }, 56062306a36Sopenharmony_ci }, 56162306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL] = { 56262306a36Sopenharmony_ci .name = "Hauppauge WinTV USB2 FM (PAL)", 56362306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 56462306a36Sopenharmony_ci .tuner_addr = 0x60, 56562306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 56662306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 56762306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 56862306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 56962306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 57062306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 57162306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 57262306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 57362306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 57462306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 57562306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci .input = {{ 57862306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 57962306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 58062306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 58162306a36Sopenharmony_ci .gpio = NULL, 58262306a36Sopenharmony_ci }, { 58362306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 58462306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 58562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 58662306a36Sopenharmony_ci .gpio = NULL, 58762306a36Sopenharmony_ci }, { 58862306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 58962306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 59062306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 59162306a36Sopenharmony_ci CX25840_SVIDEO_ON, 59262306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 59362306a36Sopenharmony_ci .gpio = NULL, 59462306a36Sopenharmony_ci } }, 59562306a36Sopenharmony_ci }, 59662306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC] = { 59762306a36Sopenharmony_ci .name = "Hauppauge WinTV USB2 FM (NTSC)", 59862306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 59962306a36Sopenharmony_ci .tuner_addr = 0x60, 60062306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 60162306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 60262306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 60362306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 60462306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 60562306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 60662306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 60762306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 60862306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 60962306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 61062306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci .input = {{ 61362306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 61462306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 61562306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 61662306a36Sopenharmony_ci .gpio = NULL, 61762306a36Sopenharmony_ci }, { 61862306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 61962306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 62062306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 62162306a36Sopenharmony_ci .gpio = NULL, 62262306a36Sopenharmony_ci }, { 62362306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 62462306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 62562306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 62662306a36Sopenharmony_ci CX25840_SVIDEO_ON, 62762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 62862306a36Sopenharmony_ci .gpio = NULL, 62962306a36Sopenharmony_ci } }, 63062306a36Sopenharmony_ci }, 63162306a36Sopenharmony_ci [CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2] = { 63262306a36Sopenharmony_ci .name = "Elgato Video Capture V2", 63362306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 63462306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 63562306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 63662306a36Sopenharmony_ci .demod_xfer_mode = 0, 63762306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 63862306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 63962306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 64062306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 64162306a36Sopenharmony_ci .no_alt_vanc = 1, 64262306a36Sopenharmony_ci .external_av = 1, 64362306a36Sopenharmony_ci .input = {{ 64462306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 64562306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 64662306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 64762306a36Sopenharmony_ci .gpio = NULL, 64862306a36Sopenharmony_ci }, { 64962306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 65062306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 65162306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 65262306a36Sopenharmony_ci CX25840_SVIDEO_ON, 65362306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 65462306a36Sopenharmony_ci .gpio = NULL, 65562306a36Sopenharmony_ci } }, 65662306a36Sopenharmony_ci }, 65762306a36Sopenharmony_ci [CX231XX_BOARD_OTG102] = { 65862306a36Sopenharmony_ci .name = "Geniatech OTG102", 65962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 66062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 66162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 66262306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 66362306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 66462306a36Sopenharmony_ci /* According with PV CxPlrCAP.inf file */ 66562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 66662306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 66762306a36Sopenharmony_ci .no_alt_vanc = 1, 66862306a36Sopenharmony_ci .external_av = 1, 66962306a36Sopenharmony_ci /*.has_417 = 1, */ 67062306a36Sopenharmony_ci /* This board is believed to have a hardware encoding chip 67162306a36Sopenharmony_ci * supporting mpeg1/2/4, but as the 417 is apparently not 67262306a36Sopenharmony_ci * working for the reference board it is not here either. */ 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci .input = {{ 67562306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 67662306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 67762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 67862306a36Sopenharmony_ci .gpio = NULL, 67962306a36Sopenharmony_ci }, { 68062306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 68162306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 68262306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 68362306a36Sopenharmony_ci CX25840_SVIDEO_ON, 68462306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 68562306a36Sopenharmony_ci .gpio = NULL, 68662306a36Sopenharmony_ci } 68762306a36Sopenharmony_ci }, 68862306a36Sopenharmony_ci }, 68962306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx] = { 69062306a36Sopenharmony_ci .name = "Hauppauge WinTV 930C-HD (1113xx) / HVR-900H (111xxx) / PCTV QuatroStick 521e", 69162306a36Sopenharmony_ci .tuner_type = TUNER_NXP_TDA18271, 69262306a36Sopenharmony_ci .tuner_addr = 0x60, 69362306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 69462306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 69562306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 69662306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 69762306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 69862306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 69962306a36Sopenharmony_ci .demod_xfer_mode = 0, 70062306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 70162306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 70262306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 70362306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 70462306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 70562306a36Sopenharmony_ci .has_dvb = 1, 70662306a36Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 70762306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci .input = {{ 71062306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 71162306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 71262306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 71362306a36Sopenharmony_ci .gpio = NULL, 71462306a36Sopenharmony_ci }, { 71562306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 71662306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 71762306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 71862306a36Sopenharmony_ci .gpio = NULL, 71962306a36Sopenharmony_ci }, { 72062306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 72162306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 72262306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 72362306a36Sopenharmony_ci CX25840_SVIDEO_ON, 72462306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 72562306a36Sopenharmony_ci .gpio = NULL, 72662306a36Sopenharmony_ci } }, 72762306a36Sopenharmony_ci }, 72862306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx] = { 72962306a36Sopenharmony_ci .name = "Hauppauge WinTV 930C-HD (1114xx) / HVR-901H (1114xx) / PCTV QuatroStick 522e", 73062306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 73162306a36Sopenharmony_ci .tuner_addr = 0x60, 73262306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 73362306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 73462306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 73562306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 73662306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 73762306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 73862306a36Sopenharmony_ci .demod_xfer_mode = 0, 73962306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 74062306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 74162306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 74262306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 74362306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 74462306a36Sopenharmony_ci .has_dvb = 1, 74562306a36Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 74662306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci .input = {{ 74962306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 75062306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 75162306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 75262306a36Sopenharmony_ci .gpio = NULL, 75362306a36Sopenharmony_ci }, { 75462306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 75562306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 75662306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 75762306a36Sopenharmony_ci .gpio = NULL, 75862306a36Sopenharmony_ci }, { 75962306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 76062306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 76162306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 76262306a36Sopenharmony_ci CX25840_SVIDEO_ON, 76362306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 76462306a36Sopenharmony_ci .gpio = NULL, 76562306a36Sopenharmony_ci } }, 76662306a36Sopenharmony_ci }, 76762306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_955Q] = { 76862306a36Sopenharmony_ci .name = "Hauppauge WinTV-HVR-955Q (111401)", 76962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 77062306a36Sopenharmony_ci .tuner_addr = 0x60, 77162306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 77262306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 77362306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 77462306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 77562306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 77662306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 77762306a36Sopenharmony_ci .demod_xfer_mode = 0, 77862306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 77962306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 78062306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 78162306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 78262306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 78362306a36Sopenharmony_ci .has_dvb = 1, 78462306a36Sopenharmony_ci .demod_addr = 0x59, /* 0xb2 >> 1 */ 78562306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci .input = {{ 78862306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 78962306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 79062306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 79162306a36Sopenharmony_ci .gpio = NULL, 79262306a36Sopenharmony_ci }, { 79362306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 79462306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 79562306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 79662306a36Sopenharmony_ci .gpio = NULL, 79762306a36Sopenharmony_ci }, { 79862306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 79962306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 80062306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 80162306a36Sopenharmony_ci CX25840_SVIDEO_ON, 80262306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 80362306a36Sopenharmony_ci .gpio = NULL, 80462306a36Sopenharmony_ci } }, 80562306a36Sopenharmony_ci }, 80662306a36Sopenharmony_ci [CX231XX_BOARD_TERRATEC_GRABBY] = { 80762306a36Sopenharmony_ci .name = "Terratec Grabby", 80862306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 80962306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 81062306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 81162306a36Sopenharmony_ci .demod_xfer_mode = 0, 81262306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 81362306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 81462306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 81562306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 81662306a36Sopenharmony_ci .no_alt_vanc = 1, 81762306a36Sopenharmony_ci .external_av = 1, 81862306a36Sopenharmony_ci .input = {{ 81962306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 82062306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 82162306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 82262306a36Sopenharmony_ci .gpio = NULL, 82362306a36Sopenharmony_ci }, { 82462306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 82562306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 82662306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 82762306a36Sopenharmony_ci CX25840_SVIDEO_ON, 82862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 82962306a36Sopenharmony_ci .gpio = NULL, 83062306a36Sopenharmony_ci } }, 83162306a36Sopenharmony_ci }, 83262306a36Sopenharmony_ci [CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD] = { 83362306a36Sopenharmony_ci .name = "Evromedia USB Full Hybrid Full HD", 83462306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 83562306a36Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 83662306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 83762306a36Sopenharmony_ci .has_dvb = 1, 83862306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 83962306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 84062306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 84162306a36Sopenharmony_ci .tuner_addr = 0x60, /* 0xc0 >> 1 */ 84262306a36Sopenharmony_ci .tuner_i2c_master = I2C_2, 84362306a36Sopenharmony_ci .input = {{ 84462306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 84562306a36Sopenharmony_ci .vmux = 0, 84662306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 84762306a36Sopenharmony_ci }, { 84862306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 84962306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 85062306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 85162306a36Sopenharmony_ci }, { 85262306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 85362306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 85462306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 85562306a36Sopenharmony_ci CX25840_SVIDEO_ON, 85662306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 85762306a36Sopenharmony_ci } }, 85862306a36Sopenharmony_ci }, 85962306a36Sopenharmony_ci [CX231XX_BOARD_ASTROMETA_T2HYBRID] = { 86062306a36Sopenharmony_ci .name = "Astrometa T2hybrid", 86162306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 86262306a36Sopenharmony_ci .has_dvb = 1, 86362306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 86462306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 86562306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x01, 86662306a36Sopenharmony_ci .ctl_pin_status_mask = 0xffffffc4, 86762306a36Sopenharmony_ci .demod_addr = 0x18, /* 0x30 >> 1 */ 86862306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_1, 86962306a36Sopenharmony_ci .gpio_pin_status_mask = 0xa, 87062306a36Sopenharmony_ci .norm = V4L2_STD_NTSC, 87162306a36Sopenharmony_ci .tuner_addr = 0x3a, /* 0x74 >> 1 */ 87262306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 87362306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 87462306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 87562306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 87662306a36Sopenharmony_ci .input = {{ 87762306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 87862306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1, 87962306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 88062306a36Sopenharmony_ci }, { 88162306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 88262306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 88362306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 88462306a36Sopenharmony_ci }, 88562306a36Sopenharmony_ci }, 88662306a36Sopenharmony_ci }, 88762306a36Sopenharmony_ci [CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO] = { 88862306a36Sopenharmony_ci .name = "The Imaging Source DFG/USB2pro", 88962306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 89062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 89162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 89262306a36Sopenharmony_ci .demod_xfer_mode = 0, 89362306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 89462306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 89562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 89662306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 89762306a36Sopenharmony_ci .no_alt_vanc = 1, 89862306a36Sopenharmony_ci .external_av = 1, 89962306a36Sopenharmony_ci .input = {{ 90062306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 90162306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1, 90262306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 90362306a36Sopenharmony_ci .gpio = NULL, 90462306a36Sopenharmony_ci }, { 90562306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 90662306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1 | 90762306a36Sopenharmony_ci (CX231XX_VIN_2_2 << 8) | 90862306a36Sopenharmony_ci CX25840_SVIDEO_ON, 90962306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 91062306a36Sopenharmony_ci .gpio = NULL, 91162306a36Sopenharmony_ci } }, 91262306a36Sopenharmony_ci }, 91362306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_935C] = { 91462306a36Sopenharmony_ci .name = "Hauppauge WinTV-HVR-935C", 91562306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 91662306a36Sopenharmony_ci .tuner_addr = 0x60, 91762306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 91862306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 91962306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 92062306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 92162306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 92262306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 92362306a36Sopenharmony_ci .demod_xfer_mode = 0, 92462306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 92562306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 92662306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 92762306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 92862306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 92962306a36Sopenharmony_ci .has_dvb = 1, 93062306a36Sopenharmony_ci .demod_addr = 0x64, /* 0xc8 >> 1 */ 93162306a36Sopenharmony_ci .norm = V4L2_STD_PAL, 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci .input = {{ 93462306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 93562306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 93662306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 93762306a36Sopenharmony_ci .gpio = NULL, 93862306a36Sopenharmony_ci }, { 93962306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 94062306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 94162306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 94262306a36Sopenharmony_ci .gpio = NULL, 94362306a36Sopenharmony_ci }, { 94462306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 94562306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 94662306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 94762306a36Sopenharmony_ci CX25840_SVIDEO_ON, 94862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 94962306a36Sopenharmony_ci .gpio = NULL, 95062306a36Sopenharmony_ci } }, 95162306a36Sopenharmony_ci }, 95262306a36Sopenharmony_ci [CX231XX_BOARD_HAUPPAUGE_975] = { 95362306a36Sopenharmony_ci .name = "Hauppauge WinTV-HVR-975", 95462306a36Sopenharmony_ci .tuner_type = TUNER_ABSENT, 95562306a36Sopenharmony_ci .tuner_addr = 0x60, 95662306a36Sopenharmony_ci .tuner_gpio = RDE250_XCV_TUNER, 95762306a36Sopenharmony_ci .tuner_sif_gpio = 0x05, 95862306a36Sopenharmony_ci .tuner_scl_gpio = 0x1a, 95962306a36Sopenharmony_ci .tuner_sda_gpio = 0x1b, 96062306a36Sopenharmony_ci .decoder = CX231XX_AVDECODER, 96162306a36Sopenharmony_ci .output_mode = OUT_MODE_VIP11, 96262306a36Sopenharmony_ci .demod_xfer_mode = 0, 96362306a36Sopenharmony_ci .ctl_pin_status_mask = 0xFFFFFFC4, 96462306a36Sopenharmony_ci .agc_analog_digital_select_gpio = 0x0c, 96562306a36Sopenharmony_ci .gpio_pin_status_mask = 0x4001000, 96662306a36Sopenharmony_ci .tuner_i2c_master = I2C_1_MUX_3, 96762306a36Sopenharmony_ci .demod_i2c_master = I2C_1_MUX_3, 96862306a36Sopenharmony_ci .has_dvb = 1, 96962306a36Sopenharmony_ci .demod_addr = 0x59, /* 0xb2 >> 1 */ 97062306a36Sopenharmony_ci .demod_addr2 = 0x64, /* 0xc8 >> 1 */ 97162306a36Sopenharmony_ci .norm = V4L2_STD_ALL, 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci .input = {{ 97462306a36Sopenharmony_ci .type = CX231XX_VMUX_TELEVISION, 97562306a36Sopenharmony_ci .vmux = CX231XX_VIN_3_1, 97662306a36Sopenharmony_ci .amux = CX231XX_AMUX_VIDEO, 97762306a36Sopenharmony_ci .gpio = NULL, 97862306a36Sopenharmony_ci }, { 97962306a36Sopenharmony_ci .type = CX231XX_VMUX_COMPOSITE1, 98062306a36Sopenharmony_ci .vmux = CX231XX_VIN_2_1, 98162306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 98262306a36Sopenharmony_ci .gpio = NULL, 98362306a36Sopenharmony_ci }, { 98462306a36Sopenharmony_ci .type = CX231XX_VMUX_SVIDEO, 98562306a36Sopenharmony_ci .vmux = CX231XX_VIN_1_1 | 98662306a36Sopenharmony_ci (CX231XX_VIN_1_2 << 8) | 98762306a36Sopenharmony_ci CX25840_SVIDEO_ON, 98862306a36Sopenharmony_ci .amux = CX231XX_AMUX_LINE_IN, 98962306a36Sopenharmony_ci .gpio = NULL, 99062306a36Sopenharmony_ci } }, 99162306a36Sopenharmony_ci }, 99262306a36Sopenharmony_ci}; 99362306a36Sopenharmony_ciconst unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ci/* table of devices that work with this driver */ 99662306a36Sopenharmony_cistruct usb_device_id cx231xx_id_table[] = { 99762306a36Sopenharmony_ci {USB_DEVICE(0x1D19, 0x6109), 99862306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 99962306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x5A3C), 100062306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_UNKNOWN}, 100162306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A2), 100262306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_CARRAERA}, 100362306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A1), 100462306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_SHELBY}, 100562306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A4), 100662306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDE_253S}, 100762306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A5), 100862306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDU_253S}, 100962306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A6), 101062306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, 101162306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x589E), 101262306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDE_250}, 101362306a36Sopenharmony_ci {USB_DEVICE(0x0572, 0x58A0), 101462306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_RDU_250}, 101562306a36Sopenharmony_ci /* AverMedia DVD EZMaker 7 */ 101662306a36Sopenharmony_ci {USB_DEVICE(0x07ca, 0xc039), 101762306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, 101862306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb110), 101962306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL}, 102062306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb111), 102162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, 102262306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb120), 102362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, 102462306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb123), 102562306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, 102662306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb124), 102762306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, 102862306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb151), 102962306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_935C}, 103062306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb150), 103162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_975}, 103262306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb130), 103362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 103462306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb131), 103562306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 103662306a36Sopenharmony_ci /* Hauppauge WinTV-HVR-900-H */ 103762306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb138), 103862306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 103962306a36Sopenharmony_ci /* Hauppauge WinTV-HVR-901-H */ 104062306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb139), 104162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 104262306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xb140), 104362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, 104462306a36Sopenharmony_ci {USB_DEVICE(0x2040, 0xc200), 104562306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, 104662306a36Sopenharmony_ci /* PCTV QuatroStick 521e */ 104762306a36Sopenharmony_ci {USB_DEVICE(0x2013, 0x0259), 104862306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, 104962306a36Sopenharmony_ci /* PCTV QuatroStick 522e */ 105062306a36Sopenharmony_ci {USB_DEVICE(0x2013, 0x025e), 105162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx}, 105262306a36Sopenharmony_ci {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), 105362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 105462306a36Sopenharmony_ci {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014), 105562306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 105662306a36Sopenharmony_ci {USB_DEVICE(0x1b80, 0xe424), 105762306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID}, 105862306a36Sopenharmony_ci {USB_DEVICE(0x1b80, 0xe421), 105962306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_KWORLD_UB445_USB_HYBRID}, 106062306a36Sopenharmony_ci {USB_DEVICE(0x1f4d, 0x0237), 106162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_ICONBIT_U100}, 106262306a36Sopenharmony_ci {USB_DEVICE(0x0fd9, 0x0037), 106362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2}, 106462306a36Sopenharmony_ci {USB_DEVICE(0x1f4d, 0x0102), 106562306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_OTG102}, 106662306a36Sopenharmony_ci {USB_DEVICE(USB_VID_TERRATEC, 0x00a6), 106762306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_TERRATEC_GRABBY}, 106862306a36Sopenharmony_ci {USB_DEVICE(0x1b80, 0xd3b2), 106962306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD}, 107062306a36Sopenharmony_ci {USB_DEVICE(0x15f4, 0x0135), 107162306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_ASTROMETA_T2HYBRID}, 107262306a36Sopenharmony_ci {USB_DEVICE(0x199e, 0x8002), 107362306a36Sopenharmony_ci .driver_info = CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO}, 107462306a36Sopenharmony_ci {}, 107562306a36Sopenharmony_ci}; 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, cx231xx_id_table); 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci/* cx231xx_tuner_callback 108062306a36Sopenharmony_ci * will be used to reset XC5000 tuner using GPIO pin 108162306a36Sopenharmony_ci */ 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ciint cx231xx_tuner_callback(void *ptr, int component, int command, int arg) 108462306a36Sopenharmony_ci{ 108562306a36Sopenharmony_ci int rc = 0; 108662306a36Sopenharmony_ci struct cx231xx *dev = ptr; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci if (dev->tuner_type == TUNER_XC5000) { 108962306a36Sopenharmony_ci if (command == XC5000_TUNER_RESET) { 109062306a36Sopenharmony_ci dev_dbg(dev->dev, 109162306a36Sopenharmony_ci "Tuner CB: RESET: cmd %d : tuner type %d\n", 109262306a36Sopenharmony_ci command, dev->tuner_type); 109362306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 109462306a36Sopenharmony_ci 1); 109562306a36Sopenharmony_ci msleep(10); 109662306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 109762306a36Sopenharmony_ci 0); 109862306a36Sopenharmony_ci msleep(330); 109962306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 110062306a36Sopenharmony_ci 1); 110162306a36Sopenharmony_ci msleep(10); 110262306a36Sopenharmony_ci } 110362306a36Sopenharmony_ci } else if (dev->tuner_type == TUNER_NXP_TDA18271) { 110462306a36Sopenharmony_ci switch (command) { 110562306a36Sopenharmony_ci case TDA18271_CALLBACK_CMD_AGC_ENABLE: 110662306a36Sopenharmony_ci if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID) 110762306a36Sopenharmony_ci rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg); 110862306a36Sopenharmony_ci break; 110962306a36Sopenharmony_ci default: 111062306a36Sopenharmony_ci rc = -EINVAL; 111162306a36Sopenharmony_ci break; 111262306a36Sopenharmony_ci } 111362306a36Sopenharmony_ci } 111462306a36Sopenharmony_ci return rc; 111562306a36Sopenharmony_ci} 111662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(cx231xx_tuner_callback); 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_cistatic void cx231xx_reset_out(struct cx231xx *dev) 111962306a36Sopenharmony_ci{ 112062306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 1); 112162306a36Sopenharmony_ci msleep(200); 112262306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 0); 112362306a36Sopenharmony_ci msleep(200); 112462306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_RESET, 1); 112562306a36Sopenharmony_ci} 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_cistatic void cx231xx_enable_OSC(struct cx231xx *dev) 112862306a36Sopenharmony_ci{ 112962306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1); 113062306a36Sopenharmony_ci} 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_cistatic void cx231xx_sleep_s5h1432(struct cx231xx *dev) 113362306a36Sopenharmony_ci{ 113462306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0); 113562306a36Sopenharmony_ci} 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_cistatic inline void cx231xx_set_model(struct cx231xx *dev) 113862306a36Sopenharmony_ci{ 113962306a36Sopenharmony_ci dev->board = cx231xx_boards[dev->model]; 114062306a36Sopenharmony_ci} 114162306a36Sopenharmony_ci 114262306a36Sopenharmony_ci/* Since cx231xx_pre_card_setup() requires a proper dev->model, 114362306a36Sopenharmony_ci * this won't work for boards with generic PCI IDs 114462306a36Sopenharmony_ci */ 114562306a36Sopenharmony_civoid cx231xx_pre_card_setup(struct cx231xx *dev) 114662306a36Sopenharmony_ci{ 114762306a36Sopenharmony_ci dev_info(dev->dev, "Identified as %s (card=%d)\n", 114862306a36Sopenharmony_ci dev->board.name, dev->model); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci if (CX231XX_BOARD_ASTROMETA_T2HYBRID == dev->model) { 115162306a36Sopenharmony_ci /* turn on demodulator chip */ 115262306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, 0x03, 0x01); 115362306a36Sopenharmony_ci } 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci /* set the direction for GPIO pins */ 115662306a36Sopenharmony_ci if (dev->board.tuner_gpio) { 115762306a36Sopenharmony_ci cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); 115862306a36Sopenharmony_ci cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); 115962306a36Sopenharmony_ci } 116062306a36Sopenharmony_ci if (dev->board.tuner_sif_gpio >= 0) 116162306a36Sopenharmony_ci cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci /* request some modules if any required */ 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci /* set the mode to Analog mode initially */ 116662306a36Sopenharmony_ci cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci /* Unlock device */ 116962306a36Sopenharmony_ci /* cx231xx_set_mode(dev, CX231XX_SUSPEND); */ 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci} 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_cistatic void cx231xx_config_tuner(struct cx231xx *dev) 117462306a36Sopenharmony_ci{ 117562306a36Sopenharmony_ci struct tuner_setup tun_setup; 117662306a36Sopenharmony_ci struct v4l2_frequency f; 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci if (dev->tuner_type == TUNER_ABSENT) 117962306a36Sopenharmony_ci return; 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_ci tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; 118262306a36Sopenharmony_ci tun_setup.type = dev->tuner_type; 118362306a36Sopenharmony_ci tun_setup.addr = dev->tuner_addr; 118462306a36Sopenharmony_ci tun_setup.tuner_callback = cx231xx_tuner_callback; 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ci tuner_call(dev, tuner, s_type_addr, &tun_setup); 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci#if 0 118962306a36Sopenharmony_ci if (tun_setup.type == TUNER_XC5000) { 119062306a36Sopenharmony_ci static struct xc2028_ctrl ctrl = { 119162306a36Sopenharmony_ci .fname = XC5000_DEFAULT_FIRMWARE, 119262306a36Sopenharmony_ci .max_len = 64, 119362306a36Sopenharmony_ci .demod = 0; 119462306a36Sopenharmony_ci }; 119562306a36Sopenharmony_ci struct v4l2_priv_tun_config cfg = { 119662306a36Sopenharmony_ci .tuner = dev->tuner_type, 119762306a36Sopenharmony_ci .priv = &ctrl, 119862306a36Sopenharmony_ci }; 119962306a36Sopenharmony_ci tuner_call(dev, tuner, s_config, &cfg); 120062306a36Sopenharmony_ci } 120162306a36Sopenharmony_ci#endif 120262306a36Sopenharmony_ci /* configure tuner */ 120362306a36Sopenharmony_ci f.tuner = 0; 120462306a36Sopenharmony_ci f.type = V4L2_TUNER_ANALOG_TV; 120562306a36Sopenharmony_ci f.frequency = 9076; /* just a magic number */ 120662306a36Sopenharmony_ci dev->ctl_freq = f.frequency; 120762306a36Sopenharmony_ci call_all(dev, tuner, s_frequency, &f); 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci} 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_cistatic int read_eeprom(struct cx231xx *dev, struct i2c_client *client, 121262306a36Sopenharmony_ci u8 *eedata, int len) 121362306a36Sopenharmony_ci{ 121462306a36Sopenharmony_ci int ret; 121562306a36Sopenharmony_ci u8 start_offset = 0; 121662306a36Sopenharmony_ci int len_todo = len; 121762306a36Sopenharmony_ci u8 *eedata_cur = eedata; 121862306a36Sopenharmony_ci int i; 121962306a36Sopenharmony_ci struct i2c_msg msg_write = { .addr = client->addr, .flags = 0, 122062306a36Sopenharmony_ci .buf = &start_offset, .len = 1 }; 122162306a36Sopenharmony_ci struct i2c_msg msg_read = { .addr = client->addr, .flags = I2C_M_RD }; 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci /* start reading at offset 0 */ 122462306a36Sopenharmony_ci ret = i2c_transfer(client->adapter, &msg_write, 1); 122562306a36Sopenharmony_ci if (ret < 0) { 122662306a36Sopenharmony_ci dev_err(dev->dev, "Can't read eeprom\n"); 122762306a36Sopenharmony_ci return ret; 122862306a36Sopenharmony_ci } 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci while (len_todo > 0) { 123162306a36Sopenharmony_ci msg_read.len = (len_todo > 64) ? 64 : len_todo; 123262306a36Sopenharmony_ci msg_read.buf = eedata_cur; 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci ret = i2c_transfer(client->adapter, &msg_read, 1); 123562306a36Sopenharmony_ci if (ret < 0) { 123662306a36Sopenharmony_ci dev_err(dev->dev, "Can't read eeprom\n"); 123762306a36Sopenharmony_ci return ret; 123862306a36Sopenharmony_ci } 123962306a36Sopenharmony_ci eedata_cur += msg_read.len; 124062306a36Sopenharmony_ci len_todo -= msg_read.len; 124162306a36Sopenharmony_ci } 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci for (i = 0; i + 15 < len; i += 16) 124462306a36Sopenharmony_ci dev_dbg(dev->dev, "i2c eeprom %02x: %*ph\n", 124562306a36Sopenharmony_ci i, 16, &eedata[i]); 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_ci return 0; 124862306a36Sopenharmony_ci} 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_civoid cx231xx_card_setup(struct cx231xx *dev) 125162306a36Sopenharmony_ci{ 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci cx231xx_set_model(dev); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_ci dev->tuner_type = cx231xx_boards[dev->model].tuner_type; 125662306a36Sopenharmony_ci if (cx231xx_boards[dev->model].tuner_addr) 125762306a36Sopenharmony_ci dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr; 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci /* request some modules */ 126062306a36Sopenharmony_ci if (dev->board.decoder == CX231XX_AVDECODER) { 126162306a36Sopenharmony_ci dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 126262306a36Sopenharmony_ci cx231xx_get_i2c_adap(dev, I2C_0), 126362306a36Sopenharmony_ci "cx25840", 0x88 >> 1, NULL); 126462306a36Sopenharmony_ci if (dev->sd_cx25840 == NULL) 126562306a36Sopenharmony_ci dev_err(dev->dev, 126662306a36Sopenharmony_ci "cx25840 subdev registration failure\n"); 126762306a36Sopenharmony_ci cx25840_call(dev, core, load_fw); 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci } 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci /* Initialize the tuner */ 127262306a36Sopenharmony_ci if (dev->board.tuner_type != TUNER_ABSENT) { 127362306a36Sopenharmony_ci struct i2c_adapter *tuner_i2c = cx231xx_get_i2c_adap(dev, 127462306a36Sopenharmony_ci dev->board.tuner_i2c_master); 127562306a36Sopenharmony_ci dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, 127662306a36Sopenharmony_ci tuner_i2c, 127762306a36Sopenharmony_ci "tuner", 127862306a36Sopenharmony_ci dev->tuner_addr, NULL); 127962306a36Sopenharmony_ci if (dev->sd_tuner == NULL) 128062306a36Sopenharmony_ci dev_err(dev->dev, 128162306a36Sopenharmony_ci "tuner subdev registration failure\n"); 128262306a36Sopenharmony_ci else 128362306a36Sopenharmony_ci cx231xx_config_tuner(dev); 128462306a36Sopenharmony_ci } 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci switch (dev->model) { 128762306a36Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: 128862306a36Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: 128962306a36Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_955Q: 129062306a36Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_935C: 129162306a36Sopenharmony_ci case CX231XX_BOARD_HAUPPAUGE_975: 129262306a36Sopenharmony_ci { 129362306a36Sopenharmony_ci struct eeprom { 129462306a36Sopenharmony_ci struct tveeprom tvee; 129562306a36Sopenharmony_ci u8 eeprom[256]; 129662306a36Sopenharmony_ci struct i2c_client client; 129762306a36Sopenharmony_ci }; 129862306a36Sopenharmony_ci struct eeprom *e = kzalloc(sizeof(*e), GFP_KERNEL); 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_ci if (e == NULL) { 130162306a36Sopenharmony_ci dev_err(dev->dev, 130262306a36Sopenharmony_ci "failed to allocate memory to read eeprom\n"); 130362306a36Sopenharmony_ci break; 130462306a36Sopenharmony_ci } 130562306a36Sopenharmony_ci e->client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); 130662306a36Sopenharmony_ci e->client.addr = 0xa0 >> 1; 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom)); 130962306a36Sopenharmony_ci tveeprom_hauppauge_analog(&e->tvee, e->eeprom + 0xc0); 131062306a36Sopenharmony_ci kfree(e); 131162306a36Sopenharmony_ci break; 131262306a36Sopenharmony_ci } 131362306a36Sopenharmony_ci } 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci} 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci/* 131862306a36Sopenharmony_ci * cx231xx_config() 131962306a36Sopenharmony_ci * inits registers with sane defaults 132062306a36Sopenharmony_ci */ 132162306a36Sopenharmony_ciint cx231xx_config(struct cx231xx *dev) 132262306a36Sopenharmony_ci{ 132362306a36Sopenharmony_ci /* TBD need to add cx231xx specific code */ 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci return 0; 132662306a36Sopenharmony_ci} 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci/* 132962306a36Sopenharmony_ci * cx231xx_config_i2c() 133062306a36Sopenharmony_ci * configure i2c attached devices 133162306a36Sopenharmony_ci */ 133262306a36Sopenharmony_civoid cx231xx_config_i2c(struct cx231xx *dev) 133362306a36Sopenharmony_ci{ 133462306a36Sopenharmony_ci /* u32 input = INPUT(dev->video_input)->vmux; */ 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci call_all(dev, video, s_stream, 1); 133762306a36Sopenharmony_ci} 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_cistatic void cx231xx_unregister_media_device(struct cx231xx *dev) 134062306a36Sopenharmony_ci{ 134162306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 134262306a36Sopenharmony_ci if (dev->media_dev) { 134362306a36Sopenharmony_ci media_device_unregister(dev->media_dev); 134462306a36Sopenharmony_ci media_device_cleanup(dev->media_dev); 134562306a36Sopenharmony_ci kfree(dev->media_dev); 134662306a36Sopenharmony_ci dev->media_dev = NULL; 134762306a36Sopenharmony_ci } 134862306a36Sopenharmony_ci#endif 134962306a36Sopenharmony_ci} 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci/* 135262306a36Sopenharmony_ci * cx231xx_realease_resources() 135362306a36Sopenharmony_ci * unregisters the v4l2,i2c and usb devices 135462306a36Sopenharmony_ci * called when the device gets disconnected or at module unload 135562306a36Sopenharmony_ci*/ 135662306a36Sopenharmony_civoid cx231xx_release_resources(struct cx231xx *dev) 135762306a36Sopenharmony_ci{ 135862306a36Sopenharmony_ci cx231xx_ir_exit(dev); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci cx231xx_release_analog_resources(dev); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci cx231xx_remove_from_devlist(dev); 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci /* Release I2C buses */ 136562306a36Sopenharmony_ci cx231xx_dev_uninit(dev); 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci /* delete v4l2 device */ 136862306a36Sopenharmony_ci v4l2_device_unregister(&dev->v4l2_dev); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci cx231xx_unregister_media_device(dev); 137162306a36Sopenharmony_ci 137262306a36Sopenharmony_ci usb_put_dev(dev->udev); 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci /* Mark device as unused */ 137562306a36Sopenharmony_ci clear_bit(dev->devno, &cx231xx_devused); 137662306a36Sopenharmony_ci} 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_cistatic int cx231xx_media_device_init(struct cx231xx *dev, 137962306a36Sopenharmony_ci struct usb_device *udev) 138062306a36Sopenharmony_ci{ 138162306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 138262306a36Sopenharmony_ci struct media_device *mdev; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 138562306a36Sopenharmony_ci if (!mdev) 138662306a36Sopenharmony_ci return -ENOMEM; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci media_device_usb_init(mdev, udev, dev->board.name); 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci dev->media_dev = mdev; 139162306a36Sopenharmony_ci#endif 139262306a36Sopenharmony_ci return 0; 139362306a36Sopenharmony_ci} 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci/* 139662306a36Sopenharmony_ci * cx231xx_init_dev() 139762306a36Sopenharmony_ci * allocates and inits the device structs, registers i2c bus and v4l device 139862306a36Sopenharmony_ci */ 139962306a36Sopenharmony_cistatic int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, 140062306a36Sopenharmony_ci int minor) 140162306a36Sopenharmony_ci{ 140262306a36Sopenharmony_ci int retval = -ENOMEM; 140362306a36Sopenharmony_ci unsigned int maxh, maxw; 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci dev->udev = udev; 140662306a36Sopenharmony_ci mutex_init(&dev->lock); 140762306a36Sopenharmony_ci mutex_init(&dev->ctrl_urb_lock); 140862306a36Sopenharmony_ci mutex_init(&dev->gpio_i2c_lock); 140962306a36Sopenharmony_ci mutex_init(&dev->i2c_lock); 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci spin_lock_init(&dev->video_mode.slock); 141262306a36Sopenharmony_ci spin_lock_init(&dev->vbi_mode.slock); 141362306a36Sopenharmony_ci spin_lock_init(&dev->sliced_cc_mode.slock); 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci init_waitqueue_head(&dev->open); 141662306a36Sopenharmony_ci init_waitqueue_head(&dev->wait_frame); 141762306a36Sopenharmony_ci init_waitqueue_head(&dev->wait_stream); 141862306a36Sopenharmony_ci 141962306a36Sopenharmony_ci dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg; 142062306a36Sopenharmony_ci dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg; 142162306a36Sopenharmony_ci dev->cx231xx_send_usb_command = cx231xx_send_usb_command; 142262306a36Sopenharmony_ci dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read; 142362306a36Sopenharmony_ci dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write; 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci /* Query cx231xx to find what pcb config it is related to */ 142662306a36Sopenharmony_ci retval = initialize_cx231xx(dev); 142762306a36Sopenharmony_ci if (retval < 0) { 142862306a36Sopenharmony_ci dev_err(dev->dev, "Failed to read PCB config\n"); 142962306a36Sopenharmony_ci return retval; 143062306a36Sopenharmony_ci } 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci /*To workaround error number=-71 on EP0 for VideoGrabber, 143362306a36Sopenharmony_ci need set alt here.*/ 143462306a36Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 143562306a36Sopenharmony_ci dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) { 143662306a36Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); 143762306a36Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VANC, 1); 143862306a36Sopenharmony_ci } 143962306a36Sopenharmony_ci /* Cx231xx pre card setup */ 144062306a36Sopenharmony_ci cx231xx_pre_card_setup(dev); 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci retval = cx231xx_config(dev); 144362306a36Sopenharmony_ci if (retval) { 144462306a36Sopenharmony_ci dev_err(dev->dev, "error configuring device\n"); 144562306a36Sopenharmony_ci return -ENOMEM; 144662306a36Sopenharmony_ci } 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci /* set default norm */ 144962306a36Sopenharmony_ci dev->norm = dev->board.norm; 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci /* register i2c bus */ 145262306a36Sopenharmony_ci retval = cx231xx_dev_init(dev); 145362306a36Sopenharmony_ci if (retval) { 145462306a36Sopenharmony_ci dev_err(dev->dev, 145562306a36Sopenharmony_ci "%s: cx231xx_i2c_register - errCode [%d]!\n", 145662306a36Sopenharmony_ci __func__, retval); 145762306a36Sopenharmony_ci goto err_dev_init; 145862306a36Sopenharmony_ci } 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* Do board specific init */ 146162306a36Sopenharmony_ci cx231xx_card_setup(dev); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci /* configure the device */ 146462306a36Sopenharmony_ci cx231xx_config_i2c(dev); 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci maxw = norm_maxw(dev); 146762306a36Sopenharmony_ci maxh = norm_maxh(dev); 146862306a36Sopenharmony_ci 146962306a36Sopenharmony_ci /* set default image size */ 147062306a36Sopenharmony_ci dev->width = maxw; 147162306a36Sopenharmony_ci dev->height = maxh; 147262306a36Sopenharmony_ci dev->interlaced = 0; 147362306a36Sopenharmony_ci dev->video_input = 0; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci retval = cx231xx_config(dev); 147662306a36Sopenharmony_ci if (retval) { 147762306a36Sopenharmony_ci dev_err(dev->dev, "%s: cx231xx_config - errCode [%d]!\n", 147862306a36Sopenharmony_ci __func__, retval); 147962306a36Sopenharmony_ci goto err_dev_init; 148062306a36Sopenharmony_ci } 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci /* init video dma queue */ 148362306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->video_mode.vidq.active); 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci /* init vbi dma queue */ 148662306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->vbi_mode.vidq.active); 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci /* Reset other chips required if they are tied up with GPIO pins */ 148962306a36Sopenharmony_ci cx231xx_add_into_devlist(dev); 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci if (dev->board.has_417) { 149262306a36Sopenharmony_ci dev_info(dev->dev, "attach 417 %d\n", dev->model); 149362306a36Sopenharmony_ci if (cx231xx_417_register(dev) < 0) { 149462306a36Sopenharmony_ci dev_err(dev->dev, 149562306a36Sopenharmony_ci "%s() Failed to register 417 on VID_B\n", 149662306a36Sopenharmony_ci __func__); 149762306a36Sopenharmony_ci } 149862306a36Sopenharmony_ci } 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci retval = cx231xx_register_analog_devices(dev); 150162306a36Sopenharmony_ci if (retval) 150262306a36Sopenharmony_ci goto err_analog; 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci cx231xx_ir_init(dev); 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci cx231xx_init_extension(dev); 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ci return 0; 150962306a36Sopenharmony_cierr_analog: 151062306a36Sopenharmony_ci cx231xx_unregister_media_device(dev); 151162306a36Sopenharmony_ci cx231xx_release_analog_resources(dev); 151262306a36Sopenharmony_ci cx231xx_remove_from_devlist(dev); 151362306a36Sopenharmony_cierr_dev_init: 151462306a36Sopenharmony_ci cx231xx_dev_uninit(dev); 151562306a36Sopenharmony_ci return retval; 151662306a36Sopenharmony_ci} 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE) 151962306a36Sopenharmony_cistatic void request_module_async(struct work_struct *work) 152062306a36Sopenharmony_ci{ 152162306a36Sopenharmony_ci struct cx231xx *dev = container_of(work, 152262306a36Sopenharmony_ci struct cx231xx, request_module_wk); 152362306a36Sopenharmony_ci 152462306a36Sopenharmony_ci if (dev->has_alsa_audio) 152562306a36Sopenharmony_ci request_module("cx231xx-alsa"); 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci if (dev->board.has_dvb) 152862306a36Sopenharmony_ci request_module("cx231xx-dvb"); 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci} 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_cistatic void request_modules(struct cx231xx *dev) 153362306a36Sopenharmony_ci{ 153462306a36Sopenharmony_ci INIT_WORK(&dev->request_module_wk, request_module_async); 153562306a36Sopenharmony_ci schedule_work(&dev->request_module_wk); 153662306a36Sopenharmony_ci} 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_cistatic void flush_request_modules(struct cx231xx *dev) 153962306a36Sopenharmony_ci{ 154062306a36Sopenharmony_ci flush_work(&dev->request_module_wk); 154162306a36Sopenharmony_ci} 154262306a36Sopenharmony_ci#else 154362306a36Sopenharmony_ci#define request_modules(dev) 154462306a36Sopenharmony_ci#define flush_request_modules(dev) 154562306a36Sopenharmony_ci#endif /* CONFIG_MODULES */ 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_cistatic int cx231xx_init_v4l2(struct cx231xx *dev, 154862306a36Sopenharmony_ci struct usb_device *udev, 154962306a36Sopenharmony_ci struct usb_interface *interface, 155062306a36Sopenharmony_ci int isoc_pipe) 155162306a36Sopenharmony_ci{ 155262306a36Sopenharmony_ci struct usb_interface *uif; 155362306a36Sopenharmony_ci int i, idx; 155462306a36Sopenharmony_ci 155562306a36Sopenharmony_ci /* Video Init */ 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci /* compute alternate max packet sizes for video */ 155862306a36Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; 155962306a36Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 156062306a36Sopenharmony_ci dev_err(dev->dev, 156162306a36Sopenharmony_ci "Video PCB interface #%d doesn't exist\n", idx); 156262306a36Sopenharmony_ci return -ENODEV; 156362306a36Sopenharmony_ci } 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci uif = udev->actconfig->interface[idx]; 156662306a36Sopenharmony_ci 156762306a36Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 156862306a36Sopenharmony_ci return -ENODEV; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; 157162306a36Sopenharmony_ci dev->video_mode.num_alt = uif->num_altsetting; 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci dev_info(dev->dev, 157462306a36Sopenharmony_ci "video EndPoint Addr 0x%x, Alternate settings: %i\n", 157562306a36Sopenharmony_ci dev->video_mode.end_point_addr, 157662306a36Sopenharmony_ci dev->video_mode.num_alt); 157762306a36Sopenharmony_ci 157862306a36Sopenharmony_ci dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); 157962306a36Sopenharmony_ci if (dev->video_mode.alt_max_pkt_size == NULL) 158062306a36Sopenharmony_ci return -ENOMEM; 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci for (i = 0; i < dev->video_mode.num_alt; i++) { 158362306a36Sopenharmony_ci u16 tmp; 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 158662306a36Sopenharmony_ci return -ENODEV; 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); 158962306a36Sopenharmony_ci dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 159062306a36Sopenharmony_ci dev_dbg(dev->dev, 159162306a36Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 159262306a36Sopenharmony_ci dev->video_mode.alt_max_pkt_size[i]); 159362306a36Sopenharmony_ci } 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_ci /* VBI Init */ 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; 159862306a36Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 159962306a36Sopenharmony_ci dev_err(dev->dev, 160062306a36Sopenharmony_ci "VBI PCB interface #%d doesn't exist\n", idx); 160162306a36Sopenharmony_ci return -ENODEV; 160262306a36Sopenharmony_ci } 160362306a36Sopenharmony_ci uif = udev->actconfig->interface[idx]; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 160662306a36Sopenharmony_ci return -ENODEV; 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci dev->vbi_mode.end_point_addr = 160962306a36Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe].desc. 161062306a36Sopenharmony_ci bEndpointAddress; 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci dev->vbi_mode.num_alt = uif->num_altsetting; 161362306a36Sopenharmony_ci dev_info(dev->dev, 161462306a36Sopenharmony_ci "VBI EndPoint Addr 0x%x, Alternate settings: %i\n", 161562306a36Sopenharmony_ci dev->vbi_mode.end_point_addr, 161662306a36Sopenharmony_ci dev->vbi_mode.num_alt); 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci /* compute alternate max packet sizes for vbi */ 161962306a36Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); 162062306a36Sopenharmony_ci if (dev->vbi_mode.alt_max_pkt_size == NULL) 162162306a36Sopenharmony_ci return -ENOMEM; 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci for (i = 0; i < dev->vbi_mode.num_alt; i++) { 162462306a36Sopenharmony_ci u16 tmp; 162562306a36Sopenharmony_ci 162662306a36Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 162762306a36Sopenharmony_ci return -ENODEV; 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 163062306a36Sopenharmony_ci desc.wMaxPacketSize); 163162306a36Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size[i] = 163262306a36Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 163362306a36Sopenharmony_ci dev_dbg(dev->dev, 163462306a36Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 163562306a36Sopenharmony_ci dev->vbi_mode.alt_max_pkt_size[i]); 163662306a36Sopenharmony_ci } 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci /* Sliced CC VBI init */ 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ci /* compute alternate max packet sizes for sliced CC */ 164162306a36Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; 164262306a36Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 164362306a36Sopenharmony_ci dev_err(dev->dev, 164462306a36Sopenharmony_ci "Sliced CC PCB interface #%d doesn't exist\n", idx); 164562306a36Sopenharmony_ci return -ENODEV; 164662306a36Sopenharmony_ci } 164762306a36Sopenharmony_ci uif = udev->actconfig->interface[idx]; 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) 165062306a36Sopenharmony_ci return -ENODEV; 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci dev->sliced_cc_mode.end_point_addr = 165362306a36Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe].desc. 165462306a36Sopenharmony_ci bEndpointAddress; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci dev->sliced_cc_mode.num_alt = uif->num_altsetting; 165762306a36Sopenharmony_ci dev_info(dev->dev, 165862306a36Sopenharmony_ci "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", 165962306a36Sopenharmony_ci dev->sliced_cc_mode.end_point_addr, 166062306a36Sopenharmony_ci dev->sliced_cc_mode.num_alt); 166162306a36Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); 166262306a36Sopenharmony_ci if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) 166362306a36Sopenharmony_ci return -ENOMEM; 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { 166662306a36Sopenharmony_ci u16 tmp; 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) 166962306a36Sopenharmony_ci return -ENODEV; 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 167262306a36Sopenharmony_ci desc.wMaxPacketSize); 167362306a36Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size[i] = 167462306a36Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 167562306a36Sopenharmony_ci dev_dbg(dev->dev, 167662306a36Sopenharmony_ci "Alternate setting %i, max size= %i\n", i, 167762306a36Sopenharmony_ci dev->sliced_cc_mode.alt_max_pkt_size[i]); 167862306a36Sopenharmony_ci } 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci return 0; 168162306a36Sopenharmony_ci} 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci/* 168462306a36Sopenharmony_ci * cx231xx_usb_probe() 168562306a36Sopenharmony_ci * checks for supported devices 168662306a36Sopenharmony_ci */ 168762306a36Sopenharmony_cistatic int cx231xx_usb_probe(struct usb_interface *interface, 168862306a36Sopenharmony_ci const struct usb_device_id *id) 168962306a36Sopenharmony_ci{ 169062306a36Sopenharmony_ci struct usb_device *udev; 169162306a36Sopenharmony_ci struct device *d = &interface->dev; 169262306a36Sopenharmony_ci struct usb_interface *uif; 169362306a36Sopenharmony_ci struct cx231xx *dev = NULL; 169462306a36Sopenharmony_ci int retval = -ENODEV; 169562306a36Sopenharmony_ci int nr = 0, ifnum; 169662306a36Sopenharmony_ci int i, isoc_pipe = 0; 169762306a36Sopenharmony_ci char *speed; 169862306a36Sopenharmony_ci u8 idx; 169962306a36Sopenharmony_ci struct usb_interface_assoc_descriptor *assoc_desc; 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci ifnum = interface->altsetting[0].desc.bInterfaceNumber; 170262306a36Sopenharmony_ci 170362306a36Sopenharmony_ci /* 170462306a36Sopenharmony_ci * Interface number 0 - IR interface (handled by mceusb driver) 170562306a36Sopenharmony_ci * Interface number 1 - AV interface (handled by this driver) 170662306a36Sopenharmony_ci */ 170762306a36Sopenharmony_ci if (ifnum != 1) 170862306a36Sopenharmony_ci return -ENODEV; 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci /* Check to see next free device and mark as used */ 171162306a36Sopenharmony_ci do { 171262306a36Sopenharmony_ci nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); 171362306a36Sopenharmony_ci if (nr >= CX231XX_MAXBOARDS) { 171462306a36Sopenharmony_ci /* No free device slots */ 171562306a36Sopenharmony_ci dev_err(d, 171662306a36Sopenharmony_ci "Supports only %i devices.\n", 171762306a36Sopenharmony_ci CX231XX_MAXBOARDS); 171862306a36Sopenharmony_ci return -ENOMEM; 171962306a36Sopenharmony_ci } 172062306a36Sopenharmony_ci } while (test_and_set_bit(nr, &cx231xx_devused)); 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci udev = usb_get_dev(interface_to_usbdev(interface)); 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci /* allocate memory for our device state and initialize it */ 172562306a36Sopenharmony_ci dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); 172662306a36Sopenharmony_ci if (dev == NULL) { 172762306a36Sopenharmony_ci retval = -ENOMEM; 172862306a36Sopenharmony_ci goto err_if; 172962306a36Sopenharmony_ci } 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci snprintf(dev->name, 29, "cx231xx #%d", nr); 173262306a36Sopenharmony_ci dev->devno = nr; 173362306a36Sopenharmony_ci dev->model = id->driver_info; 173462306a36Sopenharmony_ci dev->video_mode.alt = -1; 173562306a36Sopenharmony_ci dev->dev = d; 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_ci cx231xx_set_model(dev); 173862306a36Sopenharmony_ci 173962306a36Sopenharmony_ci dev->interface_count++; 174062306a36Sopenharmony_ci /* reset gpio dir and value */ 174162306a36Sopenharmony_ci dev->gpio_dir = 0; 174262306a36Sopenharmony_ci dev->gpio_val = 0; 174362306a36Sopenharmony_ci dev->xc_fw_load_done = 0; 174462306a36Sopenharmony_ci dev->has_alsa_audio = 1; 174562306a36Sopenharmony_ci dev->power_mode = -1; 174662306a36Sopenharmony_ci atomic_set(&dev->devlist_count, 0); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci /* 0 - vbi ; 1 -sliced cc mode */ 174962306a36Sopenharmony_ci dev->vbi_or_sliced_cc_mode = 0; 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci /* get maximum no.of IAD interfaces */ 175262306a36Sopenharmony_ci dev->max_iad_interface_count = udev->config->desc.bNumInterfaces; 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci /* init CIR module TBD */ 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ci /*mode_tv: digital=1 or analog=0*/ 175762306a36Sopenharmony_ci dev->mode_tv = 0; 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci dev->USE_ISO = transfer_mode; 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ci switch (udev->speed) { 176262306a36Sopenharmony_ci case USB_SPEED_LOW: 176362306a36Sopenharmony_ci speed = "1.5"; 176462306a36Sopenharmony_ci break; 176562306a36Sopenharmony_ci case USB_SPEED_UNKNOWN: 176662306a36Sopenharmony_ci case USB_SPEED_FULL: 176762306a36Sopenharmony_ci speed = "12"; 176862306a36Sopenharmony_ci break; 176962306a36Sopenharmony_ci case USB_SPEED_HIGH: 177062306a36Sopenharmony_ci speed = "480"; 177162306a36Sopenharmony_ci break; 177262306a36Sopenharmony_ci default: 177362306a36Sopenharmony_ci speed = "unknown"; 177462306a36Sopenharmony_ci } 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_ci dev_info(d, 177762306a36Sopenharmony_ci "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", 177862306a36Sopenharmony_ci udev->manufacturer ? udev->manufacturer : "", 177962306a36Sopenharmony_ci udev->product ? udev->product : "", 178062306a36Sopenharmony_ci speed, 178162306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.idVendor), 178262306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct), 178362306a36Sopenharmony_ci dev->max_iad_interface_count); 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci /* increment interface count */ 178662306a36Sopenharmony_ci dev->interface_count++; 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci /* get device number */ 178962306a36Sopenharmony_ci nr = dev->devno; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci assoc_desc = udev->actconfig->intf_assoc[0]; 179262306a36Sopenharmony_ci if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) { 179362306a36Sopenharmony_ci dev_err(d, "Not found matching IAD interface\n"); 179462306a36Sopenharmony_ci retval = -ENODEV; 179562306a36Sopenharmony_ci goto err_if; 179662306a36Sopenharmony_ci } 179762306a36Sopenharmony_ci 179862306a36Sopenharmony_ci dev_dbg(d, "registering interface %d\n", ifnum); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci /* save our data pointer in this interface device */ 180162306a36Sopenharmony_ci usb_set_intfdata(interface, dev); 180262306a36Sopenharmony_ci 180362306a36Sopenharmony_ci /* Initialize the media controller */ 180462306a36Sopenharmony_ci retval = cx231xx_media_device_init(dev, udev); 180562306a36Sopenharmony_ci if (retval) { 180662306a36Sopenharmony_ci dev_err(d, "cx231xx_media_device_init failed\n"); 180762306a36Sopenharmony_ci goto err_media_init; 180862306a36Sopenharmony_ci } 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci /* Create v4l2 device */ 181162306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 181262306a36Sopenharmony_ci dev->v4l2_dev.mdev = dev->media_dev; 181362306a36Sopenharmony_ci#endif 181462306a36Sopenharmony_ci retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); 181562306a36Sopenharmony_ci if (retval) { 181662306a36Sopenharmony_ci dev_err(d, "v4l2_device_register failed\n"); 181762306a36Sopenharmony_ci goto err_v4l2; 181862306a36Sopenharmony_ci } 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci /* allocate device struct */ 182162306a36Sopenharmony_ci retval = cx231xx_init_dev(dev, udev, nr); 182262306a36Sopenharmony_ci if (retval) 182362306a36Sopenharmony_ci goto err_init; 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe); 182662306a36Sopenharmony_ci if (retval) 182762306a36Sopenharmony_ci goto err_init; 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci if (dev->current_pcb_config.ts1_source != 0xff) { 183062306a36Sopenharmony_ci /* compute alternate max packet sizes for TS1 */ 183162306a36Sopenharmony_ci idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; 183262306a36Sopenharmony_ci if (idx >= dev->max_iad_interface_count) { 183362306a36Sopenharmony_ci dev_err(d, "TS1 PCB interface #%d doesn't exist\n", 183462306a36Sopenharmony_ci idx); 183562306a36Sopenharmony_ci retval = -ENODEV; 183662306a36Sopenharmony_ci goto err_video_alt; 183762306a36Sopenharmony_ci } 183862306a36Sopenharmony_ci uif = udev->actconfig->interface[idx]; 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) { 184162306a36Sopenharmony_ci retval = -ENODEV; 184262306a36Sopenharmony_ci goto err_video_alt; 184362306a36Sopenharmony_ci } 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci dev->ts1_mode.end_point_addr = 184662306a36Sopenharmony_ci uif->altsetting[0].endpoint[isoc_pipe]. 184762306a36Sopenharmony_ci desc.bEndpointAddress; 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci dev->ts1_mode.num_alt = uif->num_altsetting; 185062306a36Sopenharmony_ci dev_info(d, 185162306a36Sopenharmony_ci "TS EndPoint Addr 0x%x, Alternate settings: %i\n", 185262306a36Sopenharmony_ci dev->ts1_mode.end_point_addr, 185362306a36Sopenharmony_ci dev->ts1_mode.num_alt); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); 185662306a36Sopenharmony_ci if (dev->ts1_mode.alt_max_pkt_size == NULL) { 185762306a36Sopenharmony_ci retval = -ENOMEM; 185862306a36Sopenharmony_ci goto err_video_alt; 185962306a36Sopenharmony_ci } 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci for (i = 0; i < dev->ts1_mode.num_alt; i++) { 186262306a36Sopenharmony_ci u16 tmp; 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_ci if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) { 186562306a36Sopenharmony_ci retval = -ENODEV; 186662306a36Sopenharmony_ci goto err_video_alt; 186762306a36Sopenharmony_ci } 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ci tmp = le16_to_cpu(uif->altsetting[i]. 187062306a36Sopenharmony_ci endpoint[isoc_pipe].desc. 187162306a36Sopenharmony_ci wMaxPacketSize); 187262306a36Sopenharmony_ci dev->ts1_mode.alt_max_pkt_size[i] = 187362306a36Sopenharmony_ci (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 187462306a36Sopenharmony_ci dev_dbg(d, "Alternate setting %i, max size= %i\n", 187562306a36Sopenharmony_ci i, dev->ts1_mode.alt_max_pkt_size[i]); 187662306a36Sopenharmony_ci } 187762306a36Sopenharmony_ci } 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 188062306a36Sopenharmony_ci cx231xx_enable_OSC(dev); 188162306a36Sopenharmony_ci cx231xx_reset_out(dev); 188262306a36Sopenharmony_ci cx231xx_set_alt_setting(dev, INDEX_VIDEO, 3); 188362306a36Sopenharmony_ci } 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci if (dev->model == CX231XX_BOARD_CNXT_RDE_253S) 188662306a36Sopenharmony_ci cx231xx_sleep_s5h1432(dev); 188762306a36Sopenharmony_ci 188862306a36Sopenharmony_ci /* load other modules required */ 188962306a36Sopenharmony_ci request_modules(dev); 189062306a36Sopenharmony_ci 189162306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 189262306a36Sopenharmony_ci /* Init entities at the Media Controller */ 189362306a36Sopenharmony_ci cx231xx_v4l2_create_entities(dev); 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci retval = v4l2_mc_create_media_graph(dev->media_dev); 189662306a36Sopenharmony_ci if (!retval) 189762306a36Sopenharmony_ci retval = media_device_register(dev->media_dev); 189862306a36Sopenharmony_ci#endif 189962306a36Sopenharmony_ci if (retval < 0) 190062306a36Sopenharmony_ci cx231xx_release_resources(dev); 190162306a36Sopenharmony_ci return retval; 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_cierr_video_alt: 190462306a36Sopenharmony_ci /* cx231xx_uninit_dev: */ 190562306a36Sopenharmony_ci cx231xx_close_extension(dev); 190662306a36Sopenharmony_ci cx231xx_ir_exit(dev); 190762306a36Sopenharmony_ci cx231xx_release_analog_resources(dev); 190862306a36Sopenharmony_ci cx231xx_417_unregister(dev); 190962306a36Sopenharmony_ci cx231xx_remove_from_devlist(dev); 191062306a36Sopenharmony_ci cx231xx_dev_uninit(dev); 191162306a36Sopenharmony_cierr_init: 191262306a36Sopenharmony_ci v4l2_device_unregister(&dev->v4l2_dev); 191362306a36Sopenharmony_cierr_v4l2: 191462306a36Sopenharmony_ci cx231xx_unregister_media_device(dev); 191562306a36Sopenharmony_cierr_media_init: 191662306a36Sopenharmony_ci usb_set_intfdata(interface, NULL); 191762306a36Sopenharmony_cierr_if: 191862306a36Sopenharmony_ci usb_put_dev(udev); 191962306a36Sopenharmony_ci clear_bit(nr, &cx231xx_devused); 192062306a36Sopenharmony_ci return retval; 192162306a36Sopenharmony_ci} 192262306a36Sopenharmony_ci 192362306a36Sopenharmony_ci/* 192462306a36Sopenharmony_ci * cx231xx_usb_disconnect() 192562306a36Sopenharmony_ci * called when the device gets disconnected 192662306a36Sopenharmony_ci * video device will be unregistered on v4l2_close in case it is still open 192762306a36Sopenharmony_ci */ 192862306a36Sopenharmony_cistatic void cx231xx_usb_disconnect(struct usb_interface *interface) 192962306a36Sopenharmony_ci{ 193062306a36Sopenharmony_ci struct cx231xx *dev; 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci dev = usb_get_intfdata(interface); 193362306a36Sopenharmony_ci usb_set_intfdata(interface, NULL); 193462306a36Sopenharmony_ci 193562306a36Sopenharmony_ci if (!dev) 193662306a36Sopenharmony_ci return; 193762306a36Sopenharmony_ci 193862306a36Sopenharmony_ci if (!dev->udev) 193962306a36Sopenharmony_ci return; 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci dev->state |= DEV_DISCONNECTED; 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci flush_request_modules(dev); 194462306a36Sopenharmony_ci 194562306a36Sopenharmony_ci /* wait until all current v4l2 io is finished then deallocate 194662306a36Sopenharmony_ci resources */ 194762306a36Sopenharmony_ci mutex_lock(&dev->lock); 194862306a36Sopenharmony_ci 194962306a36Sopenharmony_ci wake_up_interruptible_all(&dev->open); 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci if (dev->users) { 195262306a36Sopenharmony_ci dev_warn(dev->dev, 195362306a36Sopenharmony_ci "device %s is open! Deregistration and memory deallocation are deferred on close.\n", 195462306a36Sopenharmony_ci video_device_node_name(&dev->vdev)); 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci /* Even having users, it is safe to remove the RC i2c driver */ 195762306a36Sopenharmony_ci cx231xx_ir_exit(dev); 195862306a36Sopenharmony_ci 195962306a36Sopenharmony_ci if (dev->USE_ISO) 196062306a36Sopenharmony_ci cx231xx_uninit_isoc(dev); 196162306a36Sopenharmony_ci else 196262306a36Sopenharmony_ci cx231xx_uninit_bulk(dev); 196362306a36Sopenharmony_ci wake_up_interruptible(&dev->wait_frame); 196462306a36Sopenharmony_ci wake_up_interruptible(&dev->wait_stream); 196562306a36Sopenharmony_ci } else { 196662306a36Sopenharmony_ci } 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci cx231xx_close_extension(dev); 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_ci mutex_unlock(&dev->lock); 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_ci if (!dev->users) 197362306a36Sopenharmony_ci cx231xx_release_resources(dev); 197462306a36Sopenharmony_ci} 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_cistatic struct usb_driver cx231xx_usb_driver = { 197762306a36Sopenharmony_ci .name = "cx231xx", 197862306a36Sopenharmony_ci .probe = cx231xx_usb_probe, 197962306a36Sopenharmony_ci .disconnect = cx231xx_usb_disconnect, 198062306a36Sopenharmony_ci .id_table = cx231xx_id_table, 198162306a36Sopenharmony_ci}; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_cimodule_usb_driver(cx231xx_usb_driver); 1984