int saa7134_board_init2()

in pci/saa7134/saa7134-cards.c [7754:8127]


int saa7134_board_init2(struct saa7134_dev *dev)
{
	unsigned char buf;
	int board;

	/* Put here the code that enables the chips that are needed
	   for analog mode and doesn't depend on the tuner attachment.
	   It is also a good idea to get tuner type from eeprom, etc before
	   initializing tuner, since we can avoid loading tuner driver
	   on devices that has TUNER_ABSENT
	 */
	switch (dev->board) {
	case SAA7134_BOARD_BMK_MPEX_NOTUNER:
	case SAA7134_BOARD_BMK_MPEX_TUNER:
		/* Checks if the device has a tuner at 0x60 addr
		   If the device doesn't have a tuner, TUNER_ABSENT
		   will be used at tuner_type, avoiding loading tuner
		   without needing it
		 */
		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;
		pr_warn("%s: board type fixup: %s\n", dev->name,
		saa7134_boards[dev->board].name);
		dev->tuner_type = saa7134_boards[dev->board].tuner_type;

		break;
	case SAA7134_BOARD_MD7134:
	{
		u8 subaddr;
		u8 data[3], data1[] = { 0x09, 0x9f, 0x86, 0x11};
		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}},
				msg1 = {.addr = 0x61, .flags = 0, .buf = data1, .len = sizeof(data1)};

		subaddr= 0x14;
		tuner_t = 0;

		/* Retrieve device data from eeprom, checking for the
		   proper tuner_type.
		 */
		ret = i2c_transfer(&dev->i2c_adap, msg, 2);
		if (ret != 2) {
			pr_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:
				pr_err("%s Can't 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;
				pr_info("%s Board has DVB-T\n",
				       dev->name);
				break;
			default:
				pr_err("%s Can't determine tuner type %x from EEPROM\n",
				       dev->name, tuner_t);
			}
		} else {
			pr_err("%s unexpected config structure\n", dev->name);
		}

		pr_info("%s Tuner type is %d\n", dev->name, dev->tuner_type);

		/* The tuner TUNER_PHILIPS_FMD1216ME_MK3 after hardware    */
		/* start has disabled IF and enabled DVB-T. When saa7134   */
		/* scan I2C devices it will not detect IF tda9887 and can`t*/
		/* watch TV without software reboot. To solve this problem */
		/* switch the tuner to analog TV mode manually.            */
		if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
			if (i2c_transfer(&dev->i2c_adap, &msg1, 1) != 1)
				printk(KERN_WARNING "%s: Unable to enable IF of the tuner.\n", dev->name);
		}
		break;
	}
	case SAA7134_BOARD_PHILIPS_EUROPA:
		if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) {
			/* Reconfigure board as Snake reference design */
			dev->board = SAA7134_BOARD_PHILIPS_SNAKE;
			dev->tuner_type = saa7134_boards[dev->board].tuner_type;
			pr_info("%s: Reconfigured board as %s\n",
				dev->name, saa7134_boards[dev->board].name);
			break;
		}
		fallthrough;
	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
	case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
	case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
	{

		/* The Philips EUROPA based hybrid boards have the tuner
		   connected through the channel decoder. We have to make it
		   transparent to find it
		 */
		u8 data[] = { 0x07, 0x02};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);

		break;
	}
	case SAA7134_BOARD_PHILIPS_TIGER:
	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;
			pr_info("%s: Reconfigured board as %s\n",
				dev->name, saa7134_boards[dev->board].name);
		}
		if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
			dev->tuner_type = TUNER_PHILIPS_TDA8290;

			data[2] = 0x68;
			i2c_transfer(&dev->i2c_adap, &msg, 1);
			break;
		}
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	case SAA7134_BOARD_ASUSTeK_TVFM7135:
	/* The card below is detected as card=53, but is different */
	       if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
			dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
			pr_info("%s: P7131 analog only, using entry of %s\n",
				dev->name, saa7134_boards[dev->board].name);

			/*
			 * IR init has already happened for other cards, so
			 * we have to catch up.
			 */
			dev->has_remote = SAA7134_REMOTE_GPIO;
			saa7134_input_init1(dev);
	       }
	       break;
	case SAA7134_BOARD_HAUPPAUGE_HVR1150:
	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
		hauppauge_eeprom(dev, dev->eedata+0x80);
		break;
	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
		hauppauge_eeprom(dev, dev->eedata+0x80);
		fallthrough;
	case SAA7134_BOARD_PINNACLE_PCTV_310i:
	case SAA7134_BOARD_KWORLD_DVBT_210:
	case SAA7134_BOARD_TEVION_DVBT_220RF:
	case SAA7134_BOARD_ASUSTeK_TIGER:
	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
	case SAA7134_BOARD_CREATIX_CTX953:
	{
		/* this is a hybrid board, initialize to analog mode
		 * and configure firmware eeprom address
		 */
		u8 data[] = { 0x3c, 0x33, 0x60};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	case SAA7134_BOARD_ASUSTeK_TIGER_3IN1:
	{
		u8 data[] = { 0x3c, 0x33, 0x60};
		struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
							.len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	case SAA7134_BOARD_ASUSTeK_PS3_100:
	{
		u8 data[] = { 0x3c, 0x33, 0x60};
		struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
						       .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	case SAA7134_BOARD_FLYDVB_TRIO:
	{
		u8 temp = 0;
		int rc;
		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);

		/*
		 * send weak up message to pic16C505 chip
		 * @ LifeView FlyDVB Trio
		 */
		msg.buf = &temp;
		msg.addr = 0x0b;
		msg.len = 1;
		if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) {
			pr_warn("%s: send wake up byte to pic16C505(IR chip) failed\n",
				dev->name);
		} else {
			msg.flags = I2C_M_RD;
			rc = i2c_transfer(&dev->i2c_adap, &msg, 1);
			pr_info("%s: probe IR chip @ i2c 0x%02x: %s\n",
				   dev->name, msg.addr,
				   (1 == rc) ? "yes" : "no");
			if (rc == 1)
				dev->has_remote = SAA7134_REMOTE_I2C;
		}
		break;
	}
	case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
	case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
	{
		/* initialize analog mode  */
		u8 data[] = { 0x3c, 0x33, 0x6a};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
	case SAA7134_BOARD_CINERGY_HT_PCI:
	{
		/* initialize analog mode */
		u8 data[] = { 0x3c, 0x33, 0x68};
		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
		i2c_transfer(&dev->i2c_adap, &msg, 1);
		break;
	}
	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;
			pr_info("%s: Reconfigured board as %s\n",
				dev->name, saa7134_boards[dev->board].name);
		} else {
			pr_warn("%s: Unexpected tuner type info: %x in eeprom\n",
				dev->name, dev->eedata[0x41]);
			break;
		}
		break;
	case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
	case SAA7134_BOARD_KWORLD_ATSC110:
	{
		struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
		int i;
		static u8 buffer[][2] = {
			{ 0x10, 0x12 },
			{ 0x13, 0x04 },
			{ 0x16, 0x00 },
			{ 0x14, 0x04 },
			{ 0x17, 0x00 },
		};

		for (i = 0; i < ARRAY_SIZE(buffer); i++) {
			msg.buf = &buffer[i][0];
			msg.len = ARRAY_SIZE(buffer[0]);
			if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
				pr_warn("%s: Unable to enable tuner(%i).\n",
					dev->name, i);
		}
		break;
	}
	case SAA7134_BOARD_BEHOLD_H6:
	{
		u8 data[] = { 0x09, 0x9f, 0x86, 0x11};
		struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = data,
							.len = sizeof(data)};

		/* The tuner TUNER_PHILIPS_FMD1216MEX_MK3 after hardware    */
		/* start has disabled IF and enabled DVB-T. When saa7134    */
		/* scan I2C devices it not detect IF tda9887 and can`t      */
		/* watch TV without software reboot. For solve this problem */
		/* switch the tuner to analog TV mode manually.             */
		if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
			pr_warn("%s: Unable to enable IF of the tuner.\n",
				dev->name);
		break;
	}
	case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);

		saa7134_set_gpio(dev, 27, 0);
		break;
	} /* switch() */

	/* initialize tuner (don't do this when resuming) */
	if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) {
		int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);

		/* Note: radio tuner address is always filled in,
		   so we do not need to probe for a radio tuner device. */
		if (dev->radio_type != UNSET)
			v4l2_i2c_new_subdev(&dev->v4l2_dev,
				&dev->i2c_adap, "tuner",
				dev->radio_addr, NULL);
		if (has_demod)
			v4l2_i2c_new_subdev(&dev->v4l2_dev,
				&dev->i2c_adap, "tuner",
				0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
		if (dev->tuner_addr == ADDR_UNSET) {
			enum v4l2_i2c_tuner_type type =
				has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;

			v4l2_i2c_new_subdev(&dev->v4l2_dev,
				&dev->i2c_adap, "tuner",
				0, v4l2_i2c_tuner_addrs(type));
		} else {
			v4l2_i2c_new_subdev(&dev->v4l2_dev,
				&dev->i2c_adap, "tuner",
				dev->tuner_addr, NULL);
		}
	}

	saa7134_tuner_setup(dev);

	switch (dev->board) {
	case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
	{
		struct v4l2_priv_tun_config tea5767_cfg;
		struct tea5767_ctrl ctl;

		dev->i2c_client.addr = 0xC0;
		/* set TEA5767(analog FM) defines */
		memset(&ctl, 0, sizeof(ctl));
		ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
		tea5767_cfg.tuner = TUNER_TEA5767;
		tea5767_cfg.priv  = &ctl;
		saa_call_all(dev, tuner, s_config, &tea5767_cfg);
		break;
	}
	} /* switch() */

	return 0;
}