1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * LTRF216A Ambient Light Sensor |
4 | * |
5 | * Copyright (C) 2022 Collabora, Ltd. |
6 | * Author: Shreeya Patel <shreeya.patel@collabora.com> |
7 | * |
8 | * Copyright (C) 2021 Lite-On Technology Corp (Singapore) |
9 | * Author: Shi Zhigang <Zhigang.Shi@liteon.com> |
10 | * |
11 | * IIO driver for LTRF216A (7-bit I2C slave address 0x53). |
12 | */ |
13 | |
14 | #include <linux/bitfield.h> |
15 | #include <linux/bits.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/init.h> |
19 | #include <linux/iopoll.h> |
20 | #include <linux/mod_devicetable.h> |
21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> |
23 | #include <linux/pm.h> |
24 | #include <linux/pm_runtime.h> |
25 | #include <linux/regmap.h> |
26 | |
27 | #include <linux/iio/iio.h> |
28 | |
29 | #include <asm/unaligned.h> |
30 | |
31 | #define LTRF216A_ALS_RESET_MASK BIT(4) |
32 | #define LTRF216A_ALS_DATA_STATUS BIT(3) |
33 | #define LTRF216A_ALS_ENABLE_MASK BIT(1) |
34 | #define LTRF216A_MAIN_CTRL 0x00 |
35 | #define LTRF216A_ALS_MEAS_RES 0x04 |
36 | #define LTRF216A_ALS_GAIN 0x05 |
37 | #define LTRF216A_PART_ID 0x06 |
38 | #define LTRF216A_MAIN_STATUS 0x07 |
39 | #define LTRF216A_ALS_CLEAR_DATA_0 0x0a |
40 | #define LTRF216A_ALS_CLEAR_DATA_1 0x0b |
41 | #define LTRF216A_ALS_CLEAR_DATA_2 0x0c |
42 | #define LTRF216A_ALS_DATA_0 0x0d |
43 | #define LTRF216A_ALS_DATA_1 0x0e |
44 | #define LTRF216A_ALS_DATA_2 0x0f |
45 | #define LTRF216A_INT_CFG 0x19 |
46 | #define LTRF216A_INT_PST 0x1a |
47 | #define LTRF216A_ALS_THRES_UP_0 0x21 |
48 | #define LTRF216A_ALS_THRES_UP_1 0x22 |
49 | #define LTRF216A_ALS_THRES_UP_2 0x23 |
50 | #define LTRF216A_ALS_THRES_LOW_0 0x24 |
51 | #define LTRF216A_ALS_THRES_LOW_1 0x25 |
52 | #define LTRF216A_ALS_THRES_LOW_2 0x26 |
53 | #define LTRF216A_ALS_READ_DATA_DELAY_US 20000 |
54 | |
55 | static const int ltrf216a_int_time_available[][2] = { |
56 | { 0, 400000 }, |
57 | { 0, 200000 }, |
58 | { 0, 100000 }, |
59 | { 0, 50000 }, |
60 | { 0, 25000 }, |
61 | }; |
62 | |
63 | static const int ltrf216a_int_time_reg[][2] = { |
64 | { 400, 0x03 }, |
65 | { 200, 0x13 }, |
66 | { 100, 0x22 }, |
67 | { 50, 0x31 }, |
68 | { 25, 0x40 }, |
69 | }; |
70 | |
71 | /* |
72 | * Window Factor is needed when the device is under Window glass |
73 | * with coated tinted ink. This is to compensate for the light loss |
74 | * due to the lower transmission rate of the window glass and helps |
75 | * in calculating lux. |
76 | */ |
77 | #define LTRF216A_WIN_FAC 1 |
78 | |
79 | struct ltrf216a_data { |
80 | struct regmap *regmap; |
81 | struct i2c_client *client; |
82 | u32 int_time; |
83 | u16 int_time_fac; |
84 | u8 als_gain_fac; |
85 | /* |
86 | * Protects regmap accesses and makes sure integration time |
87 | * remains constant during the measurement of lux. |
88 | */ |
89 | struct mutex lock; |
90 | }; |
91 | |
92 | static const struct iio_chan_spec ltrf216a_channels[] = { |
93 | { |
94 | .type = IIO_LIGHT, |
95 | .info_mask_separate = |
96 | BIT(IIO_CHAN_INFO_RAW) | |
97 | BIT(IIO_CHAN_INFO_PROCESSED) | |
98 | BIT(IIO_CHAN_INFO_INT_TIME), |
99 | .info_mask_separate_available = |
100 | BIT(IIO_CHAN_INFO_INT_TIME), |
101 | }, |
102 | }; |
103 | |
104 | static void ltrf216a_reset(struct iio_dev *indio_dev) |
105 | { |
106 | struct ltrf216a_data *data = iio_priv(indio_dev); |
107 | |
108 | /* reset sensor, chip fails to respond to this, so ignore any errors */ |
109 | regmap_write(map: data->regmap, LTRF216A_MAIN_CTRL, LTRF216A_ALS_RESET_MASK); |
110 | |
111 | /* reset time */ |
112 | usleep_range(min: 1000, max: 2000); |
113 | } |
114 | |
115 | static int ltrf216a_enable(struct iio_dev *indio_dev) |
116 | { |
117 | struct ltrf216a_data *data = iio_priv(indio_dev); |
118 | struct device *dev = &data->client->dev; |
119 | int ret; |
120 | |
121 | /* enable sensor */ |
122 | ret = regmap_set_bits(map: data->regmap, |
123 | LTRF216A_MAIN_CTRL, LTRF216A_ALS_ENABLE_MASK); |
124 | if (ret) { |
125 | dev_err(dev, "failed to enable sensor: %d\n" , ret); |
126 | return ret; |
127 | } |
128 | |
129 | /* sleep for one integration cycle after enabling the device */ |
130 | msleep(msecs: ltrf216a_int_time_reg[0][0]); |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | static int ltrf216a_disable(struct iio_dev *indio_dev) |
136 | { |
137 | struct ltrf216a_data *data = iio_priv(indio_dev); |
138 | struct device *dev = &data->client->dev; |
139 | int ret; |
140 | |
141 | ret = regmap_write(map: data->regmap, LTRF216A_MAIN_CTRL, val: 0); |
142 | if (ret) |
143 | dev_err(dev, "failed to disable sensor: %d\n" , ret); |
144 | |
145 | return ret; |
146 | } |
147 | |
148 | static void ltrf216a_cleanup(void *data) |
149 | { |
150 | struct iio_dev *indio_dev = data; |
151 | |
152 | ltrf216a_disable(indio_dev); |
153 | } |
154 | |
155 | static int ltrf216a_set_int_time(struct ltrf216a_data *data, int itime) |
156 | { |
157 | struct device *dev = &data->client->dev; |
158 | unsigned int i; |
159 | u8 reg_val; |
160 | int ret; |
161 | |
162 | for (i = 0; i < ARRAY_SIZE(ltrf216a_int_time_available); i++) { |
163 | if (ltrf216a_int_time_available[i][1] == itime) |
164 | break; |
165 | } |
166 | if (i == ARRAY_SIZE(ltrf216a_int_time_available)) |
167 | return -EINVAL; |
168 | |
169 | reg_val = ltrf216a_int_time_reg[i][1]; |
170 | |
171 | ret = regmap_write(map: data->regmap, LTRF216A_ALS_MEAS_RES, val: reg_val); |
172 | if (ret) { |
173 | dev_err(dev, "failed to set integration time: %d\n" , ret); |
174 | return ret; |
175 | } |
176 | |
177 | data->int_time_fac = ltrf216a_int_time_reg[i][0]; |
178 | data->int_time = itime; |
179 | |
180 | return 0; |
181 | } |
182 | |
183 | static int ltrf216a_get_int_time(struct ltrf216a_data *data, |
184 | int *val, int *val2) |
185 | { |
186 | *val = 0; |
187 | *val2 = data->int_time; |
188 | return IIO_VAL_INT_PLUS_MICRO; |
189 | } |
190 | |
191 | static int ltrf216a_set_power_state(struct ltrf216a_data *data, bool on) |
192 | { |
193 | struct device *dev = &data->client->dev; |
194 | int ret = 0; |
195 | |
196 | if (on) { |
197 | ret = pm_runtime_resume_and_get(dev); |
198 | if (ret) { |
199 | dev_err(dev, "failed to resume runtime PM: %d\n" , ret); |
200 | return ret; |
201 | } |
202 | } else { |
203 | pm_runtime_mark_last_busy(dev); |
204 | pm_runtime_put_autosuspend(dev); |
205 | } |
206 | |
207 | return ret; |
208 | } |
209 | |
210 | static int ltrf216a_read_data(struct ltrf216a_data *data, u8 addr) |
211 | { |
212 | struct device *dev = &data->client->dev; |
213 | int ret, val; |
214 | u8 buf[3]; |
215 | |
216 | ret = regmap_read_poll_timeout(data->regmap, LTRF216A_MAIN_STATUS, |
217 | val, val & LTRF216A_ALS_DATA_STATUS, |
218 | LTRF216A_ALS_READ_DATA_DELAY_US, |
219 | LTRF216A_ALS_READ_DATA_DELAY_US * 50); |
220 | if (ret) { |
221 | dev_err(dev, "failed to wait for measurement data: %d\n" , ret); |
222 | return ret; |
223 | } |
224 | |
225 | ret = regmap_bulk_read(map: data->regmap, reg: addr, val: buf, val_count: sizeof(buf)); |
226 | if (ret) { |
227 | dev_err(dev, "failed to read measurement data: %d\n" , ret); |
228 | return ret; |
229 | } |
230 | |
231 | return get_unaligned_le24(p: &buf[0]); |
232 | } |
233 | |
234 | static int ltrf216a_get_lux(struct ltrf216a_data *data) |
235 | { |
236 | int ret, greendata; |
237 | u64 lux; |
238 | |
239 | ret = ltrf216a_set_power_state(data, on: true); |
240 | if (ret) |
241 | return ret; |
242 | |
243 | greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0); |
244 | if (greendata < 0) |
245 | return greendata; |
246 | |
247 | ltrf216a_set_power_state(data, on: false); |
248 | |
249 | lux = greendata * 45 * LTRF216A_WIN_FAC; |
250 | |
251 | return lux; |
252 | } |
253 | |
254 | static int ltrf216a_read_raw(struct iio_dev *indio_dev, |
255 | struct iio_chan_spec const *chan, int *val, |
256 | int *val2, long mask) |
257 | { |
258 | struct ltrf216a_data *data = iio_priv(indio_dev); |
259 | int ret; |
260 | |
261 | switch (mask) { |
262 | case IIO_CHAN_INFO_RAW: |
263 | ret = ltrf216a_set_power_state(data, on: true); |
264 | if (ret) |
265 | return ret; |
266 | mutex_lock(&data->lock); |
267 | ret = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0); |
268 | mutex_unlock(lock: &data->lock); |
269 | ltrf216a_set_power_state(data, on: false); |
270 | if (ret < 0) |
271 | return ret; |
272 | *val = ret; |
273 | return IIO_VAL_INT; |
274 | case IIO_CHAN_INFO_PROCESSED: |
275 | mutex_lock(&data->lock); |
276 | ret = ltrf216a_get_lux(data); |
277 | mutex_unlock(lock: &data->lock); |
278 | if (ret < 0) |
279 | return ret; |
280 | *val = ret; |
281 | *val2 = data->als_gain_fac * data->int_time_fac; |
282 | return IIO_VAL_FRACTIONAL; |
283 | case IIO_CHAN_INFO_INT_TIME: |
284 | mutex_lock(&data->lock); |
285 | ret = ltrf216a_get_int_time(data, val, val2); |
286 | mutex_unlock(lock: &data->lock); |
287 | return ret; |
288 | default: |
289 | return -EINVAL; |
290 | } |
291 | } |
292 | |
293 | static int ltrf216a_write_raw(struct iio_dev *indio_dev, |
294 | struct iio_chan_spec const *chan, int val, |
295 | int val2, long mask) |
296 | { |
297 | struct ltrf216a_data *data = iio_priv(indio_dev); |
298 | int ret; |
299 | |
300 | switch (mask) { |
301 | case IIO_CHAN_INFO_INT_TIME: |
302 | if (val != 0) |
303 | return -EINVAL; |
304 | mutex_lock(&data->lock); |
305 | ret = ltrf216a_set_int_time(data, itime: val2); |
306 | mutex_unlock(lock: &data->lock); |
307 | return ret; |
308 | default: |
309 | return -EINVAL; |
310 | } |
311 | } |
312 | |
313 | static int ltrf216a_read_available(struct iio_dev *indio_dev, |
314 | struct iio_chan_spec const *chan, |
315 | const int **vals, int *type, int *length, |
316 | long mask) |
317 | { |
318 | switch (mask) { |
319 | case IIO_CHAN_INFO_INT_TIME: |
320 | *length = ARRAY_SIZE(ltrf216a_int_time_available) * 2; |
321 | *vals = (const int *)ltrf216a_int_time_available; |
322 | *type = IIO_VAL_INT_PLUS_MICRO; |
323 | return IIO_AVAIL_LIST; |
324 | default: |
325 | return -EINVAL; |
326 | } |
327 | } |
328 | |
329 | static const struct iio_info ltrf216a_info = { |
330 | .read_raw = ltrf216a_read_raw, |
331 | .write_raw = ltrf216a_write_raw, |
332 | .read_avail = ltrf216a_read_available, |
333 | }; |
334 | |
335 | static bool ltrf216a_readable_reg(struct device *dev, unsigned int reg) |
336 | { |
337 | switch (reg) { |
338 | case LTRF216A_MAIN_CTRL: |
339 | case LTRF216A_ALS_MEAS_RES: |
340 | case LTRF216A_ALS_GAIN: |
341 | case LTRF216A_PART_ID: |
342 | case LTRF216A_MAIN_STATUS: |
343 | case LTRF216A_ALS_CLEAR_DATA_0: |
344 | case LTRF216A_ALS_CLEAR_DATA_1: |
345 | case LTRF216A_ALS_CLEAR_DATA_2: |
346 | case LTRF216A_ALS_DATA_0: |
347 | case LTRF216A_ALS_DATA_1: |
348 | case LTRF216A_ALS_DATA_2: |
349 | case LTRF216A_INT_CFG: |
350 | case LTRF216A_INT_PST: |
351 | case LTRF216A_ALS_THRES_UP_0: |
352 | case LTRF216A_ALS_THRES_UP_1: |
353 | case LTRF216A_ALS_THRES_UP_2: |
354 | case LTRF216A_ALS_THRES_LOW_0: |
355 | case LTRF216A_ALS_THRES_LOW_1: |
356 | case LTRF216A_ALS_THRES_LOW_2: |
357 | return true; |
358 | default: |
359 | return false; |
360 | } |
361 | } |
362 | |
363 | static bool ltrf216a_writable_reg(struct device *dev, unsigned int reg) |
364 | { |
365 | switch (reg) { |
366 | case LTRF216A_MAIN_CTRL: |
367 | case LTRF216A_ALS_MEAS_RES: |
368 | case LTRF216A_ALS_GAIN: |
369 | case LTRF216A_INT_CFG: |
370 | case LTRF216A_INT_PST: |
371 | case LTRF216A_ALS_THRES_UP_0: |
372 | case LTRF216A_ALS_THRES_UP_1: |
373 | case LTRF216A_ALS_THRES_UP_2: |
374 | case LTRF216A_ALS_THRES_LOW_0: |
375 | case LTRF216A_ALS_THRES_LOW_1: |
376 | case LTRF216A_ALS_THRES_LOW_2: |
377 | return true; |
378 | default: |
379 | return false; |
380 | } |
381 | } |
382 | |
383 | static bool ltrf216a_volatile_reg(struct device *dev, unsigned int reg) |
384 | { |
385 | switch (reg) { |
386 | case LTRF216A_MAIN_STATUS: |
387 | case LTRF216A_ALS_CLEAR_DATA_0: |
388 | case LTRF216A_ALS_CLEAR_DATA_1: |
389 | case LTRF216A_ALS_CLEAR_DATA_2: |
390 | case LTRF216A_ALS_DATA_0: |
391 | case LTRF216A_ALS_DATA_1: |
392 | case LTRF216A_ALS_DATA_2: |
393 | return true; |
394 | default: |
395 | return false; |
396 | } |
397 | } |
398 | |
399 | static bool ltrf216a_precious_reg(struct device *dev, unsigned int reg) |
400 | { |
401 | return reg == LTRF216A_MAIN_STATUS; |
402 | } |
403 | |
404 | static const struct regmap_config ltrf216a_regmap_config = { |
405 | .name = "ltrf216a" , |
406 | .reg_bits = 8, |
407 | .val_bits = 8, |
408 | .cache_type = REGCACHE_RBTREE, |
409 | .max_register = LTRF216A_ALS_THRES_LOW_2, |
410 | .readable_reg = ltrf216a_readable_reg, |
411 | .writeable_reg = ltrf216a_writable_reg, |
412 | .volatile_reg = ltrf216a_volatile_reg, |
413 | .precious_reg = ltrf216a_precious_reg, |
414 | .disable_locking = true, |
415 | }; |
416 | |
417 | static int ltrf216a_probe(struct i2c_client *client) |
418 | { |
419 | struct ltrf216a_data *data; |
420 | struct iio_dev *indio_dev; |
421 | int ret; |
422 | |
423 | indio_dev = devm_iio_device_alloc(parent: &client->dev, sizeof_priv: sizeof(*data)); |
424 | if (!indio_dev) |
425 | return -ENOMEM; |
426 | |
427 | data = iio_priv(indio_dev); |
428 | |
429 | data->regmap = devm_regmap_init_i2c(client, <rf216a_regmap_config); |
430 | if (IS_ERR(ptr: data->regmap)) |
431 | return dev_err_probe(dev: &client->dev, err: PTR_ERR(ptr: data->regmap), |
432 | fmt: "regmap initialization failed\n" ); |
433 | |
434 | i2c_set_clientdata(client, data: indio_dev); |
435 | data->client = client; |
436 | |
437 | mutex_init(&data->lock); |
438 | |
439 | indio_dev->info = <rf216a_info; |
440 | indio_dev->name = "ltrf216a" ; |
441 | indio_dev->channels = ltrf216a_channels; |
442 | indio_dev->num_channels = ARRAY_SIZE(ltrf216a_channels); |
443 | indio_dev->modes = INDIO_DIRECT_MODE; |
444 | |
445 | ret = pm_runtime_set_active(dev: &client->dev); |
446 | if (ret) |
447 | return ret; |
448 | |
449 | /* reset sensor, chip fails to respond to this, so ignore any errors */ |
450 | ltrf216a_reset(indio_dev); |
451 | |
452 | ret = regmap_reinit_cache(map: data->regmap, config: <rf216a_regmap_config); |
453 | if (ret) |
454 | return dev_err_probe(dev: &client->dev, err: ret, |
455 | fmt: "failed to reinit regmap cache\n" ); |
456 | |
457 | ret = ltrf216a_enable(indio_dev); |
458 | if (ret) |
459 | return ret; |
460 | |
461 | ret = devm_add_action_or_reset(&client->dev, ltrf216a_cleanup, |
462 | indio_dev); |
463 | if (ret) |
464 | return ret; |
465 | |
466 | ret = devm_pm_runtime_enable(dev: &client->dev); |
467 | if (ret) |
468 | return dev_err_probe(dev: &client->dev, err: ret, |
469 | fmt: "failed to enable runtime PM\n" ); |
470 | |
471 | pm_runtime_set_autosuspend_delay(dev: &client->dev, delay: 1000); |
472 | pm_runtime_use_autosuspend(dev: &client->dev); |
473 | |
474 | data->int_time = 100000; |
475 | data->int_time_fac = 100; |
476 | data->als_gain_fac = 3; |
477 | |
478 | return devm_iio_device_register(&client->dev, indio_dev); |
479 | } |
480 | |
481 | static int ltrf216a_runtime_suspend(struct device *dev) |
482 | { |
483 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
484 | struct ltrf216a_data *data = iio_priv(indio_dev); |
485 | int ret; |
486 | |
487 | ret = ltrf216a_disable(indio_dev); |
488 | if (ret) |
489 | return ret; |
490 | |
491 | regcache_cache_only(map: data->regmap, enable: true); |
492 | |
493 | return 0; |
494 | } |
495 | |
496 | static int ltrf216a_runtime_resume(struct device *dev) |
497 | { |
498 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
499 | struct ltrf216a_data *data = iio_priv(indio_dev); |
500 | int ret; |
501 | |
502 | regcache_cache_only(map: data->regmap, enable: false); |
503 | regcache_mark_dirty(map: data->regmap); |
504 | ret = regcache_sync(map: data->regmap); |
505 | if (ret) |
506 | goto cache_only; |
507 | |
508 | ret = ltrf216a_enable(indio_dev); |
509 | if (ret) |
510 | goto cache_only; |
511 | |
512 | return 0; |
513 | |
514 | cache_only: |
515 | regcache_cache_only(map: data->regmap, enable: true); |
516 | |
517 | return ret; |
518 | } |
519 | |
520 | static DEFINE_RUNTIME_DEV_PM_OPS(ltrf216a_pm_ops, ltrf216a_runtime_suspend, |
521 | ltrf216a_runtime_resume, NULL); |
522 | |
523 | static const struct i2c_device_id ltrf216a_id[] = { |
524 | { "ltrf216a" }, |
525 | {} |
526 | }; |
527 | MODULE_DEVICE_TABLE(i2c, ltrf216a_id); |
528 | |
529 | static const struct of_device_id ltrf216a_of_match[] = { |
530 | { .compatible = "liteon,ltrf216a" }, |
531 | { .compatible = "ltr,ltrf216a" }, |
532 | {} |
533 | }; |
534 | MODULE_DEVICE_TABLE(of, ltrf216a_of_match); |
535 | |
536 | static struct i2c_driver ltrf216a_driver = { |
537 | .driver = { |
538 | .name = "ltrf216a" , |
539 | .pm = pm_ptr(<rf216a_pm_ops), |
540 | .of_match_table = ltrf216a_of_match, |
541 | }, |
542 | .probe = ltrf216a_probe, |
543 | .id_table = ltrf216a_id, |
544 | }; |
545 | module_i2c_driver(ltrf216a_driver); |
546 | |
547 | MODULE_AUTHOR("Shreeya Patel <shreeya.patel@collabora.com>" ); |
548 | MODULE_AUTHOR("Shi Zhigang <Zhigang.Shi@liteon.com>" ); |
549 | MODULE_DESCRIPTION("LTRF216A ambient light sensor driver" ); |
550 | MODULE_LICENSE("GPL" ); |
551 | |