cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mantis_dvb.c (7122B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3	Mantis PCI bridge driver
      4	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
      5
      6*/
      7
      8#include <linux/kernel.h>
      9#include <linux/bitops.h>
     10
     11#include <linux/signal.h>
     12#include <linux/sched.h>
     13#include <linux/interrupt.h>
     14#include <linux/pci.h>
     15#include <linux/i2c.h>
     16
     17#include <media/dmxdev.h>
     18#include <media/dvbdev.h>
     19#include <media/dvb_demux.h>
     20#include <media/dvb_frontend.h>
     21#include <media/dvb_net.h>
     22
     23#include "mantis_common.h"
     24#include "mantis_dma.h"
     25#include "mantis_ca.h"
     26#include "mantis_ioc.h"
     27#include "mantis_dvb.h"
     28
     29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
     30
     31int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
     32{
     33	struct mantis_hwconfig *config = mantis->hwconfig;
     34
     35	switch (power) {
     36	case POWER_ON:
     37		dprintk(MANTIS_DEBUG, 1, "Power ON");
     38		mantis_gpio_set_bits(mantis, config->power, POWER_ON);
     39		msleep(100);
     40		mantis_gpio_set_bits(mantis, config->power, POWER_ON);
     41		msleep(100);
     42		break;
     43
     44	case POWER_OFF:
     45		dprintk(MANTIS_DEBUG, 1, "Power OFF");
     46		mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
     47		msleep(100);
     48		break;
     49
     50	default:
     51		dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
     52		return -1;
     53	}
     54
     55	return 0;
     56}
     57EXPORT_SYMBOL_GPL(mantis_frontend_power);
     58
     59void mantis_frontend_soft_reset(struct mantis_pci *mantis)
     60{
     61	struct mantis_hwconfig *config = mantis->hwconfig;
     62
     63	dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
     64	mantis_gpio_set_bits(mantis, config->reset, 0);
     65	msleep(100);
     66	mantis_gpio_set_bits(mantis, config->reset, 0);
     67	msleep(100);
     68	mantis_gpio_set_bits(mantis, config->reset, 1);
     69	msleep(100);
     70	mantis_gpio_set_bits(mantis, config->reset, 1);
     71	msleep(100);
     72
     73	return;
     74}
     75EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
     76
     77static int mantis_frontend_shutdown(struct mantis_pci *mantis)
     78{
     79	int err;
     80
     81	mantis_frontend_soft_reset(mantis);
     82	err = mantis_frontend_power(mantis, POWER_OFF);
     83	if (err != 0) {
     84		dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
     85		return 1;
     86	}
     87
     88	return 0;
     89}
     90
     91static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
     92{
     93	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
     94	struct mantis_pci *mantis = dvbdmx->priv;
     95
     96	dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
     97	if (!dvbdmx->dmx.frontend) {
     98		dprintk(MANTIS_DEBUG, 1, "no frontend ?");
     99		return -EINVAL;
    100	}
    101
    102	mantis->feeds++;
    103	dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d",	mantis->feeds);
    104
    105	if (mantis->feeds == 1)	 {
    106		dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
    107		mantis_dma_start(mantis);
    108		tasklet_enable(&mantis->tasklet);
    109	}
    110
    111	return mantis->feeds;
    112}
    113
    114static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
    115{
    116	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
    117	struct mantis_pci *mantis = dvbdmx->priv;
    118
    119	dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
    120	if (!dvbdmx->dmx.frontend) {
    121		dprintk(MANTIS_DEBUG, 1, "no frontend ?");
    122		return -EINVAL;
    123	}
    124
    125	mantis->feeds--;
    126	if (mantis->feeds == 0) {
    127		dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
    128		tasklet_disable(&mantis->tasklet);
    129		mantis_dma_stop(mantis);
    130	}
    131
    132	return 0;
    133}
    134
    135int mantis_dvb_init(struct mantis_pci *mantis)
    136{
    137	struct mantis_hwconfig *config = mantis->hwconfig;
    138	int result;
    139
    140	dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
    141
    142	result = dvb_register_adapter(&mantis->dvb_adapter,
    143				      "Mantis DVB adapter",
    144				      THIS_MODULE,
    145				      &mantis->pdev->dev,
    146				      adapter_nr);
    147
    148	if (result < 0) {
    149
    150		dprintk(MANTIS_ERROR, 1, "Error registering adapter");
    151		return -ENODEV;
    152	}
    153
    154	mantis->dvb_adapter.priv	= mantis;
    155	mantis->demux.dmx.capabilities	= DMX_TS_FILTERING	|
    156					 DMX_SECTION_FILTERING	|
    157					 DMX_MEMORY_BASED_FILTERING;
    158
    159	mantis->demux.priv		= mantis;
    160	mantis->demux.filternum		= 256;
    161	mantis->demux.feednum		= 256;
    162	mantis->demux.start_feed	= mantis_dvb_start_feed;
    163	mantis->demux.stop_feed		= mantis_dvb_stop_feed;
    164	mantis->demux.write_to_decoder	= NULL;
    165
    166	dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
    167	result = dvb_dmx_init(&mantis->demux);
    168	if (result < 0) {
    169		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
    170
    171		goto err0;
    172	}
    173
    174	mantis->dmxdev.filternum	= 256;
    175	mantis->dmxdev.demux		= &mantis->demux.dmx;
    176	mantis->dmxdev.capabilities	= 0;
    177	dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
    178
    179	result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
    180	if (result < 0) {
    181
    182		dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
    183		goto err1;
    184	}
    185
    186	mantis->fe_hw.source		= DMX_FRONTEND_0;
    187	result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
    188	if (result < 0) {
    189
    190		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
    191		goto err2;
    192	}
    193
    194	mantis->fe_mem.source		= DMX_MEMORY_FE;
    195	result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
    196	if (result < 0) {
    197		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
    198		goto err3;
    199	}
    200
    201	result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
    202	if (result < 0) {
    203		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
    204		goto err4;
    205	}
    206
    207	dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
    208	tasklet_setup(&mantis->tasklet, mantis_dma_xfer);
    209	tasklet_disable(&mantis->tasklet);
    210	if (mantis->hwconfig) {
    211		result = config->frontend_init(mantis, mantis->fe);
    212		if (result < 0) {
    213			dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
    214			goto err5;
    215		} else {
    216			if (mantis->fe == NULL) {
    217				result = -ENOMEM;
    218				dprintk(MANTIS_ERROR, 1, "FE <NULL>");
    219				goto err5;
    220			}
    221			result = dvb_register_frontend(&mantis->dvb_adapter, mantis->fe);
    222			if (result) {
    223				dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
    224
    225				if (mantis->fe->ops.release)
    226					mantis->fe->ops.release(mantis->fe);
    227
    228				mantis->fe = NULL;
    229				goto err5;
    230			}
    231		}
    232	}
    233
    234	return 0;
    235
    236	/* Error conditions ..	*/
    237err5:
    238	tasklet_kill(&mantis->tasklet);
    239	dvb_net_release(&mantis->dvbnet);
    240	if (mantis->fe) {
    241		dvb_unregister_frontend(mantis->fe);
    242		dvb_frontend_detach(mantis->fe);
    243	}
    244err4:
    245	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
    246
    247err3:
    248	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
    249
    250err2:
    251	dvb_dmxdev_release(&mantis->dmxdev);
    252
    253err1:
    254	dvb_dmx_release(&mantis->demux);
    255
    256err0:
    257	dvb_unregister_adapter(&mantis->dvb_adapter);
    258
    259	return result;
    260}
    261EXPORT_SYMBOL_GPL(mantis_dvb_init);
    262
    263int mantis_dvb_exit(struct mantis_pci *mantis)
    264{
    265	int err;
    266
    267	if (mantis->fe) {
    268		/* mantis_ca_exit(mantis); */
    269		err = mantis_frontend_shutdown(mantis);
    270		if (err != 0)
    271			dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
    272		dvb_unregister_frontend(mantis->fe);
    273		dvb_frontend_detach(mantis->fe);
    274	}
    275
    276	tasklet_kill(&mantis->tasklet);
    277	dvb_net_release(&mantis->dvbnet);
    278
    279	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
    280	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
    281
    282	dvb_dmxdev_release(&mantis->dmxdev);
    283	dvb_dmx_release(&mantis->demux);
    284
    285	dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
    286	dvb_unregister_adapter(&mantis->dvb_adapter);
    287
    288	return 0;
    289}
    290EXPORT_SYMBOL_GPL(mantis_dvb_exit);