/* * Driver for the Conexant CX23885 PCIe bridge * * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/init.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/delay.h> #include <media/cx25840.h> #include <linux/firmware.h> #include <misc/altera.h> #include "cx23885.h" #include "tuner-xc2028.h" #include "netup-eeprom.h" #include "netup-init.h" #include "altera-ci.h" #include "xc4000.h" #include "xc5000.h" #include "cx23888-ir.h" static unsigned int netup_card_rev = 4; module_param(netup_card_rev, int, 0644); MODULE_PARM_DESC(netup_card_rev, "NetUP Dual DVB-T/C CI card revision"); static unsigned int enable_885_ir; module_param(enable_885_ir, int, 0644); MODULE_PARM_DESC(enable_885_ir, "Enable integrated IR controller for supported\n" "\t\t CX2388[57] boards that are wired for it:\n" "\t\t\tHVR-1250 (reported safe)\n" "\t\t\tTerraTec Cinergy T PCIe Dual (not well tested, appears to be safe)\n" "\t\t\tTeVii S470 (reported unsafe)\n" "\t\t This can cause an interrupt storm with some cards.\n" "\t\t Default: 0 [Disabled]"); /* ------------------------------------------------------------------ */ /* board config info */ struct cx23885_board cx23885_boards[] = { [CX23885_BOARD_UNKNOWN] = { .name = "UNKNOWN/GENERIC", /* Ensure safe default for unknown boards */ .clk_freq = 0, .input = {{ .type = CX23885_VMUX_COMPOSITE1, .vmux = 0, }, { .type = CX23885_VMUX_COMPOSITE2, .vmux = 1, }, { .type = CX23885_VMUX_COMPOSITE3, .vmux = 2, }, { .type = CX23885_VMUX_COMPOSITE4, .vmux = 3, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { .name = "Hauppauge WinTV-HVR1800lp", .portc = CX23885_MPEG_DVB, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0xff00, }, { .type = CX23885_VMUX_DEBUG, .vmux = 0, .gpio0 = 0xff01, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0xff02, }, { .type = CX23885_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0xff02, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1800] = { .name = "Hauppauge WinTV-HVR1800", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_ENCODER, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x42, /* 0x84 >> 1 */ .tuner_bus = 1, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1, .amux = CX25840_AUDIO8, .gpio0 = 0, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .amux = CX25840_AUDIO7, .gpio0 = 0, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO7, .gpio0 = 0, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1250] = { .name = "Hauppauge WinTV-HVR1250", .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, #ifdef MT2131_NO_ANALOG_SUPPORT_YET .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x42, /* 0x84 >> 1 */ .tuner_bus = 1, #endif .force_bff = 1, .input = {{ #ifdef MT2131_NO_ANALOG_SUPPORT_YET .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1, .amux = CX25840_AUDIO8, .gpio0 = 0xff00, }, { #endif .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .amux = CX25840_AUDIO7, .gpio0 = 0xff02, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO7, .gpio0 = 0xff02, } }, }, [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { .name = "DViCO FusionHDTV5 Express", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = { .name = "Hauppauge WinTV-HVR1500Q", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1500] = { .name = "Hauppauge WinTV-HVR1500", .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, /* 0xc2 >> 1 */ .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1, .gpio0 = 0, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .gpio0 = 0, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .gpio0 = 0, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1200] = { .name = "Hauppauge WinTV-HVR1200", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1700] = { .name = "Hauppauge WinTV-HVR1700", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1400] = { .name = "Hauppauge WinTV-HVR1400", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { .name = "DViCO FusionHDTV7 Dual Express", .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = { .name = "DViCO FusionHDTV DVB-T Dual Express", .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H] = { .name = "Leadtek Winfast PxDVR3200 H", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = { .name = "Leadtek Winfast PxDVR3200 H XC4000", .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_XC4000, .tuner_addr = 0x61, .radio_type = UNSET, .radio_addr = ADDR_UNSET, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN2_CH1 | CX25840_VIN5_CH2 | CX25840_NONE0_CH3, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE1, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_VIN7_CH1 | CX25840_VIN6_CH2 | CX25840_VIN8_CH3 | CX25840_COMPONENT_ON, } }, }, [CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = { .name = "Compro VideoMate E650F", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_TBS_6920] = { .name = "TurboSight TBS 6920", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_TEVII_S470] = { .name = "TeVii S470", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_DVBWORLD_2005] = { .name = "DVBWorld DVB-S2 2005", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { .ci_type = 1, .name = "NetUP Dual DVB-S2 CI", .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1270] = { .name = "Hauppauge WinTV-HVR1270", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1275] = { .name = "Hauppauge WinTV-HVR1275", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1255] = { .name = "Hauppauge WinTV-HVR1255", .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_ABSENT, .tuner_addr = 0x42, /* 0x84 >> 1 */ .force_bff = 1, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1 | CX25840_DIF_ON, .amux = CX25840_AUDIO8, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .amux = CX25840_AUDIO7, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO7, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1255_22111] = { .name = "Hauppauge WinTV-HVR1255", .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_ABSENT, .tuner_addr = 0x42, /* 0x84 >> 1 */ .force_bff = 1, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1 | CX25840_DIF_ON, .amux = CX25840_AUDIO8, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO7, } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1210] = { .name = "Hauppauge WinTV-HVR1210", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_MYGICA_X8506] = { .name = "Mygica X8506 DMB-TH", .tuner_type = TUNER_XC5000, .tuner_addr = 0x61, .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .input = { { .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_COMPOSITE2, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE8, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_COMPONENT_ON | CX25840_VIN1_CH1 | CX25840_VIN6_CH2 | CX25840_VIN7_CH3, }, }, }, [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { .name = "Magic-Pro ProHDTV Extreme 2", .tuner_type = TUNER_XC5000, .tuner_addr = 0x61, .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .input = { { .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_COMPOSITE2, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE8, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_COMPONENT_ON | CX25840_VIN1_CH1 | CX25840_VIN6_CH2 | CX25840_VIN7_CH3, }, }, }, [CX23885_BOARD_HAUPPAUGE_HVR1850] = { .name = "Hauppauge WinTV-HVR1850", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_ENCODER, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_ABSENT, .tuner_addr = 0x42, /* 0x84 >> 1 */ .force_bff = 1, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN7_CH3 | CX25840_VIN5_CH2 | CX25840_VIN2_CH1 | CX25840_DIF_ON, .amux = CX25840_AUDIO8, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN6_CH1, .amux = CX25840_AUDIO7, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN7_CH3 | CX25840_VIN4_CH2 | CX25840_VIN8_CH1 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO7, } }, }, [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = { .name = "Compro VideoMate E800", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR1290] = { .name = "Hauppauge WinTV-HVR1290", .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_MYGICA_X8558PRO] = { .name = "Mygica X8558 PRO DMB-TH", .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = { .name = "LEADTEK WinFast PxTV1200", .porta = CX23885_ANALOG_VIDEO, .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, .tuner_bus = 1, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN2_CH1 | CX25840_VIN5_CH2 | CX25840_NONE0_CH3, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE1, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_VIN7_CH1 | CX25840_VIN6_CH2 | CX25840_VIN8_CH3 | CX25840_COMPONENT_ON, } }, }, [CX23885_BOARD_GOTVIEW_X5_3D_HYBRID] = { .name = "GoTView X5 3D Hybrid", .tuner_type = TUNER_XC5000, .tuner_addr = 0x64, .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN2_CH1 | CX25840_VIN5_CH2, .gpio0 = 0x02, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX23885_VMUX_COMPOSITE1, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, } }, }, [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = { .ci_type = 2, .name = "NetUP Dual DVB-T/C-CI RF", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, .num_fds_portb = 2, .num_fds_portc = 2, .tuner_type = TUNER_XC5000, .tuner_addr = 0x64, .input = { { .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_COMPOSITE1, } }, }, [CX23885_BOARD_MPX885] = { .name = "MPX-885", .porta = CX23885_ANALOG_VIDEO, .input = {{ .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE1, .amux = CX25840_AUDIO6, .gpio0 = 0, }, { .type = CX23885_VMUX_COMPOSITE2, .vmux = CX25840_COMPOSITE2, .amux = CX25840_AUDIO6, .gpio0 = 0, }, { .type = CX23885_VMUX_COMPOSITE3, .vmux = CX25840_COMPOSITE3, .amux = CX25840_AUDIO7, .gpio0 = 0, }, { .type = CX23885_VMUX_COMPOSITE4, .vmux = CX25840_COMPOSITE4, .amux = CX25840_AUDIO7, .gpio0 = 0, } }, }, [CX23885_BOARD_MYGICA_X8507] = { .name = "Mygica X8507", .tuner_type = TUNER_XC5000, .tuner_addr = 0x61, .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, .input = { { .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_COMPOSITE2, .amux = CX25840_AUDIO8, }, { .type = CX23885_VMUX_COMPOSITE1, .vmux = CX25840_COMPOSITE8, .amux = CX25840_AUDIO7, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4, .amux = CX25840_AUDIO7, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_COMPONENT_ON | CX25840_VIN1_CH1 | CX25840_VIN6_CH2 | CX25840_VIN7_CH3, .amux = CX25840_AUDIO7, }, }, }, [CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL] = { .name = "TerraTec Cinergy T PCIe Dual", .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, [CX23885_BOARD_TEVII_S471] = { .name = "TeVii S471", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_PROF_8000] = { .name = "Prof Revolution DVB-S2 8000", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR4400] = { .name = "Hauppauge WinTV-HVR4400", .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_AVERMEDIA_HC81R] = { .name = "AVerTV Hybrid Express Slim HC81R", .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, /* 0xc2 >> 1 */ .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, .input = {{ .type = CX23885_VMUX_TELEVISION, .vmux = CX25840_VIN2_CH1 | CX25840_VIN5_CH2 | CX25840_NONE0_CH3 | CX25840_NONE1_CH3, .amux = CX25840_AUDIO8, }, { .type = CX23885_VMUX_SVIDEO, .vmux = CX25840_VIN8_CH1 | CX25840_NONE_CH2 | CX25840_VIN7_CH3 | CX25840_SVIDEO_ON, .amux = CX25840_AUDIO6, }, { .type = CX23885_VMUX_COMPONENT, .vmux = CX25840_VIN1_CH1 | CX25840_NONE_CH2 | CX25840_NONE0_CH3 | CX25840_NONE1_CH3, .amux = CX25840_AUDIO6, } }, } }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); /* ------------------------------------------------------------------ */ /* PCI subsystem IDs */ struct cx23885_subid cx23885_subids[] = { { .subvendor = 0x0070, .subdevice = 0x3400, .card = CX23885_BOARD_UNKNOWN, }, { .subvendor = 0x0070, .subdevice = 0x7600, .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, }, { .subvendor = 0x0070, .subdevice = 0x7800, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, }, { .subvendor = 0x0070, .subdevice = 0x7801, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, }, { .subvendor = 0x0070, .subdevice = 0x7809, .card = CX23885_BOARD_HAUPPAUGE_HVR1800, }, { .subvendor = 0x0070, .subdevice = 0x7911, .card = CX23885_BOARD_HAUPPAUGE_HVR1250, }, { .subvendor = 0x18ac, .subdevice = 0xd500, .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, }, { .subvendor = 0x0070, .subdevice = 0x7790, .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, }, { .subvendor = 0x0070, .subdevice = 0x7797, .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, }, { .subvendor = 0x0070, .subdevice = 0x7710, .card = CX23885_BOARD_HAUPPAUGE_HVR1500, }, { .subvendor = 0x0070, .subdevice = 0x7717, .card = CX23885_BOARD_HAUPPAUGE_HVR1500, }, { .subvendor = 0x0070, .subdevice = 0x71d1, .card = CX23885_BOARD_HAUPPAUGE_HVR1200, }, { .subvendor = 0x0070, .subdevice = 0x71d3, .card = CX23885_BOARD_HAUPPAUGE_HVR1200, }, { .subvendor = 0x0070, .subdevice = 0x8101, .card = CX23885_BOARD_HAUPPAUGE_HVR1700, }, { .subvendor = 0x0070, .subdevice = 0x8010, .card = CX23885_BOARD_HAUPPAUGE_HVR1400, }, { .subvendor = 0x18ac, .subdevice = 0xd618, .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, }, { .subvendor = 0x18ac, .subdevice = 0xdb78, .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, }, { .subvendor = 0x107d, .subdevice = 0x6681, .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, }, { .subvendor = 0x107d, .subdevice = 0x6f39, .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000, }, { .subvendor = 0x185b, .subdevice = 0xe800, .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F, }, { .subvendor = 0x6920, .subdevice = 0x8888, .card = CX23885_BOARD_TBS_6920, }, { .subvendor = 0xd470, .subdevice = 0x9022, .card = CX23885_BOARD_TEVII_S470, }, { .subvendor = 0x0001, .subdevice = 0x2005, .card = CX23885_BOARD_DVBWORLD_2005, }, { .subvendor = 0x1b55, .subdevice = 0x2a2c, .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, }, { .subvendor = 0x0070, .subdevice = 0x2211, .card = CX23885_BOARD_HAUPPAUGE_HVR1270, }, { .subvendor = 0x0070, .subdevice = 0x2215, .card = CX23885_BOARD_HAUPPAUGE_HVR1275, }, { .subvendor = 0x0070, .subdevice = 0x221d, .card = CX23885_BOARD_HAUPPAUGE_HVR1275, }, { .subvendor = 0x0070, .subdevice = 0x2251, .card = CX23885_BOARD_HAUPPAUGE_HVR1255, }, { .subvendor = 0x0070, .subdevice = 0x2259, .card = CX23885_BOARD_HAUPPAUGE_HVR1255_22111, }, { .subvendor = 0x0070, .subdevice = 0x2291, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, }, { .subvendor = 0x0070, .subdevice = 0x2295, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, }, { .subvendor = 0x0070, .subdevice = 0x2299, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, }, { .subvendor = 0x0070, .subdevice = 0x229d, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ }, { .subvendor = 0x0070, .subdevice = 0x22f0, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, }, { .subvendor = 0x0070, .subdevice = 0x22f1, .card = CX23885_BOARD_HAUPPAUGE_HVR1255, }, { .subvendor = 0x0070, .subdevice = 0x22f2, .card = CX23885_BOARD_HAUPPAUGE_HVR1275, }, { .subvendor = 0x0070, .subdevice = 0x22f3, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ }, { .subvendor = 0x0070, .subdevice = 0x22f4, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, }, { .subvendor = 0x0070, .subdevice = 0x22f5, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ }, { .subvendor = 0x14f1, .subdevice = 0x8651, .card = CX23885_BOARD_MYGICA_X8506, }, { .subvendor = 0x14f1, .subdevice = 0x8657, .card = CX23885_BOARD_MAGICPRO_PROHDTVE2, }, { .subvendor = 0x0070, .subdevice = 0x8541, .card = CX23885_BOARD_HAUPPAUGE_HVR1850, }, { .subvendor = 0x1858, .subdevice = 0xe800, .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800, }, { .subvendor = 0x0070, .subdevice = 0x8551, .card = CX23885_BOARD_HAUPPAUGE_HVR1290, }, { .subvendor = 0x14f1, .subdevice = 0x8578, .card = CX23885_BOARD_MYGICA_X8558PRO, }, { .subvendor = 0x107d, .subdevice = 0x6f22, .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200, }, { .subvendor = 0x5654, .subdevice = 0x2390, .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, }, { .subvendor = 0x1b55, .subdevice = 0xe2e4, .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, }, { .subvendor = 0x14f1, .subdevice = 0x8502, .card = CX23885_BOARD_MYGICA_X8507, }, { .subvendor = 0x153b, .subdevice = 0x117e, .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL, }, { .subvendor = 0xd471, .subdevice = 0x9022, .card = CX23885_BOARD_TEVII_S471, }, { .subvendor = 0x8000, .subdevice = 0x3034, .card = CX23885_BOARD_PROF_8000, }, { .subvendor = 0x0070, .subdevice = 0xc108, .card = CX23885_BOARD_HAUPPAUGE_HVR4400, }, { .subvendor = 0x0070, .subdevice = 0xc138, .card = CX23885_BOARD_HAUPPAUGE_HVR4400, }, { .subvendor = 0x0070, .subdevice = 0xc12a, .card = CX23885_BOARD_HAUPPAUGE_HVR4400, }, { .subvendor = 0x0070, .subdevice = 0xc1f8, .card = CX23885_BOARD_HAUPPAUGE_HVR4400, }, { .subvendor = 0x1461, .subdevice = 0xd939, .card = CX23885_BOARD_AVERMEDIA_HC81R, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); void cx23885_card_list(struct cx23885_dev *dev) { int i; if (0 == dev->pci->subsystem_vendor && 0 == dev->pci->subsystem_device) { printk(KERN_INFO "%s: Board has no valid PCIe Subsystem ID and can't\n" "%s: be autodetected. Pass card=<n> insmod option\n" "%s: to workaround that. Redirect complaints to the\n" "%s: vendor of the TV card. Best regards,\n" "%s: -- tux\n", dev->name, dev->name, dev->name, dev->name, dev->name); } else { printk(KERN_INFO "%s: Your board isn't known (yet) to the driver.\n" "%s: Try to pick one of the existing card configs via\n" "%s: card=<n> insmod option. Updating to the latest\n" "%s: version might help as well.\n", dev->name, dev->name, dev->name, dev->name); } printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n", dev->name); for (i = 0; i < cx23885_bcount; i++) printk(KERN_INFO "%s: card=%d -> %s\n", dev->name, i, cx23885_boards[i].name); } static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) { struct tveeprom tv; tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data); /* Make sure we support the board model */ switch (tv.model) { case 22001: /* WinTV-HVR1270 (PCIe, Retail, half height) * ATSC/QAM and basic analog, IR Blast */ case 22009: /* WinTV-HVR1210 (PCIe, Retail, half height) * DVB-T and basic analog, IR Blast */ case 22011: /* WinTV-HVR1270 (PCIe, Retail, half height) * ATSC/QAM and basic analog, IR Recv */ case 22019: /* WinTV-HVR1210 (PCIe, Retail, half height) * DVB-T and basic analog, IR Recv */ case 22021: /* WinTV-HVR1275 (PCIe, Retail, half height) * ATSC/QAM and basic analog, IR Recv */ case 22029: /* WinTV-HVR1210 (PCIe, Retail, half height) * DVB-T and basic analog, IR Recv */ case 22101: /* WinTV-HVR1270 (PCIe, Retail, full height) * ATSC/QAM and basic analog, IR Blast */ case 22109: /* WinTV-HVR1210 (PCIe, Retail, full height) * DVB-T and basic analog, IR Blast */ case 22111: /* WinTV-HVR1270 (PCIe, Retail, full height) * ATSC/QAM and basic analog, IR Recv */ case 22119: /* WinTV-HVR1210 (PCIe, Retail, full height) * DVB-T and basic analog, IR Recv */ case 22121: /* WinTV-HVR1275 (PCIe, Retail, full height) * ATSC/QAM and basic analog, IR Recv */ case 22129: /* WinTV-HVR1210 (PCIe, Retail, full height) * DVB-T and basic analog, IR Recv */ case 71009: /* WinTV-HVR1200 (PCIe, Retail, full height) * DVB-T and basic analog */ case 71359: /* WinTV-HVR1200 (PCIe, OEM, half height) * DVB-T and basic analog */ case 71439: /* WinTV-HVR1200 (PCIe, OEM, half height) * DVB-T and basic analog */ case 71449: /* WinTV-HVR1200 (PCIe, OEM, full height) * DVB-T and basic analog */ case 71939: /* WinTV-HVR1200 (PCIe, OEM, half height) * DVB-T and basic analog */ case 71949: /* WinTV-HVR1200 (PCIe, OEM, full height) * DVB-T and basic analog */ case 71959: /* WinTV-HVR1200 (PCIe, OEM, full height) * DVB-T and basic analog */ case 71979: /* WinTV-HVR1200 (PCIe, OEM, half height) * DVB-T and basic analog */ case 71999: /* WinTV-HVR1200 (PCIe, OEM, full height) * DVB-T and basic analog */ case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */ case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */ case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */ case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */ case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */ case 79501: /* WinTV-HVR1250 (PCIe, No IR, half height, ATSC [at least] and Basic analog) */ case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ case 80019: /* WinTV-HVR1400 (Express Card, Retail, IR, * DVB-T and Basic analog */ case 81509: /* WinTV-HVR1700 (PCIe, OEM, No IR, half height) * DVB-T and MPEG2 HW Encoder */ case 81519: /* WinTV-HVR1700 (PCIe, OEM, No IR, full height) * DVB-T and MPEG2 HW Encoder */ break; case 85021: /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM, Dual channel ATSC and MPEG2 HW Encoder */ break; case 85721: /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR, Dual channel ATSC and Basic analog */ break; default: printk(KERN_WARNING "%s: warning: " "unknown hauppauge model #%d\n", dev->name, tv.model); break; } printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", dev->name, tv.model); } int cx23885_tuner_callback(void *priv, int component, int command, int arg) { struct cx23885_tsport *port = priv; struct cx23885_dev *dev = port->dev; u32 bitmask = 0; if ((command == XC2028_RESET_CLK) || (command == XC2028_I2C_FLUSH)) return 0; if (command != 0) { printk(KERN_ERR "%s(): Unknown command 0x%x.\n", __func__, command); return -EINVAL; } switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: /* Tuner Reset Command */ bitmask = 0x04; break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: /* Two identical tuners on two different i2c buses, * we need to reset the correct gpio. */ if (port->nr == 1) bitmask = 0x01; else if (port->nr == 2) bitmask = 0x04; break; case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: /* Tuner Reset Command */ bitmask = 0x02; break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: altera_ci_tuner_reset(dev, port->nr); break; case CX23885_BOARD_AVERMEDIA_HC81R: /* XC3028L Reset Command */ bitmask = 1 << 2; break; } if (bitmask) { /* Drive the tuner into reset and back out */ cx_clear(GP0_IO, bitmask); mdelay(200); cx_set(GP0_IO, bitmask); } return 0; } void cx23885_gpio_setup(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: /* GPIO-0 cx24227 demodulator reset */ cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1500: /* GPIO-0 cx24227 demodulator */ /* GPIO-2 xc3028 tuner */ /* Put the parts into reset */ cx_set(GP0_IO, 0x00050000); cx_clear(GP0_IO, 0x00000005); msleep(5); /* Bring the parts out of reset */ cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: /* GPIO-0 cx24227 demodulator reset */ /* GPIO-2 xc5000 tuner reset */ cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1800: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* GPIO-19 IR_RX */ /* CX23417 GPIO's */ /* EIO15 Zilog Reset */ /* EIO14 S5H1409/CX24227 Reset */ mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1); /* Put the demod into reset and protect the eeprom */ mc417_gpio_clear(dev, GPIO_15 | GPIO_14); mdelay(100); /* Bring the demod and blaster out of reset */ mc417_gpio_set(dev, GPIO_15 | GPIO_14); mdelay(100); /* Force the TDA8295A into reset and back */ cx23885_gpio_enable(dev, GPIO_2, 1); cx23885_gpio_set(dev, GPIO_2); mdelay(20); cx23885_gpio_clear(dev, GPIO_2); mdelay(20); cx23885_gpio_set(dev, GPIO_2); mdelay(20); break; case CX23885_BOARD_HAUPPAUGE_HVR1200: /* GPIO-0 tda10048 demodulator reset */ /* GPIO-2 tda18271 tuner reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1700: /* GPIO-0 TDA10048 demodulator reset */ /* GPIO-2 TDA8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* The following GPIO's are on the interna AVCore (cx25840) */ /* GPIO-19 IR_RX */ /* GPIO-20 IR_TX 416/DVBT Select */ /* GPIO-21 IIS DAT */ /* GPIO-22 IIS WCLK */ /* GPIO-23 IIS BCLK */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1400: /* GPIO-0 Dibcom7000p demodulator reset */ /* GPIO-2 xc3028L tuner reset */ /* GPIO-13 LED */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: /* GPIO-0 xc5000 tuner reset i2c bus 0 */ /* GPIO-1 s5h1409 demod reset i2c bus 0 */ /* GPIO-2 xc5000 tuner reset i2c bus 1 */ /* GPIO-3 s5h1409 demod reset i2c bus 0 */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: /* GPIO-0 portb xc3028 reset */ /* GPIO-1 portb zl10353 reset */ /* GPIO-2 portc xc3028 reset */ /* GPIO-3 portc zl10353 reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: /* GPIO-2 xc3028 tuner reset */ /* The following GPIO's are on the internal AVCore (cx25840) */ /* GPIO-? zl10353 demod reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00040000); mdelay(20); cx_clear(GP0_IO, 0x00000004); mdelay(20); cx_set(GP0_IO, 0x00040004); break; case CX23885_BOARD_TBS_6920: case CX23885_BOARD_PROF_8000: cx_write(MC417_CTL, 0x00000036); cx_write(MC417_OEN, 0x00001000); cx_set(MC417_RWD, 0x00000002); mdelay(200); cx_clear(MC417_RWD, 0x00000800); mdelay(200); cx_set(MC417_RWD, 0x00000800); mdelay(200); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: /* GPIO-0 INTA from CiMax1 GPIO-1 INTB from CiMax2 GPIO-2 reset chips GPIO-3 to GPIO-10 data/addr for CA GPIO-11 ~CS0 to CiMax1 GPIO-12 ~CS1 to CiMax2 GPIO-13 ADL0 load LSB addr GPIO-14 ADL1 load MSB addr GPIO-15 ~RDY from CiMax GPIO-17 ~RD to CiMax GPIO-18 ~WR to CiMax */ cx_set(GP0_IO, 0x00040000); /* GPIO as out */ /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */ cx_clear(GP0_IO, 0x00030004); mdelay(100);/* reset delay */ cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ /* GPIO-15 IN as ~ACK, rest as OUT */ cx_write(MC417_OEN, 0x00001000); /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ cx_write(MC417_RWD, 0x0000c300); /* enable irq */ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ /* GPIO-6 I2C Gate which can isolate the demod from the bus */ /* GPIO-9 Demod reset */ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1); cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5); cx23885_gpio_clear(dev, GPIO_9); mdelay(20); cx23885_gpio_set(dev, GPIO_9); break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: case CX23885_BOARD_MYGICA_X8507: /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ /* GPIO-2 reset LGS8GL5 / LGS8G75 */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); mdelay(100); cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); mdelay(100); break; case CX23885_BOARD_MYGICA_X8558PRO: /* GPIO-0 reset first ATBM8830 */ /* GPIO-1 reset second ATBM8830 */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1); cx23885_gpio_clear(dev, GPIO_0 | GPIO_1); mdelay(100); cx23885_gpio_set(dev, GPIO_0 | GPIO_1); mdelay(100); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 Wake# */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* GPIO-19 IR_RX */ /* GPIO-20 C_IR_TX */ /* GPIO-21 I2S DAT */ /* GPIO-22 I2S WCLK */ /* GPIO-23 I2S BCLK */ /* ALT GPIO: EXP GPIO LATCH */ /* CX23417 GPIO's */ /* GPIO-14 S5H1411/CX24228 Reset */ /* GPIO-13 EEPROM write protect */ mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1); /* Put the demod into reset and protect the eeprom */ mc417_gpio_clear(dev, GPIO_14 | GPIO_13); mdelay(100); /* Bring the demod out of reset */ mc417_gpio_set(dev, GPIO_14); mdelay(100); /* CX24228 GPIO */ /* Connected to IF / Mux */ break; case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: /* GPIO-0 ~INT in GPIO-1 TMS out GPIO-2 ~reset chips out GPIO-3 to GPIO-10 data/addr for CA in/out GPIO-11 ~CS out GPIO-12 ADDR out GPIO-13 ~WR out GPIO-14 ~RD out GPIO-15 ~RDY in GPIO-16 TCK out GPIO-17 TDO in GPIO-18 TDI out */ cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */ /* GPIO-0 as INT, reset & TMS low */ cx_clear(GP0_IO, 0x00010006); mdelay(100);/* reset delay */ cx_set(GP0_IO, 0x00000004); /* reset high */ cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */ /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */ cx_write(MC417_OEN, 0x00005000); /* ~RD, ~WR high; ADDR low; ~CS high */ cx_write(MC417_RWD, 0x00000d00); /* enable irq */ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR4400: /* GPIO-8 tda10071 demod reset */ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_8, 1); cx23885_gpio_clear(dev, GPIO_8); mdelay(100); cx23885_gpio_set(dev, GPIO_8); mdelay(100); break; case CX23885_BOARD_AVERMEDIA_HC81R: cx_clear(MC417_CTL, 1); /* GPIO-0,1,2 setup direction as output */ cx_set(GP0_IO, 0x00070000); mdelay(10); /* AF9013 demod reset */ cx_set(GP0_IO, 0x00010001); mdelay(10); cx_clear(GP0_IO, 0x00010001); mdelay(10); cx_set(GP0_IO, 0x00010001); mdelay(10); /* demod tune? */ cx_clear(GP0_IO, 0x00030003); mdelay(10); cx_set(GP0_IO, 0x00020002); mdelay(10); cx_set(GP0_IO, 0x00010001); mdelay(10); cx_clear(GP0_IO, 0x00020002); /* XC3028L tuner reset */ cx_set(GP0_IO, 0x00040004); cx_clear(GP0_IO, 0x00040004); cx_set(GP0_IO, 0x00040004); mdelay(60); break; } } int cx23885_ir_init(struct cx23885_dev *dev) { static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = { { .flags = V4L2_SUBDEV_IO_PIN_INPUT, .pin = CX23885_PIN_IR_RX_GPIO19, .function = CX23885_PAD_IR_RX, .value = 0, .strength = CX25840_PIN_DRIVE_MEDIUM, }, { .flags = V4L2_SUBDEV_IO_PIN_OUTPUT, .pin = CX23885_PIN_IR_TX_GPIO20, .function = CX23885_PAD_IR_TX, .value = 0, .strength = CX25840_PIN_DRIVE_MEDIUM, } }; const size_t ir_rxtx_pin_cfg_count = ARRAY_SIZE(ir_rxtx_pin_cfg); static struct v4l2_subdev_io_pin_config ir_rx_pin_cfg[] = { { .flags = V4L2_SUBDEV_IO_PIN_INPUT, .pin = CX23885_PIN_IR_RX_GPIO19, .function = CX23885_PAD_IR_RX, .value = 0, .strength = CX25840_PIN_DRIVE_MEDIUM, } }; const size_t ir_rx_pin_cfg_count = ARRAY_SIZE(ir_rx_pin_cfg); struct v4l2_subdev_ir_parameters params; int ret = 0; switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* FIXME: Implement me */ break; case CX23885_BOARD_HAUPPAUGE_HVR1270: ret = cx23888_ir_probe(dev); if (ret) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ir_rx_pin_cfg_count, ir_rx_pin_cfg); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: ret = cx23888_ir_probe(dev); if (ret) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg); /* * For these boards we need to invert the Tx output via the * IR controller to have the LED off while idle */ v4l2_subdev_call(dev->sd_ir, ir, tx_g_parameters, ¶ms); params.enable = false; params.shutdown = false; params.invert_level = true; v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, ¶ms); params.shutdown = true; v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, ¶ms); break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_MYGICA_X8507: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); if (dev->sd_ir == NULL) { ret = -ENODEV; break; } v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ir_rx_pin_cfg_count, ir_rx_pin_cfg); break; case CX23885_BOARD_HAUPPAUGE_HVR1250: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); if (dev->sd_ir == NULL) { ret = -ENODEV; break; } v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: request_module("ir-kbd-i2c"); break; } return ret; } void cx23885_ir_fini(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: cx23885_irq_remove(dev, PCI_MSK_IR); cx23888_ir_remove(dev); dev->sd_ir = NULL; break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_MYGICA_X8507: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; break; } } static int netup_jtag_io(void *device, int tms, int tdi, int read_tdo) { int data; int tdo = 0; struct cx23885_dev *dev = (struct cx23885_dev *)device; /*TMS*/ data = ((cx_read(GP0_IO)) & (~0x00000002)); data |= (tms ? 0x00020002 : 0x00020000); cx_write(GP0_IO, data); /*TDI*/ data = ((cx_read(MC417_RWD)) & (~0x0000a000)); data |= (tdi ? 0x00008000 : 0); cx_write(MC417_RWD, data); if (read_tdo) tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/ cx_write(MC417_RWD, data | 0x00002000); udelay(1); /*TCK*/ cx_write(MC417_RWD, data); return tdo; } void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_IR); break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_MYGICA_X8507: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; } } void cx23885_card_setup(struct cx23885_dev *dev) { struct cx23885_tsport *ts1 = &dev->ts1; struct cx23885_tsport *ts2 = &dev->ts2; static u8 eeprom[256]; if (dev->i2c_bus[0].i2c_rc == 0) { dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); } switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: if (dev->i2c_bus[0].i2c_rc == 0) { if (eeprom[0x80] != 0x84) hauppauge_eeprom(dev, eeprom+0xc0); else hauppauge_eeprom(dev, eeprom+0x80); } break; case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1400: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0x80); break; case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR4400: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); break; } switch (dev->board) { case CX23885_BOARD_AVERMEDIA_HC81R: /* Defaults for VID B */ ts1->gen_ctrl_val = 0x4; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; /* Defaults for VID C */ /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ ts2->gen_ctrl_val = 0x10e; ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; /* break omitted intentionally */ case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1800: /* Defaults for VID B - Analog encoder */ /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ ts1->gen_ctrl_val = 0x10e; ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; /* APB_TSVALERR_POL (active low)*/ ts1->vld_misc_val = 0x2000; ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); cx_write(0x130184, 0xc); /* Defaults for VID C */ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_TBS_6920: ts1->gen_ctrl_val = 0x4; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_TEVII_S470: case CX23885_BOARD_TEVII_S471: case CX23885_BOARD_DVBWORLD_2005: case CX23885_BOARD_PROF_8000: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_MYGICA_X8558PRO: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_HAUPPAUGE_HVR4400: ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: default: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; } /* Certain boards support analog, or require the avcore to be * loaded, ensure this happens. */ switch (dev->board) { case CX23885_BOARD_TEVII_S470: /* Currently only enabled for the integrated IR controller */ if (!enable_885_ir) break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_MPX885: case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: case CX23885_BOARD_AVERMEDIA_HC81R: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840) { dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; v4l2_subdev_call(dev->sd_cx25840, core, load_fw); } break; } /* AUX-PLL 27MHz CLK */ switch (dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_initialize(dev); break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { int ret; const struct firmware *fw; const char *filename = "dvb-netup-altera-01.fw"; char *action = "configure"; static struct netup_card_info cinfo; struct altera_config netup_config = { .dev = dev, .action = action, .jtag_io = netup_jtag_io, }; netup_initialize(dev); netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); if (netup_card_rev) cinfo.rev = netup_card_rev; switch (cinfo.rev) { case 0x4: filename = "dvb-netup-altera-04.fw"; break; default: filename = "dvb-netup-altera-01.fw"; break; } printk(KERN_INFO "NetUP card rev=0x%x fw_filename=%s\n", cinfo.rev, filename); ret = request_firmware(&fw, filename, &dev->pci->dev); if (ret != 0) printk(KERN_ERR "did not find the firmware file. (%s) " "Please see linux/Documentation/dvb/ for more details " "on firmware-problems.", filename); else altera_init(&netup_config, fw); release_firmware(fw); break; } } } /* ------------------------------------------------------------------ */