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