/*
    Conexant cx22700 DVB OFDM demodulator driver

    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
	Holger Waechtler <holger@convergence.de>

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


struct cx22700_state {

	struct i2c_adapter* i2c;

	const struct cx22700_config* config;

	struct dvb_frontend frontend;
};


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

static u8 init_tab [] = {
	0x04, 0x10,
	0x05, 0x09,
	0x06, 0x00,
	0x08, 0x04,
	0x09, 0x00,
	0x0a, 0x01,
	0x15, 0x40,
	0x16, 0x10,
	0x17, 0x87,
	0x18, 0x17,
	0x1a, 0x10,
	0x25, 0x04,
	0x2e, 0x00,
	0x39, 0x00,
	0x3a, 0x04,
	0x45, 0x08,
	0x46, 0x02,
	0x47, 0x05,
};


static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
{
	int ret;
	u8 buf [] = { reg, data };
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };

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

	ret = i2c_transfer (state->i2c, &msg, 1);

	if (ret != 1)
		printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
			__func__, reg, data, ret);

	return (ret != 1) ? -1 : 0;
}

static int cx22700_readreg (struct cx22700_state* state, u8 reg)
{
	int ret;
	u8 b0 [] = { reg };
	u8 b1 [] = { 0 };
	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
			   { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };

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

	ret = i2c_transfer (state->i2c, msg, 2);

	if (ret != 2) return -EIO;

	return b1[0];
}

static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
{
	u8 val;

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

	switch (inversion) {
	case INVERSION_AUTO:
		return -EOPNOTSUPP;
	case INVERSION_ON:
		val = cx22700_readreg (state, 0x09);
		return cx22700_writereg (state, 0x09, val | 0x01);
	case INVERSION_OFF:
		val = cx22700_readreg (state, 0x09);
		return cx22700_writereg (state, 0x09, val & 0xfe);
	default:
		return -EINVAL;
	}
}

static int cx22700_set_tps(struct cx22700_state *state,
			   struct dtv_frontend_properties *p)
{
	static const u8 qam_tab [4] = { 0, 1, 0, 2 };
	static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
	u8 val;

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

	if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
		return -EINVAL;

	if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
		return -EINVAL;

	if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
		return -EINVAL;

	if ((int)p->guard_interval < GUARD_INTERVAL_1_32 ||
	    p->guard_interval > GUARD_INTERVAL_1_4)
		return -EINVAL;

	if (p->transmission_mode != TRANSMISSION_MODE_2K &&
	    p->transmission_mode != TRANSMISSION_MODE_8K)
		return -EINVAL;

	if (p->modulation != QPSK &&
	    p->modulation != QAM_16 &&
	    p->modulation != QAM_64)
		return -EINVAL;

	if ((int)p->hierarchy < HIERARCHY_NONE ||
	    p->hierarchy > HIERARCHY_4)
		return -EINVAL;

	if (p->bandwidth_hz > 8000000 || p->bandwidth_hz < 6000000)
		return -EINVAL;

	if (p->bandwidth_hz == 7000000)
		cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
	else
		cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));

	val = qam_tab[p->modulation - QPSK];
	val |= p->hierarchy - HIERARCHY_NONE;

	cx22700_writereg (state, 0x04, val);

	val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
	val |= fec_tab[p->code_rate_LP - FEC_1_2];

	cx22700_writereg (state, 0x05, val);

	val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
	val |= p->transmission_mode - TRANSMISSION_MODE_2K;

	cx22700_writereg (state, 0x06, val);

	cx22700_writereg (state, 0x08, 0x04 | 0x02);  /* use user tps parameters */
	cx22700_writereg (state, 0x08, 0x04);         /* restart acquisition */

	return 0;
}

static int cx22700_get_tps(struct cx22700_state *state,
			   struct dtv_frontend_properties *p)
{
	static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
	static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
						    FEC_5_6, FEC_7_8 };
	u8 val;

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

	if (!(cx22700_readreg(state, 0x07) & 0x20))  /*  tps valid? */
		return -EAGAIN;

	val = cx22700_readreg (state, 0x01);

	if ((val & 0x7) > 4)
		p->hierarchy = HIERARCHY_AUTO;
	else
		p->hierarchy = HIERARCHY_NONE + (val & 0x7);

	if (((val >> 3) & 0x3) > 2)
		p->modulation = QAM_AUTO;
	else
		p->modulation = qam_tab[(val >> 3) & 0x3];

	val = cx22700_readreg (state, 0x02);

	if (((val >> 3) & 0x07) > 4)
		p->code_rate_HP = FEC_AUTO;
	else
		p->code_rate_HP = fec_tab[(val >> 3) & 0x07];

	if ((val & 0x07) > 4)
		p->code_rate_LP = FEC_AUTO;
	else
		p->code_rate_LP = fec_tab[val & 0x07];

	val = cx22700_readreg (state, 0x03);

	p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
	p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);

	return 0;
}

static int cx22700_init (struct dvb_frontend* fe)

{	struct cx22700_state* state = fe->demodulator_priv;
	int i;

	dprintk("cx22700_init: init chip\n");

	cx22700_writereg (state, 0x00, 0x02);   /*  soft reset */
	cx22700_writereg (state, 0x00, 0x00);

	msleep(10);

	for (i=0; i<sizeof(init_tab); i+=2)
		cx22700_writereg (state, init_tab[i], init_tab[i+1]);

	cx22700_writereg (state, 0x00, 0x01);

	return 0;
}

static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
	struct cx22700_state* state = fe->demodulator_priv;

	u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
		   | (cx22700_readreg (state, 0x0e) << 1);
	u8 sync = cx22700_readreg (state, 0x07);

	*status = 0;

	if (rs_ber < 0xff00)
		*status |= FE_HAS_SIGNAL;

	if (sync & 0x20)
		*status |= FE_HAS_CARRIER;

	if (sync & 0x10)
		*status |= FE_HAS_VITERBI;

	if (sync & 0x10)
		*status |= FE_HAS_SYNC;

	if (*status == 0x0f)
		*status |= FE_HAS_LOCK;

	return 0;
}

static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
{
	struct cx22700_state* state = fe->demodulator_priv;

	*ber = cx22700_readreg (state, 0x0c) & 0x7f;
	cx22700_writereg (state, 0x0c, 0x00);

	return 0;
}

static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
{
	struct cx22700_state* state = fe->demodulator_priv;

	u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
		   | (cx22700_readreg (state, 0x0e) << 1);
	*signal_strength = ~rs_ber;

	return 0;
}

static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
{
	struct cx22700_state* state = fe->demodulator_priv;

	u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
		   | (cx22700_readreg (state, 0x0e) << 1);
	*snr = ~rs_ber;

	return 0;
}

static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
	struct cx22700_state* state = fe->demodulator_priv;

	*ucblocks = cx22700_readreg (state, 0x0f);
	cx22700_writereg (state, 0x0f, 0x00);

	return 0;
}

static int cx22700_set_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct cx22700_state* state = fe->demodulator_priv;

	cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
	cx22700_writereg (state, 0x00, 0x00);

	if (fe->ops.tuner_ops.set_params) {
		fe->ops.tuner_ops.set_params(fe);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	}

	cx22700_set_inversion(state, c->inversion);
	cx22700_set_tps(state, c);
	cx22700_writereg (state, 0x37, 0x01);  /* PAL loop filter off */
	cx22700_writereg (state, 0x00, 0x01);  /* restart acquire */

	return 0;
}

static int cx22700_get_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct cx22700_state* state = fe->demodulator_priv;
	u8 reg09 = cx22700_readreg (state, 0x09);

	c->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
	return cx22700_get_tps(state, c);
}

static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
	struct cx22700_state* state = fe->demodulator_priv;

	if (enable) {
		return cx22700_writereg(state, 0x0a, 0x00);
	} else {
		return cx22700_writereg(state, 0x0a, 0x01);
	}
}

static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
{
	fesettings->min_delay_ms = 150;
	fesettings->step_size = 166667;
	fesettings->max_drift = 166667*2;
	return 0;
}

static void cx22700_release(struct dvb_frontend* fe)
{
	struct cx22700_state* state = fe->demodulator_priv;
	kfree(state);
}

static struct dvb_frontend_ops cx22700_ops;

struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
				    struct i2c_adapter* i2c)
{
	struct cx22700_state* state = NULL;

	/* allocate memory for the internal state */
	state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
	if (state == NULL) goto error;

	/* setup the state */
	state->config = config;
	state->i2c = i2c;

	/* check if the demod is there */
	if (cx22700_readreg(state, 0x07) < 0) goto error;

	/* create dvb_frontend */
	memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
	state->frontend.demodulator_priv = state;
	return &state->frontend;

error:
	kfree(state);
	return NULL;
}

static struct dvb_frontend_ops cx22700_ops = {
	.delsys = { SYS_DVBT },
	.info = {
		.name			= "Conexant CX22700 DVB-T",
		.frequency_min		= 470000000,
		.frequency_max		= 860000000,
		.frequency_stepsize	= 166667,
		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
		      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
		      FE_CAN_RECOVER
	},

	.release = cx22700_release,

	.init = cx22700_init,
	.i2c_gate_ctrl = cx22700_i2c_gate_ctrl,

	.set_frontend = cx22700_set_frontend,
	.get_frontend = cx22700_get_frontend,
	.get_tune_settings = cx22700_get_tune_settings,

	.read_status = cx22700_read_status,
	.read_ber = cx22700_read_ber,
	.read_signal_strength = cx22700_read_signal_strength,
	.read_snr = cx22700_read_snr,
	.read_ucblocks = cx22700_read_ucblocks,
};

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

MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
MODULE_AUTHOR("Holger Waechtler");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(cx22700_attach);
