Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * si1133.c - Support for Silabs SI1133 combined ambient
0004  * light and UV index sensors
0005  *
0006  * Copyright 2018 Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>
0007  */
0008 
0009 #include <linux/delay.h>
0010 #include <linux/i2c.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/module.h>
0013 #include <linux/regmap.h>
0014 
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 
0018 #include <linux/util_macros.h>
0019 
0020 #include <asm/unaligned.h>
0021 
0022 #define SI1133_REG_PART_ID      0x00
0023 #define SI1133_REG_REV_ID       0x01
0024 #define SI1133_REG_MFR_ID       0x02
0025 #define SI1133_REG_INFO0        0x03
0026 #define SI1133_REG_INFO1        0x04
0027 
0028 #define SI1133_PART_ID          0x33
0029 
0030 #define SI1133_REG_HOSTIN0      0x0A
0031 #define SI1133_REG_COMMAND      0x0B
0032 #define SI1133_REG_IRQ_ENABLE       0x0F
0033 #define SI1133_REG_RESPONSE1        0x10
0034 #define SI1133_REG_RESPONSE0        0x11
0035 #define SI1133_REG_IRQ_STATUS       0x12
0036 #define SI1133_REG_MEAS_RATE        0x1A
0037 
0038 #define SI1133_IRQ_CHANNEL_ENABLE   0xF
0039 
0040 #define SI1133_CMD_RESET_CTR        0x00
0041 #define SI1133_CMD_RESET_SW     0x01
0042 #define SI1133_CMD_FORCE        0x11
0043 #define SI1133_CMD_START_AUTONOMOUS 0x13
0044 #define SI1133_CMD_PARAM_SET        0x80
0045 #define SI1133_CMD_PARAM_QUERY      0x40
0046 #define SI1133_CMD_PARAM_MASK       0x3F
0047 
0048 #define SI1133_CMD_ERR_MASK     BIT(4)
0049 #define SI1133_CMD_SEQ_MASK     0xF
0050 #define SI1133_MAX_CMD_CTR      0xF
0051 
0052 #define SI1133_PARAM_REG_CHAN_LIST  0x01
0053 #define SI1133_PARAM_REG_ADCCONFIG(x)   ((x) * 4) + 2
0054 #define SI1133_PARAM_REG_ADCSENS(x) ((x) * 4) + 3
0055 #define SI1133_PARAM_REG_ADCPOST(x) ((x) * 4) + 4
0056 
0057 #define SI1133_ADCMUX_MASK 0x1F
0058 
0059 #define SI1133_ADCCONFIG_DECIM_RATE(x)  (x) << 5
0060 
0061 #define SI1133_ADCSENS_SCALE_MASK 0x70
0062 #define SI1133_ADCSENS_SCALE_SHIFT 4
0063 #define SI1133_ADCSENS_HSIG_MASK BIT(7)
0064 #define SI1133_ADCSENS_HSIG_SHIFT 7
0065 #define SI1133_ADCSENS_HW_GAIN_MASK 0xF
0066 #define SI1133_ADCSENS_NB_MEAS(x)   fls(x) << SI1133_ADCSENS_SCALE_SHIFT
0067 
0068 #define SI1133_ADCPOST_24BIT_EN BIT(6)
0069 #define SI1133_ADCPOST_POSTSHIFT_BITQTY(x) (x & GENMASK(2, 0)) << 3
0070 
0071 #define SI1133_PARAM_ADCMUX_SMALL_IR    0x0
0072 #define SI1133_PARAM_ADCMUX_MED_IR  0x1
0073 #define SI1133_PARAM_ADCMUX_LARGE_IR    0x2
0074 #define SI1133_PARAM_ADCMUX_WHITE   0xB
0075 #define SI1133_PARAM_ADCMUX_LARGE_WHITE 0xD
0076 #define SI1133_PARAM_ADCMUX_UV      0x18
0077 #define SI1133_PARAM_ADCMUX_UV_DEEP 0x19
0078 
0079 #define SI1133_ERR_INVALID_CMD      0x0
0080 #define SI1133_ERR_INVALID_LOCATION_CMD 0x1
0081 #define SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION 0x2
0082 #define SI1133_ERR_OUTPUT_BUFFER_OVERFLOW 0x3
0083 
0084 #define SI1133_COMPLETION_TIMEOUT_MS    500
0085 
0086 #define SI1133_CMD_MINSLEEP_US_LOW  5000
0087 #define SI1133_CMD_MINSLEEP_US_HIGH 7500
0088 #define SI1133_CMD_TIMEOUT_MS       25
0089 #define SI1133_CMD_LUX_TIMEOUT_MS   5000
0090 #define SI1133_CMD_TIMEOUT_US       SI1133_CMD_TIMEOUT_MS * 1000
0091 
0092 #define SI1133_REG_HOSTOUT(x)       (x) + 0x13
0093 
0094 #define SI1133_MEASUREMENT_FREQUENCY 1250
0095 
0096 #define SI1133_X_ORDER_MASK            0x0070
0097 #define SI1133_Y_ORDER_MASK            0x0007
0098 #define si1133_get_x_order(m)          ((m) & SI1133_X_ORDER_MASK) >> 4
0099 #define si1133_get_y_order(m)          ((m) & SI1133_Y_ORDER_MASK)
0100 
0101 #define SI1133_LUX_ADC_MASK     0xE
0102 #define SI1133_ADC_THRESHOLD        16000
0103 #define SI1133_INPUT_FRACTION_HIGH  7
0104 #define SI1133_INPUT_FRACTION_LOW   15
0105 #define SI1133_LUX_OUTPUT_FRACTION  12
0106 #define SI1133_LUX_BUFFER_SIZE      9
0107 #define SI1133_MEASURE_BUFFER_SIZE  3
0108 
0109 static const int si1133_scale_available[] = {
0110     1, 2, 4, 8, 16, 32, 64, 128};
0111 
0112 static IIO_CONST_ATTR(scale_available, "1 2 4 8 16 32 64 128");
0113 
0114 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.0244 0.0488 0.0975 0.195 0.390 0.780 "
0115                      "1.560 3.120 6.24 12.48 25.0 50.0");
0116 
0117 /* A.K.A. HW_GAIN in datasheet */
0118 enum si1133_int_time {
0119         _24_4_us = 0,
0120         _48_8_us = 1,
0121         _97_5_us = 2,
0122        _195_0_us = 3,
0123        _390_0_us = 4,
0124        _780_0_us = 5,
0125      _1_560_0_us = 6,
0126      _3_120_0_us = 7,
0127      _6_240_0_us = 8,
0128     _12_480_0_us = 9,
0129     _25_ms = 10,
0130     _50_ms = 11,
0131 };
0132 
0133 /* Integration time in milliseconds, nanoseconds */
0134 static const int si1133_int_time_table[][2] = {
0135     [_24_4_us] = {0, 24400},
0136     [_48_8_us] = {0, 48800},
0137     [_97_5_us] = {0, 97500},
0138     [_195_0_us] = {0, 195000},
0139     [_390_0_us] = {0, 390000},
0140     [_780_0_us] = {0, 780000},
0141     [_1_560_0_us] = {1, 560000},
0142     [_3_120_0_us] = {3, 120000},
0143     [_6_240_0_us] = {6, 240000},
0144     [_12_480_0_us] = {12, 480000},
0145     [_25_ms] = {25, 000000},
0146     [_50_ms] = {50, 000000},
0147 };
0148 
0149 static const struct regmap_range si1133_reg_ranges[] = {
0150     regmap_reg_range(0x00, 0x02),
0151     regmap_reg_range(0x0A, 0x0B),
0152     regmap_reg_range(0x0F, 0x0F),
0153     regmap_reg_range(0x10, 0x12),
0154     regmap_reg_range(0x13, 0x2C),
0155 };
0156 
0157 static const struct regmap_range si1133_reg_ro_ranges[] = {
0158     regmap_reg_range(0x00, 0x02),
0159     regmap_reg_range(0x10, 0x2C),
0160 };
0161 
0162 static const struct regmap_range si1133_precious_ranges[] = {
0163     regmap_reg_range(0x12, 0x12),
0164 };
0165 
0166 static const struct regmap_access_table si1133_write_ranges_table = {
0167     .yes_ranges = si1133_reg_ranges,
0168     .n_yes_ranges   = ARRAY_SIZE(si1133_reg_ranges),
0169     .no_ranges  = si1133_reg_ro_ranges,
0170     .n_no_ranges    = ARRAY_SIZE(si1133_reg_ro_ranges),
0171 };
0172 
0173 static const struct regmap_access_table si1133_read_ranges_table = {
0174     .yes_ranges = si1133_reg_ranges,
0175     .n_yes_ranges   = ARRAY_SIZE(si1133_reg_ranges),
0176 };
0177 
0178 static const struct regmap_access_table si1133_precious_table = {
0179     .yes_ranges = si1133_precious_ranges,
0180     .n_yes_ranges   = ARRAY_SIZE(si1133_precious_ranges),
0181 };
0182 
0183 static const struct regmap_config si1133_regmap_config = {
0184     .reg_bits = 8,
0185     .val_bits = 8,
0186 
0187     .max_register = 0x2C,
0188 
0189     .wr_table = &si1133_write_ranges_table,
0190     .rd_table = &si1133_read_ranges_table,
0191 
0192     .precious_table = &si1133_precious_table,
0193 };
0194 
0195 struct si1133_data {
0196     struct regmap *regmap;
0197     struct i2c_client *client;
0198 
0199     /* Lock protecting one command at a time can be processed */
0200     struct mutex mutex;
0201 
0202     int rsp_seq;
0203     u8 scan_mask;
0204     u8 adc_sens[6];
0205     u8 adc_config[6];
0206 
0207     struct completion completion;
0208 };
0209 
0210 struct si1133_coeff {
0211     s16 info;
0212     u16 mag;
0213 };
0214 
0215 struct si1133_lux_coeff {
0216     struct si1133_coeff coeff_high[4];
0217     struct si1133_coeff coeff_low[9];
0218 };
0219 
0220 static const struct si1133_lux_coeff lux_coeff = {
0221     {
0222         {  0,   209},
0223         { 1665,  93},
0224         { 2064,  65},
0225         {-2671, 234}
0226     },
0227     {
0228         {    0,     0},
0229         { 1921, 29053},
0230         {-1022, 36363},
0231         { 2320, 20789},
0232         { -367, 57909},
0233         {-1774, 38240},
0234         { -608, 46775},
0235         {-1503, 51831},
0236         {-1886, 58928}
0237     }
0238 };
0239 
0240 static int si1133_calculate_polynomial_inner(s32 input, u8 fraction, u16 mag,
0241                          s8 shift)
0242 {
0243     return ((input << fraction) / mag) << shift;
0244 }
0245 
0246 static int si1133_calculate_output(s32 x, s32 y, u8 x_order, u8 y_order,
0247                    u8 input_fraction, s8 sign,
0248                    const struct si1133_coeff *coeffs)
0249 {
0250     s8 shift;
0251     int x1 = 1;
0252     int x2 = 1;
0253     int y1 = 1;
0254     int y2 = 1;
0255 
0256     shift = ((u16)coeffs->info & 0xFF00) >> 8;
0257     shift ^= 0xFF;
0258     shift += 1;
0259     shift = -shift;
0260 
0261     if (x_order > 0) {
0262         x1 = si1133_calculate_polynomial_inner(x, input_fraction,
0263                                coeffs->mag, shift);
0264         if (x_order > 1)
0265             x2 = x1;
0266     }
0267 
0268     if (y_order > 0) {
0269         y1 = si1133_calculate_polynomial_inner(y, input_fraction,
0270                                coeffs->mag, shift);
0271         if (y_order > 1)
0272             y2 = y1;
0273     }
0274 
0275     return sign * x1 * x2 * y1 * y2;
0276 }
0277 
0278 /*
0279  * The algorithm is from:
0280  * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00716
0281  */
0282 static int si1133_calc_polynomial(s32 x, s32 y, u8 input_fraction, u8 num_coeff,
0283                   const struct si1133_coeff *coeffs)
0284 {
0285     u8 x_order, y_order;
0286     u8 counter;
0287     s8 sign;
0288     int output = 0;
0289 
0290     for (counter = 0; counter < num_coeff; counter++) {
0291         if (coeffs->info < 0)
0292             sign = -1;
0293         else
0294             sign = 1;
0295 
0296         x_order = si1133_get_x_order(coeffs->info);
0297         y_order = si1133_get_y_order(coeffs->info);
0298 
0299         if ((x_order == 0) && (y_order == 0))
0300             output +=
0301                    sign * coeffs->mag << SI1133_LUX_OUTPUT_FRACTION;
0302         else
0303             output += si1133_calculate_output(x, y, x_order,
0304                               y_order,
0305                               input_fraction, sign,
0306                               coeffs);
0307         coeffs++;
0308     }
0309 
0310     return abs(output);
0311 }
0312 
0313 static int si1133_cmd_reset_sw(struct si1133_data *data)
0314 {
0315     struct device *dev = &data->client->dev;
0316     unsigned int resp;
0317     unsigned long timeout;
0318     int err;
0319 
0320     err = regmap_write(data->regmap, SI1133_REG_COMMAND,
0321                SI1133_CMD_RESET_SW);
0322     if (err)
0323         return err;
0324 
0325     timeout = jiffies + msecs_to_jiffies(SI1133_CMD_TIMEOUT_MS);
0326     while (true) {
0327         err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
0328         if (err == -ENXIO) {
0329             usleep_range(SI1133_CMD_MINSLEEP_US_LOW,
0330                      SI1133_CMD_MINSLEEP_US_HIGH);
0331             continue;
0332         }
0333 
0334         if ((resp & SI1133_MAX_CMD_CTR) == SI1133_MAX_CMD_CTR)
0335             break;
0336 
0337         if (time_after(jiffies, timeout)) {
0338             dev_warn(dev, "Timeout on reset ctr resp: %d\n", resp);
0339             return -ETIMEDOUT;
0340         }
0341     }
0342 
0343     if (!err)
0344         data->rsp_seq = SI1133_MAX_CMD_CTR;
0345 
0346     return err;
0347 }
0348 
0349 static int si1133_parse_response_err(struct device *dev, u32 resp, u8 cmd)
0350 {
0351     resp &= 0xF;
0352 
0353     switch (resp) {
0354     case SI1133_ERR_OUTPUT_BUFFER_OVERFLOW:
0355         dev_warn(dev, "Output buffer overflow: 0x%02x\n", cmd);
0356         return -EOVERFLOW;
0357     case SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION:
0358         dev_warn(dev, "Saturation of the ADC or overflow of accumulation: 0x%02x\n",
0359              cmd);
0360         return -EOVERFLOW;
0361     case SI1133_ERR_INVALID_LOCATION_CMD:
0362         dev_warn(dev,
0363              "Parameter access to an invalid location: 0x%02x\n",
0364              cmd);
0365         return -EINVAL;
0366     case SI1133_ERR_INVALID_CMD:
0367         dev_warn(dev, "Invalid command 0x%02x\n", cmd);
0368         return -EINVAL;
0369     default:
0370         dev_warn(dev, "Unknown error 0x%02x\n", cmd);
0371         return -EINVAL;
0372     }
0373 }
0374 
0375 static int si1133_cmd_reset_counter(struct si1133_data *data)
0376 {
0377     int err = regmap_write(data->regmap, SI1133_REG_COMMAND,
0378                    SI1133_CMD_RESET_CTR);
0379     if (err)
0380         return err;
0381 
0382     data->rsp_seq = 0;
0383 
0384     return 0;
0385 }
0386 
0387 static int si1133_command(struct si1133_data *data, u8 cmd)
0388 {
0389     struct device *dev = &data->client->dev;
0390     u32 resp;
0391     int err;
0392     int expected_seq;
0393 
0394     mutex_lock(&data->mutex);
0395 
0396     expected_seq = (data->rsp_seq + 1) & SI1133_MAX_CMD_CTR;
0397 
0398     if (cmd == SI1133_CMD_FORCE)
0399         reinit_completion(&data->completion);
0400 
0401     err = regmap_write(data->regmap, SI1133_REG_COMMAND, cmd);
0402     if (err) {
0403         dev_warn(dev, "Failed to write command 0x%02x, ret=%d\n", cmd,
0404              err);
0405         goto out;
0406     }
0407 
0408     if (cmd == SI1133_CMD_FORCE) {
0409         /* wait for irq */
0410         if (!wait_for_completion_timeout(&data->completion,
0411             msecs_to_jiffies(SI1133_COMPLETION_TIMEOUT_MS))) {
0412             err = -ETIMEDOUT;
0413             goto out;
0414         }
0415         err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
0416         if (err)
0417             goto out;
0418     } else {
0419         err = regmap_read_poll_timeout(data->regmap,
0420                            SI1133_REG_RESPONSE0, resp,
0421                            (resp & SI1133_CMD_SEQ_MASK) ==
0422                            expected_seq ||
0423                            (resp & SI1133_CMD_ERR_MASK),
0424                            SI1133_CMD_MINSLEEP_US_LOW,
0425                            SI1133_CMD_TIMEOUT_MS * 1000);
0426         if (err) {
0427             dev_warn(dev,
0428                  "Failed to read command 0x%02x, ret=%d\n",
0429                  cmd, err);
0430             goto out;
0431         }
0432     }
0433 
0434     if (resp & SI1133_CMD_ERR_MASK) {
0435         err = si1133_parse_response_err(dev, resp, cmd);
0436         si1133_cmd_reset_counter(data);
0437     } else {
0438         data->rsp_seq = expected_seq;
0439     }
0440 
0441 out:
0442     mutex_unlock(&data->mutex);
0443 
0444     return err;
0445 }
0446 
0447 static int si1133_param_set(struct si1133_data *data, u8 param, u32 value)
0448 {
0449     int err = regmap_write(data->regmap, SI1133_REG_HOSTIN0, value);
0450 
0451     if (err)
0452         return err;
0453 
0454     return si1133_command(data, SI1133_CMD_PARAM_SET |
0455                   (param & SI1133_CMD_PARAM_MASK));
0456 }
0457 
0458 static int si1133_param_query(struct si1133_data *data, u8 param, u32 *result)
0459 {
0460     int err = si1133_command(data, SI1133_CMD_PARAM_QUERY |
0461                  (param & SI1133_CMD_PARAM_MASK));
0462     if (err)
0463         return err;
0464 
0465     return regmap_read(data->regmap, SI1133_REG_RESPONSE1, result);
0466 }
0467 
0468 #define SI1133_CHANNEL(_ch, _type) \
0469     .type = _type, \
0470     .channel = _ch, \
0471     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0472     .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | \
0473         BIT(IIO_CHAN_INFO_SCALE) | \
0474         BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
0475 
0476 static const struct iio_chan_spec si1133_channels[] = {
0477     {
0478         .type = IIO_LIGHT,
0479         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0480         .channel = 0,
0481     },
0482     {
0483         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_WHITE, IIO_INTENSITY)
0484         .channel2 = IIO_MOD_LIGHT_BOTH,
0485     },
0486     {
0487         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_WHITE, IIO_INTENSITY)
0488         .channel2 = IIO_MOD_LIGHT_BOTH,
0489         .extend_name = "large",
0490     },
0491     {
0492         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_SMALL_IR, IIO_INTENSITY)
0493         .extend_name = "small",
0494         .modified = 1,
0495         .channel2 = IIO_MOD_LIGHT_IR,
0496     },
0497     {
0498         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_MED_IR, IIO_INTENSITY)
0499         .modified = 1,
0500         .channel2 = IIO_MOD_LIGHT_IR,
0501     },
0502     {
0503         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_IR, IIO_INTENSITY)
0504         .extend_name = "large",
0505         .modified = 1,
0506         .channel2 = IIO_MOD_LIGHT_IR,
0507     },
0508     {
0509         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV, IIO_UVINDEX)
0510     },
0511     {
0512         SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV_DEEP, IIO_UVINDEX)
0513         .modified = 1,
0514         .channel2 = IIO_MOD_LIGHT_DUV,
0515     }
0516 };
0517 
0518 static int si1133_get_int_time_index(int milliseconds, int nanoseconds)
0519 {
0520     int i;
0521 
0522     for (i = 0; i < ARRAY_SIZE(si1133_int_time_table); i++) {
0523         if (milliseconds == si1133_int_time_table[i][0] &&
0524             nanoseconds == si1133_int_time_table[i][1])
0525             return i;
0526     }
0527     return -EINVAL;
0528 }
0529 
0530 static int si1133_set_integration_time(struct si1133_data *data, u8 adc,
0531                        int milliseconds, int nanoseconds)
0532 {
0533     int index;
0534 
0535     index = si1133_get_int_time_index(milliseconds, nanoseconds);
0536     if (index < 0)
0537         return index;
0538 
0539     data->adc_sens[adc] &= 0xF0;
0540     data->adc_sens[adc] |= index;
0541 
0542     return si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(0),
0543                 data->adc_sens[adc]);
0544 }
0545 
0546 static int si1133_set_chlist(struct si1133_data *data, u8 scan_mask)
0547 {
0548     /* channel list already set, no need to reprogram */
0549     if (data->scan_mask == scan_mask)
0550         return 0;
0551 
0552     data->scan_mask = scan_mask;
0553 
0554     return si1133_param_set(data, SI1133_PARAM_REG_CHAN_LIST, scan_mask);
0555 }
0556 
0557 static int si1133_chan_set_adcconfig(struct si1133_data *data, u8 adc,
0558                      u8 adc_config)
0559 {
0560     int err;
0561 
0562     err = si1133_param_set(data, SI1133_PARAM_REG_ADCCONFIG(adc),
0563                    adc_config);
0564     if (err)
0565         return err;
0566 
0567     data->adc_config[adc] = adc_config;
0568 
0569     return 0;
0570 }
0571 
0572 static int si1133_update_adcconfig(struct si1133_data *data, uint8_t adc,
0573                    u8 mask, u8 shift, u8 value)
0574 {
0575     u32 adc_config;
0576     int err;
0577 
0578     err = si1133_param_query(data, SI1133_PARAM_REG_ADCCONFIG(adc),
0579                  &adc_config);
0580     if (err)
0581         return err;
0582 
0583     adc_config &= ~mask;
0584     adc_config |= (value << shift);
0585 
0586     return si1133_chan_set_adcconfig(data, adc, adc_config);
0587 }
0588 
0589 static int si1133_set_adcmux(struct si1133_data *data, u8 adc, u8 mux)
0590 {
0591     if ((mux & data->adc_config[adc]) == mux)
0592         return 0; /* mux already set to correct value */
0593 
0594     return si1133_update_adcconfig(data, adc, SI1133_ADCMUX_MASK, 0, mux);
0595 }
0596 
0597 static int si1133_force_measurement(struct si1133_data *data)
0598 {
0599     return si1133_command(data, SI1133_CMD_FORCE);
0600 }
0601 
0602 static int si1133_bulk_read(struct si1133_data *data, u8 start_reg, u8 length,
0603                 u8 *buffer)
0604 {
0605     int err;
0606 
0607     err = si1133_force_measurement(data);
0608     if (err)
0609         return err;
0610 
0611     return regmap_bulk_read(data->regmap, start_reg, buffer, length);
0612 }
0613 
0614 static int si1133_measure(struct si1133_data *data,
0615               struct iio_chan_spec const *chan,
0616               int *val)
0617 {
0618     int err;
0619 
0620     u8 buffer[SI1133_MEASURE_BUFFER_SIZE];
0621 
0622     err = si1133_set_adcmux(data, 0, chan->channel);
0623     if (err)
0624         return err;
0625 
0626     /* Deactivate lux measurements if they were active */
0627     err = si1133_set_chlist(data, BIT(0));
0628     if (err)
0629         return err;
0630 
0631     err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(buffer),
0632                    buffer);
0633     if (err)
0634         return err;
0635 
0636     *val = sign_extend32(get_unaligned_be24(&buffer[0]), 23);
0637 
0638     return err;
0639 }
0640 
0641 static irqreturn_t si1133_threaded_irq_handler(int irq, void *private)
0642 {
0643     struct iio_dev *iio_dev = private;
0644     struct si1133_data *data = iio_priv(iio_dev);
0645     u32 irq_status;
0646     int err;
0647 
0648     err = regmap_read(data->regmap, SI1133_REG_IRQ_STATUS, &irq_status);
0649     if (err) {
0650         dev_err_ratelimited(&iio_dev->dev, "Error reading IRQ\n");
0651         goto out;
0652     }
0653 
0654     if (irq_status != data->scan_mask)
0655         return IRQ_NONE;
0656 
0657 out:
0658     complete(&data->completion);
0659 
0660     return IRQ_HANDLED;
0661 }
0662 
0663 static int si1133_scale_to_swgain(int scale_integer, int scale_fractional)
0664 {
0665     scale_integer = find_closest(scale_integer, si1133_scale_available,
0666                      ARRAY_SIZE(si1133_scale_available));
0667     if (scale_integer < 0 ||
0668         scale_integer > ARRAY_SIZE(si1133_scale_available) ||
0669         scale_fractional != 0)
0670         return -EINVAL;
0671 
0672     return scale_integer;
0673 }
0674 
0675 static int si1133_chan_set_adcsens(struct si1133_data *data, u8 adc,
0676                    u8 adc_sens)
0677 {
0678     int err;
0679 
0680     err = si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(adc), adc_sens);
0681     if (err)
0682         return err;
0683 
0684     data->adc_sens[adc] = adc_sens;
0685 
0686     return 0;
0687 }
0688 
0689 static int si1133_update_adcsens(struct si1133_data *data, u8 mask,
0690                  u8 shift, u8 value)
0691 {
0692     int err;
0693     u32 adc_sens;
0694 
0695     err = si1133_param_query(data, SI1133_PARAM_REG_ADCSENS(0),
0696                  &adc_sens);
0697     if (err)
0698         return err;
0699 
0700     adc_sens &= ~mask;
0701     adc_sens |= (value << shift);
0702 
0703     return si1133_chan_set_adcsens(data, 0, adc_sens);
0704 }
0705 
0706 static int si1133_get_lux(struct si1133_data *data, int *val)
0707 {
0708     int err;
0709     int lux;
0710     s32 high_vis;
0711     s32 low_vis;
0712     s32 ir;
0713     u8 buffer[SI1133_LUX_BUFFER_SIZE];
0714 
0715     /* Activate lux channels */
0716     err = si1133_set_chlist(data, SI1133_LUX_ADC_MASK);
0717     if (err)
0718         return err;
0719 
0720     err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0),
0721                    SI1133_LUX_BUFFER_SIZE, buffer);
0722     if (err)
0723         return err;
0724 
0725     high_vis = sign_extend32(get_unaligned_be24(&buffer[0]), 23);
0726 
0727     low_vis = sign_extend32(get_unaligned_be24(&buffer[3]), 23);
0728 
0729     ir = sign_extend32(get_unaligned_be24(&buffer[6]), 23);
0730 
0731     if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD)
0732         lux = si1133_calc_polynomial(high_vis, ir,
0733                          SI1133_INPUT_FRACTION_HIGH,
0734                          ARRAY_SIZE(lux_coeff.coeff_high),
0735                          &lux_coeff.coeff_high[0]);
0736     else
0737         lux = si1133_calc_polynomial(low_vis, ir,
0738                          SI1133_INPUT_FRACTION_LOW,
0739                          ARRAY_SIZE(lux_coeff.coeff_low),
0740                          &lux_coeff.coeff_low[0]);
0741 
0742     *val = lux >> SI1133_LUX_OUTPUT_FRACTION;
0743 
0744     return err;
0745 }
0746 
0747 static int si1133_read_raw(struct iio_dev *iio_dev,
0748                struct iio_chan_spec const *chan,
0749                int *val, int *val2, long mask)
0750 {
0751     struct si1133_data *data = iio_priv(iio_dev);
0752     u8 adc_sens = data->adc_sens[0];
0753     int err;
0754 
0755     switch (mask) {
0756     case IIO_CHAN_INFO_PROCESSED:
0757         switch (chan->type) {
0758         case IIO_LIGHT:
0759             err = si1133_get_lux(data, val);
0760             if (err)
0761                 return err;
0762 
0763             return IIO_VAL_INT;
0764         default:
0765             return -EINVAL;
0766         }
0767     case IIO_CHAN_INFO_RAW:
0768         switch (chan->type) {
0769         case IIO_INTENSITY:
0770         case IIO_UVINDEX:
0771             err = si1133_measure(data, chan, val);
0772             if (err)
0773                 return err;
0774 
0775             return IIO_VAL_INT;
0776         default:
0777             return -EINVAL;
0778         }
0779     case IIO_CHAN_INFO_INT_TIME:
0780         switch (chan->type) {
0781         case IIO_INTENSITY:
0782         case IIO_UVINDEX:
0783             adc_sens &= SI1133_ADCSENS_HW_GAIN_MASK;
0784 
0785             *val = si1133_int_time_table[adc_sens][0];
0786             *val2 = si1133_int_time_table[adc_sens][1];
0787             return IIO_VAL_INT_PLUS_MICRO;
0788         default:
0789             return -EINVAL;
0790         }
0791     case IIO_CHAN_INFO_SCALE:
0792         switch (chan->type) {
0793         case IIO_INTENSITY:
0794         case IIO_UVINDEX:
0795             adc_sens &= SI1133_ADCSENS_SCALE_MASK;
0796             adc_sens >>= SI1133_ADCSENS_SCALE_SHIFT;
0797 
0798             *val = BIT(adc_sens);
0799 
0800             return IIO_VAL_INT;
0801         default:
0802             return -EINVAL;
0803         }
0804     case IIO_CHAN_INFO_HARDWAREGAIN:
0805         switch (chan->type) {
0806         case IIO_INTENSITY:
0807         case IIO_UVINDEX:
0808             adc_sens >>= SI1133_ADCSENS_HSIG_SHIFT;
0809 
0810             *val = adc_sens;
0811 
0812             return IIO_VAL_INT;
0813         default:
0814             return -EINVAL;
0815         }
0816     default:
0817         return -EINVAL;
0818     }
0819 }
0820 
0821 static int si1133_write_raw(struct iio_dev *iio_dev,
0822                 struct iio_chan_spec const *chan,
0823                 int val, int val2, long mask)
0824 {
0825     struct si1133_data *data = iio_priv(iio_dev);
0826 
0827     switch (mask) {
0828     case IIO_CHAN_INFO_SCALE:
0829         switch (chan->type) {
0830         case IIO_INTENSITY:
0831         case IIO_UVINDEX:
0832             val = si1133_scale_to_swgain(val, val2);
0833             if (val < 0)
0834                 return val;
0835 
0836             return si1133_update_adcsens(data,
0837                              SI1133_ADCSENS_SCALE_MASK,
0838                              SI1133_ADCSENS_SCALE_SHIFT,
0839                              val);
0840         default:
0841             return -EINVAL;
0842         }
0843     case IIO_CHAN_INFO_INT_TIME:
0844         return si1133_set_integration_time(data, 0, val, val2);
0845     case IIO_CHAN_INFO_HARDWAREGAIN:
0846         switch (chan->type) {
0847         case IIO_INTENSITY:
0848         case IIO_UVINDEX:
0849             if (val != 0 && val != 1)
0850                 return -EINVAL;
0851 
0852             return si1133_update_adcsens(data,
0853                              SI1133_ADCSENS_HSIG_MASK,
0854                              SI1133_ADCSENS_HSIG_SHIFT,
0855                              val);
0856         default:
0857             return -EINVAL;
0858         }
0859     default:
0860         return -EINVAL;
0861     }
0862 }
0863 
0864 static struct attribute *si1133_attributes[] = {
0865     &iio_const_attr_integration_time_available.dev_attr.attr,
0866     &iio_const_attr_scale_available.dev_attr.attr,
0867     NULL,
0868 };
0869 
0870 static const struct attribute_group si1133_attribute_group = {
0871     .attrs = si1133_attributes,
0872 };
0873 
0874 static const struct iio_info si1133_info = {
0875     .read_raw = si1133_read_raw,
0876     .write_raw = si1133_write_raw,
0877     .attrs = &si1133_attribute_group,
0878 };
0879 
0880 /*
0881  * si1133_init_lux_channels - Configure 3 different channels(adc) (1,2 and 3)
0882  * The channel configuration for the lux measurement was taken from :
0883  * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00578
0884  *
0885  * Reserved the channel 0 for the other raw measurements
0886  */
0887 static int si1133_init_lux_channels(struct si1133_data *data)
0888 {
0889     int err;
0890 
0891     err = si1133_chan_set_adcconfig(data, 1,
0892                     SI1133_ADCCONFIG_DECIM_RATE(1) |
0893                     SI1133_PARAM_ADCMUX_LARGE_WHITE);
0894     if (err)
0895         return err;
0896 
0897     err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(1),
0898                    SI1133_ADCPOST_24BIT_EN |
0899                    SI1133_ADCPOST_POSTSHIFT_BITQTY(0));
0900     if (err)
0901         return err;
0902     err = si1133_chan_set_adcsens(data, 1, SI1133_ADCSENS_HSIG_MASK |
0903                       SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
0904     if (err)
0905         return err;
0906 
0907     err = si1133_chan_set_adcconfig(data, 2,
0908                     SI1133_ADCCONFIG_DECIM_RATE(1) |
0909                     SI1133_PARAM_ADCMUX_LARGE_WHITE);
0910     if (err)
0911         return err;
0912 
0913     err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(2),
0914                    SI1133_ADCPOST_24BIT_EN |
0915                    SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
0916     if (err)
0917         return err;
0918 
0919     err = si1133_chan_set_adcsens(data, 2, SI1133_ADCSENS_HSIG_MASK |
0920                       SI1133_ADCSENS_NB_MEAS(1) | _3_120_0_us);
0921     if (err)
0922         return err;
0923 
0924     err = si1133_chan_set_adcconfig(data, 3,
0925                     SI1133_ADCCONFIG_DECIM_RATE(1) |
0926                     SI1133_PARAM_ADCMUX_MED_IR);
0927     if (err)
0928         return err;
0929 
0930     err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(3),
0931                    SI1133_ADCPOST_24BIT_EN |
0932                    SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
0933     if (err)
0934         return err;
0935 
0936     return  si1133_chan_set_adcsens(data, 3, SI1133_ADCSENS_HSIG_MASK |
0937                     SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
0938 }
0939 
0940 static int si1133_initialize(struct si1133_data *data)
0941 {
0942     int err;
0943 
0944     err = si1133_cmd_reset_sw(data);
0945     if (err)
0946         return err;
0947 
0948     /* Turn off autonomous mode */
0949     err = si1133_param_set(data, SI1133_REG_MEAS_RATE, 0);
0950     if (err)
0951         return err;
0952 
0953     err = si1133_init_lux_channels(data);
0954     if (err)
0955         return err;
0956 
0957     return regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE,
0958                 SI1133_IRQ_CHANNEL_ENABLE);
0959 }
0960 
0961 static int si1133_validate_ids(struct iio_dev *iio_dev)
0962 {
0963     struct si1133_data *data = iio_priv(iio_dev);
0964 
0965     unsigned int part_id, rev_id, mfr_id;
0966     int err;
0967 
0968     err = regmap_read(data->regmap, SI1133_REG_PART_ID, &part_id);
0969     if (err)
0970         return err;
0971 
0972     err = regmap_read(data->regmap, SI1133_REG_REV_ID, &rev_id);
0973     if (err)
0974         return err;
0975 
0976     err = regmap_read(data->regmap, SI1133_REG_MFR_ID, &mfr_id);
0977     if (err)
0978         return err;
0979 
0980     dev_info(&iio_dev->dev,
0981          "Device ID part 0x%02x rev 0x%02x mfr 0x%02x\n",
0982          part_id, rev_id, mfr_id);
0983     if (part_id != SI1133_PART_ID) {
0984         dev_err(&iio_dev->dev,
0985             "Part ID mismatch got 0x%02x, expected 0x%02x\n",
0986             part_id, SI1133_PART_ID);
0987         return -ENODEV;
0988     }
0989 
0990     return 0;
0991 }
0992 
0993 static int si1133_probe(struct i2c_client *client,
0994             const struct i2c_device_id *id)
0995 {
0996     struct si1133_data *data;
0997     struct iio_dev *iio_dev;
0998     int err;
0999 
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 
1057 static const struct i2c_device_id si1133_ids[] = {
1058     { "si1133", 0 },
1059     { }
1060 };
1061 MODULE_DEVICE_TABLE(i2c, si1133_ids);
1062 
1063 static struct i2c_driver si1133_driver = {
1064     .driver = {
1065         .name   = "si1133",
1066     },
1067     .probe  = si1133_probe,
1068     .id_table = si1133_ids,
1069 };
1070 
1071 module_i2c_driver(si1133_driver);
1072 
1073 MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
1074 MODULE_DESCRIPTION("Silabs SI1133, UV index sensor and ambient light sensor driver");
1075 MODULE_LICENSE("GPL");