// SPDX-License-Identifier: GPL-2.0
/*
 * The Virtual DTV test driver serves as a reference DVB driver and helps
 * validate the existing APIs in the media subsystem. It can also aid
 * developers working on userspace applications.
 *
 * When this module is loaded, it will attempt to modprobe 'dvb_vidtv_tuner' and 'dvb_vidtv_demod'.
 *
 * Copyright (C) 2020 Daniel W. S. Almeida
 */

#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/dev_printk.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include "vidtv_bridge.h"
#include "vidtv_demod.h"
#include "vidtv_tuner.h"
#include "vidtv_ts.h"
#include "vidtv_mux.h"
#include "vidtv_common.h"

//#define MUX_BUF_MAX_SZ
//#define MUX_BUF_MIN_SZ
#define TUNER_DEFAULT_ADDR 0x68
#define DEMOD_DEFAULT_ADDR 0x60

/* LNBf fake parameters: ranges used by an Universal (extended) European LNBf */
#define LNB_CUT_FREQUENCY	11700000
#define LNB_LOW_FREQ		9750000
#define LNB_HIGH_FREQ		10600000


static unsigned int drop_tslock_prob_on_low_snr;
module_param(drop_tslock_prob_on_low_snr, uint, 0);
MODULE_PARM_DESC(drop_tslock_prob_on_low_snr,
		 "Probability of losing the TS lock if the signal quality is bad");

static unsigned int recover_tslock_prob_on_good_snr;
module_param(recover_tslock_prob_on_good_snr, uint, 0);
MODULE_PARM_DESC(recover_tslock_prob_on_good_snr,
		 "Probability recovering the TS lock when the signal improves");

static unsigned int mock_power_up_delay_msec;
module_param(mock_power_up_delay_msec, uint, 0);
MODULE_PARM_DESC(mock_power_up_delay_msec, "Simulate a power up delay");

static unsigned int mock_tune_delay_msec;
module_param(mock_tune_delay_msec, uint, 0);
MODULE_PARM_DESC(mock_tune_delay_msec, "Simulate a tune delay");

static unsigned int vidtv_valid_dvb_t_freqs[NUM_VALID_TUNER_FREQS] = {
	474000000
};

module_param_array(vidtv_valid_dvb_t_freqs, uint, NULL, 0);
MODULE_PARM_DESC(vidtv_valid_dvb_t_freqs,
		 "Valid DVB-T frequencies to simulate, in Hz");

static unsigned int vidtv_valid_dvb_c_freqs[NUM_VALID_TUNER_FREQS] = {
	474000000
};

module_param_array(vidtv_valid_dvb_c_freqs, uint, NULL, 0);
MODULE_PARM_DESC(vidtv_valid_dvb_c_freqs,
		 "Valid DVB-C frequencies to simulate, in Hz");

static unsigned int vidtv_valid_dvb_s_freqs[NUM_VALID_TUNER_FREQS] = {
	11362000
};
module_param_array(vidtv_valid_dvb_s_freqs, uint, NULL, 0);
MODULE_PARM_DESC(vidtv_valid_dvb_s_freqs,
		 "Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz");

static unsigned int max_frequency_shift_hz;
module_param(max_frequency_shift_hz, uint, 0);
MODULE_PARM_DESC(max_frequency_shift_hz,
		 "Maximum shift in HZ allowed when tuning in a channel");

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums);

/*
 * Influences the signal acquisition time. See ISO/IEC 13818-1 : 2000. p. 113.
 */
static unsigned int si_period_msec = 40;
module_param(si_period_msec, uint, 0);
MODULE_PARM_DESC(si_period_msec, "How often to send SI packets. Default: 40ms");

static unsigned int pcr_period_msec = 40;
module_param(pcr_period_msec, uint, 0);
MODULE_PARM_DESC(pcr_period_msec, "How often to send PCR packets. Default: 40ms");

static unsigned int mux_rate_kbytes_sec = 4096;
module_param(mux_rate_kbytes_sec, uint, 0);
MODULE_PARM_DESC(mux_rate_kbytes_sec, "Mux rate: will pad stream if below");

static unsigned int pcr_pid = 0x200;
module_param(pcr_pid, uint, 0);
MODULE_PARM_DESC(pcr_pid, "PCR PID for all channels: defaults to 0x200");

static unsigned int mux_buf_sz_pkts;
module_param(mux_buf_sz_pkts, uint, 0);
MODULE_PARM_DESC(mux_buf_sz_pkts, "Size for the internal mux buffer in multiples of 188 bytes");

#define MUX_BUF_MIN_SZ 90164
#define MUX_BUF_MAX_SZ (MUX_BUF_MIN_SZ * 10)

static u32 vidtv_bridge_mux_buf_sz_for_mux_rate(void)
{
	u32 max_elapsed_time_msecs =  VIDTV_MAX_SLEEP_USECS / USEC_PER_MSEC;
	u32 nbytes_expected;
	u32 mux_buf_sz = mux_buf_sz_pkts * TS_PACKET_LEN;

	nbytes_expected = mux_rate_kbytes_sec;
	nbytes_expected *= max_elapsed_time_msecs;

	mux_buf_sz = roundup(nbytes_expected, TS_PACKET_LEN);
	mux_buf_sz += mux_buf_sz / 10;

	if (mux_buf_sz < MUX_BUF_MIN_SZ)
		mux_buf_sz = MUX_BUF_MIN_SZ;

	if (mux_buf_sz > MUX_BUF_MAX_SZ)
		mux_buf_sz = MUX_BUF_MAX_SZ;

	return mux_buf_sz;
}

static bool vidtv_bridge_check_demod_lock(struct vidtv_dvb *dvb, u32 n)
{
	enum fe_status status;

	dvb->fe[n]->ops.read_status(dvb->fe[n], &status);

	return status == (FE_HAS_SIGNAL  |
			  FE_HAS_CARRIER |
			  FE_HAS_VITERBI |
			  FE_HAS_SYNC    |
			  FE_HAS_LOCK);
}

static void
vidtv_bridge_on_new_pkts_avail(void *priv, u8 *buf, u32 npkts)
{
	/*
	 * called on a separate thread by the mux when new packets become
	 * available
	 */
	struct vidtv_dvb *dvb = (struct vidtv_dvb *)priv;

	/* drop packets if we lose the lock */
	if (vidtv_bridge_check_demod_lock(dvb, 0))
		dvb_dmx_swfilter_packets(&dvb->demux, buf, npkts);
}

static int vidtv_start_streaming(struct vidtv_dvb *dvb)
{
	struct vidtv_mux_init_args mux_args = {0};
	struct device *dev = &dvb->pdev->dev;
	u32 mux_buf_sz;

	if (dvb->streaming) {
		dev_warn_ratelimited(dev, "Already streaming. Skipping.\n");
		return 0;
	}

	mux_buf_sz = (mux_buf_sz_pkts) ? mux_buf_sz_pkts : vidtv_bridge_mux_buf_sz_for_mux_rate();

	mux_args.mux_rate_kbytes_sec         = mux_rate_kbytes_sec;
	mux_args.on_new_packets_available_cb = vidtv_bridge_on_new_pkts_avail;
	mux_args.mux_buf_sz                  = mux_buf_sz;
	mux_args.pcr_period_usecs            = pcr_period_msec * 1000;
	mux_args.si_period_usecs             = si_period_msec * 1000;
	mux_args.pcr_pid                     = pcr_pid;
	mux_args.transport_stream_id         = VIDTV_DEFAULT_TS_ID;
	mux_args.priv                        = dvb;

	dvb->streaming = true;
	dvb->mux = vidtv_mux_init(dvb->fe[0], dev, mux_args);
	vidtv_mux_start_thread(dvb->mux);

	dev_dbg_ratelimited(dev, "Started streaming\n");
	return 0;
}

static int vidtv_stop_streaming(struct vidtv_dvb *dvb)
{
	struct device *dev = &dvb->pdev->dev;

	dvb->streaming = false;
	vidtv_mux_stop_thread(dvb->mux);
	vidtv_mux_destroy(dvb->mux);
	dvb->mux = NULL;

	dev_dbg_ratelimited(dev, "Stopped streaming\n");
	return 0;
}

static int vidtv_start_feed(struct dvb_demux_feed *feed)
{
	struct dvb_demux *demux = feed->demux;
	struct vidtv_dvb *dvb   = demux->priv;
	int rc;
	int ret;

	if (!demux->dmx.frontend)
		return -EINVAL;

	mutex_lock(&dvb->feed_lock);

	dvb->nfeeds++;
	rc = dvb->nfeeds;

	if (dvb->nfeeds == 1) {
		ret = vidtv_start_streaming(dvb);
		if (ret < 0)
			rc = ret;
	}

	mutex_unlock(&dvb->feed_lock);
	return rc;
}

static int vidtv_stop_feed(struct dvb_demux_feed *feed)
{
	struct dvb_demux *demux = feed->demux;
	struct vidtv_dvb *dvb   = demux->priv;
	int err = 0;

	mutex_lock(&dvb->feed_lock);
	dvb->nfeeds--;

	if (!dvb->nfeeds)
		err = vidtv_stop_streaming(dvb);

	mutex_unlock(&dvb->feed_lock);
	return err;
}

static struct dvb_frontend *vidtv_get_frontend_ptr(struct i2c_client *c)
{
	/* the demod will set this when its probe function runs */
	struct vidtv_demod_state *state = i2c_get_clientdata(c);

	return &state->frontend;
}

static int vidtv_master_xfer(struct i2c_adapter *i2c_adap,
			     struct i2c_msg msgs[],
			     int num)
{
	return 0;
}

static u32 vidtv_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C;
}

static const struct i2c_algorithm vidtv_i2c_algorithm = {
	.master_xfer   = vidtv_master_xfer,
	.functionality = vidtv_i2c_func,
};

static int vidtv_bridge_i2c_register_adap(struct vidtv_dvb *dvb)
{
	struct i2c_adapter *i2c_adapter = &dvb->i2c_adapter;

	strscpy(i2c_adapter->name, "vidtv_i2c", sizeof(i2c_adapter->name));
	i2c_adapter->owner      = THIS_MODULE;
	i2c_adapter->algo       = &vidtv_i2c_algorithm;
	i2c_adapter->algo_data  = NULL;
	i2c_adapter->timeout    = 500;
	i2c_adapter->retries    = 3;
	i2c_adapter->dev.parent = &dvb->pdev->dev;

	i2c_set_adapdata(i2c_adapter, dvb);
	return i2c_add_adapter(&dvb->i2c_adapter);
}

static int vidtv_bridge_register_adap(struct vidtv_dvb *dvb)
{
	int ret = 0;

	ret = dvb_register_adapter(&dvb->adapter,
				   KBUILD_MODNAME,
				   THIS_MODULE,
				   &dvb->i2c_adapter.dev,
				   adapter_nums);

	return ret;
}

static int vidtv_bridge_dmx_init(struct vidtv_dvb *dvb)
{
	dvb->demux.dmx.capabilities = DMX_TS_FILTERING |
				      DMX_SECTION_FILTERING;

	dvb->demux.priv       = dvb;
	dvb->demux.filternum  = 256;
	dvb->demux.feednum    = 256;
	dvb->demux.start_feed = vidtv_start_feed;
	dvb->demux.stop_feed  = vidtv_stop_feed;

	return dvb_dmx_init(&dvb->demux);
}

static int vidtv_bridge_dmxdev_init(struct vidtv_dvb *dvb)
{
	dvb->dmx_dev.filternum    = 256;
	dvb->dmx_dev.demux        = &dvb->demux.dmx;
	dvb->dmx_dev.capabilities = 0;

	return dvb_dmxdev_init(&dvb->dmx_dev, &dvb->adapter);
}

static int vidtv_bridge_probe_demod(struct vidtv_dvb *dvb, u32 n)
{
	struct vidtv_demod_config cfg = {};

	cfg.drop_tslock_prob_on_low_snr     = drop_tslock_prob_on_low_snr;
	cfg.recover_tslock_prob_on_good_snr = recover_tslock_prob_on_good_snr;

	dvb->i2c_client_demod[n] = dvb_module_probe("dvb_vidtv_demod",
						    NULL,
						    &dvb->i2c_adapter,
						    DEMOD_DEFAULT_ADDR,
						    &cfg);

	/* driver will not work anyways so bail out */
	if (!dvb->i2c_client_demod[n])
		return -ENODEV;

	/* retrieve a ptr to the frontend state */
	dvb->fe[n] = vidtv_get_frontend_ptr(dvb->i2c_client_demod[n]);

	return 0;
}

static int vidtv_bridge_probe_tuner(struct vidtv_dvb *dvb, u32 n)
{
	struct vidtv_tuner_config cfg = {};
	u32 freq;
	int i;

	cfg.fe                       = dvb->fe[n];
	cfg.mock_power_up_delay_msec = mock_power_up_delay_msec;
	cfg.mock_tune_delay_msec     = mock_tune_delay_msec;

	/* TODO: check if the frequencies are at a valid range */

	memcpy(cfg.vidtv_valid_dvb_t_freqs,
	       vidtv_valid_dvb_t_freqs,
	       sizeof(vidtv_valid_dvb_t_freqs));

	memcpy(cfg.vidtv_valid_dvb_c_freqs,
	       vidtv_valid_dvb_c_freqs,
	       sizeof(vidtv_valid_dvb_c_freqs));

	/*
	 * Convert Satellite frequencies from Ku-band in kHZ into S-band
	 * frequencies in Hz.
	 */
	for (i = 0; i < ARRAY_SIZE(vidtv_valid_dvb_s_freqs); i++) {
		freq = vidtv_valid_dvb_s_freqs[i];
		if (freq) {
			if (freq < LNB_CUT_FREQUENCY)
				freq = abs(freq - LNB_LOW_FREQ);
			else
				freq = abs(freq - LNB_HIGH_FREQ);
		}
		cfg.vidtv_valid_dvb_s_freqs[i] = freq;
	}

	cfg.max_frequency_shift_hz = max_frequency_shift_hz;

	dvb->i2c_client_tuner[n] = dvb_module_probe("dvb_vidtv_tuner",
						    NULL,
						    &dvb->i2c_adapter,
						    TUNER_DEFAULT_ADDR,
						    &cfg);

	return (dvb->i2c_client_tuner[n]) ? 0 : -ENODEV;
}

static int vidtv_bridge_dvb_init(struct vidtv_dvb *dvb)
{
	int ret;
	int i;
	int j;

	ret = vidtv_bridge_i2c_register_adap(dvb);
	if (ret < 0)
		goto fail_i2c;

	ret = vidtv_bridge_register_adap(dvb);
	if (ret < 0)
		goto fail_adapter;

	for (i = 0; i < NUM_FE; ++i) {
		ret = vidtv_bridge_probe_demod(dvb, i);
		if (ret < 0)
			goto fail_demod_probe;

		ret = vidtv_bridge_probe_tuner(dvb, i);
		if (ret < 0)
			goto fail_tuner_probe;

		ret = dvb_register_frontend(&dvb->adapter, dvb->fe[i]);
		if (ret < 0)
			goto fail_fe;
	}

	ret = vidtv_bridge_dmx_init(dvb);
	if (ret < 0)
		goto fail_dmx;

	ret = vidtv_bridge_dmxdev_init(dvb);
	if (ret < 0)
		goto fail_dmx_dev;

	for (j = 0; j < NUM_FE; ++j) {
		ret = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx,
						      &dvb->dmx_fe[j]);
		if (ret < 0)
			goto fail_dmx_conn;

		/*
		 * The source of the demux is a frontend connected
		 * to the demux.
		 */
		dvb->dmx_fe[j].source = DMX_FRONTEND_0;
	}

	return ret;

fail_dmx_conn:
	for (j = j - 1; j >= 0; --j)
		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx,
					       &dvb->dmx_fe[j]);
fail_dmx_dev:
	dvb_dmxdev_release(&dvb->dmx_dev);
fail_dmx:
	dvb_dmx_release(&dvb->demux);
fail_fe:
	for (j = i; j >= 0; --j)
		dvb_unregister_frontend(dvb->fe[j]);
fail_tuner_probe:
	for (j = i; j >= 0; --j)
		if (dvb->i2c_client_tuner[j])
			dvb_module_release(dvb->i2c_client_tuner[j]);

fail_demod_probe:
	for (j = i; j >= 0; --j)
		if (dvb->i2c_client_demod[j])
			dvb_module_release(dvb->i2c_client_demod[j]);

fail_adapter:
	dvb_unregister_adapter(&dvb->adapter);

fail_i2c:
	i2c_del_adapter(&dvb->i2c_adapter);

	return ret;
}

static int vidtv_bridge_probe(struct platform_device *pdev)
{
	struct vidtv_dvb *dvb;
	int ret;

	dvb = kzalloc(sizeof(*dvb), GFP_KERNEL);
	if (!dvb)
		return -ENOMEM;

	dvb->pdev = pdev;

	ret = vidtv_bridge_dvb_init(dvb);
	if (ret < 0)
		goto err_dvb;

	mutex_init(&dvb->feed_lock);

	platform_set_drvdata(pdev, dvb);

	dev_info(&pdev->dev, "Successfully initialized vidtv!\n");
	return ret;

err_dvb:
	kfree(dvb);
	return ret;
}

static int vidtv_bridge_remove(struct platform_device *pdev)
{
	struct vidtv_dvb *dvb;
	u32 i;

	dvb = platform_get_drvdata(pdev);

	mutex_destroy(&dvb->feed_lock);

	for (i = 0; i < NUM_FE; ++i) {
		dvb_unregister_frontend(dvb->fe[i]);
		dvb_module_release(dvb->i2c_client_tuner[i]);
		dvb_module_release(dvb->i2c_client_demod[i]);
	}

	dvb_dmxdev_release(&dvb->dmx_dev);
	dvb_dmx_release(&dvb->demux);
	dvb_unregister_adapter(&dvb->adapter);

	return 0;
}

static void vidtv_bridge_dev_release(struct device *dev)
{
}

static struct platform_device vidtv_bridge_dev = {
	.name		= "vidtv_bridge",
	.dev.release	= vidtv_bridge_dev_release,
};

static struct platform_driver vidtv_bridge_driver = {
	.driver = {
		.name                = "vidtv_bridge",
		.suppress_bind_attrs = true,
	},
	.probe    = vidtv_bridge_probe,
	.remove   = vidtv_bridge_remove,
};

static void __exit vidtv_bridge_exit(void)
{
	platform_driver_unregister(&vidtv_bridge_driver);
	platform_device_unregister(&vidtv_bridge_dev);
}

static int __init vidtv_bridge_init(void)
{
	int ret;

	ret = platform_device_register(&vidtv_bridge_dev);
	if (ret)
		return ret;

	ret = platform_driver_register(&vidtv_bridge_driver);
	if (ret)
		platform_device_unregister(&vidtv_bridge_dev);

	return ret;
}

module_init(vidtv_bridge_init);
module_exit(vidtv_bridge_exit);

MODULE_DESCRIPTION("Virtual Digital TV Test Driver");
MODULE_AUTHOR("Daniel W. S. Almeida");
MODULE_LICENSE("GPL");
MODULE_ALIAS("vidtv");
MODULE_ALIAS("dvb_vidtv");
