/*
 * Abilis Systems Single DVB-T Receiver
 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
 *
 * 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, 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/version.h>

#include "as102_drv.h"
#include "as10x_types.h"
#include "as10x_cmd.h"

static void as10x_fe_copy_tps_parameters(struct dtv_frontend_properties *dst,
					 struct as10x_tps *src);

static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst,
					  struct dtv_frontend_properties *src);

static int as102_fe_set_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	int ret = 0;
	struct as102_dev_t *dev;
	struct as10x_tune_args tune_args = { 0 };

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	if (mutex_lock_interruptible(&dev->bus_adap.lock))
		return -EBUSY;

	as102_fe_copy_tune_parameters(&tune_args, p);

	/* send abilis command: SET_TUNE */
	ret =  as10x_cmd_set_tune(&dev->bus_adap, &tune_args);
	if (ret != 0)
		dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret);

	mutex_unlock(&dev->bus_adap.lock);

	LEAVE();
	return (ret < 0) ? -EINVAL : 0;
}

static int as102_fe_get_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	int ret = 0;
	struct as102_dev_t *dev;
	struct as10x_tps tps = { 0 };

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -EINVAL;

	if (mutex_lock_interruptible(&dev->bus_adap.lock))
		return -EBUSY;

	/* send abilis command: GET_TPS */
	ret = as10x_cmd_get_tps(&dev->bus_adap, &tps);

	if (ret == 0)
		as10x_fe_copy_tps_parameters(p, &tps);

	mutex_unlock(&dev->bus_adap.lock);

	LEAVE();
	return (ret < 0) ? -EINVAL : 0;
}

static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
			struct dvb_frontend_tune_settings *settings) {
	ENTER();

#if 0
	dprintk(debug, "step_size    = %d\n", settings->step_size);
	dprintk(debug, "max_drift    = %d\n", settings->max_drift);
	dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms,
		1000);
#endif

	settings->min_delay_ms = 1000;

	LEAVE();
	return 0;
}


static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	int ret = 0;
	struct as102_dev_t *dev;
	struct as10x_tune_status tstate = { 0 };

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	if (mutex_lock_interruptible(&dev->bus_adap.lock))
		return -EBUSY;

	/* send abilis command: GET_TUNE_STATUS */
	ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate);
	if (ret < 0) {
		dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n",
			ret);
		goto out;
	}

	dev->signal_strength  = tstate.signal_strength;
	dev->ber  = tstate.BER;

	switch (tstate.tune_state) {
	case TUNE_STATUS_SIGNAL_DVB_OK:
		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
		break;
	case TUNE_STATUS_STREAM_DETECTED:
		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC;
		break;
	case TUNE_STATUS_STREAM_TUNED:
		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
			FE_HAS_LOCK;
		break;
	default:
		*status = TUNE_STATUS_NOT_TUNED;
	}

	dprintk(debug, "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
			tstate.tune_state, tstate.signal_strength,
			tstate.PER, tstate.BER);

	if (*status & FE_HAS_LOCK) {
		if (as10x_cmd_get_demod_stats(&dev->bus_adap,
			(struct as10x_demod_stats *) &dev->demod_stats) < 0) {
			memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
			dprintk(debug, "as10x_cmd_get_demod_stats failed "
				"(probably not tuned)\n");
		} else {
			dprintk(debug,
				"demod status: fc: 0x%08x, bad fc: 0x%08x, "
				"bytes corrected: 0x%08x , MER: 0x%04x\n",
				dev->demod_stats.frame_count,
				dev->demod_stats.bad_frame_count,
				dev->demod_stats.bytes_fixed_by_rs,
				dev->demod_stats.mer);
		}
	} else {
		memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
	}

out:
	mutex_unlock(&dev->bus_adap.lock);
	LEAVE();
	return ret;
}

/*
 * Note:
 * - in AS102 SNR=MER
 *   - the SNR will be returned in linear terms, i.e. not in dB
 *   - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
 *   - the accuracy is >2dB for SNR values outside this range
 */
static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	struct as102_dev_t *dev;

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	*snr = dev->demod_stats.mer;

	LEAVE();
	return 0;
}

static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
{
	struct as102_dev_t *dev;

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	*ber = dev->ber;

	LEAVE();
	return 0;
}

static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
					 u16 *strength)
{
	struct as102_dev_t *dev;

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	*strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);

	LEAVE();
	return 0;
}

static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
	struct as102_dev_t *dev;

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	if (dev->demod_stats.has_started)
		*ucblocks = dev->demod_stats.bad_frame_count;
	else
		*ucblocks = 0;

	LEAVE();
	return 0;
}

static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
{
	struct as102_dev_t *dev;
	int ret;

	ENTER();

	dev = (struct as102_dev_t *) fe->tuner_priv;
	if (dev == NULL)
		return -ENODEV;

	if (mutex_lock_interruptible(&dev->bus_adap.lock))
		return -EBUSY;

	if (acquire) {
		if (elna_enable)
			as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);

		ret = as10x_cmd_turn_on(&dev->bus_adap);
	} else {
		ret = as10x_cmd_turn_off(&dev->bus_adap);
	}

	mutex_unlock(&dev->bus_adap.lock);

	LEAVE();
	return ret;
}

static struct dvb_frontend_ops as102_fe_ops = {
	.delsys = { SYS_DVBT },
	.info = {
		.name			= "Unknown AS102 device",
		.frequency_min		= 174000000,
		.frequency_max		= 862000000,
		.frequency_stepsize	= 166667,
		.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_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
			| 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
	},

	.set_frontend		= as102_fe_set_frontend,
	.get_frontend		= as102_fe_get_frontend,
	.get_tune_settings	= as102_fe_get_tune_settings,

	.read_status		= as102_fe_read_status,
	.read_snr		= as102_fe_read_snr,
	.read_ber		= as102_fe_read_ber,
	.read_signal_strength	= as102_fe_read_signal_strength,
	.read_ucblocks		= as102_fe_read_ucblocks,
	.ts_bus_ctrl		= as102_fe_ts_bus_ctrl,
};

int as102_dvb_unregister_fe(struct dvb_frontend *fe)
{
	/* unregister frontend */
	dvb_unregister_frontend(fe);

	/* detach frontend */
	dvb_frontend_detach(fe);

	return 0;
}

int as102_dvb_register_fe(struct as102_dev_t *as102_dev,
			  struct dvb_frontend *dvb_fe)
{
	int errno;
	struct dvb_adapter *dvb_adap;

	if (as102_dev == NULL)
		return -EINVAL;

	/* extract dvb_adapter */
	dvb_adap = &as102_dev->dvb_adap;

	/* init frontend callback ops */
	memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
	strncpy(dvb_fe->ops.info.name, as102_dev->name,
		sizeof(dvb_fe->ops.info.name));

	/* register dbvb frontend */
	errno = dvb_register_frontend(dvb_adap, dvb_fe);
	if (errno == 0)
		dvb_fe->tuner_priv = as102_dev;

	return errno;
}

static void as10x_fe_copy_tps_parameters(struct dtv_frontend_properties *fe_tps,
					 struct as10x_tps *as10x_tps)
{

	/* extract consteallation */
	switch (as10x_tps->modulation) {
	case CONST_QPSK:
		fe_tps->modulation = QPSK;
		break;
	case CONST_QAM16:
		fe_tps->modulation = QAM_16;
		break;
	case CONST_QAM64:
		fe_tps->modulation = QAM_64;
		break;
	}

	/* extract hierarchy */
	switch (as10x_tps->hierarchy) {
	case HIER_NONE:
		fe_tps->hierarchy = HIERARCHY_NONE;
		break;
	case HIER_ALPHA_1:
		fe_tps->hierarchy = HIERARCHY_1;
		break;
	case HIER_ALPHA_2:
		fe_tps->hierarchy = HIERARCHY_2;
		break;
	case HIER_ALPHA_4:
		fe_tps->hierarchy = HIERARCHY_4;
		break;
	}

	/* extract code rate HP */
	switch (as10x_tps->code_rate_HP) {
	case CODE_RATE_1_2:
		fe_tps->code_rate_HP = FEC_1_2;
		break;
	case CODE_RATE_2_3:
		fe_tps->code_rate_HP = FEC_2_3;
		break;
	case CODE_RATE_3_4:
		fe_tps->code_rate_HP = FEC_3_4;
		break;
	case CODE_RATE_5_6:
		fe_tps->code_rate_HP = FEC_5_6;
		break;
	case CODE_RATE_7_8:
		fe_tps->code_rate_HP = FEC_7_8;
		break;
	}

	/* extract code rate LP */
	switch (as10x_tps->code_rate_LP) {
	case CODE_RATE_1_2:
		fe_tps->code_rate_LP = FEC_1_2;
		break;
	case CODE_RATE_2_3:
		fe_tps->code_rate_LP = FEC_2_3;
		break;
	case CODE_RATE_3_4:
		fe_tps->code_rate_LP = FEC_3_4;
		break;
	case CODE_RATE_5_6:
		fe_tps->code_rate_LP = FEC_5_6;
		break;
	case CODE_RATE_7_8:
		fe_tps->code_rate_LP = FEC_7_8;
		break;
	}

	/* extract guard interval */
	switch (as10x_tps->guard_interval) {
	case GUARD_INT_1_32:
		fe_tps->guard_interval = GUARD_INTERVAL_1_32;
		break;
	case GUARD_INT_1_16:
		fe_tps->guard_interval = GUARD_INTERVAL_1_16;
		break;
	case GUARD_INT_1_8:
		fe_tps->guard_interval = GUARD_INTERVAL_1_8;
		break;
	case GUARD_INT_1_4:
		fe_tps->guard_interval = GUARD_INTERVAL_1_4;
		break;
	}

	/* extract transmission mode */
	switch (as10x_tps->transmission_mode) {
	case TRANS_MODE_2K:
		fe_tps->transmission_mode = TRANSMISSION_MODE_2K;
		break;
	case TRANS_MODE_8K:
		fe_tps->transmission_mode = TRANSMISSION_MODE_8K;
		break;
	}
}

static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
{
	uint8_t c;

	switch (arg) {
	case FEC_1_2:
		c = CODE_RATE_1_2;
		break;
	case FEC_2_3:
		c = CODE_RATE_2_3;
		break;
	case FEC_3_4:
		c = CODE_RATE_3_4;
		break;
	case FEC_5_6:
		c = CODE_RATE_5_6;
		break;
	case FEC_7_8:
		c = CODE_RATE_7_8;
		break;
	default:
		c = CODE_RATE_UNKNOWN;
		break;
	}

	return c;
}

static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
			  struct dtv_frontend_properties *params)
{

	/* set frequency */
	tune_args->freq = params->frequency / 1000;

	/* fix interleaving_mode */
	tune_args->interleaving_mode = INTLV_NATIVE;

	switch (params->bandwidth_hz) {
	case 8000000:
		tune_args->bandwidth = BW_8_MHZ;
		break;
	case 7000000:
		tune_args->bandwidth = BW_7_MHZ;
		break;
	case 6000000:
		tune_args->bandwidth = BW_6_MHZ;
		break;
	default:
		tune_args->bandwidth = BW_8_MHZ;
	}

	switch (params->guard_interval) {
	case GUARD_INTERVAL_1_32:
		tune_args->guard_interval = GUARD_INT_1_32;
		break;
	case GUARD_INTERVAL_1_16:
		tune_args->guard_interval = GUARD_INT_1_16;
		break;
	case GUARD_INTERVAL_1_8:
		tune_args->guard_interval = GUARD_INT_1_8;
		break;
	case GUARD_INTERVAL_1_4:
		tune_args->guard_interval = GUARD_INT_1_4;
		break;
	case GUARD_INTERVAL_AUTO:
	default:
		tune_args->guard_interval = GUARD_UNKNOWN;
		break;
	}

	switch (params->modulation) {
	case QPSK:
		tune_args->modulation = CONST_QPSK;
		break;
	case QAM_16:
		tune_args->modulation = CONST_QAM16;
		break;
	case QAM_64:
		tune_args->modulation = CONST_QAM64;
		break;
	default:
		tune_args->modulation = CONST_UNKNOWN;
		break;
	}

	switch (params->transmission_mode) {
	case TRANSMISSION_MODE_2K:
		tune_args->transmission_mode = TRANS_MODE_2K;
		break;
	case TRANSMISSION_MODE_8K:
		tune_args->transmission_mode = TRANS_MODE_8K;
		break;
	default:
		tune_args->transmission_mode = TRANS_MODE_UNKNOWN;
	}

	switch (params->hierarchy) {
	case HIERARCHY_NONE:
		tune_args->hierarchy = HIER_NONE;
		break;
	case HIERARCHY_1:
		tune_args->hierarchy = HIER_ALPHA_1;
		break;
	case HIERARCHY_2:
		tune_args->hierarchy = HIER_ALPHA_2;
		break;
	case HIERARCHY_4:
		tune_args->hierarchy = HIER_ALPHA_4;
		break;
	case HIERARCHY_AUTO:
		tune_args->hierarchy = HIER_UNKNOWN;
		break;
	}

	dprintk(debug, "tuner parameters: freq: %d  bw: 0x%02x  gi: 0x%02x\n",
			params->frequency,
			tune_args->bandwidth,
			tune_args->guard_interval);

	/*
	 * Detect a hierarchy selection
	 * if HP/LP are both set to FEC_NONE, HP will be selected.
	 */
	if ((tune_args->hierarchy != HIER_NONE) &&
		       ((params->code_rate_LP == FEC_NONE) ||
			(params->code_rate_HP == FEC_NONE))) {

		if (params->code_rate_LP == FEC_NONE) {
			tune_args->hier_select = HIER_HIGH_PRIORITY;
			tune_args->code_rate =
			   as102_fe_get_code_rate(params->code_rate_HP);
		}

		if (params->code_rate_HP == FEC_NONE) {
			tune_args->hier_select = HIER_LOW_PRIORITY;
			tune_args->code_rate =
			   as102_fe_get_code_rate(params->code_rate_LP);
		}

		dprintk(debug, "\thierarchy: 0x%02x  "
				"selected: %s  code_rate_%s: 0x%02x\n",
			tune_args->hierarchy,
			tune_args->hier_select == HIER_HIGH_PRIORITY ?
			"HP" : "LP",
			tune_args->hier_select == HIER_HIGH_PRIORITY ?
			"HP" : "LP",
			tune_args->code_rate);
	} else {
		tune_args->code_rate =
			as102_fe_get_code_rate(params->code_rate_HP);
	}
}
