/*
 *  Driver for Quantek QT1010 silicon tuner
 *
 *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
 *                     Aapo Tahkola <aet@rasterburn.org>
 *
 *  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 "qt1010.h"
#include "qt1010_priv.h"

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

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

/* read single register */
static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
{
	struct i2c_msg msg[2] = {
		{ .addr = priv->cfg->i2c_address,
		  .flags = 0, .buf = &reg, .len = 1 },
		{ .addr = priv->cfg->i2c_address,
		  .flags = I2C_M_RD, .buf = val, .len = 1 },
	};

	if (i2c_transfer(priv->i2c, msg, 2) != 2) {
		printk(KERN_WARNING "qt1010 I2C read failed\n");
		return -EREMOTEIO;
	}
	return 0;
}

/* write single register */
static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
{
	u8 buf[2] = { reg, val };
	struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
			       .flags = 0, .buf = buf, .len = 2 };

	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
		printk(KERN_WARNING "qt1010 I2C write failed\n");
		return -EREMOTEIO;
	}
	return 0;
}

/* dump all registers */
static void qt1010_dump_regs(struct qt1010_priv *priv)
{
	char buf[52], buf2[4];
	u8 reg, val;

	for (reg = 0; ; reg++) {
		if (reg % 16 == 0) {
			if (reg)
				printk("%s\n", buf);
			sprintf(buf, "%02x: ", reg);
		}
		if (qt1010_readreg(priv, reg, &val) == 0)
			sprintf(buf2, "%02x ", val);
		else
			strcpy(buf2, "-- ");
		strcat(buf, buf2);
		if (reg == 0x2f)
			break;
	}
	printk("%s\n", buf);
}

static int qt1010_set_params(struct dvb_frontend *fe,
			     struct dvb_frontend_parameters *params)
{
	struct qt1010_priv *priv;
	int err;
	u32 freq, div, mod1, mod2;
	u8 i, tmpval, reg05;
	qt1010_i2c_oper_t rd[48] = {
		{ QT1010_WR, 0x01, 0x80 },
		{ QT1010_WR, 0x02, 0x3f },
		{ QT1010_WR, 0x05, 0xff }, /* 02 c write */
		{ QT1010_WR, 0x06, 0x44 },
		{ QT1010_WR, 0x07, 0xff }, /* 04 c write */
		{ QT1010_WR, 0x08, 0x08 },
		{ QT1010_WR, 0x09, 0xff }, /* 06 c write */
		{ QT1010_WR, 0x0a, 0xff }, /* 07 c write */
		{ QT1010_WR, 0x0b, 0xff }, /* 08 c write */
		{ QT1010_WR, 0x0c, 0xe1 },
		{ QT1010_WR, 0x1a, 0xff }, /* 10 c write */
		{ QT1010_WR, 0x1b, 0x00 },
		{ QT1010_WR, 0x1c, 0x89 },
		{ QT1010_WR, 0x11, 0xff }, /* 13 c write */
		{ QT1010_WR, 0x12, 0xff }, /* 14 c write */
		{ QT1010_WR, 0x22, 0xff }, /* 15 c write */
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x1e, 0xd0 },
		{ QT1010_RD, 0x22, 0xff }, /* 16 c read */
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_RD, 0x05, 0xff }, /* 20 c read */
		{ QT1010_RD, 0x22, 0xff }, /* 21 c read */
		{ QT1010_WR, 0x23, 0xd0 },
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x1e, 0xe0 },
		{ QT1010_RD, 0x23, 0xff }, /* 25 c read */
		{ QT1010_RD, 0x23, 0xff }, /* 26 c read */
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x24, 0xd0 },
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x1e, 0xf0 },
		{ QT1010_RD, 0x24, 0xff }, /* 31 c read */
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x14, 0x7f },
		{ QT1010_WR, 0x15, 0x7f },
		{ QT1010_WR, 0x05, 0xff }, /* 35 c write */
		{ QT1010_WR, 0x06, 0x00 },
		{ QT1010_WR, 0x15, 0x1f },
		{ QT1010_WR, 0x16, 0xff },
		{ QT1010_WR, 0x18, 0xff },
		{ QT1010_WR, 0x1f, 0xff }, /* 40 c write */
		{ QT1010_WR, 0x20, 0xff }, /* 41 c write */
		{ QT1010_WR, 0x21, 0x53 },
		{ QT1010_WR, 0x25, 0xff }, /* 43 c write */
		{ QT1010_WR, 0x26, 0x15 },
		{ QT1010_WR, 0x00, 0xff }, /* 45 c write */
		{ QT1010_WR, 0x02, 0x00 },
		{ QT1010_WR, 0x01, 0x00 }
	};

#define FREQ1 32000000 /* 32 MHz */
#define FREQ2  4000000 /* 4 MHz Quartz oscillator in the stick? */

	priv = fe->tuner_priv;
	freq = params->frequency;
	div = (freq + QT1010_OFFSET) / QT1010_STEP;
	freq = (div * QT1010_STEP) - QT1010_OFFSET;
	mod1 = (freq + QT1010_OFFSET) % FREQ1;
	mod2 = (freq + QT1010_OFFSET) % FREQ2;
	priv->bandwidth =
		(fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
	priv->frequency = freq;

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */

	/* reg 05 base value */
	if      (freq < 290000000) reg05 = 0x14; /* 290 MHz */
	else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
	else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
	else                       reg05 = 0x74;

	/* 0x5 */
	rd[2].val = reg05;

	/* 07 - set frequency: 32 MHz scale */
	rd[4].val = (freq + QT1010_OFFSET) / FREQ1;

	/* 09 - changes every 8/24 MHz */
	if (mod1 < 8000000) rd[6].val = 0x1d;
	else                rd[6].val = 0x1c;

	/* 0a - set frequency: 4 MHz scale (max 28 MHz) */
	if      (mod1 < 1*FREQ2) rd[7].val = 0x09; /*  +0 MHz */
	else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /*  +4 MHz */
	else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /*  +8 MHz */
	else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
	else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
	else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
	else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
	else                     rd[7].val = 0x0a; /* +28 MHz */

	/* 0b - changes every 2/2 MHz */
	if (mod2 < 2000000) rd[8].val = 0x45;
	else                rd[8].val = 0x44;

	/* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
	tmpval = 0x78; /* byte, overflows intentionally */
	rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);

	/* 11 */
	rd[13].val = 0xfd; /* TODO: correct value calculation */

	/* 12 */
	rd[14].val = 0x91; /* TODO: correct value calculation */

	/* 22 */
	if      (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
	else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
	else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
	else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
	else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
	else                       rd[15].val = 0xd0;

	/* 05 */
	rd[35].val = (reg05 & 0xf0);

	/* 1f */
	if      (mod1 <  8000000) tmpval = 0x00;
	else if (mod1 < 12000000) tmpval = 0x01;
	else if (mod1 < 16000000) tmpval = 0x02;
	else if (mod1 < 24000000) tmpval = 0x03;
	else if (mod1 < 28000000) tmpval = 0x04;
	else                      tmpval = 0x05;
	rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);

	/* 20 */
	if      (mod1 <  8000000) tmpval = 0x00;
	else if (mod1 < 12000000) tmpval = 0x01;
	else if (mod1 < 20000000) tmpval = 0x02;
	else if (mod1 < 24000000) tmpval = 0x03;
	else if (mod1 < 28000000) tmpval = 0x04;
	else                      tmpval = 0x05;
	rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);

	/* 25 */
	rd[43].val = priv->reg25_init_val;

	/* 00 */
	rd[45].val = 0x92; /* TODO: correct value calculation */

	dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
		"1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
		"20:%02x 25:%02x 00:%02x", \
		freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
		rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
		rd[40].val, rd[41].val, rd[43].val, rd[45].val);

	for (i = 0; i < ARRAY_SIZE(rd); i++) {
		if (rd[i].oper == QT1010_WR) {
			err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
		} else { /* read is required to proper locking */
			err = qt1010_readreg(priv, rd[i].reg, &tmpval);
		}
		if (err) return err;
	}

	if (debug)
		qt1010_dump_regs(priv);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */

	return 0;
}

static int qt1010_init_meas1(struct qt1010_priv *priv,
			     u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
{
	u8 i, val1, val2;
	int err;

	qt1010_i2c_oper_t i2c_data[] = {
		{ QT1010_WR, reg, reg_init_val },
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x1e, oper },
		{ QT1010_RD, reg, 0xff }
	};

	for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
		if (i2c_data[i].oper == QT1010_WR) {
			err = qt1010_writereg(priv, i2c_data[i].reg,
					      i2c_data[i].val);
		} else {
			err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
		}
		if (err) return err;
	}

	do {
		val1 = val2;
		err = qt1010_readreg(priv, reg, &val2);
		if (err) return err;
		dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
	} while (val1 != val2);
	*retval = val1;

	return qt1010_writereg(priv, 0x1e, 0x00);
}

static u8 qt1010_init_meas2(struct qt1010_priv *priv,
			    u8 reg_init_val, u8 *retval)
{
	u8 i, val;
	int err;
	qt1010_i2c_oper_t i2c_data[] = {
		{ QT1010_WR, 0x07, reg_init_val },
		{ QT1010_WR, 0x22, 0xd0 },
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x1e, 0xd0 },
		{ QT1010_RD, 0x22, 0xff },
		{ QT1010_WR, 0x1e, 0x00 },
		{ QT1010_WR, 0x22, 0xff }
	};
	for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
		if (i2c_data[i].oper == QT1010_WR) {
			err = qt1010_writereg(priv, i2c_data[i].reg,
					      i2c_data[i].val);
		} else {
			err = qt1010_readreg(priv, i2c_data[i].reg, &val);
		}
		if (err) return err;
	}
	*retval = val;
	return 0;
}

static int qt1010_init(struct dvb_frontend *fe)
{
	struct qt1010_priv *priv = fe->tuner_priv;
	struct dvb_frontend_parameters params;
	int err = 0;
	u8 i, tmpval, *valptr = NULL;

	qt1010_i2c_oper_t i2c_data[] = {
		{ QT1010_WR, 0x01, 0x80 },
		{ QT1010_WR, 0x0d, 0x84 },
		{ QT1010_WR, 0x0e, 0xb7 },
		{ QT1010_WR, 0x2a, 0x23 },
		{ QT1010_WR, 0x2c, 0xdc },
		{ QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
		{ QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
		{ QT1010_WR, 0x2b, 0x70 },
		{ QT1010_WR, 0x2a, 0x23 },
		{ QT1010_M1, 0x26, 0x08 },
		{ QT1010_M1, 0x82, 0xff },
		{ QT1010_WR, 0x05, 0x14 },
		{ QT1010_WR, 0x06, 0x44 },
		{ QT1010_WR, 0x07, 0x28 },
		{ QT1010_WR, 0x08, 0x0b },
		{ QT1010_WR, 0x11, 0xfd },
		{ QT1010_M1, 0x22, 0x0d },
		{ QT1010_M1, 0xd0, 0xff },
		{ QT1010_WR, 0x06, 0x40 },
		{ QT1010_WR, 0x16, 0xf0 },
		{ QT1010_WR, 0x02, 0x38 },
		{ QT1010_WR, 0x03, 0x18 },
		{ QT1010_WR, 0x20, 0xe0 },
		{ QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
		{ QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
		{ QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
		{ QT1010_WR, 0x03, 0x19 },
		{ QT1010_WR, 0x02, 0x3f },
		{ QT1010_WR, 0x21, 0x53 },
		{ QT1010_RD, 0x21, 0xff },
		{ QT1010_WR, 0x11, 0xfd },
		{ QT1010_WR, 0x05, 0x34 },
		{ QT1010_WR, 0x06, 0x44 },
		{ QT1010_WR, 0x08, 0x08 }
	};

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */

	for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
		switch (i2c_data[i].oper) {
		case QT1010_WR:
			err = qt1010_writereg(priv, i2c_data[i].reg,
					      i2c_data[i].val);
			break;
		case QT1010_RD:
			if (i2c_data[i].val == 0x20)
				valptr = &priv->reg20_init_val;
			else
				valptr = &tmpval;
			err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
			break;
		case QT1010_M1:
			if (i2c_data[i].val == 0x25)
				valptr = &priv->reg25_init_val;
			else if (i2c_data[i].val == 0x1f)
				valptr = &priv->reg1f_init_val;
			else
				valptr = &tmpval;
			err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
						i2c_data[i].reg,
						i2c_data[i].val, valptr);
			i++;
			break;
		}
		if (err) return err;
	}

	for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
		if ((err = qt1010_init_meas2(priv, i, &tmpval)))
			return err;

	params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */
				      /* MSI Megasky 580 GL861 533000000 */
	return qt1010_set_params(fe, &params);
}

static int qt1010_release(struct dvb_frontend *fe)
{
	kfree(fe->tuner_priv);
	fe->tuner_priv = NULL;
	return 0;
}

static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct qt1010_priv *priv = fe->tuner_priv;
	*frequency = priv->frequency;
	return 0;
}

static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
	struct qt1010_priv *priv = fe->tuner_priv;
	*bandwidth = priv->bandwidth;
	return 0;
}

static const struct dvb_tuner_ops qt1010_tuner_ops = {
	.info = {
		.name           = "Quantek QT1010",
		.frequency_min  = QT1010_MIN_FREQ,
		.frequency_max  = QT1010_MAX_FREQ,
		.frequency_step = QT1010_STEP,
	},

	.release       = qt1010_release,
	.init          = qt1010_init,
	/* TODO: implement sleep */

	.set_params    = qt1010_set_params,
	.get_frequency = qt1010_get_frequency,
	.get_bandwidth = qt1010_get_bandwidth
};

struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
				    struct i2c_adapter *i2c,
				    struct qt1010_config *cfg)
{
	struct qt1010_priv *priv = NULL;
	u8 id;

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

	priv->cfg = cfg;
	priv->i2c = i2c;

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */


	/* Try to detect tuner chip. Probably this is not correct register. */
	if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
		kfree(priv);
		return NULL;
	}

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */

	printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
	memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
	       sizeof(struct dvb_tuner_ops));

	fe->tuner_priv = priv;
	return fe;
}
EXPORT_SYMBOL(qt1010_attach);

MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
