/*
	TDA665x tuner driver
	Copyright (C) Manu Abraham (abraham.manu@gmail.com)

	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 <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

#include "dvb_frontend.h"
#include "tda665x.h"

struct tda665x_state {
	struct dvb_frontend		*fe;
	struct i2c_adapter		*i2c;
	const struct tda665x_config	*config;

	u32 frequency;
	u32 bandwidth;
};

static int tda665x_read(struct tda665x_state *state, u8 *buf)
{
	const struct tda665x_config *config = state->config;
	int err = 0;
	struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };

	err = i2c_transfer(state->i2c, &msg, 1);
	if (err != 1)
		goto exit;

	return err;
exit:
	printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
	return err;
}

static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
{
	const struct tda665x_config *config = state->config;
	int err = 0;
	struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };

	err = i2c_transfer(state->i2c, &msg, 1);
	if (err != 1)
		goto exit;

	return err;
exit:
	printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
	return err;
}

static int tda665x_get_state(struct dvb_frontend *fe,
			     enum tuner_param param,
			     struct tuner_state *tstate)
{
	struct tda665x_state *state = fe->tuner_priv;
	int err = 0;

	switch (param) {
	case DVBFE_TUNER_FREQUENCY:
		tstate->frequency = state->frequency;
		break;
	case DVBFE_TUNER_BANDWIDTH:
		break;
	default:
		printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
		err = -EINVAL;
		break;
	}

	return err;
}

static int tda665x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct tda665x_state *state = fe->tuner_priv;

	*frequency = state->frequency;

	return 0;
}

static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
{
	struct tda665x_state *state = fe->tuner_priv;
	u8 result = 0;
	int err = 0;

	*status = 0;

	err = tda665x_read(state, &result);
	if (err < 0)
		goto exit;

	if ((result >> 6) & 0x01) {
		printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
		*status = 1;
	}

	return err;
exit:
	printk(KERN_ERR "%s: I/O Error\n", __func__);
	return err;
}

static int tda665x_set_frequency(struct dvb_frontend *fe,
				 u32 new_frequency)
{
	struct tda665x_state *state = fe->tuner_priv;
	const struct tda665x_config *config = state->config;
	u32 frequency, status = 0;
	u8 buf[4];
	int err = 0;

	if ((new_frequency < config->frequency_max)
	    || (new_frequency > config->frequency_min)) {
		printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n",
		       __func__, new_frequency);
		return -EINVAL;
	}

	frequency = new_frequency;

	frequency += config->frequency_offst;
	frequency *= config->ref_multiplier;
	frequency += config->ref_divider >> 1;
	frequency /= config->ref_divider;

	buf[0] = (u8) ((frequency & 0x7f00) >> 8);
	buf[1] = (u8) (frequency & 0x00ff) >> 0;
	buf[2] = 0x80 | 0x40 | 0x02;
	buf[3] = 0x00;

	/* restore frequency */
	frequency = new_frequency;

	if (frequency < 153000000) {
		/* VHF-L */
		buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
		if (frequency < 68000000)
			buf[3] |= 0x40; /* 83uA */
		if (frequency < 1040000000)
			buf[3] |= 0x60; /* 122uA */
		if (frequency < 1250000000)
			buf[3] |= 0x80; /* 163uA */
		else
			buf[3] |= 0xa0; /* 254uA */
	} else if (frequency < 438000000) {
		/* VHF-H */
		buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
		if (frequency < 230000000)
			buf[3] |= 0x40;
		if (frequency < 300000000)
			buf[3] |= 0x60;
		else
			buf[3] |= 0x80;
	} else {
		/* UHF */
		buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
		if (frequency < 470000000)
			buf[3] |= 0x60;
		if (frequency < 526000000)
			buf[3] |= 0x80;
		else
			buf[3] |= 0xa0;
	}

	/* Set params */
	err = tda665x_write(state, buf, 5);
	if (err < 0)
		goto exit;

	/* sleep for some time */
	printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
	msleep(20);
	/* check status */
	err = tda665x_get_status(fe, &status);
	if (err < 0)
		goto exit;

	if (status == 1) {
		printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n",
		       __func__, status);
		state->frequency = frequency; /* cache successful state */
	} else {
		printk(KERN_ERR "%s: No Phase lock: status=%d\n",
		       __func__, status);
	}

	return 0;
exit:
	printk(KERN_ERR "%s: I/O Error\n", __func__);
	return err;
}

static int tda665x_set_params(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;

	tda665x_set_frequency(fe, c->frequency);

	return 0;
}

static int tda665x_set_state(struct dvb_frontend *fe,
			     enum tuner_param param,
			     struct tuner_state *tstate)
{
	if (param & DVBFE_TUNER_FREQUENCY)
		return  tda665x_set_frequency(fe, tstate->frequency);

	printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
	return -EINVAL;
}

static int tda665x_release(struct dvb_frontend *fe)
{
	struct tda665x_state *state = fe->tuner_priv;

	fe->tuner_priv = NULL;
	kfree(state);
	return 0;
}

static struct dvb_tuner_ops tda665x_ops = {

	.set_state	= tda665x_set_state,
	.get_state	= tda665x_get_state,
	.get_status	= tda665x_get_status,
	.set_params	= tda665x_set_params,
	.get_frequency	= tda665x_get_frequency,
	.release	= tda665x_release
};

struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
				    const struct tda665x_config *config,
				    struct i2c_adapter *i2c)
{
	struct tda665x_state *state = NULL;
	struct dvb_tuner_info *info;

	state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
	if (!state)
		return NULL;

	state->config		= config;
	state->i2c		= i2c;
	state->fe		= fe;
	fe->tuner_priv		= state;
	fe->ops.tuner_ops	= tda665x_ops;
	info			 = &fe->ops.tuner_ops.info;

	memcpy(info->name, config->name, sizeof(config->name));
	info->frequency_min	= config->frequency_min;
	info->frequency_max	= config->frequency_max;
	info->frequency_step	= config->frequency_offst;

	printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);

	return fe;
}
EXPORT_SYMBOL(tda665x_attach);

MODULE_DESCRIPTION("TDA665x driver");
MODULE_AUTHOR("Manu Abraham");
MODULE_LICENSE("GPL");
