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#include <asm/unaligned.h>
21
22#define SI1133_REG_PART_ID		0x00
23#define SI1133_REG_REV_ID		0x01
24#define SI1133_REG_MFR_ID		0x02
25#define SI1133_REG_INFO0		0x03
26#define SI1133_REG_INFO1		0x04
27
28#define SI1133_PART_ID			0x33
29
30#define SI1133_REG_HOSTIN0		0x0A
31#define SI1133_REG_COMMAND		0x0B
32#define SI1133_REG_IRQ_ENABLE		0x0F
33#define SI1133_REG_RESPONSE1		0x10
34#define SI1133_REG_RESPONSE0		0x11
35#define SI1133_REG_IRQ_STATUS		0x12
36#define SI1133_REG_MEAS_RATE		0x1A
37
38#define SI1133_IRQ_CHANNEL_ENABLE	0xF
39
40#define SI1133_CMD_RESET_CTR		0x00
41#define SI1133_CMD_RESET_SW		0x01
42#define SI1133_CMD_FORCE		0x11
43#define SI1133_CMD_START_AUTONOMOUS	0x13
44#define SI1133_CMD_PARAM_SET		0x80
45#define SI1133_CMD_PARAM_QUERY		0x40
46#define SI1133_CMD_PARAM_MASK		0x3F
47
48#define SI1133_CMD_ERR_MASK		BIT(4)
49#define SI1133_CMD_SEQ_MASK		0xF
50#define SI1133_MAX_CMD_CTR		0xF
51
52#define SI1133_PARAM_REG_CHAN_LIST	0x01
53#define SI1133_PARAM_REG_ADCCONFIG(x)	((x) * 4) + 2
54#define SI1133_PARAM_REG_ADCSENS(x)	((x) * 4) + 3
55#define SI1133_PARAM_REG_ADCPOST(x)	((x) * 4) + 4
56
57#define SI1133_ADCMUX_MASK 0x1F
58
59#define SI1133_ADCCONFIG_DECIM_RATE(x)	(x) << 5
60
61#define SI1133_ADCSENS_SCALE_MASK 0x70
62#define SI1133_ADCSENS_SCALE_SHIFT 4
63#define SI1133_ADCSENS_HSIG_MASK BIT(7)
64#define SI1133_ADCSENS_HSIG_SHIFT 7
65#define SI1133_ADCSENS_HW_GAIN_MASK 0xF
66#define SI1133_ADCSENS_NB_MEAS(x)	fls(x) << SI1133_ADCSENS_SCALE_SHIFT
67
68#define SI1133_ADCPOST_24BIT_EN BIT(6)
69#define SI1133_ADCPOST_POSTSHIFT_BITQTY(x) (x & GENMASK(2, 0)) << 3
70
71#define SI1133_PARAM_ADCMUX_SMALL_IR	0x0
72#define SI1133_PARAM_ADCMUX_MED_IR	0x1
73#define SI1133_PARAM_ADCMUX_LARGE_IR	0x2
74#define SI1133_PARAM_ADCMUX_WHITE	0xB
75#define SI1133_PARAM_ADCMUX_LARGE_WHITE	0xD
76#define SI1133_PARAM_ADCMUX_UV		0x18
77#define SI1133_PARAM_ADCMUX_UV_DEEP	0x19
78
79#define SI1133_ERR_INVALID_CMD		0x0
80#define SI1133_ERR_INVALID_LOCATION_CMD 0x1
81#define SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION 0x2
82#define SI1133_ERR_OUTPUT_BUFFER_OVERFLOW 0x3
83
84#define SI1133_COMPLETION_TIMEOUT_MS	500
85
86#define SI1133_CMD_MINSLEEP_US_LOW	5000
87#define SI1133_CMD_MINSLEEP_US_HIGH	7500
88#define SI1133_CMD_TIMEOUT_MS		25
89#define SI1133_CMD_LUX_TIMEOUT_MS	5000
90#define SI1133_CMD_TIMEOUT_US		SI1133_CMD_TIMEOUT_MS * 1000
91
92#define SI1133_REG_HOSTOUT(x)		(x) + 0x13
93
94#define SI1133_MEASUREMENT_FREQUENCY 1250
95
96#define SI1133_X_ORDER_MASK            0x0070
97#define SI1133_Y_ORDER_MASK            0x0007
98#define si1133_get_x_order(m)          ((m) & SI1133_X_ORDER_MASK) >> 4
99#define si1133_get_y_order(m)          ((m) & SI1133_Y_ORDER_MASK)
100
101#define SI1133_LUX_ADC_MASK		0xE
102#define SI1133_ADC_THRESHOLD		16000
103#define SI1133_INPUT_FRACTION_HIGH	7
104#define SI1133_INPUT_FRACTION_LOW	15
105#define SI1133_LUX_OUTPUT_FRACTION	12
106#define SI1133_LUX_BUFFER_SIZE		9
107#define SI1133_MEASURE_BUFFER_SIZE	3
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
240static int si1133_calculate_polynomial_inner(s32 input, u8 fraction, u16 mag,
241					     s8 shift)
242{
243	return ((input << fraction) / mag) << shift;
244}
245
246static int si1133_calculate_output(s32 x, s32 y, u8 x_order, u8 y_order,
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 */
282static int si1133_calc_polynomial(s32 x, s32 y, u8 input_fraction, u8 num_coeff,
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: 0x%02x\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: 0x%02x\n",
359			 cmd);
360		return -EOVERFLOW;
361	case SI1133_ERR_INVALID_LOCATION_CMD:
362		dev_warn(dev,
363			 "Parameter access to an invalid location: 0x%02x\n",
364			 cmd);
365		return -EINVAL;
366	case SI1133_ERR_INVALID_CMD:
367		dev_warn(dev, "Invalid command 0x%02x\n", cmd);
368		return -EINVAL;
369	default:
370		dev_warn(dev, "Unknown error 0x%02x\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 0x%02x, 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		}
415		err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
416		if (err)
417			goto out;
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 0x%02x, 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
620	u8 buffer[SI1133_MEASURE_BUFFER_SIZE];
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
631	err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(buffer),
632			       buffer);
633	if (err)
634		return err;
635
636	*val = sign_extend32(get_unaligned_be24(&buffer[0]), 23);
637
638	return err;
639}
640
641static irqreturn_t si1133_threaded_irq_handler(int irq, void *private)
642{
643	struct iio_dev *iio_dev = private;
644	struct si1133_data *data = iio_priv(iio_dev);
645	u32 irq_status;
646	int err;
647
648	err = regmap_read(data->regmap, SI1133_REG_IRQ_STATUS, &irq_status);
649	if (err) {
650		dev_err_ratelimited(&iio_dev->dev, "Error reading IRQ\n");
651		goto out;
652	}
653
654	if (irq_status != data->scan_mask)
655		return IRQ_NONE;
656
657out:
658	complete(&data->completion);
659
660	return IRQ_HANDLED;
661}
662
663static int si1133_scale_to_swgain(int scale_integer, int scale_fractional)
664{
665	scale_integer = find_closest(scale_integer, si1133_scale_available,
666				     ARRAY_SIZE(si1133_scale_available));
667	if (scale_integer < 0 ||
668	    scale_integer > ARRAY_SIZE(si1133_scale_available) ||
669	    scale_fractional != 0)
670		return -EINVAL;
671
672	return scale_integer;
673}
674
675static int si1133_chan_set_adcsens(struct si1133_data *data, u8 adc,
676				   u8 adc_sens)
677{
678	int err;
679
680	err = si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(adc), adc_sens);
681	if (err)
682		return err;
683
684	data->adc_sens[adc] = adc_sens;
685
686	return 0;
687}
688
689static int si1133_update_adcsens(struct si1133_data *data, u8 mask,
690				 u8 shift, u8 value)
691{
692	int err;
693	u32 adc_sens;
694
695	err = si1133_param_query(data, SI1133_PARAM_REG_ADCSENS(0),
696				 &adc_sens);
697	if (err)
698		return err;
699
700	adc_sens &= ~mask;
701	adc_sens |= (value << shift);
702
703	return si1133_chan_set_adcsens(data, 0, adc_sens);
704}
705
706static int si1133_get_lux(struct si1133_data *data, int *val)
707{
708	int err;
709	int lux;
710	s32 high_vis;
711	s32 low_vis;
712	s32 ir;
713	u8 buffer[SI1133_LUX_BUFFER_SIZE];
714
715	/* Activate lux channels */
716	err = si1133_set_chlist(data, SI1133_LUX_ADC_MASK);
717	if (err)
718		return err;
719
720	err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0),
721			       SI1133_LUX_BUFFER_SIZE, buffer);
722	if (err)
723		return err;
724
725	high_vis = sign_extend32(get_unaligned_be24(&buffer[0]), 23);
726
727	low_vis = sign_extend32(get_unaligned_be24(&buffer[3]), 23);
728
729	ir = sign_extend32(get_unaligned_be24(&buffer[6]), 23);
730
731	if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD)
732		lux = si1133_calc_polynomial(high_vis, ir,
733					     SI1133_INPUT_FRACTION_HIGH,
734					     ARRAY_SIZE(lux_coeff.coeff_high),
735					     &lux_coeff.coeff_high[0]);
736	else
737		lux = si1133_calc_polynomial(low_vis, ir,
738					     SI1133_INPUT_FRACTION_LOW,
739					     ARRAY_SIZE(lux_coeff.coeff_low),
740					     &lux_coeff.coeff_low[0]);
741
742	*val = lux >> SI1133_LUX_OUTPUT_FRACTION;
743
744	return err;
745}
746
747static int si1133_read_raw(struct iio_dev *iio_dev,
748			   struct iio_chan_spec const *chan,
749			   int *val, int *val2, long mask)
750{
751	struct si1133_data *data = iio_priv(iio_dev);
752	u8 adc_sens = data->adc_sens[0];
753	int err;
754
755	switch (mask) {
756	case IIO_CHAN_INFO_PROCESSED:
757		switch (chan->type) {
758		case IIO_LIGHT:
759			err = si1133_get_lux(data, val);
760			if (err)
761				return err;
762
763			return IIO_VAL_INT;
764		default:
765			return -EINVAL;
766		}
767	case IIO_CHAN_INFO_RAW:
768		switch (chan->type) {
769		case IIO_INTENSITY:
770		case IIO_UVINDEX:
771			err = si1133_measure(data, chan, val);
772			if (err)
773				return err;
774
775			return IIO_VAL_INT;
776		default:
777			return -EINVAL;
778		}
779	case IIO_CHAN_INFO_INT_TIME:
780		switch (chan->type) {
781		case IIO_INTENSITY:
782		case IIO_UVINDEX:
783			adc_sens &= SI1133_ADCSENS_HW_GAIN_MASK;
784
785			*val = si1133_int_time_table[adc_sens][0];
786			*val2 = si1133_int_time_table[adc_sens][1];
787			return IIO_VAL_INT_PLUS_MICRO;
788		default:
789			return -EINVAL;
790		}
791	case IIO_CHAN_INFO_SCALE:
792		switch (chan->type) {
793		case IIO_INTENSITY:
794		case IIO_UVINDEX:
795			adc_sens &= SI1133_ADCSENS_SCALE_MASK;
796			adc_sens >>= SI1133_ADCSENS_SCALE_SHIFT;
797
798			*val = BIT(adc_sens);
799
800			return IIO_VAL_INT;
801		default:
802			return -EINVAL;
803		}
804	case IIO_CHAN_INFO_HARDWAREGAIN:
805		switch (chan->type) {
806		case IIO_INTENSITY:
807		case IIO_UVINDEX:
808			adc_sens >>= SI1133_ADCSENS_HSIG_SHIFT;
809
810			*val = adc_sens;
811
812			return IIO_VAL_INT;
813		default:
814			return -EINVAL;
815		}
816	default:
817		return -EINVAL;
818	}
819}
820
821static int si1133_write_raw(struct iio_dev *iio_dev,
822			    struct iio_chan_spec const *chan,
823			    int val, int val2, long mask)
824{
825	struct si1133_data *data = iio_priv(iio_dev);
826
827	switch (mask) {
828	case IIO_CHAN_INFO_SCALE:
829		switch (chan->type) {
830		case IIO_INTENSITY:
831		case IIO_UVINDEX:
832			val = si1133_scale_to_swgain(val, val2);
833			if (val < 0)
834				return val;
835
836			return si1133_update_adcsens(data,
837						     SI1133_ADCSENS_SCALE_MASK,
838						     SI1133_ADCSENS_SCALE_SHIFT,
839						     val);
840		default:
841			return -EINVAL;
842		}
843	case IIO_CHAN_INFO_INT_TIME:
844		return si1133_set_integration_time(data, 0, val, val2);
845	case IIO_CHAN_INFO_HARDWAREGAIN:
846		switch (chan->type) {
847		case IIO_INTENSITY:
848		case IIO_UVINDEX:
849			if (val != 0 && val != 1)
850				return -EINVAL;
851
852			return si1133_update_adcsens(data,
853						     SI1133_ADCSENS_HSIG_MASK,
854						     SI1133_ADCSENS_HSIG_SHIFT,
855						     val);
856		default:
857			return -EINVAL;
858		}
859	default:
860		return -EINVAL;
861	}
862}
863
864static struct attribute *si1133_attributes[] = {
865	&iio_const_attr_integration_time_available.dev_attr.attr,
866	&iio_const_attr_scale_available.dev_attr.attr,
867	NULL,
868};
869
870static const struct attribute_group si1133_attribute_group = {
871	.attrs = si1133_attributes,
872};
873
874static const struct iio_info si1133_info = {
875	.read_raw = si1133_read_raw,
876	.write_raw = si1133_write_raw,
877	.attrs = &si1133_attribute_group,
878};
879
880/*
881 * si1133_init_lux_channels - Configure 3 different channels(adc) (1,2 and 3)
882 * The channel configuration for the lux measurement was taken from :
883 * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00578
884 *
885 * Reserved the channel 0 for the other raw measurements
886 */
887static int si1133_init_lux_channels(struct si1133_data *data)
888{
889	int err;
890
891	err = si1133_chan_set_adcconfig(data, 1,
892					SI1133_ADCCONFIG_DECIM_RATE(1) |
893					SI1133_PARAM_ADCMUX_LARGE_WHITE);
894	if (err)
895		return err;
896
897	err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(1),
898			       SI1133_ADCPOST_24BIT_EN |
899			       SI1133_ADCPOST_POSTSHIFT_BITQTY(0));
900	if (err)
901		return err;
902	err = si1133_chan_set_adcsens(data, 1, SI1133_ADCSENS_HSIG_MASK |
903				      SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
904	if (err)
905		return err;
906
907	err = si1133_chan_set_adcconfig(data, 2,
908					SI1133_ADCCONFIG_DECIM_RATE(1) |
909					SI1133_PARAM_ADCMUX_LARGE_WHITE);
910	if (err)
911		return err;
912
913	err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(2),
914			       SI1133_ADCPOST_24BIT_EN |
915			       SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
916	if (err)
917		return err;
918
919	err = si1133_chan_set_adcsens(data, 2, SI1133_ADCSENS_HSIG_MASK |
920				      SI1133_ADCSENS_NB_MEAS(1) | _3_120_0_us);
921	if (err)
922		return err;
923
924	err = si1133_chan_set_adcconfig(data, 3,
925					SI1133_ADCCONFIG_DECIM_RATE(1) |
926					SI1133_PARAM_ADCMUX_MED_IR);
927	if (err)
928		return err;
929
930	err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(3),
931			       SI1133_ADCPOST_24BIT_EN |
932			       SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
933	if (err)
934		return err;
935
936	return  si1133_chan_set_adcsens(data, 3, SI1133_ADCSENS_HSIG_MASK |
937					SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
938}
939
940static int si1133_initialize(struct si1133_data *data)
941{
942	int err;
943
944	err = si1133_cmd_reset_sw(data);
945	if (err)
946		return err;
947
948	/* Turn off autonomous mode */
949	err = si1133_param_set(data, SI1133_REG_MEAS_RATE, 0);
950	if (err)
951		return err;
952
953	err = si1133_init_lux_channels(data);
954	if (err)
955		return err;
956
957	return regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE,
958			    SI1133_IRQ_CHANNEL_ENABLE);
959}
960
961static int si1133_validate_ids(struct iio_dev *iio_dev)
962{
963	struct si1133_data *data = iio_priv(iio_dev);
964
965	unsigned int part_id, rev_id, mfr_id;
966	int err;
967
968	err = regmap_read(data->regmap, SI1133_REG_PART_ID, &part_id);
969	if (err)
970		return err;
971
972	err = regmap_read(data->regmap, SI1133_REG_REV_ID, &rev_id);
973	if (err)
974		return err;
975
976	err = regmap_read(data->regmap, SI1133_REG_MFR_ID, &mfr_id);
977	if (err)
978		return err;
979
980	dev_info(&iio_dev->dev,
981		 "Device ID part 0x%02x rev 0x%02x mfr 0x%02x\n",
982		 part_id, rev_id, mfr_id);
983	if (part_id != SI1133_PART_ID) {
984		dev_err(&iio_dev->dev,
985			"Part ID mismatch got 0x%02x, expected 0x%02x\n",
986			part_id, SI1133_PART_ID);
987		return -ENODEV;
988	}
989
990	return 0;
991}
992
993static int si1133_probe(struct i2c_client *client)
994{
995	const struct i2c_device_id *id = i2c_client_get_device_id(client);
996	struct si1133_data *data;
997	struct iio_dev *iio_dev;
998	int err;
999
1000	iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1001	if (!iio_dev)
1002		return -ENOMEM;
1003
1004	data = iio_priv(iio_dev);
1005
1006	init_completion(&data->completion);
1007
1008	data->regmap = devm_regmap_init_i2c(client, &si1133_regmap_config);
1009	if (IS_ERR(data->regmap)) {
1010		err = PTR_ERR(data->regmap);
1011		dev_err(&client->dev, "Failed to initialise regmap: %d\n", err);
1012		return err;
1013	}
1014
1015	i2c_set_clientdata(client, iio_dev);
1016	data->client = client;
1017
1018	iio_dev->name = id->name;
1019	iio_dev->channels = si1133_channels;
1020	iio_dev->num_channels = ARRAY_SIZE(si1133_channels);
1021	iio_dev->info = &si1133_info;
1022	iio_dev->modes = INDIO_DIRECT_MODE;
1023
1024	mutex_init(&data->mutex);
1025
1026	err = si1133_validate_ids(iio_dev);
1027	if (err)
1028		return err;
1029
1030	err = si1133_initialize(data);
1031	if (err) {
1032		dev_err(&client->dev,
1033			"Error when initializing chip: %d\n", err);
1034		return err;
1035	}
1036
1037	if (!client->irq) {
1038		dev_err(&client->dev,
1039			"Required interrupt not provided, cannot proceed\n");
1040		return -EINVAL;
1041	}
1042
1043	err = devm_request_threaded_irq(&client->dev, client->irq,
1044					NULL,
1045					si1133_threaded_irq_handler,
1046					IRQF_ONESHOT | IRQF_SHARED,
1047					client->name, iio_dev);
1048	if (err) {
1049		dev_warn(&client->dev, "Request irq %d failed: %i\n",
1050			 client->irq, err);
1051		return err;
1052	}
1053
1054	return devm_iio_device_register(&client->dev, iio_dev);
1055}
1056
1057static const struct i2c_device_id si1133_ids[] = {
1058	{ "si1133", 0 },
1059	{ }
1060};
1061MODULE_DEVICE_TABLE(i2c, si1133_ids);
1062
1063static struct i2c_driver si1133_driver = {
1064	.driver = {
1065	    .name   = "si1133",
1066	},
1067	.probe = si1133_probe,
1068	.id_table = si1133_ids,
1069};
1070
1071module_i2c_driver(si1133_driver);
1072
1073MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
1074MODULE_DESCRIPTION("Silabs SI1133, UV index sensor and ambient light sensor driver");
1075MODULE_LICENSE("GPL");
1076