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

stb6000.c (4761B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2  /*
      3     Driver for ST STB6000 DVBS Silicon tuner
      4
      5     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
      6
      7
      8  */
      9
     10#include <linux/slab.h>
     11#include <linux/module.h>
     12#include <linux/dvb/frontend.h>
     13#include <asm/types.h>
     14
     15#include "stb6000.h"
     16
     17static int debug;
     18#define dprintk(args...) \
     19	do { \
     20		if (debug) \
     21			printk(KERN_DEBUG "stb6000: " args); \
     22	} while (0)
     23
     24struct stb6000_priv {
     25	/* i2c details */
     26	int i2c_address;
     27	struct i2c_adapter *i2c;
     28	u32 frequency;
     29};
     30
     31static void stb6000_release(struct dvb_frontend *fe)
     32{
     33	kfree(fe->tuner_priv);
     34	fe->tuner_priv = NULL;
     35}
     36
     37static int stb6000_sleep(struct dvb_frontend *fe)
     38{
     39	struct stb6000_priv *priv = fe->tuner_priv;
     40	int ret;
     41	u8 buf[] = { 10, 0 };
     42	struct i2c_msg msg = {
     43		.addr = priv->i2c_address,
     44		.flags = 0,
     45		.buf = buf,
     46		.len = 2
     47	};
     48
     49	dprintk("%s:\n", __func__);
     50
     51	if (fe->ops.i2c_gate_ctrl)
     52		fe->ops.i2c_gate_ctrl(fe, 1);
     53
     54	ret = i2c_transfer(priv->i2c, &msg, 1);
     55	if (ret != 1)
     56		dprintk("%s: i2c error\n", __func__);
     57
     58	if (fe->ops.i2c_gate_ctrl)
     59		fe->ops.i2c_gate_ctrl(fe, 0);
     60
     61	return (ret == 1) ? 0 : ret;
     62}
     63
     64static int stb6000_set_params(struct dvb_frontend *fe)
     65{
     66	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
     67	struct stb6000_priv *priv = fe->tuner_priv;
     68	unsigned int n, m;
     69	int ret;
     70	u32 freq_mhz;
     71	int bandwidth;
     72	u8 buf[12];
     73	struct i2c_msg msg = {
     74		.addr = priv->i2c_address,
     75		.flags = 0,
     76		.buf = buf,
     77		.len = 12
     78	};
     79
     80	dprintk("%s:\n", __func__);
     81
     82	freq_mhz = p->frequency / 1000;
     83	bandwidth = p->symbol_rate / 1000000;
     84
     85	if (bandwidth > 31)
     86		bandwidth = 31;
     87
     88	if ((freq_mhz > 949) && (freq_mhz < 2151)) {
     89		buf[0] = 0x01;
     90		buf[1] = 0xac;
     91		if (freq_mhz < 1950)
     92			buf[1] = 0xaa;
     93		if (freq_mhz < 1800)
     94			buf[1] = 0xa8;
     95		if (freq_mhz < 1650)
     96			buf[1] = 0xa6;
     97		if (freq_mhz < 1530)
     98			buf[1] = 0xa5;
     99		if (freq_mhz < 1470)
    100			buf[1] = 0xa4;
    101		if (freq_mhz < 1370)
    102			buf[1] = 0xa2;
    103		if (freq_mhz < 1300)
    104			buf[1] = 0xa1;
    105		if (freq_mhz < 1200)
    106			buf[1] = 0xa0;
    107		if (freq_mhz < 1075)
    108			buf[1] = 0xbc;
    109		if (freq_mhz < 1000)
    110			buf[1] = 0xba;
    111		if (freq_mhz < 1075) {
    112			n = freq_mhz / 8; /* vco=lo*4 */
    113			m = 2;
    114		} else {
    115			n = freq_mhz / 16; /* vco=lo*2 */
    116			m = 1;
    117		}
    118		buf[2] = n >> 1;
    119		buf[3] = (unsigned char)(((n & 1) << 7) |
    120					(m * freq_mhz - n * 16) | 0x60);
    121		buf[4] = 0x04;
    122		buf[5] = 0x0e;
    123
    124		buf[6] = (unsigned char)(bandwidth);
    125
    126		buf[7] = 0xd8;
    127		buf[8] = 0xd0;
    128		buf[9] = 0x50;
    129		buf[10] = 0xeb;
    130		buf[11] = 0x4f;
    131
    132		if (fe->ops.i2c_gate_ctrl)
    133			fe->ops.i2c_gate_ctrl(fe, 1);
    134
    135		ret = i2c_transfer(priv->i2c, &msg, 1);
    136		if (ret != 1)
    137			dprintk("%s: i2c error\n", __func__);
    138
    139		udelay(10);
    140		if (fe->ops.i2c_gate_ctrl)
    141			fe->ops.i2c_gate_ctrl(fe, 0);
    142
    143		buf[0] = 0x07;
    144		buf[1] = 0xdf;
    145		buf[2] = 0xd0;
    146		buf[3] = 0x50;
    147		buf[4] = 0xfb;
    148		msg.len = 5;
    149
    150		if (fe->ops.i2c_gate_ctrl)
    151			fe->ops.i2c_gate_ctrl(fe, 1);
    152
    153		ret = i2c_transfer(priv->i2c, &msg, 1);
    154		if (ret != 1)
    155			dprintk("%s: i2c error\n", __func__);
    156
    157		udelay(10);
    158		if (fe->ops.i2c_gate_ctrl)
    159			fe->ops.i2c_gate_ctrl(fe, 0);
    160
    161		priv->frequency = freq_mhz * 1000;
    162
    163		return (ret == 1) ? 0 : ret;
    164	}
    165	return -1;
    166}
    167
    168static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
    169{
    170	struct stb6000_priv *priv = fe->tuner_priv;
    171	*frequency = priv->frequency;
    172	return 0;
    173}
    174
    175static const struct dvb_tuner_ops stb6000_tuner_ops = {
    176	.info = {
    177		.name = "ST STB6000",
    178		.frequency_min_hz =  950 * MHz,
    179		.frequency_max_hz = 2150 * MHz
    180	},
    181	.release = stb6000_release,
    182	.sleep = stb6000_sleep,
    183	.set_params = stb6000_set_params,
    184	.get_frequency = stb6000_get_frequency,
    185};
    186
    187struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
    188						struct i2c_adapter *i2c)
    189{
    190	struct stb6000_priv *priv = NULL;
    191	u8 b0[] = { 0 };
    192	u8 b1[] = { 0, 0 };
    193	struct i2c_msg msg[2] = {
    194		{
    195			.addr = addr,
    196			.flags = 0,
    197			.buf = b0,
    198			.len = 0
    199		}, {
    200			.addr = addr,
    201			.flags = I2C_M_RD,
    202			.buf = b1,
    203			.len = 2
    204		}
    205	};
    206	int ret;
    207
    208	dprintk("%s:\n", __func__);
    209
    210	if (fe->ops.i2c_gate_ctrl)
    211		fe->ops.i2c_gate_ctrl(fe, 1);
    212
    213	/* is some i2c device here ? */
    214	ret = i2c_transfer(i2c, msg, 2);
    215	if (fe->ops.i2c_gate_ctrl)
    216		fe->ops.i2c_gate_ctrl(fe, 0);
    217
    218	if (ret != 2)
    219		return NULL;
    220
    221	priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
    222	if (priv == NULL)
    223		return NULL;
    224
    225	priv->i2c_address = addr;
    226	priv->i2c = i2c;
    227
    228	memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
    229				sizeof(struct dvb_tuner_ops));
    230
    231	fe->tuner_priv = priv;
    232
    233	return fe;
    234}
    235EXPORT_SYMBOL(stb6000_attach);
    236
    237module_param(debug, int, 0644);
    238MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
    239
    240MODULE_DESCRIPTION("DVB STB6000 driver");
    241MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
    242MODULE_LICENSE("GPL");