/*
	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_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_state(struct dvb_frontend *fe,
			     enum tuner_param param,
			     struct tuner_state *tstate)
{
	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 (param & DVBFE_TUNER_FREQUENCY) {

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

		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 = tstate->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);
		}
	} else {
		printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
		return -EINVAL;
	}

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

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