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

tua9001.c (5675B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Infineon TUA9001 silicon tuner driver
      4 *
      5 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
      6 */
      7
      8#include "tua9001_priv.h"
      9
     10static int tua9001_init(struct dvb_frontend *fe)
     11{
     12	struct tua9001_dev *dev = fe->tuner_priv;
     13	struct i2c_client *client = dev->client;
     14	int ret, i;
     15	static const struct tua9001_reg_val data[] = {
     16		{0x1e, 0x6512},
     17		{0x25, 0xb888},
     18		{0x39, 0x5460},
     19		{0x3b, 0x00c0},
     20		{0x3a, 0xf000},
     21		{0x08, 0x0000},
     22		{0x32, 0x0030},
     23		{0x41, 0x703a},
     24		{0x40, 0x1c78},
     25		{0x2c, 0x1c00},
     26		{0x36, 0xc013},
     27		{0x37, 0x6f18},
     28		{0x27, 0x0008},
     29		{0x2a, 0x0001},
     30		{0x34, 0x0a40},
     31	};
     32
     33	dev_dbg(&client->dev, "\n");
     34
     35	if (fe->callback) {
     36		ret = fe->callback(client->adapter,
     37				   DVB_FRONTEND_COMPONENT_TUNER,
     38				   TUA9001_CMD_RESETN, 0);
     39		if (ret)
     40			goto err;
     41	}
     42
     43	for (i = 0; i < ARRAY_SIZE(data); i++) {
     44		ret = regmap_write(dev->regmap, data[i].reg, data[i].val);
     45		if (ret)
     46			goto err;
     47	}
     48	return 0;
     49err:
     50	dev_dbg(&client->dev, "failed=%d\n", ret);
     51	return ret;
     52}
     53
     54static int tua9001_sleep(struct dvb_frontend *fe)
     55{
     56	struct tua9001_dev *dev = fe->tuner_priv;
     57	struct i2c_client *client = dev->client;
     58	int ret;
     59
     60	dev_dbg(&client->dev, "\n");
     61
     62	if (fe->callback) {
     63		ret = fe->callback(client->adapter,
     64				   DVB_FRONTEND_COMPONENT_TUNER,
     65				   TUA9001_CMD_RESETN, 1);
     66		if (ret)
     67			goto err;
     68	}
     69	return 0;
     70err:
     71	dev_dbg(&client->dev, "failed=%d\n", ret);
     72	return ret;
     73}
     74
     75static int tua9001_set_params(struct dvb_frontend *fe)
     76{
     77	struct tua9001_dev *dev = fe->tuner_priv;
     78	struct i2c_client *client = dev->client;
     79	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
     80	int ret, i;
     81	u16 val;
     82	struct tua9001_reg_val data[2];
     83
     84	dev_dbg(&client->dev,
     85		"delivery_system=%u frequency=%u bandwidth_hz=%u\n",
     86		c->delivery_system, c->frequency, c->bandwidth_hz);
     87
     88	switch (c->delivery_system) {
     89	case SYS_DVBT:
     90		switch (c->bandwidth_hz) {
     91		case 8000000:
     92			val  = 0x0000;
     93			break;
     94		case 7000000:
     95			val  = 0x1000;
     96			break;
     97		case 6000000:
     98			val  = 0x2000;
     99			break;
    100		case 5000000:
    101			val  = 0x3000;
    102			break;
    103		default:
    104			ret = -EINVAL;
    105			goto err;
    106		}
    107		break;
    108	default:
    109		ret = -EINVAL;
    110		goto err;
    111	}
    112
    113	data[0].reg = 0x04;
    114	data[0].val = val;
    115	data[1].reg = 0x1f;
    116	data[1].val = div_u64((u64) (c->frequency - 150000000) * 48, 1000000);
    117
    118	if (fe->callback) {
    119		ret = fe->callback(client->adapter,
    120				   DVB_FRONTEND_COMPONENT_TUNER,
    121				   TUA9001_CMD_RXEN, 0);
    122		if (ret)
    123			goto err;
    124	}
    125
    126	for (i = 0; i < ARRAY_SIZE(data); i++) {
    127		ret = regmap_write(dev->regmap, data[i].reg, data[i].val);
    128		if (ret)
    129			goto err;
    130	}
    131
    132	if (fe->callback) {
    133		ret = fe->callback(client->adapter,
    134				   DVB_FRONTEND_COMPONENT_TUNER,
    135				   TUA9001_CMD_RXEN, 1);
    136		if (ret)
    137			goto err;
    138	}
    139	return 0;
    140err:
    141	dev_dbg(&client->dev, "failed=%d\n", ret);
    142	return ret;
    143}
    144
    145static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
    146{
    147	struct tua9001_dev *dev = fe->tuner_priv;
    148	struct i2c_client *client = dev->client;
    149
    150	dev_dbg(&client->dev, "\n");
    151
    152	*frequency = 0; /* Zero-IF */
    153	return 0;
    154}
    155
    156static const struct dvb_tuner_ops tua9001_tuner_ops = {
    157	.info = {
    158		.name             = "Infineon TUA9001",
    159		.frequency_min_hz = 170 * MHz,
    160		.frequency_max_hz = 862 * MHz,
    161	},
    162
    163	.init = tua9001_init,
    164	.sleep = tua9001_sleep,
    165	.set_params = tua9001_set_params,
    166
    167	.get_if_frequency = tua9001_get_if_frequency,
    168};
    169
    170static int tua9001_probe(struct i2c_client *client,
    171			const struct i2c_device_id *id)
    172{
    173	struct tua9001_dev *dev;
    174	struct tua9001_platform_data *pdata = client->dev.platform_data;
    175	struct dvb_frontend *fe = pdata->dvb_frontend;
    176	int ret;
    177	static const struct regmap_config regmap_config = {
    178		.reg_bits =  8,
    179		.val_bits = 16,
    180	};
    181
    182	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    183	if (!dev) {
    184		ret = -ENOMEM;
    185		goto err;
    186	}
    187
    188	dev->fe = pdata->dvb_frontend;
    189	dev->client = client;
    190	dev->regmap = devm_regmap_init_i2c(client, &regmap_config);
    191	if (IS_ERR(dev->regmap)) {
    192		ret = PTR_ERR(dev->regmap);
    193		goto err_kfree;
    194	}
    195
    196	if (fe->callback) {
    197		ret = fe->callback(client->adapter,
    198				   DVB_FRONTEND_COMPONENT_TUNER,
    199				   TUA9001_CMD_CEN, 1);
    200		if (ret)
    201			goto err_kfree;
    202
    203		ret = fe->callback(client->adapter,
    204				   DVB_FRONTEND_COMPONENT_TUNER,
    205				   TUA9001_CMD_RXEN, 0);
    206		if (ret)
    207			goto err_kfree;
    208
    209		ret = fe->callback(client->adapter,
    210				   DVB_FRONTEND_COMPONENT_TUNER,
    211				   TUA9001_CMD_RESETN, 1);
    212		if (ret)
    213			goto err_kfree;
    214	}
    215
    216	fe->tuner_priv = dev;
    217	memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
    218			sizeof(struct dvb_tuner_ops));
    219	i2c_set_clientdata(client, dev);
    220
    221	dev_info(&client->dev, "Infineon TUA9001 successfully attached\n");
    222	return 0;
    223err_kfree:
    224	kfree(dev);
    225err:
    226	dev_dbg(&client->dev, "failed=%d\n", ret);
    227	return ret;
    228}
    229
    230static int tua9001_remove(struct i2c_client *client)
    231{
    232	struct tua9001_dev *dev = i2c_get_clientdata(client);
    233	struct dvb_frontend *fe = dev->fe;
    234	int ret;
    235
    236	dev_dbg(&client->dev, "\n");
    237
    238	if (fe->callback) {
    239		ret = fe->callback(client->adapter,
    240				   DVB_FRONTEND_COMPONENT_TUNER,
    241				   TUA9001_CMD_CEN, 0);
    242		if (ret)
    243			dev_err(&client->dev, "Tuner disable failed (%pe)\n", ERR_PTR(ret));
    244	}
    245	kfree(dev);
    246	return 0;
    247}
    248
    249static const struct i2c_device_id tua9001_id_table[] = {
    250	{"tua9001", 0},
    251	{}
    252};
    253MODULE_DEVICE_TABLE(i2c, tua9001_id_table);
    254
    255static struct i2c_driver tua9001_driver = {
    256	.driver = {
    257		.name	= "tua9001",
    258		.suppress_bind_attrs = true,
    259	},
    260	.probe		= tua9001_probe,
    261	.remove		= tua9001_remove,
    262	.id_table	= tua9001_id_table,
    263};
    264
    265module_i2c_driver(tua9001_driver);
    266
    267MODULE_DESCRIPTION("Infineon TUA9001 silicon tuner driver");
    268MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
    269MODULE_LICENSE("GPL");