/*
 *  Driver for Zarlink DVB-T MT352 demodulator
 *
 *  Written by Holger Waechtler <holger@qanu.de>
 *	 and Daniel Mack <daniel@qanu.de>
 *
 *  AVerMedia AVerTV DVB-T 771 support by
 *       Wolfram Joost <dbox2@frokaschwei.de>
 *
 *  Support for Samsung TDTC9251DH01C(M) tuner
 *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
 *                     Amauri  Celani  <acelani@essegi.net>
 *
 *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
 *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
 *
 *  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/delay.h>
#include <linux/string.h>
#include <linux/slab.h>

#include "dvb_frontend.h"
#include "mt352_priv.h"
#include "mt352.h"

struct mt352_state {
	struct i2c_adapter* i2c;
	struct dvb_frontend frontend;

	/* configuration settings */
	struct mt352_config config;
};

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

static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
{
	struct mt352_state* state = fe->demodulator_priv;
	u8 buf[2] = { reg, val };
	struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
			       .buf = buf, .len = 2 };
	int err = i2c_transfer(state->i2c, &msg, 1);
	if (err != 1) {
		printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
		return err;
	}
	return 0;
}

static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
{
	int err,i;
	for (i=0; i < ilen-1; i++)
		if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
			return err;

	return 0;
}

static int mt352_read_register(struct mt352_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 } };

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

	if (ret != 2) {
		printk("%s: readreg error (reg=%d, ret==%i)\n",
		       __func__, reg, ret);
		return ret;
	}

	return b1[0];
}

static int mt352_sleep(struct dvb_frontend* fe)
{
	static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };

	_mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
	return 0;
}

static void mt352_calc_nominal_rate(struct mt352_state* state,
				    enum fe_bandwidth bandwidth,
				    unsigned char *buf)
{
	u32 adc_clock = 20480; /* 20.340 MHz */
	u32 bw,value;

	switch (bandwidth) {
	case BANDWIDTH_6_MHZ:
		bw = 6;
		break;
	case BANDWIDTH_7_MHZ:
		bw = 7;
		break;
	case BANDWIDTH_8_MHZ:
	default:
		bw = 8;
		break;
	}
	if (state->config.adc_clock)
		adc_clock = state->config.adc_clock;

	value = 64 * bw * (1<<16) / (7 * 8);
	value = value * 1000 / adc_clock;
	dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
		__func__, bw, adc_clock, value);
	buf[0] = msb(value);
	buf[1] = lsb(value);
}

static void mt352_calc_input_freq(struct mt352_state* state,
				  unsigned char *buf)
{
	int adc_clock = 20480; /* 20.480000 MHz */
	int if2       = 36167; /* 36.166667 MHz */
	int ife,value;

	if (state->config.adc_clock)
		adc_clock = state->config.adc_clock;
	if (state->config.if2)
		if2 = state->config.if2;

	if (adc_clock >= if2 * 2)
		ife = if2;
	else {
		ife = adc_clock - (if2 % adc_clock);
		if (ife > adc_clock / 2)
			ife = adc_clock - ife;
	}
	value = -16374 * ife / adc_clock;
	dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
		__func__, if2, ife, adc_clock, value, value & 0x3fff);
	buf[0] = msb(value);
	buf[1] = lsb(value);
}

static int mt352_set_parameters(struct dvb_frontend* fe,
				struct dvb_frontend_parameters *param)
{
	struct mt352_state* state = fe->demodulator_priv;
	unsigned char buf[13];
	static unsigned char tuner_go[] = { 0x5d, 0x01 };
	static unsigned char fsm_go[]   = { 0x5e, 0x01 };
	unsigned int tps = 0;
	struct dvb_ofdm_parameters *op = &param->u.ofdm;

	switch (op->code_rate_HP) {
		case FEC_2_3:
			tps |= (1 << 7);
			break;
		case FEC_3_4:
			tps |= (2 << 7);
			break;
		case FEC_5_6:
			tps |= (3 << 7);
			break;
		case FEC_7_8:
			tps |= (4 << 7);
			break;
		case FEC_1_2:
		case FEC_AUTO:
			break;
		default:
			return -EINVAL;
	}

	switch (op->code_rate_LP) {
		case FEC_2_3:
			tps |= (1 << 4);
			break;
		case FEC_3_4:
			tps |= (2 << 4);
			break;
		case FEC_5_6:
			tps |= (3 << 4);
			break;
		case FEC_7_8:
			tps |= (4 << 4);
			break;
		case FEC_1_2:
		case FEC_AUTO:
			break;
		case FEC_NONE:
			if (op->hierarchy_information == HIERARCHY_AUTO ||
			    op->hierarchy_information == HIERARCHY_NONE)
				break;
		default:
			return -EINVAL;
	}

	switch (op->constellation) {
		case QPSK:
			break;
		case QAM_AUTO:
		case QAM_16:
			tps |= (1 << 13);
			break;
		case QAM_64:
			tps |= (2 << 13);
			break;
		default:
			return -EINVAL;
	}

	switch (op->transmission_mode) {
		case TRANSMISSION_MODE_2K:
		case TRANSMISSION_MODE_AUTO:
			break;
		case TRANSMISSION_MODE_8K:
			tps |= (1 << 0);
			break;
		default:
			return -EINVAL;
	}

	switch (op->guard_interval) {
		case GUARD_INTERVAL_1_32:
		case GUARD_INTERVAL_AUTO:
			break;
		case GUARD_INTERVAL_1_16:
			tps |= (1 << 2);
			break;
		case GUARD_INTERVAL_1_8:
			tps |= (2 << 2);
			break;
		case GUARD_INTERVAL_1_4:
			tps |= (3 << 2);
			break;
		default:
			return -EINVAL;
	}

	switch (op->hierarchy_information) {
		case HIERARCHY_AUTO:
		case HIERARCHY_NONE:
			break;
		case HIERARCHY_1:
			tps |= (1 << 10);
			break;
		case HIERARCHY_2:
			tps |= (2 << 10);
			break;
		case HIERARCHY_4:
			tps |= (3 << 10);
			break;
		default:
			return -EINVAL;
	}


	buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */

	buf[1] = msb(tps);      /* TPS_GIVEN_(1|0) */
	buf[2] = lsb(tps);

	buf[3] = 0x50;  // old
//	buf[3] = 0xf4;  // pinnacle

	mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
	mt352_calc_input_freq(state, buf+6);

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

		_mt352_write(fe, buf, 8);
		_mt352_write(fe, fsm_go, 2);
	} else {
		if (fe->ops.tuner_ops.calc_regs) {
			fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
			buf[8] <<= 1;
			_mt352_write(fe, buf, sizeof(buf));
			_mt352_write(fe, tuner_go, 2);
		}
	}

	return 0;
}

static int mt352_get_parameters(struct dvb_frontend* fe,
				struct dvb_frontend_parameters *param)
{
	struct mt352_state* state = fe->demodulator_priv;
	u16 tps;
	u16 div;
	u8 trl;
	struct dvb_ofdm_parameters *op = &param->u.ofdm;
	static const u8 tps_fec_to_api[8] =
	{
		FEC_1_2,
		FEC_2_3,
		FEC_3_4,
		FEC_5_6,
		FEC_7_8,
		FEC_AUTO,
		FEC_AUTO,
		FEC_AUTO
	};

	if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
		return -EINVAL;

	/* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
	 * the mt352 sometimes works with the wrong parameters
	 */
	tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
	div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
	trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);

	op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
	op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];

	switch ( (tps >> 13) & 3)
	{
		case 0:
			op->constellation = QPSK;
			break;
		case 1:
			op->constellation = QAM_16;
			break;
		case 2:
			op->constellation = QAM_64;
			break;
		default:
			op->constellation = QAM_AUTO;
			break;
	}

	op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;

	switch ( (tps >> 2) & 3)
	{
		case 0:
			op->guard_interval = GUARD_INTERVAL_1_32;
			break;
		case 1:
			op->guard_interval = GUARD_INTERVAL_1_16;
			break;
		case 2:
			op->guard_interval = GUARD_INTERVAL_1_8;
			break;
		case 3:
			op->guard_interval = GUARD_INTERVAL_1_4;
			break;
		default:
			op->guard_interval = GUARD_INTERVAL_AUTO;
			break;
	}

	switch ( (tps >> 10) & 7)
	{
		case 0:
			op->hierarchy_information = HIERARCHY_NONE;
			break;
		case 1:
			op->hierarchy_information = HIERARCHY_1;
			break;
		case 2:
			op->hierarchy_information = HIERARCHY_2;
			break;
		case 3:
			op->hierarchy_information = HIERARCHY_4;
			break;
		default:
			op->hierarchy_information = HIERARCHY_AUTO;
			break;
	}

	param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;

	if (trl == 0x72)
		op->bandwidth = BANDWIDTH_8_MHZ;
	else if (trl == 0x64)
		op->bandwidth = BANDWIDTH_7_MHZ;
	else
		op->bandwidth = BANDWIDTH_6_MHZ;


	if (mt352_read_register(state, STATUS_2) & 0x02)
		param->inversion = INVERSION_OFF;
	else
		param->inversion = INVERSION_ON;

	return 0;
}

static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
	struct mt352_state* state = fe->demodulator_priv;
	int s0, s1, s3;

	/* FIXME:
	 *
	 * The MT352 design manual from Zarlink states (page 46-47):
	 *
	 * Notes about the TUNER_GO register:
	 *
	 * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
	 * byte is copied from the tuner to the STATUS_3 register and
	 * completion of the read operation is indicated by bit-5 of the
	 * INTERRUPT_3 register.
	 */

	if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
		return -EREMOTEIO;
	if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
		return -EREMOTEIO;
	if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
		return -EREMOTEIO;

	*status = 0;
	if (s0 & (1 << 4))
		*status |= FE_HAS_CARRIER;
	if (s0 & (1 << 1))
		*status |= FE_HAS_VITERBI;
	if (s0 & (1 << 5))
		*status |= FE_HAS_LOCK;
	if (s1 & (1 << 1))
		*status |= FE_HAS_SYNC;
	if (s3 & (1 << 6))
		*status |= FE_HAS_SIGNAL;

	if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
		      (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
		*status &= ~FE_HAS_LOCK;

	return 0;
}

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

	*ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
	       (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
	       (mt352_read_register (state, RS_ERR_CNT_0));

	return 0;
}

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

	/* align the 12 bit AGC gain with the most significant bits */
	u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
		(mt352_read_register(state, AGC_GAIN_0) << 4);

	/* inverse of gain is signal strength */
	*strength = ~signal;
	return 0;
}

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

	u8 _snr = mt352_read_register (state, SNR);
	*snr = (_snr << 8) | _snr;

	return 0;
}

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

	*ucblocks = (mt352_read_register (state,  RS_UBC_1) << 8) |
		    (mt352_read_register (state,  RS_UBC_0));

	return 0;
}

static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
{
	fe_tune_settings->min_delay_ms = 800;
	fe_tune_settings->step_size = 0;
	fe_tune_settings->max_drift = 0;

	return 0;
}

static int mt352_init(struct dvb_frontend* fe)
{
	struct mt352_state* state = fe->demodulator_priv;

	static u8 mt352_reset_attach [] = { RESET, 0xC0 };

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

	if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
	    (mt352_read_register(state, CONFIG) & 0x20) == 0) {

		/* Do a "hard" reset */
		_mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
		return state->config.demod_init(fe);
	}

	return 0;
}

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

static struct dvb_frontend_ops mt352_ops;

struct dvb_frontend* mt352_attach(const struct mt352_config* config,
				  struct i2c_adapter* i2c)
{
	struct mt352_state* state = NULL;

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

	/* setup the state */
	state->i2c = i2c;
	memcpy(&state->config,config,sizeof(struct mt352_config));

	/* check if the demod is there */
	if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;

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

error:
	kfree(state);
	return NULL;
}

static struct dvb_frontend_ops mt352_ops = {

	.info = {
		.name			= "Zarlink MT352 DVB-T",
		.type			= FE_OFDM,
		.frequency_min		= 174000000,
		.frequency_max		= 862000000,
		.frequency_stepsize	= 166667,
		.frequency_tolerance	= 0,
		.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_QAM_AUTO |
			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
			FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
			FE_CAN_MUTE_TS
	},

	.release = mt352_release,

	.init = mt352_init,
	.sleep = mt352_sleep,
	.write = _mt352_write,

	.set_frontend = mt352_set_parameters,
	.get_frontend = mt352_get_parameters,
	.get_tune_settings = mt352_get_tune_settings,

	.read_status = mt352_read_status,
	.read_ber = mt352_read_ber,
	.read_signal_strength = mt352_read_signal_strength,
	.read_snr = mt352_read_snr,
	.read_ucblocks = mt352_read_ucblocks,
};

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

MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(mt352_attach);
