blob: 57f52c004a2336e3b677198005ffa726d02f0fa0 [file] [log] [blame]
Thomas Gleixnerc942fdd2019-05-27 08:55:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Antti Palosaari85bc9b52011-08-01 00:52:11 -03002/*
3 * Allegro A8293 SEC driver
4 *
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
Antti Palosaari85bc9b52011-08-01 00:52:11 -03006 */
7
Antti Palosaari85bc9b52011-08-01 00:52:11 -03008#include "a8293.h"
9
Antti Palosaari2c509b82015-04-20 18:16:19 -030010struct a8293_dev {
Antti Palosaarib561bae2015-04-16 13:28:39 -030011 struct i2c_client *client;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030012 u8 reg[2];
13};
14
Antti Palosaari85bc9b52011-08-01 00:52:11 -030015static int a8293_set_voltage(struct dvb_frontend *fe,
Antti Palosaari3250a5502015-04-20 18:57:03 -030016 enum fe_sec_voltage fe_sec_voltage)
Antti Palosaari85bc9b52011-08-01 00:52:11 -030017{
Antti Palosaari2c509b82015-04-20 18:16:19 -030018 struct a8293_dev *dev = fe->sec_priv;
19 struct i2c_client *client = dev->client;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030020 int ret;
Antti Palosaari4bef67e2015-04-20 18:47:44 -030021 u8 reg0, reg1;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030022
Antti Palosaari2c509b82015-04-20 18:16:19 -030023 dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
Antti Palosaari85bc9b52011-08-01 00:52:11 -030024
25 switch (fe_sec_voltage) {
26 case SEC_VOLTAGE_OFF:
27 /* ENB=0 */
Antti Palosaari4bef67e2015-04-20 18:47:44 -030028 reg0 = 0x10;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030029 break;
30 case SEC_VOLTAGE_13:
31 /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
Antti Palosaari4bef67e2015-04-20 18:47:44 -030032 reg0 = 0x31;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030033 break;
34 case SEC_VOLTAGE_18:
35 /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
Antti Palosaari4bef67e2015-04-20 18:47:44 -030036 reg0 = 0x38;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030037 break;
38 default:
39 ret = -EINVAL;
40 goto err;
Peter Senna Tschudinc2c1b412012-09-28 05:37:22 -030041 }
Antti Palosaari4bef67e2015-04-20 18:47:44 -030042 if (reg0 != dev->reg[0]) {
43 ret = i2c_master_send(client, &reg0, 1);
44 if (ret < 0)
45 goto err;
46 dev->reg[0] = reg0;
47 }
Antti Palosaari85bc9b52011-08-01 00:52:11 -030048
Antti Palosaari4bef67e2015-04-20 18:47:44 -030049 /* TMODE=0, TGATE=1 */
50 reg1 = 0x82;
51 if (reg1 != dev->reg[1]) {
52 ret = i2c_master_send(client, &reg1, 1);
53 if (ret < 0)
54 goto err;
55 dev->reg[1] = reg1;
56 }
Antti Palosaari85bc9b52011-08-01 00:52:11 -030057
Antti Palosaaric0ec1c42013-02-25 08:24:18 -030058 usleep_range(1500, 50000);
Antti Palosaari2c509b82015-04-20 18:16:19 -030059 return 0;
Antti Palosaari85bc9b52011-08-01 00:52:11 -030060err:
Antti Palosaari2c509b82015-04-20 18:16:19 -030061 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari85bc9b52011-08-01 00:52:11 -030062 return ret;
63}
64
Antti Palosaarib561bae2015-04-16 13:28:39 -030065static int a8293_probe(struct i2c_client *client,
Antti Palosaari55881b42015-04-20 17:39:33 -030066 const struct i2c_device_id *id)
Antti Palosaarib561bae2015-04-16 13:28:39 -030067{
Antti Palosaari2c509b82015-04-20 18:16:19 -030068 struct a8293_dev *dev;
Antti Palosaarib561bae2015-04-16 13:28:39 -030069 struct a8293_platform_data *pdata = client->dev.platform_data;
70 struct dvb_frontend *fe = pdata->dvb_frontend;
71 int ret;
72 u8 buf[2];
73
74 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
75 if (!dev) {
76 ret = -ENOMEM;
77 goto err;
78 }
79
80 dev->client = client;
Antti Palosaarib561bae2015-04-16 13:28:39 -030081
82 /* check if the SEC is there */
Antti Palosaari2c509b82015-04-20 18:16:19 -030083 ret = i2c_master_recv(client, buf, 2);
84 if (ret < 0)
Antti Palosaarib561bae2015-04-16 13:28:39 -030085 goto err_kfree;
86
Antti Palosaarib561bae2015-04-16 13:28:39 -030087 /* override frontend ops */
88 fe->ops.set_voltage = a8293_set_voltage;
Antti Palosaarib561bae2015-04-16 13:28:39 -030089 fe->sec_priv = dev;
90 i2c_set_clientdata(client, dev);
91
92 dev_info(&client->dev, "Allegro A8293 SEC successfully attached\n");
93 return 0;
94err_kfree:
95 kfree(dev);
96err:
97 dev_dbg(&client->dev, "failed=%d\n", ret);
98 return ret;
99}
100
101static int a8293_remove(struct i2c_client *client)
102{
103 struct a8293_dev *dev = i2c_get_clientdata(client);
104
105 dev_dbg(&client->dev, "\n");
106
107 kfree(dev);
108 return 0;
109}
110
111static const struct i2c_device_id a8293_id_table[] = {
112 {"a8293", 0},
113 {}
114};
115MODULE_DEVICE_TABLE(i2c, a8293_id_table);
116
117static struct i2c_driver a8293_driver = {
118 .driver = {
Antti Palosaarib561bae2015-04-16 13:28:39 -0300119 .name = "a8293",
120 .suppress_bind_attrs = true,
121 },
122 .probe = a8293_probe,
123 .remove = a8293_remove,
124 .id_table = a8293_id_table,
125};
126
127module_i2c_driver(a8293_driver);
128
Antti Palosaari85bc9b52011-08-01 00:52:11 -0300129MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
130MODULE_DESCRIPTION("Allegro A8293 SEC driver");
131MODULE_LICENSE("GPL");