saa7134-cards.c 130 KB
Newer Older
5001
5002
5003
5004
		saa_writeb(SAA7134_GPIO_GPMODE3, 0x80);
		saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x40);
		dev->has_remote = SAA7134_REMOTE_GPIO;
		break;
Linus Torvalds's avatar
Linus Torvalds committed
5005
5006
	case SAA7134_BOARD_MD5044:
		printk("%s: seems there are two different versions of the MD5044\n"
5007
5008
5009
		       "%s: (with the same ID) out there.  If sound doesn't work for\n"
		       "%s: you try the audio_clock_override=0x200000 insmod option.\n",
		       dev->name,dev->name,dev->name);
Linus Torvalds's avatar
Linus Torvalds committed
5010
5011
5012
5013
5014
		break;
	case SAA7134_BOARD_CINERGY400_CARDBUS:
		/* power-up tuner chip */
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
5015
		break;
5016
5017
5018
5019
5020
	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
		/* this turns the remote control chip off to work around a bug in it */
		saa_writeb(SAA7134_GPIO_GPMODE1, 0x80);
		saa_writeb(SAA7134_GPIO_GPSTATUS1, 0x80);
		break;
5021
5022
5023
5024
	case SAA7134_BOARD_MONSTERTV_MOBILE:
		/* power-up tuner chip */
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
Linus Torvalds's avatar
Linus Torvalds committed
5025
		break;
5026
	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
5027
		/* turn the fan on */
5028
5029
5030
		saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
		saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
		break;
5031
	case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
5032
	case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
5033
5034
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08000000, 0x08000000);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
5035
		break;
5036
	case SAA7134_BOARD_AVERMEDIA_CARDBUS:
5037
	case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
5038
5039
5040
5041
5042
		/* power-up tuner chip */
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
		msleep(1);
		break;
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
	case SAA7134_BOARD_RTD_VFG7350:

		/*
		 * Make sure Production Test Register at offset 0x1D1 is cleared
		 * to take chip out of test mode.  Clearing bit 4 (TST_EN_AOUT)
		 * prevents pin 105 from remaining low; keeping pin 105 low
		 * continually resets the SAA6752 chip.
		 */

		saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
		break;
5054
5055
	/* i2c remotes */
	case SAA7134_BOARD_PINNACLE_PCTV_110i:
5056
	case SAA7134_BOARD_PINNACLE_PCTV_310i:
5057
	case SAA7134_BOARD_UPMOST_PURPLE_TV:
5058
	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
5059
5060
	case SAA7134_BOARD_BEHOLD_607_9FM:
	case SAA7134_BOARD_BEHOLD_M6:
5061
5062
		dev->has_remote = SAA7134_REMOTE_I2C;
		break;
5063
	case SAA7134_BOARD_AVERMEDIA_A169_B:
5064
	case SAA7134_BOARD_MD7134_BRIDGE_2:
5065
		printk("%s: %s: dual saa713x broadcast decoders\n"
5066
5067
		       "%s: Sorry, none of the inputs to this chip are supported yet.\n"
		       "%s: Dual decoder functionality is disabled for now, use the other chip.\n",
5068
		       dev->name,card(dev).name,dev->name,dev->name);
5069
		break;
5070
5071
	case SAA7134_BOARD_AVERMEDIA_M102:
		/* enable tuner */
5072
	       dev->has_remote = SAA7134_REMOTE_GPIO;
5073
5074
5075
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x8c040007, 0x8c040007);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
		break;
Linus Torvalds's avatar
Linus Torvalds committed
5076
5077
5078
5079
5080
5081
5082
5083
5084
	}
	return 0;
}

/* stuff which needs working i2c */
int saa7134_board_init2(struct saa7134_dev *dev)
{
	unsigned char buf;
	int board;
5085
5086
5087
	struct tuner_setup tun_setup;
	tun_setup.config = 0;
	tun_setup.tuner_callback = saa7134_tuner_callback;
Linus Torvalds's avatar
Linus Torvalds committed
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099

	switch (dev->board) {
	case SAA7134_BOARD_BMK_MPEX_NOTUNER:
	case SAA7134_BOARD_BMK_MPEX_TUNER:
		dev->i2c_client.addr = 0x60;
		board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0)
			? SAA7134_BOARD_BMK_MPEX_NOTUNER
			: SAA7134_BOARD_BMK_MPEX_TUNER;
		if (board == dev->board)
			break;
		dev->board = board;
		printk("%s: board type fixup: %s\n", dev->name,
5100
		saa7134_boards[dev->board].name);
Linus Torvalds's avatar
Linus Torvalds committed
5101
		dev->tuner_type = saa7134_boards[dev->board].tuner_type;
5102
5103
5104
5105
5106
5107
5108
5109
5110

		if (TUNER_ABSENT != dev->tuner_type) {
				tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
				tun_setup.type = dev->tuner_type;
				tun_setup.addr = ADDR_UNSET;

				saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
		}
		break;
5111
	case SAA7134_BOARD_MD7134:
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
		{
		u8 subaddr;
		u8 data[3];
		int ret, tuner_t;

		struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
					{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
		subaddr= 0x14;
		tuner_t = 0;
		ret = i2c_transfer(&dev->i2c_adap, msg, 2);
		if (ret != 2) {
			printk(KERN_ERR "EEPROM read failure\n");
		} else if ((data[0] != 0) && (data[0] != 0xff)) {
			/* old config structure */
			subaddr = data[0] + 2;
			msg[1].len = 2;
			i2c_transfer(&dev->i2c_adap, msg, 2);
			tuner_t = (data[0] << 8) + data[1];
			switch (tuner_t){
			case 0x0103:
				dev->tuner_type = TUNER_PHILIPS_PAL;
				break;
			case 0x010C:
				dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
				break;
			default:
				printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
			}
		} else if ((data[1] != 0) && (data[1] != 0xff)) {
			/* new config structure */
			subaddr = data[1] + 1;
			msg[1].len = 1;
			i2c_transfer(&dev->i2c_adap, msg, 2);
			subaddr = data[0] + 1;
			msg[1].len = 2;
			i2c_transfer(&dev->i2c_adap, msg, 2);
			tuner_t = (data[1] << 8) + data[0];
			switch (tuner_t) {
			case 0x0005:
				dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
				break;
			case 0x001d:
				dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3;
					printk(KERN_INFO "%s Board has DVB-T\n", dev->name);
				break;
			default:
				printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
			}
		} else {
			printk(KERN_ERR "%s unexpected config structure\n", dev->name);
		}

		printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
		if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
			struct v4l2_priv_tun_config tda9887_cfg;

			tda9887_cfg.tuner = TUNER_TDA9887;
			tda9887_cfg.priv  = &dev->tda9887_conf;

			dev->tda9887_conf = TDA9887_PRESENT      |
					    TDA9887_PORT1_ACTIVE |
					    TDA9887_PORT2_ACTIVE;

			saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
						 &tda9887_cfg);
5177
5178
5179
5180
5181
5182
5183
5184
		}

		tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
		tun_setup.type = dev->tuner_type;
		tun_setup.addr = ADDR_UNSET;

		saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
		}
Linus Torvalds's avatar
Linus Torvalds committed
5185
		break;
5186
5187
	case SAA7134_BOARD_PHILIPS_EUROPA:
	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
5188
	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
5189
5190
		/* The Philips EUROPA based hybrid boards have the tuner connected through
		 * the channel decoder. We have to make it transparent to find it
5191
		 */
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
		{
		u8 data[] = { 0x07, 0x02};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);

		tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
		tun_setup.type = dev->tuner_type;
		tun_setup.addr = dev->tuner_addr;

		saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
5202
		}
5203
		break;
5204
	case SAA7134_BOARD_PHILIPS_TIGER:
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
	case SAA7134_BOARD_PHILIPS_TIGER_S:
		{
		u8 data[] = { 0x3c, 0x33, 0x60};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		if(dev->autodetected && (dev->eedata[0x49] == 0x50)) {
			dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
			printk(KERN_INFO "%s: Reconfigured board as %s\n",
				dev->name, saa7134_boards[dev->board].name);
		}
		if(dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
			tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
			tun_setup.type = TUNER_PHILIPS_TDA8290;
			tun_setup.addr = 0x4b;
			tun_setup.config = 2;

			saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
			data[2] = 0x68;
		}
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		}
		break;
5226
5227
5228
	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
		hauppauge_eeprom(dev, dev->eedata+0x80);
		/* break intentionally omitted */
5229
	case SAA7134_BOARD_PINNACLE_PCTV_310i:
5230
	case SAA7134_BOARD_KWORLD_DVBT_210:
5231
	case SAA7134_BOARD_TEVION_DVBT_220RF:
5232
	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
5233
	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
5234
	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
5235
       case SAA7134_BOARD_AVERMEDIA_SUPER_007:
5236
5237
5238
		/* this is a hybrid board, initialize to analog mode
		 * and configure firmware eeprom address
		 */
5239
		{
5240
		u8 data[] = { 0x3c, 0x33, 0x60};
5241
5242
5243
5244
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		}
		break;
5245
	case SAA7134_BOARD_FLYDVB_TRIO:
5246
5247
5248
5249
5250
5251
		{
		u8 data[] = { 0x3c, 0x33, 0x62};
		struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		}
		break;
5252
	case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
5253
	case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
5254
		/* initialize analog mode  */
5255
		{
5256
		u8 data[] = { 0x3c, 0x33, 0x6a};
5257
5258
5259
5260
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		}
		break;
5261
	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
5262
	case SAA7134_BOARD_CINERGY_HT_PCI:
5263
		/* initialize analog mode */
5264
		{
5265
		u8 data[] = { 0x3c, 0x33, 0x68};
5266
5267
5268
5269
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		}
		break;
5270
5271
5272
5273
	case SAA7134_BOARD_KWORLD_ATSC110:
		{
			/* enable tuner */
			int i;
5274
			static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
5275
5276
5277
5278
5279
5280
5281
			dev->i2c_client.addr = 0x0a;
			for (i = 0; i < 5; i++)
				if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2))
					printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
					       dev->name, i);
		}
		break;
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
	case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
		/* The T200 and the T200A share the same pci id.  Consequently,
		 * we are going to query eeprom to try to find out which one we
		 * are actually looking at. */

		/* Don't do this if the board was specifically selected with an
		 * insmod option or if we have the default configuration T200*/
		if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
			break;
		if(dev->eedata[0x41] == 0x02) {
			/* Reconfigure board  as T200A */
			dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
			dev->tuner_type   = saa7134_boards[dev->board].tuner_type;
			dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
			printk(KERN_INFO "%s: Reconfigured board as %s\n",
				dev->name, saa7134_boards[dev->board].name);
		} else {
			printk(KERN_WARNING "%s: Unexpected tuner type info: %x in eeprom\n",
				dev->name, dev->eedata[0x41]);
			break;
		}
		break;
Linus Torvalds's avatar
Linus Torvalds committed
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
	}
	return 0;
}

/* ----------------------------------------------------------- */
/*
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
For faster browsing, not all history is shown. View entire blame