1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * MAX44000 Ambient and Infrared Proximity Sensor |
4 | * |
5 | * Copyright (c) 2016, Intel Corporation. |
6 | * |
7 | * Data sheet: https://datasheets.maximintegrated.com/en/ds/MAX44000.pdf |
8 | * |
9 | * 7-bit I2C slave address 0x4a |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/init.h> |
14 | #include <linux/i2c.h> |
15 | #include <linux/regmap.h> |
16 | #include <linux/util_macros.h> |
17 | #include <linux/iio/iio.h> |
18 | #include <linux/iio/sysfs.h> |
19 | #include <linux/iio/buffer.h> |
20 | #include <linux/iio/trigger_consumer.h> |
21 | #include <linux/iio/triggered_buffer.h> |
22 | #include <linux/acpi.h> |
23 | |
24 | #define MAX44000_DRV_NAME "max44000" |
25 | |
26 | /* Registers in datasheet order */ |
27 | #define MAX44000_REG_STATUS 0x00 |
28 | #define MAX44000_REG_CFG_MAIN 0x01 |
29 | #define MAX44000_REG_CFG_RX 0x02 |
30 | #define MAX44000_REG_CFG_TX 0x03 |
31 | #define MAX44000_REG_ALS_DATA_HI 0x04 |
32 | #define MAX44000_REG_ALS_DATA_LO 0x05 |
33 | #define MAX44000_REG_PRX_DATA 0x16 |
34 | #define MAX44000_REG_ALS_UPTHR_HI 0x06 |
35 | #define MAX44000_REG_ALS_UPTHR_LO 0x07 |
36 | #define MAX44000_REG_ALS_LOTHR_HI 0x08 |
37 | #define MAX44000_REG_ALS_LOTHR_LO 0x09 |
38 | #define MAX44000_REG_PST 0x0a |
39 | #define MAX44000_REG_PRX_IND 0x0b |
40 | #define MAX44000_REG_PRX_THR 0x0c |
41 | #define MAX44000_REG_TRIM_GAIN_GREEN 0x0f |
42 | #define MAX44000_REG_TRIM_GAIN_IR 0x10 |
43 | |
44 | /* REG_CFG bits */ |
45 | #define MAX44000_CFG_ALSINTE 0x01 |
46 | #define MAX44000_CFG_PRXINTE 0x02 |
47 | #define MAX44000_CFG_MASK 0x1c |
48 | #define MAX44000_CFG_MODE_SHUTDOWN 0x00 |
49 | #define MAX44000_CFG_MODE_ALS_GIR 0x04 |
50 | #define MAX44000_CFG_MODE_ALS_G 0x08 |
51 | #define MAX44000_CFG_MODE_ALS_IR 0x0c |
52 | #define MAX44000_CFG_MODE_ALS_PRX 0x10 |
53 | #define MAX44000_CFG_MODE_PRX 0x14 |
54 | #define MAX44000_CFG_TRIM 0x20 |
55 | |
56 | /* |
57 | * Upper 4 bits are not documented but start as 1 on powerup |
58 | * Setting them to 0 causes proximity to misbehave so set them to 1 |
59 | */ |
60 | #define MAX44000_REG_CFG_RX_DEFAULT 0xf0 |
61 | |
62 | /* REG_RX bits */ |
63 | #define MAX44000_CFG_RX_ALSTIM_MASK 0x0c |
64 | #define MAX44000_CFG_RX_ALSTIM_SHIFT 2 |
65 | #define MAX44000_CFG_RX_ALSPGA_MASK 0x03 |
66 | #define MAX44000_CFG_RX_ALSPGA_SHIFT 0 |
67 | |
68 | /* REG_TX bits */ |
69 | #define MAX44000_LED_CURRENT_MASK 0xf |
70 | #define MAX44000_LED_CURRENT_MAX 11 |
71 | #define MAX44000_LED_CURRENT_DEFAULT 6 |
72 | |
73 | #define MAX44000_ALSDATA_OVERFLOW 0x4000 |
74 | |
75 | struct max44000_data { |
76 | struct mutex lock; |
77 | struct regmap *regmap; |
78 | /* Ensure naturally aligned timestamp */ |
79 | struct { |
80 | u16 channels[2]; |
81 | s64 ts __aligned(8); |
82 | } scan; |
83 | }; |
84 | |
85 | /* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */ |
86 | #define MAX44000_ALS_TO_LUX_DEFAULT_FRACTION_LOG2 5 |
87 | |
88 | /* Scale can be multiplied by up to 128x via ALSPGA for measurement gain */ |
89 | static const int max44000_alspga_shift[] = {0, 2, 4, 7}; |
90 | #define MAX44000_ALSPGA_MAX_SHIFT 7 |
91 | |
92 | /* |
93 | * Scale can be multiplied by up to 64x via ALSTIM because of lost resolution |
94 | * |
95 | * This scaling factor is hidden from userspace and instead accounted for when |
96 | * reading raw values from the device. |
97 | * |
98 | * This makes it possible to cleanly expose ALSPGA as IIO_CHAN_INFO_SCALE and |
99 | * ALSTIM as IIO_CHAN_INFO_INT_TIME without the values affecting each other. |
100 | * |
101 | * Handling this internally is also required for buffer support because the |
102 | * channel's scan_type can't be modified dynamically. |
103 | */ |
104 | #define MAX44000_ALSTIM_SHIFT(alstim) (2 * (alstim)) |
105 | |
106 | /* Available integration times with pretty manual alignment: */ |
107 | static const int max44000_int_time_avail_ns_array[] = { |
108 | 100000000, |
109 | 25000000, |
110 | 6250000, |
111 | 1562500, |
112 | }; |
113 | static const char max44000_int_time_avail_str[] = |
114 | "0.100 " |
115 | "0.025 " |
116 | "0.00625 " |
117 | "0.0015625" ; |
118 | |
119 | /* Available scales (internal to ulux) with pretty manual alignment: */ |
120 | static const int max44000_scale_avail_ulux_array[] = { |
121 | 31250, |
122 | 125000, |
123 | 500000, |
124 | 4000000, |
125 | }; |
126 | static const char max44000_scale_avail_str[] = |
127 | "0.03125 " |
128 | "0.125 " |
129 | "0.5 " |
130 | "4" ; |
131 | |
132 | #define MAX44000_SCAN_INDEX_ALS 0 |
133 | #define MAX44000_SCAN_INDEX_PRX 1 |
134 | |
135 | static const struct iio_chan_spec max44000_channels[] = { |
136 | { |
137 | .type = IIO_LIGHT, |
138 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
139 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | |
140 | BIT(IIO_CHAN_INFO_INT_TIME), |
141 | .scan_index = MAX44000_SCAN_INDEX_ALS, |
142 | .scan_type = { |
143 | .sign = 'u', |
144 | .realbits = 14, |
145 | .storagebits = 16, |
146 | } |
147 | }, |
148 | { |
149 | .type = IIO_PROXIMITY, |
150 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
151 | .scan_index = MAX44000_SCAN_INDEX_PRX, |
152 | .scan_type = { |
153 | .sign = 'u', |
154 | .realbits = 8, |
155 | .storagebits = 16, |
156 | } |
157 | }, |
158 | IIO_CHAN_SOFT_TIMESTAMP(2), |
159 | { |
160 | .type = IIO_CURRENT, |
161 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
162 | BIT(IIO_CHAN_INFO_SCALE), |
163 | .extend_name = "led" , |
164 | .output = 1, |
165 | .scan_index = -1, |
166 | }, |
167 | }; |
168 | |
169 | static int max44000_read_alstim(struct max44000_data *data) |
170 | { |
171 | unsigned int val; |
172 | int ret; |
173 | |
174 | ret = regmap_read(map: data->regmap, MAX44000_REG_CFG_RX, val: &val); |
175 | if (ret < 0) |
176 | return ret; |
177 | return (val & MAX44000_CFG_RX_ALSTIM_MASK) >> MAX44000_CFG_RX_ALSTIM_SHIFT; |
178 | } |
179 | |
180 | static int max44000_write_alstim(struct max44000_data *data, int val) |
181 | { |
182 | return regmap_write_bits(map: data->regmap, MAX44000_REG_CFG_RX, |
183 | MAX44000_CFG_RX_ALSTIM_MASK, |
184 | val: val << MAX44000_CFG_RX_ALSTIM_SHIFT); |
185 | } |
186 | |
187 | static int max44000_read_alspga(struct max44000_data *data) |
188 | { |
189 | unsigned int val; |
190 | int ret; |
191 | |
192 | ret = regmap_read(map: data->regmap, MAX44000_REG_CFG_RX, val: &val); |
193 | if (ret < 0) |
194 | return ret; |
195 | return (val & MAX44000_CFG_RX_ALSPGA_MASK) >> MAX44000_CFG_RX_ALSPGA_SHIFT; |
196 | } |
197 | |
198 | static int max44000_write_alspga(struct max44000_data *data, int val) |
199 | { |
200 | return regmap_write_bits(map: data->regmap, MAX44000_REG_CFG_RX, |
201 | MAX44000_CFG_RX_ALSPGA_MASK, |
202 | val: val << MAX44000_CFG_RX_ALSPGA_SHIFT); |
203 | } |
204 | |
205 | static int max44000_read_alsval(struct max44000_data *data) |
206 | { |
207 | u16 regval; |
208 | __be16 val; |
209 | int alstim, ret; |
210 | |
211 | ret = regmap_bulk_read(map: data->regmap, MAX44000_REG_ALS_DATA_HI, |
212 | val: &val, val_count: sizeof(val)); |
213 | if (ret < 0) |
214 | return ret; |
215 | alstim = ret = max44000_read_alstim(data); |
216 | if (ret < 0) |
217 | return ret; |
218 | |
219 | regval = be16_to_cpu(val); |
220 | |
221 | /* |
222 | * Overflow is explained on datasheet page 17. |
223 | * |
224 | * It's a warning that either the G or IR channel has become saturated |
225 | * and that the value in the register is likely incorrect. |
226 | * |
227 | * The recommendation is to change the scale (ALSPGA). |
228 | * The driver just returns the max representable value. |
229 | */ |
230 | if (regval & MAX44000_ALSDATA_OVERFLOW) |
231 | return 0x3FFF; |
232 | |
233 | return regval << MAX44000_ALSTIM_SHIFT(alstim); |
234 | } |
235 | |
236 | static int max44000_write_led_current_raw(struct max44000_data *data, int val) |
237 | { |
238 | /* Maybe we should clamp the value instead? */ |
239 | if (val < 0 || val > MAX44000_LED_CURRENT_MAX) |
240 | return -ERANGE; |
241 | if (val >= 8) |
242 | val += 4; |
243 | return regmap_write_bits(map: data->regmap, MAX44000_REG_CFG_TX, |
244 | MAX44000_LED_CURRENT_MASK, val); |
245 | } |
246 | |
247 | static int max44000_read_led_current_raw(struct max44000_data *data) |
248 | { |
249 | unsigned int regval; |
250 | int ret; |
251 | |
252 | ret = regmap_read(map: data->regmap, MAX44000_REG_CFG_TX, val: ®val); |
253 | if (ret < 0) |
254 | return ret; |
255 | regval &= MAX44000_LED_CURRENT_MASK; |
256 | if (regval >= 8) |
257 | regval -= 4; |
258 | return regval; |
259 | } |
260 | |
261 | static int max44000_read_raw(struct iio_dev *indio_dev, |
262 | struct iio_chan_spec const *chan, |
263 | int *val, int *val2, long mask) |
264 | { |
265 | struct max44000_data *data = iio_priv(indio_dev); |
266 | int alstim, alspga; |
267 | unsigned int regval; |
268 | int ret; |
269 | |
270 | switch (mask) { |
271 | case IIO_CHAN_INFO_RAW: |
272 | switch (chan->type) { |
273 | case IIO_LIGHT: |
274 | mutex_lock(&data->lock); |
275 | ret = max44000_read_alsval(data); |
276 | mutex_unlock(lock: &data->lock); |
277 | if (ret < 0) |
278 | return ret; |
279 | *val = ret; |
280 | return IIO_VAL_INT; |
281 | |
282 | case IIO_PROXIMITY: |
283 | mutex_lock(&data->lock); |
284 | ret = regmap_read(map: data->regmap, MAX44000_REG_PRX_DATA, val: ®val); |
285 | mutex_unlock(lock: &data->lock); |
286 | if (ret < 0) |
287 | return ret; |
288 | *val = regval; |
289 | return IIO_VAL_INT; |
290 | |
291 | case IIO_CURRENT: |
292 | mutex_lock(&data->lock); |
293 | ret = max44000_read_led_current_raw(data); |
294 | mutex_unlock(lock: &data->lock); |
295 | if (ret < 0) |
296 | return ret; |
297 | *val = ret; |
298 | return IIO_VAL_INT; |
299 | |
300 | default: |
301 | return -EINVAL; |
302 | } |
303 | |
304 | case IIO_CHAN_INFO_SCALE: |
305 | switch (chan->type) { |
306 | case IIO_CURRENT: |
307 | /* Output register is in 10s of miliamps */ |
308 | *val = 10; |
309 | return IIO_VAL_INT; |
310 | |
311 | case IIO_LIGHT: |
312 | mutex_lock(&data->lock); |
313 | alspga = ret = max44000_read_alspga(data); |
314 | mutex_unlock(lock: &data->lock); |
315 | if (ret < 0) |
316 | return ret; |
317 | |
318 | /* Avoid negative shifts */ |
319 | *val = (1 << MAX44000_ALSPGA_MAX_SHIFT); |
320 | *val2 = MAX44000_ALS_TO_LUX_DEFAULT_FRACTION_LOG2 |
321 | + MAX44000_ALSPGA_MAX_SHIFT |
322 | - max44000_alspga_shift[alspga]; |
323 | return IIO_VAL_FRACTIONAL_LOG2; |
324 | |
325 | default: |
326 | return -EINVAL; |
327 | } |
328 | |
329 | case IIO_CHAN_INFO_INT_TIME: |
330 | mutex_lock(&data->lock); |
331 | alstim = ret = max44000_read_alstim(data); |
332 | mutex_unlock(lock: &data->lock); |
333 | |
334 | if (ret < 0) |
335 | return ret; |
336 | *val = 0; |
337 | *val2 = max44000_int_time_avail_ns_array[alstim]; |
338 | return IIO_VAL_INT_PLUS_NANO; |
339 | |
340 | default: |
341 | return -EINVAL; |
342 | } |
343 | } |
344 | |
345 | static int max44000_write_raw(struct iio_dev *indio_dev, |
346 | struct iio_chan_spec const *chan, |
347 | int val, int val2, long mask) |
348 | { |
349 | struct max44000_data *data = iio_priv(indio_dev); |
350 | int ret; |
351 | |
352 | if (mask == IIO_CHAN_INFO_RAW && chan->type == IIO_CURRENT) { |
353 | mutex_lock(&data->lock); |
354 | ret = max44000_write_led_current_raw(data, val); |
355 | mutex_unlock(lock: &data->lock); |
356 | return ret; |
357 | } else if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT) { |
358 | s64 valns = val * NSEC_PER_SEC + val2; |
359 | int alstim = find_closest_descending(valns, |
360 | max44000_int_time_avail_ns_array, |
361 | ARRAY_SIZE(max44000_int_time_avail_ns_array)); |
362 | mutex_lock(&data->lock); |
363 | ret = max44000_write_alstim(data, val: alstim); |
364 | mutex_unlock(lock: &data->lock); |
365 | return ret; |
366 | } else if (mask == IIO_CHAN_INFO_SCALE && chan->type == IIO_LIGHT) { |
367 | s64 valus = val * USEC_PER_SEC + val2; |
368 | int alspga = find_closest(valus, |
369 | max44000_scale_avail_ulux_array, |
370 | ARRAY_SIZE(max44000_scale_avail_ulux_array)); |
371 | mutex_lock(&data->lock); |
372 | ret = max44000_write_alspga(data, val: alspga); |
373 | mutex_unlock(lock: &data->lock); |
374 | return ret; |
375 | } |
376 | |
377 | return -EINVAL; |
378 | } |
379 | |
380 | static int max44000_write_raw_get_fmt(struct iio_dev *indio_dev, |
381 | struct iio_chan_spec const *chan, |
382 | long mask) |
383 | { |
384 | if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT) |
385 | return IIO_VAL_INT_PLUS_NANO; |
386 | else if (mask == IIO_CHAN_INFO_SCALE && chan->type == IIO_LIGHT) |
387 | return IIO_VAL_INT_PLUS_MICRO; |
388 | else |
389 | return IIO_VAL_INT; |
390 | } |
391 | |
392 | static IIO_CONST_ATTR(illuminance_integration_time_available, max44000_int_time_avail_str); |
393 | static IIO_CONST_ATTR(illuminance_scale_available, max44000_scale_avail_str); |
394 | |
395 | static struct attribute *max44000_attributes[] = { |
396 | &iio_const_attr_illuminance_integration_time_available.dev_attr.attr, |
397 | &iio_const_attr_illuminance_scale_available.dev_attr.attr, |
398 | NULL |
399 | }; |
400 | |
401 | static const struct attribute_group max44000_attribute_group = { |
402 | .attrs = max44000_attributes, |
403 | }; |
404 | |
405 | static const struct iio_info max44000_info = { |
406 | .read_raw = max44000_read_raw, |
407 | .write_raw = max44000_write_raw, |
408 | .write_raw_get_fmt = max44000_write_raw_get_fmt, |
409 | .attrs = &max44000_attribute_group, |
410 | }; |
411 | |
412 | static bool max44000_readable_reg(struct device *dev, unsigned int reg) |
413 | { |
414 | switch (reg) { |
415 | case MAX44000_REG_STATUS: |
416 | case MAX44000_REG_CFG_MAIN: |
417 | case MAX44000_REG_CFG_RX: |
418 | case MAX44000_REG_CFG_TX: |
419 | case MAX44000_REG_ALS_DATA_HI: |
420 | case MAX44000_REG_ALS_DATA_LO: |
421 | case MAX44000_REG_PRX_DATA: |
422 | case MAX44000_REG_ALS_UPTHR_HI: |
423 | case MAX44000_REG_ALS_UPTHR_LO: |
424 | case MAX44000_REG_ALS_LOTHR_HI: |
425 | case MAX44000_REG_ALS_LOTHR_LO: |
426 | case MAX44000_REG_PST: |
427 | case MAX44000_REG_PRX_IND: |
428 | case MAX44000_REG_PRX_THR: |
429 | case MAX44000_REG_TRIM_GAIN_GREEN: |
430 | case MAX44000_REG_TRIM_GAIN_IR: |
431 | return true; |
432 | default: |
433 | return false; |
434 | } |
435 | } |
436 | |
437 | static bool max44000_writeable_reg(struct device *dev, unsigned int reg) |
438 | { |
439 | switch (reg) { |
440 | case MAX44000_REG_CFG_MAIN: |
441 | case MAX44000_REG_CFG_RX: |
442 | case MAX44000_REG_CFG_TX: |
443 | case MAX44000_REG_ALS_UPTHR_HI: |
444 | case MAX44000_REG_ALS_UPTHR_LO: |
445 | case MAX44000_REG_ALS_LOTHR_HI: |
446 | case MAX44000_REG_ALS_LOTHR_LO: |
447 | case MAX44000_REG_PST: |
448 | case MAX44000_REG_PRX_IND: |
449 | case MAX44000_REG_PRX_THR: |
450 | case MAX44000_REG_TRIM_GAIN_GREEN: |
451 | case MAX44000_REG_TRIM_GAIN_IR: |
452 | return true; |
453 | default: |
454 | return false; |
455 | } |
456 | } |
457 | |
458 | static bool max44000_volatile_reg(struct device *dev, unsigned int reg) |
459 | { |
460 | switch (reg) { |
461 | case MAX44000_REG_STATUS: |
462 | case MAX44000_REG_ALS_DATA_HI: |
463 | case MAX44000_REG_ALS_DATA_LO: |
464 | case MAX44000_REG_PRX_DATA: |
465 | return true; |
466 | default: |
467 | return false; |
468 | } |
469 | } |
470 | |
471 | static bool max44000_precious_reg(struct device *dev, unsigned int reg) |
472 | { |
473 | return reg == MAX44000_REG_STATUS; |
474 | } |
475 | |
476 | static const struct regmap_config max44000_regmap_config = { |
477 | .reg_bits = 8, |
478 | .val_bits = 8, |
479 | |
480 | .max_register = MAX44000_REG_PRX_DATA, |
481 | .readable_reg = max44000_readable_reg, |
482 | .writeable_reg = max44000_writeable_reg, |
483 | .volatile_reg = max44000_volatile_reg, |
484 | .precious_reg = max44000_precious_reg, |
485 | |
486 | .use_single_read = true, |
487 | .use_single_write = true, |
488 | .cache_type = REGCACHE_RBTREE, |
489 | }; |
490 | |
491 | static irqreturn_t max44000_trigger_handler(int irq, void *p) |
492 | { |
493 | struct iio_poll_func *pf = p; |
494 | struct iio_dev *indio_dev = pf->indio_dev; |
495 | struct max44000_data *data = iio_priv(indio_dev); |
496 | int index = 0; |
497 | unsigned int regval; |
498 | int ret; |
499 | |
500 | mutex_lock(&data->lock); |
501 | if (test_bit(MAX44000_SCAN_INDEX_ALS, indio_dev->active_scan_mask)) { |
502 | ret = max44000_read_alsval(data); |
503 | if (ret < 0) |
504 | goto out_unlock; |
505 | data->scan.channels[index++] = ret; |
506 | } |
507 | if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) { |
508 | ret = regmap_read(map: data->regmap, MAX44000_REG_PRX_DATA, val: ®val); |
509 | if (ret < 0) |
510 | goto out_unlock; |
511 | data->scan.channels[index] = regval; |
512 | } |
513 | mutex_unlock(lock: &data->lock); |
514 | |
515 | iio_push_to_buffers_with_timestamp(indio_dev, data: &data->scan, |
516 | timestamp: iio_get_time_ns(indio_dev)); |
517 | iio_trigger_notify_done(trig: indio_dev->trig); |
518 | return IRQ_HANDLED; |
519 | |
520 | out_unlock: |
521 | mutex_unlock(lock: &data->lock); |
522 | iio_trigger_notify_done(trig: indio_dev->trig); |
523 | return IRQ_HANDLED; |
524 | } |
525 | |
526 | static int max44000_probe(struct i2c_client *client) |
527 | { |
528 | struct max44000_data *data; |
529 | struct iio_dev *indio_dev; |
530 | int ret, reg; |
531 | |
532 | indio_dev = devm_iio_device_alloc(parent: &client->dev, sizeof_priv: sizeof(*data)); |
533 | if (!indio_dev) |
534 | return -ENOMEM; |
535 | data = iio_priv(indio_dev); |
536 | data->regmap = devm_regmap_init_i2c(client, &max44000_regmap_config); |
537 | if (IS_ERR(ptr: data->regmap)) { |
538 | dev_err(&client->dev, "regmap_init failed!\n" ); |
539 | return PTR_ERR(ptr: data->regmap); |
540 | } |
541 | |
542 | mutex_init(&data->lock); |
543 | indio_dev->info = &max44000_info; |
544 | indio_dev->name = MAX44000_DRV_NAME; |
545 | indio_dev->channels = max44000_channels; |
546 | indio_dev->num_channels = ARRAY_SIZE(max44000_channels); |
547 | |
548 | /* |
549 | * The device doesn't have a reset function so we just clear some |
550 | * important bits at probe time to ensure sane operation. |
551 | * |
552 | * Since we don't support interrupts/events the threshold values are |
553 | * not important. We also don't touch trim values. |
554 | */ |
555 | |
556 | /* Reset ALS scaling bits */ |
557 | ret = regmap_write(map: data->regmap, MAX44000_REG_CFG_RX, |
558 | MAX44000_REG_CFG_RX_DEFAULT); |
559 | if (ret < 0) { |
560 | dev_err(&client->dev, "failed to write default CFG_RX: %d\n" , |
561 | ret); |
562 | return ret; |
563 | } |
564 | |
565 | /* |
566 | * By default the LED pulse used for the proximity sensor is disabled. |
567 | * Set a middle value so that we get some sort of valid data by default. |
568 | */ |
569 | ret = max44000_write_led_current_raw(data, MAX44000_LED_CURRENT_DEFAULT); |
570 | if (ret < 0) { |
571 | dev_err(&client->dev, "failed to write init config: %d\n" , ret); |
572 | return ret; |
573 | } |
574 | |
575 | /* Reset CFG bits to ALS_PRX mode which allows easy reading of both values. */ |
576 | reg = MAX44000_CFG_TRIM | MAX44000_CFG_MODE_ALS_PRX; |
577 | ret = regmap_write(map: data->regmap, MAX44000_REG_CFG_MAIN, val: reg); |
578 | if (ret < 0) { |
579 | dev_err(&client->dev, "failed to write init config: %d\n" , ret); |
580 | return ret; |
581 | } |
582 | |
583 | /* Read status at least once to clear any stale interrupt bits. */ |
584 | ret = regmap_read(map: data->regmap, MAX44000_REG_STATUS, val: ®); |
585 | if (ret < 0) { |
586 | dev_err(&client->dev, "failed to read init status: %d\n" , ret); |
587 | return ret; |
588 | } |
589 | |
590 | ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, |
591 | max44000_trigger_handler, NULL); |
592 | if (ret < 0) { |
593 | dev_err(&client->dev, "iio triggered buffer setup failed\n" ); |
594 | return ret; |
595 | } |
596 | |
597 | return devm_iio_device_register(&client->dev, indio_dev); |
598 | } |
599 | |
600 | static const struct i2c_device_id max44000_id[] = { |
601 | {"max44000" , 0}, |
602 | { } |
603 | }; |
604 | MODULE_DEVICE_TABLE(i2c, max44000_id); |
605 | |
606 | #ifdef CONFIG_ACPI |
607 | static const struct acpi_device_id max44000_acpi_match[] = { |
608 | {"MAX44000" , 0}, |
609 | { } |
610 | }; |
611 | MODULE_DEVICE_TABLE(acpi, max44000_acpi_match); |
612 | #endif |
613 | |
614 | static struct i2c_driver max44000_driver = { |
615 | .driver = { |
616 | .name = MAX44000_DRV_NAME, |
617 | .acpi_match_table = ACPI_PTR(max44000_acpi_match), |
618 | }, |
619 | .probe = max44000_probe, |
620 | .id_table = max44000_id, |
621 | }; |
622 | |
623 | module_i2c_driver(max44000_driver); |
624 | |
625 | MODULE_AUTHOR("Crestez Dan Leonard <leonard.crestez@intel.com>" ); |
626 | MODULE_DESCRIPTION("MAX44000 Ambient and Infrared Proximity Sensor" ); |
627 | MODULE_LICENSE("GPL v2" ); |
628 | |