/*
 * E3C EC100 demodulator driver
 *
 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
 *
 *    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 "dvb_frontend.h"
#include "ec100_priv.h"
#include "ec100.h"

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

struct ec100_state {
	struct i2c_adapter *i2c;
	struct dvb_frontend frontend;
	struct ec100_config config;

	u16 ber;
};

/* write single register */
static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
{
	u8 buf[2] = {reg, val};
	struct i2c_msg msg = {
		.addr = state->config.demod_address,
		.flags = 0,
		.len = 2,
		.buf = buf};

	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
		warn("I2C write failed reg:%02x", reg);
		return -EREMOTEIO;
	}
	return 0;
}

/* read single register */
static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
{
	struct i2c_msg msg[2] = {
		{
			.addr = state->config.demod_address,
			.flags = 0,
			.len = 1,
			.buf = &reg
		}, {
			.addr = state->config.demod_address,
			.flags = I2C_M_RD,
			.len = 1,
			.buf = val
		}
	};

	if (i2c_transfer(state->i2c, msg, 2) != 2) {
		warn("I2C read failed reg:%02x", reg);
		return -EREMOTEIO;
	}
	return 0;
}

static int ec100_set_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct ec100_state *state = fe->demodulator_priv;
	int ret;
	u8 tmp, tmp2;

	deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency,
		c->bandwidth_hz);

	/* program tuner */
	if (fe->ops.tuner_ops.set_params)
		fe->ops.tuner_ops.set_params(fe);

	ret = ec100_write_reg(state, 0x04, 0x06);
	if (ret)
		goto error;
	ret = ec100_write_reg(state, 0x67, 0x58);
	if (ret)
		goto error;
	ret = ec100_write_reg(state, 0x05, 0x18);
	if (ret)
		goto error;

	/* reg/bw |   6  |   7  |   8
	   -------+------+------+------
	   A 0x1b | 0xa1 | 0xe7 | 0x2c
	   A 0x1c | 0x55 | 0x63 | 0x72
	   -------+------+------+------
	   B 0x1b | 0xb7 | 0x00 | 0x49
	   B 0x1c | 0x55 | 0x64 | 0x72 */

	switch (c->bandwidth_hz) {
	case 6000000:
		tmp = 0xb7;
		tmp2 = 0x55;
		break;
	case 7000000:
		tmp = 0x00;
		tmp2 = 0x64;
		break;
	case 8000000:
	default:
		tmp = 0x49;
		tmp2 = 0x72;
	}

	ret = ec100_write_reg(state, 0x1b, tmp);
	if (ret)
		goto error;
	ret = ec100_write_reg(state, 0x1c, tmp2);
	if (ret)
		goto error;

	ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
	if (ret)
		goto error;
	ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
	if (ret)
		goto error;

	ret = ec100_write_reg(state, 0x08, 0x24);
	if (ret)
		goto error;

	ret = ec100_write_reg(state, 0x00, 0x00); /* go */
	if (ret)
		goto error;
	ret = ec100_write_reg(state, 0x00, 0x20); /* go */
	if (ret)
		goto error;

	return ret;
error:
	deb_info("%s: failed:%d\n", __func__, ret);
	return ret;
}

static int ec100_get_tune_settings(struct dvb_frontend *fe,
	struct dvb_frontend_tune_settings *fesettings)
{
	fesettings->min_delay_ms = 300;
	fesettings->step_size = 0;
	fesettings->max_drift = 0;

	return 0;
}

static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	struct ec100_state *state = fe->demodulator_priv;
	int ret;
	u8 tmp;
	*status = 0;

	ret = ec100_read_reg(state, 0x42, &tmp);
	if (ret)
		goto error;

	if (tmp & 0x80) {
		/* bit7 set - have lock */
		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
			FE_HAS_SYNC | FE_HAS_LOCK;
	} else {
		ret = ec100_read_reg(state, 0x01, &tmp);
		if (ret)
			goto error;

		if (tmp & 0x10) {
			/* bit4 set - have signal */
			*status |= FE_HAS_SIGNAL;
			if (!(tmp & 0x01)) {
				/* bit0 clear - have ~valid signal */
				*status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
			}
		}
	}

	return ret;
error:
	deb_info("%s: failed:%d\n", __func__, ret);
	return ret;
}

static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
{
	struct ec100_state *state = fe->demodulator_priv;
	int ret;
	u8 tmp, tmp2;
	u16 ber2;

	*ber = 0;

	ret = ec100_read_reg(state, 0x65, &tmp);
	if (ret)
		goto error;
	ret = ec100_read_reg(state, 0x66, &tmp2);
	if (ret)
		goto error;

	ber2 = (tmp2 << 8) | tmp;

	/* if counter overflow or clear */
	if (ber2 < state->ber)
		*ber = ber2;
	else
		*ber = ber2 - state->ber;

	state->ber = ber2;

	return ret;
error:
	deb_info("%s: failed:%d\n", __func__, ret);
	return ret;
}

static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
	struct ec100_state *state = fe->demodulator_priv;
	int ret;
	u8 tmp;

	ret = ec100_read_reg(state, 0x24, &tmp);
	if (ret) {
		*strength = 0;
		goto error;
	}

	*strength = ((tmp << 8) | tmp);

	return ret;
error:
	deb_info("%s: failed:%d\n", __func__, ret);
	return ret;
}

static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	*snr = 0;
	return 0;
}

static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
	*ucblocks = 0;
	return 0;
}

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

static struct dvb_frontend_ops ec100_ops;

struct dvb_frontend *ec100_attach(const struct ec100_config *config,
	struct i2c_adapter *i2c)
{
	int ret;
	struct ec100_state *state = NULL;
	u8 tmp;

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

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

	/* check if the demod is there */
	ret = ec100_read_reg(state, 0x33, &tmp);
	if (ret || tmp != 0x0b)
		goto error;

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

	return &state->frontend;
error:
	kfree(state);
	return NULL;
}
EXPORT_SYMBOL(ec100_attach);

static struct dvb_frontend_ops ec100_ops = {
	.delsys = { SYS_DVBT },
	.info = {
		.name = "E3C EC100 DVB-T",
		.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_MUTE_TS
	},

	.release = ec100_release,
	.set_frontend = ec100_set_frontend,
	.get_tune_settings = ec100_get_tune_settings,
	.read_status = ec100_read_status,
	.read_ber = ec100_read_ber,
	.read_signal_strength = ec100_read_signal_strength,
	.read_snr = ec100_read_snr,
	.read_ucblocks = ec100_read_ucblocks,
};

MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
MODULE_LICENSE("GPL");
