cx88-cards.c

来自「底层驱动开发」· C语言 代码 · 共 1,131 行 · 第 1/2 页

C
1,131
字号
		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.input          = {{			.type   = CX88_VMUX_TELEVISION,			.vmux   = 0,			.gpio0  = 0x00008484,			.gpio1  = 0x00000000,			.gpio2  = 0x00000000,			.gpio3  = 0x00000000,		},{			.type   = CX88_VMUX_COMPOSITE1,			.vmux   = 1,			.gpio0  = 0x00008400,			.gpio1  = 0x00000000,			.gpio2  = 0x00000000,			.gpio3  = 0x00000000,		},{			.type   = CX88_VMUX_SVIDEO,			.vmux   = 2,			.gpio0  = 0x00008400,			.gpio1  = 0x00000000,			.gpio2  = 0x00000000,			.gpio3  = 0x00000000,		}},		.radio = {			.type   = CX88_RADIO,			.vmux   = 2,			.gpio0  = 0x00008400,			.gpio1  = 0x00000000,			.gpio2  = 0x00000000,			.gpio3  = 0x00000000,		},		.dvb            = 1,	},	[CX88_BOARD_HAUPPAUGE_ROSLYN] = {		// entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>		// GPIO values obtained from regspy, courtesy Sean Covel		.name           = "Hauppauge WinTV 28xxx (Roslyn) models",		.tuner_type     = UNSET,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.input          = {{			.type   = CX88_VMUX_TELEVISION,			.vmux   = 0,			.gpio0  = 0xed12,  /* internal decoder */			.gpio2  = 0x00ff,		},{			.type   = CX88_VMUX_DEBUG,			.vmux   = 0,			.gpio0  = 0xff01,  /* mono from tuner chip */		},{			.type   = CX88_VMUX_COMPOSITE1,			.vmux   = 1,			.gpio0  = 0xff02,		},{			.type   = CX88_VMUX_SVIDEO,			.vmux   = 2,			.gpio0  = 0xed92,			.gpio2  = 0x00ff,		}},		.radio = {			 .type   = CX88_RADIO,			 .gpio0  = 0xed96,			 .gpio2  = 0x00ff,		 },		.blackbird = 1,	},	[CX88_BOARD_DIGITALLOGIC_MEC] = {		.name           = "Digital-Logic MICROSPACE Entertainment Center (MEC)",		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.tda9887_conf   = TDA9887_PRESENT,		.input          = {{			.type   = CX88_VMUX_TELEVISION,			.vmux   = 0,			.gpio0  = 0x00009d80,		},{			.type   = CX88_VMUX_COMPOSITE1,			.vmux   = 1,			.gpio0  = 0x00009d76,		},{			.type   = CX88_VMUX_SVIDEO,			.vmux   = 2,			.gpio0  = 0x00009d76,		}},		.radio = {			.type   = CX88_RADIO,			.gpio0  = 0x00009d00,		},		.blackbird = 1,	},	[CX88_BOARD_IODATA_GVBCTV7E] = {		.name           = "IODATA GV/BCTV7E",		.tuner_type     = TUNER_PHILIPS_FQ1286,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.tda9887_conf   = TDA9887_PRESENT,		.input          = {{			.type   = CX88_VMUX_TELEVISION,			.vmux   = 1,			.gpio1  = 0x0000e03f,		},{			.type   = CX88_VMUX_COMPOSITE1,			.vmux   = 2,			.gpio1  = 0x0000e07f,		},{			.type   = CX88_VMUX_SVIDEO,			.vmux   = 3,			.gpio1  = 0x0000e07f,		}}	},	[CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {		.name           = "PixelView PlayTV Ultra Pro (Stereo)",		/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.input          = {{			.type   = CX88_VMUX_TELEVISION,			.vmux   = 0,			.gpio0  = 0xbf61,  /* internal decoder */		},{			.type   = CX88_VMUX_COMPOSITE1,			.vmux   = 1,			.gpio0	= 0xbf63,		},{			.type   = CX88_VMUX_SVIDEO,			.vmux   = 2,			.gpio0	= 0xbf63,		}},		.radio = {			 .type  = CX88_RADIO,			 .gpio0 = 0xbf60,		 },	},        [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {		.name           = "DViCO FusionHDTV 3 Gold-T",		.tuner_type     = TUNER_THOMSON_DTT7611,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.input          = {{                        .type   = CX88_VMUX_TELEVISION,                        .vmux   = 0,                        .gpio0  = 0x97ed,                },{                        .type   = CX88_VMUX_COMPOSITE1,                        .vmux   = 1,                        .gpio0  = 0x97e9,                },{                        .type   = CX88_VMUX_SVIDEO,                        .vmux   = 2,                        .gpio0  = 0x97e9,                }},		.dvb            = 1,        },        [CX88_BOARD_ADSTECH_DVB_T_PCI] = {                .name           = "ADS Tech Instant TV DVB-T PCI",		.tuner_type     = TUNER_ABSENT,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.input          = {{                        .type   = CX88_VMUX_COMPOSITE1,                        .vmux   = 1,			.gpio0  = 0x0700,			.gpio2  = 0x0101,                },{                        .type   = CX88_VMUX_SVIDEO,                        .vmux   = 2,			.gpio0  = 0x0700,			.gpio2  = 0x0101,                }},		.dvb            = 1,	},	[CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {		.name           = "TerraTec Cinergy 1400 DVB-T",		.tuner_type     = TUNER_ABSENT,		.input          = {{			.type   = CX88_VMUX_DVB,			.vmux   = 0,		}},		.dvb            = 1,	},	[CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {		.name           = "DViCO FusionHDTV 5 Gold",		.tuner_type     = TUNER_LG_TDVS_H062F,		.radio_type     = UNSET,		.tuner_addr	= ADDR_UNSET,		.radio_addr	= ADDR_UNSET,		.tda9887_conf   = TDA9887_PRESENT,		.input          = {{                        .type   = CX88_VMUX_TELEVISION,                        .vmux   = 0,                        .gpio0  = 0x87fd,                },{                        .type   = CX88_VMUX_COMPOSITE1,                        .vmux   = 1,                        .gpio0  = 0x87f9,                },{                        .type   = CX88_VMUX_SVIDEO,                        .vmux   = 2,                        .gpio0  = 0x87f9,                }},		.dvb            = 1,	},};const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);/* ------------------------------------------------------------------ *//* PCI subsystem IDs                                                  */struct cx88_subid cx88_subids[] = {	{		.subvendor = 0x0070,		.subdevice = 0x3400,		.card      = CX88_BOARD_HAUPPAUGE,	},{		.subvendor = 0x0070,		.subdevice = 0x3401,		.card      = CX88_BOARD_HAUPPAUGE,	},{		.subvendor = 0x14c7,		.subdevice = 0x0106,		.card      = CX88_BOARD_GDI,	},{		.subvendor = 0x14c7,		.subdevice = 0x0107, /* with mpeg encoder */		.card      = CX88_BOARD_GDI,	},{		.subvendor = PCI_VENDOR_ID_ATI,		.subdevice = 0x00f8,		.card      = CX88_BOARD_ATI_WONDER_PRO,	},{                .subvendor = 0x107d,                .subdevice = 0x6611,                .card      = CX88_BOARD_WINFAST2000XP_EXPERT,	},{                .subvendor = 0x107d,                .subdevice = 0x6613,	/* NTSC */                .card      = CX88_BOARD_WINFAST2000XP_EXPERT,	},{		.subvendor = 0x107d,                .subdevice = 0x6620,                .card      = CX88_BOARD_WINFAST_DV2000,        },{                .subvendor = 0x107d,                .subdevice = 0x663b,                .card      = CX88_BOARD_LEADTEK_PVR2000,        },{                .subvendor = 0x107d,                .subdevice = 0x663C,                .card      = CX88_BOARD_LEADTEK_PVR2000,        },{		.subvendor = 0x1461,		.subdevice = 0x000b,		.card      = CX88_BOARD_AVERTV_303,	},{		.subvendor = 0x1462,		.subdevice = 0x8606,		.card      = CX88_BOARD_MSI_TVANYWHERE_MASTER,	},{ 		.subvendor = 0x10fc, 		.subdevice = 0xd003, 		.card      = CX88_BOARD_IODATA_GVVCP3PCI,	},{ 		.subvendor = 0x1043, 		.subdevice = 0x4823,  /* with mpeg encoder */ 		.card      = CX88_BOARD_ASUS_PVR_416,	},{		.subvendor = 0x17de,		.subdevice = 0x08a6,		.card      = CX88_BOARD_KWORLD_DVB_T,	},{		.subvendor = 0x18ac,		.subdevice = 0xd810,		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,	},{		.subvendor = 0x18ac,		.subdevice = 0xd820,		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,	},{		.subvendor = 0x18AC,		.subdevice = 0xDB00,		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 	},{		.subvendor = 0x0070,		.subdevice = 0x9002,		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1, 	},{		.subvendor = 0x14f1,		.subdevice = 0x0187,		.card      = CX88_BOARD_CONEXANT_DVB_T1, 	},{		.subvendor = 0x1540,		.subdevice = 0x2580,		.card      = CX88_BOARD_PROVIDEO_PV259,	},{		.subvendor = 0x18AC,		.subdevice = 0xDB10,		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,	},{                .subvendor = 0x1554,                .subdevice = 0x4811,                .card      = CX88_BOARD_PIXELVIEW,	},{		.subvendor = 0x7063,		.subdevice = 0x3000, /* HD-3000 card */		.card      = CX88_BOARD_PCHDTV_HD3000,	},{		.subvendor = 0x17DE,		.subdevice = 0xA8A6,		.card      = CX88_BOARD_DNTV_LIVE_DVB_T,	},{		.subvendor = 0x0070,		.subdevice = 0x2801,		.card      = CX88_BOARD_HAUPPAUGE_ROSLYN,	},{		.subvendor = 0x14F1,		.subdevice = 0x0342,		.card      = CX88_BOARD_DIGITALLOGIC_MEC,	},{		.subvendor = 0x10fc,		.subdevice = 0xd035,		.card      = CX88_BOARD_IODATA_GVBCTV7E,	},{		.subvendor = 0x1421,		.subdevice = 0x0334,		.card      = CX88_BOARD_ADSTECH_DVB_T_PCI, 	},{		.subvendor = 0x153b,		.subdevice = 0x1166,		.card      = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, 	},{		.subvendor = 0x18ac,		.subdevice = 0xd500,		.card      = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,	},};const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);/* ----------------------------------------------------------------------- *//* some leadtek specific stuff                                             */static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data){	/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on	 * any others.	 *	 * Byte 0 is 1 on the NTSC board.	 */	if (eeprom_data[4] != 0x7d ||	    eeprom_data[5] != 0x10 ||	    eeprom_data[7] != 0x66) {		printk(KERN_WARNING "%s: Leadtek eeprom invalid.\n",		       core->name);		return;	}	core->has_radio  = 1;	core->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38;	printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: "	       "tuner=%d, eeprom[0]=0x%02x\n",	       core->name, core->tuner_type, eeprom_data[0]);}/* ----------------------------------------------------------------------- */static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data){	struct tveeprom tv;	tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);	core->tuner_type = tv.tuner_type;	core->has_radio  = tv.has_radio;}static int hauppauge_eeprom_dvb(struct cx88_core *core, u8 *ee){	int model;	int tuner;	/* Make sure we support the board model */	model = ee[0x1f] << 24 | ee[0x1e] << 16 | ee[0x1d] << 8 | ee[0x1c];	switch(model) {	case 90002:	case 90500:	case 90501:		/* known */		break;	default:		printk("%s: warning: unknown hauppauge model #%d\n",		       core->name, model);		break;	}	/* Make sure we support the tuner */	tuner = ee[0x2d];	switch(tuner) {	case 0x4B: /* dtt 7595 */	case 0x4C: /* dtt 7592 */		break;	default:		printk("%s: error: unknown hauppauge tuner 0x%02x\n",		       core->name, tuner);		return -ENODEV;	}	printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%d\n",	       core->name, model, tuner);	return 0;}/* ----------------------------------------------------------------------- *//* some GDI (was: Modular Technology) specific stuff                       */static struct {	int  id;	int  fm;	char *name;} gdi_tuner[] = {	[ 0x01 ] = { .id   = TUNER_ABSENT,		     .name = "NTSC_M" },	[ 0x02 ] = { .id   = TUNER_ABSENT,		     .name = "PAL_B" },	[ 0x03 ] = { .id   = TUNER_ABSENT,		     .name = "PAL_I" },	[ 0x04 ] = { .id   = TUNER_ABSENT,		     .name = "PAL_D" },	[ 0x05 ] = { .id   = TUNER_ABSENT,		     .name = "SECAM" },	[ 0x10 ] = { .id   = TUNER_ABSENT,		     .fm   = 1,		     .name = "TEMIC_4049" },	[ 0x11 ] = { .id   = TUNER_TEMIC_4136FY5,		     .name = "TEMIC_4136" },	[ 0x12 ] = { .id   = TUNER_ABSENT,		     .name = "TEMIC_4146" },	[ 0x20 ] = { .id   = TUNER_PHILIPS_FQ1216ME,		     .fm   = 1,		     .name = "PHILIPS_FQ1216_MK3" },	[ 0x21 ] = { .id   = TUNER_ABSENT, .fm = 1,		     .name = "PHILIPS_FQ1236_MK3" },	[ 0x22 ] = { .id   = TUNER_ABSENT,		     .name = "PHILIPS_FI1236_MK3" },	[ 0x23 ] = { .id   = TUNER_ABSENT,		     .name = "PHILIPS_FI1216_MK3" },};static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data){	char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))		? gdi_tuner[eeprom_data[0x0d]].name : NULL;	printk(KERN_INFO "%s: GDI: tuner=%s\n", core->name,	       name ? name : "unknown");	if (NULL == name)		return;	core->tuner_type = gdi_tuner[eeprom_data[0x0d]].id;	core->has_radio  = gdi_tuner[eeprom_data[0x0d]].fm;}/* ----------------------------------------------------------------------- */void cx88_card_list(struct cx88_core *core, struct pci_dev *pci){	int i;	if (0 == pci->subsystem_vendor &&	    0 == pci->subsystem_device) {		printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n"		       "%s: be autodetected.  Please pass card=<n> insmod option to\n"		       "%s: workaround that.  Redirect complaints to the vendor of\n"		       "%s: the TV card.  Best regards,\n"		       "%s:         -- tux\n",		       core->name,core->name,core->name,core->name,core->name);	} else {		printk("%s: Your board isn't known (yet) to the driver.  You can\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",		       core->name,core->name,core->name,core->name);	}	printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",	       core->name);	for (i = 0; i < cx88_bcount; i++)		printk("%s:    card=%d -> %s\n",		       core->name, i, cx88_boards[i].name);}void cx88_card_setup(struct cx88_core *core){	static u8 eeprom[128];	if (0 == core->i2c_rc) {		core->i2c_client.addr = 0xa0 >> 1;		tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));	}	switch (core->board) {	case CX88_BOARD_HAUPPAUGE:	case CX88_BOARD_HAUPPAUGE_ROSLYN:		if (0 == core->i2c_rc)			hauppauge_eeprom(core,eeprom+8);		break;	case CX88_BOARD_GDI:		if (0 == core->i2c_rc)			gdi_eeprom(core,eeprom);		break;	case CX88_BOARD_WINFAST2000XP_EXPERT:		if (0 == core->i2c_rc)			leadtek_eeprom(core,eeprom);		break;	case CX88_BOARD_HAUPPAUGE_DVB_T1:		if (0 == core->i2c_rc)			hauppauge_eeprom_dvb(core,eeprom);		break;	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:		/* GPIO0:0 is hooked to mt352 reset pin */		cx_set(MO_GP0_IO, 0x00000101);		cx_clear(MO_GP0_IO, 0x00000001);		msleep(1);		cx_set(MO_GP0_IO, 0x00000101);		break;	case CX88_BOARD_KWORLD_DVB_T:	case CX88_BOARD_DNTV_LIVE_DVB_T:		cx_set(MO_GP0_IO, 0x00000707);		cx_set(MO_GP2_IO, 0x00000101);		cx_clear(MO_GP2_IO, 0x00000001);		msleep(1);		cx_clear(MO_GP0_IO, 0x00000007);		cx_set(MO_GP2_IO, 0x00000101);		break;	}	if (cx88_boards[core->board].radio.type == CX88_RADIO)		core->has_radio = 1;}/* ------------------------------------------------------------------ */EXPORT_SYMBOL(cx88_boards);EXPORT_SYMBOL(cx88_bcount);EXPORT_SYMBOL(cx88_subids);EXPORT_SYMBOL(cx88_idcount);EXPORT_SYMBOL(cx88_card_list);EXPORT_SYMBOL(cx88_card_setup);/* * Local variables: * c-basic-offset: 8 * End: * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?