cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

si1133.c (25352B)


      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			const struct i2c_device_id *id)
    995{
    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");