/* * Driver for the Conexant CX23885 PCIe bridge * * Copyright (c) 2006 Steven Toth * * 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 #include #include #include #include #include "cx23885.h" #include "tuner-xc2028.h" #include "netup-init.h" #include "cx23888-ir.h" /* ------------------------------------------------------------------ */ /* 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 */ .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_HVR1250] = { .name = "Hauppauge WinTV-HVR1250", .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_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", .portc = CX23885_MPEG_DVB, }, [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_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] = { .cimax = 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", .portc = CX23885_MPEG_DVB, }, [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, .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, .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", .portb = CX23885_MPEG_ENCODER, .portc = CX23885_MPEG_DVB, }, [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, .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, } }, }, }; 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 = 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, }, { .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, }, }; 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= 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= 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= 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) 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_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; } 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_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: 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_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: /* 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; } } 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_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* FIXME: Implement me */ 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_TEVII_S470: 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: 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_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_TEVII_S470: case CX23885_BOARD_HAUPPAUGE_HVR1250: 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; } } void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) { switch (dev->board) { 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_TEVII_S470: case CX23885_BOARD_HAUPPAUGE_HVR1250: 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_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); break; } switch (dev->board) { 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_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); /* 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_DVBWORLD_2005: 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: 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_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_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1290: 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_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 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_TEVII_S470: case CX23885_BOARD_HAUPPAUGE_HVR1250: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", "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; } } /* ------------------------------------------------------------------ */