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