// SPDX-License-Identifier: GPL-2.0
/*
 * c8sectpfe-common.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/device.h>
#include <linux/dvb/dmx.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>

#include <media/dmxdev.h>
#include <media/dvbdev.h>
#include <media/dvb_demux.h>
#include <media/dvb_frontend.h>
#include <media/dvb_net.h>

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

static int register_dvb(struct stdemux *demux, struct dvb_adapter *adap,
				void *start_feed, void *stop_feed,
				struct c8sectpfei *fei)
{
	int result;

	demux->dvb_demux.dmx.capabilities = DMX_TS_FILTERING |
					DMX_SECTION_FILTERING |
					DMX_MEMORY_BASED_FILTERING;

	demux->dvb_demux.priv = demux;
	demux->dvb_demux.filternum = C8SECTPFE_MAXCHANNEL;
	demux->dvb_demux.feednum = C8SECTPFE_MAXCHANNEL;

	demux->dvb_demux.start_feed = start_feed;
	demux->dvb_demux.stop_feed = stop_feed;
	demux->dvb_demux.write_to_decoder = NULL;

	result = dvb_dmx_init(&demux->dvb_demux);
	if (result < 0) {
		dev_err(fei->dev, "dvb_dmx_init failed (errno = %d)\n",
			result);
		goto err_dmx;
	}

	demux->dmxdev.filternum = demux->dvb_demux.filternum;
	demux->dmxdev.demux = &demux->dvb_demux.dmx;
	demux->dmxdev.capabilities = 0;

	result = dvb_dmxdev_init(&demux->dmxdev, adap);
	if (result < 0) {
		dev_err(fei->dev, "dvb_dmxdev_init failed (errno = %d)\n",
			result);

		goto err_dmxdev;
	}

	demux->hw_frontend.source = DMX_FRONTEND_0 + demux->tsin_index;

	result = demux->dvb_demux.dmx.add_frontend(&demux->dvb_demux.dmx,
						&demux->hw_frontend);
	if (result < 0) {
		dev_err(fei->dev, "add_frontend failed (errno = %d)\n", result);
		goto err_fe_hw;
	}

	demux->mem_frontend.source = DMX_MEMORY_FE;
	result = demux->dvb_demux.dmx.add_frontend(&demux->dvb_demux.dmx,
						&demux->mem_frontend);
	if (result < 0) {
		dev_err(fei->dev, "add_frontend failed (%d)\n", result);
		goto err_fe_mem;
	}

	result = demux->dvb_demux.dmx.connect_frontend(&demux->dvb_demux.dmx,
							&demux->hw_frontend);
	if (result < 0) {
		dev_err(fei->dev, "connect_frontend (%d)\n", result);
		goto err_fe_con;
	}

	return 0;

err_fe_con:
	demux->dvb_demux.dmx.remove_frontend(&demux->dvb_demux.dmx,
						     &demux->mem_frontend);
err_fe_mem:
	demux->dvb_demux.dmx.remove_frontend(&demux->dvb_demux.dmx,
						     &demux->hw_frontend);
err_fe_hw:
	dvb_dmxdev_release(&demux->dmxdev);
err_dmxdev:
	dvb_dmx_release(&demux->dvb_demux);
err_dmx:
	return result;

}

static void unregister_dvb(struct stdemux *demux)
{

	demux->dvb_demux.dmx.remove_frontend(&demux->dvb_demux.dmx,
						     &demux->mem_frontend);

	demux->dvb_demux.dmx.remove_frontend(&demux->dvb_demux.dmx,
						     &demux->hw_frontend);

	dvb_dmxdev_release(&demux->dmxdev);

	dvb_dmx_release(&demux->dvb_demux);
}

static struct c8sectpfe *c8sectpfe_create(struct c8sectpfei *fei,
				void *start_feed,
				void *stop_feed)
{
	struct c8sectpfe *c8sectpfe;
	int result;
	int i, j;

	short int ids[] = { -1 };

	c8sectpfe = kzalloc(sizeof(struct c8sectpfe), GFP_KERNEL);
	if (!c8sectpfe)
		goto err1;

	mutex_init(&c8sectpfe->lock);

	c8sectpfe->device = fei->dev;

	result = dvb_register_adapter(&c8sectpfe->adapter, "STi c8sectpfe",
					THIS_MODULE, fei->dev, ids);
	if (result < 0) {
		dev_err(fei->dev, "dvb_register_adapter failed (errno = %d)\n",
			result);
		goto err2;
	}

	c8sectpfe->adapter.priv = fei;

	for (i = 0; i < fei->tsin_count; i++) {

		c8sectpfe->demux[i].tsin_index = i;
		c8sectpfe->demux[i].c8sectpfei = fei;

		result = register_dvb(&c8sectpfe->demux[i], &c8sectpfe->adapter,
				start_feed, stop_feed, fei);
		if (result < 0) {
			dev_err(fei->dev,
				"register_dvb feed=%d failed (errno = %d)\n",
				result, i);

			/* we take a all or nothing approach */
			for (j = 0; j < i; j++)
				unregister_dvb(&c8sectpfe->demux[j]);
			goto err3;
		}
	}

	c8sectpfe->num_feeds = fei->tsin_count;

	return c8sectpfe;
err3:
	dvb_unregister_adapter(&c8sectpfe->adapter);
err2:
	kfree(c8sectpfe);
err1:
	return NULL;
};

static void c8sectpfe_delete(struct c8sectpfe *c8sectpfe)
{
	int i;

	if (!c8sectpfe)
		return;

	for (i = 0; i < c8sectpfe->num_feeds; i++)
		unregister_dvb(&c8sectpfe->demux[i]);

	dvb_unregister_adapter(&c8sectpfe->adapter);

	kfree(c8sectpfe);
};

void c8sectpfe_tuner_unregister_frontend(struct c8sectpfe *c8sectpfe,
					struct c8sectpfei *fei)
{
	int n;
	struct channel_info *tsin;

	for (n = 0; n < fei->tsin_count; n++) {

		tsin = fei->channel_data[n];

		if (tsin) {
			if (tsin->frontend) {
				dvb_unregister_frontend(tsin->frontend);
				dvb_frontend_detach(tsin->frontend);
			}

			i2c_put_adapter(tsin->i2c_adapter);

			if (tsin->i2c_client) {
				module_put(tsin->i2c_client->dev.driver->owner);
				i2c_unregister_device(tsin->i2c_client);
			}
		}
	}

	c8sectpfe_delete(c8sectpfe);
};

int c8sectpfe_tuner_register_frontend(struct c8sectpfe **c8sectpfe,
				struct c8sectpfei *fei,
				void *start_feed,
				void *stop_feed)
{
	struct channel_info *tsin;
	struct dvb_frontend *frontend;
	int n, res;

	*c8sectpfe = c8sectpfe_create(fei, start_feed, stop_feed);
	if (!*c8sectpfe)
		return -ENOMEM;

	for (n = 0; n < fei->tsin_count; n++) {
		tsin = fei->channel_data[n];

		res = c8sectpfe_frontend_attach(&frontend, *c8sectpfe, tsin, n);
		if (res)
			goto err;

		res = dvb_register_frontend(&c8sectpfe[0]->adapter, frontend);
		if (res < 0) {
			dev_err(fei->dev, "dvb_register_frontend failed (%d)\n",
				res);
			goto err;
		}

		tsin->frontend = frontend;
	}

	return 0;

err:
	c8sectpfe_tuner_unregister_frontend(*c8sectpfe, fei);
	return res;
}
