aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Meerwald-Stadler <pmeerw@pmeerw.net>2016-09-18 10:41:30 -0400
committerJonathan Cameron <jic23@kernel.org>2016-09-18 14:56:39 -0400
commitac45e57f15903747ccd5a14cebfbd673ebcbdd6f (patch)
tree949f4caa449ba3f04f24a77510425c7cbe93487f
parent03b262f2bbf43b82eaef82ffb3bc671d5b5c8da1 (diff)
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>
-rw-r--r--drivers/iio/light/Kconfig13
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/si1145.c1404
3 files changed, 1418 insertions, 0 deletions
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 0db0a0d1bba0..ba2e64d7ee58 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -267,6 +267,19 @@ config PA12203001
267 This driver can also be built as a module. If so, the module 267 This driver can also be built as a module. If so, the module
268 will be called pa12203001. 268 will be called pa12203001.
269 269
270config 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
270config STK3310 283config STK3310
271 tristate "STK3310 ALS and proximity sensor" 284 tristate "STK3310 ALS and proximity sensor"
272 depends on I2C 285 depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 6f2a3c62de27..c5768df87a17 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_OPT3001) += opt3001.o
26obj-$(CONFIG_PA12203001) += pa12203001.o 26obj-$(CONFIG_PA12203001) += pa12203001.o
27obj-$(CONFIG_RPR0521) += rpr0521.o 27obj-$(CONFIG_RPR0521) += rpr0521.o
28obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o 28obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
29obj-$(CONFIG_SI1145) += si1145.o
29obj-$(CONFIG_STK3310) += stk3310.o 30obj-$(CONFIG_STK3310) += stk3310.o
30obj-$(CONFIG_TCS3414) += tcs3414.o 31obj-$(CONFIG_TCS3414) += tcs3414.o
31obj-$(CONFIG_TCS3472) += tcs3472.o 32obj-$(CONFIG_TCS3472) += tcs3472.o
diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c
new file mode 100644
index 000000000000..096034c126a4
--- /dev/null
+++ b/drivers/iio/light/si1145.c
@@ -0,0 +1,1404 @@
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
145enum {
146 SI1132,
147 SI1141,
148 SI1142,
149 SI1143,
150 SI1145,
151 SI1146,
152 SI1147,
153};
154
155struct 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 */
176struct 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 */
195static 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 */
231static 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
305out:
306 mutex_unlock(&data->cmdlock);
307
308 return ret;
309}
310
311static 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
324static 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 */
330static 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 */
342static 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 */
359static 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 */
395static 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
405static 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 */
416static 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
436out:
437 mutex_unlock(&data->lock);
438
439 return ret;
440}
441
442static 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
503done:
504 iio_trigger_notify_done(indio_dev->trig);
505 return IRQ_HANDLED;
506}
507
508static 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
563static 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 */
587static const int si1145_proximity_scale_available[] = {
588 128, 64, 32, 16, 8, 4};
589static const int si1145_intensity_scale_available[] = {
590 128, 64, 32, 16, 8, 4, 2, 1};
591static IIO_CONST_ATTR(in_proximity_scale_available,
592 "128 64 32 16 8 4");
593static IIO_CONST_ATTR(in_intensity_scale_available,
594 "128 64 32 16 8 4 2 1");
595static IIO_CONST_ATTR(in_intensity_ir_scale_available,
596 "128 64 32 16 8 4 2 1");
597
598static int si1145_scale_from_adcgain(int regval)
599{
600 return 128 >> regval;
601}
602
603static 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
613static 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
623static 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
722static 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
883static 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
892static 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
902static 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
914static 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
928static 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
939static 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
952static 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
967static 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
973static 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
980static const struct attribute_group si1132_attribute_group = {
981 .attrs = si1132_attributes,
982};
983
984static const struct attribute_group si114x_attribute_group = {
985 .attrs = si114x_attributes,
986};
987
988
989static 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
996static 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
1006static 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
1016static 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 */
1150static 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
1162static 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
1178static 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 */
1191static 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 {
1216disable:
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
1239static const struct iio_trigger_ops si1145_trigger_ops = {
1240 .owner = THIS_MODULE,
1241 .set_trigger_state = si1145_trigger_set_state,
1242};
1243
1244static 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
1280static 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
1290static 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
1360error_free_trigger:
1361 si1145_remove_trigger(indio_dev);
1362error_free_buffer:
1363 iio_triggered_buffer_cleanup(indio_dev);
1364
1365 return ret;
1366}
1367
1368static 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};
1378MODULE_DEVICE_TABLE(i2c, si1145_ids);
1379
1380static 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
1391static 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
1400module_i2c_driver(si1145_driver);
1401
1402MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
1403MODULE_DESCRIPTION("Silabs SI1132 and SI1141/2/3/5/6/7 proximity, ambient light and UV index sensor driver");
1404MODULE_LICENSE("GPL");