/*
 * Fitipower FC0011 tuner driver
 *
 * Copyright (C) 2012 Michael Buesch <m@bues.ch>
 *
 * Derived from FC0012 tuner driver:
 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "fc0011.h"


/* Tuner registers */
enum {
	FC11_REG_0,
	FC11_REG_FA,		/* FA */
	FC11_REG_FP,		/* FP */
	FC11_REG_XINHI,		/* XIN high 8 bit */
	FC11_REG_XINLO,		/* XIN low 8 bit */
	FC11_REG_VCO,		/* VCO */
	FC11_REG_VCOSEL,	/* VCO select */
	FC11_REG_7,		/* Unknown tuner reg 7 */
	FC11_REG_8,		/* Unknown tuner reg 8 */
	FC11_REG_9,
	FC11_REG_10,		/* Unknown tuner reg 10 */
	FC11_REG_11,		/* Unknown tuner reg 11 */
	FC11_REG_12,
	FC11_REG_RCCAL,		/* RC calibrate */
	FC11_REG_VCOCAL,	/* VCO calibrate */
	FC11_REG_15,
	FC11_REG_16,		/* Unknown tuner reg 16 */
	FC11_REG_17,

	FC11_NR_REGS,		/* Number of registers */
};

enum FC11_REG_VCOSEL_bits {
	FC11_VCOSEL_2		= 0x08, /* VCO select 2 */
	FC11_VCOSEL_1		= 0x10, /* VCO select 1 */
	FC11_VCOSEL_CLKOUT	= 0x20, /* Fix clock out */
	FC11_VCOSEL_BW7M	= 0x40, /* 7MHz bw */
	FC11_VCOSEL_BW6M	= 0x80, /* 6MHz bw */
};

enum FC11_REG_RCCAL_bits {
	FC11_RCCAL_FORCE	= 0x10, /* force */
};

enum FC11_REG_VCOCAL_bits {
	FC11_VCOCAL_RUN		= 0,	/* VCO calibration run */
	FC11_VCOCAL_VALUEMASK	= 0x3F,	/* VCO calibration value mask */
	FC11_VCOCAL_OK		= 0x40,	/* VCO calibration Ok */
	FC11_VCOCAL_RESET	= 0x80, /* VCO calibration reset */
};


struct fc0011_priv {
	struct i2c_adapter *i2c;
	u8 addr;

	u32 frequency;
	u32 bandwidth;
};


static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
{
	u8 buf[2] = { reg, val };
	struct i2c_msg msg = { .addr = priv->addr,
		.flags = 0, .buf = buf, .len = 2 };

	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
		dev_err(&priv->i2c->dev,
			"I2C write reg failed, reg: %02x, val: %02x\n",
			reg, val);
		return -EIO;
	}

	return 0;
}

static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
{
	u8 dummy;
	struct i2c_msg msg[2] = {
		{ .addr = priv->addr,
		  .flags = 0, .buf = &reg, .len = 1 },
		{ .addr = priv->addr,
		  .flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
	};

	if (i2c_transfer(priv->i2c, msg, 2) != 2) {
		dev_err(&priv->i2c->dev,
			"I2C read failed, reg: %02x\n", reg);
		return -EIO;
	}

	return 0;
}

static void fc0011_release(struct dvb_frontend *fe)
{
	kfree(fe->tuner_priv);
	fe->tuner_priv = NULL;
}

static int fc0011_init(struct dvb_frontend *fe)
{
	struct fc0011_priv *priv = fe->tuner_priv;
	int err;

	if (WARN_ON(!fe->callback))
		return -EINVAL;

	err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
			   FC0011_FE_CALLBACK_POWER, priv->addr);
	if (err) {
		dev_err(&priv->i2c->dev, "Power-on callback failed\n");
		return err;
	}
	err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
			   FC0011_FE_CALLBACK_RESET, priv->addr);
	if (err) {
		dev_err(&priv->i2c->dev, "Reset callback failed\n");
		return err;
	}

	return 0;
}

/* Initiate VCO calibration */
static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
{
	int err;

	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
	if (err)
		return err;
	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
	if (err)
		return err;

	return 0;
}

/* Read VCO calibration value */
static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
{
	int err;

	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
	if (err)
		return err;
	usleep_range(10000, 20000);
	err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
	if (err)
		return err;

	return 0;
}

static int fc0011_set_params(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	struct fc0011_priv *priv = fe->tuner_priv;
	int err;
	unsigned int i, vco_retries;
	u32 freq = p->frequency / 1000;
	u32 bandwidth = p->bandwidth_hz / 1000;
	u32 fvco, xin, frac, xdiv, xdivr;
	u8 fa, fp, vco_sel, vco_cal;
	u8 regs[FC11_NR_REGS] = { };

	regs[FC11_REG_7] = 0x0F;
	regs[FC11_REG_8] = 0x3E;
	regs[FC11_REG_10] = 0xB8;
	regs[FC11_REG_11] = 0x80;
	regs[FC11_REG_RCCAL] = 0x04;
	err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
	err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
	err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
	err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
	err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
	if (err)
		return -EIO;

	/* Set VCO freq and VCO div */
	if (freq < 54000) {
		fvco = freq * 64;
		regs[FC11_REG_VCO] = 0x82;
	} else if (freq < 108000) {
		fvco = freq * 32;
		regs[FC11_REG_VCO] = 0x42;
	} else if (freq < 216000) {
		fvco = freq * 16;
		regs[FC11_REG_VCO] = 0x22;
	} else if (freq < 432000) {
		fvco = freq * 8;
		regs[FC11_REG_VCO] = 0x12;
	} else {
		fvco = freq * 4;
		regs[FC11_REG_VCO] = 0x0A;
	}

	/* Calc XIN. The PLL reference frequency is 18 MHz. */
	xdiv = fvco / 18000;
	WARN_ON(xdiv > 0xFF);
	frac = fvco - xdiv * 18000;
	frac = (frac << 15) / 18000;
	if (frac >= 16384)
		frac += 32786;
	if (!frac)
		xin = 0;
	else
		xin = clamp_t(u32, frac, 512, 65024);
	regs[FC11_REG_XINHI] = xin >> 8;
	regs[FC11_REG_XINLO] = xin;

	/* Calc FP and FA */
	xdivr = xdiv;
	if (fvco - xdiv * 18000 >= 9000)
		xdivr += 1; /* round */
	fp = xdivr / 8;
	fa = xdivr - fp * 8;
	if (fa < 2) {
		fp -= 1;
		fa += 8;
	}
	if (fp > 0x1F) {
		fp = 0x1F;
		fa = 0xF;
	}
	if (fa >= fp) {
		dev_warn(&priv->i2c->dev,
			 "fa %02X >= fp %02X, but trying to continue\n",
			 (unsigned int)(u8)fa, (unsigned int)(u8)fp);
	}
	regs[FC11_REG_FA] = fa;
	regs[FC11_REG_FP] = fp;

	/* Select bandwidth */
	switch (bandwidth) {
	case 8000:
		break;
	case 7000:
		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
		break;
	default:
		dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. Using 6000 kHz.\n",
			 bandwidth);
		bandwidth = 6000;
		/* fallthrough */
	case 6000:
		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
		break;
	}

	/* Pre VCO select */
	if (fvco < 2320000) {
		vco_sel = 0;
		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
	} else if (fvco < 3080000) {
		vco_sel = 1;
		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
	} else {
		vco_sel = 2;
		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
	}

	/* Fix for low freqs */
	if (freq < 45000) {
		regs[FC11_REG_FA] = 0x6;
		regs[FC11_REG_FP] = 0x11;
	}

	/* Clock out fix */
	regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;

	/* Write the cached registers */
	for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
		err = fc0011_writereg(priv, i, regs[i]);
		if (err)
			return err;
	}

	/* VCO calibration */
	err = fc0011_vcocal_trigger(priv);
	if (err)
		return err;
	err = fc0011_vcocal_read(priv, &vco_cal);
	if (err)
		return err;
	vco_retries = 0;
	while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
		/* Reset the tuner and try again */
		err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
				   FC0011_FE_CALLBACK_RESET, priv->addr);
		if (err) {
			dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
			return err;
		}
		/* Reinit tuner config */
		err = 0;
		for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
			err |= fc0011_writereg(priv, i, regs[i]);
		err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
		err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
		err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
		err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
		err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
		if (err)
			return -EIO;
		/* VCO calibration */
		err = fc0011_vcocal_trigger(priv);
		if (err)
			return err;
		err = fc0011_vcocal_read(priv, &vco_cal);
		if (err)
			return err;
		vco_retries++;
	}
	if (!(vco_cal & FC11_VCOCAL_OK)) {
		dev_err(&priv->i2c->dev,
			"Failed to read VCO calibration value (got %02X)\n",
			(unsigned int)vco_cal);
		return -EIO;
	}
	vco_cal &= FC11_VCOCAL_VALUEMASK;

	switch (vco_sel) {
	default:
		WARN_ON(1);
		return -EINVAL;
	case 0:
		if (vco_cal < 8) {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
			err = fc0011_vcocal_trigger(priv);
			if (err)
				return err;
		} else {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
		}
		break;
	case 1:
		if (vco_cal < 5) {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
			err = fc0011_vcocal_trigger(priv);
			if (err)
				return err;
		} else if (vco_cal <= 48) {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
		} else {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
			err = fc0011_vcocal_trigger(priv);
			if (err)
				return err;
		}
		break;
	case 2:
		if (vco_cal > 53) {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
			err = fc0011_vcocal_trigger(priv);
			if (err)
				return err;
		} else {
			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
					      regs[FC11_REG_VCOSEL]);
			if (err)
				return err;
		}
		break;
	}
	err = fc0011_vcocal_read(priv, NULL);
	if (err)
		return err;
	usleep_range(10000, 50000);

	err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
	if (err)
		return err;
	regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
	err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
	if (err)
		return err;
	regs[FC11_REG_16] = 0xB;
	err = fc0011_writereg(priv, FC11_REG_16, regs[FC11_REG_16]);
	if (err)
		return err;

	dev_dbg(&priv->i2c->dev, "Tuned to fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X vcocal=%02X(%u) bw=%u\n",
		(unsigned int)regs[FC11_REG_FA],
		(unsigned int)regs[FC11_REG_FP],
		(unsigned int)regs[FC11_REG_XINHI],
		(unsigned int)regs[FC11_REG_XINLO],
		(unsigned int)regs[FC11_REG_VCO],
		(unsigned int)regs[FC11_REG_VCOSEL],
		(unsigned int)vco_cal, vco_retries,
		(unsigned int)bandwidth);

	priv->frequency = p->frequency;
	priv->bandwidth = p->bandwidth_hz;

	return 0;
}

static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct fc0011_priv *priv = fe->tuner_priv;

	*frequency = priv->frequency;

	return 0;
}

static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	*frequency = 0;

	return 0;
}

static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
	struct fc0011_priv *priv = fe->tuner_priv;

	*bandwidth = priv->bandwidth;

	return 0;
}

static const struct dvb_tuner_ops fc0011_tuner_ops = {
	.info = {
		.name		  = "Fitipower FC0011",

		.frequency_min_hz =   45 * MHz,
		.frequency_max_hz = 1000 * MHz,
	},

	.release		= fc0011_release,
	.init			= fc0011_init,

	.set_params		= fc0011_set_params,

	.get_frequency		= fc0011_get_frequency,
	.get_if_frequency	= fc0011_get_if_frequency,
	.get_bandwidth		= fc0011_get_bandwidth,
};

struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
				   struct i2c_adapter *i2c,
				   const struct fc0011_config *config)
{
	struct fc0011_priv *priv;

	priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
	if (!priv)
		return NULL;

	priv->i2c = i2c;
	priv->addr = config->i2c_address;

	fe->tuner_priv = priv;
	fe->ops.tuner_ops = fc0011_tuner_ops;

	dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");

	return fe;
}
EXPORT_SYMBOL(fc0011_attach);

MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
MODULE_LICENSE("GPL");
