* [PATCH 1/3] iio: Add modifier for UV light
@ 2016-03-16 1:06 Peter Meerwald-Stadler
2016-03-16 1:06 ` [PATCH 2/3] iio: Add modifier for UV index Peter Meerwald-Stadler
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Peter Meerwald-Stadler @ 2016-03-16 1:06 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, Peter Meerwald-Stadler
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
---
Documentation/ABI/testing/sysfs-bus-iio | 4 +++-
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
tools/iio/iio_event_monitor.c | 2 ++
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 17a9210..6fb9180 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1255,12 +1255,14 @@ Description:
What: /sys/.../iio:deviceX/in_intensityY_raw
What: /sys/.../iio:deviceX/in_intensityY_ir_raw
What: /sys/.../iio:deviceX/in_intensityY_both_raw
+What: /sys/.../iio:deviceX/in_intensityY_uv_raw
KernelVersion: 3.4
Contact: linux-iio@vger.kernel.org
Description:
Unit-less light intensity. Modifiers both and ir indicate
that measurements contains visible and infrared light
- components or just infrared light, respectively.
+ components or just infrared light, respectively. Modifier uv indicates
+ that measurements contain ultraviolet light components.
What: /sys/.../iio:deviceX/in_intensity_red_integration_time
What: /sys/.../iio:deviceX/in_intensity_green_integration_time
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 2e768bc..88353ae 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -101,6 +101,7 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green",
[IIO_MOD_LIGHT_BLUE] = "blue",
+ [IIO_MOD_LIGHT_UV] = "uv",
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index c077617..9337ece 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -77,6 +77,7 @@ enum iio_modifier {
IIO_MOD_Q,
IIO_MOD_CO2,
IIO_MOD_VOC,
+ IIO_MOD_LIGHT_UV,
};
enum iio_event_type {
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index 90980f5..8d7d979 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -93,6 +93,7 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green",
[IIO_MOD_LIGHT_BLUE] = "blue",
+ [IIO_MOD_LIGHT_UV] = "uv",
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
@@ -172,6 +173,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_MOD_LIGHT_RED:
case IIO_MOD_LIGHT_GREEN:
case IIO_MOD_LIGHT_BLUE:
+ case IIO_MOD_LIGHT_UV:
case IIO_MOD_QUATERNION:
case IIO_MOD_TEMP_AMBIENT:
case IIO_MOD_TEMP_OBJECT:
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] iio: Add modifier for UV index
2016-03-16 1:06 [PATCH 1/3] iio: Add modifier for UV light Peter Meerwald-Stadler
@ 2016-03-16 1:06 ` Peter Meerwald-Stadler
2016-03-16 20:41 ` Jonathan Cameron
2016-03-16 1:06 ` [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver Peter Meerwald-Stadler
2016-03-17 17:35 ` [PATCH 1/3] iio: Add modifier for UV light Matt Ranostay
2 siblings, 1 reply; 6+ messages in thread
From: Peter Meerwald-Stadler @ 2016-03-16 1:06 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, Peter Meerwald-Stadler
UV index indicating strength of sunburn-producing ultraviolet (UV) radiation
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
---
Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++
drivers/iio/industrialio-core.c | 1 +
include/uapi/linux/iio/types.h | 1 +
tools/iio/iio_event_monitor.c | 2 ++
4 files changed, 13 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 6fb9180..26da49b 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1264,6 +1264,15 @@ Description:
components or just infrared light, respectively. Modifier uv indicates
that measurements contain ultraviolet light components.
+What: /sys/.../iio:deviceX/in_intensityY_uv_index_input
+KernelVersion: 4.6
+Contact: linux-iio@vger.kernel.org
+Description:
+ UV light intensity index measuring the human skin's response to
+ different wavelength of sunlight weighted according to the
+ standardised CIE Erythemal Action Spectrum. UV index values range
+ from 0 (low) to >=11 (extreme).
+
What: /sys/.../iio:deviceX/in_intensity_red_integration_time
What: /sys/.../iio:deviceX/in_intensity_green_integration_time
What: /sys/.../iio:deviceX/in_intensity_blue_integration_time
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 88353ae..420aa06 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -102,6 +102,7 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_GREEN] = "green",
[IIO_MOD_LIGHT_BLUE] = "blue",
[IIO_MOD_LIGHT_UV] = "uv",
+ [IIO_MOD_LIGHT_UV_INDEX] = "uv_index",
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index 9337ece..0946c3e 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -78,6 +78,7 @@ enum iio_modifier {
IIO_MOD_CO2,
IIO_MOD_VOC,
IIO_MOD_LIGHT_UV,
+ IIO_MOD_LIGHT_UV_INDEX,
};
enum iio_event_type {
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index 8d7d979..0965349 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -94,6 +94,7 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_GREEN] = "green",
[IIO_MOD_LIGHT_BLUE] = "blue",
[IIO_MOD_LIGHT_UV] = "uv",
+ [IIO_MOD_LIGHT_UV_INDEX] = "uv_index",
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
@@ -174,6 +175,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_MOD_LIGHT_GREEN:
case IIO_MOD_LIGHT_BLUE:
case IIO_MOD_LIGHT_UV:
+ case IIO_MOD_LIGHT_UV_INDEX:
case IIO_MOD_QUATERNION:
case IIO_MOD_TEMP_AMBIENT:
case IIO_MOD_TEMP_OBJECT:
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver
2016-03-16 1:06 [PATCH 1/3] iio: Add modifier for UV light Peter Meerwald-Stadler
2016-03-16 1:06 ` [PATCH 2/3] iio: Add modifier for UV index Peter Meerwald-Stadler
@ 2016-03-16 1:06 ` Peter Meerwald-Stadler
2016-03-16 20:48 ` Jonathan Cameron
2016-03-17 17:35 ` [PATCH 1/3] iio: Add modifier for UV light Matt Ranostay
2 siblings, 1 reply; 6+ messages in thread
From: Peter Meerwald-Stadler @ 2016-03-16 1:06 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, Peter Meerwald-Stadler
ultraviolet (UV) light sensor with I2C interface with a peak
sensitivity at 355 nm
strangely, chip uses two addresses 0x38 and 0x39 for LSB and
MSB data, resp.
datasheet: http://www.vishay.com/docs/84277/veml6070.pdf
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
---
drivers/iio/light/Kconfig | 10 ++
drivers/iio/light/Makefile | 1 +
drivers/iio/light/veml6070.c | 220 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 231 insertions(+)
create mode 100644 drivers/iio/light/veml6070.c
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index cfd3df8..d2fe64e 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -320,4 +320,14 @@ config VCNL4000
To compile this driver as a module, choose M here: the
module will be called vcnl4000.
+config VEML6070
+ tristate "VEML6070 UV A light sensor"
+ depends on I2C
+ help
+ Say Y here if you want to build a driver for the Vishay VEML6070 UV A
+ light sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called veml6070.
+
endmenu
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index b2c3105..a447c62 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -30,3 +30,4 @@ obj-$(CONFIG_TCS3472) += tcs3472.o
obj-$(CONFIG_TSL4531) += tsl4531.o
obj-$(CONFIG_US5182D) += us5182d.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
+obj-$(CONFIG_VEML6070) += veml6070.o
diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c
new file mode 100644
index 0000000..d70b51e
--- /dev/null
+++ b/drivers/iio/light/veml6070.c
@@ -0,0 +1,220 @@
+/*
+ * veml6070.c - Support for Vishay VEML6070 UV A light sensor
+ *
+ * Copyright 2016 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * IIO driver for VEML6070 (7-bit I2C slave addresses 0x38 and 0x39)
+ *
+ * TODO: integration time, ACK signal
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define VEML6070_DRV_NAME "veml6070"
+
+#define VEML6070_ADDR_CONFIG_DATA_MSB 0x38 /* read: MSB data, write: config */
+#define VEML6070_ADDR_DATA_LSB 0x39 /* LSB data */
+
+#define VEML6070_COMMAND_ACK BIT(5) /* raise interrupt when over threshold */
+#define VEML6070_COMMAND_IT GENMASK(3, 2) /* bit mask integration time */
+#define VEML6070_COMMAND_RSRVD BIT(1) /* reserved, set to 1 */
+#define VEML6070_COMMAND_SD BIT(0) /* shutdown mode when set */
+
+#define VEML6070_IT_10 0x04 /* integration time 1x */
+
+struct veml6070_data {
+ struct i2c_client *client1;
+ struct i2c_client *client2;
+ u8 config;
+ struct mutex lock;
+};
+
+static int veml6070_read(struct veml6070_data *data)
+{
+ int ret;
+ u8 msb, lsb;
+
+ mutex_lock(&data->lock);
+
+ /* disable shutdown */
+ ret = i2c_smbus_write_byte(data->client1,
+ data->config & ~VEML6070_COMMAND_SD);
+ if (ret < 0)
+ goto out;
+
+ msleep(125 + 10); /* measurement takes up to 125 ms for IT 1x */
+
+ ret = i2c_smbus_read_byte(data->client2); /* read MSB, address 0x39 */
+ if (ret < 0)
+ goto out;
+ msb = ret;
+
+ ret = i2c_smbus_read_byte(data->client1); /* read LSB, address 0x38 */
+ if (ret < 0)
+ goto out;
+ lsb = ret;
+
+ /* shutdown again */
+ ret = i2c_smbus_write_byte(data->client1, data->config);
+ if (ret < 0)
+ goto out;
+
+ ret = (msb << 8) | lsb;
+
+out:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static const struct iio_chan_spec veml6070_channels[] = {
+ {
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_UV,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ },
+ {
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_UV_INDEX,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ }
+};
+
+static int veml6070_to_uv_index(unsigned val)
+{
+ /*
+ * conversion of raw UV intensity values to UV index depends on
+ * integration time (IT) and value of the resistor connected to
+ * the RSET pin (default: 270 KOhm)
+ */
+ unsigned uvi[11] = {
+ 187, 373, 560, /* low */
+ 746, 933, 1120, /* moderate */
+ 1308, 1494, /* high */
+ 1681, 1868, 2054}; /* very high */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(uvi); i++)
+ if (val <= uvi[i])
+ return i;
+
+ return 11; /* extreme */
+}
+
+static int veml6070_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct veml6070_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = veml6070_read(data);
+ if (ret < 0)
+ return ret;
+ if (mask == IIO_CHAN_INFO_PROCESSED)
+ *val = veml6070_to_uv_index(ret);
+ else
+ *val = ret;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info veml6070_info = {
+ .read_raw = veml6070_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int veml6070_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct veml6070_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client1 = client;
+ mutex_init(&data->lock);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &veml6070_info;
+ indio_dev->channels = veml6070_channels;
+ indio_dev->num_channels = ARRAY_SIZE(veml6070_channels);
+ indio_dev->name = VEML6070_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ data->client2 = i2c_new_dummy(client->adapter, VEML6070_ADDR_DATA_LSB);
+ if (!data->client2) {
+ dev_err(&client->dev, "i2c device for second chip address failed\n");
+ return -ENODEV;
+ }
+
+ data->config = VEML6070_IT_10 | VEML6070_COMMAND_RSRVD |
+ VEML6070_COMMAND_SD;
+ ret = i2c_smbus_write_byte(data->client1, data->config);
+ if (ret < 0)
+ goto fail;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto fail;
+
+ return ret;
+
+fail:
+ i2c_unregister_device(data->client2);
+ return ret;
+}
+
+static int veml6070_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct veml6070_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ i2c_unregister_device(data->client2);
+
+ return 0;
+}
+
+static const struct i2c_device_id veml6070_id[] = {
+ { "veml6070", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, veml6070_id);
+
+static struct i2c_driver veml6070_driver = {
+ .driver = {
+ .name = VEML6070_DRV_NAME,
+ },
+ .probe = veml6070_probe,
+ .remove = veml6070_remove,
+ .id_table = veml6070_id,
+};
+
+module_i2c_driver(veml6070_driver);
+
+MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Vishay VEML6070 UV A light sensor driver");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] iio: Add modifier for UV index
2016-03-16 1:06 ` [PATCH 2/3] iio: Add modifier for UV index Peter Meerwald-Stadler
@ 2016-03-16 20:41 ` Jonathan Cameron
0 siblings, 0 replies; 6+ messages in thread
From: Jonathan Cameron @ 2016-03-16 20:41 UTC (permalink / raw)
To: Peter Meerwald-Stadler; +Cc: linux-iio
On 16/03/16 01:06, Peter Meerwald-Stadler wrote:
> UV index indicating strength of sunburn-producing ultraviolet (UV) radiation
>
> Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
I'm not sure this wants to be a modifier rather than a new channel type
entirely. So far modifiers have been about 'direction' defined loosely
or something computational based on direction (root mean square etc)
I'd have in_uvindexX_input etc
This is kind of similar to illuminance in that it is a magic computed
wavelength dependent number that is some sort of weighted sum of
energies at different frequencies (assuming I read the wikipedia article
right!)
Jonathan
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++
> drivers/iio/industrialio-core.c | 1 +
> include/uapi/linux/iio/types.h | 1 +
> tools/iio/iio_event_monitor.c | 2 ++
> 4 files changed, 13 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 6fb9180..26da49b 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1264,6 +1264,15 @@ Description:
> components or just infrared light, respectively. Modifier uv indicates
> that measurements contain ultraviolet light components.
>
> +What: /sys/.../iio:deviceX/in_intensityY_uv_index_input
> +KernelVersion: 4.6
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + UV light intensity index measuring the human skin's response to
> + different wavelength of sunlight weighted according to the
> + standardised CIE Erythemal Action Spectrum. UV index values range
> + from 0 (low) to >=11 (extreme).
> +
> What: /sys/.../iio:deviceX/in_intensity_red_integration_time
> What: /sys/.../iio:deviceX/in_intensity_green_integration_time
> What: /sys/.../iio:deviceX/in_intensity_blue_integration_time
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 88353ae..420aa06 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -102,6 +102,7 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_LIGHT_GREEN] = "green",
> [IIO_MOD_LIGHT_BLUE] = "blue",
> [IIO_MOD_LIGHT_UV] = "uv",
> + [IIO_MOD_LIGHT_UV_INDEX] = "uv_index",
> [IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index 9337ece..0946c3e 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -78,6 +78,7 @@ enum iio_modifier {
> IIO_MOD_CO2,
> IIO_MOD_VOC,
> IIO_MOD_LIGHT_UV,
> + IIO_MOD_LIGHT_UV_INDEX,
> };
>
> enum iio_event_type {
> diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
> index 8d7d979..0965349 100644
> --- a/tools/iio/iio_event_monitor.c
> +++ b/tools/iio/iio_event_monitor.c
> @@ -94,6 +94,7 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_LIGHT_GREEN] = "green",
> [IIO_MOD_LIGHT_BLUE] = "blue",
> [IIO_MOD_LIGHT_UV] = "uv",
> + [IIO_MOD_LIGHT_UV_INDEX] = "uv_index",
> [IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> @@ -174,6 +175,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_MOD_LIGHT_GREEN:
> case IIO_MOD_LIGHT_BLUE:
> case IIO_MOD_LIGHT_UV:
> + case IIO_MOD_LIGHT_UV_INDEX:
> case IIO_MOD_QUATERNION:
> case IIO_MOD_TEMP_AMBIENT:
> case IIO_MOD_TEMP_OBJECT:
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver
2016-03-16 1:06 ` [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver Peter Meerwald-Stadler
@ 2016-03-16 20:48 ` Jonathan Cameron
0 siblings, 0 replies; 6+ messages in thread
From: Jonathan Cameron @ 2016-03-16 20:48 UTC (permalink / raw)
To: Peter Meerwald-Stadler; +Cc: linux-iio
On 16/03/16 01:06, Peter Meerwald-Stadler wrote:
> ultraviolet (UV) light sensor with I2C interface with a peak
> sensitivity at 355 nm
>
> strangely, chip uses two addresses 0x38 and 0x39 for LSB and
> MSB data, resp.
Novel - by which I mean PITA.
>
> datasheet: http://www.vishay.com/docs/84277/veml6070.pdf
>
> Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Looks good to me - except the whole thing about uvindex as a channel
type rather than a modifier.
Jonathan
> ---
> drivers/iio/light/Kconfig | 10 ++
> drivers/iio/light/Makefile | 1 +
> drivers/iio/light/veml6070.c | 220 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 231 insertions(+)
> create mode 100644 drivers/iio/light/veml6070.c
>
> diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
> index cfd3df8..d2fe64e 100644
> --- a/drivers/iio/light/Kconfig
> +++ b/drivers/iio/light/Kconfig
> @@ -320,4 +320,14 @@ config VCNL4000
> To compile this driver as a module, choose M here: the
> module will be called vcnl4000.
>
> +config VEML6070
> + tristate "VEML6070 UV A light sensor"
> + depends on I2C
> + help
> + Say Y here if you want to build a driver for the Vishay VEML6070 UV A
> + light sensor.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called veml6070.
> +
> endmenu
> diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
> index b2c3105..a447c62 100644
> --- a/drivers/iio/light/Makefile
> +++ b/drivers/iio/light/Makefile
> @@ -30,3 +30,4 @@ obj-$(CONFIG_TCS3472) += tcs3472.o
> obj-$(CONFIG_TSL4531) += tsl4531.o
> obj-$(CONFIG_US5182D) += us5182d.o
> obj-$(CONFIG_VCNL4000) += vcnl4000.o
> +obj-$(CONFIG_VEML6070) += veml6070.o
> diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c
> new file mode 100644
> index 0000000..d70b51e
> --- /dev/null
> +++ b/drivers/iio/light/veml6070.c
> @@ -0,0 +1,220 @@
> +/*
> + * veml6070.c - Support for Vishay VEML6070 UV A light sensor
> + *
> + * Copyright 2016 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> + *
> + * This file is subject to the terms and conditions of version 2 of
> + * the GNU General Public License. See the file COPYING in the main
> + * directory of this archive for more details.
> + *
> + * IIO driver for VEML6070 (7-bit I2C slave addresses 0x38 and 0x39)
> + *
> + * TODO: integration time, ACK signal
> + */
> +
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/mutex.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +
> +#define VEML6070_DRV_NAME "veml6070"
> +
> +#define VEML6070_ADDR_CONFIG_DATA_MSB 0x38 /* read: MSB data, write: config */
> +#define VEML6070_ADDR_DATA_LSB 0x39 /* LSB data */
> +
> +#define VEML6070_COMMAND_ACK BIT(5) /* raise interrupt when over threshold */
> +#define VEML6070_COMMAND_IT GENMASK(3, 2) /* bit mask integration time */
> +#define VEML6070_COMMAND_RSRVD BIT(1) /* reserved, set to 1 */
> +#define VEML6070_COMMAND_SD BIT(0) /* shutdown mode when set */
> +
> +#define VEML6070_IT_10 0x04 /* integration time 1x */
> +
> +struct veml6070_data {
> + struct i2c_client *client1;
> + struct i2c_client *client2;
> + u8 config;
> + struct mutex lock;
> +};
> +
> +static int veml6070_read(struct veml6070_data *data)
> +{
> + int ret;
> + u8 msb, lsb;
> +
> + mutex_lock(&data->lock);
> +
> + /* disable shutdown */
> + ret = i2c_smbus_write_byte(data->client1,
> + data->config & ~VEML6070_COMMAND_SD);
> + if (ret < 0)
> + goto out;
> +
> + msleep(125 + 10); /* measurement takes up to 125 ms for IT 1x */
> +
> + ret = i2c_smbus_read_byte(data->client2); /* read MSB, address 0x39 */
> + if (ret < 0)
> + goto out;
> + msb = ret;
> +
> + ret = i2c_smbus_read_byte(data->client1); /* read LSB, address 0x38 */
> + if (ret < 0)
> + goto out;
> + lsb = ret;
> +
> + /* shutdown again */
> + ret = i2c_smbus_write_byte(data->client1, data->config);
> + if (ret < 0)
> + goto out;
> +
> + ret = (msb << 8) | lsb;
> +
> +out:
> + mutex_unlock(&data->lock);
> + return ret;
> +}
> +
> +static const struct iio_chan_spec veml6070_channels[] = {
> + {
> + .type = IIO_INTENSITY,
> + .modified = 1,
> + .channel2 = IIO_MOD_LIGHT_UV,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> + },
> + {
> + .type = IIO_INTENSITY,
> + .modified = 1,
> + .channel2 = IIO_MOD_LIGHT_UV_INDEX,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
> + }
> +};
> +
> +static int veml6070_to_uv_index(unsigned val)
> +{
> + /*
> + * conversion of raw UV intensity values to UV index depends on
> + * integration time (IT) and value of the resistor connected to
> + * the RSET pin (default: 270 KOhm)
> + */
> + unsigned uvi[11] = {
> + 187, 373, 560, /* low */
> + 746, 933, 1120, /* moderate */
> + 1308, 1494, /* high */
> + 1681, 1868, 2054}; /* very high */
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(uvi); i++)
> + if (val <= uvi[i])
> + return i;
> +
> + return 11; /* extreme */
> +}
> +
> +static int veml6070_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct veml6070_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + case IIO_CHAN_INFO_PROCESSED:
> + ret = veml6070_read(data);
> + if (ret < 0)
> + return ret;
> + if (mask == IIO_CHAN_INFO_PROCESSED)
> + *val = veml6070_to_uv_index(ret);
> + else
> + *val = ret;
> + return IIO_VAL_INT;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static const struct iio_info veml6070_info = {
> + .read_raw = veml6070_read_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +static int veml6070_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct veml6070_data *data;
> + struct iio_dev *indio_dev;
> + int ret;
> +
> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + i2c_set_clientdata(client, indio_dev);
> + data->client1 = client;
> + mutex_init(&data->lock);
> +
> + indio_dev->dev.parent = &client->dev;
> + indio_dev->info = &veml6070_info;
> + indio_dev->channels = veml6070_channels;
> + indio_dev->num_channels = ARRAY_SIZE(veml6070_channels);
> + indio_dev->name = VEML6070_DRV_NAME;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> +
> + data->client2 = i2c_new_dummy(client->adapter, VEML6070_ADDR_DATA_LSB);
> + if (!data->client2) {
> + dev_err(&client->dev, "i2c device for second chip address failed\n");
> + return -ENODEV;
> + }
> +
> + data->config = VEML6070_IT_10 | VEML6070_COMMAND_RSRVD |
> + VEML6070_COMMAND_SD;
> + ret = i2c_smbus_write_byte(data->client1, data->config);
> + if (ret < 0)
> + goto fail;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0)
> + goto fail;
> +
> + return ret;
> +
> +fail:
> + i2c_unregister_device(data->client2);
> + return ret;
> +}
> +
> +static int veml6070_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct veml6070_data *data = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + i2c_unregister_device(data->client2);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id veml6070_id[] = {
> + { "veml6070", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, veml6070_id);
> +
> +static struct i2c_driver veml6070_driver = {
> + .driver = {
> + .name = VEML6070_DRV_NAME,
> + },
> + .probe = veml6070_probe,
> + .remove = veml6070_remove,
> + .id_table = veml6070_id,
> +};
> +
> +module_i2c_driver(veml6070_driver);
> +
> +MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
> +MODULE_DESCRIPTION("Vishay VEML6070 UV A light sensor driver");
> +MODULE_LICENSE("GPL");
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] iio: Add modifier for UV light
2016-03-16 1:06 [PATCH 1/3] iio: Add modifier for UV light Peter Meerwald-Stadler
2016-03-16 1:06 ` [PATCH 2/3] iio: Add modifier for UV index Peter Meerwald-Stadler
2016-03-16 1:06 ` [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver Peter Meerwald-Stadler
@ 2016-03-17 17:35 ` Matt Ranostay
2 siblings, 0 replies; 6+ messages in thread
From: Matt Ranostay @ 2016-03-17 17:35 UTC (permalink / raw)
To: Peter Meerwald-Stadler; +Cc: Jonathan Cameron, linux-iio@vger.kernel.org
On Tue, Mar 15, 2016 at 6:06 PM, Peter Meerwald-Stadler
<pmeerw@pmeerw.net> wrote:
> Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 4 +++-
> drivers/iio/industrialio-core.c | 1 +
> include/uapi/linux/iio/types.h | 1 +
> tools/iio/iio_event_monitor.c | 2 ++
> 4 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 17a9210..6fb9180 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1255,12 +1255,14 @@ Description:
> What: /sys/.../iio:deviceX/in_intensityY_raw
> What: /sys/.../iio:deviceX/in_intensityY_ir_raw
> What: /sys/.../iio:deviceX/in_intensityY_both_raw
> +What: /sys/.../iio:deviceX/in_intensityY_uv_raw
> KernelVersion: 3.4
> Contact: linux-iio@vger.kernel.org
> Description:
> Unit-less light intensity. Modifiers both and ir indicate
> that measurements contains visible and infrared light
> - components or just infrared light, respectively.
> + components or just infrared light, respectively. Modifier uv indicates
Triggering my nitpicking OCD.. uv should be UV :)
> + that measurements contain ultraviolet light components.
>
> What: /sys/.../iio:deviceX/in_intensity_red_integration_time
> What: /sys/.../iio:deviceX/in_intensity_green_integration_time
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 2e768bc..88353ae 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -101,6 +101,7 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_LIGHT_RED] = "red",
> [IIO_MOD_LIGHT_GREEN] = "green",
> [IIO_MOD_LIGHT_BLUE] = "blue",
> + [IIO_MOD_LIGHT_UV] = "uv",
> [IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index c077617..9337ece 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -77,6 +77,7 @@ enum iio_modifier {
> IIO_MOD_Q,
> IIO_MOD_CO2,
> IIO_MOD_VOC,
> + IIO_MOD_LIGHT_UV,
> };
>
> enum iio_event_type {
> diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
> index 90980f5..8d7d979 100644
> --- a/tools/iio/iio_event_monitor.c
> +++ b/tools/iio/iio_event_monitor.c
> @@ -93,6 +93,7 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_LIGHT_RED] = "red",
> [IIO_MOD_LIGHT_GREEN] = "green",
> [IIO_MOD_LIGHT_BLUE] = "blue",
> + [IIO_MOD_LIGHT_UV] = "uv",
> [IIO_MOD_QUATERNION] = "quaternion",
> [IIO_MOD_TEMP_AMBIENT] = "ambient",
> [IIO_MOD_TEMP_OBJECT] = "object",
> @@ -172,6 +173,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_MOD_LIGHT_RED:
> case IIO_MOD_LIGHT_GREEN:
> case IIO_MOD_LIGHT_BLUE:
> + case IIO_MOD_LIGHT_UV:
> case IIO_MOD_QUATERNION:
> case IIO_MOD_TEMP_AMBIENT:
> case IIO_MOD_TEMP_OBJECT:
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-03-17 17:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-16 1:06 [PATCH 1/3] iio: Add modifier for UV light Peter Meerwald-Stadler
2016-03-16 1:06 ` [PATCH 2/3] iio: Add modifier for UV index Peter Meerwald-Stadler
2016-03-16 20:41 ` Jonathan Cameron
2016-03-16 1:06 ` [PATCH 3/3] iio: Add Vishay VEML6070 UV A light sensor driver Peter Meerwald-Stadler
2016-03-16 20:48 ` Jonathan Cameron
2016-03-17 17:35 ` [PATCH 1/3] iio: Add modifier for UV light Matt Ranostay
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.