/*
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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 int fc0011_release(struct dvb_frontend *fe)
{
	kfree(fe->tuner_priv);
	fe->tuner_priv = NULL;

	return 0;
}

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);
	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	= 45000000,
		.frequency_max	= 1000000000,
	},

	.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");
