/* FMD1216ME status  */
#define FMD1216ME_RETRY (4)
#define FMD1216ME_FAIL (0xFF)
static u8 fmd1216me_get_status(struct cx88_core *core, const char *name, int addr, int bit)
{
	u8 status[1];
	struct i2c_msg status_msg = {
		.flags = I2C_M_RD, .addr = addr, .buf = status, .len = 1
	};
	int rc, retry = FMD1216ME_RETRY;

	do {
		udelay(500);
		status[0] = bit;
		rc = i2c_transfer (core->i2c_client.adapter, &status_msg, 1);
		dprintk (1, "i2c init: FMD1216ME(X) init %s (%d) "
			"(status = %02x, rc = %d)\n", name,
			1 + FMD1216ME_RETRY - retry,
			status[0], rc);
	}
	while ((status[0] & bit) && retry--);
	if (rc != 1 || (status[0] & bit)) {
		printk ("%s: i2c init: FMD1216ME(X) init %s failed "
			"(retry = %d, rc = %d, status = 0x%02x)\n",
			core->name, name, retry, rc, status[0]);
		return FMD1216ME_FAIL;
	}
	return status[0];
}

/*
 * FMD1216ME init.
 *
 * Allow TDA9887 to be detected and attached.
 *
 * This may need prior cx22702/demod reset or gate ctrl.
 */
static void fmd1216me_init(struct cx88_core *core)
{
	u8 pll_status, demod_status, pll_data[] = {
		0xde, 0x60, /* disable AGC */
		0xc6, 0x14, /* enable  TDA9887 */
		0xc6, 0x03, /* disable TDA9887 */
		0xc6, 0x14, /* enable  TDA9887 */
	};
	struct i2c_msg pll_msg = {
		.flags = 0, .addr = 0x61, .buf = pll_data, .len = 8
	};
	int rc;

	/* Wait for PLL power up */
	pll_status = fmd1216me_get_status (core, "pll", 0x61, 0x80);
	if (pll_status == FMD1216ME_FAIL)
		return;

	/* Init PLL / Reset demod */
	rc = i2c_transfer (core->i2c_client.adapter, &pll_msg, 1);
	if (rc != 1) {
		printk ("%s: i2c init: FMD1216ME(X) init failed "
			"(rc = %d)\n", core->name, rc);
		return;
	}

	/* Wait for demod power up */
	demod_status = fmd1216me_get_status (core, "demod", 0x43, 0x01);
	if (demod_status == FMD1216ME_FAIL)
		return;

	dprintk (1, "i2c init: FMD1216ME(X) init succeeded "
			"(pll = 0x%02x, demod = 0x%02x)\n",
			pll_status, demod_status);
}
