/*
    Driver for VES1893 and VES1993 QPSK Demodulators

    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
    Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
    Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
    Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>

#include "dvb_frontend.h"
#include "ves1x93.h"


struct ves1x93_state {
	struct i2c_adapter* i2c;
	/* configuration settings */
	const struct ves1x93_config* config;
	struct dvb_frontend frontend;

	/* previous uncorrected block counter */
	fe_spectral_inversion_t inversion;
	u8 *init_1x93_tab;
	u8 *init_1x93_wtab;
	u8 tab_size;
	u8 demod_type;
};

static int debug = 0;
#define dprintk	if (debug) printk

#define DEMOD_VES1893		0
#define DEMOD_VES1993		1

static u8 init_1893_tab [] = {
	0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
	0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
	0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
	0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
};

static u8 init_1993_tab [] = {
	0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
	0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
	0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
	0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x0e, 0x80, 0x00
};

static u8 init_1893_wtab[] =
{
	1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
	0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
	1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
	1,1,1,0,1,1
};

static u8 init_1993_wtab[] =
{
	1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
	0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
	1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
	1,1,1,0,1,1,1,1, 1,1,1,1,1
};

static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
{
	u8 buf [] = { 0x00, reg, data };
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
	int err;

	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
		dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
		return -EREMOTEIO;
	}

	return 0;
}

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

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

	if (ret != 2) return ret;

	return b1[0];
}

static int ves1x93_clr_bit (struct ves1x93_state* state)
{
	msleep(10);
	ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
	ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
	msleep(50);
	return 0;
}

static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
{
	u8 val;

	/*
	 * inversion on/off are interchanged because i and q seem to
	 * be swapped on the hardware
	 */

	switch (inversion) {
	case INVERSION_OFF:
		val = 0xc0;
		break;
	case INVERSION_ON:
		val = 0x80;
		break;
	case INVERSION_AUTO:
		val = 0x00;
		break;
	default:
		return -EINVAL;
	}

	return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
}

static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
{
	if (fec == FEC_AUTO)
		return ves1x93_writereg (state, 0x0d, 0x08);
	else if (fec < FEC_1_2 || fec > FEC_8_9)
		return -EINVAL;
	else
		return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
}

static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
{
	return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
}

static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
{
	u32 BDR;
	u32 ratio;
	u8  ADCONF, FCONF, FNR, AGCR;
	u32 BDRI;
	u32 tmp;
	u32 FIN;

	dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);

	if (srate > state->config->xin/2)
		srate = state->config->xin/2;

	if (srate < 500000)
		srate = 500000;

#define MUL (1UL<<26)

	FIN = (state->config->xin + 6000) >> 4;

	tmp = srate << 6;
	ratio = tmp / FIN;

	tmp = (tmp % FIN) << 8;
	ratio = (ratio << 8) + tmp / FIN;

	tmp = (tmp % FIN) << 8;
	ratio = (ratio << 8) + tmp / FIN;

	FNR = 0xff;

	if (ratio < MUL/3)	     FNR = 0;
	if (ratio < (MUL*11)/50)     FNR = 1;
	if (ratio < MUL/6)	     FNR = 2;
	if (ratio < MUL/9)	     FNR = 3;
	if (ratio < MUL/12)	     FNR = 4;
	if (ratio < (MUL*11)/200)    FNR = 5;
	if (ratio < MUL/24)	     FNR = 6;
	if (ratio < (MUL*27)/1000)   FNR = 7;
	if (ratio < MUL/48)	     FNR = 8;
	if (ratio < (MUL*137)/10000) FNR = 9;

	if (FNR == 0xff) {
		ADCONF = 0x89;
		FCONF  = 0x80;
		FNR	= 0;
	} else {
		ADCONF = 0x81;
		FCONF  = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
		/*FCONF	 = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
	}

	BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
	BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;

	dprintk("FNR= %d\n", FNR);
	dprintk("ratio= %08x\n", (unsigned int) ratio);
	dprintk("BDR= %08x\n", (unsigned int) BDR);
	dprintk("BDRI= %02x\n", (unsigned int) BDRI);

	if (BDRI > 0xff)
		BDRI = 0xff;

	ves1x93_writereg (state, 0x06, 0xff & BDR);
	ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
	ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));

	ves1x93_writereg (state, 0x09, BDRI);
	ves1x93_writereg (state, 0x20, ADCONF);
	ves1x93_writereg (state, 0x21, FCONF);

	AGCR = state->init_1x93_tab[0x05];
	if (state->config->invert_pwm)
		AGCR |= 0x20;

	if (srate < 6000000)
		AGCR |= 0x80;
	else
		AGCR &= ~0x80;

	ves1x93_writereg (state, 0x05, AGCR);

	/* ves1993 hates this, will lose lock */
	if (state->demod_type != DEMOD_VES1993)
		ves1x93_clr_bit (state);

	return 0;
}

static int ves1x93_init (struct dvb_frontend* fe)
{
	struct ves1x93_state* state = fe->demodulator_priv;
	int i;
	int val;

	dprintk("%s: init chip\n", __FUNCTION__);

	for (i = 0; i < state->tab_size; i++) {
		if (state->init_1x93_wtab[i]) {
			val = state->init_1x93_tab[i];

			if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
			ves1x93_writereg (state, i, val);
		}
	}

	return 0;
}

static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
	struct ves1x93_state* state = fe->demodulator_priv;

	switch (voltage) {
	case SEC_VOLTAGE_13:
		return ves1x93_writereg (state, 0x1f, 0x20);
	case SEC_VOLTAGE_18:
		return ves1x93_writereg (state, 0x1f, 0x30);
	case SEC_VOLTAGE_OFF:
		return ves1x93_writereg (state, 0x1f, 0x00);
	default:
		return -EINVAL;
	}
}

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

	u8 sync = ves1x93_readreg (state, 0x0e);

	/*
	 * The ves1893 sometimes returns sync values that make no sense,
	 * because, e.g., the SIGNAL bit is 0, while some of the higher
	 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
	 * Tests showed that the the VITERBI and SYNC bits are returned
	 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
	 * If such a case occurs, we read the value again, until we get a
	 * valid value.
	 */
	int maxtry = 10; /* just for safety - let's not get stuck here */
	while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
		msleep(10);
		sync = ves1x93_readreg (state, 0x0e);
	}

	*status = 0;

	if (sync & 1)
		*status |= FE_HAS_SIGNAL;

	if (sync & 2)
		*status |= FE_HAS_CARRIER;

	if (sync & 4)
		*status |= FE_HAS_VITERBI;

	if (sync & 8)
		*status |= FE_HAS_SYNC;

	if ((sync & 0x1f) == 0x1f)
		*status |= FE_HAS_LOCK;

	return 0;
}

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

	*ber = ves1x93_readreg (state, 0x15);
	*ber |= (ves1x93_readreg (state, 0x16) << 8);
	*ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
	*ber *= 10;

	return 0;
}

static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
	struct ves1x93_state* state = fe->demodulator_priv;

	u8 signal = ~ves1x93_readreg (state, 0x0b);
	*strength = (signal << 8) | signal;

	return 0;
}

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

	u8 _snr = ~ves1x93_readreg (state, 0x1c);
	*snr = (_snr << 8) | _snr;

	return 0;
}

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

	*ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;

	if (*ucblocks == 0x7f)
		*ucblocks = 0xffffffff;   /* counter overflow... */

	ves1x93_writereg (state, 0x18, 0x00);  /* reset the counter */
	ves1x93_writereg (state, 0x18, 0x80);  /* dto. */

	return 0;
}

static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct ves1x93_state* state = fe->demodulator_priv;

	if (fe->ops.tuner_ops.set_params) {
		fe->ops.tuner_ops.set_params(fe, p);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	}
	ves1x93_set_inversion (state, p->inversion);
	ves1x93_set_fec (state, p->u.qpsk.fec_inner);
	ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
	state->inversion = p->inversion;

	return 0;
}

static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
	struct ves1x93_state* state = fe->demodulator_priv;
	int afc;

	afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
	afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;

	p->frequency -= afc;

	/*
	 * inversion indicator is only valid
	 * if auto inversion was used
	 */
	if (state->inversion == INVERSION_AUTO)
		p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
				INVERSION_OFF : INVERSION_ON;
	p->u.qpsk.fec_inner = ves1x93_get_fec (state);
	/*  XXX FIXME: timing offset !! */

	return 0;
}

static int ves1x93_sleep(struct dvb_frontend* fe)
{
	struct ves1x93_state* state = fe->demodulator_priv;

	return ves1x93_writereg (state, 0x00, 0x08);
}

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

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

	if (enable) {
		return ves1x93_writereg(state, 0x00, 0x11);
	} else {
		return ves1x93_writereg(state, 0x00, 0x01);
	}
}

static struct dvb_frontend_ops ves1x93_ops;

struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
				    struct i2c_adapter* i2c)
{
	struct ves1x93_state* state = NULL;
	u8 identity;

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

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

	/* check if the demod is there + identify it */
	identity = ves1x93_readreg(state, 0x1e);
	switch (identity) {
	case 0xdc: /* VES1893A rev1 */
		printk("ves1x93: Detected ves1893a rev1\n");
		state->demod_type = DEMOD_VES1893;
		state->init_1x93_tab = init_1893_tab;
		state->init_1x93_wtab = init_1893_wtab;
		state->tab_size = sizeof(init_1893_tab);
		break;

	case 0xdd: /* VES1893A rev2 */
		printk("ves1x93: Detected ves1893a rev2\n");
		state->demod_type = DEMOD_VES1893;
		state->init_1x93_tab = init_1893_tab;
		state->init_1x93_wtab = init_1893_wtab;
		state->tab_size = sizeof(init_1893_tab);
		break;

	case 0xde: /* VES1993 */
		printk("ves1x93: Detected ves1993\n");
		state->demod_type = DEMOD_VES1993;
		state->init_1x93_tab = init_1993_tab;
		state->init_1x93_wtab = init_1993_wtab;
		state->tab_size = sizeof(init_1993_tab);
		break;

	default:
		goto error;
	}

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

error:
	kfree(state);
	return NULL;
}

static struct dvb_frontend_ops ves1x93_ops = {

	.info = {
		.name			= "VLSI VES1x93 DVB-S",
		.type			= FE_QPSK,
		.frequency_min		= 950000,
		.frequency_max		= 2150000,
		.frequency_stepsize	= 125,		 /* kHz for QPSK frontends */
		.frequency_tolerance	= 29500,
		.symbol_rate_min	= 1000000,
		.symbol_rate_max	= 45000000,
	/*	.symbol_rate_tolerance	=	???,*/
		.caps = FE_CAN_INVERSION_AUTO |
			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
	},

	.release = ves1x93_release,

	.init = ves1x93_init,
	.sleep = ves1x93_sleep,
	.i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,

	.set_frontend = ves1x93_set_frontend,
	.get_frontend = ves1x93_get_frontend,

	.read_status = ves1x93_read_status,
	.read_ber = ves1x93_read_ber,
	.read_signal_strength = ves1x93_read_signal_strength,
	.read_snr = ves1x93_read_snr,
	.read_ucblocks = ves1x93_read_ucblocks,

	.set_voltage = ves1x93_set_voltage,
};

module_param(debug, int, 0644);

MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
MODULE_AUTHOR("Ralph Metzler");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(ves1x93_attach);
