Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: light: Add driver for Silabs si1132, si1141/2/3 and si1145/6/7 ambient light, uv index and proximity sensors

The si114x supports x=1,2,3 IR LEDs for proximity sensing together with
visible and IR ambient light sensing (ALS).

Newer parts (si1132, si1145/6/7) can measure UV light and compute an UV
index
This was tested on si1143 and si1145

Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Peter Meerwald-Stadler and committed by
Jonathan Cameron
ac45e57f 03b262f2

+1418
+13
drivers/iio/light/Kconfig
··· 267 267 This driver can also be built as a module. If so, the module 268 268 will be called pa12203001. 269 269 270 + config SI1145 271 + tristate "SI1132 and SI1141/2/3/5/6/7 combined ALS, UV index and proximity sensor" 272 + depends on I2C 273 + select IIO_BUFFER 274 + select IIO_TRIGGERED_BUFFER 275 + help 276 + Say Y here if you want to build a driver for the Silicon Labs SI1132 or 277 + SI1141/2/3/5/6/7 combined ambient light, UV index and proximity sensor 278 + chips. 279 + 280 + To compile this driver as a module, choose M here: the module will be 281 + called si1145. 282 + 270 283 config STK3310 271 284 tristate "STK3310 ALS and proximity sensor" 272 285 depends on I2C
+1
drivers/iio/light/Makefile
··· 26 26 obj-$(CONFIG_PA12203001) += pa12203001.o 27 27 obj-$(CONFIG_RPR0521) += rpr0521.o 28 28 obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o 29 + obj-$(CONFIG_SI1145) += si1145.o 29 30 obj-$(CONFIG_STK3310) += stk3310.o 30 31 obj-$(CONFIG_TCS3414) += tcs3414.o 31 32 obj-$(CONFIG_TCS3472) += tcs3472.o
+1404
drivers/iio/light/si1145.c
··· 1 + /* 2 + * si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient 3 + * light, UV index and proximity sensors 4 + * 5 + * Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net> 6 + * Copyright 2016 Crestez Dan Leonard <leonard.crestez@intel.com> 7 + * 8 + * This file is subject to the terms and conditions of version 2 of 9 + * the GNU General Public License. See the file COPYING in the main 10 + * directory of this archive for more details. 11 + * 12 + * SI1132 (7-bit I2C slave address 0x60) 13 + * SI1141/2/3 (7-bit I2C slave address 0x5a) 14 + * SI1145/6/6 (7-bit I2C slave address 0x60) 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/i2c.h> 19 + #include <linux/err.h> 20 + #include <linux/slab.h> 21 + #include <linux/delay.h> 22 + #include <linux/irq.h> 23 + #include <linux/gpio.h> 24 + 25 + #include <linux/iio/iio.h> 26 + #include <linux/iio/sysfs.h> 27 + #include <linux/iio/trigger.h> 28 + #include <linux/iio/trigger_consumer.h> 29 + #include <linux/iio/triggered_buffer.h> 30 + #include <linux/iio/buffer.h> 31 + #include <linux/util_macros.h> 32 + 33 + #define SI1145_REG_PART_ID 0x00 34 + #define SI1145_REG_REV_ID 0x01 35 + #define SI1145_REG_SEQ_ID 0x02 36 + #define SI1145_REG_INT_CFG 0x03 37 + #define SI1145_REG_IRQ_ENABLE 0x04 38 + #define SI1145_REG_IRQ_MODE 0x05 39 + #define SI1145_REG_HW_KEY 0x07 40 + #define SI1145_REG_MEAS_RATE 0x08 41 + #define SI1145_REG_PS_LED21 0x0f 42 + #define SI1145_REG_PS_LED3 0x10 43 + #define SI1145_REG_UCOEF1 0x13 44 + #define SI1145_REG_UCOEF2 0x14 45 + #define SI1145_REG_UCOEF3 0x15 46 + #define SI1145_REG_UCOEF4 0x16 47 + #define SI1145_REG_PARAM_WR 0x17 48 + #define SI1145_REG_COMMAND 0x18 49 + #define SI1145_REG_RESPONSE 0x20 50 + #define SI1145_REG_IRQ_STATUS 0x21 51 + #define SI1145_REG_ALSVIS_DATA 0x22 52 + #define SI1145_REG_ALSIR_DATA 0x24 53 + #define SI1145_REG_PS1_DATA 0x26 54 + #define SI1145_REG_PS2_DATA 0x28 55 + #define SI1145_REG_PS3_DATA 0x2a 56 + #define SI1145_REG_AUX_DATA 0x2c 57 + #define SI1145_REG_PARAM_RD 0x2e 58 + #define SI1145_REG_CHIP_STAT 0x30 59 + 60 + #define SI1145_UCOEF1_DEFAULT 0x7b 61 + #define SI1145_UCOEF2_DEFAULT 0x6b 62 + #define SI1145_UCOEF3_DEFAULT 0x01 63 + #define SI1145_UCOEF4_DEFAULT 0x00 64 + 65 + /* Helper to figure out PS_LED register / shift per channel */ 66 + #define SI1145_PS_LED_REG(ch) \ 67 + (((ch) == 2) ? SI1145_REG_PS_LED3 : SI1145_REG_PS_LED21) 68 + #define SI1145_PS_LED_SHIFT(ch) \ 69 + (((ch) == 1) ? 4 : 0) 70 + 71 + /* Parameter offsets */ 72 + #define SI1145_PARAM_CHLIST 0x01 73 + #define SI1145_PARAM_PSLED12_SELECT 0x02 74 + #define SI1145_PARAM_PSLED3_SELECT 0x03 75 + #define SI1145_PARAM_PS_ENCODING 0x05 76 + #define SI1145_PARAM_ALS_ENCODING 0x06 77 + #define SI1145_PARAM_PS1_ADC_MUX 0x07 78 + #define SI1145_PARAM_PS2_ADC_MUX 0x08 79 + #define SI1145_PARAM_PS3_ADC_MUX 0x09 80 + #define SI1145_PARAM_PS_ADC_COUNTER 0x0a 81 + #define SI1145_PARAM_PS_ADC_GAIN 0x0b 82 + #define SI1145_PARAM_PS_ADC_MISC 0x0c 83 + #define SI1145_PARAM_ALS_ADC_MUX 0x0d 84 + #define SI1145_PARAM_ALSIR_ADC_MUX 0x0e 85 + #define SI1145_PARAM_AUX_ADC_MUX 0x0f 86 + #define SI1145_PARAM_ALSVIS_ADC_COUNTER 0x10 87 + #define SI1145_PARAM_ALSVIS_ADC_GAIN 0x11 88 + #define SI1145_PARAM_ALSVIS_ADC_MISC 0x12 89 + #define SI1145_PARAM_LED_RECOVERY 0x1c 90 + #define SI1145_PARAM_ALSIR_ADC_COUNTER 0x1d 91 + #define SI1145_PARAM_ALSIR_ADC_GAIN 0x1e 92 + #define SI1145_PARAM_ALSIR_ADC_MISC 0x1f 93 + #define SI1145_PARAM_ADC_OFFSET 0x1a 94 + 95 + /* Channel enable masks for CHLIST parameter */ 96 + #define SI1145_CHLIST_EN_PS1 BIT(0) 97 + #define SI1145_CHLIST_EN_PS2 BIT(1) 98 + #define SI1145_CHLIST_EN_PS3 BIT(2) 99 + #define SI1145_CHLIST_EN_ALSVIS BIT(4) 100 + #define SI1145_CHLIST_EN_ALSIR BIT(5) 101 + #define SI1145_CHLIST_EN_AUX BIT(6) 102 + #define SI1145_CHLIST_EN_UV BIT(7) 103 + 104 + /* Proximity measurement mode for ADC_MISC parameter */ 105 + #define SI1145_PS_ADC_MODE_NORMAL BIT(2) 106 + /* Signal range mask for ADC_MISC parameter */ 107 + #define SI1145_ADC_MISC_RANGE BIT(5) 108 + 109 + /* Commands for REG_COMMAND */ 110 + #define SI1145_CMD_NOP 0x00 111 + #define SI1145_CMD_RESET 0x01 112 + #define SI1145_CMD_PS_FORCE 0x05 113 + #define SI1145_CMD_ALS_FORCE 0x06 114 + #define SI1145_CMD_PSALS_FORCE 0x07 115 + #define SI1145_CMD_PS_PAUSE 0x09 116 + #define SI1145_CMD_ALS_PAUSE 0x0a 117 + #define SI1145_CMD_PSALS_PAUSE 0x0b 118 + #define SI1145_CMD_PS_AUTO 0x0d 119 + #define SI1145_CMD_ALS_AUTO 0x0e 120 + #define SI1145_CMD_PSALS_AUTO 0x0f 121 + #define SI1145_CMD_PARAM_QUERY 0x80 122 + #define SI1145_CMD_PARAM_SET 0xa0 123 + 124 + #define SI1145_RSP_INVALID_SETTING 0x80 125 + #define SI1145_RSP_COUNTER_MASK 0x0F 126 + 127 + /* Minimum sleep after each command to ensure it's received */ 128 + #define SI1145_COMMAND_MINSLEEP_MS 5 129 + /* Return -ETIMEDOUT after this long */ 130 + #define SI1145_COMMAND_TIMEOUT_MS 25 131 + 132 + /* Interrupt configuration masks for INT_CFG register */ 133 + #define SI1145_INT_CFG_OE BIT(0) /* enable interrupt */ 134 + #define SI1145_INT_CFG_MODE BIT(1) /* auto reset interrupt pin */ 135 + 136 + /* Interrupt enable masks for IRQ_ENABLE register */ 137 + #define SI1145_MASK_ALL_IE (BIT(4) | BIT(3) | BIT(2) | BIT(0)) 138 + 139 + #define SI1145_MUX_TEMP 0x65 140 + #define SI1145_MUX_VDD 0x75 141 + 142 + /* Proximity LED current; see Table 2 in datasheet */ 143 + #define SI1145_LED_CURRENT_45mA 0x04 144 + 145 + enum { 146 + SI1132, 147 + SI1141, 148 + SI1142, 149 + SI1143, 150 + SI1145, 151 + SI1146, 152 + SI1147, 153 + }; 154 + 155 + struct si1145_part_info { 156 + u8 part; 157 + const struct iio_info *iio_info; 158 + const struct iio_chan_spec *channels; 159 + unsigned int num_channels; 160 + unsigned int num_leds; 161 + bool uncompressed_meas_rate; 162 + }; 163 + 164 + /** 165 + * struct si1145_data - si1145 chip state data 166 + * @client: I2C client 167 + * @lock: mutex to protect shared state. 168 + * @cmdlock: Low-level mutex to protect command execution only 169 + * @rsp_seq: Next expected response number or -1 if counter reset required 170 + * @scan_mask: Saved scan mask to avoid duplicate set_chlist 171 + * @autonomous: If automatic measurements are active (for buffer support) 172 + * @part_info: Part information 173 + * @trig: Pointer to iio trigger 174 + * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode 175 + */ 176 + struct si1145_data { 177 + struct i2c_client *client; 178 + struct mutex lock; 179 + struct mutex cmdlock; 180 + int rsp_seq; 181 + const struct si1145_part_info *part_info; 182 + unsigned long scan_mask; 183 + bool autonomous; 184 + struct iio_trigger *trig; 185 + int meas_rate; 186 + }; 187 + 188 + /** 189 + * __si1145_command_reset() - Send CMD_NOP and wait for response 0 190 + * 191 + * Does not modify data->rsp_seq 192 + * 193 + * Return: 0 on success and -errno on error. 194 + */ 195 + static int __si1145_command_reset(struct si1145_data *data) 196 + { 197 + struct device *dev = &data->client->dev; 198 + unsigned long stop_jiffies; 199 + int ret; 200 + 201 + ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, 202 + SI1145_CMD_NOP); 203 + if (ret < 0) 204 + return ret; 205 + msleep(SI1145_COMMAND_MINSLEEP_MS); 206 + 207 + stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000; 208 + while (true) { 209 + ret = i2c_smbus_read_byte_data(data->client, 210 + SI1145_REG_RESPONSE); 211 + if (ret <= 0) 212 + return ret; 213 + if (time_after(jiffies, stop_jiffies)) { 214 + dev_warn(dev, "timeout on reset\n"); 215 + return -ETIMEDOUT; 216 + } 217 + msleep(SI1145_COMMAND_MINSLEEP_MS); 218 + continue; 219 + } 220 + } 221 + 222 + /** 223 + * si1145_command() - Execute a command and poll the response register 224 + * 225 + * All conversion overflows are reported as -EOVERFLOW 226 + * INVALID_SETTING is reported as -EINVAL 227 + * Timeouts are reported as -ETIMEDOUT 228 + * 229 + * Return: 0 on success or -errno on failure 230 + */ 231 + static int si1145_command(struct si1145_data *data, u8 cmd) 232 + { 233 + struct device *dev = &data->client->dev; 234 + unsigned long stop_jiffies; 235 + int ret; 236 + 237 + mutex_lock(&data->cmdlock); 238 + 239 + if (data->rsp_seq < 0) { 240 + ret = __si1145_command_reset(data); 241 + if (ret < 0) { 242 + dev_err(dev, "failed to reset command counter, ret=%d\n", 243 + ret); 244 + goto out; 245 + } 246 + data->rsp_seq = 0; 247 + } 248 + 249 + ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, cmd); 250 + if (ret) { 251 + dev_warn(dev, "failed to write command, ret=%d\n", ret); 252 + goto out; 253 + } 254 + /* Sleep a little to ensure the command is received */ 255 + msleep(SI1145_COMMAND_MINSLEEP_MS); 256 + 257 + stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000; 258 + while (true) { 259 + ret = i2c_smbus_read_byte_data(data->client, 260 + SI1145_REG_RESPONSE); 261 + if (ret < 0) { 262 + dev_warn(dev, "failed to read response, ret=%d\n", ret); 263 + break; 264 + } 265 + 266 + if ((ret & ~SI1145_RSP_COUNTER_MASK) == 0) { 267 + if (ret == data->rsp_seq) { 268 + if (time_after(jiffies, stop_jiffies)) { 269 + dev_warn(dev, "timeout on command %#02hhx\n", 270 + cmd); 271 + ret = -ETIMEDOUT; 272 + break; 273 + } 274 + msleep(SI1145_COMMAND_MINSLEEP_MS); 275 + continue; 276 + } 277 + if (ret == ((data->rsp_seq + 1) & 278 + SI1145_RSP_COUNTER_MASK)) { 279 + data->rsp_seq = ret; 280 + ret = 0; 281 + break; 282 + } 283 + dev_warn(dev, "unexpected response counter %d instead of %d\n", 284 + ret, (data->rsp_seq + 1) & 285 + SI1145_RSP_COUNTER_MASK); 286 + ret = -EIO; 287 + } else { 288 + if (ret == SI1145_RSP_INVALID_SETTING) { 289 + dev_warn(dev, "INVALID_SETTING error on command %#02hhx\n", 290 + cmd); 291 + ret = -EINVAL; 292 + } else { 293 + /* All overflows are treated identically */ 294 + dev_dbg(dev, "overflow, ret=%d, cmd=%#02hhx\n", 295 + ret, cmd); 296 + ret = -EOVERFLOW; 297 + } 298 + } 299 + 300 + /* Force a counter reset next time */ 301 + data->rsp_seq = -1; 302 + break; 303 + } 304 + 305 + out: 306 + mutex_unlock(&data->cmdlock); 307 + 308 + return ret; 309 + } 310 + 311 + static int si1145_param_update(struct si1145_data *data, u8 op, u8 param, 312 + u8 value) 313 + { 314 + int ret; 315 + 316 + ret = i2c_smbus_write_byte_data(data->client, 317 + SI1145_REG_PARAM_WR, value); 318 + if (ret < 0) 319 + return ret; 320 + 321 + return si1145_command(data, op | (param & 0x1F)); 322 + } 323 + 324 + static int si1145_param_set(struct si1145_data *data, u8 param, u8 value) 325 + { 326 + return si1145_param_update(data, SI1145_CMD_PARAM_SET, param, value); 327 + } 328 + 329 + /* Set param. Returns negative errno or current value */ 330 + static int si1145_param_query(struct si1145_data *data, u8 param) 331 + { 332 + int ret; 333 + 334 + ret = si1145_command(data, SI1145_CMD_PARAM_QUERY | (param & 0x1F)); 335 + if (ret < 0) 336 + return ret; 337 + 338 + return i2c_smbus_read_byte_data(data->client, SI1145_REG_PARAM_RD); 339 + } 340 + 341 + /* Expand 8 bit compressed value to 16 bit, see Silabs AN498 */ 342 + static u16 si1145_uncompress(u8 x) 343 + { 344 + u16 result = 0; 345 + u8 exponent = 0; 346 + 347 + if (x < 8) 348 + return 0; 349 + 350 + exponent = (x & 0xf0) >> 4; 351 + result = 0x10 | (x & 0x0f); 352 + 353 + if (exponent >= 4) 354 + return result << (exponent - 4); 355 + return result >> (4 - exponent); 356 + } 357 + 358 + /* Compress 16 bit value to 8 bit, see Silabs AN498 */ 359 + static u8 si1145_compress(u16 x) 360 + { 361 + u32 exponent = 0; 362 + u32 significand = 0; 363 + u32 tmp = x; 364 + 365 + if (x == 0x0000) 366 + return 0x00; 367 + if (x == 0x0001) 368 + return 0x08; 369 + 370 + while (1) { 371 + tmp >>= 1; 372 + exponent += 1; 373 + if (tmp == 1) 374 + break; 375 + } 376 + 377 + if (exponent < 5) { 378 + significand = x << (4 - exponent); 379 + return (exponent << 4) | (significand & 0xF); 380 + } 381 + 382 + significand = x >> (exponent - 5); 383 + if (significand & 1) { 384 + significand += 2; 385 + if (significand & 0x0040) { 386 + exponent += 1; 387 + significand >>= 1; 388 + } 389 + } 390 + 391 + return (exponent << 4) | ((significand >> 1) & 0xF); 392 + } 393 + 394 + /* Write meas_rate in hardware */ 395 + static int si1145_set_meas_rate(struct si1145_data *data, int interval) 396 + { 397 + if (data->part_info->uncompressed_meas_rate) 398 + return i2c_smbus_write_word_data(data->client, 399 + SI1145_REG_MEAS_RATE, interval); 400 + else 401 + return i2c_smbus_write_byte_data(data->client, 402 + SI1145_REG_MEAS_RATE, interval); 403 + } 404 + 405 + static int si1145_read_samp_freq(struct si1145_data *data, int *val, int *val2) 406 + { 407 + *val = 32000; 408 + if (data->part_info->uncompressed_meas_rate) 409 + *val2 = data->meas_rate; 410 + else 411 + *val2 = si1145_uncompress(data->meas_rate); 412 + return IIO_VAL_FRACTIONAL; 413 + } 414 + 415 + /* Set the samp freq in driver private data */ 416 + static int si1145_store_samp_freq(struct si1145_data *data, int val) 417 + { 418 + int ret = 0; 419 + int meas_rate; 420 + 421 + if (val <= 0 || val > 32000) 422 + return -ERANGE; 423 + meas_rate = 32000 / val; 424 + 425 + mutex_lock(&data->lock); 426 + if (data->autonomous) { 427 + ret = si1145_set_meas_rate(data, meas_rate); 428 + if (ret) 429 + goto out; 430 + } 431 + if (data->part_info->uncompressed_meas_rate) 432 + data->meas_rate = meas_rate; 433 + else 434 + data->meas_rate = si1145_compress(meas_rate); 435 + 436 + out: 437 + mutex_unlock(&data->lock); 438 + 439 + return ret; 440 + } 441 + 442 + static irqreturn_t si1145_trigger_handler(int irq, void *private) 443 + { 444 + struct iio_poll_func *pf = private; 445 + struct iio_dev *indio_dev = pf->indio_dev; 446 + struct si1145_data *data = iio_priv(indio_dev); 447 + /* 448 + * Maximum buffer size: 449 + * 6*2 bytes channels data + 4 bytes alignment + 450 + * 8 bytes timestamp 451 + */ 452 + u8 buffer[24]; 453 + int i, j = 0; 454 + int ret; 455 + u8 irq_status = 0; 456 + 457 + if (!data->autonomous) { 458 + ret = si1145_command(data, SI1145_CMD_PSALS_FORCE); 459 + if (ret < 0 && ret != -EOVERFLOW) 460 + goto done; 461 + } else { 462 + irq_status = ret = i2c_smbus_read_byte_data(data->client, 463 + SI1145_REG_IRQ_STATUS); 464 + if (ret < 0) 465 + goto done; 466 + if (!(irq_status & SI1145_MASK_ALL_IE)) 467 + goto done; 468 + } 469 + 470 + for_each_set_bit(i, indio_dev->active_scan_mask, 471 + indio_dev->masklength) { 472 + int run = 1; 473 + 474 + while (i + run < indio_dev->masklength) { 475 + if (!test_bit(i + run, indio_dev->active_scan_mask)) 476 + break; 477 + if (indio_dev->channels[i + run].address != 478 + indio_dev->channels[i].address + 2 * run) 479 + break; 480 + run++; 481 + } 482 + 483 + ret = i2c_smbus_read_i2c_block_data_or_emulated( 484 + data->client, indio_dev->channels[i].address, 485 + sizeof(u16) * run, &buffer[j]); 486 + if (ret < 0) 487 + goto done; 488 + j += run * sizeof(u16); 489 + i += run - 1; 490 + } 491 + 492 + if (data->autonomous) { 493 + ret = i2c_smbus_write_byte_data(data->client, 494 + SI1145_REG_IRQ_STATUS, 495 + irq_status & SI1145_MASK_ALL_IE); 496 + if (ret < 0) 497 + goto done; 498 + } 499 + 500 + iio_push_to_buffers_with_timestamp(indio_dev, buffer, 501 + iio_get_time_ns(indio_dev)); 502 + 503 + done: 504 + iio_trigger_notify_done(indio_dev->trig); 505 + return IRQ_HANDLED; 506 + } 507 + 508 + static int si1145_set_chlist(struct iio_dev *indio_dev, unsigned long scan_mask) 509 + { 510 + struct si1145_data *data = iio_priv(indio_dev); 511 + u8 reg = 0, mux; 512 + int ret; 513 + int i; 514 + 515 + /* channel list already set, no need to reprogram */ 516 + if (data->scan_mask == scan_mask) 517 + return 0; 518 + 519 + for_each_set_bit(i, &scan_mask, indio_dev->masklength) { 520 + switch (indio_dev->channels[i].address) { 521 + case SI1145_REG_ALSVIS_DATA: 522 + reg |= SI1145_CHLIST_EN_ALSVIS; 523 + break; 524 + case SI1145_REG_ALSIR_DATA: 525 + reg |= SI1145_CHLIST_EN_ALSIR; 526 + break; 527 + case SI1145_REG_PS1_DATA: 528 + reg |= SI1145_CHLIST_EN_PS1; 529 + break; 530 + case SI1145_REG_PS2_DATA: 531 + reg |= SI1145_CHLIST_EN_PS2; 532 + break; 533 + case SI1145_REG_PS3_DATA: 534 + reg |= SI1145_CHLIST_EN_PS3; 535 + break; 536 + case SI1145_REG_AUX_DATA: 537 + switch (indio_dev->channels[i].type) { 538 + case IIO_UVINDEX: 539 + reg |= SI1145_CHLIST_EN_UV; 540 + break; 541 + default: 542 + reg |= SI1145_CHLIST_EN_AUX; 543 + if (indio_dev->channels[i].type == IIO_TEMP) 544 + mux = SI1145_MUX_TEMP; 545 + else 546 + mux = SI1145_MUX_VDD; 547 + ret = si1145_param_set(data, 548 + SI1145_PARAM_AUX_ADC_MUX, mux); 549 + if (ret < 0) 550 + return ret; 551 + 552 + break; 553 + } 554 + } 555 + } 556 + 557 + data->scan_mask = scan_mask; 558 + ret = si1145_param_set(data, SI1145_PARAM_CHLIST, reg); 559 + 560 + return ret < 0 ? ret : 0; 561 + } 562 + 563 + static int si1145_measure(struct iio_dev *indio_dev, 564 + struct iio_chan_spec const *chan) 565 + { 566 + struct si1145_data *data = iio_priv(indio_dev); 567 + u8 cmd; 568 + int ret; 569 + 570 + ret = si1145_set_chlist(indio_dev, BIT(chan->scan_index)); 571 + if (ret < 0) 572 + return ret; 573 + 574 + cmd = (chan->type == IIO_PROXIMITY) ? SI1145_CMD_PS_FORCE : 575 + SI1145_CMD_ALS_FORCE; 576 + ret = si1145_command(data, cmd); 577 + if (ret < 0 && ret != -EOVERFLOW) 578 + return ret; 579 + 580 + return i2c_smbus_read_word_data(data->client, chan->address); 581 + } 582 + 583 + /* 584 + * Conversion between iio scale and ADC_GAIN values 585 + * These could be further adjusted but proximity/intensity are dimensionless 586 + */ 587 + static const int si1145_proximity_scale_available[] = { 588 + 128, 64, 32, 16, 8, 4}; 589 + static const int si1145_intensity_scale_available[] = { 590 + 128, 64, 32, 16, 8, 4, 2, 1}; 591 + static IIO_CONST_ATTR(in_proximity_scale_available, 592 + "128 64 32 16 8 4"); 593 + static IIO_CONST_ATTR(in_intensity_scale_available, 594 + "128 64 32 16 8 4 2 1"); 595 + static IIO_CONST_ATTR(in_intensity_ir_scale_available, 596 + "128 64 32 16 8 4 2 1"); 597 + 598 + static int si1145_scale_from_adcgain(int regval) 599 + { 600 + return 128 >> regval; 601 + } 602 + 603 + static int si1145_proximity_adcgain_from_scale(int val, int val2) 604 + { 605 + val = find_closest_descending(val, si1145_proximity_scale_available, 606 + ARRAY_SIZE(si1145_proximity_scale_available)); 607 + if (val < 0 || val > 5 || val2 != 0) 608 + return -EINVAL; 609 + 610 + return val; 611 + } 612 + 613 + static int si1145_intensity_adcgain_from_scale(int val, int val2) 614 + { 615 + val = find_closest_descending(val, si1145_intensity_scale_available, 616 + ARRAY_SIZE(si1145_intensity_scale_available)); 617 + if (val < 0 || val > 7 || val2 != 0) 618 + return -EINVAL; 619 + 620 + return val; 621 + } 622 + 623 + static int si1145_read_raw(struct iio_dev *indio_dev, 624 + struct iio_chan_spec const *chan, 625 + int *val, int *val2, long mask) 626 + { 627 + struct si1145_data *data = iio_priv(indio_dev); 628 + int ret; 629 + u8 reg; 630 + 631 + switch (mask) { 632 + case IIO_CHAN_INFO_RAW: 633 + switch (chan->type) { 634 + case IIO_INTENSITY: 635 + case IIO_PROXIMITY: 636 + case IIO_VOLTAGE: 637 + case IIO_TEMP: 638 + case IIO_UVINDEX: 639 + ret = iio_device_claim_direct_mode(indio_dev); 640 + if (ret) 641 + return ret; 642 + ret = si1145_measure(indio_dev, chan); 643 + iio_device_release_direct_mode(indio_dev); 644 + 645 + if (ret < 0) 646 + return ret; 647 + 648 + *val = ret; 649 + 650 + return IIO_VAL_INT; 651 + case IIO_CURRENT: 652 + ret = i2c_smbus_read_byte_data(data->client, 653 + SI1145_PS_LED_REG(chan->channel)); 654 + if (ret < 0) 655 + return ret; 656 + 657 + *val = (ret >> SI1145_PS_LED_SHIFT(chan->channel)) 658 + & 0x0f; 659 + 660 + return IIO_VAL_INT; 661 + default: 662 + return -EINVAL; 663 + } 664 + case IIO_CHAN_INFO_SCALE: 665 + switch (chan->type) { 666 + case IIO_PROXIMITY: 667 + reg = SI1145_PARAM_PS_ADC_GAIN; 668 + break; 669 + case IIO_INTENSITY: 670 + if (chan->channel2 == IIO_MOD_LIGHT_IR) 671 + reg = SI1145_PARAM_ALSIR_ADC_GAIN; 672 + else 673 + reg = SI1145_PARAM_ALSVIS_ADC_GAIN; 674 + break; 675 + case IIO_TEMP: 676 + *val = 28; 677 + *val2 = 571429; 678 + return IIO_VAL_INT_PLUS_MICRO; 679 + case IIO_UVINDEX: 680 + *val = 0; 681 + *val2 = 10000; 682 + return IIO_VAL_INT_PLUS_MICRO; 683 + default: 684 + return -EINVAL; 685 + } 686 + 687 + ret = si1145_param_query(data, reg); 688 + if (ret < 0) 689 + return ret; 690 + 691 + *val = si1145_scale_from_adcgain(ret & 0x07); 692 + 693 + return IIO_VAL_INT; 694 + case IIO_CHAN_INFO_OFFSET: 695 + switch (chan->type) { 696 + case IIO_TEMP: 697 + /* 698 + * -ADC offset - ADC counts @ 25°C - 699 + * 35 * ADC counts / °C 700 + */ 701 + *val = -256 - 11136 + 25 * 35; 702 + return IIO_VAL_INT; 703 + default: 704 + /* 705 + * All ADC measurements have are by default offset 706 + * by -256 707 + * See AN498 5.6.3 708 + */ 709 + ret = si1145_param_query(data, SI1145_PARAM_ADC_OFFSET); 710 + if (ret < 0) 711 + return ret; 712 + *val = -si1145_uncompress(ret); 713 + return IIO_VAL_INT; 714 + } 715 + case IIO_CHAN_INFO_SAMP_FREQ: 716 + return si1145_read_samp_freq(data, val, val2); 717 + default: 718 + return -EINVAL; 719 + } 720 + } 721 + 722 + static int si1145_write_raw(struct iio_dev *indio_dev, 723 + struct iio_chan_spec const *chan, 724 + int val, int val2, long mask) 725 + { 726 + struct si1145_data *data = iio_priv(indio_dev); 727 + u8 reg1, reg2, shift; 728 + int ret; 729 + 730 + switch (mask) { 731 + case IIO_CHAN_INFO_SCALE: 732 + switch (chan->type) { 733 + case IIO_PROXIMITY: 734 + val = si1145_proximity_adcgain_from_scale(val, val2); 735 + if (val < 0) 736 + return val; 737 + reg1 = SI1145_PARAM_PS_ADC_GAIN; 738 + reg2 = SI1145_PARAM_PS_ADC_COUNTER; 739 + break; 740 + case IIO_INTENSITY: 741 + val = si1145_intensity_adcgain_from_scale(val, val2); 742 + if (val < 0) 743 + return val; 744 + if (chan->channel2 == IIO_MOD_LIGHT_IR) { 745 + reg1 = SI1145_PARAM_ALSIR_ADC_GAIN; 746 + reg2 = SI1145_PARAM_ALSIR_ADC_COUNTER; 747 + } else { 748 + reg1 = SI1145_PARAM_ALSVIS_ADC_GAIN; 749 + reg2 = SI1145_PARAM_ALSVIS_ADC_COUNTER; 750 + } 751 + break; 752 + default: 753 + return -EINVAL; 754 + } 755 + 756 + ret = iio_device_claim_direct_mode(indio_dev); 757 + if (ret) 758 + return ret; 759 + 760 + ret = si1145_param_set(data, reg1, val); 761 + if (ret < 0) { 762 + iio_device_release_direct_mode(indio_dev); 763 + return ret; 764 + } 765 + /* Set recovery period to one's complement of gain */ 766 + ret = si1145_param_set(data, reg2, (~val & 0x07) << 4); 767 + iio_device_release_direct_mode(indio_dev); 768 + return ret; 769 + case IIO_CHAN_INFO_RAW: 770 + if (chan->type != IIO_CURRENT) 771 + return -EINVAL; 772 + 773 + if (val < 0 || val > 15 || val2 != 0) 774 + return -EINVAL; 775 + 776 + reg1 = SI1145_PS_LED_REG(chan->channel); 777 + shift = SI1145_PS_LED_SHIFT(chan->channel); 778 + 779 + ret = iio_device_claim_direct_mode(indio_dev); 780 + if (ret) 781 + return ret; 782 + 783 + ret = i2c_smbus_read_byte_data(data->client, reg1); 784 + if (ret < 0) { 785 + iio_device_release_direct_mode(indio_dev); 786 + return ret; 787 + } 788 + ret = i2c_smbus_write_byte_data(data->client, reg1, 789 + (ret & ~(0x0f << shift)) | 790 + ((val & 0x0f) << shift)); 791 + iio_device_release_direct_mode(indio_dev); 792 + return ret; 793 + case IIO_CHAN_INFO_SAMP_FREQ: 794 + return si1145_store_samp_freq(data, val); 795 + default: 796 + return -EINVAL; 797 + } 798 + } 799 + 800 + #define SI1145_ST { \ 801 + .sign = 'u', \ 802 + .realbits = 16, \ 803 + .storagebits = 16, \ 804 + .endianness = IIO_LE, \ 805 + } 806 + 807 + #define SI1145_INTENSITY_CHANNEL(_si) { \ 808 + .type = IIO_INTENSITY, \ 809 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 810 + BIT(IIO_CHAN_INFO_OFFSET) | \ 811 + BIT(IIO_CHAN_INFO_SCALE), \ 812 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 813 + .scan_type = SI1145_ST, \ 814 + .scan_index = _si, \ 815 + .address = SI1145_REG_ALSVIS_DATA, \ 816 + } 817 + 818 + #define SI1145_INTENSITY_IR_CHANNEL(_si) { \ 819 + .type = IIO_INTENSITY, \ 820 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 821 + BIT(IIO_CHAN_INFO_OFFSET) | \ 822 + BIT(IIO_CHAN_INFO_SCALE), \ 823 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 824 + .modified = 1, \ 825 + .channel2 = IIO_MOD_LIGHT_IR, \ 826 + .scan_type = SI1145_ST, \ 827 + .scan_index = _si, \ 828 + .address = SI1145_REG_ALSIR_DATA, \ 829 + } 830 + 831 + #define SI1145_TEMP_CHANNEL(_si) { \ 832 + .type = IIO_TEMP, \ 833 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 834 + BIT(IIO_CHAN_INFO_OFFSET) | \ 835 + BIT(IIO_CHAN_INFO_SCALE), \ 836 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 837 + .scan_type = SI1145_ST, \ 838 + .scan_index = _si, \ 839 + .address = SI1145_REG_AUX_DATA, \ 840 + } 841 + 842 + #define SI1145_UV_CHANNEL(_si) { \ 843 + .type = IIO_UVINDEX, \ 844 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 845 + BIT(IIO_CHAN_INFO_SCALE), \ 846 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 847 + .scan_type = SI1145_ST, \ 848 + .scan_index = _si, \ 849 + .address = SI1145_REG_AUX_DATA, \ 850 + } 851 + 852 + #define SI1145_PROXIMITY_CHANNEL(_si, _ch) { \ 853 + .type = IIO_PROXIMITY, \ 854 + .indexed = 1, \ 855 + .channel = _ch, \ 856 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 857 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 858 + BIT(IIO_CHAN_INFO_OFFSET), \ 859 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 860 + .scan_type = SI1145_ST, \ 861 + .scan_index = _si, \ 862 + .address = SI1145_REG_PS1_DATA + _ch * 2, \ 863 + } 864 + 865 + #define SI1145_VOLTAGE_CHANNEL(_si) { \ 866 + .type = IIO_VOLTAGE, \ 867 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 868 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 869 + .scan_type = SI1145_ST, \ 870 + .scan_index = _si, \ 871 + .address = SI1145_REG_AUX_DATA, \ 872 + } 873 + 874 + #define SI1145_CURRENT_CHANNEL(_ch) { \ 875 + .type = IIO_CURRENT, \ 876 + .indexed = 1, \ 877 + .channel = _ch, \ 878 + .output = 1, \ 879 + .scan_index = -1, \ 880 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 881 + } 882 + 883 + static const struct iio_chan_spec si1132_channels[] = { 884 + SI1145_INTENSITY_CHANNEL(0), 885 + SI1145_INTENSITY_IR_CHANNEL(1), 886 + SI1145_TEMP_CHANNEL(2), 887 + SI1145_VOLTAGE_CHANNEL(3), 888 + SI1145_UV_CHANNEL(4), 889 + IIO_CHAN_SOFT_TIMESTAMP(6), 890 + }; 891 + 892 + static const struct iio_chan_spec si1141_channels[] = { 893 + SI1145_INTENSITY_CHANNEL(0), 894 + SI1145_INTENSITY_IR_CHANNEL(1), 895 + SI1145_PROXIMITY_CHANNEL(2, 0), 896 + SI1145_TEMP_CHANNEL(3), 897 + SI1145_VOLTAGE_CHANNEL(4), 898 + IIO_CHAN_SOFT_TIMESTAMP(5), 899 + SI1145_CURRENT_CHANNEL(0), 900 + }; 901 + 902 + static const struct iio_chan_spec si1142_channels[] = { 903 + SI1145_INTENSITY_CHANNEL(0), 904 + SI1145_INTENSITY_IR_CHANNEL(1), 905 + SI1145_PROXIMITY_CHANNEL(2, 0), 906 + SI1145_PROXIMITY_CHANNEL(3, 1), 907 + SI1145_TEMP_CHANNEL(4), 908 + SI1145_VOLTAGE_CHANNEL(5), 909 + IIO_CHAN_SOFT_TIMESTAMP(6), 910 + SI1145_CURRENT_CHANNEL(0), 911 + SI1145_CURRENT_CHANNEL(1), 912 + }; 913 + 914 + static const struct iio_chan_spec si1143_channels[] = { 915 + SI1145_INTENSITY_CHANNEL(0), 916 + SI1145_INTENSITY_IR_CHANNEL(1), 917 + SI1145_PROXIMITY_CHANNEL(2, 0), 918 + SI1145_PROXIMITY_CHANNEL(3, 1), 919 + SI1145_PROXIMITY_CHANNEL(4, 2), 920 + SI1145_TEMP_CHANNEL(5), 921 + SI1145_VOLTAGE_CHANNEL(6), 922 + IIO_CHAN_SOFT_TIMESTAMP(7), 923 + SI1145_CURRENT_CHANNEL(0), 924 + SI1145_CURRENT_CHANNEL(1), 925 + SI1145_CURRENT_CHANNEL(2), 926 + }; 927 + 928 + static const struct iio_chan_spec si1145_channels[] = { 929 + SI1145_INTENSITY_CHANNEL(0), 930 + SI1145_INTENSITY_IR_CHANNEL(1), 931 + SI1145_PROXIMITY_CHANNEL(2, 0), 932 + SI1145_TEMP_CHANNEL(3), 933 + SI1145_VOLTAGE_CHANNEL(4), 934 + SI1145_UV_CHANNEL(5), 935 + IIO_CHAN_SOFT_TIMESTAMP(6), 936 + SI1145_CURRENT_CHANNEL(0), 937 + }; 938 + 939 + static const struct iio_chan_spec si1146_channels[] = { 940 + SI1145_INTENSITY_CHANNEL(0), 941 + SI1145_INTENSITY_IR_CHANNEL(1), 942 + SI1145_TEMP_CHANNEL(2), 943 + SI1145_VOLTAGE_CHANNEL(3), 944 + SI1145_UV_CHANNEL(4), 945 + SI1145_PROXIMITY_CHANNEL(5, 0), 946 + SI1145_PROXIMITY_CHANNEL(6, 1), 947 + IIO_CHAN_SOFT_TIMESTAMP(7), 948 + SI1145_CURRENT_CHANNEL(0), 949 + SI1145_CURRENT_CHANNEL(1), 950 + }; 951 + 952 + static const struct iio_chan_spec si1147_channels[] = { 953 + SI1145_INTENSITY_CHANNEL(0), 954 + SI1145_INTENSITY_IR_CHANNEL(1), 955 + SI1145_PROXIMITY_CHANNEL(2, 0), 956 + SI1145_PROXIMITY_CHANNEL(3, 1), 957 + SI1145_PROXIMITY_CHANNEL(4, 2), 958 + SI1145_TEMP_CHANNEL(5), 959 + SI1145_VOLTAGE_CHANNEL(6), 960 + SI1145_UV_CHANNEL(7), 961 + IIO_CHAN_SOFT_TIMESTAMP(8), 962 + SI1145_CURRENT_CHANNEL(0), 963 + SI1145_CURRENT_CHANNEL(1), 964 + SI1145_CURRENT_CHANNEL(2), 965 + }; 966 + 967 + static struct attribute *si1132_attributes[] = { 968 + &iio_const_attr_in_intensity_scale_available.dev_attr.attr, 969 + &iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr, 970 + NULL, 971 + }; 972 + 973 + static struct attribute *si114x_attributes[] = { 974 + &iio_const_attr_in_intensity_scale_available.dev_attr.attr, 975 + &iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr, 976 + &iio_const_attr_in_proximity_scale_available.dev_attr.attr, 977 + NULL, 978 + }; 979 + 980 + static const struct attribute_group si1132_attribute_group = { 981 + .attrs = si1132_attributes, 982 + }; 983 + 984 + static const struct attribute_group si114x_attribute_group = { 985 + .attrs = si114x_attributes, 986 + }; 987 + 988 + 989 + static const struct iio_info si1132_info = { 990 + .read_raw = si1145_read_raw, 991 + .write_raw = si1145_write_raw, 992 + .driver_module = THIS_MODULE, 993 + .attrs = &si1132_attribute_group, 994 + }; 995 + 996 + static const struct iio_info si114x_info = { 997 + .read_raw = si1145_read_raw, 998 + .write_raw = si1145_write_raw, 999 + .driver_module = THIS_MODULE, 1000 + .attrs = &si114x_attribute_group, 1001 + }; 1002 + 1003 + #define SI1145_PART(id, iio_info, chans, leds, uncompressed_meas_rate) \ 1004 + {id, iio_info, chans, ARRAY_SIZE(chans), leds, uncompressed_meas_rate} 1005 + 1006 + static const struct si1145_part_info si1145_part_info[] = { 1007 + [SI1132] = SI1145_PART(0x32, &si1132_info, si1132_channels, 0, true), 1008 + [SI1141] = SI1145_PART(0x41, &si114x_info, si1141_channels, 1, false), 1009 + [SI1142] = SI1145_PART(0x42, &si114x_info, si1142_channels, 2, false), 1010 + [SI1143] = SI1145_PART(0x43, &si114x_info, si1143_channels, 3, false), 1011 + [SI1145] = SI1145_PART(0x45, &si114x_info, si1145_channels, 1, true), 1012 + [SI1146] = SI1145_PART(0x46, &si114x_info, si1146_channels, 2, true), 1013 + [SI1147] = SI1145_PART(0x47, &si114x_info, si1147_channels, 3, true), 1014 + }; 1015 + 1016 + static int si1145_initialize(struct si1145_data *data) 1017 + { 1018 + struct i2c_client *client = data->client; 1019 + int ret; 1020 + 1021 + ret = i2c_smbus_write_byte_data(client, SI1145_REG_COMMAND, 1022 + SI1145_CMD_RESET); 1023 + if (ret < 0) 1024 + return ret; 1025 + msleep(SI1145_COMMAND_TIMEOUT_MS); 1026 + 1027 + /* Hardware key, magic value */ 1028 + ret = i2c_smbus_write_byte_data(client, SI1145_REG_HW_KEY, 0x17); 1029 + if (ret < 0) 1030 + return ret; 1031 + msleep(SI1145_COMMAND_TIMEOUT_MS); 1032 + 1033 + /* Turn off autonomous mode */ 1034 + ret = si1145_set_meas_rate(data, 0); 1035 + if (ret < 0) 1036 + return ret; 1037 + 1038 + /* Initialize sampling freq to 10 Hz */ 1039 + ret = si1145_store_samp_freq(data, 10); 1040 + if (ret < 0) 1041 + return ret; 1042 + 1043 + /* Set LED currents to 45 mA; have 4 bits, see Table 2 in datasheet */ 1044 + switch (data->part_info->num_leds) { 1045 + case 3: 1046 + ret = i2c_smbus_write_byte_data(client, 1047 + SI1145_REG_PS_LED3, 1048 + SI1145_LED_CURRENT_45mA); 1049 + if (ret < 0) 1050 + return ret; 1051 + /* fallthrough */ 1052 + case 2: 1053 + ret = i2c_smbus_write_byte_data(client, 1054 + SI1145_REG_PS_LED21, 1055 + (SI1145_LED_CURRENT_45mA << 4) | 1056 + SI1145_LED_CURRENT_45mA); 1057 + break; 1058 + case 1: 1059 + ret = i2c_smbus_write_byte_data(client, 1060 + SI1145_REG_PS_LED21, 1061 + SI1145_LED_CURRENT_45mA); 1062 + break; 1063 + default: 1064 + ret = 0; 1065 + break; 1066 + } 1067 + if (ret < 0) 1068 + return ret; 1069 + 1070 + /* Set normal proximity measurement mode */ 1071 + ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_MISC, 1072 + SI1145_PS_ADC_MODE_NORMAL); 1073 + if (ret < 0) 1074 + return ret; 1075 + 1076 + ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_GAIN, 0x01); 1077 + if (ret < 0) 1078 + return ret; 1079 + 1080 + /* ADC_COUNTER should be one complement of ADC_GAIN */ 1081 + ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_COUNTER, 0x06 << 4); 1082 + if (ret < 0) 1083 + return ret; 1084 + 1085 + /* Set ALS visible measurement mode */ 1086 + ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_MISC, 1087 + SI1145_ADC_MISC_RANGE); 1088 + if (ret < 0) 1089 + return ret; 1090 + 1091 + ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_GAIN, 0x03); 1092 + if (ret < 0) 1093 + return ret; 1094 + 1095 + ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_COUNTER, 1096 + 0x04 << 4); 1097 + if (ret < 0) 1098 + return ret; 1099 + 1100 + /* Set ALS IR measurement mode */ 1101 + ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_MISC, 1102 + SI1145_ADC_MISC_RANGE); 1103 + if (ret < 0) 1104 + return ret; 1105 + 1106 + ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_GAIN, 0x01); 1107 + if (ret < 0) 1108 + return ret; 1109 + 1110 + ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_COUNTER, 1111 + 0x06 << 4); 1112 + if (ret < 0) 1113 + return ret; 1114 + 1115 + /* 1116 + * Initialize UCOEF to default values in datasheet 1117 + * These registers are normally zero on reset 1118 + */ 1119 + if (data->part_info == &si1145_part_info[SI1132] || 1120 + data->part_info == &si1145_part_info[SI1145] || 1121 + data->part_info == &si1145_part_info[SI1146] || 1122 + data->part_info == &si1145_part_info[SI1147]) { 1123 + ret = i2c_smbus_write_byte_data(data->client, 1124 + SI1145_REG_UCOEF1, 1125 + SI1145_UCOEF1_DEFAULT); 1126 + if (ret < 0) 1127 + return ret; 1128 + ret = i2c_smbus_write_byte_data(data->client, 1129 + SI1145_REG_UCOEF2, SI1145_UCOEF2_DEFAULT); 1130 + if (ret < 0) 1131 + return ret; 1132 + ret = i2c_smbus_write_byte_data(data->client, 1133 + SI1145_REG_UCOEF3, SI1145_UCOEF3_DEFAULT); 1134 + if (ret < 0) 1135 + return ret; 1136 + ret = i2c_smbus_write_byte_data(data->client, 1137 + SI1145_REG_UCOEF4, SI1145_UCOEF4_DEFAULT); 1138 + if (ret < 0) 1139 + return ret; 1140 + } 1141 + 1142 + return 0; 1143 + } 1144 + 1145 + /* 1146 + * Program the channels we want to measure with CMD_PSALS_AUTO. No need for 1147 + * _postdisable as we stop with CMD_PSALS_PAUSE; single measurement (direct) 1148 + * mode reprograms the channels list anyway... 1149 + */ 1150 + static int si1145_buffer_preenable(struct iio_dev *indio_dev) 1151 + { 1152 + struct si1145_data *data = iio_priv(indio_dev); 1153 + int ret; 1154 + 1155 + mutex_lock(&data->lock); 1156 + ret = si1145_set_chlist(indio_dev, *indio_dev->active_scan_mask); 1157 + mutex_unlock(&data->lock); 1158 + 1159 + return ret; 1160 + } 1161 + 1162 + static bool si1145_validate_scan_mask(struct iio_dev *indio_dev, 1163 + const unsigned long *scan_mask) 1164 + { 1165 + struct si1145_data *data = iio_priv(indio_dev); 1166 + unsigned int count = 0; 1167 + int i; 1168 + 1169 + /* Check that at most one AUX channel is enabled */ 1170 + for_each_set_bit(i, scan_mask, data->part_info->num_channels) { 1171 + if (indio_dev->channels[i].address == SI1145_REG_AUX_DATA) 1172 + count++; 1173 + } 1174 + 1175 + return count <= 1; 1176 + } 1177 + 1178 + static const struct iio_buffer_setup_ops si1145_buffer_setup_ops = { 1179 + .preenable = si1145_buffer_preenable, 1180 + .postenable = iio_triggered_buffer_postenable, 1181 + .predisable = iio_triggered_buffer_predisable, 1182 + .validate_scan_mask = si1145_validate_scan_mask, 1183 + }; 1184 + 1185 + /** 1186 + * si1145_trigger_set_state() - Set trigger state 1187 + * 1188 + * When not using triggers interrupts are disabled and measurement rate is 1189 + * set to zero in order to minimize power consumption. 1190 + */ 1191 + static int si1145_trigger_set_state(struct iio_trigger *trig, bool state) 1192 + { 1193 + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 1194 + struct si1145_data *data = iio_priv(indio_dev); 1195 + int err = 0, ret; 1196 + 1197 + mutex_lock(&data->lock); 1198 + 1199 + if (state) { 1200 + data->autonomous = true; 1201 + err = i2c_smbus_write_byte_data(data->client, 1202 + SI1145_REG_INT_CFG, SI1145_INT_CFG_OE); 1203 + if (err < 0) 1204 + goto disable; 1205 + err = i2c_smbus_write_byte_data(data->client, 1206 + SI1145_REG_IRQ_ENABLE, SI1145_MASK_ALL_IE); 1207 + if (err < 0) 1208 + goto disable; 1209 + err = si1145_set_meas_rate(data, data->meas_rate); 1210 + if (err < 0) 1211 + goto disable; 1212 + err = si1145_command(data, SI1145_CMD_PSALS_AUTO); 1213 + if (err < 0) 1214 + goto disable; 1215 + } else { 1216 + disable: 1217 + /* Disable as much as possible skipping errors */ 1218 + ret = si1145_command(data, SI1145_CMD_PSALS_PAUSE); 1219 + if (ret < 0 && !err) 1220 + err = ret; 1221 + ret = si1145_set_meas_rate(data, 0); 1222 + if (ret < 0 && !err) 1223 + err = ret; 1224 + ret = i2c_smbus_write_byte_data(data->client, 1225 + SI1145_REG_IRQ_ENABLE, 0); 1226 + if (ret < 0 && !err) 1227 + err = ret; 1228 + ret = i2c_smbus_write_byte_data(data->client, 1229 + SI1145_REG_INT_CFG, 0); 1230 + if (ret < 0 && !err) 1231 + err = ret; 1232 + data->autonomous = false; 1233 + } 1234 + 1235 + mutex_unlock(&data->lock); 1236 + return err; 1237 + } 1238 + 1239 + static const struct iio_trigger_ops si1145_trigger_ops = { 1240 + .owner = THIS_MODULE, 1241 + .set_trigger_state = si1145_trigger_set_state, 1242 + }; 1243 + 1244 + static int si1145_probe_trigger(struct iio_dev *indio_dev) 1245 + { 1246 + struct si1145_data *data = iio_priv(indio_dev); 1247 + struct i2c_client *client = data->client; 1248 + struct iio_trigger *trig; 1249 + int ret; 1250 + 1251 + trig = devm_iio_trigger_alloc(&client->dev, 1252 + "%s-dev%d", indio_dev->name, indio_dev->id); 1253 + if (!trig) 1254 + return -ENOMEM; 1255 + 1256 + trig->dev.parent = &client->dev; 1257 + trig->ops = &si1145_trigger_ops; 1258 + iio_trigger_set_drvdata(trig, indio_dev); 1259 + 1260 + ret = devm_request_irq(&client->dev, client->irq, 1261 + iio_trigger_generic_data_rdy_poll, 1262 + IRQF_TRIGGER_FALLING, 1263 + "si1145_irq", 1264 + trig); 1265 + if (ret < 0) { 1266 + dev_err(&client->dev, "irq request failed\n"); 1267 + return ret; 1268 + } 1269 + 1270 + ret = iio_trigger_register(trig); 1271 + if (ret) 1272 + return ret; 1273 + 1274 + data->trig = trig; 1275 + indio_dev->trig = iio_trigger_get(data->trig); 1276 + 1277 + return 0; 1278 + } 1279 + 1280 + static void si1145_remove_trigger(struct iio_dev *indio_dev) 1281 + { 1282 + struct si1145_data *data = iio_priv(indio_dev); 1283 + 1284 + if (data->trig) { 1285 + iio_trigger_unregister(data->trig); 1286 + data->trig = NULL; 1287 + } 1288 + } 1289 + 1290 + static int si1145_probe(struct i2c_client *client, 1291 + const struct i2c_device_id *id) 1292 + { 1293 + struct si1145_data *data; 1294 + struct iio_dev *indio_dev; 1295 + u8 part_id, rev_id, seq_id; 1296 + int ret; 1297 + 1298 + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1299 + if (!indio_dev) 1300 + return -ENOMEM; 1301 + 1302 + data = iio_priv(indio_dev); 1303 + i2c_set_clientdata(client, indio_dev); 1304 + data->client = client; 1305 + data->part_info = &si1145_part_info[id->driver_data]; 1306 + 1307 + part_id = ret = i2c_smbus_read_byte_data(data->client, 1308 + SI1145_REG_PART_ID); 1309 + if (ret < 0) 1310 + return ret; 1311 + rev_id = ret = i2c_smbus_read_byte_data(data->client, 1312 + SI1145_REG_REV_ID); 1313 + if (ret < 0) 1314 + return ret; 1315 + seq_id = ret = i2c_smbus_read_byte_data(data->client, 1316 + SI1145_REG_SEQ_ID); 1317 + if (ret < 0) 1318 + return ret; 1319 + dev_info(&client->dev, "device ID part %#02hhx rev %#02hhx seq %#02hhx\n", 1320 + part_id, rev_id, seq_id); 1321 + if (part_id != data->part_info->part) { 1322 + dev_err(&client->dev, "part ID mismatch got %#02hhx, expected %#02x\n", 1323 + part_id, data->part_info->part); 1324 + return -ENODEV; 1325 + } 1326 + 1327 + indio_dev->dev.parent = &client->dev; 1328 + indio_dev->name = id->name; 1329 + indio_dev->channels = data->part_info->channels; 1330 + indio_dev->num_channels = data->part_info->num_channels; 1331 + indio_dev->info = data->part_info->iio_info; 1332 + indio_dev->modes = INDIO_DIRECT_MODE; 1333 + 1334 + mutex_init(&data->lock); 1335 + mutex_init(&data->cmdlock); 1336 + 1337 + ret = si1145_initialize(data); 1338 + if (ret < 0) 1339 + return ret; 1340 + 1341 + ret = iio_triggered_buffer_setup(indio_dev, NULL, 1342 + si1145_trigger_handler, &si1145_buffer_setup_ops); 1343 + if (ret < 0) 1344 + return ret; 1345 + 1346 + if (client->irq) { 1347 + ret = si1145_probe_trigger(indio_dev); 1348 + if (ret < 0) 1349 + goto error_free_buffer; 1350 + } else { 1351 + dev_info(&client->dev, "no irq, using polling\n"); 1352 + } 1353 + 1354 + ret = iio_device_register(indio_dev); 1355 + if (ret < 0) 1356 + goto error_free_trigger; 1357 + 1358 + return 0; 1359 + 1360 + error_free_trigger: 1361 + si1145_remove_trigger(indio_dev); 1362 + error_free_buffer: 1363 + iio_triggered_buffer_cleanup(indio_dev); 1364 + 1365 + return ret; 1366 + } 1367 + 1368 + static const struct i2c_device_id si1145_ids[] = { 1369 + { "si1132", SI1132 }, 1370 + { "si1141", SI1141 }, 1371 + { "si1142", SI1142 }, 1372 + { "si1143", SI1143 }, 1373 + { "si1145", SI1145 }, 1374 + { "si1146", SI1146 }, 1375 + { "si1147", SI1147 }, 1376 + { } 1377 + }; 1378 + MODULE_DEVICE_TABLE(i2c, si1145_ids); 1379 + 1380 + static int si1145_remove(struct i2c_client *client) 1381 + { 1382 + struct iio_dev *indio_dev = i2c_get_clientdata(client); 1383 + 1384 + iio_device_unregister(indio_dev); 1385 + si1145_remove_trigger(indio_dev); 1386 + iio_triggered_buffer_cleanup(indio_dev); 1387 + 1388 + return 0; 1389 + } 1390 + 1391 + static struct i2c_driver si1145_driver = { 1392 + .driver = { 1393 + .name = "si1145", 1394 + }, 1395 + .probe = si1145_probe, 1396 + .remove = si1145_remove, 1397 + .id_table = si1145_ids, 1398 + }; 1399 + 1400 + module_i2c_driver(si1145_driver); 1401 + 1402 + MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>"); 1403 + MODULE_DESCRIPTION("Silabs SI1132 and SI1141/2/3/5/6/7 proximity, ambient light and UV index sensor driver"); 1404 + MODULE_LICENSE("GPL");