Linux-libre 5.4.49-gnu
[librecmc/linux-libre.git] / drivers / media / usb / stk1160 / stk1160-i2c.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * STK1160 driver
4  *
5  * Copyright (C) 2012 Ezequiel Garcia
6  * <elezegarcia--a.t--gmail.com>
7  *
8  * Based on Easycap driver by R.M. Thomas
9  *      Copyright (C) 2010 R.M. Thomas
10  *      <rmthomas--a.t--sciolus.org>
11  */
12
13 #include <linux/module.h>
14 #include <linux/usb.h>
15 #include <linux/i2c.h>
16
17 #include "stk1160.h"
18 #include "stk1160-reg.h"
19
20 static unsigned int i2c_debug;
21 module_param(i2c_debug, int, 0644);
22 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
23
24 #define dprintk_i2c(fmt, args...)                               \
25 do {                                                            \
26         if (i2c_debug)                                          \
27                 printk(KERN_DEBUG fmt, ##args);                 \
28 } while (0)
29
30 static int stk1160_i2c_busy_wait(struct stk1160 *dev, u8 wait_bit_mask)
31 {
32         unsigned long end;
33         u8 flag;
34
35         /* Wait until read/write finish bit is set */
36         end = jiffies + msecs_to_jiffies(STK1160_I2C_TIMEOUT);
37         while (time_is_after_jiffies(end)) {
38
39                 stk1160_read_reg(dev, STK1160_SICTL+1, &flag);
40                 /* read/write done? */
41                 if (flag & wait_bit_mask)
42                         goto done;
43
44                 usleep_range(10 * USEC_PER_MSEC, 20 * USEC_PER_MSEC);
45         }
46
47         return -ETIMEDOUT;
48
49 done:
50         return 0;
51 }
52
53 static int stk1160_i2c_write_reg(struct stk1160 *dev, u8 addr,
54                 u8 reg, u8 value)
55 {
56         int rc;
57
58         /* Set serial device address */
59         rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
60         if (rc < 0)
61                 return rc;
62
63         /* Set i2c device register sub-address */
64         rc = stk1160_write_reg(dev, STK1160_SBUSW_WA, reg);
65         if (rc < 0)
66                 return rc;
67
68         /* Set i2c device register value */
69         rc = stk1160_write_reg(dev, STK1160_SBUSW_WD, value);
70         if (rc < 0)
71                 return rc;
72
73         /* Start write now */
74         rc = stk1160_write_reg(dev, STK1160_SICTL, 0x01);
75         if (rc < 0)
76                 return rc;
77
78         rc = stk1160_i2c_busy_wait(dev, 0x04);
79         if (rc < 0)
80                 return rc;
81
82         return 0;
83 }
84
85 static int stk1160_i2c_read_reg(struct stk1160 *dev, u8 addr,
86                 u8 reg, u8 *value)
87 {
88         int rc;
89
90         /* Set serial device address */
91         rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
92         if (rc < 0)
93                 return rc;
94
95         /* Set i2c device register sub-address */
96         rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, reg);
97         if (rc < 0)
98                 return rc;
99
100         /* Start read now */
101         rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
102         if (rc < 0)
103                 return rc;
104
105         rc = stk1160_i2c_busy_wait(dev, 0x01);
106         if (rc < 0)
107                 return rc;
108
109         rc = stk1160_read_reg(dev, STK1160_SBUSR_RD, value);
110         if (rc < 0)
111                 return rc;
112
113         return 0;
114 }
115
116 /*
117  * stk1160_i2c_check_for_device()
118  * check if there is a i2c_device at the supplied address
119  */
120 static int stk1160_i2c_check_for_device(struct stk1160 *dev,
121                 unsigned char addr)
122 {
123         int rc;
124
125         /* Set serial device address */
126         rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
127         if (rc < 0)
128                 return rc;
129
130         /* Set device sub-address, we'll chip version reg */
131         rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, 0x00);
132         if (rc < 0)
133                 return rc;
134
135         /* Start read now */
136         rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
137         if (rc < 0)
138                 return rc;
139
140         rc = stk1160_i2c_busy_wait(dev, 0x01);
141         if (rc < 0)
142                 return -ENODEV;
143
144         return 0;
145 }
146
147 /*
148  * stk1160_i2c_xfer()
149  * the main i2c transfer function
150  */
151 static int stk1160_i2c_xfer(struct i2c_adapter *i2c_adap,
152                            struct i2c_msg msgs[], int num)
153 {
154         struct stk1160 *dev = i2c_adap->algo_data;
155         int addr, rc, i;
156
157         for (i = 0; i < num; i++) {
158                 addr = msgs[i].addr << 1;
159                 dprintk_i2c("%s: addr=%x", __func__, addr);
160
161                 if (!msgs[i].len) {
162                         /* no len: check only for device presence */
163                         rc = stk1160_i2c_check_for_device(dev, addr);
164                         if (rc < 0) {
165                                 dprintk_i2c(" no device\n");
166                                 return rc;
167                         }
168
169                 } else if (msgs[i].flags & I2C_M_RD) {
170                         /* read request without preceding register selection */
171                         dprintk_i2c(" subaddr not selected");
172                         rc = -EOPNOTSUPP;
173                         goto err;
174
175                 } else if (i + 1 < num && msgs[i].len <= 2 &&
176                            (msgs[i + 1].flags & I2C_M_RD) &&
177                            msgs[i].addr == msgs[i + 1].addr) {
178
179                         if (msgs[i].len != 1 || msgs[i + 1].len != 1) {
180                                 dprintk_i2c(" len not supported");
181                                 rc = -EOPNOTSUPP;
182                                 goto err;
183                         }
184
185                         dprintk_i2c(" subaddr=%x", msgs[i].buf[0]);
186
187                         rc = stk1160_i2c_read_reg(dev, addr, msgs[i].buf[0],
188                                 msgs[i + 1].buf);
189
190                         dprintk_i2c(" read=%x", *msgs[i + 1].buf);
191
192                         /* consumed two msgs, so we skip one of them */
193                         i++;
194
195                 } else {
196                         if (msgs[i].len != 2) {
197                                 dprintk_i2c(" len not supported");
198                                 rc = -EOPNOTSUPP;
199                                 goto err;
200                         }
201
202                         dprintk_i2c(" subaddr=%x write=%x",
203                                 msgs[i].buf[0],  msgs[i].buf[1]);
204
205                         rc = stk1160_i2c_write_reg(dev, addr, msgs[i].buf[0],
206                                 msgs[i].buf[1]);
207                 }
208
209                 if (rc < 0)
210                         goto err;
211                 dprintk_i2c(" OK\n");
212         }
213
214         return num;
215 err:
216         dprintk_i2c(" ERROR: %d\n", rc);
217         return num;
218 }
219
220 /*
221  * functionality(), what da heck is this?
222  */
223 static u32 functionality(struct i2c_adapter *adap)
224 {
225         return I2C_FUNC_SMBUS_EMUL;
226 }
227
228 static const struct i2c_algorithm algo = {
229         .master_xfer   = stk1160_i2c_xfer,
230         .functionality = functionality,
231 };
232
233 static const struct i2c_adapter adap_template = {
234         .owner = THIS_MODULE,
235         .name = "stk1160",
236         .algo = &algo,
237 };
238
239 static const struct i2c_client client_template = {
240         .name = "stk1160 internal",
241 };
242
243 /*
244  * stk1160_i2c_register()
245  * register i2c bus
246  */
247 int stk1160_i2c_register(struct stk1160 *dev)
248 {
249         int rc;
250
251         dev->i2c_adap = adap_template;
252         dev->i2c_adap.dev.parent = dev->dev;
253         strscpy(dev->i2c_adap.name, "stk1160", sizeof(dev->i2c_adap.name));
254         dev->i2c_adap.algo_data = dev;
255
256         i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
257
258         rc = i2c_add_adapter(&dev->i2c_adap);
259         if (rc < 0) {
260                 stk1160_err("cannot add i2c adapter (%d)\n", rc);
261                 return rc;
262         }
263
264         dev->i2c_client = client_template;
265         dev->i2c_client.adapter = &dev->i2c_adap;
266
267         /* Set i2c clock divider device address */
268         stk1160_write_reg(dev, STK1160_SICTL_CD,  0x0f);
269
270         /* ??? */
271         stk1160_write_reg(dev, STK1160_ASIC + 3,  0x00);
272
273         return 0;
274 }
275
276 /*
277  * stk1160_i2c_unregister()
278  * unregister i2c_bus
279  */
280 int stk1160_i2c_unregister(struct stk1160 *dev)
281 {
282         i2c_del_adapter(&dev->i2c_adap);
283         return 0;
284 }