Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for the NXP SAA7164 PCIe bridge
0004  *
0005  *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
0006  */
0007 
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/pci.h>
0011 #include <linux/delay.h>
0012 
0013 #include "saa7164.h"
0014 
0015 /* The Bridge API needs to understand register widths (in bytes) for the
0016  * attached I2C devices, so we can simplify the virtual i2c mechansms
0017  * and keep the -i2c.c implementation clean.
0018  */
0019 #define REGLEN_0bit 0
0020 #define REGLEN_8bit 1
0021 #define REGLEN_16bit    2
0022 
0023 struct saa7164_board saa7164_boards[] = {
0024     [SAA7164_BOARD_UNKNOWN] = {
0025         /* Bridge will not load any firmware, without knowing
0026          * the rev this would be fatal. */
0027         .name       = "Unknown",
0028     },
0029     [SAA7164_BOARD_UNKNOWN_REV2] = {
0030         /* Bridge will load the v2 f/w and dump descriptors */
0031         /* Required during new board bringup */
0032         .name       = "Generic Rev2",
0033         .chiprev    = SAA7164_CHIP_REV2,
0034     },
0035     [SAA7164_BOARD_UNKNOWN_REV3] = {
0036         /* Bridge will load the v2 f/w and dump descriptors */
0037         /* Required during new board bringup */
0038         .name       = "Generic Rev3",
0039         .chiprev    = SAA7164_CHIP_REV3,
0040     },
0041     [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
0042         .name       = "Hauppauge WinTV-HVR2200",
0043         .porta      = SAA7164_MPEG_DVB,
0044         .portb      = SAA7164_MPEG_DVB,
0045         .portc      = SAA7164_MPEG_ENCODER,
0046         .portd      = SAA7164_MPEG_ENCODER,
0047         .porte      = SAA7164_MPEG_VBI,
0048         .portf      = SAA7164_MPEG_VBI,
0049         .chiprev    = SAA7164_CHIP_REV3,
0050         .unit       = {{
0051             .id     = 0x1d,
0052             .type       = SAA7164_UNIT_EEPROM,
0053             .name       = "4K EEPROM",
0054             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0055             .i2c_bus_addr   = 0xa0 >> 1,
0056             .i2c_reg_len    = REGLEN_8bit,
0057         }, {
0058             .id     = 0x04,
0059             .type       = SAA7164_UNIT_TUNER,
0060             .name       = "TDA18271-1",
0061             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0062             .i2c_bus_addr   = 0xc0 >> 1,
0063             .i2c_reg_len    = REGLEN_8bit,
0064         }, {
0065             .id     = 0x1b,
0066             .type       = SAA7164_UNIT_TUNER,
0067             .name       = "TDA18271-2",
0068             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0069             .i2c_bus_addr   = 0xc0 >> 1,
0070             .i2c_reg_len    = REGLEN_8bit,
0071         }, {
0072             .id     = 0x1e,
0073             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0074             .name       = "TDA10048-1",
0075             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0076             .i2c_bus_addr   = 0x10 >> 1,
0077             .i2c_reg_len    = REGLEN_8bit,
0078         }, {
0079             .id     = 0x1f,
0080             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0081             .name       = "TDA10048-2",
0082             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0083             .i2c_bus_addr   = 0x12 >> 1,
0084             .i2c_reg_len    = REGLEN_8bit,
0085         } },
0086     },
0087     [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
0088         .name       = "Hauppauge WinTV-HVR2200",
0089         .porta      = SAA7164_MPEG_DVB,
0090         .portb      = SAA7164_MPEG_DVB,
0091         .portc      = SAA7164_MPEG_ENCODER,
0092         .portd      = SAA7164_MPEG_ENCODER,
0093         .porte      = SAA7164_MPEG_VBI,
0094         .portf      = SAA7164_MPEG_VBI,
0095         .chiprev    = SAA7164_CHIP_REV2,
0096         .unit       = {{
0097             .id     = 0x06,
0098             .type       = SAA7164_UNIT_EEPROM,
0099             .name       = "4K EEPROM",
0100             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0101             .i2c_bus_addr   = 0xa0 >> 1,
0102             .i2c_reg_len    = REGLEN_8bit,
0103         }, {
0104             .id     = 0x04,
0105             .type       = SAA7164_UNIT_TUNER,
0106             .name       = "TDA18271-1",
0107             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0108             .i2c_bus_addr   = 0xc0 >> 1,
0109             .i2c_reg_len    = REGLEN_8bit,
0110         }, {
0111             .id     = 0x05,
0112             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0113             .name       = "TDA10048-1",
0114             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0115             .i2c_bus_addr   = 0x10 >> 1,
0116             .i2c_reg_len    = REGLEN_8bit,
0117         }, {
0118             .id     = 0x1e,
0119             .type       = SAA7164_UNIT_TUNER,
0120             .name       = "TDA18271-2",
0121             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0122             .i2c_bus_addr   = 0xc0 >> 1,
0123             .i2c_reg_len    = REGLEN_8bit,
0124         }, {
0125             .id     = 0x1f,
0126             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0127             .name       = "TDA10048-2",
0128             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0129             .i2c_bus_addr   = 0x12 >> 1,
0130             .i2c_reg_len    = REGLEN_8bit,
0131         } },
0132     },
0133     [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
0134         .name       = "Hauppauge WinTV-HVR2200",
0135         .porta      = SAA7164_MPEG_DVB,
0136         .portb      = SAA7164_MPEG_DVB,
0137         .portc      = SAA7164_MPEG_ENCODER,
0138         .portd      = SAA7164_MPEG_ENCODER,
0139         .porte      = SAA7164_MPEG_VBI,
0140         .portf      = SAA7164_MPEG_VBI,
0141         .chiprev    = SAA7164_CHIP_REV2,
0142         .unit       = {{
0143             .id     = 0x1d,
0144             .type       = SAA7164_UNIT_EEPROM,
0145             .name       = "4K EEPROM",
0146             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0147             .i2c_bus_addr   = 0xa0 >> 1,
0148             .i2c_reg_len    = REGLEN_8bit,
0149         }, {
0150             .id     = 0x04,
0151             .type       = SAA7164_UNIT_TUNER,
0152             .name       = "TDA18271-1",
0153             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0154             .i2c_bus_addr   = 0xc0 >> 1,
0155             .i2c_reg_len    = REGLEN_8bit,
0156         }, {
0157             .id     = 0x05,
0158             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0159             .name       = "TDA8290-1",
0160             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0161             .i2c_bus_addr   = 0x84 >> 1,
0162             .i2c_reg_len    = REGLEN_8bit,
0163         }, {
0164             .id     = 0x1b,
0165             .type       = SAA7164_UNIT_TUNER,
0166             .name       = "TDA18271-2",
0167             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0168             .i2c_bus_addr   = 0xc0 >> 1,
0169             .i2c_reg_len    = REGLEN_8bit,
0170         }, {
0171             .id     = 0x1c,
0172             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0173             .name       = "TDA8290-2",
0174             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0175             .i2c_bus_addr   = 0x84 >> 1,
0176             .i2c_reg_len    = REGLEN_8bit,
0177         }, {
0178             .id     = 0x1e,
0179             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0180             .name       = "TDA10048-1",
0181             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0182             .i2c_bus_addr   = 0x10 >> 1,
0183             .i2c_reg_len    = REGLEN_8bit,
0184         }, {
0185             .id     = 0x1f,
0186             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0187             .name       = "TDA10048-2",
0188             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0189             .i2c_bus_addr   = 0x12 >> 1,
0190             .i2c_reg_len    = REGLEN_8bit,
0191         } },
0192     },
0193     [SAA7164_BOARD_HAUPPAUGE_HVR2200_4] = {
0194         .name       = "Hauppauge WinTV-HVR2200",
0195         .porta      = SAA7164_MPEG_DVB,
0196         .portb      = SAA7164_MPEG_DVB,
0197         .portc      = SAA7164_MPEG_ENCODER,
0198         .portd      = SAA7164_MPEG_ENCODER,
0199         .porte      = SAA7164_MPEG_VBI,
0200         .portf      = SAA7164_MPEG_VBI,
0201         .chiprev    = SAA7164_CHIP_REV3,
0202         .unit       = {{
0203             .id     = 0x1d,
0204             .type       = SAA7164_UNIT_EEPROM,
0205             .name       = "4K EEPROM",
0206             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0207             .i2c_bus_addr   = 0xa0 >> 1,
0208             .i2c_reg_len    = REGLEN_8bit,
0209         }, {
0210             .id     = 0x04,
0211             .type       = SAA7164_UNIT_TUNER,
0212             .name       = "TDA18271-1",
0213             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0214             .i2c_bus_addr   = 0xc0 >> 1,
0215             .i2c_reg_len    = REGLEN_8bit,
0216         }, {
0217             .id     = 0x05,
0218             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0219             .name       = "TDA8290-1",
0220             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0221             .i2c_bus_addr   = 0x84 >> 1,
0222             .i2c_reg_len    = REGLEN_8bit,
0223         }, {
0224             .id     = 0x1b,
0225             .type       = SAA7164_UNIT_TUNER,
0226             .name       = "TDA18271-2",
0227             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0228             .i2c_bus_addr   = 0xc0 >> 1,
0229             .i2c_reg_len    = REGLEN_8bit,
0230         }, {
0231             .id     = 0x1c,
0232             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0233             .name       = "TDA8290-2",
0234             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0235             .i2c_bus_addr   = 0x84 >> 1,
0236             .i2c_reg_len    = REGLEN_8bit,
0237         }, {
0238             .id     = 0x1e,
0239             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0240             .name       = "TDA10048-1",
0241             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0242             .i2c_bus_addr   = 0x10 >> 1,
0243             .i2c_reg_len    = REGLEN_8bit,
0244         }, {
0245             .id     = 0x1f,
0246             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0247             .name       = "TDA10048-2",
0248             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0249             .i2c_bus_addr   = 0x12 >> 1,
0250             .i2c_reg_len    = REGLEN_8bit,
0251         } },
0252     },
0253     [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
0254         .name       = "Hauppauge WinTV-HVR2250",
0255         .porta      = SAA7164_MPEG_DVB,
0256         .portb      = SAA7164_MPEG_DVB,
0257         .portc      = SAA7164_MPEG_ENCODER,
0258         .portd      = SAA7164_MPEG_ENCODER,
0259         .porte      = SAA7164_MPEG_VBI,
0260         .portf      = SAA7164_MPEG_VBI,
0261         .chiprev    = SAA7164_CHIP_REV3,
0262         .unit       = {{
0263             .id     = 0x22,
0264             .type       = SAA7164_UNIT_EEPROM,
0265             .name       = "4K EEPROM",
0266             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0267             .i2c_bus_addr   = 0xa0 >> 1,
0268             .i2c_reg_len    = REGLEN_8bit,
0269         }, {
0270             .id     = 0x04,
0271             .type       = SAA7164_UNIT_TUNER,
0272             .name       = "TDA18271-1",
0273             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0274             .i2c_bus_addr   = 0xc0 >> 1,
0275             .i2c_reg_len    = REGLEN_8bit,
0276         }, {
0277             .id     = 0x07,
0278             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0279             .name       = "CX24228/S5H1411-1 (TOP)",
0280             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0281             .i2c_bus_addr   = 0x32 >> 1,
0282             .i2c_reg_len    = REGLEN_8bit,
0283         }, {
0284             .id     = 0x08,
0285             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0286             .name       = "CX24228/S5H1411-1 (QAM)",
0287             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0288             .i2c_bus_addr   = 0x34 >> 1,
0289             .i2c_reg_len    = REGLEN_8bit,
0290         }, {
0291             .id     = 0x1e,
0292             .type       = SAA7164_UNIT_TUNER,
0293             .name       = "TDA18271-2",
0294             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0295             .i2c_bus_addr   = 0xc0 >> 1,
0296             .i2c_reg_len    = REGLEN_8bit,
0297         }, {
0298             .id     = 0x20,
0299             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0300             .name       = "CX24228/S5H1411-2 (TOP)",
0301             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0302             .i2c_bus_addr   = 0x32 >> 1,
0303             .i2c_reg_len    = REGLEN_8bit,
0304         }, {
0305             .id     = 0x23,
0306             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0307             .name       = "CX24228/S5H1411-2 (QAM)",
0308             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0309             .i2c_bus_addr   = 0x34 >> 1,
0310             .i2c_reg_len    = REGLEN_8bit,
0311         } },
0312     },
0313     [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
0314         .name       = "Hauppauge WinTV-HVR2250",
0315         .porta      = SAA7164_MPEG_DVB,
0316         .portb      = SAA7164_MPEG_DVB,
0317         .portc      = SAA7164_MPEG_ENCODER,
0318         .portd      = SAA7164_MPEG_ENCODER,
0319         .porte      = SAA7164_MPEG_VBI,
0320         .portf      = SAA7164_MPEG_VBI,
0321         .chiprev    = SAA7164_CHIP_REV3,
0322         .unit       = {{
0323             .id     = 0x28,
0324             .type       = SAA7164_UNIT_EEPROM,
0325             .name       = "4K EEPROM",
0326             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0327             .i2c_bus_addr   = 0xa0 >> 1,
0328             .i2c_reg_len    = REGLEN_8bit,
0329         }, {
0330             .id     = 0x04,
0331             .type       = SAA7164_UNIT_TUNER,
0332             .name       = "TDA18271-1",
0333             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0334             .i2c_bus_addr   = 0xc0 >> 1,
0335             .i2c_reg_len    = REGLEN_8bit,
0336         }, {
0337             .id     = 0x07,
0338             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0339             .name       = "CX24228/S5H1411-1 (TOP)",
0340             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0341             .i2c_bus_addr   = 0x32 >> 1,
0342             .i2c_reg_len    = REGLEN_8bit,
0343         }, {
0344             .id     = 0x08,
0345             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0346             .name       = "CX24228/S5H1411-1 (QAM)",
0347             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0348             .i2c_bus_addr   = 0x34 >> 1,
0349             .i2c_reg_len    = REGLEN_8bit,
0350         }, {
0351             .id     = 0x24,
0352             .type       = SAA7164_UNIT_TUNER,
0353             .name       = "TDA18271-2",
0354             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0355             .i2c_bus_addr   = 0xc0 >> 1,
0356             .i2c_reg_len    = REGLEN_8bit,
0357         }, {
0358             .id     = 0x26,
0359             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0360             .name       = "CX24228/S5H1411-2 (TOP)",
0361             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0362             .i2c_bus_addr   = 0x32 >> 1,
0363             .i2c_reg_len    = REGLEN_8bit,
0364         }, {
0365             .id     = 0x29,
0366             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0367             .name       = "CX24228/S5H1411-2 (QAM)",
0368             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0369             .i2c_bus_addr   = 0x34 >> 1,
0370             .i2c_reg_len    = REGLEN_8bit,
0371         } },
0372     },
0373     [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
0374         .name       = "Hauppauge WinTV-HVR2250",
0375         .porta      = SAA7164_MPEG_DVB,
0376         .portb      = SAA7164_MPEG_DVB,
0377         .portc      = SAA7164_MPEG_ENCODER,
0378         .portd      = SAA7164_MPEG_ENCODER,
0379         .porte      = SAA7164_MPEG_VBI,
0380         .portf      = SAA7164_MPEG_VBI,
0381         .chiprev    = SAA7164_CHIP_REV3,
0382         .unit       = {{
0383             .id     = 0x26,
0384             .type       = SAA7164_UNIT_EEPROM,
0385             .name       = "4K EEPROM",
0386             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0387             .i2c_bus_addr   = 0xa0 >> 1,
0388             .i2c_reg_len    = REGLEN_8bit,
0389         }, {
0390             .id     = 0x04,
0391             .type       = SAA7164_UNIT_TUNER,
0392             .name       = "TDA18271-1",
0393             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0394             .i2c_bus_addr   = 0xc0 >> 1,
0395             .i2c_reg_len    = REGLEN_8bit,
0396         }, {
0397             .id     = 0x07,
0398             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0399             .name       = "CX24228/S5H1411-1 (TOP)",
0400             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0401             .i2c_bus_addr   = 0x32 >> 1,
0402             .i2c_reg_len    = REGLEN_8bit,
0403         }, {
0404             .id     = 0x08,
0405             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0406             .name       = "CX24228/S5H1411-1 (QAM)",
0407             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0408             .i2c_bus_addr   = 0x34 >> 1,
0409             .i2c_reg_len    = REGLEN_8bit,
0410         }, {
0411             .id     = 0x22,
0412             .type       = SAA7164_UNIT_TUNER,
0413             .name       = "TDA18271-2",
0414             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0415             .i2c_bus_addr   = 0xc0 >> 1,
0416             .i2c_reg_len    = REGLEN_8bit,
0417         }, {
0418             .id     = 0x24,
0419             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0420             .name       = "CX24228/S5H1411-2 (TOP)",
0421             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0422             .i2c_bus_addr   = 0x32 >> 1,
0423             .i2c_reg_len    = REGLEN_8bit,
0424         }, {
0425             .id     = 0x27,
0426             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0427             .name       = "CX24228/S5H1411-2 (QAM)",
0428             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0429             .i2c_bus_addr   = 0x34 >> 1,
0430             .i2c_reg_len    = REGLEN_8bit,
0431         } },
0432     },
0433     [SAA7164_BOARD_HAUPPAUGE_HVR2200_5] = {
0434         .name       = "Hauppauge WinTV-HVR2200",
0435         .porta      = SAA7164_MPEG_DVB,
0436         .portb      = SAA7164_MPEG_DVB,
0437         .chiprev    = SAA7164_CHIP_REV3,
0438         .unit       = {{
0439             .id     = 0x23,
0440             .type       = SAA7164_UNIT_EEPROM,
0441             .name       = "4K EEPROM",
0442             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0443             .i2c_bus_addr   = 0xa0 >> 1,
0444             .i2c_reg_len    = REGLEN_8bit,
0445         }, {
0446             .id     = 0x04,
0447             .type       = SAA7164_UNIT_TUNER,
0448             .name       = "TDA18271-1",
0449             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0450             .i2c_bus_addr   = 0xc0 >> 1,
0451             .i2c_reg_len    = REGLEN_8bit,
0452         }, {
0453             .id     = 0x05,
0454             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0455             .name       = "TDA8290-1",
0456             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0457             .i2c_bus_addr   = 0x84 >> 1,
0458             .i2c_reg_len    = REGLEN_8bit,
0459         }, {
0460             .id     = 0x21,
0461             .type       = SAA7164_UNIT_TUNER,
0462             .name       = "TDA18271-2",
0463             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0464             .i2c_bus_addr   = 0xc0 >> 1,
0465             .i2c_reg_len    = REGLEN_8bit,
0466         }, {
0467             .id     = 0x22,
0468             .type       = SAA7164_UNIT_ANALOG_DEMODULATOR,
0469             .name       = "TDA8290-2",
0470             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0471             .i2c_bus_addr   = 0x84 >> 1,
0472             .i2c_reg_len    = REGLEN_8bit,
0473         }, {
0474             .id     = 0x24,
0475             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0476             .name       = "TDA10048-1",
0477             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0478             .i2c_bus_addr   = 0x10 >> 1,
0479             .i2c_reg_len    = REGLEN_8bit,
0480         }, {
0481             .id     = 0x25,
0482             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0483             .name       = "TDA10048-2",
0484             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0485             .i2c_bus_addr   = 0x12 >> 1,
0486             .i2c_reg_len    = REGLEN_8bit,
0487         } },
0488     },
0489     [SAA7164_BOARD_HAUPPAUGE_HVR2255proto] = {
0490         .name       = "Hauppauge WinTV-HVR2255(proto)",
0491         .porta      = SAA7164_MPEG_DVB,
0492         .portb      = SAA7164_MPEG_DVB,
0493         .portc      = SAA7164_MPEG_ENCODER,
0494         .portd      = SAA7164_MPEG_ENCODER,
0495         .porte      = SAA7164_MPEG_VBI,
0496         .portf      = SAA7164_MPEG_VBI,
0497         .chiprev    = SAA7164_CHIP_REV3,
0498         .unit       = {{
0499             .id     = 0x27,
0500             .type       = SAA7164_UNIT_EEPROM,
0501             .name       = "4K EEPROM",
0502             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0503             .i2c_bus_addr   = 0xa0 >> 1,
0504             .i2c_reg_len    = REGLEN_8bit,
0505         }, {
0506             .id     = 0x04,
0507             .type       = SAA7164_UNIT_TUNER,
0508             .name       = "SI2157-1",
0509             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0510             .i2c_bus_addr   = 0xc0 >> 1,
0511             .i2c_reg_len    = REGLEN_0bit,
0512         }, {
0513             .id     = 0x06,
0514             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0515             .name       = "LGDT3306",
0516             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0517             .i2c_bus_addr   = 0xb2 >> 1,
0518             .i2c_reg_len    = REGLEN_8bit,
0519         }, {
0520             .id     = 0x24,
0521             .type       = SAA7164_UNIT_TUNER,
0522             .name       = "SI2157-2",
0523             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0524             .i2c_bus_addr   = 0xc0 >> 1,
0525             .i2c_reg_len    = REGLEN_0bit,
0526         }, {
0527             .id     = 0x26,
0528             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0529             .name       = "LGDT3306-2",
0530             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0531             .i2c_bus_addr   = 0x1c >> 1,
0532             .i2c_reg_len    = REGLEN_8bit,
0533         } },
0534     },
0535     [SAA7164_BOARD_HAUPPAUGE_HVR2255] = {
0536         .name       = "Hauppauge WinTV-HVR2255",
0537         .porta      = SAA7164_MPEG_DVB,
0538         .portb      = SAA7164_MPEG_DVB,
0539         .portc      = SAA7164_MPEG_ENCODER,
0540         .portd      = SAA7164_MPEG_ENCODER,
0541         .porte      = SAA7164_MPEG_VBI,
0542         .portf      = SAA7164_MPEG_VBI,
0543         .chiprev    = SAA7164_CHIP_REV3,
0544         .unit       = {{
0545             .id     = 0x28,
0546             .type       = SAA7164_UNIT_EEPROM,
0547             .name       = "4K EEPROM",
0548             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0549             .i2c_bus_addr   = 0xa0 >> 1,
0550             .i2c_reg_len    = REGLEN_8bit,
0551         }, {
0552             .id     = 0x04,
0553             .type       = SAA7164_UNIT_TUNER,
0554             .name       = "SI2157-1",
0555             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0556             .i2c_bus_addr   = 0xc0 >> 1,
0557             .i2c_reg_len    = REGLEN_0bit,
0558         }, {
0559             .id     = 0x06,
0560             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0561             .name       = "LGDT3306-1",
0562             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0563             .i2c_bus_addr   = 0xb2 >> 1,
0564             .i2c_reg_len    = REGLEN_8bit,
0565         }, {
0566             .id     = 0x25,
0567             .type       = SAA7164_UNIT_TUNER,
0568             .name       = "SI2157-2",
0569             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0570             .i2c_bus_addr   = 0xc0 >> 1,
0571             .i2c_reg_len    = REGLEN_0bit,
0572         }, {
0573             .id     = 0x27,
0574             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0575             .name       = "LGDT3306-2",
0576             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0577             .i2c_bus_addr   = 0x1c >> 1,
0578             .i2c_reg_len    = REGLEN_8bit,
0579         } },
0580     },
0581     [SAA7164_BOARD_HAUPPAUGE_HVR2205] = {
0582         .name       = "Hauppauge WinTV-HVR2205",
0583         .porta      = SAA7164_MPEG_DVB,
0584         .portb      = SAA7164_MPEG_DVB,
0585         .portc      = SAA7164_MPEG_ENCODER,
0586         .portd      = SAA7164_MPEG_ENCODER,
0587         .porte      = SAA7164_MPEG_VBI,
0588         .portf      = SAA7164_MPEG_VBI,
0589         .chiprev    = SAA7164_CHIP_REV3,
0590         .unit       = {{
0591             .id     = 0x28,
0592             .type       = SAA7164_UNIT_EEPROM,
0593             .name       = "4K EEPROM",
0594             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0595             .i2c_bus_addr   = 0xa0 >> 1,
0596             .i2c_reg_len    = REGLEN_8bit,
0597         }, {
0598             .id     = 0x04,
0599             .type       = SAA7164_UNIT_TUNER,
0600             .name       = "SI2157-1",
0601             .i2c_bus_nr = SAA7164_I2C_BUS_0,
0602             .i2c_bus_addr   = 0xc0 >> 1,
0603             .i2c_reg_len    = REGLEN_0bit,
0604         }, {
0605             .id     = 0x06,
0606             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0607             .name       = "SI2168-1",
0608             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0609             .i2c_bus_addr   = 0xc8 >> 1,
0610             .i2c_reg_len    = REGLEN_0bit,
0611         }, {
0612             .id     = 0x25,
0613             .type       = SAA7164_UNIT_TUNER,
0614             .name       = "SI2157-2",
0615             .i2c_bus_nr = SAA7164_I2C_BUS_1,
0616             .i2c_bus_addr   = 0xc0 >> 1,
0617             .i2c_reg_len    = REGLEN_0bit,
0618         }, {
0619             .id     = 0x27,
0620             .type       = SAA7164_UNIT_DIGITAL_DEMODULATOR,
0621             .name       = "SI2168-2",
0622             .i2c_bus_nr = SAA7164_I2C_BUS_2,
0623             .i2c_bus_addr   = 0xcc >> 1,
0624             .i2c_reg_len    = REGLEN_0bit,
0625         } },
0626     },
0627 };
0628 const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
0629 
0630 /* ------------------------------------------------------------------ */
0631 /* PCI subsystem IDs                                                  */
0632 
0633 struct saa7164_subid saa7164_subids[] = {
0634     {
0635         .subvendor = 0x0070,
0636         .subdevice = 0x8880,
0637         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
0638     }, {
0639         .subvendor = 0x0070,
0640         .subdevice = 0x8810,
0641         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
0642     }, {
0643         .subvendor = 0x0070,
0644         .subdevice = 0x8980,
0645         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
0646     }, {
0647         .subvendor = 0x0070,
0648         .subdevice = 0x8900,
0649         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
0650     }, {
0651         .subvendor = 0x0070,
0652         .subdevice = 0x8901,
0653         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
0654     }, {
0655         .subvendor = 0x0070,
0656         .subdevice = 0x88A1,
0657         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
0658     }, {
0659         .subvendor = 0x0070,
0660         .subdevice = 0x8891,
0661         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
0662     }, {
0663         .subvendor = 0x0070,
0664         .subdevice = 0x8851,
0665         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
0666     }, {
0667         .subvendor = 0x0070,
0668         .subdevice = 0x8940,
0669         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_4,
0670     }, {
0671         .subvendor = 0x0070,
0672         .subdevice = 0x8953,
0673         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_5,
0674     }, {
0675         .subvendor = 0x0070,
0676         .subdevice = 0xf111,
0677         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255,
0678         /* Prototype card left here for documentation purposes.
0679         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2255proto,
0680         */
0681     }, {
0682         .subvendor = 0x0070,
0683         .subdevice = 0xf123,
0684         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
0685     }, {
0686         .subvendor = 0x0070,
0687         .subdevice = 0xf120,
0688         .card      = SAA7164_BOARD_HAUPPAUGE_HVR2205,
0689     },
0690 };
0691 const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
0692 
0693 void saa7164_card_list(struct saa7164_dev *dev)
0694 {
0695     int i;
0696 
0697     if (0 == dev->pci->subsystem_vendor &&
0698         0 == dev->pci->subsystem_device) {
0699         printk(KERN_ERR
0700             "%s: Board has no valid PCIe Subsystem ID and can't\n"
0701             "%s: be autodetected. Pass card=<n> insmod option to\n"
0702             "%s: workaround that. Send complaints to the vendor\n"
0703             "%s: of the TV card. Best regards,\n"
0704             "%s:         -- tux\n",
0705             dev->name, dev->name, dev->name, dev->name, dev->name);
0706     } else {
0707         printk(KERN_ERR
0708             "%s: Your board isn't known (yet) to the driver.\n"
0709             "%s: Try to pick one of the existing card configs via\n"
0710             "%s: card=<n> insmod option.  Updating to the latest\n"
0711             "%s: version might help as well.\n",
0712             dev->name, dev->name, dev->name, dev->name);
0713     }
0714 
0715     printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod option:\n",
0716            dev->name);
0717 
0718     for (i = 0; i < saa7164_bcount; i++)
0719         printk(KERN_ERR "%s:    card=%d -> %s\n",
0720                dev->name, i, saa7164_boards[i].name);
0721 }
0722 
0723 /* TODO: clean this define up into the -cards.c structs */
0724 #define PCIEBRIDGE_UNITID 2
0725 
0726 void saa7164_gpio_setup(struct saa7164_dev *dev)
0727 {
0728     switch (dev->board) {
0729     case SAA7164_BOARD_HAUPPAUGE_HVR2200:
0730     case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
0731     case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
0732     case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
0733     case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
0734     case SAA7164_BOARD_HAUPPAUGE_HVR2250:
0735     case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
0736     case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
0737     case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
0738     case SAA7164_BOARD_HAUPPAUGE_HVR2255:
0739     case SAA7164_BOARD_HAUPPAUGE_HVR2205:
0740         /*
0741         HVR2200 / HVR2250
0742         GPIO 2: s5h1411 / tda10048-1 demod reset
0743         GPIO 3: s5h1411 / tda10048-2 demod reset
0744         GPIO 7: IRBlaster Zilog reset
0745          */
0746 
0747         /* HVR2255
0748          * GPIO 2: lgdg3306-1 demod reset
0749          * GPIO 3: lgdt3306-2 demod reset
0750          */
0751 
0752         /* HVR2205
0753          * GPIO 2: si2168-1 demod reset
0754          * GPIO 3: si2168-2 demod reset
0755          */
0756 
0757         /* Reset parts by going in and out of reset */
0758         saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
0759         saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
0760 
0761         msleep(20);
0762 
0763         saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
0764         saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
0765         break;
0766     }
0767 }
0768 
0769 static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
0770 {
0771     struct tveeprom tv;
0772 
0773     tveeprom_hauppauge_analog(&tv, eeprom_data);
0774 
0775     /* Make sure we support the board model */
0776     switch (tv.model) {
0777     case 88001:
0778         /* Development board - Limit circulation */
0779         /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
0780          * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
0781     case 88021:
0782         /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
0783          * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
0784         break;
0785     case 88041:
0786         /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
0787          * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
0788         break;
0789     case 88061:
0790         /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
0791          * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
0792         break;
0793     case 89519:
0794     case 89609:
0795         /* WinTV-HVR2200 (PCIe, Retail, full-height)
0796          * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
0797         break;
0798     case 89619:
0799         /* WinTV-HVR2200 (PCIe, Retail, half-height)
0800          * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
0801         break;
0802     case 151009:
0803         /* First production board rev B2I6 */
0804         /* WinTV-HVR2205 (PCIe, Retail, full-height bracket)
0805          * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
0806         break;
0807     case 151609:
0808         /* First production board rev B2I6 */
0809         /* WinTV-HVR2205 (PCIe, Retail, half-height bracket)
0810          * DVB-T/T2/C (SI2157/SI2168) and basic analog, FM */
0811         break;
0812     case 151061:
0813         /* First production board rev B1I6 */
0814         /* WinTV-HVR2255 (PCIe, Retail, full-height bracket)
0815          * ATSC/QAM (SI2157/LGDT3306) and basic analog, FM */
0816         break;
0817     default:
0818         printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
0819             dev->name, tv.model);
0820         break;
0821     }
0822 
0823     printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
0824         tv.model);
0825 }
0826 
0827 void saa7164_card_setup(struct saa7164_dev *dev)
0828 {
0829     static u8 eeprom[256];
0830 
0831     if (dev->i2c_bus[0].i2c_rc == 0) {
0832         if (saa7164_api_read_eeprom(dev, &eeprom[0],
0833             sizeof(eeprom)) < 0)
0834             return;
0835     }
0836 
0837     switch (dev->board) {
0838     case SAA7164_BOARD_HAUPPAUGE_HVR2200:
0839     case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
0840     case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
0841     case SAA7164_BOARD_HAUPPAUGE_HVR2200_4:
0842     case SAA7164_BOARD_HAUPPAUGE_HVR2200_5:
0843     case SAA7164_BOARD_HAUPPAUGE_HVR2250:
0844     case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
0845     case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
0846     case SAA7164_BOARD_HAUPPAUGE_HVR2255proto:
0847     case SAA7164_BOARD_HAUPPAUGE_HVR2255:
0848     case SAA7164_BOARD_HAUPPAUGE_HVR2205:
0849         hauppauge_eeprom(dev, &eeprom[0]);
0850         break;
0851     }
0852 }
0853 
0854 /* With most other drivers, the kernel expects to communicate with subdrivers
0855  * through i2c. This bridge does not allow that, it does not expose any direct
0856  * access to I2C. Instead we have to communicate through the device f/w for
0857  * register access to 'processing units'. Each unit has a unique
0858  * id, regardless of how the physical implementation occurs across
0859  * the three physical i2c buses. The being said if we want leverge of
0860  * the existing kernel drivers for tuners and demods we have to 'speak i2c',
0861  * to this bridge implements 3 virtual i2c buses. This is a helper function
0862  * for those.
0863  *
0864  * Description: Translate the kernels notion of an i2c address and bus into
0865  * the appropriate unitid.
0866  */
0867 int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
0868 {
0869     /* For a given bus and i2c device address, return the saa7164 unique
0870      * unitid. < 0 on error */
0871 
0872     struct saa7164_dev *dev = bus->dev;
0873     struct saa7164_unit *unit;
0874     int i;
0875 
0876     for (i = 0; i < SAA7164_MAX_UNITS; i++) {
0877         unit = &saa7164_boards[dev->board].unit[i];
0878 
0879         if (unit->type == SAA7164_UNIT_UNDEFINED)
0880             continue;
0881         if ((bus->nr == unit->i2c_bus_nr) &&
0882             (addr == unit->i2c_bus_addr))
0883             return unit->id;
0884     }
0885 
0886     return -1;
0887 }
0888 
0889 /* The 7164 API needs to know the i2c register length in advance.
0890  * this is a helper function. Based on a specific chip addr and bus return the
0891  * reg length.
0892  */
0893 int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
0894 {
0895     /* For a given bus and i2c device address, return the
0896      * saa7164 registry address width. < 0 on error
0897      */
0898 
0899     struct saa7164_dev *dev = bus->dev;
0900     struct saa7164_unit *unit;
0901     int i;
0902 
0903     for (i = 0; i < SAA7164_MAX_UNITS; i++) {
0904         unit = &saa7164_boards[dev->board].unit[i];
0905 
0906         if (unit->type == SAA7164_UNIT_UNDEFINED)
0907             continue;
0908 
0909         if ((bus->nr == unit->i2c_bus_nr) &&
0910             (addr == unit->i2c_bus_addr))
0911             return unit->i2c_reg_len;
0912     }
0913 
0914     return -1;
0915 }
0916 /* TODO: implement a 'findeeprom' functio like the above and fix any other
0917  * eeprom related todo's in -api.c.
0918  */
0919 
0920 /* Translate a unitid into a x readable device name, for display purposes.  */
0921 char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
0922 {
0923     char *undefed = "UNDEFINED";
0924     char *bridge = "BRIDGE";
0925     struct saa7164_unit *unit;
0926     int i;
0927 
0928     if (unitid == 0)
0929         return bridge;
0930 
0931     for (i = 0; i < SAA7164_MAX_UNITS; i++) {
0932         unit = &saa7164_boards[dev->board].unit[i];
0933 
0934         if (unit->type == SAA7164_UNIT_UNDEFINED)
0935             continue;
0936 
0937         if (unitid == unit->id)
0938                 return unit->name;
0939     }
0940 
0941     return undefed;
0942 }
0943