/*
   Driver for the Spase sp887x demodulator
*/

/*
 * This driver needs external firmware. Please use the command
 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
 * or /lib/firmware (depending on configuration of firmware hotplug).
 */
#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/string.h>
#include <linux/slab.h>

#include "dvb_frontend.h"
#include "sp887x.h"


struct sp887x_state {
	struct i2c_adapter* i2c;
	const struct sp887x_config* config;
	struct dvb_frontend frontend;

	/* demodulator private data */
	u8 initialised:1;
};

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

static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
{
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
	int err;

	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
		printk ("%s: i2c write error (addr %02x, err == %i)\n",
			__FUNCTION__, state->config->demod_address, err);
		return -EREMOTEIO;
	}

	return 0;
}

static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
{
	u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
	int ret;

	if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
		/**
		 *  in case of soft reset we ignore ACK errors...
		 */
		if (!(reg == 0xf1a && data == 0x000 &&
			(ret == -EREMOTEIO || ret == -EFAULT)))
		{
			printk("%s: writereg error "
			       "(reg %03x, data %03x, ret == %i)\n",
			       __FUNCTION__, reg & 0xffff, data & 0xffff, ret);
			return ret;
		}
	}

	return 0;
}

static int sp887x_readreg (struct sp887x_state* state, u16 reg)
{
	u8 b0 [] = { reg >> 8 , reg & 0xff };
	u8 b1 [2];
	int ret;
	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 = 2 }};

	if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
		printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
		return -1;
	}

	return (((b1[0] << 8) | b1[1]) & 0xfff);
}

static void sp887x_microcontroller_stop (struct sp887x_state* state)
{
	dprintk("%s\n", __FUNCTION__);
	sp887x_writereg(state, 0xf08, 0x000);
	sp887x_writereg(state, 0xf09, 0x000);

	/* microcontroller STOP */
	sp887x_writereg(state, 0xf00, 0x000);
}

static void sp887x_microcontroller_start (struct sp887x_state* state)
{
	dprintk("%s\n", __FUNCTION__);
	sp887x_writereg(state, 0xf08, 0x000);
	sp887x_writereg(state, 0xf09, 0x000);

	/* microcontroller START */
	sp887x_writereg(state, 0xf00, 0x001);
}

static void sp887x_setup_agc (struct sp887x_state* state)
{
	/* setup AGC parameters */
	dprintk("%s\n", __FUNCTION__);
	sp887x_writereg(state, 0x33c, 0x054);
	sp887x_writereg(state, 0x33b, 0x04c);
	sp887x_writereg(state, 0x328, 0x000);
	sp887x_writereg(state, 0x327, 0x005);
	sp887x_writereg(state, 0x326, 0x001);
	sp887x_writereg(state, 0x325, 0x001);
	sp887x_writereg(state, 0x324, 0x001);
	sp887x_writereg(state, 0x318, 0x050);
	sp887x_writereg(state, 0x317, 0x3fe);
	sp887x_writereg(state, 0x316, 0x001);
	sp887x_writereg(state, 0x313, 0x005);
	sp887x_writereg(state, 0x312, 0x002);
	sp887x_writereg(state, 0x306, 0x000);
	sp887x_writereg(state, 0x303, 0x000);
}

#define BLOCKSIZE 30
#define FW_SIZE 0x4000
/**
 *  load firmware and setup MPEG interface...
 */
static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
{
	struct sp887x_state* state = fe->demodulator_priv;
	u8 buf [BLOCKSIZE+2];
	int i;
	int fw_size = fw->size;
	unsigned char *mem = fw->data;

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

	/* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
	if (fw_size < FW_SIZE+10)
		return -ENODEV;

	mem = fw->data + 10;

	/* soft reset */
	sp887x_writereg(state, 0xf1a, 0x000);

	sp887x_microcontroller_stop (state);

	printk ("%s: firmware upload... ", __FUNCTION__);

	/* setup write pointer to -1 (end of memory) */
	/* bit 0x8000 in address is set to enable 13bit mode */
	sp887x_writereg(state, 0x8f08, 0x1fff);

	/* dummy write (wrap around to start of memory) */
	sp887x_writereg(state, 0x8f0a, 0x0000);

	for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
		int c = BLOCKSIZE;
		int err;

		if (i+c > FW_SIZE)
			c = FW_SIZE - i;

		/* bit 0x8000 in address is set to enable 13bit mode */
		/* bit 0x4000 enables multibyte read/write transfers */
		/* write register is 0xf0a */
		buf[0] = 0xcf;
		buf[1] = 0x0a;

		memcpy(&buf[2], mem + i, c);

		if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
			printk ("failed.\n");
			printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
			return err;
		}
	}

	/* don't write RS bytes between packets */
	sp887x_writereg(state, 0xc13, 0x001);

	/* suppress clock if (!data_valid) */
	sp887x_writereg(state, 0xc14, 0x000);

	/* setup MPEG interface... */
	sp887x_writereg(state, 0xc1a, 0x872);
	sp887x_writereg(state, 0xc1b, 0x001);
	sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
	sp887x_writereg(state, 0xc1a, 0x871);

	/* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
	sp887x_writereg(state, 0x301, 0x002);

	sp887x_setup_agc(state);

	/* bit 0x010: enable data valid signal */
	sp887x_writereg(state, 0xd00, 0x010);
	sp887x_writereg(state, 0x0d1, 0x000);
	return 0;
};

static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
{
	int known_parameters = 1;

	*reg0xc05 = 0x000;

	switch (p->u.ofdm.constellation) {
	case QPSK:
		break;
	case QAM_16:
		*reg0xc05 |= (1 << 10);
		break;
	case QAM_64:
		*reg0xc05 |= (2 << 10);
		break;
	case QAM_AUTO:
		known_parameters = 0;
		break;
	default:
		return -EINVAL;
	};

	switch (p->u.ofdm.hierarchy_information) {
	case HIERARCHY_NONE:
		break;
	case HIERARCHY_1:
		*reg0xc05 |= (1 << 7);
		break;
	case HIERARCHY_2:
		*reg0xc05 |= (2 << 7);
		break;
	case HIERARCHY_4:
		*reg0xc05 |= (3 << 7);
		break;
	case HIERARCHY_AUTO:
		known_parameters = 0;
		break;
	default:
		return -EINVAL;
	};

	switch (p->u.ofdm.code_rate_HP) {
	case FEC_1_2:
		break;
	case FEC_2_3:
		*reg0xc05 |= (1 << 3);
		break;
	case FEC_3_4:
		*reg0xc05 |= (2 << 3);
		break;
	case FEC_5_6:
		*reg0xc05 |= (3 << 3);
		break;
	case FEC_7_8:
		*reg0xc05 |= (4 << 3);
		break;
	case FEC_AUTO:
		known_parameters = 0;
		break;
	default:
		return -EINVAL;
	};

	if (known_parameters)
		*reg0xc05 |= (2 << 1);	/* use specified parameters */
	else
		*reg0xc05 |= (1 << 1);	/* enable autoprobing */

	return 0;
}

/**
 *  estimates division of two 24bit numbers,
 *  derived from the ves1820/stv0299 driver code
 */
static void divide (int n, int d, int *quotient_i, int *quotient_f)
{
	unsigned int q, r;

	r = (n % d) << 8;
	q = (r / d);

	if (quotient_i)
		*quotient_i = q;

	if (quotient_f) {
		r = (r % d) << 8;
		q = (q << 8) | (r / d);
		r = (r % d) << 8;
		*quotient_f = (q << 8) | (r / d);
	}
}

static void sp887x_correct_offsets (struct sp887x_state* state,
				    struct dvb_frontend_parameters *p,
				    int actual_freq)
{
	static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
	int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
	int freq_offset = actual_freq - p->frequency;
	int sysclock = 61003; //[kHz]
	int ifreq = 36000000;
	int freq;
	int frequency_shift;

	if (p->inversion == INVERSION_ON)
		freq = ifreq - freq_offset;
	else
		freq = ifreq + freq_offset;

	divide(freq / 333, sysclock, NULL, &frequency_shift);

	if (p->inversion == INVERSION_ON)
		frequency_shift = -frequency_shift;

	/* sample rate correction */
	sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
	sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);

	/* carrier offset correction */
	sp887x_writereg(state, 0x309, frequency_shift >> 12);
	sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
}

static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
					     struct dvb_frontend_parameters *p)
{
	struct sp887x_state* state = fe->demodulator_priv;
	int actual_freq, err;
	u16 val, reg0xc05;

	if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
	    p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ &&
	    p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ)
		return -EINVAL;

	if ((err = configure_reg0xc05(p, &reg0xc05)))
		return err;

	sp887x_microcontroller_stop(state);

	/* setup the PLL */
	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);
	}
	if (fe->ops.tuner_ops.get_frequency) {
		fe->ops.tuner_ops.get_frequency(fe, &actual_freq);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	} else {
		actual_freq = p->frequency;
	}

	/* read status reg in order to clear <pending irqs */
	sp887x_readreg(state, 0x200);

	sp887x_correct_offsets(state, p, actual_freq);

	/* filter for 6/7/8 Mhz channel */
	if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
		val = 2;
	else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
		val = 1;
	else
		val = 0;

	sp887x_writereg(state, 0x311, val);

	/* scan order: 2k first = 0, 8k first = 1 */
	if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
		sp887x_writereg(state, 0x338, 0x000);
	else
		sp887x_writereg(state, 0x338, 0x001);

	sp887x_writereg(state, 0xc05, reg0xc05);

	if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
		val = 2 << 3;
	else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
		val = 3 << 3;
	else
		val = 0 << 3;

	/* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
	 * optimize algorithm for given bandwidth...
	 */
	sp887x_writereg(state, 0xf14, 0x160 | val);
	sp887x_writereg(state, 0xf15, 0x000);

	sp887x_microcontroller_start(state);
	return 0;
}

static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
	struct sp887x_state* state = fe->demodulator_priv;
	u16 snr12 = sp887x_readreg(state, 0xf16);
	u16 sync0x200 = sp887x_readreg(state, 0x200);
	u16 sync0xf17 = sp887x_readreg(state, 0xf17);

	*status = 0;

	if (snr12 > 0x00f)
		*status |= FE_HAS_SIGNAL;

	//if (sync0x200 & 0x004)
	//	*status |= FE_HAS_SYNC | FE_HAS_CARRIER;

	//if (sync0x200 & 0x008)
	//	*status |= FE_HAS_VITERBI;

	if ((sync0xf17 & 0x00f) == 0x002) {
		*status |= FE_HAS_LOCK;
		*status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
	}

	if (sync0x200 & 0x001) {	/* tuner adjustment requested...*/
		int steps = (sync0x200 >> 4) & 0x00f;
		if (steps & 0x008)
			steps = -steps;
		dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
		       steps);
	}

	return 0;
}

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

	*ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
	       (sp887x_readreg(state, 0xc07) << 6);
	sp887x_writereg(state, 0xc08, 0x000);
	sp887x_writereg(state, 0xc07, 0x000);
	if (*ber >= 0x3fff0)
		*ber = ~0;

	return 0;
}

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

	u16 snr12 = sp887x_readreg(state, 0xf16);
	u32 signal = 3 * (snr12 << 4);
	*strength = (signal < 0xffff) ? signal : 0xffff;

	return 0;
}

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

	u16 snr12 = sp887x_readreg(state, 0xf16);
	*snr = (snr12 << 4) | (snr12 >> 8);

	return 0;
}

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

	*ucblocks = sp887x_readreg(state, 0xc0c);
	if (*ucblocks == 0xfff)
		*ucblocks = ~0;

	return 0;
}

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

	if (enable) {
		return sp887x_writereg(state, 0x206, 0x001);
	} else {
		return sp887x_writereg(state, 0x206, 0x000);
	}
}

static int sp887x_sleep(struct dvb_frontend* fe)
{
	struct sp887x_state* state = fe->demodulator_priv;

	/* tristate TS output and disable interface pins */
	sp887x_writereg(state, 0xc18, 0x000);

	return 0;
}

static int sp887x_init(struct dvb_frontend* fe)
{
	struct sp887x_state* state = fe->demodulator_priv;
	const struct firmware *fw = NULL;
	int ret;

	if (!state->initialised) {
		/* request the firmware, this will block until someone uploads it */
		printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
		ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
		if (ret) {
			printk("sp887x: no firmware upload (timeout or file not found?)\n");
			return ret;
		}

		ret = sp887x_initial_setup(fe, fw);
		release_firmware(fw);
		if (ret) {
			printk("sp887x: writing firmware to device failed\n");
			return ret;
		}
		printk("sp887x: firmware upload complete\n");
		state->initialised = 1;
	}

	/* enable TS output and interface pins */
	sp887x_writereg(state, 0xc18, 0x00d);

	return 0;
}

static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
{
	fesettings->min_delay_ms = 350;
	fesettings->step_size = 166666*2;
	fesettings->max_drift = (166666*2)+1;
	return 0;
}

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

static struct dvb_frontend_ops sp887x_ops;

struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
				   struct i2c_adapter* i2c)
{
	struct sp887x_state* state = NULL;

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

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

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

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

error:
	kfree(state);
	return NULL;
}

static struct dvb_frontend_ops sp887x_ops = {

	.info = {
		.name = "Spase SP887x DVB-T",
		.type = FE_OFDM,
		.frequency_min =  50500000,
		.frequency_max = 858000000,
		.frequency_stepsize = 166666,
		.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 = sp887x_release,

	.init = sp887x_init,
	.sleep = sp887x_sleep,
	.i2c_gate_ctrl = sp887x_i2c_gate_ctrl,

	.set_frontend = sp887x_setup_frontend_parameters,
	.get_tune_settings = sp887x_get_tune_settings,

	.read_status = sp887x_read_status,
	.read_ber = sp887x_read_ber,
	.read_signal_strength = sp887x_read_signal_strength,
	.read_snr = sp887x_read_snr,
	.read_ucblocks = sp887x_read_ucblocks,
};

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

MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(sp887x_attach);
