Merge branch 'core-objtool-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / drivers / iio / light / si1133.c
CommitLineData
e01e7eaf
MRB
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * si1133.c - Support for Silabs SI1133 combined ambient
4 * light and UV index sensors
5 *
6 * Copyright 2018 Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>
7 */
8
9#include <linux/delay.h>
10#include <linux/i2c.h>
11#include <linux/interrupt.h>
12#include <linux/module.h>
13#include <linux/regmap.h>
14
15#include <linux/iio/iio.h>
16#include <linux/iio/sysfs.h>
17
18#include <linux/util_macros.h>
19
20#define SI1133_REG_PART_ID 0x00
21#define SI1133_REG_REV_ID 0x01
22#define SI1133_REG_MFR_ID 0x02
23#define SI1133_REG_INFO0 0x03
24#define SI1133_REG_INFO1 0x04
25
26#define SI1133_PART_ID 0x33
27
28#define SI1133_REG_HOSTIN0 0x0A
29#define SI1133_REG_COMMAND 0x0B
30#define SI1133_REG_IRQ_ENABLE 0x0F
31#define SI1133_REG_RESPONSE1 0x10
32#define SI1133_REG_RESPONSE0 0x11
33#define SI1133_REG_IRQ_STATUS 0x12
34#define SI1133_REG_MEAS_RATE 0x1A
35
36#define SI1133_IRQ_CHANNEL_ENABLE 0xF
37
38#define SI1133_CMD_RESET_CTR 0x00
39#define SI1133_CMD_RESET_SW 0x01
40#define SI1133_CMD_FORCE 0x11
41#define SI1133_CMD_START_AUTONOMOUS 0x13
42#define SI1133_CMD_PARAM_SET 0x80
43#define SI1133_CMD_PARAM_QUERY 0x40
44#define SI1133_CMD_PARAM_MASK 0x3F
45
46#define SI1133_CMD_ERR_MASK BIT(4)
47#define SI1133_CMD_SEQ_MASK 0xF
48#define SI1133_MAX_CMD_CTR 0xF
49
50#define SI1133_PARAM_REG_CHAN_LIST 0x01
51#define SI1133_PARAM_REG_ADCCONFIG(x) ((x) * 4) + 2
52#define SI1133_PARAM_REG_ADCSENS(x) ((x) * 4) + 3
53#define SI1133_PARAM_REG_ADCPOST(x) ((x) * 4) + 4
54
55#define SI1133_ADCMUX_MASK 0x1F
56
57#define SI1133_ADCCONFIG_DECIM_RATE(x) (x) << 5
58
59#define SI1133_ADCSENS_SCALE_MASK 0x70
60#define SI1133_ADCSENS_SCALE_SHIFT 4
61#define SI1133_ADCSENS_HSIG_MASK BIT(7)
62#define SI1133_ADCSENS_HSIG_SHIFT 7
63#define SI1133_ADCSENS_HW_GAIN_MASK 0xF
64#define SI1133_ADCSENS_NB_MEAS(x) fls(x) << SI1133_ADCSENS_SCALE_SHIFT
65
66#define SI1133_ADCPOST_24BIT_EN BIT(6)
67#define SI1133_ADCPOST_POSTSHIFT_BITQTY(x) (x & GENMASK(2, 0)) << 3
68
69#define SI1133_PARAM_ADCMUX_SMALL_IR 0x0
70#define SI1133_PARAM_ADCMUX_MED_IR 0x1
71#define SI1133_PARAM_ADCMUX_LARGE_IR 0x2
72#define SI1133_PARAM_ADCMUX_WHITE 0xB
73#define SI1133_PARAM_ADCMUX_LARGE_WHITE 0xD
74#define SI1133_PARAM_ADCMUX_UV 0x18
75#define SI1133_PARAM_ADCMUX_UV_DEEP 0x19
76
77#define SI1133_ERR_INVALID_CMD 0x0
78#define SI1133_ERR_INVALID_LOCATION_CMD 0x1
79#define SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION 0x2
80#define SI1133_ERR_OUTPUT_BUFFER_OVERFLOW 0x3
81
82#define SI1133_COMPLETION_TIMEOUT_MS 500
83
84#define SI1133_CMD_MINSLEEP_US_LOW 5000
85#define SI1133_CMD_MINSLEEP_US_HIGH 7500
86#define SI1133_CMD_TIMEOUT_MS 25
87#define SI1133_CMD_LUX_TIMEOUT_MS 5000
88#define SI1133_CMD_TIMEOUT_US SI1133_CMD_TIMEOUT_MS * 1000
89
90#define SI1133_REG_HOSTOUT(x) (x) + 0x13
91
92#define SI1133_MEASUREMENT_FREQUENCY 1250
93
94#define SI1133_X_ORDER_MASK 0x0070
95#define SI1133_Y_ORDER_MASK 0x0007
96#define si1133_get_x_order(m) ((m) & SI1133_X_ORDER_MASK) >> 4
97#define si1133_get_y_order(m) ((m) & SI1133_Y_ORDER_MASK)
98
99#define SI1133_LUX_ADC_MASK 0xE
100#define SI1133_ADC_THRESHOLD 16000
101#define SI1133_INPUT_FRACTION_HIGH 7
102#define SI1133_INPUT_FRACTION_LOW 15
103#define SI1133_LUX_OUTPUT_FRACTION 12
104#define SI1133_LUX_BUFFER_SIZE 9
328b50e9
MRB
105#define SI1133_MEASURE_BUFFER_SIZE 3
106
107#define SI1133_SIGN_BIT_INDEX 23
e01e7eaf
MRB
108
109static const int si1133_scale_available[] = {
110 1, 2, 4, 8, 16, 32, 64, 128};
111
112static IIO_CONST_ATTR(scale_available, "1 2 4 8 16 32 64 128");
113
114static IIO_CONST_ATTR_INT_TIME_AVAIL("0.0244 0.0488 0.0975 0.195 0.390 0.780 "
115 "1.560 3.120 6.24 12.48 25.0 50.0");
116
117/* A.K.A. HW_GAIN in datasheet */
118enum si1133_int_time {
119 _24_4_us = 0,
120 _48_8_us = 1,
121 _97_5_us = 2,
122 _195_0_us = 3,
123 _390_0_us = 4,
124 _780_0_us = 5,
125 _1_560_0_us = 6,
126 _3_120_0_us = 7,
127 _6_240_0_us = 8,
128 _12_480_0_us = 9,
129 _25_ms = 10,
130 _50_ms = 11,
131};
132
133/* Integration time in milliseconds, nanoseconds */
134static const int si1133_int_time_table[][2] = {
135 [_24_4_us] = {0, 24400},
136 [_48_8_us] = {0, 48800},
137 [_97_5_us] = {0, 97500},
138 [_195_0_us] = {0, 195000},
139 [_390_0_us] = {0, 390000},
140 [_780_0_us] = {0, 780000},
141 [_1_560_0_us] = {1, 560000},
142 [_3_120_0_us] = {3, 120000},
143 [_6_240_0_us] = {6, 240000},
144 [_12_480_0_us] = {12, 480000},
145 [_25_ms] = {25, 000000},
146 [_50_ms] = {50, 000000},
147};
148
149static const struct regmap_range si1133_reg_ranges[] = {
150 regmap_reg_range(0x00, 0x02),
151 regmap_reg_range(0x0A, 0x0B),
152 regmap_reg_range(0x0F, 0x0F),
153 regmap_reg_range(0x10, 0x12),
154 regmap_reg_range(0x13, 0x2C),
155};
156
157static const struct regmap_range si1133_reg_ro_ranges[] = {
158 regmap_reg_range(0x00, 0x02),
159 regmap_reg_range(0x10, 0x2C),
160};
161
162static const struct regmap_range si1133_precious_ranges[] = {
163 regmap_reg_range(0x12, 0x12),
164};
165
166static const struct regmap_access_table si1133_write_ranges_table = {
167 .yes_ranges = si1133_reg_ranges,
168 .n_yes_ranges = ARRAY_SIZE(si1133_reg_ranges),
169 .no_ranges = si1133_reg_ro_ranges,
170 .n_no_ranges = ARRAY_SIZE(si1133_reg_ro_ranges),
171};
172
173static const struct regmap_access_table si1133_read_ranges_table = {
174 .yes_ranges = si1133_reg_ranges,
175 .n_yes_ranges = ARRAY_SIZE(si1133_reg_ranges),
176};
177
178static const struct regmap_access_table si1133_precious_table = {
179 .yes_ranges = si1133_precious_ranges,
180 .n_yes_ranges = ARRAY_SIZE(si1133_precious_ranges),
181};
182
183static const struct regmap_config si1133_regmap_config = {
184 .reg_bits = 8,
185 .val_bits = 8,
186
187 .max_register = 0x2C,
188
189 .wr_table = &si1133_write_ranges_table,
190 .rd_table = &si1133_read_ranges_table,
191
192 .precious_table = &si1133_precious_table,
193};
194
195struct si1133_data {
196 struct regmap *regmap;
197 struct i2c_client *client;
198
199 /* Lock protecting one command at a time can be processed */
200 struct mutex mutex;
201
202 int rsp_seq;
203 u8 scan_mask;
204 u8 adc_sens[6];
205 u8 adc_config[6];
206
207 struct completion completion;
208};
209
210struct si1133_coeff {
211 s16 info;
212 u16 mag;
213};
214
215struct si1133_lux_coeff {
216 struct si1133_coeff coeff_high[4];
217 struct si1133_coeff coeff_low[9];
218};
219
220static const struct si1133_lux_coeff lux_coeff = {
221 {
222 { 0, 209},
223 { 1665, 93},
224 { 2064, 65},
225 {-2671, 234}
226 },
227 {
228 { 0, 0},
229 { 1921, 29053},
230 {-1022, 36363},
231 { 2320, 20789},
232 { -367, 57909},
233 {-1774, 38240},
234 { -608, 46775},
235 {-1503, 51831},
236 {-1886, 58928}
237 }
238};
239
328b50e9 240static int si1133_calculate_polynomial_inner(s32 input, u8 fraction, u16 mag,
e01e7eaf
MRB
241 s8 shift)
242{
243 return ((input << fraction) / mag) << shift;
244}
245
328b50e9 246static int si1133_calculate_output(s32 x, s32 y, u8 x_order, u8 y_order,
e01e7eaf
MRB
247 u8 input_fraction, s8 sign,
248 const struct si1133_coeff *coeffs)
249{
250 s8 shift;
251 int x1 = 1;
252 int x2 = 1;
253 int y1 = 1;
254 int y2 = 1;
255
256 shift = ((u16)coeffs->info & 0xFF00) >> 8;
257 shift ^= 0xFF;
258 shift += 1;
259 shift = -shift;
260
261 if (x_order > 0) {
262 x1 = si1133_calculate_polynomial_inner(x, input_fraction,
263 coeffs->mag, shift);
264 if (x_order > 1)
265 x2 = x1;
266 }
267
268 if (y_order > 0) {
269 y1 = si1133_calculate_polynomial_inner(y, input_fraction,
270 coeffs->mag, shift);
271 if (y_order > 1)
272 y2 = y1;
273 }
274
275 return sign * x1 * x2 * y1 * y2;
276}
277
278/*
279 * The algorithm is from:
280 * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00716
281 */
328b50e9 282static int si1133_calc_polynomial(s32 x, s32 y, u8 input_fraction, u8 num_coeff,
e01e7eaf
MRB
283 const struct si1133_coeff *coeffs)
284{
285 u8 x_order, y_order;
286 u8 counter;
287 s8 sign;
288 int output = 0;
289
290 for (counter = 0; counter < num_coeff; counter++) {
291 if (coeffs->info < 0)
292 sign = -1;
293 else
294 sign = 1;
295
296 x_order = si1133_get_x_order(coeffs->info);
297 y_order = si1133_get_y_order(coeffs->info);
298
299 if ((x_order == 0) && (y_order == 0))
300 output +=
301 sign * coeffs->mag << SI1133_LUX_OUTPUT_FRACTION;
302 else
303 output += si1133_calculate_output(x, y, x_order,
304 y_order,
305 input_fraction, sign,
306 coeffs);
307 coeffs++;
308 }
309
310 return abs(output);
311}
312
313static int si1133_cmd_reset_sw(struct si1133_data *data)
314{
315 struct device *dev = &data->client->dev;
316 unsigned int resp;
317 unsigned long timeout;
318 int err;
319
320 err = regmap_write(data->regmap, SI1133_REG_COMMAND,
321 SI1133_CMD_RESET_SW);
322 if (err)
323 return err;
324
325 timeout = jiffies + msecs_to_jiffies(SI1133_CMD_TIMEOUT_MS);
326 while (true) {
327 err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
328 if (err == -ENXIO) {
329 usleep_range(SI1133_CMD_MINSLEEP_US_LOW,
330 SI1133_CMD_MINSLEEP_US_HIGH);
331 continue;
332 }
333
334 if ((resp & SI1133_MAX_CMD_CTR) == SI1133_MAX_CMD_CTR)
335 break;
336
337 if (time_after(jiffies, timeout)) {
338 dev_warn(dev, "Timeout on reset ctr resp: %d\n", resp);
339 return -ETIMEDOUT;
340 }
341 }
342
343 if (!err)
344 data->rsp_seq = SI1133_MAX_CMD_CTR;
345
346 return err;
347}
348
349static int si1133_parse_response_err(struct device *dev, u32 resp, u8 cmd)
350{
351 resp &= 0xF;
352
353 switch (resp) {
354 case SI1133_ERR_OUTPUT_BUFFER_OVERFLOW:
355 dev_warn(dev, "Output buffer overflow: %#02hhx\n", cmd);
356 return -EOVERFLOW;
357 case SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION:
358 dev_warn(dev, "Saturation of the ADC or overflow of accumulation: %#02hhx\n",
359 cmd);
360 return -EOVERFLOW;
361 case SI1133_ERR_INVALID_LOCATION_CMD:
362 dev_warn(dev,
363 "Parameter access to an invalid location: %#02hhx\n",
364 cmd);
365 return -EINVAL;
366 case SI1133_ERR_INVALID_CMD:
367 dev_warn(dev, "Invalid command %#02hhx\n", cmd);
368 return -EINVAL;
369 default:
370 dev_warn(dev, "Unknown error %#02hhx\n", cmd);
371 return -EINVAL;
372 }
373}
374
375static int si1133_cmd_reset_counter(struct si1133_data *data)
376{
377 int err = regmap_write(data->regmap, SI1133_REG_COMMAND,
378 SI1133_CMD_RESET_CTR);
379 if (err)
380 return err;
381
382 data->rsp_seq = 0;
383
384 return 0;
385}
386
387static int si1133_command(struct si1133_data *data, u8 cmd)
388{
389 struct device *dev = &data->client->dev;
390 u32 resp;
391 int err;
392 int expected_seq;
393
394 mutex_lock(&data->mutex);
395
396 expected_seq = (data->rsp_seq + 1) & SI1133_MAX_CMD_CTR;
397
398 if (cmd == SI1133_CMD_FORCE)
399 reinit_completion(&data->completion);
400
401 err = regmap_write(data->regmap, SI1133_REG_COMMAND, cmd);
402 if (err) {
403 dev_warn(dev, "Failed to write command %#02hhx, ret=%d\n", cmd,
404 err);
405 goto out;
406 }
407
408 if (cmd == SI1133_CMD_FORCE) {
409 /* wait for irq */
410 if (!wait_for_completion_timeout(&data->completion,
411 msecs_to_jiffies(SI1133_COMPLETION_TIMEOUT_MS))) {
412 err = -ETIMEDOUT;
413 goto out;
414 }
496fb59e
MRB
415 err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
416 if (err)
417 goto out;
e01e7eaf
MRB
418 } else {
419 err = regmap_read_poll_timeout(data->regmap,
420 SI1133_REG_RESPONSE0, resp,
421 (resp & SI1133_CMD_SEQ_MASK) ==
422 expected_seq ||
423 (resp & SI1133_CMD_ERR_MASK),
424 SI1133_CMD_MINSLEEP_US_LOW,
425 SI1133_CMD_TIMEOUT_MS * 1000);
426 if (err) {
427 dev_warn(dev,
428 "Failed to read command %#02hhx, ret=%d\n",
429 cmd, err);
430 goto out;
431 }
432 }
433
434 if (resp & SI1133_CMD_ERR_MASK) {
435 err = si1133_parse_response_err(dev, resp, cmd);
436 si1133_cmd_reset_counter(data);
437 } else {
438 data->rsp_seq = expected_seq;
439 }
440
441out:
442 mutex_unlock(&data->mutex);
443
444 return err;
445}
446
447static int si1133_param_set(struct si1133_data *data, u8 param, u32 value)
448{
449 int err = regmap_write(data->regmap, SI1133_REG_HOSTIN0, value);
450
451 if (err)
452 return err;
453
454 return si1133_command(data, SI1133_CMD_PARAM_SET |
455 (param & SI1133_CMD_PARAM_MASK));
456}
457
458static int si1133_param_query(struct si1133_data *data, u8 param, u32 *result)
459{
460 int err = si1133_command(data, SI1133_CMD_PARAM_QUERY |
461 (param & SI1133_CMD_PARAM_MASK));
462 if (err)
463 return err;
464
465 return regmap_read(data->regmap, SI1133_REG_RESPONSE1, result);
466}
467
468#define SI1133_CHANNEL(_ch, _type) \
469 .type = _type, \
470 .channel = _ch, \
471 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
472 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | \
473 BIT(IIO_CHAN_INFO_SCALE) | \
474 BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
475
476static const struct iio_chan_spec si1133_channels[] = {
477 {
478 .type = IIO_LIGHT,
479 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
480 .channel = 0,
481 },
482 {
483 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_WHITE, IIO_INTENSITY)
484 .channel2 = IIO_MOD_LIGHT_BOTH,
485 },
486 {
487 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_WHITE, IIO_INTENSITY)
488 .channel2 = IIO_MOD_LIGHT_BOTH,
489 .extend_name = "large",
490 },
491 {
492 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_SMALL_IR, IIO_INTENSITY)
493 .extend_name = "small",
494 .modified = 1,
495 .channel2 = IIO_MOD_LIGHT_IR,
496 },
497 {
498 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_MED_IR, IIO_INTENSITY)
499 .modified = 1,
500 .channel2 = IIO_MOD_LIGHT_IR,
501 },
502 {
503 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_IR, IIO_INTENSITY)
504 .extend_name = "large",
505 .modified = 1,
506 .channel2 = IIO_MOD_LIGHT_IR,
507 },
508 {
509 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV, IIO_UVINDEX)
510 },
511 {
512 SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV_DEEP, IIO_UVINDEX)
513 .modified = 1,
514 .channel2 = IIO_MOD_LIGHT_DUV,
515 }
516};
517
518static int si1133_get_int_time_index(int milliseconds, int nanoseconds)
519{
520 int i;
521
522 for (i = 0; i < ARRAY_SIZE(si1133_int_time_table); i++) {
523 if (milliseconds == si1133_int_time_table[i][0] &&
524 nanoseconds == si1133_int_time_table[i][1])
525 return i;
526 }
527 return -EINVAL;
528}
529
530static int si1133_set_integration_time(struct si1133_data *data, u8 adc,
531 int milliseconds, int nanoseconds)
532{
533 int index;
534
535 index = si1133_get_int_time_index(milliseconds, nanoseconds);
536 if (index < 0)
537 return index;
538
539 data->adc_sens[adc] &= 0xF0;
540 data->adc_sens[adc] |= index;
541
542 return si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(0),
543 data->adc_sens[adc]);
544}
545
546static int si1133_set_chlist(struct si1133_data *data, u8 scan_mask)
547{
548 /* channel list already set, no need to reprogram */
549 if (data->scan_mask == scan_mask)
550 return 0;
551
552 data->scan_mask = scan_mask;
553
554 return si1133_param_set(data, SI1133_PARAM_REG_CHAN_LIST, scan_mask);
555}
556
557static int si1133_chan_set_adcconfig(struct si1133_data *data, u8 adc,
558 u8 adc_config)
559{
560 int err;
561
562 err = si1133_param_set(data, SI1133_PARAM_REG_ADCCONFIG(adc),
563 adc_config);
564 if (err)
565 return err;
566
567 data->adc_config[adc] = adc_config;
568
569 return 0;
570}
571
572static int si1133_update_adcconfig(struct si1133_data *data, uint8_t adc,
573 u8 mask, u8 shift, u8 value)
574{
575 u32 adc_config;
576 int err;
577
578 err = si1133_param_query(data, SI1133_PARAM_REG_ADCCONFIG(adc),
579 &adc_config);
580 if (err)
581 return err;
582
583 adc_config &= ~mask;
584 adc_config |= (value << shift);
585
586 return si1133_chan_set_adcconfig(data, adc, adc_config);
587}
588
589static int si1133_set_adcmux(struct si1133_data *data, u8 adc, u8 mux)
590{
591 if ((mux & data->adc_config[adc]) == mux)
592 return 0; /* mux already set to correct value */
593
594 return si1133_update_adcconfig(data, adc, SI1133_ADCMUX_MASK, 0, mux);
595}
596
597static int si1133_force_measurement(struct si1133_data *data)
598{
599 return si1133_command(data, SI1133_CMD_FORCE);
600}
601
602static int si1133_bulk_read(struct si1133_data *data, u8 start_reg, u8 length,
603 u8 *buffer)
604{
605 int err;
606
607 err = si1133_force_measurement(data);
608 if (err)
609 return err;
610
611 return regmap_bulk_read(data->regmap, start_reg, buffer, length);
612}
613
614static int si1133_measure(struct si1133_data *data,
615 struct iio_chan_spec const *chan,
616 int *val)
617{
618 int err;
619
328b50e9 620 u8 buffer[SI1133_MEASURE_BUFFER_SIZE];
e01e7eaf
MRB
621
622 err = si1133_set_adcmux(data, 0, chan->channel);
623 if (err)
624 return err;
625
626 /* Deactivate lux measurements if they were active */
627 err = si1133_set_chlist(data, BIT(0));
628 if (err)
629 return err;
630
328b50e9
MRB
631 err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(buffer),
632 buffer);
e01e7eaf
MRB
633 if (err)
634 return err;
635
328b50e9
MRB
636 *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2],
637 SI1133_SIGN_BIT_INDEX);
e01e7eaf
MRB
638
639 return err;
640}
641
642static irqreturn_t si1133_threaded_irq_handler(int irq, void *private)
643{
644 struct iio_dev *iio_dev = private;
645 struct si1133_data *data = iio_priv(iio_dev);
646 u32 irq_status;
647 int err;
648
649 err = regmap_read(data->regmap, SI1133_REG_IRQ_STATUS, &irq_status);
650 if (err) {
651 dev_err_ratelimited(&iio_dev->dev, "Error reading IRQ\n");
652 goto out;
653 }
654
655 if (irq_status != data->scan_mask)
656 return IRQ_NONE;
657
658out:
659 complete(&data->completion);
660
661 return IRQ_HANDLED;
662}
663
664static int si1133_scale_to_swgain(int scale_integer, int scale_fractional)
665{
666 scale_integer = find_closest(scale_integer, si1133_scale_available,
667 ARRAY_SIZE(si1133_scale_available));
668 if (scale_integer < 0 ||
669 scale_integer > ARRAY_SIZE(si1133_scale_available) ||
670 scale_fractional != 0)
671 return -EINVAL;
672
673 return scale_integer;
674}
675
676static int si1133_chan_set_adcsens(struct si1133_data *data, u8 adc,
677 u8 adc_sens)
678{
679 int err;
680
681 err = si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(adc), adc_sens);
682 if (err)
683 return err;
684
685 data->adc_sens[adc] = adc_sens;
686
687 return 0;
688}
689
690static int si1133_update_adcsens(struct si1133_data *data, u8 mask,
691 u8 shift, u8 value)
692{
693 int err;
694 u32 adc_sens;
695
696 err = si1133_param_query(data, SI1133_PARAM_REG_ADCSENS(0),
697 &adc_sens);
698 if (err)
699 return err;
700
701 adc_sens &= ~mask;
702 adc_sens |= (value << shift);
703
704 return si1133_chan_set_adcsens(data, 0, adc_sens);
705}
706
707static int si1133_get_lux(struct si1133_data *data, int *val)
708{
709 int err;
710 int lux;
328b50e9
MRB
711 s32 high_vis;
712 s32 low_vis;
713 s32 ir;
e01e7eaf
MRB
714 u8 buffer[SI1133_LUX_BUFFER_SIZE];
715
716 /* Activate lux channels */
717 err = si1133_set_chlist(data, SI1133_LUX_ADC_MASK);
718 if (err)
719 return err;
720
721 err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0),
722 SI1133_LUX_BUFFER_SIZE, buffer);
723 if (err)
724 return err;
725
328b50e9
MRB
726 high_vis =
727 sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2],
728 SI1133_SIGN_BIT_INDEX);
729
730 low_vis =
731 sign_extend32((buffer[3] << 16) | (buffer[4] << 8) | buffer[5],
732 SI1133_SIGN_BIT_INDEX);
733
734 ir = sign_extend32((buffer[6] << 16) | (buffer[7] << 8) | buffer[8],
735 SI1133_SIGN_BIT_INDEX);
e01e7eaf
MRB
736
737 if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD)
738 lux = si1133_calc_polynomial(high_vis, ir,
739 SI1133_INPUT_FRACTION_HIGH,
740 ARRAY_SIZE(lux_coeff.coeff_high),
741 &lux_coeff.coeff_high[0]);
742 else
743 lux = si1133_calc_polynomial(low_vis, ir,
744 SI1133_INPUT_FRACTION_LOW,
745 ARRAY_SIZE(lux_coeff.coeff_low),
746 &lux_coeff.coeff_low[0]);
747
748 *val = lux >> SI1133_LUX_OUTPUT_FRACTION;
749
750 return err;
751}
752
753static int si1133_read_raw(struct iio_dev *iio_dev,
754 struct iio_chan_spec const *chan,
755 int *val, int *val2, long mask)
756{
757 struct si1133_data *data = iio_priv(iio_dev);
758 u8 adc_sens = data->adc_sens[0];
759 int err;
760
761 switch (mask) {
762 case IIO_CHAN_INFO_PROCESSED:
763 switch (chan->type) {
764 case IIO_LIGHT:
765 err = si1133_get_lux(data, val);
766 if (err)
767 return err;
768
769 return IIO_VAL_INT;
770 default:
771 return -EINVAL;
772 }
773 case IIO_CHAN_INFO_RAW:
774 switch (chan->type) {
775 case IIO_INTENSITY:
776 case IIO_UVINDEX:
777 err = si1133_measure(data, chan, val);
778 if (err)
779 return err;
780
781 return IIO_VAL_INT;
782 default:
783 return -EINVAL;
784 }
785 case IIO_CHAN_INFO_INT_TIME:
786 switch (chan->type) {
787 case IIO_INTENSITY:
788 case IIO_UVINDEX:
789 adc_sens &= SI1133_ADCSENS_HW_GAIN_MASK;
790
791 *val = si1133_int_time_table[adc_sens][0];
792 *val2 = si1133_int_time_table[adc_sens][1];
793 return IIO_VAL_INT_PLUS_MICRO;
794 default:
795 return -EINVAL;
796 }
797 case IIO_CHAN_INFO_SCALE:
798 switch (chan->type) {
799 case IIO_INTENSITY:
800 case IIO_UVINDEX:
801 adc_sens &= SI1133_ADCSENS_SCALE_MASK;
802 adc_sens >>= SI1133_ADCSENS_SCALE_SHIFT;
803
804 *val = BIT(adc_sens);
805
806 return IIO_VAL_INT;
807 default:
808 return -EINVAL;
809 }
810 case IIO_CHAN_INFO_HARDWAREGAIN:
811 switch (chan->type) {
812 case IIO_INTENSITY:
813 case IIO_UVINDEX:
814 adc_sens >>= SI1133_ADCSENS_HSIG_SHIFT;
815
816 *val = adc_sens;
817
818 return IIO_VAL_INT;
819 default:
820 return -EINVAL;
821 }
822 default:
823 return -EINVAL;
824 }
825}
826
827static int si1133_write_raw(struct iio_dev *iio_dev,
828 struct iio_chan_spec const *chan,
829 int val, int val2, long mask)
830{
831 struct si1133_data *data = iio_priv(iio_dev);
832
833 switch (mask) {
834 case IIO_CHAN_INFO_SCALE:
835 switch (chan->type) {
836 case IIO_INTENSITY:
837 case IIO_UVINDEX:
838 val = si1133_scale_to_swgain(val, val2);
839 if (val < 0)
840 return val;
841
842 return si1133_update_adcsens(data,
843 SI1133_ADCSENS_SCALE_MASK,
844 SI1133_ADCSENS_SCALE_SHIFT,
845 val);
846 default:
847 return -EINVAL;
848 }
849 case IIO_CHAN_INFO_INT_TIME:
850 return si1133_set_integration_time(data, 0, val, val2);
851 case IIO_CHAN_INFO_HARDWAREGAIN:
852 switch (chan->type) {
853 case IIO_INTENSITY:
854 case IIO_UVINDEX:
1e96e93a 855 if (val != 0 && val != 1)
e01e7eaf
MRB
856 return -EINVAL;
857
858 return si1133_update_adcsens(data,
859 SI1133_ADCSENS_HSIG_MASK,
860 SI1133_ADCSENS_HSIG_SHIFT,
861 val);
862 default:
863 return -EINVAL;
864 }
865 default:
866 return -EINVAL;
867 }
868}
869
870static struct attribute *si1133_attributes[] = {
871 &iio_const_attr_integration_time_available.dev_attr.attr,
872 &iio_const_attr_scale_available.dev_attr.attr,
873 NULL,
874};
875
876static const struct attribute_group si1133_attribute_group = {
877 .attrs = si1133_attributes,
878};
879
880static const struct iio_info si1133_info = {
881 .read_raw = si1133_read_raw,
882 .write_raw = si1133_write_raw,
883 .attrs = &si1133_attribute_group,
884};
885
886/*
887 * si1133_init_lux_channels - Configure 3 different channels(adc) (1,2 and 3)
888 * The channel configuration for the lux measurement was taken from :
889 * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00578
890 *
891 * Reserved the channel 0 for the other raw measurements
892 */
893static int si1133_init_lux_channels(struct si1133_data *data)
894{
895 int err;
896
897 err = si1133_chan_set_adcconfig(data, 1,
898 SI1133_ADCCONFIG_DECIM_RATE(1) |
899 SI1133_PARAM_ADCMUX_LARGE_WHITE);
900 if (err)
901 return err;
902
903 err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(1),
904 SI1133_ADCPOST_24BIT_EN |
905 SI1133_ADCPOST_POSTSHIFT_BITQTY(0));
906 if (err)
907 return err;
908 err = si1133_chan_set_adcsens(data, 1, SI1133_ADCSENS_HSIG_MASK |
909 SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
910 if (err)
911 return err;
912
913 err = si1133_chan_set_adcconfig(data, 2,
914 SI1133_ADCCONFIG_DECIM_RATE(1) |
915 SI1133_PARAM_ADCMUX_LARGE_WHITE);
916 if (err)
917 return err;
918
919 err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(2),
920 SI1133_ADCPOST_24BIT_EN |
921 SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
922 if (err)
923 return err;
924
925 err = si1133_chan_set_adcsens(data, 2, SI1133_ADCSENS_HSIG_MASK |
926 SI1133_ADCSENS_NB_MEAS(1) | _3_120_0_us);
927 if (err)
928 return err;
929
930 err = si1133_chan_set_adcconfig(data, 3,
931 SI1133_ADCCONFIG_DECIM_RATE(1) |
932 SI1133_PARAM_ADCMUX_MED_IR);
933 if (err)
934 return err;
935
936 err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(3),
937 SI1133_ADCPOST_24BIT_EN |
938 SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
939 if (err)
940 return err;
941
942 return si1133_chan_set_adcsens(data, 3, SI1133_ADCSENS_HSIG_MASK |
943 SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
944}
945
946static int si1133_initialize(struct si1133_data *data)
947{
948 int err;
949
950 err = si1133_cmd_reset_sw(data);
951 if (err)
952 return err;
953
954 /* Turn off autonomous mode */
955 err = si1133_param_set(data, SI1133_REG_MEAS_RATE, 0);
956 if (err)
957 return err;
958
959 err = si1133_init_lux_channels(data);
960 if (err)
961 return err;
962
963 return regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE,
964 SI1133_IRQ_CHANNEL_ENABLE);
965}
966
967static int si1133_validate_ids(struct iio_dev *iio_dev)
968{
969 struct si1133_data *data = iio_priv(iio_dev);
970
971 unsigned int part_id, rev_id, mfr_id;
972 int err;
973
974 err = regmap_read(data->regmap, SI1133_REG_PART_ID, &part_id);
975 if (err)
976 return err;
977
978 err = regmap_read(data->regmap, SI1133_REG_REV_ID, &rev_id);
979 if (err)
980 return err;
981
982 err = regmap_read(data->regmap, SI1133_REG_MFR_ID, &mfr_id);
983 if (err)
984 return err;
985
986 dev_info(&iio_dev->dev,
987 "Device ID part %#02hhx rev %#02hhx mfr %#02hhx\n",
988 part_id, rev_id, mfr_id);
989 if (part_id != SI1133_PART_ID) {
990 dev_err(&iio_dev->dev,
991 "Part ID mismatch got %#02hhx, expected %#02x\n",
992 part_id, SI1133_PART_ID);
993 return -ENODEV;
994 }
995
996 return 0;
997}
998
999static int si1133_probe(struct i2c_client *client,
1000 const struct i2c_device_id *id)
1001{
1002 struct si1133_data *data;
1003 struct iio_dev *iio_dev;
1004 int err;
1005
1006 iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1007 if (!iio_dev)
1008 return -ENOMEM;
1009
1010 data = iio_priv(iio_dev);
1011
1012 init_completion(&data->completion);
1013
1014 data->regmap = devm_regmap_init_i2c(client, &si1133_regmap_config);
1015 if (IS_ERR(data->regmap)) {
1016 err = PTR_ERR(data->regmap);
1017 dev_err(&client->dev, "Failed to initialise regmap: %d\n", err);
1018 return err;
1019 }
1020
1021 i2c_set_clientdata(client, iio_dev);
1022 data->client = client;
1023
1024 iio_dev->dev.parent = &client->dev;
1025 iio_dev->name = id->name;
1026 iio_dev->channels = si1133_channels;
1027 iio_dev->num_channels = ARRAY_SIZE(si1133_channels);
1028 iio_dev->info = &si1133_info;
1029 iio_dev->modes = INDIO_DIRECT_MODE;
1030
1031 mutex_init(&data->mutex);
1032
1033 err = si1133_validate_ids(iio_dev);
1034 if (err)
1035 return err;
1036
1037 err = si1133_initialize(data);
1038 if (err) {
1039 dev_err(&client->dev,
1040 "Error when initializing chip: %d\n", err);
1041 return err;
1042 }
1043
1044 if (!client->irq) {
1045 dev_err(&client->dev,
1046 "Required interrupt not provided, cannot proceed\n");
1047 return -EINVAL;
1048 }
1049
1050 err = devm_request_threaded_irq(&client->dev, client->irq,
1051 NULL,
1052 si1133_threaded_irq_handler,
1053 IRQF_ONESHOT | IRQF_SHARED,
1054 client->name, iio_dev);
1055 if (err) {
1056 dev_warn(&client->dev, "Request irq %d failed: %i\n",
1057 client->irq, err);
1058 return err;
1059 }
1060
1061 return devm_iio_device_register(&client->dev, iio_dev);
1062}
1063
1064static const struct i2c_device_id si1133_ids[] = {
1065 { "si1133", 0 },
1066 { }
1067};
1068MODULE_DEVICE_TABLE(i2c, si1133_ids);
1069
1070static struct i2c_driver si1133_driver = {
1071 .driver = {
1072 .name = "si1133",
1073 },
1074 .probe = si1133_probe,
1075 .id_table = si1133_ids,
1076};
1077
1078module_i2c_driver(si1133_driver);
1079
1080MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
1081MODULE_DESCRIPTION("Silabs SI1133, UV index sensor and ambient light sensor driver");
1082MODULE_LICENSE("GPL");