root/drivers/iio/light/si1133.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. si1133_calculate_polynomial_inner
  2. si1133_calculate_output
  3. si1133_calc_polynomial
  4. si1133_cmd_reset_sw
  5. si1133_parse_response_err
  6. si1133_cmd_reset_counter
  7. si1133_command
  8. si1133_param_set
  9. si1133_param_query
  10. si1133_get_int_time_index
  11. si1133_set_integration_time
  12. si1133_set_chlist
  13. si1133_chan_set_adcconfig
  14. si1133_update_adcconfig
  15. si1133_set_adcmux
  16. si1133_force_measurement
  17. si1133_bulk_read
  18. si1133_measure
  19. si1133_threaded_irq_handler
  20. si1133_scale_to_swgain
  21. si1133_chan_set_adcsens
  22. si1133_update_adcsens
  23. si1133_get_lux
  24. si1133_read_raw
  25. si1133_write_raw
  26. si1133_init_lux_channels
  27. si1133_initialize
  28. si1133_validate_ids
  29. si1133_probe

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

/* [<][>][^][v][top][bottom][index][help] */