// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * stv6110.c
 *
 * Driver for ST STV6110 satellite tuner IC.
 *
 * Copyright (C) 2009 NetUP Inc.
 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>

#include <linux/types.h>

#include "stv6110.h"

/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  64

static int debug;

struct stv6110_priv {
	int i2c_address;
	struct i2c_adapter *i2c;

	u32 mclk;
	u8 clk_div;
	u8 gain;
	u8 regs[8];
};

#define dprintk(args...) \
	do { \
		if (debug) \
			printk(KERN_DEBUG args); \
	} while (0)

static s32 abssub(s32 a, s32 b)
{
	if (a > b)
		return a - b;
	else
		return b - a;
};

static void stv6110_release(struct dvb_frontend *fe)
{
	kfree(fe->tuner_priv);
	fe->tuner_priv = NULL;
}

static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
							int start, int len)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	int rc;
	u8 cmdbuf[MAX_XFER_SIZE];
	struct i2c_msg msg = {
		.addr	= priv->i2c_address,
		.flags	= 0,
		.buf	= cmdbuf,
		.len	= len + 1
	};

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

	if (1 + len > sizeof(cmdbuf)) {
		printk(KERN_WARNING
		       "%s: i2c wr: len=%d is too big!\n",
		       KBUILD_MODNAME, len);
		return -EINVAL;
	}

	if (start + len > 8)
		return -EINVAL;

	memcpy(&cmdbuf[1], buf, len);
	cmdbuf[0] = start;

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	rc = i2c_transfer(priv->i2c, &msg, 1);
	if (rc != 1)
		dprintk("%s: i2c error\n", __func__);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	return 0;
}

static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
							int start, int len)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	int rc;
	u8 reg[] = { start };
	struct i2c_msg msg[] = {
		{
			.addr	= priv->i2c_address,
			.flags	= 0,
			.buf	= reg,
			.len	= 1,
		}, {
			.addr	= priv->i2c_address,
			.flags	= I2C_M_RD,
			.buf	= regs,
			.len	= len,
		},
	};

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	rc = i2c_transfer(priv->i2c, msg, 2);
	if (rc != 2)
		dprintk("%s: i2c error\n", __func__);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	memcpy(&priv->regs[start], regs, len);

	return 0;
}

static int stv6110_read_reg(struct dvb_frontend *fe, int start)
{
	u8 buf[] = { 0 };
	stv6110_read_regs(fe, buf, start, 1);

	return buf[0];
}

static int stv6110_sleep(struct dvb_frontend *fe)
{
	u8 reg[] = { 0 };
	stv6110_write_regs(fe, reg, 0, 1);

	return 0;
}

static u32 carrier_width(u32 symbol_rate, enum fe_rolloff rolloff)
{
	u32 rlf;

	switch (rolloff) {
	case ROLLOFF_20:
		rlf = 20;
		break;
	case ROLLOFF_25:
		rlf = 25;
		break;
	default:
		rlf = 35;
		break;
	}

	return symbol_rate  + ((symbol_rate * rlf) / 100);
}

static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 r8, ret = 0x04;
	int i;

	if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
		r8 = 31;
	else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
		r8 = 0;
	else /*if 5 < BW/2 < 36*/
		r8 = (bandwidth / 2) / 1000000 - 5;

	/* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
	/* ctrl3, CF = r8 Set the LPF value */
	priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
	priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
	/* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
	priv->regs[RSTV6110_STAT1] |= 0x02;
	stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);

	i = 0;
	/* Wait for CALRCSTRT == 0 */
	while ((i < 10) && (ret != 0)) {
		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
		mdelay(1);	/* wait for LPF auto calibration */
		i++;
	}

	/* RCCLKOFF = 1 calibration done, deactivate the calibration Clock */
	priv->regs[RSTV6110_CTRL3] |= (1 << 6);
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
	return 0;
}

static int stv6110_init(struct dvb_frontend *fe)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };

	memcpy(priv->regs, buf0, 8);
	/* K = (Reference / 1000000) - 16 */
	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
	priv->regs[RSTV6110_CTRL1] |=
				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);

	/* divisor value for the output clock */
	priv->regs[RSTV6110_CTRL2] &= ~0xc0;
	priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);

	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
	msleep(1);
	stv6110_set_bandwidth(fe, 72000000);

	return 0;
}

static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u32 nbsteps, divider, psd2, freq;
	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };

	stv6110_read_regs(fe, regs, 0, 8);
	/*N*/
	divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
	divider += priv->regs[RSTV6110_TUNING1];

	/*R*/
	nbsteps  = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
	/*p*/
	psd2  = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;

	freq = divider * (priv->mclk / 1000);
	freq /= (1 << (nbsteps + psd2));
	freq /= 4;

	*frequency = freq;

	return 0;
}

static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 ret = 0x04;
	u32 divider, ref, p, presc, i, result_freq, vco_freq;
	s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;

	dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
						frequency, priv->mclk);

	/* K = (Reference / 1000000) - 16 */
	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
	priv->regs[RSTV6110_CTRL1] |=
				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);

	/* BB_GAIN = db/2 */
	priv->regs[RSTV6110_CTRL2] &= ~0x0f;
	priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);

	if (frequency <= 1023000) {
		p = 1;
		presc = 0;
	} else if (frequency <= 1300000) {
		p = 1;
		presc = 1;
	} else if (frequency <= 2046000) {
		p = 0;
		presc = 0;
	} else {
		p = 0;
		presc = 1;
	}
	/* DIV4SEL = p*/
	priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
	priv->regs[RSTV6110_TUNING2] |= (p << 4);

	/* PRESC32ON = presc */
	priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
	priv->regs[RSTV6110_TUNING2] |= (presc << 5);

	p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
	for (r_div = 0; r_div <= 3; r_div++) {
		p_calc = (priv->mclk / 100000);
		p_calc /= (1 << (r_div + 1));
		if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
			r_div_opt = r_div;

		p_calc_opt = (priv->mclk / 100000);
		p_calc_opt /= (1 << (r_div_opt + 1));
	}

	ref = priv->mclk / ((1 << (r_div_opt + 1))  * (1 << (p + 1)));
	divider = (((frequency * 1000) + (ref >> 1)) / ref);

	/* RDIV = r_div_opt */
	priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
	priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);

	/* NDIV_MSB = MSB(divider) */
	priv->regs[RSTV6110_TUNING2] &= ~0x0f;
	priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);

	/* NDIV_LSB, LSB(divider) */
	priv->regs[RSTV6110_TUNING1] = (divider & 0xff);

	/* CALVCOSTRT = 1 VCO Auto Calibration */
	priv->regs[RSTV6110_STAT1] |= 0x04;
	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
						RSTV6110_CTRL1, 8);

	i = 0;
	/* Wait for CALVCOSTRT == 0 */
	while ((i < 10) && (ret != 0)) {
		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
		msleep(1); /* wait for VCO auto calibration */
		i++;
	}

	ret = stv6110_read_reg(fe, RSTV6110_STAT1);
	stv6110_get_frequency(fe, &result_freq);

	vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
	dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
						ret, result_freq, vco_freq);

	return 0;
}

static int stv6110_set_params(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);

	stv6110_set_frequency(fe, c->frequency);
	stv6110_set_bandwidth(fe, bandwidth);

	return 0;
}

static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
	struct stv6110_priv *priv = fe->tuner_priv;
	u8 r8 = 0;
	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	stv6110_read_regs(fe, regs, 0, 8);

	/* CF */
	r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
	*bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */

	return 0;
}

static const struct dvb_tuner_ops stv6110_tuner_ops = {
	.info = {
		.name = "ST STV6110",
		.frequency_min_hz  =  950 * MHz,
		.frequency_max_hz  = 2150 * MHz,
		.frequency_step_hz =    1 * MHz,
	},
	.init = stv6110_init,
	.release = stv6110_release,
	.sleep = stv6110_sleep,
	.set_params = stv6110_set_params,
	.get_frequency = stv6110_get_frequency,
	.set_frequency = stv6110_set_frequency,
	.get_bandwidth = stv6110_get_bandwidth,
	.set_bandwidth = stv6110_set_bandwidth,

};

struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
					const struct stv6110_config *config,
					struct i2c_adapter *i2c)
{
	struct stv6110_priv *priv = NULL;
	u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };

	struct i2c_msg msg[] = {
		{
			.addr = config->i2c_address,
			.flags = 0,
			.buf = reg0,
			.len = 9
		}
	};
	int ret;

	/* divisor value for the output clock */
	reg0[2] &= ~0xc0;
	reg0[2] |= (config->clk_div << 6);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);

	ret = i2c_transfer(i2c, msg, 1);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	if (ret != 1)
		return NULL;

	priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
	if (priv == NULL)
		return NULL;

	priv->i2c_address = config->i2c_address;
	priv->i2c = i2c;
	priv->mclk = config->mclk;
	priv->clk_div = config->clk_div;
	priv->gain = config->gain;

	memcpy(&priv->regs, &reg0[1], 8);

	memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
				sizeof(struct dvb_tuner_ops));
	fe->tuner_priv = priv;
	printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);

	return fe;
}
EXPORT_SYMBOL(stv6110_attach);

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

MODULE_DESCRIPTION("ST STV6110 driver");
MODULE_AUTHOR("Igor M. Liplianin");
MODULE_LICENSE("GPL");
