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