// SPDX-License-Identifier: GPL-2.0
/*
 *  c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
 *
 * Copyright (c) STMicroelectronics 2015
 *
 *  Author Peter Griffin <peter.griffin@linaro.org>
 *
 */
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/version.h>

#include <dt-bindings/media/c8sectpfe.h>

#include "c8sectpfe-common.h"
#include "c8sectpfe-core.h"
#include "c8sectpfe-dvb.h"

#include "dvb-pll.h"
#include "lnbh24.h"
#include "stv0367.h"
#include "stv0367_priv.h"
#include "stv6110x.h"
#include "stv090x.h"
#include "tda18212.h"

static inline const char *dvb_card_str(unsigned int c)
{
	switch (c) {
	case STV0367_TDA18212_NIMA_1:	return "STV0367_TDA18212_NIMA_1";
	case STV0367_TDA18212_NIMA_2:	return "STV0367_TDA18212_NIMA_2";
	case STV0367_TDA18212_NIMB_1:	return "STV0367_TDA18212_NIMB_1";
	case STV0367_TDA18212_NIMB_2:	return "STV0367_TDA18212_NIMB_2";
	case STV0903_6110_LNB24_NIMA:	return "STV0903_6110_LNB24_NIMA";
	case STV0903_6110_LNB24_NIMB:	return "STV0903_6110_LNB24_NIMB";
	default:			return "unknown dvb frontend card";
	}
}

static struct stv090x_config stv090x_config = {
	.device                 = STV0903,
	.demod_mode             = STV090x_SINGLE,
	.clk_mode               = STV090x_CLK_EXT,
	.xtal                   = 16000000,
	.address                = 0x69,

	.ts1_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
	.ts2_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,

	.repeater_level         = STV090x_RPTLEVEL_64,

	.tuner_init             = NULL,
	.tuner_set_mode         = NULL,
	.tuner_set_frequency    = NULL,
	.tuner_get_frequency    = NULL,
	.tuner_set_bandwidth    = NULL,
	.tuner_get_bandwidth    = NULL,
	.tuner_set_bbgain       = NULL,
	.tuner_get_bbgain       = NULL,
	.tuner_set_refclk       = NULL,
	.tuner_get_status       = NULL,
};

static struct stv6110x_config stv6110x_config = {
	.addr                   = 0x60,
	.refclk                 = 16000000,
};

#define NIMA 0
#define NIMB 1

static struct stv0367_config stv0367_tda18212_config[] = {
	{
		.demod_address = 0x1c,
		.xtal = 16000000,
		.if_khz = 4500,
		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
	}, {
		.demod_address = 0x1d,
		.xtal = 16000000,
		.if_khz = 4500,
		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
	}, {
		.demod_address = 0x1e,
		.xtal = 16000000,
		.if_khz = 4500,
		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
	},
};

static struct tda18212_config tda18212_conf = {
	.if_dvbt_6 = 4150,
	.if_dvbt_7 = 4150,
	.if_dvbt_8 = 4500,
	.if_dvbc = 5000,
};

int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
		struct c8sectpfe *c8sectpfe,
		struct channel_info *tsin, int chan_num)
{
	struct tda18212_config *tda18212;
	const struct stv6110x_devctl *fe2;
	struct i2c_client *client;
	struct i2c_board_info tda18212_info = {
		.type = "tda18212",
		.addr = 0x60,
	};

	if (!tsin)
		return -EINVAL;

	switch (tsin->dvb_card) {

	case STV0367_TDA18212_NIMA_1:
	case STV0367_TDA18212_NIMA_2:
	case STV0367_TDA18212_NIMB_1:
	case STV0367_TDA18212_NIMB_2:
		if (tsin->dvb_card == STV0367_TDA18212_NIMA_1)
			*fe = dvb_attach(stv0367ter_attach,
				 &stv0367_tda18212_config[0],
					tsin->i2c_adapter);
		else if (tsin->dvb_card == STV0367_TDA18212_NIMB_1)
			*fe = dvb_attach(stv0367ter_attach,
				 &stv0367_tda18212_config[1],
					tsin->i2c_adapter);
		else
			*fe = dvb_attach(stv0367ter_attach,
				 &stv0367_tda18212_config[2],
					tsin->i2c_adapter);

		if (!*fe) {
			dev_err(c8sectpfe->device,
				"%s: stv0367ter_attach failed for NIM card %s\n"
				, __func__, dvb_card_str(tsin->dvb_card));
			return -ENODEV;
		};

		/*
		 * init the demod so that i2c gate_ctrl
		 * to the tuner works correctly
		 */
		(*fe)->ops.init(*fe);

		/* Allocate the tda18212 structure */
		tda18212 = devm_kzalloc(c8sectpfe->device,
					sizeof(struct tda18212_config),
					GFP_KERNEL);
		if (!tda18212) {
			dev_err(c8sectpfe->device,
				"%s: devm_kzalloc failed\n", __func__);
			return -ENOMEM;
		}

		memcpy(tda18212, &tda18212_conf,
			sizeof(struct tda18212_config));

		tda18212->fe = (*fe);

		tda18212_info.platform_data = tda18212;

		/* attach tuner */
		request_module("tda18212");
		client = i2c_new_device(tsin->i2c_adapter, &tda18212_info);
		if (!client || !client->dev.driver) {
			dvb_frontend_detach(*fe);
			return -ENODEV;
		}

		if (!try_module_get(client->dev.driver->owner)) {
			i2c_unregister_device(client);
			dvb_frontend_detach(*fe);
			return -ENODEV;
		}

		tsin->i2c_client = client;

		break;

	case STV0903_6110_LNB24_NIMA:
		*fe = dvb_attach(stv090x_attach,	&stv090x_config,
				tsin->i2c_adapter, STV090x_DEMODULATOR_0);
		if (!*fe) {
			dev_err(c8sectpfe->device, "%s: stv090x_attach failed\n"
				"\tfor NIM card %s\n",
				__func__, dvb_card_str(tsin->dvb_card));
			return -ENODEV;
		}

		fe2 = dvb_attach(stv6110x_attach, *fe,
					&stv6110x_config, tsin->i2c_adapter);
		if (!fe2) {
			dev_err(c8sectpfe->device,
				"%s: stv6110x_attach failed for NIM card %s\n"
				, __func__, dvb_card_str(tsin->dvb_card));
			return -ENODEV;
		};

		stv090x_config.tuner_init = fe2->tuner_init;
		stv090x_config.tuner_set_mode = fe2->tuner_set_mode;
		stv090x_config.tuner_set_frequency = fe2->tuner_set_frequency;
		stv090x_config.tuner_get_frequency = fe2->tuner_get_frequency;
		stv090x_config.tuner_set_bandwidth = fe2->tuner_set_bandwidth;
		stv090x_config.tuner_get_bandwidth = fe2->tuner_get_bandwidth;
		stv090x_config.tuner_set_bbgain = fe2->tuner_set_bbgain;
		stv090x_config.tuner_get_bbgain = fe2->tuner_get_bbgain;
		stv090x_config.tuner_set_refclk = fe2->tuner_set_refclk;
		stv090x_config.tuner_get_status = fe2->tuner_get_status;

		dvb_attach(lnbh24_attach, *fe, tsin->i2c_adapter, 0, 0, 0x9);
		break;

	default:
		dev_err(c8sectpfe->device,
			"%s: DVB frontend card %s not yet supported\n",
			__func__, dvb_card_str(tsin->dvb_card));
		return -ENODEV;
	}

	(*fe)->id = chan_num;

	dev_info(c8sectpfe->device,
			"DVB frontend card %s successfully attached",
			dvb_card_str(tsin->dvb_card));
	return 0;
}
