1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * opt3001.c - Texas Instruments OPT3001 Light Sensor |
4 | * |
5 | * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com |
6 | * |
7 | * Author: Andreas Dannenberg <dannenberg@ti.com> |
8 | * Based on previous work from: Felipe Balbi <balbi@ti.com> |
9 | */ |
10 | |
11 | #include <linux/bitops.h> |
12 | #include <linux/delay.h> |
13 | #include <linux/device.h> |
14 | #include <linux/i2c.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/irq.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> |
19 | #include <linux/mod_devicetable.h> |
20 | #include <linux/mutex.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/types.h> |
23 | |
24 | #include <linux/iio/events.h> |
25 | #include <linux/iio/iio.h> |
26 | #include <linux/iio/sysfs.h> |
27 | |
28 | #define OPT3001_RESULT 0x00 |
29 | #define OPT3001_CONFIGURATION 0x01 |
30 | #define OPT3001_LOW_LIMIT 0x02 |
31 | #define OPT3001_HIGH_LIMIT 0x03 |
32 | #define OPT3001_MANUFACTURER_ID 0x7e |
33 | #define OPT3001_DEVICE_ID 0x7f |
34 | |
35 | #define OPT3001_CONFIGURATION_RN_MASK (0xf << 12) |
36 | #define OPT3001_CONFIGURATION_RN_AUTO (0xc << 12) |
37 | |
38 | #define OPT3001_CONFIGURATION_CT BIT(11) |
39 | |
40 | #define OPT3001_CONFIGURATION_M_MASK (3 << 9) |
41 | #define OPT3001_CONFIGURATION_M_SHUTDOWN (0 << 9) |
42 | #define OPT3001_CONFIGURATION_M_SINGLE (1 << 9) |
43 | #define OPT3001_CONFIGURATION_M_CONTINUOUS (2 << 9) /* also 3 << 9 */ |
44 | |
45 | #define OPT3001_CONFIGURATION_OVF BIT(8) |
46 | #define OPT3001_CONFIGURATION_CRF BIT(7) |
47 | #define OPT3001_CONFIGURATION_FH BIT(6) |
48 | #define OPT3001_CONFIGURATION_FL BIT(5) |
49 | #define OPT3001_CONFIGURATION_L BIT(4) |
50 | #define OPT3001_CONFIGURATION_POL BIT(3) |
51 | #define OPT3001_CONFIGURATION_ME BIT(2) |
52 | |
53 | #define OPT3001_CONFIGURATION_FC_MASK (3 << 0) |
54 | |
55 | /* The end-of-conversion enable is located in the low-limit register */ |
56 | #define OPT3001_LOW_LIMIT_EOC_ENABLE 0xc000 |
57 | |
58 | #define OPT3001_REG_EXPONENT(n) ((n) >> 12) |
59 | #define OPT3001_REG_MANTISSA(n) ((n) & 0xfff) |
60 | |
61 | #define OPT3001_INT_TIME_LONG 800000 |
62 | #define OPT3001_INT_TIME_SHORT 100000 |
63 | |
64 | /* |
65 | * Time to wait for conversion result to be ready. The device datasheet |
66 | * sect. 6.5 states results are ready after total integration time plus 3ms. |
67 | * This results in worst-case max values of 113ms or 883ms, respectively. |
68 | * Add some slack to be on the safe side. |
69 | */ |
70 | #define OPT3001_RESULT_READY_SHORT 150 |
71 | #define OPT3001_RESULT_READY_LONG 1000 |
72 | |
73 | struct opt3001 { |
74 | struct i2c_client *client; |
75 | struct device *dev; |
76 | |
77 | struct mutex lock; |
78 | bool ok_to_ignore_lock; |
79 | bool result_ready; |
80 | wait_queue_head_t result_ready_queue; |
81 | u16 result; |
82 | |
83 | u32 int_time; |
84 | u32 mode; |
85 | |
86 | u16 high_thresh_mantissa; |
87 | u16 low_thresh_mantissa; |
88 | |
89 | u8 high_thresh_exp; |
90 | u8 low_thresh_exp; |
91 | |
92 | bool use_irq; |
93 | }; |
94 | |
95 | struct opt3001_scale { |
96 | int val; |
97 | int val2; |
98 | }; |
99 | |
100 | static const struct opt3001_scale opt3001_scales[] = { |
101 | { |
102 | .val = 40, |
103 | .val2 = 950000, |
104 | }, |
105 | { |
106 | .val = 81, |
107 | .val2 = 900000, |
108 | }, |
109 | { |
110 | .val = 163, |
111 | .val2 = 800000, |
112 | }, |
113 | { |
114 | .val = 327, |
115 | .val2 = 600000, |
116 | }, |
117 | { |
118 | .val = 655, |
119 | .val2 = 200000, |
120 | }, |
121 | { |
122 | .val = 1310, |
123 | .val2 = 400000, |
124 | }, |
125 | { |
126 | .val = 2620, |
127 | .val2 = 800000, |
128 | }, |
129 | { |
130 | .val = 5241, |
131 | .val2 = 600000, |
132 | }, |
133 | { |
134 | .val = 10483, |
135 | .val2 = 200000, |
136 | }, |
137 | { |
138 | .val = 20966, |
139 | .val2 = 400000, |
140 | }, |
141 | { |
142 | .val = 83865, |
143 | .val2 = 600000, |
144 | }, |
145 | }; |
146 | |
147 | static int opt3001_find_scale(const struct opt3001 *opt, int val, |
148 | int val2, u8 *exponent) |
149 | { |
150 | int i; |
151 | |
152 | for (i = 0; i < ARRAY_SIZE(opt3001_scales); i++) { |
153 | const struct opt3001_scale *scale = &opt3001_scales[i]; |
154 | |
155 | /* |
156 | * Combine the integer and micro parts for comparison |
157 | * purposes. Use milli lux precision to avoid 32-bit integer |
158 | * overflows. |
159 | */ |
160 | if ((val * 1000 + val2 / 1000) <= |
161 | (scale->val * 1000 + scale->val2 / 1000)) { |
162 | *exponent = i; |
163 | return 0; |
164 | } |
165 | } |
166 | |
167 | return -EINVAL; |
168 | } |
169 | |
170 | static void opt3001_to_iio_ret(struct opt3001 *opt, u8 exponent, |
171 | u16 mantissa, int *val, int *val2) |
172 | { |
173 | int lux; |
174 | |
175 | lux = 10 * (mantissa << exponent); |
176 | *val = lux / 1000; |
177 | *val2 = (lux - (*val * 1000)) * 1000; |
178 | } |
179 | |
180 | static void opt3001_set_mode(struct opt3001 *opt, u16 *reg, u16 mode) |
181 | { |
182 | *reg &= ~OPT3001_CONFIGURATION_M_MASK; |
183 | *reg |= mode; |
184 | opt->mode = mode; |
185 | } |
186 | |
187 | static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.8" ); |
188 | |
189 | static struct attribute *opt3001_attributes[] = { |
190 | &iio_const_attr_integration_time_available.dev_attr.attr, |
191 | NULL |
192 | }; |
193 | |
194 | static const struct attribute_group opt3001_attribute_group = { |
195 | .attrs = opt3001_attributes, |
196 | }; |
197 | |
198 | static const struct iio_event_spec opt3001_event_spec[] = { |
199 | { |
200 | .type = IIO_EV_TYPE_THRESH, |
201 | .dir = IIO_EV_DIR_RISING, |
202 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
203 | BIT(IIO_EV_INFO_ENABLE), |
204 | }, |
205 | { |
206 | .type = IIO_EV_TYPE_THRESH, |
207 | .dir = IIO_EV_DIR_FALLING, |
208 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
209 | BIT(IIO_EV_INFO_ENABLE), |
210 | }, |
211 | }; |
212 | |
213 | static const struct iio_chan_spec opt3001_channels[] = { |
214 | { |
215 | .type = IIO_LIGHT, |
216 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | |
217 | BIT(IIO_CHAN_INFO_INT_TIME), |
218 | .event_spec = opt3001_event_spec, |
219 | .num_event_specs = ARRAY_SIZE(opt3001_event_spec), |
220 | }, |
221 | IIO_CHAN_SOFT_TIMESTAMP(1), |
222 | }; |
223 | |
224 | static int opt3001_get_lux(struct opt3001 *opt, int *val, int *val2) |
225 | { |
226 | int ret; |
227 | u16 mantissa; |
228 | u16 reg; |
229 | u8 exponent; |
230 | u16 value; |
231 | long timeout; |
232 | |
233 | if (opt->use_irq) { |
234 | /* |
235 | * Enable the end-of-conversion interrupt mechanism. Note that |
236 | * doing so will overwrite the low-level limit value however we |
237 | * will restore this value later on. |
238 | */ |
239 | ret = i2c_smbus_write_word_swapped(client: opt->client, |
240 | OPT3001_LOW_LIMIT, |
241 | OPT3001_LOW_LIMIT_EOC_ENABLE); |
242 | if (ret < 0) { |
243 | dev_err(opt->dev, "failed to write register %02x\n" , |
244 | OPT3001_LOW_LIMIT); |
245 | return ret; |
246 | } |
247 | |
248 | /* Allow IRQ to access the device despite lock being set */ |
249 | opt->ok_to_ignore_lock = true; |
250 | } |
251 | |
252 | /* Reset data-ready indicator flag */ |
253 | opt->result_ready = false; |
254 | |
255 | /* Configure for single-conversion mode and start a new conversion */ |
256 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
257 | if (ret < 0) { |
258 | dev_err(opt->dev, "failed to read register %02x\n" , |
259 | OPT3001_CONFIGURATION); |
260 | goto err; |
261 | } |
262 | |
263 | reg = ret; |
264 | opt3001_set_mode(opt, reg: ®, OPT3001_CONFIGURATION_M_SINGLE); |
265 | |
266 | ret = i2c_smbus_write_word_swapped(client: opt->client, OPT3001_CONFIGURATION, |
267 | value: reg); |
268 | if (ret < 0) { |
269 | dev_err(opt->dev, "failed to write register %02x\n" , |
270 | OPT3001_CONFIGURATION); |
271 | goto err; |
272 | } |
273 | |
274 | if (opt->use_irq) { |
275 | /* Wait for the IRQ to indicate the conversion is complete */ |
276 | ret = wait_event_timeout(opt->result_ready_queue, |
277 | opt->result_ready, |
278 | msecs_to_jiffies(OPT3001_RESULT_READY_LONG)); |
279 | if (ret == 0) |
280 | return -ETIMEDOUT; |
281 | } else { |
282 | /* Sleep for result ready time */ |
283 | timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ? |
284 | OPT3001_RESULT_READY_SHORT : OPT3001_RESULT_READY_LONG; |
285 | msleep(msecs: timeout); |
286 | |
287 | /* Check result ready flag */ |
288 | ret = i2c_smbus_read_word_swapped(client: opt->client, |
289 | OPT3001_CONFIGURATION); |
290 | if (ret < 0) { |
291 | dev_err(opt->dev, "failed to read register %02x\n" , |
292 | OPT3001_CONFIGURATION); |
293 | goto err; |
294 | } |
295 | |
296 | if (!(ret & OPT3001_CONFIGURATION_CRF)) { |
297 | ret = -ETIMEDOUT; |
298 | goto err; |
299 | } |
300 | |
301 | /* Obtain value */ |
302 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_RESULT); |
303 | if (ret < 0) { |
304 | dev_err(opt->dev, "failed to read register %02x\n" , |
305 | OPT3001_RESULT); |
306 | goto err; |
307 | } |
308 | opt->result = ret; |
309 | opt->result_ready = true; |
310 | } |
311 | |
312 | err: |
313 | if (opt->use_irq) |
314 | /* Disallow IRQ to access the device while lock is active */ |
315 | opt->ok_to_ignore_lock = false; |
316 | |
317 | if (ret < 0) |
318 | return ret; |
319 | |
320 | if (opt->use_irq) { |
321 | /* |
322 | * Disable the end-of-conversion interrupt mechanism by |
323 | * restoring the low-level limit value (clearing |
324 | * OPT3001_LOW_LIMIT_EOC_ENABLE). Note that selectively clearing |
325 | * those enable bits would affect the actual limit value due to |
326 | * bit-overlap and therefore can't be done. |
327 | */ |
328 | value = (opt->low_thresh_exp << 12) | opt->low_thresh_mantissa; |
329 | ret = i2c_smbus_write_word_swapped(client: opt->client, |
330 | OPT3001_LOW_LIMIT, |
331 | value); |
332 | if (ret < 0) { |
333 | dev_err(opt->dev, "failed to write register %02x\n" , |
334 | OPT3001_LOW_LIMIT); |
335 | return ret; |
336 | } |
337 | } |
338 | |
339 | exponent = OPT3001_REG_EXPONENT(opt->result); |
340 | mantissa = OPT3001_REG_MANTISSA(opt->result); |
341 | |
342 | opt3001_to_iio_ret(opt, exponent, mantissa, val, val2); |
343 | |
344 | return IIO_VAL_INT_PLUS_MICRO; |
345 | } |
346 | |
347 | static int opt3001_get_int_time(struct opt3001 *opt, int *val, int *val2) |
348 | { |
349 | *val = 0; |
350 | *val2 = opt->int_time; |
351 | |
352 | return IIO_VAL_INT_PLUS_MICRO; |
353 | } |
354 | |
355 | static int opt3001_set_int_time(struct opt3001 *opt, int time) |
356 | { |
357 | int ret; |
358 | u16 reg; |
359 | |
360 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
361 | if (ret < 0) { |
362 | dev_err(opt->dev, "failed to read register %02x\n" , |
363 | OPT3001_CONFIGURATION); |
364 | return ret; |
365 | } |
366 | |
367 | reg = ret; |
368 | |
369 | switch (time) { |
370 | case OPT3001_INT_TIME_SHORT: |
371 | reg &= ~OPT3001_CONFIGURATION_CT; |
372 | opt->int_time = OPT3001_INT_TIME_SHORT; |
373 | break; |
374 | case OPT3001_INT_TIME_LONG: |
375 | reg |= OPT3001_CONFIGURATION_CT; |
376 | opt->int_time = OPT3001_INT_TIME_LONG; |
377 | break; |
378 | default: |
379 | return -EINVAL; |
380 | } |
381 | |
382 | return i2c_smbus_write_word_swapped(client: opt->client, OPT3001_CONFIGURATION, |
383 | value: reg); |
384 | } |
385 | |
386 | static int opt3001_read_raw(struct iio_dev *iio, |
387 | struct iio_chan_spec const *chan, int *val, int *val2, |
388 | long mask) |
389 | { |
390 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
391 | int ret; |
392 | |
393 | if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) |
394 | return -EBUSY; |
395 | |
396 | if (chan->type != IIO_LIGHT) |
397 | return -EINVAL; |
398 | |
399 | mutex_lock(&opt->lock); |
400 | |
401 | switch (mask) { |
402 | case IIO_CHAN_INFO_PROCESSED: |
403 | ret = opt3001_get_lux(opt, val, val2); |
404 | break; |
405 | case IIO_CHAN_INFO_INT_TIME: |
406 | ret = opt3001_get_int_time(opt, val, val2); |
407 | break; |
408 | default: |
409 | ret = -EINVAL; |
410 | } |
411 | |
412 | mutex_unlock(lock: &opt->lock); |
413 | |
414 | return ret; |
415 | } |
416 | |
417 | static int opt3001_write_raw(struct iio_dev *iio, |
418 | struct iio_chan_spec const *chan, int val, int val2, |
419 | long mask) |
420 | { |
421 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
422 | int ret; |
423 | |
424 | if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) |
425 | return -EBUSY; |
426 | |
427 | if (chan->type != IIO_LIGHT) |
428 | return -EINVAL; |
429 | |
430 | if (mask != IIO_CHAN_INFO_INT_TIME) |
431 | return -EINVAL; |
432 | |
433 | if (val != 0) |
434 | return -EINVAL; |
435 | |
436 | mutex_lock(&opt->lock); |
437 | ret = opt3001_set_int_time(opt, time: val2); |
438 | mutex_unlock(lock: &opt->lock); |
439 | |
440 | return ret; |
441 | } |
442 | |
443 | static int opt3001_read_event_value(struct iio_dev *iio, |
444 | const struct iio_chan_spec *chan, enum iio_event_type type, |
445 | enum iio_event_direction dir, enum iio_event_info info, |
446 | int *val, int *val2) |
447 | { |
448 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
449 | int ret = IIO_VAL_INT_PLUS_MICRO; |
450 | |
451 | mutex_lock(&opt->lock); |
452 | |
453 | switch (dir) { |
454 | case IIO_EV_DIR_RISING: |
455 | opt3001_to_iio_ret(opt, exponent: opt->high_thresh_exp, |
456 | mantissa: opt->high_thresh_mantissa, val, val2); |
457 | break; |
458 | case IIO_EV_DIR_FALLING: |
459 | opt3001_to_iio_ret(opt, exponent: opt->low_thresh_exp, |
460 | mantissa: opt->low_thresh_mantissa, val, val2); |
461 | break; |
462 | default: |
463 | ret = -EINVAL; |
464 | } |
465 | |
466 | mutex_unlock(lock: &opt->lock); |
467 | |
468 | return ret; |
469 | } |
470 | |
471 | static int opt3001_write_event_value(struct iio_dev *iio, |
472 | const struct iio_chan_spec *chan, enum iio_event_type type, |
473 | enum iio_event_direction dir, enum iio_event_info info, |
474 | int val, int val2) |
475 | { |
476 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
477 | int ret; |
478 | |
479 | u16 mantissa; |
480 | u16 value; |
481 | u16 reg; |
482 | |
483 | u8 exponent; |
484 | |
485 | if (val < 0) |
486 | return -EINVAL; |
487 | |
488 | mutex_lock(&opt->lock); |
489 | |
490 | ret = opt3001_find_scale(opt, val, val2, exponent: &exponent); |
491 | if (ret < 0) { |
492 | dev_err(opt->dev, "can't find scale for %d.%06u\n" , val, val2); |
493 | goto err; |
494 | } |
495 | |
496 | mantissa = (((val * 1000) + (val2 / 1000)) / 10) >> exponent; |
497 | value = (exponent << 12) | mantissa; |
498 | |
499 | switch (dir) { |
500 | case IIO_EV_DIR_RISING: |
501 | reg = OPT3001_HIGH_LIMIT; |
502 | opt->high_thresh_mantissa = mantissa; |
503 | opt->high_thresh_exp = exponent; |
504 | break; |
505 | case IIO_EV_DIR_FALLING: |
506 | reg = OPT3001_LOW_LIMIT; |
507 | opt->low_thresh_mantissa = mantissa; |
508 | opt->low_thresh_exp = exponent; |
509 | break; |
510 | default: |
511 | ret = -EINVAL; |
512 | goto err; |
513 | } |
514 | |
515 | ret = i2c_smbus_write_word_swapped(client: opt->client, command: reg, value); |
516 | if (ret < 0) { |
517 | dev_err(opt->dev, "failed to write register %02x\n" , reg); |
518 | goto err; |
519 | } |
520 | |
521 | err: |
522 | mutex_unlock(lock: &opt->lock); |
523 | |
524 | return ret; |
525 | } |
526 | |
527 | static int opt3001_read_event_config(struct iio_dev *iio, |
528 | const struct iio_chan_spec *chan, enum iio_event_type type, |
529 | enum iio_event_direction dir) |
530 | { |
531 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
532 | |
533 | return opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS; |
534 | } |
535 | |
536 | static int opt3001_write_event_config(struct iio_dev *iio, |
537 | const struct iio_chan_spec *chan, enum iio_event_type type, |
538 | enum iio_event_direction dir, int state) |
539 | { |
540 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
541 | int ret; |
542 | u16 mode; |
543 | u16 reg; |
544 | |
545 | if (state && opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) |
546 | return 0; |
547 | |
548 | if (!state && opt->mode == OPT3001_CONFIGURATION_M_SHUTDOWN) |
549 | return 0; |
550 | |
551 | mutex_lock(&opt->lock); |
552 | |
553 | mode = state ? OPT3001_CONFIGURATION_M_CONTINUOUS |
554 | : OPT3001_CONFIGURATION_M_SHUTDOWN; |
555 | |
556 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
557 | if (ret < 0) { |
558 | dev_err(opt->dev, "failed to read register %02x\n" , |
559 | OPT3001_CONFIGURATION); |
560 | goto err; |
561 | } |
562 | |
563 | reg = ret; |
564 | opt3001_set_mode(opt, reg: ®, mode); |
565 | |
566 | ret = i2c_smbus_write_word_swapped(client: opt->client, OPT3001_CONFIGURATION, |
567 | value: reg); |
568 | if (ret < 0) { |
569 | dev_err(opt->dev, "failed to write register %02x\n" , |
570 | OPT3001_CONFIGURATION); |
571 | goto err; |
572 | } |
573 | |
574 | err: |
575 | mutex_unlock(lock: &opt->lock); |
576 | |
577 | return ret; |
578 | } |
579 | |
580 | static const struct iio_info opt3001_info = { |
581 | .attrs = &opt3001_attribute_group, |
582 | .read_raw = opt3001_read_raw, |
583 | .write_raw = opt3001_write_raw, |
584 | .read_event_value = opt3001_read_event_value, |
585 | .write_event_value = opt3001_write_event_value, |
586 | .read_event_config = opt3001_read_event_config, |
587 | .write_event_config = opt3001_write_event_config, |
588 | }; |
589 | |
590 | static int opt3001_read_id(struct opt3001 *opt) |
591 | { |
592 | char manufacturer[2]; |
593 | u16 device_id; |
594 | int ret; |
595 | |
596 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_MANUFACTURER_ID); |
597 | if (ret < 0) { |
598 | dev_err(opt->dev, "failed to read register %02x\n" , |
599 | OPT3001_MANUFACTURER_ID); |
600 | return ret; |
601 | } |
602 | |
603 | manufacturer[0] = ret >> 8; |
604 | manufacturer[1] = ret & 0xff; |
605 | |
606 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_DEVICE_ID); |
607 | if (ret < 0) { |
608 | dev_err(opt->dev, "failed to read register %02x\n" , |
609 | OPT3001_DEVICE_ID); |
610 | return ret; |
611 | } |
612 | |
613 | device_id = ret; |
614 | |
615 | dev_info(opt->dev, "Found %c%c OPT%04x\n" , manufacturer[0], |
616 | manufacturer[1], device_id); |
617 | |
618 | return 0; |
619 | } |
620 | |
621 | static int opt3001_configure(struct opt3001 *opt) |
622 | { |
623 | int ret; |
624 | u16 reg; |
625 | |
626 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
627 | if (ret < 0) { |
628 | dev_err(opt->dev, "failed to read register %02x\n" , |
629 | OPT3001_CONFIGURATION); |
630 | return ret; |
631 | } |
632 | |
633 | reg = ret; |
634 | |
635 | /* Enable automatic full-scale setting mode */ |
636 | reg &= ~OPT3001_CONFIGURATION_RN_MASK; |
637 | reg |= OPT3001_CONFIGURATION_RN_AUTO; |
638 | |
639 | /* Reflect status of the device's integration time setting */ |
640 | if (reg & OPT3001_CONFIGURATION_CT) |
641 | opt->int_time = OPT3001_INT_TIME_LONG; |
642 | else |
643 | opt->int_time = OPT3001_INT_TIME_SHORT; |
644 | |
645 | /* Ensure device is in shutdown initially */ |
646 | opt3001_set_mode(opt, reg: ®, OPT3001_CONFIGURATION_M_SHUTDOWN); |
647 | |
648 | /* Configure for latched window-style comparison operation */ |
649 | reg |= OPT3001_CONFIGURATION_L; |
650 | reg &= ~OPT3001_CONFIGURATION_POL; |
651 | reg &= ~OPT3001_CONFIGURATION_ME; |
652 | reg &= ~OPT3001_CONFIGURATION_FC_MASK; |
653 | |
654 | ret = i2c_smbus_write_word_swapped(client: opt->client, OPT3001_CONFIGURATION, |
655 | value: reg); |
656 | if (ret < 0) { |
657 | dev_err(opt->dev, "failed to write register %02x\n" , |
658 | OPT3001_CONFIGURATION); |
659 | return ret; |
660 | } |
661 | |
662 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_LOW_LIMIT); |
663 | if (ret < 0) { |
664 | dev_err(opt->dev, "failed to read register %02x\n" , |
665 | OPT3001_LOW_LIMIT); |
666 | return ret; |
667 | } |
668 | |
669 | opt->low_thresh_mantissa = OPT3001_REG_MANTISSA(ret); |
670 | opt->low_thresh_exp = OPT3001_REG_EXPONENT(ret); |
671 | |
672 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_HIGH_LIMIT); |
673 | if (ret < 0) { |
674 | dev_err(opt->dev, "failed to read register %02x\n" , |
675 | OPT3001_HIGH_LIMIT); |
676 | return ret; |
677 | } |
678 | |
679 | opt->high_thresh_mantissa = OPT3001_REG_MANTISSA(ret); |
680 | opt->high_thresh_exp = OPT3001_REG_EXPONENT(ret); |
681 | |
682 | return 0; |
683 | } |
684 | |
685 | static irqreturn_t opt3001_irq(int irq, void *_iio) |
686 | { |
687 | struct iio_dev *iio = _iio; |
688 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
689 | int ret; |
690 | bool wake_result_ready_queue = false; |
691 | |
692 | if (!opt->ok_to_ignore_lock) |
693 | mutex_lock(&opt->lock); |
694 | |
695 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
696 | if (ret < 0) { |
697 | dev_err(opt->dev, "failed to read register %02x\n" , |
698 | OPT3001_CONFIGURATION); |
699 | goto out; |
700 | } |
701 | |
702 | if ((ret & OPT3001_CONFIGURATION_M_MASK) == |
703 | OPT3001_CONFIGURATION_M_CONTINUOUS) { |
704 | if (ret & OPT3001_CONFIGURATION_FH) |
705 | iio_push_event(indio_dev: iio, |
706 | IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, |
707 | IIO_EV_TYPE_THRESH, |
708 | IIO_EV_DIR_RISING), |
709 | timestamp: iio_get_time_ns(indio_dev: iio)); |
710 | if (ret & OPT3001_CONFIGURATION_FL) |
711 | iio_push_event(indio_dev: iio, |
712 | IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, |
713 | IIO_EV_TYPE_THRESH, |
714 | IIO_EV_DIR_FALLING), |
715 | timestamp: iio_get_time_ns(indio_dev: iio)); |
716 | } else if (ret & OPT3001_CONFIGURATION_CRF) { |
717 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_RESULT); |
718 | if (ret < 0) { |
719 | dev_err(opt->dev, "failed to read register %02x\n" , |
720 | OPT3001_RESULT); |
721 | goto out; |
722 | } |
723 | opt->result = ret; |
724 | opt->result_ready = true; |
725 | wake_result_ready_queue = true; |
726 | } |
727 | |
728 | out: |
729 | if (!opt->ok_to_ignore_lock) |
730 | mutex_unlock(lock: &opt->lock); |
731 | |
732 | if (wake_result_ready_queue) |
733 | wake_up(&opt->result_ready_queue); |
734 | |
735 | return IRQ_HANDLED; |
736 | } |
737 | |
738 | static int opt3001_probe(struct i2c_client *client) |
739 | { |
740 | struct device *dev = &client->dev; |
741 | |
742 | struct iio_dev *iio; |
743 | struct opt3001 *opt; |
744 | int irq = client->irq; |
745 | int ret; |
746 | |
747 | iio = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*opt)); |
748 | if (!iio) |
749 | return -ENOMEM; |
750 | |
751 | opt = iio_priv(indio_dev: iio); |
752 | opt->client = client; |
753 | opt->dev = dev; |
754 | |
755 | mutex_init(&opt->lock); |
756 | init_waitqueue_head(&opt->result_ready_queue); |
757 | i2c_set_clientdata(client, data: iio); |
758 | |
759 | ret = opt3001_read_id(opt); |
760 | if (ret) |
761 | return ret; |
762 | |
763 | ret = opt3001_configure(opt); |
764 | if (ret) |
765 | return ret; |
766 | |
767 | iio->name = client->name; |
768 | iio->channels = opt3001_channels; |
769 | iio->num_channels = ARRAY_SIZE(opt3001_channels); |
770 | iio->modes = INDIO_DIRECT_MODE; |
771 | iio->info = &opt3001_info; |
772 | |
773 | ret = devm_iio_device_register(dev, iio); |
774 | if (ret) { |
775 | dev_err(dev, "failed to register IIO device\n" ); |
776 | return ret; |
777 | } |
778 | |
779 | /* Make use of INT pin only if valid IRQ no. is given */ |
780 | if (irq > 0) { |
781 | ret = request_threaded_irq(irq, NULL, thread_fn: opt3001_irq, |
782 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
783 | name: "opt3001" , dev: iio); |
784 | if (ret) { |
785 | dev_err(dev, "failed to request IRQ #%d\n" , irq); |
786 | return ret; |
787 | } |
788 | opt->use_irq = true; |
789 | } else { |
790 | dev_dbg(opt->dev, "enabling interrupt-less operation\n" ); |
791 | } |
792 | |
793 | return 0; |
794 | } |
795 | |
796 | static void opt3001_remove(struct i2c_client *client) |
797 | { |
798 | struct iio_dev *iio = i2c_get_clientdata(client); |
799 | struct opt3001 *opt = iio_priv(indio_dev: iio); |
800 | int ret; |
801 | u16 reg; |
802 | |
803 | if (opt->use_irq) |
804 | free_irq(client->irq, iio); |
805 | |
806 | ret = i2c_smbus_read_word_swapped(client: opt->client, OPT3001_CONFIGURATION); |
807 | if (ret < 0) { |
808 | dev_err(opt->dev, "failed to read register %02x\n" , |
809 | OPT3001_CONFIGURATION); |
810 | return; |
811 | } |
812 | |
813 | reg = ret; |
814 | opt3001_set_mode(opt, reg: ®, OPT3001_CONFIGURATION_M_SHUTDOWN); |
815 | |
816 | ret = i2c_smbus_write_word_swapped(client: opt->client, OPT3001_CONFIGURATION, |
817 | value: reg); |
818 | if (ret < 0) { |
819 | dev_err(opt->dev, "failed to write register %02x\n" , |
820 | OPT3001_CONFIGURATION); |
821 | } |
822 | } |
823 | |
824 | static const struct i2c_device_id opt3001_id[] = { |
825 | { "opt3001" , 0 }, |
826 | { } /* Terminating Entry */ |
827 | }; |
828 | MODULE_DEVICE_TABLE(i2c, opt3001_id); |
829 | |
830 | static const struct of_device_id opt3001_of_match[] = { |
831 | { .compatible = "ti,opt3001" }, |
832 | { } |
833 | }; |
834 | MODULE_DEVICE_TABLE(of, opt3001_of_match); |
835 | |
836 | static struct i2c_driver opt3001_driver = { |
837 | .probe = opt3001_probe, |
838 | .remove = opt3001_remove, |
839 | .id_table = opt3001_id, |
840 | |
841 | .driver = { |
842 | .name = "opt3001" , |
843 | .of_match_table = opt3001_of_match, |
844 | }, |
845 | }; |
846 | |
847 | module_i2c_driver(opt3001_driver); |
848 | |
849 | MODULE_LICENSE("GPL v2" ); |
850 | MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>" ); |
851 | MODULE_DESCRIPTION("Texas Instruments OPT3001 Light Sensor Driver" ); |
852 | |