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

it913x.c (10132B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * ITE IT913X silicon tuner driver
      4 *
      5 *  Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
      6 *  IT9137 Copyright (C) ITE Tech Inc.
      7 */
      8
      9#include "it913x.h"
     10#include <linux/platform_device.h>
     11#include <linux/regmap.h>
     12
     13struct it913x_dev {
     14	struct platform_device *pdev;
     15	struct regmap *regmap;
     16	struct dvb_frontend *fe;
     17	u8 chip_ver:2;
     18	u8 role:2;
     19	u16 xtal;
     20	u8 fdiv;
     21	u8 clk_mode;
     22	u32 fn_min;
     23	bool active;
     24};
     25
     26static int it913x_init(struct dvb_frontend *fe)
     27{
     28	struct it913x_dev *dev = fe->tuner_priv;
     29	struct platform_device *pdev = dev->pdev;
     30	int ret;
     31	unsigned int utmp;
     32	u8 iqik_m_cal, nv_val, buf[2];
     33	static const u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
     34	unsigned long timeout;
     35
     36	dev_dbg(&pdev->dev, "role %u\n", dev->role);
     37
     38	ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);
     39	if (ret)
     40		goto err;
     41
     42	usleep_range(10000, 100000);
     43
     44	ret = regmap_read(dev->regmap, 0x80ec86, &utmp);
     45	if (ret)
     46		goto err;
     47
     48	switch (utmp) {
     49	case 0:
     50		/* 12.000 MHz */
     51		dev->clk_mode = utmp;
     52		dev->xtal = 2000;
     53		dev->fdiv = 3;
     54		iqik_m_cal = 16;
     55		break;
     56	case 1:
     57		/* 20.480 MHz */
     58		dev->clk_mode = utmp;
     59		dev->xtal = 640;
     60		dev->fdiv = 1;
     61		iqik_m_cal = 6;
     62		break;
     63	default:
     64		dev_err(&pdev->dev, "unknown clock identifier %d\n", utmp);
     65		ret = -EINVAL;
     66		goto err;
     67	}
     68
     69	ret = regmap_read(dev->regmap, 0x80ed03,  &utmp);
     70	if (ret)
     71		goto err;
     72
     73	else if (utmp < ARRAY_SIZE(nv))
     74		nv_val = nv[utmp];
     75	else
     76		nv_val = 2;
     77
     78	#define TIMEOUT 50
     79	timeout = jiffies + msecs_to_jiffies(TIMEOUT);
     80	while (!time_after(jiffies, timeout)) {
     81		ret = regmap_bulk_read(dev->regmap, 0x80ed23, buf, 2);
     82		if (ret)
     83			goto err;
     84
     85		utmp = (buf[1] << 8) | (buf[0] << 0);
     86		if (utmp)
     87			break;
     88	}
     89
     90	dev_dbg(&pdev->dev, "r_fbc_m_bdry took %u ms, val %u\n",
     91			jiffies_to_msecs(jiffies) -
     92			(jiffies_to_msecs(timeout) - TIMEOUT), utmp);
     93
     94	dev->fn_min = dev->xtal * utmp;
     95	dev->fn_min /= (dev->fdiv * nv_val);
     96	dev->fn_min *= 1000;
     97	dev_dbg(&pdev->dev, "fn_min %u\n", dev->fn_min);
     98
     99	/*
    100	 * Chip version BX never sets that flag so we just wait 50ms in that
    101	 * case. It is possible poll BX similarly than AX and then timeout in
    102	 * order to get 50ms delay, but that causes about 120 extra I2C
    103	 * messages. As for now, we just wait and reduce IO.
    104	 */
    105	if (dev->chip_ver == 1) {
    106		#define TIMEOUT 50
    107		timeout = jiffies + msecs_to_jiffies(TIMEOUT);
    108		while (!time_after(jiffies, timeout)) {
    109			ret = regmap_read(dev->regmap, 0x80ec82, &utmp);
    110			if (ret)
    111				goto err;
    112
    113			if (utmp)
    114				break;
    115		}
    116
    117		dev_dbg(&pdev->dev, "p_tsm_init_mode took %u ms, val %u\n",
    118				jiffies_to_msecs(jiffies) -
    119				(jiffies_to_msecs(timeout) - TIMEOUT), utmp);
    120	} else {
    121		msleep(50);
    122	}
    123
    124	ret = regmap_write(dev->regmap, 0x80ed81, iqik_m_cal);
    125	if (ret)
    126		goto err;
    127
    128	ret = regmap_write(dev->regmap, 0x80ec57, 0x00);
    129	if (ret)
    130		goto err;
    131
    132	ret = regmap_write(dev->regmap, 0x80ec58, 0x00);
    133	if (ret)
    134		goto err;
    135
    136	ret = regmap_write(dev->regmap, 0x80ec40, 0x01);
    137	if (ret)
    138		goto err;
    139
    140	dev->active = true;
    141
    142	return 0;
    143err:
    144	dev_dbg(&pdev->dev, "failed %d\n", ret);
    145	return ret;
    146}
    147
    148static int it913x_sleep(struct dvb_frontend *fe)
    149{
    150	struct it913x_dev *dev = fe->tuner_priv;
    151	struct platform_device *pdev = dev->pdev;
    152	int ret, len;
    153
    154	dev_dbg(&pdev->dev, "role %u\n", dev->role);
    155
    156	dev->active = false;
    157
    158	ret  = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1);
    159	if (ret)
    160		goto err;
    161
    162	/*
    163	 * Writing '0x00' to master tuner register '0x80ec08' causes slave tuner
    164	 * communication lost. Due to that, we cannot put master full sleep.
    165	 */
    166	if (dev->role == IT913X_ROLE_DUAL_MASTER)
    167		len = 4;
    168	else
    169		len = 15;
    170
    171	dev_dbg(&pdev->dev, "role %u, len %d\n", dev->role, len);
    172
    173	ret = regmap_bulk_write(dev->regmap, 0x80ec02,
    174			"\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
    175			len);
    176	if (ret)
    177		goto err;
    178
    179	ret = regmap_bulk_write(dev->regmap, 0x80ec12, "\x00\x00\x00\x00", 4);
    180	if (ret)
    181		goto err;
    182
    183	ret = regmap_bulk_write(dev->regmap, 0x80ec17,
    184			"\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9);
    185	if (ret)
    186		goto err;
    187
    188	ret = regmap_bulk_write(dev->regmap, 0x80ec22,
    189			"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10);
    190	if (ret)
    191		goto err;
    192
    193	ret = regmap_bulk_write(dev->regmap, 0x80ec20, "\x00", 1);
    194	if (ret)
    195		goto err;
    196
    197	ret = regmap_bulk_write(dev->regmap, 0x80ec3f, "\x01", 1);
    198	if (ret)
    199		goto err;
    200
    201	return 0;
    202err:
    203	dev_dbg(&pdev->dev, "failed %d\n", ret);
    204	return ret;
    205}
    206
    207static int it913x_set_params(struct dvb_frontend *fe)
    208{
    209	struct it913x_dev *dev = fe->tuner_priv;
    210	struct platform_device *pdev = dev->pdev;
    211	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    212	int ret;
    213	unsigned int utmp;
    214	u32 pre_lo_freq, t_cal_freq;
    215	u16 iqik_m_cal, n_div;
    216	u8 u8tmp, n, l_band, lna_band;
    217
    218	dev_dbg(&pdev->dev, "role=%u, frequency %u, bandwidth_hz %u\n",
    219			dev->role, c->frequency, c->bandwidth_hz);
    220
    221	if (!dev->active) {
    222		ret = -EINVAL;
    223		goto err;
    224	}
    225
    226	if (c->frequency <=         74000000) {
    227		n_div = 48;
    228		n = 0;
    229	} else if (c->frequency <= 111000000) {
    230		n_div = 32;
    231		n = 1;
    232	} else if (c->frequency <= 148000000) {
    233		n_div = 24;
    234		n = 2;
    235	} else if (c->frequency <= 222000000) {
    236		n_div = 16;
    237		n = 3;
    238	} else if (c->frequency <= 296000000) {
    239		n_div = 12;
    240		n = 4;
    241	} else if (c->frequency <= 445000000) {
    242		n_div = 8;
    243		n = 5;
    244	} else if (c->frequency <= dev->fn_min) {
    245		n_div = 6;
    246		n = 6;
    247	} else if (c->frequency <= 950000000) {
    248		n_div = 4;
    249		n = 7;
    250	} else {
    251		n_div = 2;
    252		n = 0;
    253	}
    254
    255	ret = regmap_read(dev->regmap, 0x80ed81, &utmp);
    256	if (ret)
    257		goto err;
    258
    259	iqik_m_cal = utmp * n_div;
    260
    261	if (utmp < 0x20) {
    262		if (dev->clk_mode == 0)
    263			iqik_m_cal = (iqik_m_cal * 9) >> 5;
    264		else
    265			iqik_m_cal >>= 1;
    266	} else {
    267		iqik_m_cal = 0x40 - iqik_m_cal;
    268		if (dev->clk_mode == 0)
    269			iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
    270		else
    271			iqik_m_cal = ~(iqik_m_cal >> 1);
    272	}
    273
    274	t_cal_freq = (c->frequency / 1000) * n_div * dev->fdiv;
    275	pre_lo_freq = t_cal_freq / dev->xtal;
    276	utmp = pre_lo_freq * dev->xtal;
    277
    278	if ((t_cal_freq - utmp) >= (dev->xtal >> 1))
    279		pre_lo_freq++;
    280
    281	pre_lo_freq += (u32) n << 13;
    282	/* Frequency OMEGA_IQIK_M_CAL_MID*/
    283	t_cal_freq = pre_lo_freq + (u32)iqik_m_cal;
    284	dev_dbg(&pdev->dev, "t_cal_freq %u, pre_lo_freq %u\n",
    285			t_cal_freq, pre_lo_freq);
    286
    287	if (c->frequency <=         440000000) {
    288		l_band = 0;
    289		lna_band = 0;
    290	} else if (c->frequency <=  484000000) {
    291		l_band = 1;
    292		lna_band = 1;
    293	} else if (c->frequency <=  533000000) {
    294		l_band = 1;
    295		lna_band = 2;
    296	} else if (c->frequency <=  587000000) {
    297		l_band = 1;
    298		lna_band = 3;
    299	} else if (c->frequency <=  645000000) {
    300		l_band = 1;
    301		lna_band = 4;
    302	} else if (c->frequency <=  710000000) {
    303		l_band = 1;
    304		lna_band = 5;
    305	} else if (c->frequency <=  782000000) {
    306		l_band = 1;
    307		lna_band = 6;
    308	} else if (c->frequency <=  860000000) {
    309		l_band = 1;
    310		lna_band = 7;
    311	} else if (c->frequency <= 1492000000) {
    312		l_band = 1;
    313		lna_band = 0;
    314	} else if (c->frequency <= 1685000000) {
    315		l_band = 1;
    316		lna_band = 1;
    317	} else {
    318		ret = -EINVAL;
    319		goto err;
    320	}
    321
    322	/* XXX: latest windows driver does not set that at all */
    323	ret = regmap_write(dev->regmap, 0x80ee06, lna_band);
    324	if (ret)
    325		goto err;
    326
    327	if (c->bandwidth_hz <=      5000000)
    328		u8tmp = 0;
    329	else if (c->bandwidth_hz <= 6000000)
    330		u8tmp = 2;
    331	else if (c->bandwidth_hz <= 7000000)
    332		u8tmp = 4;
    333	else
    334		u8tmp = 6;       /* 8000000 */
    335
    336	ret = regmap_write(dev->regmap, 0x80ec56, u8tmp);
    337	if (ret)
    338		goto err;
    339
    340	/* XXX: latest windows driver sets different value (a8 != 68) */
    341	ret = regmap_write(dev->regmap, 0x80ec4c, 0xa0 | (l_band << 3));
    342	if (ret)
    343		goto err;
    344
    345	ret = regmap_write(dev->regmap, 0x80ec4d, (t_cal_freq >> 0) & 0xff);
    346	if (ret)
    347		goto err;
    348
    349	ret = regmap_write(dev->regmap, 0x80ec4e, (t_cal_freq >> 8) & 0xff);
    350	if (ret)
    351		goto err;
    352
    353	ret = regmap_write(dev->regmap, 0x80011e, (pre_lo_freq >> 0) & 0xff);
    354	if (ret)
    355		goto err;
    356
    357	ret = regmap_write(dev->regmap, 0x80011f, (pre_lo_freq >> 8) & 0xff);
    358	if (ret)
    359		goto err;
    360
    361	return 0;
    362err:
    363	dev_dbg(&pdev->dev, "failed %d\n", ret);
    364	return ret;
    365}
    366
    367static const struct dvb_tuner_ops it913x_tuner_ops = {
    368	.info = {
    369		.name             = "ITE IT913X",
    370		.frequency_min_hz = 174 * MHz,
    371		.frequency_max_hz = 862 * MHz,
    372	},
    373
    374	.init = it913x_init,
    375	.sleep = it913x_sleep,
    376	.set_params = it913x_set_params,
    377};
    378
    379static int it913x_probe(struct platform_device *pdev)
    380{
    381	struct it913x_platform_data *pdata = pdev->dev.platform_data;
    382	struct dvb_frontend *fe = pdata->fe;
    383	struct it913x_dev *dev;
    384	const struct platform_device_id *id = platform_get_device_id(pdev);
    385	int ret;
    386	char *chip_ver_str;
    387
    388	dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL);
    389	if (dev == NULL) {
    390		ret = -ENOMEM;
    391		dev_err(&pdev->dev, "kzalloc() failed\n");
    392		goto err;
    393	}
    394
    395	dev->pdev = pdev;
    396	dev->regmap = pdata->regmap;
    397	dev->fe = pdata->fe;
    398	dev->chip_ver = id->driver_data;
    399	dev->role = pdata->role;
    400
    401	fe->tuner_priv = dev;
    402	memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
    403			sizeof(struct dvb_tuner_ops));
    404	platform_set_drvdata(pdev, dev);
    405
    406	if (dev->chip_ver == 1)
    407		chip_ver_str = "AX";
    408	else if (dev->chip_ver == 2)
    409		chip_ver_str = "BX";
    410	else
    411		chip_ver_str = "??";
    412
    413	dev_info(&pdev->dev, "ITE IT913X %s successfully attached\n",
    414		 chip_ver_str);
    415	dev_dbg(&pdev->dev, "chip_ver %u, role %u\n", dev->chip_ver, dev->role);
    416	return 0;
    417err:
    418	dev_dbg(&pdev->dev, "failed %d\n", ret);
    419	return ret;
    420}
    421
    422static int it913x_remove(struct platform_device *pdev)
    423{
    424	struct it913x_dev *dev = platform_get_drvdata(pdev);
    425	struct dvb_frontend *fe = dev->fe;
    426
    427	dev_dbg(&pdev->dev, "\n");
    428
    429	memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
    430	fe->tuner_priv = NULL;
    431	kfree(dev);
    432
    433	return 0;
    434}
    435
    436static const struct platform_device_id it913x_id_table[] = {
    437	{"it9133ax-tuner", 1},
    438	{"it9133bx-tuner", 2},
    439	{},
    440};
    441MODULE_DEVICE_TABLE(platform, it913x_id_table);
    442
    443static struct platform_driver it913x_driver = {
    444	.driver = {
    445		.name	= "it913x",
    446		.suppress_bind_attrs	= true,
    447	},
    448	.probe		= it913x_probe,
    449	.remove		= it913x_remove,
    450	.id_table	= it913x_id_table,
    451};
    452
    453module_platform_driver(it913x_driver);
    454
    455MODULE_DESCRIPTION("ITE IT913X silicon tuner driver");
    456MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
    457MODULE_LICENSE("GPL");