/*
 * 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"

extern int elna_enable;

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

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

static int as102_fe_set_frontend(struct dvb_frontend *fe,
				 struct dvb_frontend_parameters *params)
{
	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, params);

	/* 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 dvb_frontend_parameters *p) {
	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 = {
	.info = {
		.name			= "Unknown AS102 device",
		.type			= FE_OFDM,
		.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 dvb_frontend_parameters *dst,
					 struct as10x_tps *as10x_tps)
{

	struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm;

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

	/* extract hierarchy */
	switch (as10x_tps->hierarchy) {
	case HIER_NONE:
		fe_tps->hierarchy_information = HIERARCHY_NONE;
		break;
	case HIER_ALPHA_1:
		fe_tps->hierarchy_information = HIERARCHY_1;
		break;
	case HIER_ALPHA_2:
		fe_tps->hierarchy_information = HIERARCHY_2;
		break;
	case HIER_ALPHA_4:
		fe_tps->hierarchy_information = 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 dvb_frontend_parameters *params)
{

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

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

	switch (params->u.ofdm.bandwidth) {
	case BANDWIDTH_8_MHZ:
		tune_args->bandwidth = BW_8_MHZ;
		break;
	case BANDWIDTH_7_MHZ:
		tune_args->bandwidth = BW_7_MHZ;
		break;
	case BANDWIDTH_6_MHZ:
		tune_args->bandwidth = BW_6_MHZ;
		break;
	default:
		tune_args->bandwidth = BW_8_MHZ;
	}

	switch (params->u.ofdm.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->u.ofdm.constellation) {
	case QPSK:
		tune_args->constellation = CONST_QPSK;
		break;
	case QAM_16:
		tune_args->constellation = CONST_QAM16;
		break;
	case QAM_64:
		tune_args->constellation = CONST_QAM64;
		break;
	default:
		tune_args->constellation = CONST_UNKNOWN;
		break;
	}

	switch (params->u.ofdm.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->u.ofdm.hierarchy_information) {
	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->u.ofdm.code_rate_LP == FEC_NONE) ||
			(params->u.ofdm.code_rate_HP == FEC_NONE))) {

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

		if (params->u.ofdm.code_rate_HP == FEC_NONE) {
			tune_args->hier_select = HIER_LOW_PRIORITY;
			tune_args->code_rate =
			   as102_fe_get_code_rate(params->u.ofdm.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->u.ofdm.code_rate_HP);
	}
}

/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
