diff options
-rw-r--r-- | drivers/iio/light/max44000.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index 05e11698201a..e01e58a9bd14 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c | |||
@@ -19,6 +19,9 @@ | |||
19 | #include <linux/util_macros.h> | 19 | #include <linux/util_macros.h> |
20 | #include <linux/iio/iio.h> | 20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> | 21 | #include <linux/iio/sysfs.h> |
22 | #include <linux/iio/buffer.h> | ||
23 | #include <linux/iio/trigger_consumer.h> | ||
24 | #include <linux/iio/triggered_buffer.h> | ||
22 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
23 | 26 | ||
24 | #define MAX44000_DRV_NAME "max44000" | 27 | #define MAX44000_DRV_NAME "max44000" |
@@ -125,24 +128,41 @@ static const char max44000_scale_avail_str[] = | |||
125 | "0.5 " | 128 | "0.5 " |
126 | "4"; | 129 | "4"; |
127 | 130 | ||
131 | #define MAX44000_SCAN_INDEX_ALS 0 | ||
132 | #define MAX44000_SCAN_INDEX_PRX 1 | ||
133 | |||
128 | static const struct iio_chan_spec max44000_channels[] = { | 134 | static const struct iio_chan_spec max44000_channels[] = { |
129 | { | 135 | { |
130 | .type = IIO_LIGHT, | 136 | .type = IIO_LIGHT, |
131 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 137 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
132 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | | 138 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | |
133 | BIT(IIO_CHAN_INFO_INT_TIME), | 139 | BIT(IIO_CHAN_INFO_INT_TIME), |
140 | .scan_index = MAX44000_SCAN_INDEX_ALS, | ||
141 | .scan_type = { | ||
142 | .sign = 'u', | ||
143 | .realbits = 14, | ||
144 | .storagebits = 16, | ||
145 | } | ||
134 | }, | 146 | }, |
135 | { | 147 | { |
136 | .type = IIO_PROXIMITY, | 148 | .type = IIO_PROXIMITY, |
137 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 149 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
138 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), | 150 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), |
151 | .scan_index = MAX44000_SCAN_INDEX_PRX, | ||
152 | .scan_type = { | ||
153 | .sign = 'u', | ||
154 | .realbits = 8, | ||
155 | .storagebits = 16, | ||
156 | } | ||
139 | }, | 157 | }, |
158 | IIO_CHAN_SOFT_TIMESTAMP(2), | ||
140 | { | 159 | { |
141 | .type = IIO_CURRENT, | 160 | .type = IIO_CURRENT, |
142 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | 161 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
143 | BIT(IIO_CHAN_INFO_SCALE), | 162 | BIT(IIO_CHAN_INFO_SCALE), |
144 | .extend_name = "led", | 163 | .extend_name = "led", |
145 | .output = 1, | 164 | .output = 1, |
165 | .scan_index = -1, | ||
146 | }, | 166 | }, |
147 | }; | 167 | }; |
148 | 168 | ||
@@ -467,6 +487,41 @@ static const struct regmap_config max44000_regmap_config = { | |||
467 | .cache_type = REGCACHE_RBTREE, | 487 | .cache_type = REGCACHE_RBTREE, |
468 | }; | 488 | }; |
469 | 489 | ||
490 | static irqreturn_t max44000_trigger_handler(int irq, void *p) | ||
491 | { | ||
492 | struct iio_poll_func *pf = p; | ||
493 | struct iio_dev *indio_dev = pf->indio_dev; | ||
494 | struct max44000_data *data = iio_priv(indio_dev); | ||
495 | u16 buf[8]; /* 2x u16 + padding + 8 bytes timestamp */ | ||
496 | int index = 0; | ||
497 | unsigned int regval; | ||
498 | int ret; | ||
499 | |||
500 | mutex_lock(&data->lock); | ||
501 | if (test_bit(MAX44000_SCAN_INDEX_ALS, indio_dev->active_scan_mask)) { | ||
502 | ret = max44000_read_alsval(data); | ||
503 | if (ret < 0) | ||
504 | goto out_unlock; | ||
505 | buf[index++] = ret; | ||
506 | } | ||
507 | if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) { | ||
508 | ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, ®val); | ||
509 | if (ret < 0) | ||
510 | goto out_unlock; | ||
511 | buf[index] = regval; | ||
512 | } | ||
513 | mutex_unlock(&data->lock); | ||
514 | |||
515 | iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); | ||
516 | iio_trigger_notify_done(indio_dev->trig); | ||
517 | return IRQ_HANDLED; | ||
518 | |||
519 | out_unlock: | ||
520 | mutex_unlock(&data->lock); | ||
521 | iio_trigger_notify_done(indio_dev->trig); | ||
522 | return IRQ_HANDLED; | ||
523 | } | ||
524 | |||
470 | static int max44000_probe(struct i2c_client *client, | 525 | static int max44000_probe(struct i2c_client *client, |
471 | const struct i2c_device_id *id) | 526 | const struct i2c_device_id *id) |
472 | { | 527 | { |
@@ -534,6 +589,12 @@ static int max44000_probe(struct i2c_client *client, | |||
534 | return ret; | 589 | return ret; |
535 | } | 590 | } |
536 | 591 | ||
592 | ret = iio_triggered_buffer_setup(indio_dev, NULL, max44000_trigger_handler, NULL); | ||
593 | if (ret < 0) { | ||
594 | dev_err(&client->dev, "iio triggered buffer setup failed\n"); | ||
595 | return ret; | ||
596 | } | ||
597 | |||
537 | return iio_device_register(indio_dev); | 598 | return iio_device_register(indio_dev); |
538 | } | 599 | } |
539 | 600 | ||
@@ -542,6 +603,7 @@ static int max44000_remove(struct i2c_client *client) | |||
542 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | 603 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
543 | 604 | ||
544 | iio_device_unregister(indio_dev); | 605 | iio_device_unregister(indio_dev); |
606 | iio_triggered_buffer_cleanup(indio_dev); | ||
545 | 607 | ||
546 | return 0; | 608 | return 0; |
547 | } | 609 | } |