brintos

brintos / linux-shallow public Read only

0
0
Text · 6.1 KiB · feb48cb Raw
236 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  c8sectpfe-dvb.c - C8SECTPFE STi DVB driver4 *5 * Copyright (c) STMicroelectronics 20156 *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 072#define NIMB 173 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		else136			*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_ctrl149		 * to the tuner works correctly150		 */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}236