Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / media / dvb-frontends / a8293.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Allegro A8293 SEC driver
4  *
5  * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6  */
7
8 #include "a8293.h"
9
10 struct a8293_dev {
11         struct i2c_client *client;
12         u8 reg[2];
13 };
14
15 static int a8293_set_voltage(struct dvb_frontend *fe,
16                              enum fe_sec_voltage fe_sec_voltage)
17 {
18         struct a8293_dev *dev = fe->sec_priv;
19         struct i2c_client *client = dev->client;
20         int ret;
21         u8 reg0, reg1;
22
23         dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
24
25         switch (fe_sec_voltage) {
26         case SEC_VOLTAGE_OFF:
27                 /* ENB=0 */
28                 reg0 = 0x10;
29                 break;
30         case SEC_VOLTAGE_13:
31                 /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
32                 reg0 = 0x31;
33                 break;
34         case SEC_VOLTAGE_18:
35                 /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
36                 reg0 = 0x38;
37                 break;
38         default:
39                 ret = -EINVAL;
40                 goto err;
41         }
42         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         }
48
49         /* 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         }
57
58         usleep_range(1500, 50000);
59         return 0;
60 err:
61         dev_dbg(&client->dev, "failed=%d\n", ret);
62         return ret;
63 }
64
65 static int a8293_probe(struct i2c_client *client,
66                        const struct i2c_device_id *id)
67 {
68         struct a8293_dev *dev;
69         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;
81
82         /* check if the SEC is there */
83         ret = i2c_master_recv(client, buf, 2);
84         if (ret < 0)
85                 goto err_kfree;
86
87         /* override frontend ops */
88         fe->ops.set_voltage = a8293_set_voltage;
89         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;
94 err_kfree:
95         kfree(dev);
96 err:
97         dev_dbg(&client->dev, "failed=%d\n", ret);
98         return ret;
99 }
100
101 static 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
111 static const struct i2c_device_id a8293_id_table[] = {
112         {"a8293", 0},
113         {}
114 };
115 MODULE_DEVICE_TABLE(i2c, a8293_id_table);
116
117 static struct i2c_driver a8293_driver = {
118         .driver = {
119                 .name   = "a8293",
120                 .suppress_bind_attrs = true,
121         },
122         .probe          = a8293_probe,
123         .remove         = a8293_remove,
124         .id_table       = a8293_id_table,
125 };
126
127 module_i2c_driver(a8293_driver);
128
129 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
130 MODULE_DESCRIPTION("Allegro A8293 SEC driver");
131 MODULE_LICENSE("GPL");