/*
 * Montage M88DS3103/M88RS6000 demodulator driver
 *
 * Copyright (C) 2013 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.
 */

#include "m88ds3103_priv.h"

static struct dvb_frontend_ops m88ds3103_ops;

/* write multiple registers */
static int m88ds3103_wr_regs(struct m88ds3103_priv *priv,
		u8 reg, const u8 *val, int len)
{
#define MAX_WR_LEN 32
#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
	int ret;
	u8 buf[MAX_WR_XFER_LEN];
	struct i2c_msg msg[1] = {
		{
			.addr = priv->cfg->i2c_addr,
			.flags = 0,
			.len = 1 + len,
			.buf = buf,
		}
	};

	if (WARN_ON(len > MAX_WR_LEN))
		return -EINVAL;

	buf[0] = reg;
	memcpy(&buf[1], val, len);

	mutex_lock(&priv->i2c_mutex);
	ret = i2c_transfer(priv->i2c, msg, 1);
	mutex_unlock(&priv->i2c_mutex);
	if (ret == 1) {
		ret = 0;
	} else {
		dev_warn(&priv->i2c->dev,
				"%s: i2c wr failed=%d reg=%02x len=%d\n",
				KBUILD_MODNAME, ret, reg, len);
		ret = -EREMOTEIO;
	}

	return ret;
}

/* read multiple registers */
static int m88ds3103_rd_regs(struct m88ds3103_priv *priv,
		u8 reg, u8 *val, int len)
{
#define MAX_RD_LEN 3
#define MAX_RD_XFER_LEN (MAX_RD_LEN)
	int ret;
	u8 buf[MAX_RD_XFER_LEN];
	struct i2c_msg msg[2] = {
		{
			.addr = priv->cfg->i2c_addr,
			.flags = 0,
			.len = 1,
			.buf = &reg,
		}, {
			.addr = priv->cfg->i2c_addr,
			.flags = I2C_M_RD,
			.len = len,
			.buf = buf,
		}
	};

	if (WARN_ON(len > MAX_RD_LEN))
		return -EINVAL;

	mutex_lock(&priv->i2c_mutex);
	ret = i2c_transfer(priv->i2c, msg, 2);
	mutex_unlock(&priv->i2c_mutex);
	if (ret == 2) {
		memcpy(val, buf, len);
		ret = 0;
	} else {
		dev_warn(&priv->i2c->dev,
				"%s: i2c rd failed=%d reg=%02x len=%d\n",
				KBUILD_MODNAME, ret, reg, len);
		ret = -EREMOTEIO;
	}

	return ret;
}

/* write single register */
static int m88ds3103_wr_reg(struct m88ds3103_priv *priv, u8 reg, u8 val)
{
	return m88ds3103_wr_regs(priv, reg, &val, 1);
}

/* read single register */
static int m88ds3103_rd_reg(struct m88ds3103_priv *priv, u8 reg, u8 *val)
{
	return m88ds3103_rd_regs(priv, reg, val, 1);
}

/* write single register with mask */
static int m88ds3103_wr_reg_mask(struct m88ds3103_priv *priv,
		u8 reg, u8 val, u8 mask)
{
	int ret;
	u8 u8tmp;

	/* no need for read if whole reg is written */
	if (mask != 0xff) {
		ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1);
		if (ret)
			return ret;

		val &= mask;
		u8tmp &= ~mask;
		val |= u8tmp;
	}

	return m88ds3103_wr_regs(priv, reg, &val, 1);
}

/* read single register with mask */
static int m88ds3103_rd_reg_mask(struct m88ds3103_priv *priv,
		u8 reg, u8 *val, u8 mask)
{
	int ret, i;
	u8 u8tmp;

	ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1);
	if (ret)
		return ret;

	u8tmp &= mask;

	/* find position of the first bit */
	for (i = 0; i < 8; i++) {
		if ((mask >> i) & 0x01)
			break;
	}
	*val = u8tmp >> i;

	return 0;
}

/* write reg val table using reg addr auto increment */
static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
		const struct m88ds3103_reg_val *tab, int tab_len)
{
	int ret, i, j;
	u8 buf[83];

	dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);

	if (tab_len > 86) {
		ret = -EINVAL;
		goto err;
	}

	for (i = 0, j = 0; i < tab_len; i++, j++) {
		buf[j] = tab[i].val;

		if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 ||
				!((j + 1) % (priv->cfg->i2c_wr_max - 1))) {
			ret = m88ds3103_wr_regs(priv, tab[i].reg - j, buf, j + 1);
			if (ret)
				goto err;

			j = -1;
		}
	}

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	int ret;
	u8 u8tmp;

	*status = 0;

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	switch (c->delivery_system) {
	case SYS_DVBS:
		ret = m88ds3103_rd_reg_mask(priv, 0xd1, &u8tmp, 0x07);
		if (ret)
			goto err;

		if (u8tmp == 0x07)
			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
					FE_HAS_VITERBI | FE_HAS_SYNC |
					FE_HAS_LOCK;
		break;
	case SYS_DVBS2:
		ret = m88ds3103_rd_reg_mask(priv, 0x0d, &u8tmp, 0x8f);
		if (ret)
			goto err;

		if (u8tmp == 0x8f)
			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
					FE_HAS_VITERBI | FE_HAS_SYNC |
					FE_HAS_LOCK;
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	priv->fe_status = *status;

	dev_dbg(&priv->i2c->dev, "%s: lock=%02x status=%02x\n",
			__func__, u8tmp, *status);

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_set_frontend(struct dvb_frontend *fe)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	int ret, len;
	const struct m88ds3103_reg_val *init;
	u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */
	u8 buf[3];
	u16 u16tmp, divide_ratio = 0;
	u32 tuner_frequency, target_mclk;
	s32 s32tmp;

	dev_dbg(&priv->i2c->dev,
			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
			__func__, c->delivery_system,
			c->modulation, c->frequency, c->symbol_rate,
			c->inversion, c->pilot, c->rolloff);

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	/* reset */
	ret = m88ds3103_wr_reg(priv, 0x07, 0x80);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
	if (ret)
		goto err;

	/* Disable demod clock path */
	if (priv->chip_id == M88RS6000_CHIP_ID) {
		ret = m88ds3103_wr_reg(priv, 0x06, 0xe0);
		if (ret)
			goto err;
	}

	/* program tuner */
	if (fe->ops.tuner_ops.set_params) {
		ret = fe->ops.tuner_ops.set_params(fe);
		if (ret)
			goto err;
	}

	if (fe->ops.tuner_ops.get_frequency) {
		ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_frequency);
		if (ret)
			goto err;
	} else {
		/*
		 * Use nominal target frequency as tuner driver does not provide
		 * actual frequency used. Carrier offset calculation is not
		 * valid.
		 */
		tuner_frequency = c->frequency;
	}

	/* select M88RS6000 demod main mclk and ts mclk from tuner die. */
	if (priv->chip_id == M88RS6000_CHIP_ID) {
		if (c->symbol_rate > 45010000)
			priv->mclk_khz = 110250;
		else
			priv->mclk_khz = 96000;

		if (c->delivery_system == SYS_DVBS)
			target_mclk = 96000;
		else
			target_mclk = 144000;

		/* Enable demod clock path */
		ret = m88ds3103_wr_reg(priv, 0x06, 0x00);
		if (ret)
			goto err;
		usleep_range(10000, 20000);
	} else {
	/* set M88DS3103 mclk and ts mclk. */
		priv->mclk_khz = 96000;

		switch (priv->cfg->ts_mode) {
		case M88DS3103_TS_SERIAL:
		case M88DS3103_TS_SERIAL_D7:
			target_mclk = priv->cfg->ts_clk;
			break;
		case M88DS3103_TS_PARALLEL:
		case M88DS3103_TS_CI:
			if (c->delivery_system == SYS_DVBS)
				target_mclk = 96000;
			else {
				if (c->symbol_rate < 18000000)
					target_mclk = 96000;
				else if (c->symbol_rate < 28000000)
					target_mclk = 144000;
				else
					target_mclk = 192000;
			}
			break;
		default:
			dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n",
					__func__);
			ret = -EINVAL;
			goto err;
		}

		switch (target_mclk) {
		case 96000:
			u8tmp1 = 0x02; /* 0b10 */
			u8tmp2 = 0x01; /* 0b01 */
			break;
		case 144000:
			u8tmp1 = 0x00; /* 0b00 */
			u8tmp2 = 0x01; /* 0b01 */
			break;
		case 192000:
			u8tmp1 = 0x03; /* 0b11 */
			u8tmp2 = 0x00; /* 0b00 */
			break;
		}
		ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
		if (ret)
			goto err;
		ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0);
		if (ret)
			goto err;
	}

	ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0x00, 0x01);
	if (ret)
		goto err;

	switch (c->delivery_system) {
	case SYS_DVBS:
		if (priv->chip_id == M88RS6000_CHIP_ID) {
			len = ARRAY_SIZE(m88rs6000_dvbs_init_reg_vals);
			init = m88rs6000_dvbs_init_reg_vals;
		} else {
			len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals);
			init = m88ds3103_dvbs_init_reg_vals;
		}
		break;
	case SYS_DVBS2:
		if (priv->chip_id == M88RS6000_CHIP_ID) {
			len = ARRAY_SIZE(m88rs6000_dvbs2_init_reg_vals);
			init = m88rs6000_dvbs2_init_reg_vals;
		} else {
			len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals);
			init = m88ds3103_dvbs2_init_reg_vals;
		}
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	/* program init table */
	if (c->delivery_system != priv->delivery_system) {
		ret = m88ds3103_wr_reg_val_tab(priv, init, len);
		if (ret)
			goto err;
	}

	if (priv->chip_id == M88RS6000_CHIP_ID) {
		if ((c->delivery_system == SYS_DVBS2)
			&& ((c->symbol_rate / 1000) <= 5000)) {
			ret = m88ds3103_wr_reg(priv, 0xc0, 0x04);
			if (ret)
				goto err;
			buf[0] = 0x09;
			buf[1] = 0x22;
			buf[2] = 0x88;
			ret = m88ds3103_wr_regs(priv, 0x8a, buf, 3);
			if (ret)
				goto err;
		}
		ret = m88ds3103_wr_reg_mask(priv, 0x9d, 0x08, 0x08);
		if (ret)
			goto err;
		ret = m88ds3103_wr_reg(priv, 0xf1, 0x01);
		if (ret)
			goto err;
		ret = m88ds3103_wr_reg_mask(priv, 0x30, 0x80, 0x80);
		if (ret)
			goto err;
	}

	switch (priv->cfg->ts_mode) {
	case M88DS3103_TS_SERIAL:
		u8tmp1 = 0x00;
		u8tmp = 0x06;
		break;
	case M88DS3103_TS_SERIAL_D7:
		u8tmp1 = 0x20;
		u8tmp = 0x06;
		break;
	case M88DS3103_TS_PARALLEL:
		u8tmp = 0x02;
		break;
	case M88DS3103_TS_CI:
		u8tmp = 0x03;
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__);
		ret = -EINVAL;
		goto err;
	}

	if (priv->cfg->ts_clk_pol)
		u8tmp |= 0x40;

	/* TS mode */
	ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp);
	if (ret)
		goto err;

	switch (priv->cfg->ts_mode) {
	case M88DS3103_TS_SERIAL:
	case M88DS3103_TS_SERIAL_D7:
		ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20);
		if (ret)
			goto err;
		u8tmp1 = 0;
		u8tmp2 = 0;
		break;
	default:
		if (priv->cfg->ts_clk) {
			divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
			u8tmp1 = divide_ratio / 2;
			u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
		}
	}

	dev_dbg(&priv->i2c->dev,
			"%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n",
			__func__, target_mclk, priv->cfg->ts_clk, divide_ratio);

	u8tmp1--;
	u8tmp2--;
	/* u8tmp1[5:2] => fe[3:0], u8tmp1[1:0] => ea[7:6] */
	u8tmp1 &= 0x3f;
	/* u8tmp2[5:0] => ea[5:0] */
	u8tmp2 &= 0x3f;

	ret = m88ds3103_rd_reg(priv, 0xfe, &u8tmp);
	if (ret)
		goto err;

	u8tmp = ((u8tmp  & 0xf0) << 0) | u8tmp1 >> 2;
	ret = m88ds3103_wr_reg(priv, 0xfe, u8tmp);
	if (ret)
		goto err;

	u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0;
	ret = m88ds3103_wr_reg(priv, 0xea, u8tmp);
	if (ret)
		goto err;

	if (c->symbol_rate <= 3000000)
		u8tmp = 0x20;
	else if (c->symbol_rate <= 10000000)
		u8tmp = 0x10;
	else
		u8tmp = 0x06;

	ret = m88ds3103_wr_reg(priv, 0xc3, 0x08);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0xc8, u8tmp);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0xc4, 0x08);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0xc7, 0x00);
	if (ret)
		goto err;

	u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, priv->mclk_khz / 2);
	buf[0] = (u16tmp >> 0) & 0xff;
	buf[1] = (u16tmp >> 8) & 0xff;
	ret = m88ds3103_wr_regs(priv, 0x61, buf, 2);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x4d, priv->cfg->spec_inv << 1, 0x02);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x30, priv->cfg->agc_inv << 4, 0x10);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0x33, priv->cfg->agc);
	if (ret)
		goto err;

	dev_dbg(&priv->i2c->dev, "%s: carrier offset=%d\n", __func__,
			(tuner_frequency - c->frequency));

	s32tmp = 0x10000 * (tuner_frequency - c->frequency);
	s32tmp = DIV_ROUND_CLOSEST(s32tmp, priv->mclk_khz);
	if (s32tmp < 0)
		s32tmp += 0x10000;

	buf[0] = (s32tmp >> 0) & 0xff;
	buf[1] = (s32tmp >> 8) & 0xff;
	ret = m88ds3103_wr_regs(priv, 0x5e, buf, 2);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0x00, 0x00);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0xb2, 0x00);
	if (ret)
		goto err;

	priv->delivery_system = c->delivery_system;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_init(struct dvb_frontend *fe)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret, len, remaining;
	const struct firmware *fw = NULL;
	u8 *fw_file;
	u8 u8tmp;

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);

	/* set cold state by default */
	priv->warm = false;

	/* wake up device from sleep */
	ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x01, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x00, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x00, 0x10);
	if (ret)
		goto err;

	/* firmware status */
	ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp);
	if (ret)
		goto err;

	dev_dbg(&priv->i2c->dev, "%s: firmware=%02x\n", __func__, u8tmp);

	if (u8tmp)
		goto skip_fw_download;

	/* global reset, global diseqc reset, golbal fec reset */
	ret = m88ds3103_wr_reg(priv, 0x07, 0xe0);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
	if (ret)
		goto err;

	/* cold state - try to download firmware */
	dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n",
			KBUILD_MODNAME, m88ds3103_ops.info.name);

	if (priv->chip_id == M88RS6000_CHIP_ID)
		fw_file = M88RS6000_FIRMWARE;
	else
		fw_file = M88DS3103_FIRMWARE;
	/* request the firmware, this will block and timeout */
	ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
	if (ret) {
		dev_err(&priv->i2c->dev, "%s: firmware file '%s' not found\n",
				KBUILD_MODNAME, fw_file);
		goto err;
	}

	dev_info(&priv->i2c->dev, "%s: downloading firmware from file '%s'\n",
			KBUILD_MODNAME, fw_file);

	ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
	if (ret)
		goto error_fw_release;

	for (remaining = fw->size; remaining > 0;
			remaining -= (priv->cfg->i2c_wr_max - 1)) {
		len = remaining;
		if (len > (priv->cfg->i2c_wr_max - 1))
			len = (priv->cfg->i2c_wr_max - 1);

		ret = m88ds3103_wr_regs(priv, 0xb0,
				&fw->data[fw->size - remaining], len);
		if (ret) {
			dev_err(&priv->i2c->dev,
					"%s: firmware download failed=%d\n",
					KBUILD_MODNAME, ret);
			goto error_fw_release;
		}
	}

	ret = m88ds3103_wr_reg(priv, 0xb2, 0x00);
	if (ret)
		goto error_fw_release;

	release_firmware(fw);
	fw = NULL;

	ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp);
	if (ret)
		goto err;

	if (!u8tmp) {
		dev_info(&priv->i2c->dev, "%s: firmware did not run\n",
				KBUILD_MODNAME);
		ret = -EFAULT;
		goto err;
	}

	dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n",
			KBUILD_MODNAME, m88ds3103_ops.info.name);
	dev_info(&priv->i2c->dev, "%s: firmware version %X.%X\n",
			KBUILD_MODNAME, (u8tmp >> 4) & 0xf, (u8tmp >> 0 & 0xf));

skip_fw_download:
	/* warm state */
	priv->warm = true;

	return 0;

error_fw_release:
	release_firmware(fw);
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_sleep(struct dvb_frontend *fe)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret;
	u8 u8tmp;

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);

	priv->delivery_system = SYS_UNDEFINED;

	/* TS Hi-Z */
	if (priv->chip_id == M88RS6000_CHIP_ID)
		u8tmp = 0x29;
	else
		u8tmp = 0x27;
	ret = m88ds3103_wr_reg_mask(priv, u8tmp, 0x00, 0x01);
	if (ret)
		goto err;

	/* sleep */
	ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10);
	if (ret)
		goto err;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_get_frontend(struct dvb_frontend *fe)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	int ret;
	u8 buf[3];

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);

	if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
		ret = -EAGAIN;
		goto err;
	}

	switch (c->delivery_system) {
	case SYS_DVBS:
		ret = m88ds3103_rd_reg(priv, 0xe0, &buf[0]);
		if (ret)
			goto err;

		ret = m88ds3103_rd_reg(priv, 0xe6, &buf[1]);
		if (ret)
			goto err;

		switch ((buf[0] >> 2) & 0x01) {
		case 0:
			c->inversion = INVERSION_OFF;
			break;
		case 1:
			c->inversion = INVERSION_ON;
			break;
		}

		switch ((buf[1] >> 5) & 0x07) {
		case 0:
			c->fec_inner = FEC_7_8;
			break;
		case 1:
			c->fec_inner = FEC_5_6;
			break;
		case 2:
			c->fec_inner = FEC_3_4;
			break;
		case 3:
			c->fec_inner = FEC_2_3;
			break;
		case 4:
			c->fec_inner = FEC_1_2;
			break;
		default:
			dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n",
					__func__);
		}

		c->modulation = QPSK;

		break;
	case SYS_DVBS2:
		ret = m88ds3103_rd_reg(priv, 0x7e, &buf[0]);
		if (ret)
			goto err;

		ret = m88ds3103_rd_reg(priv, 0x89, &buf[1]);
		if (ret)
			goto err;

		ret = m88ds3103_rd_reg(priv, 0xf2, &buf[2]);
		if (ret)
			goto err;

		switch ((buf[0] >> 0) & 0x0f) {
		case 2:
			c->fec_inner = FEC_2_5;
			break;
		case 3:
			c->fec_inner = FEC_1_2;
			break;
		case 4:
			c->fec_inner = FEC_3_5;
			break;
		case 5:
			c->fec_inner = FEC_2_3;
			break;
		case 6:
			c->fec_inner = FEC_3_4;
			break;
		case 7:
			c->fec_inner = FEC_4_5;
			break;
		case 8:
			c->fec_inner = FEC_5_6;
			break;
		case 9:
			c->fec_inner = FEC_8_9;
			break;
		case 10:
			c->fec_inner = FEC_9_10;
			break;
		default:
			dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n",
					__func__);
		}

		switch ((buf[0] >> 5) & 0x01) {
		case 0:
			c->pilot = PILOT_OFF;
			break;
		case 1:
			c->pilot = PILOT_ON;
			break;
		}

		switch ((buf[0] >> 6) & 0x07) {
		case 0:
			c->modulation = QPSK;
			break;
		case 1:
			c->modulation = PSK_8;
			break;
		case 2:
			c->modulation = APSK_16;
			break;
		case 3:
			c->modulation = APSK_32;
			break;
		default:
			dev_dbg(&priv->i2c->dev, "%s: invalid modulation\n",
					__func__);
		}

		switch ((buf[1] >> 7) & 0x01) {
		case 0:
			c->inversion = INVERSION_OFF;
			break;
		case 1:
			c->inversion = INVERSION_ON;
			break;
		}

		switch ((buf[2] >> 0) & 0x03) {
		case 0:
			c->rolloff = ROLLOFF_35;
			break;
		case 1:
			c->rolloff = ROLLOFF_25;
			break;
		case 2:
			c->rolloff = ROLLOFF_20;
			break;
		default:
			dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n",
					__func__);
		}
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	ret = m88ds3103_rd_regs(priv, 0x6d, buf, 2);
	if (ret)
		goto err;

	c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) *
			priv->mclk_khz * 1000 / 0x10000;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	int ret, i, tmp;
	u8 buf[3];
	u16 noise, signal;
	u32 noise_tot, signal_tot;

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
	/* reports SNR in resolution of 0.1 dB */

	/* more iterations for more accurate estimation */
	#define M88DS3103_SNR_ITERATIONS 3

	switch (c->delivery_system) {
	case SYS_DVBS:
		tmp = 0;

		for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
			ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]);
			if (ret)
				goto err;

			tmp += buf[0];
		}

		/* use of one register limits max value to 15 dB */
		/* SNR(X) dB = 10 * ln(X) / ln(10) dB */
		tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
		if (tmp)
			*snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10));
		else
			*snr = 0;
		break;
	case SYS_DVBS2:
		noise_tot = 0;
		signal_tot = 0;

		for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
			ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3);
			if (ret)
				goto err;

			noise = buf[1] << 6;    /* [13:6] */
			noise |= buf[0] & 0x3f; /*  [5:0] */
			noise >>= 2;
			signal = buf[2] * buf[2];
			signal >>= 1;

			noise_tot += noise;
			signal_tot += signal;
		}

		noise = noise_tot / M88DS3103_SNR_ITERATIONS;
		signal = signal_tot / M88DS3103_SNR_ITERATIONS;

		/* SNR(X) dB = 10 * log10(X) dB */
		if (signal > noise) {
			tmp = signal / noise;
			*snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24));
		} else {
			*snr = 0;
		}
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	int ret;
	unsigned int utmp;
	u8 buf[3], u8tmp;

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);

	switch (c->delivery_system) {
	case SYS_DVBS:
		ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
		if (ret)
			goto err;

		ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
		if (ret)
			goto err;

		if (!(u8tmp & 0x10)) {
			u8tmp |= 0x10;

			ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
			if (ret)
				goto err;

			priv->ber = (buf[1] << 8) | (buf[0] << 0);

			/* restart counters */
			ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
			if (ret)
				goto err;
		}
		break;
	case SYS_DVBS2:
		ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
		if (ret)
			goto err;

		utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);

		if (utmp > 3000) {
			ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
			if (ret)
				goto err;

			priv->ber = (buf[1] << 8) | (buf[0] << 0);

			/* restart counters */
			ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
			if (ret)
				goto err;

			ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
			if (ret)
				goto err;

			ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
			if (ret)
				goto err;

			ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
			if (ret)
				goto err;
		}
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	*ber = priv->ber;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_set_tone(struct dvb_frontend *fe,
	fe_sec_tone_mode_t fe_sec_tone_mode)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret;
	u8 u8tmp, tone, reg_a1_mask;

	dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__,
			fe_sec_tone_mode);

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	switch (fe_sec_tone_mode) {
	case SEC_TONE_ON:
		tone = 0;
		reg_a1_mask = 0x47;
		break;
	case SEC_TONE_OFF:
		tone = 1;
		reg_a1_mask = 0x00;
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	u8tmp = tone << 7 | priv->cfg->envelope_mode << 5;
	ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
	if (ret)
		goto err;

	u8tmp = 1 << 2;
	ret = m88ds3103_wr_reg_mask(priv, 0xa1, u8tmp, reg_a1_mask);
	if (ret)
		goto err;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_set_voltage(struct dvb_frontend *fe,
	fe_sec_voltage_t fe_sec_voltage)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret;
	u8 u8tmp;
	bool voltage_sel, voltage_dis;

	dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
			fe_sec_voltage);

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	switch (fe_sec_voltage) {
	case SEC_VOLTAGE_18:
		voltage_sel = true;
		voltage_dis = false;
		break;
	case SEC_VOLTAGE_13:
		voltage_sel = false;
		voltage_dis = false;
		break;
	case SEC_VOLTAGE_OFF:
		voltage_sel = false;
		voltage_dis = true;
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	/* output pin polarity */
	voltage_sel ^= priv->cfg->lnb_hv_pol;
	voltage_dis ^= priv->cfg->lnb_en_pol;

	u8tmp = voltage_dis << 1 | voltage_sel << 0;
	ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0x03);
	if (ret)
		goto err;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
		struct dvb_diseqc_master_cmd *diseqc_cmd)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret, i;
	u8 u8tmp;

	dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
			diseqc_cmd->msg_len, diseqc_cmd->msg);

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
		ret = -EINVAL;
		goto err;
	}

	u8tmp = priv->cfg->envelope_mode << 5;
	ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
	if (ret)
		goto err;

	ret = m88ds3103_wr_regs(priv, 0xa3, diseqc_cmd->msg,
			diseqc_cmd->msg_len);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg(priv, 0xa1,
			(diseqc_cmd->msg_len - 1) << 3 | 0x07);
	if (ret)
		goto err;

	/* DiSEqC message typical period is 54 ms */
	usleep_range(40000, 60000);

	/* wait DiSEqC TX ready */
	for (i = 20, u8tmp = 1; i && u8tmp; i--) {
		usleep_range(5000, 10000);

		ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
		if (ret)
			goto err;
	}

	dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);

	if (i == 0) {
		dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);

		ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0);
		if (ret)
			goto err;
	}

	ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0);
	if (ret)
		goto err;

	if (i == 0) {
		ret = -ETIMEDOUT;
		goto err;
	}

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
	fe_sec_mini_cmd_t fe_sec_mini_cmd)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;
	int ret, i;
	u8 u8tmp, burst;

	dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
			fe_sec_mini_cmd);

	if (!priv->warm) {
		ret = -EAGAIN;
		goto err;
	}

	u8tmp = priv->cfg->envelope_mode << 5;
	ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
	if (ret)
		goto err;

	switch (fe_sec_mini_cmd) {
	case SEC_MINI_A:
		burst = 0x02;
		break;
	case SEC_MINI_B:
		burst = 0x01;
		break;
	default:
		dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n",
				__func__);
		ret = -EINVAL;
		goto err;
	}

	ret = m88ds3103_wr_reg(priv, 0xa1, burst);
	if (ret)
		goto err;

	/* DiSEqC ToneBurst period is 12.5 ms */
	usleep_range(11000, 20000);

	/* wait DiSEqC TX ready */
	for (i = 5, u8tmp = 1; i && u8tmp; i--) {
		usleep_range(800, 2000);

		ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
		if (ret)
			goto err;
	}

	dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);

	ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0);
	if (ret)
		goto err;

	if (i == 0) {
		dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
		ret = -ETIMEDOUT;
		goto err;
	}

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
	struct dvb_frontend_tune_settings *s)
{
	s->min_delay_ms = 3000;

	return 0;
}

static void m88ds3103_release(struct dvb_frontend *fe)
{
	struct m88ds3103_priv *priv = fe->demodulator_priv;

	i2c_del_mux_adapter(priv->i2c_adapter);
	kfree(priv);
}

static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
{
	struct m88ds3103_priv *priv = mux_priv;
	int ret;
	struct i2c_msg gate_open_msg[1] = {
		{
			.addr = priv->cfg->i2c_addr,
			.flags = 0,
			.len = 2,
			.buf = "\x03\x11",
		}
	};

	mutex_lock(&priv->i2c_mutex);

	/* open tuner I2C repeater for 1 xfer, closes automatically */
	ret = __i2c_transfer(priv->i2c, gate_open_msg, 1);
	if (ret != 1) {
		dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d\n",
				KBUILD_MODNAME, ret);
		if (ret >= 0)
			ret = -EREMOTEIO;

		return ret;
	}

	return 0;
}

static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv,
		u32 chan)
{
	struct m88ds3103_priv *priv = mux_priv;

	mutex_unlock(&priv->i2c_mutex);

	return 0;
}

struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
		struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
{
	int ret;
	struct m88ds3103_priv *priv;
	u8 chip_id, u8tmp;

	/* allocate memory for the internal priv */
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
		goto err;
	}

	priv->cfg = cfg;
	priv->i2c = i2c;
	mutex_init(&priv->i2c_mutex);

	/* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */
	ret = m88ds3103_rd_reg(priv, 0x00, &chip_id);
	if (ret)
		goto err;

	chip_id >>= 1;
	dev_info(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);

	switch (chip_id) {
	case M88RS6000_CHIP_ID:
	case M88DS3103_CHIP_ID:
		break;
	default:
		goto err;
	}
	priv->chip_id = chip_id;

	switch (priv->cfg->clock_out) {
	case M88DS3103_CLOCK_OUT_DISABLED:
		u8tmp = 0x80;
		break;
	case M88DS3103_CLOCK_OUT_ENABLED:
		u8tmp = 0x00;
		break;
	case M88DS3103_CLOCK_OUT_ENABLED_DIV2:
		u8tmp = 0x10;
		break;
	default:
		goto err;
	}

	/* 0x29 register is defined differently for m88rs6000. */
	/* set internal tuner address to 0x21 */
	if (chip_id == M88RS6000_CHIP_ID)
		u8tmp = 0x00;

	ret = m88ds3103_wr_reg(priv, 0x29, u8tmp);
	if (ret)
		goto err;

	/* sleep */
	ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01);
	if (ret)
		goto err;

	ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10);
	if (ret)
		goto err;

	/* create mux i2c adapter for tuner */
	priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
			m88ds3103_select, m88ds3103_deselect);
	if (priv->i2c_adapter == NULL)
		goto err;

	*tuner_i2c_adapter = priv->i2c_adapter;

	/* create dvb_frontend */
	memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
	if (priv->chip_id == M88RS6000_CHIP_ID)
		strncpy(priv->fe.ops.info.name,
			"Montage M88RS6000", sizeof(priv->fe.ops.info.name));
	priv->fe.demodulator_priv = priv;

	return &priv->fe;
err:
	dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
	kfree(priv);
	return NULL;
}
EXPORT_SYMBOL(m88ds3103_attach);

static struct dvb_frontend_ops m88ds3103_ops = {
	.delsys = { SYS_DVBS, SYS_DVBS2 },
	.info = {
		.name = "Montage M88DS3103",
		.frequency_min =  950000,
		.frequency_max = 2150000,
		.frequency_tolerance = 5000,
		.symbol_rate_min =  1000000,
		.symbol_rate_max = 45000000,
		.caps = FE_CAN_INVERSION_AUTO |
			FE_CAN_FEC_1_2 |
			FE_CAN_FEC_2_3 |
			FE_CAN_FEC_3_4 |
			FE_CAN_FEC_4_5 |
			FE_CAN_FEC_5_6 |
			FE_CAN_FEC_6_7 |
			FE_CAN_FEC_7_8 |
			FE_CAN_FEC_8_9 |
			FE_CAN_FEC_AUTO |
			FE_CAN_QPSK |
			FE_CAN_RECOVER |
			FE_CAN_2G_MODULATION
	},

	.release = m88ds3103_release,

	.get_tune_settings = m88ds3103_get_tune_settings,

	.init = m88ds3103_init,
	.sleep = m88ds3103_sleep,

	.set_frontend = m88ds3103_set_frontend,
	.get_frontend = m88ds3103_get_frontend,

	.read_status = m88ds3103_read_status,
	.read_snr = m88ds3103_read_snr,
	.read_ber = m88ds3103_read_ber,

	.diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
	.diseqc_send_burst = m88ds3103_diseqc_send_burst,

	.set_tone = m88ds3103_set_tone,
	.set_voltage = m88ds3103_set_voltage,
};

MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(M88DS3103_FIRMWARE);
MODULE_FIRMWARE(M88RS6000_FIRMWARE);
