/*
 * stv6110.c
 *
 * Driver for ST STV6110 satellite tuner IC.
 *
 * Copyright (C) 2009 NetUP Inc.
 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
 *
 * 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 <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>

#include <linux/types.h>

#include "stv6110.h"

/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  64

static int debug;

struct stv6110_priv {
	int i2c_address;
	struct i2c_adapter *i2c;

	u32 mclk;
	u8 clk_div;
	u8 gain;
	u8 regs[8];
};

#define dprintk(args...) \
	do { \
		if (debug) \
			printk(KERN_DEBUG args); \
	} while (0)

static s32 abssub(s32 a, s32 b)
{
	if (a > b)
		return a - b;
	else
		return b - a;
};

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

static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
							int start, int len)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	int rc;
	u8 cmdbuf[MAX_XFER_SIZE];
	struct i2c_msg msg = {
		.addr	= priv->i2c_address,
		.flags	= 0,
		.buf	= cmdbuf,
		.len	= len + 1
	};

	dprintk("%s\n", __func__);

	if (1 + len > sizeof(cmdbuf)) {
		printk(KERN_WARNING
		       "%s: i2c wr: len=%d is too big!\n",
		       KBUILD_MODNAME, len);
		return -EINVAL;
	}

	if (start + len > 8)
		return -EINVAL;

	memcpy(&cmdbuf[1], buf, len);
	cmdbuf[0] = start;

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	rc = i2c_transfer(priv->i2c, &msg, 1);
	if (rc != 1)
		dprintk("%s: i2c error\n", __func__);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	return 0;
}

static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
							int start, int len)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	int rc;
	u8 reg[] = { start };
	struct i2c_msg msg[] = {
		{
			.addr	= priv->i2c_address,
			.flags	= 0,
			.buf	= reg,
			.len	= 1,
		}, {
			.addr	= priv->i2c_address,
			.flags	= I2C_M_RD,
			.buf	= regs,
			.len	= len,
		},
	};

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	rc = i2c_transfer(priv->i2c, msg, 2);
	if (rc != 2)
		dprintk("%s: i2c error\n", __func__);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	memcpy(&priv->regs[start], regs, len);

	return 0;
}

static int stv6110_read_reg(struct dvb_frontend *fe, int start)
{
	u8 buf[] = { 0 };
	stv6110_read_regs(fe, buf, start, 1);

	return buf[0];
}

static int stv6110_sleep(struct dvb_frontend *fe)
{
	u8 reg[] = { 0 };
	stv6110_write_regs(fe, reg, 0, 1);

	return 0;
}

static u32 carrier_width(u32 symbol_rate, enum fe_rolloff rolloff)
{
	u32 rlf;

	switch (rolloff) {
	case ROLLOFF_20:
		rlf = 20;
		break;
	case ROLLOFF_25:
		rlf = 25;
		break;
	default:
		rlf = 35;
		break;
	}

	return symbol_rate  + ((symbol_rate * rlf) / 100);
}

static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 r8, ret = 0x04;
	int i;

	if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
		r8 = 31;
	else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
		r8 = 0;
	else /*if 5 < BW/2 < 36*/
		r8 = (bandwidth / 2) / 1000000 - 5;

	/* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
	/* ctrl3, CF = r8 Set the LPF value */
	priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
	priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
	/* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
	priv->regs[RSTV6110_STAT1] |= 0x02;
	stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);

	i = 0;
	/* Wait for CALRCSTRT == 0 */
	while ((i < 10) && (ret != 0)) {
		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
		mdelay(1);	/* wait for LPF auto calibration */
		i++;
	}

	/* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
	priv->regs[RSTV6110_CTRL3] |= (1 << 6);
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
	return 0;
}

static int stv6110_init(struct dvb_frontend *fe)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };

	memcpy(priv->regs, buf0, 8);
	/* K = (Reference / 1000000) - 16 */
	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
	priv->regs[RSTV6110_CTRL1] |=
				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);

	/* divisor value for the output clock */
	priv->regs[RSTV6110_CTRL2] &= ~0xc0;
	priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);

	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
	msleep(1);
	stv6110_set_bandwidth(fe, 72000000);

	return 0;
}

static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u32 nbsteps, divider, psd2, freq;
	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };

	stv6110_read_regs(fe, regs, 0, 8);
	/*N*/
	divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
	divider += priv->regs[RSTV6110_TUNING1];

	/*R*/
	nbsteps  = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
	/*p*/
	psd2  = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;

	freq = divider * (priv->mclk / 1000);
	freq /= (1 << (nbsteps + psd2));
	freq /= 4;

	*frequency = freq;

	return 0;
}

static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u8 ret = 0x04;
	u32 divider, ref, p, presc, i, result_freq, vco_freq;
	s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
	s32 srate;

	dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
						frequency, priv->mclk);

	/* K = (Reference / 1000000) - 16 */
	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
	priv->regs[RSTV6110_CTRL1] |=
				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);

	/* BB_GAIN = db/2 */
	if (fe->ops.set_property && fe->ops.get_property) {
		srate = c->symbol_rate;
		dprintk("%s: Get Frontend parameters: srate=%d\n",
							__func__, srate);
	} else
		srate = 15000000;

	priv->regs[RSTV6110_CTRL2] &= ~0x0f;
	priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);

	if (frequency <= 1023000) {
		p = 1;
		presc = 0;
	} else if (frequency <= 1300000) {
		p = 1;
		presc = 1;
	} else if (frequency <= 2046000) {
		p = 0;
		presc = 0;
	} else {
		p = 0;
		presc = 1;
	}
	/* DIV4SEL = p*/
	priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
	priv->regs[RSTV6110_TUNING2] |= (p << 4);

	/* PRESC32ON = presc */
	priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
	priv->regs[RSTV6110_TUNING2] |= (presc << 5);

	p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
	for (r_div = 0; r_div <= 3; r_div++) {
		p_calc = (priv->mclk / 100000);
		p_calc /= (1 << (r_div + 1));
		if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
			r_div_opt = r_div;

		p_calc_opt = (priv->mclk / 100000);
		p_calc_opt /= (1 << (r_div_opt + 1));
	}

	ref = priv->mclk / ((1 << (r_div_opt + 1))  * (1 << (p + 1)));
	divider = (((frequency * 1000) + (ref >> 1)) / ref);

	/* RDIV = r_div_opt */
	priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
	priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);

	/* NDIV_MSB = MSB(divider) */
	priv->regs[RSTV6110_TUNING2] &= ~0x0f;
	priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);

	/* NDIV_LSB, LSB(divider) */
	priv->regs[RSTV6110_TUNING1] = (divider & 0xff);

	/* CALVCOSTRT = 1 VCO Auto Calibration */
	priv->regs[RSTV6110_STAT1] |= 0x04;
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
						RSTV6110_CTRL1, 8);

	i = 0;
	/* Wait for CALVCOSTRT == 0 */
	while ((i < 10) && (ret != 0)) {
		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
		msleep(1); /* wait for VCO auto calibration */
		i++;
	}

	ret = stv6110_read_reg(fe, RSTV6110_STAT1);
	stv6110_get_frequency(fe, &result_freq);

	vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
	dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
						ret, result_freq, vco_freq);

	return 0;
}

static int stv6110_set_params(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);

	stv6110_set_frequency(fe, c->frequency);
	stv6110_set_bandwidth(fe, bandwidth);

	return 0;
}

static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 r8 = 0;
	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	stv6110_read_regs(fe, regs, 0, 8);

	/* CF */
	r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
	*bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */

	return 0;
}

static const struct dvb_tuner_ops stv6110_tuner_ops = {
	.info = {
		.name = "ST STV6110",
		.frequency_min = 950000,
		.frequency_max = 2150000,
		.frequency_step = 1000,
	},
	.init = stv6110_init,
	.release = stv6110_release,
	.sleep = stv6110_sleep,
	.set_params = stv6110_set_params,
	.get_frequency = stv6110_get_frequency,
	.set_frequency = stv6110_set_frequency,
	.get_bandwidth = stv6110_get_bandwidth,
	.set_bandwidth = stv6110_set_bandwidth,

};

struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
					const struct stv6110_config *config,
					struct i2c_adapter *i2c)
{
	struct stv6110_priv *priv = NULL;
	u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };

	struct i2c_msg msg[] = {
		{
			.addr = config->i2c_address,
			.flags = 0,
			.buf = reg0,
			.len = 9
		}
	};
	int ret;

	/* divisor value for the output clock */
	reg0[2] &= ~0xc0;
	reg0[2] |= (config->clk_div << 6);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	ret = i2c_transfer(i2c, msg, 1);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	if (ret != 1)
		return NULL;

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

	priv->i2c_address = config->i2c_address;
	priv->i2c = i2c;
	priv->mclk = config->mclk;
	priv->clk_div = config->clk_div;
	priv->gain = config->gain;

	memcpy(&priv->regs, &reg0[1], 8);

	memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
				sizeof(struct dvb_tuner_ops));
	fe->tuner_priv = priv;
	printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);

	return fe;
}
EXPORT_SYMBOL_GPL(stv6110_attach);

module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");

MODULE_DESCRIPTION("ST STV6110 driver");
MODULE_AUTHOR("Igor M. Liplianin");
MODULE_LICENSE("GPL");
