brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · 562a7a5 Raw
268 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Infineon TUA9001 silicon tuner driver4 *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{172	struct tua9001_dev *dev;173	struct tua9001_platform_data *pdata = client->dev.platform_data;174	struct dvb_frontend *fe = pdata->dvb_frontend;175	int ret;176	static const struct regmap_config regmap_config = {177		.reg_bits =  8,178		.val_bits = 16,179	};180 181	dev = kzalloc(sizeof(*dev), GFP_KERNEL);182	if (!dev) {183		ret = -ENOMEM;184		goto err;185	}186 187	dev->fe = pdata->dvb_frontend;188	dev->client = client;189	dev->regmap = devm_regmap_init_i2c(client, &regmap_config);190	if (IS_ERR(dev->regmap)) {191		ret = PTR_ERR(dev->regmap);192		goto err_kfree;193	}194 195	if (fe->callback) {196		ret = fe->callback(client->adapter,197				   DVB_FRONTEND_COMPONENT_TUNER,198				   TUA9001_CMD_CEN, 1);199		if (ret)200			goto err_kfree;201 202		ret = fe->callback(client->adapter,203				   DVB_FRONTEND_COMPONENT_TUNER,204				   TUA9001_CMD_RXEN, 0);205		if (ret)206			goto err_kfree;207 208		ret = fe->callback(client->adapter,209				   DVB_FRONTEND_COMPONENT_TUNER,210				   TUA9001_CMD_RESETN, 1);211		if (ret)212			goto err_kfree;213	}214 215	fe->tuner_priv = dev;216	memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,217			sizeof(struct dvb_tuner_ops));218	i2c_set_clientdata(client, dev);219 220	dev_info(&client->dev, "Infineon TUA9001 successfully attached\n");221	return 0;222err_kfree:223	kfree(dev);224err:225	dev_dbg(&client->dev, "failed=%d\n", ret);226	return ret;227}228 229static void tua9001_remove(struct i2c_client *client)230{231	struct tua9001_dev *dev = i2c_get_clientdata(client);232	struct dvb_frontend *fe = dev->fe;233	int ret;234 235	dev_dbg(&client->dev, "\n");236 237	if (fe->callback) {238		ret = fe->callback(client->adapter,239				   DVB_FRONTEND_COMPONENT_TUNER,240				   TUA9001_CMD_CEN, 0);241		if (ret)242			dev_err(&client->dev, "Tuner disable failed (%pe)\n", ERR_PTR(ret));243	}244	kfree(dev);245}246 247static const struct i2c_device_id tua9001_id_table[] = {248	{ "tua9001" },249	{}250};251MODULE_DEVICE_TABLE(i2c, tua9001_id_table);252 253static struct i2c_driver tua9001_driver = {254	.driver = {255		.name	= "tua9001",256		.suppress_bind_attrs = true,257	},258	.probe		= tua9001_probe,259	.remove		= tua9001_remove,260	.id_table	= tua9001_id_table,261};262 263module_i2c_driver(tua9001_driver);264 265MODULE_DESCRIPTION("Infineon TUA9001 silicon tuner driver");266MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");267MODULE_LICENSE("GPL");268