xref: /linux/drivers/media/usb/stk1160/stk1160-i2c.c (revision 26fbb4c8c7c3ee9a4c3b4de555a8587b5a19154e)
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 }
285