This source file includes following definitions.
- pca9541_reg_write
- pca9541_reg_read
- pca9541_release_bus
- pca9541_arbitrate
- pca9541_select_chan
- pca9541_release_chan
- pca9541_probe
- pca9541_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <linux/delay.h>
20 #include <linux/device.h>
21 #include <linux/i2c.h>
22 #include <linux/i2c-mux.h>
23 #include <linux/jiffies.h>
24 #include <linux/module.h>
25 #include <linux/slab.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #define PCA9541_CONTROL 0x01
43 #define PCA9541_ISTAT 0x02
44
45 #define PCA9541_CTL_MYBUS (1 << 0)
46 #define PCA9541_CTL_NMYBUS (1 << 1)
47 #define PCA9541_CTL_BUSON (1 << 2)
48 #define PCA9541_CTL_NBUSON (1 << 3)
49 #define PCA9541_CTL_BUSINIT (1 << 4)
50 #define PCA9541_CTL_TESTON (1 << 6)
51 #define PCA9541_CTL_NTESTON (1 << 7)
52
53 #define PCA9541_ISTAT_INTIN (1 << 0)
54 #define PCA9541_ISTAT_BUSINIT (1 << 1)
55 #define PCA9541_ISTAT_BUSOK (1 << 2)
56 #define PCA9541_ISTAT_BUSLOST (1 << 3)
57 #define PCA9541_ISTAT_MYTEST (1 << 6)
58 #define PCA9541_ISTAT_NMYTEST (1 << 7)
59
60 #define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
61 #define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
62 #define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
63 #define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON)
64
65
66 #define ARB_TIMEOUT (HZ / 8)
67 #define ARB2_TIMEOUT (HZ / 4)
68
69
70 #define SELECT_DELAY_SHORT 50
71 #define SELECT_DELAY_LONG 1000
72
73 struct pca9541 {
74 struct i2c_client *client;
75 unsigned long select_timeout;
76 unsigned long arb_timeout;
77 };
78
79 static const struct i2c_device_id pca9541_id[] = {
80 {"pca9541", 0},
81 {}
82 };
83
84 MODULE_DEVICE_TABLE(i2c, pca9541_id);
85
86 #ifdef CONFIG_OF
87 static const struct of_device_id pca9541_of_match[] = {
88 { .compatible = "nxp,pca9541" },
89 {}
90 };
91 MODULE_DEVICE_TABLE(of, pca9541_of_match);
92 #endif
93
94
95
96
97
98 static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
99 {
100 struct i2c_adapter *adap = client->adapter;
101 union i2c_smbus_data data = { .byte = val };
102
103 return __i2c_smbus_xfer(adap, client->addr, client->flags,
104 I2C_SMBUS_WRITE, command,
105 I2C_SMBUS_BYTE_DATA, &data);
106 }
107
108
109
110
111
112 static int pca9541_reg_read(struct i2c_client *client, u8 command)
113 {
114 struct i2c_adapter *adap = client->adapter;
115 union i2c_smbus_data data;
116 int ret;
117
118 ret = __i2c_smbus_xfer(adap, client->addr, client->flags,
119 I2C_SMBUS_READ, command,
120 I2C_SMBUS_BYTE_DATA, &data);
121
122 return ret ?: data.byte;
123 }
124
125
126
127
128
129
130 static void pca9541_release_bus(struct i2c_client *client)
131 {
132 int reg;
133
134 reg = pca9541_reg_read(client, PCA9541_CONTROL);
135 if (reg >= 0 && !busoff(reg) && mybus(reg))
136 pca9541_reg_write(client, PCA9541_CONTROL,
137 (reg & PCA9541_CTL_NBUSON) >> 1);
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 static const u8 pca9541_control[16] = {
166 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
167 };
168
169
170
171
172
173
174
175
176
177 static int pca9541_arbitrate(struct i2c_client *client)
178 {
179 struct i2c_mux_core *muxc = i2c_get_clientdata(client);
180 struct pca9541 *data = i2c_mux_priv(muxc);
181 int reg;
182
183 reg = pca9541_reg_read(client, PCA9541_CONTROL);
184 if (reg < 0)
185 return reg;
186
187 if (busoff(reg)) {
188 int istat;
189
190
191
192
193 istat = pca9541_reg_read(client, PCA9541_ISTAT);
194 if (!(istat & PCA9541_ISTAT_NMYTEST)
195 || time_is_before_eq_jiffies(data->arb_timeout)) {
196
197
198
199
200 pca9541_reg_write(client,
201 PCA9541_CONTROL,
202 pca9541_control[reg & 0x0f]
203 | PCA9541_CTL_NTESTON);
204 data->select_timeout = SELECT_DELAY_SHORT;
205 } else {
206
207
208
209
210 data->select_timeout = SELECT_DELAY_LONG * 2;
211 }
212 } else if (mybus(reg)) {
213
214
215
216
217 if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
218 pca9541_reg_write(client,
219 PCA9541_CONTROL,
220 reg & ~(PCA9541_CTL_NTESTON
221 | PCA9541_CTL_BUSINIT));
222 return 1;
223 } else {
224
225
226
227
228
229 data->select_timeout = SELECT_DELAY_LONG;
230 if (time_is_before_eq_jiffies(data->arb_timeout)) {
231
232 pca9541_reg_write(client,
233 PCA9541_CONTROL,
234 pca9541_control[reg & 0x0f]
235 | PCA9541_CTL_BUSINIT
236 | PCA9541_CTL_NTESTON);
237 } else {
238
239 if (!(reg & PCA9541_CTL_NTESTON))
240 pca9541_reg_write(client,
241 PCA9541_CONTROL,
242 reg | PCA9541_CTL_NTESTON);
243 }
244 }
245 return 0;
246 }
247
248 static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
249 {
250 struct pca9541 *data = i2c_mux_priv(muxc);
251 struct i2c_client *client = data->client;
252 int ret;
253 unsigned long timeout = jiffies + ARB2_TIMEOUT;
254
255
256 data->arb_timeout = jiffies + ARB_TIMEOUT;
257
258
259 do {
260 ret = pca9541_arbitrate(client);
261 if (ret)
262 return ret < 0 ? ret : 0;
263
264 if (data->select_timeout == SELECT_DELAY_SHORT)
265 udelay(data->select_timeout);
266 else
267 msleep(data->select_timeout / 1000);
268 } while (time_is_after_eq_jiffies(timeout));
269
270 return -ETIMEDOUT;
271 }
272
273 static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
274 {
275 struct pca9541 *data = i2c_mux_priv(muxc);
276 struct i2c_client *client = data->client;
277
278 pca9541_release_bus(client);
279 return 0;
280 }
281
282
283
284
285 static int pca9541_probe(struct i2c_client *client,
286 const struct i2c_device_id *id)
287 {
288 struct i2c_adapter *adap = client->adapter;
289 struct i2c_mux_core *muxc;
290 struct pca9541 *data;
291 int ret;
292
293 if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
294 return -ENODEV;
295
296
297
298
299
300 i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
301 pca9541_release_bus(client);
302 i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
303
304
305
306 muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
307 I2C_MUX_ARBITRATOR,
308 pca9541_select_chan, pca9541_release_chan);
309 if (!muxc)
310 return -ENOMEM;
311
312 data = i2c_mux_priv(muxc);
313 data->client = client;
314
315 i2c_set_clientdata(client, muxc);
316
317 ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
318 if (ret)
319 return ret;
320
321 dev_info(&client->dev, "registered master selector for I2C %s\n",
322 client->name);
323
324 return 0;
325 }
326
327 static int pca9541_remove(struct i2c_client *client)
328 {
329 struct i2c_mux_core *muxc = i2c_get_clientdata(client);
330
331 i2c_mux_del_adapters(muxc);
332 return 0;
333 }
334
335 static struct i2c_driver pca9541_driver = {
336 .driver = {
337 .name = "pca9541",
338 .of_match_table = of_match_ptr(pca9541_of_match),
339 },
340 .probe = pca9541_probe,
341 .remove = pca9541_remove,
342 .id_table = pca9541_id,
343 };
344
345 module_i2c_driver(pca9541_driver);
346
347 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
348 MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
349 MODULE_LICENSE("GPL v2");