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

c8sectpfe-dvb.c (6288B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
      4 *
      5 * Copyright (c) STMicroelectronics 2015
      6 *
      7 *  Author Peter Griffin <peter.griffin@linaro.org>
      8 *
      9 */
     10#include <linux/completion.h>
     11#include <linux/delay.h>
     12#include <linux/i2c.h>
     13#include <linux/interrupt.h>
     14
     15#include <dt-bindings/media/c8sectpfe.h>
     16
     17#include "c8sectpfe-common.h"
     18#include "c8sectpfe-core.h"
     19#include "c8sectpfe-dvb.h"
     20
     21#include "dvb-pll.h"
     22#include "lnbh24.h"
     23#include "stv0367.h"
     24#include "stv0367_priv.h"
     25#include "stv6110x.h"
     26#include "stv090x.h"
     27#include "tda18212.h"
     28
     29static inline const char *dvb_card_str(unsigned int c)
     30{
     31	switch (c) {
     32	case STV0367_TDA18212_NIMA_1:	return "STV0367_TDA18212_NIMA_1";
     33	case STV0367_TDA18212_NIMA_2:	return "STV0367_TDA18212_NIMA_2";
     34	case STV0367_TDA18212_NIMB_1:	return "STV0367_TDA18212_NIMB_1";
     35	case STV0367_TDA18212_NIMB_2:	return "STV0367_TDA18212_NIMB_2";
     36	case STV0903_6110_LNB24_NIMA:	return "STV0903_6110_LNB24_NIMA";
     37	case STV0903_6110_LNB24_NIMB:	return "STV0903_6110_LNB24_NIMB";
     38	default:			return "unknown dvb frontend card";
     39	}
     40}
     41
     42static struct stv090x_config stv090x_config = {
     43	.device                 = STV0903,
     44	.demod_mode             = STV090x_SINGLE,
     45	.clk_mode               = STV090x_CLK_EXT,
     46	.xtal                   = 16000000,
     47	.address                = 0x69,
     48
     49	.ts1_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
     50	.ts2_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
     51
     52	.repeater_level         = STV090x_RPTLEVEL_64,
     53
     54	.tuner_init             = NULL,
     55	.tuner_set_mode         = NULL,
     56	.tuner_set_frequency    = NULL,
     57	.tuner_get_frequency    = NULL,
     58	.tuner_set_bandwidth    = NULL,
     59	.tuner_get_bandwidth    = NULL,
     60	.tuner_set_bbgain       = NULL,
     61	.tuner_get_bbgain       = NULL,
     62	.tuner_set_refclk       = NULL,
     63	.tuner_get_status       = NULL,
     64};
     65
     66static struct stv6110x_config stv6110x_config = {
     67	.addr                   = 0x60,
     68	.refclk                 = 16000000,
     69};
     70
     71#define NIMA 0
     72#define NIMB 1
     73
     74static struct stv0367_config stv0367_tda18212_config[] = {
     75	{
     76		.demod_address = 0x1c,
     77		.xtal = 16000000,
     78		.if_khz = 4500,
     79		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
     80		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
     81		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
     82	}, {
     83		.demod_address = 0x1d,
     84		.xtal = 16000000,
     85		.if_khz = 4500,
     86		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
     87		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
     88		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
     89	}, {
     90		.demod_address = 0x1e,
     91		.xtal = 16000000,
     92		.if_khz = 4500,
     93		.if_iq_mode = FE_TER_NORMAL_IF_TUNER,
     94		.ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
     95		.clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
     96	},
     97};
     98
     99static struct tda18212_config tda18212_conf = {
    100	.if_dvbt_6 = 4150,
    101	.if_dvbt_7 = 4150,
    102	.if_dvbt_8 = 4500,
    103	.if_dvbc = 5000,
    104};
    105
    106int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
    107		struct c8sectpfe *c8sectpfe,
    108		struct channel_info *tsin, int chan_num)
    109{
    110	struct tda18212_config *tda18212;
    111	const struct stv6110x_devctl *fe2;
    112	struct i2c_client *client;
    113	struct i2c_board_info tda18212_info = {
    114		.type = "tda18212",
    115		.addr = 0x60,
    116	};
    117
    118	if (!tsin)
    119		return -EINVAL;
    120
    121	switch (tsin->dvb_card) {
    122
    123	case STV0367_TDA18212_NIMA_1:
    124	case STV0367_TDA18212_NIMA_2:
    125	case STV0367_TDA18212_NIMB_1:
    126	case STV0367_TDA18212_NIMB_2:
    127		if (tsin->dvb_card == STV0367_TDA18212_NIMA_1)
    128			*fe = dvb_attach(stv0367ter_attach,
    129				 &stv0367_tda18212_config[0],
    130					tsin->i2c_adapter);
    131		else if (tsin->dvb_card == STV0367_TDA18212_NIMB_1)
    132			*fe = dvb_attach(stv0367ter_attach,
    133				 &stv0367_tda18212_config[1],
    134					tsin->i2c_adapter);
    135		else
    136			*fe = dvb_attach(stv0367ter_attach,
    137				 &stv0367_tda18212_config[2],
    138					tsin->i2c_adapter);
    139
    140		if (!*fe) {
    141			dev_err(c8sectpfe->device,
    142				"%s: stv0367ter_attach failed for NIM card %s\n"
    143				, __func__, dvb_card_str(tsin->dvb_card));
    144			return -ENODEV;
    145		}
    146
    147		/*
    148		 * init the demod so that i2c gate_ctrl
    149		 * to the tuner works correctly
    150		 */
    151		(*fe)->ops.init(*fe);
    152
    153		/* Allocate the tda18212 structure */
    154		tda18212 = devm_kzalloc(c8sectpfe->device,
    155					sizeof(struct tda18212_config),
    156					GFP_KERNEL);
    157		if (!tda18212) {
    158			dev_err(c8sectpfe->device,
    159				"%s: devm_kzalloc failed\n", __func__);
    160			return -ENOMEM;
    161		}
    162
    163		memcpy(tda18212, &tda18212_conf,
    164			sizeof(struct tda18212_config));
    165
    166		tda18212->fe = (*fe);
    167
    168		tda18212_info.platform_data = tda18212;
    169
    170		/* attach tuner */
    171		request_module("tda18212");
    172		client = i2c_new_client_device(tsin->i2c_adapter,
    173					       &tda18212_info);
    174		if (!i2c_client_has_driver(client)) {
    175			dvb_frontend_detach(*fe);
    176			return -ENODEV;
    177		}
    178
    179		if (!try_module_get(client->dev.driver->owner)) {
    180			i2c_unregister_device(client);
    181			dvb_frontend_detach(*fe);
    182			return -ENODEV;
    183		}
    184
    185		tsin->i2c_client = client;
    186
    187		break;
    188
    189	case STV0903_6110_LNB24_NIMA:
    190		*fe = dvb_attach(stv090x_attach,	&stv090x_config,
    191				tsin->i2c_adapter, STV090x_DEMODULATOR_0);
    192		if (!*fe) {
    193			dev_err(c8sectpfe->device, "%s: stv090x_attach failed\n"
    194				"\tfor NIM card %s\n",
    195				__func__, dvb_card_str(tsin->dvb_card));
    196			return -ENODEV;
    197		}
    198
    199		fe2 = dvb_attach(stv6110x_attach, *fe,
    200					&stv6110x_config, tsin->i2c_adapter);
    201		if (!fe2) {
    202			dev_err(c8sectpfe->device,
    203				"%s: stv6110x_attach failed for NIM card %s\n"
    204				, __func__, dvb_card_str(tsin->dvb_card));
    205			return -ENODEV;
    206		}
    207
    208		stv090x_config.tuner_init = fe2->tuner_init;
    209		stv090x_config.tuner_set_mode = fe2->tuner_set_mode;
    210		stv090x_config.tuner_set_frequency = fe2->tuner_set_frequency;
    211		stv090x_config.tuner_get_frequency = fe2->tuner_get_frequency;
    212		stv090x_config.tuner_set_bandwidth = fe2->tuner_set_bandwidth;
    213		stv090x_config.tuner_get_bandwidth = fe2->tuner_get_bandwidth;
    214		stv090x_config.tuner_set_bbgain = fe2->tuner_set_bbgain;
    215		stv090x_config.tuner_get_bbgain = fe2->tuner_get_bbgain;
    216		stv090x_config.tuner_set_refclk = fe2->tuner_set_refclk;
    217		stv090x_config.tuner_get_status = fe2->tuner_get_status;
    218
    219		dvb_attach(lnbh24_attach, *fe, tsin->i2c_adapter, 0, 0, 0x9);
    220		break;
    221
    222	default:
    223		dev_err(c8sectpfe->device,
    224			"%s: DVB frontend card %s not yet supported\n",
    225			__func__, dvb_card_str(tsin->dvb_card));
    226		return -ENODEV;
    227	}
    228
    229	(*fe)->id = chan_num;
    230
    231	dev_info(c8sectpfe->device,
    232			"DVB frontend card %s successfully attached",
    233			dvb_card_str(tsin->dvb_card));
    234	return 0;
    235}