Re: [PATCH v2 2/2] iio: light: noa1305: Add support for NOA1305

2019-07-14 Thread Jonathan Cameron
On Fri, 28 Jun 2019 18:57:13 +0100
Martyn Welch  wrote:

> This driver adds the initial support for the ON Semiconductor
> NOA1305 Ambient Light Sensor.
> 
> Originally written by Sergei Miroshnichenko. Found here:
>   
> https://github.com/EmcraftSystems/linux-upstream/commit/196d6cf897e632d2cb82d45484bd7a1bfdd5b6d9
> 
> Signed-off-by: Sergei M 
> Signed-off-by: Martyn Welch 

A few minor things inline.

Thanks,

Jonathan

> ---
> 
> Changes:
> v2: Correcting authorship and SOB.
> 
>  drivers/iio/light/Kconfig   |  10 ++
>  drivers/iio/light/Makefile  |   1 +
>  drivers/iio/light/noa1305.c | 247 
>  3 files changed, 258 insertions(+)
>  create mode 100644 drivers/iio/light/noa1305.c
> 
> diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
> index 954c958cfc43..d1db0ec0d0f5 100644
> --- a/drivers/iio/light/Kconfig
> +++ b/drivers/iio/light/Kconfig
> @@ -309,6 +309,16 @@ config MAX44009
>To compile this driver as a module, choose M here:
>the module will be called max44009.
>  
> +config NOA1305
> + tristate "ON Semiconductor NOA1305 ambient light sensor"
> + depends on I2C
> + help
> +  Say Y here if you want to build support for the ON Semiconductor
> +  NOA1305 ambient light sensor.
> +
> +  To compile this driver as a module, choose M here:
> +  The module will be called noa1305.
> +
>  config OPT3001
>   tristate "Texas Instruments OPT3001 Light Sensor"
>   depends on I2C
> diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
> index e40794fbb435..00d1f9b98f39 100644
> --- a/drivers/iio/light/Makefile
> +++ b/drivers/iio/light/Makefile
> @@ -29,6 +29,7 @@ obj-$(CONFIG_LTR501)+= ltr501.o
>  obj-$(CONFIG_LV0104CS)   += lv0104cs.o
>  obj-$(CONFIG_MAX44000)   += max44000.o
>  obj-$(CONFIG_MAX44009)   += max44009.o
> +obj-$(CONFIG_NOA1305)+= noa1305.o
>  obj-$(CONFIG_OPT3001)+= opt3001.o
>  obj-$(CONFIG_PA12203001) += pa12203001.o
>  obj-$(CONFIG_RPR0521)+= rpr0521.o
> diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c
> new file mode 100644
> index ..2c65c5c2e09a
> --- /dev/null
> +++ b/drivers/iio/light/noa1305.c
> @@ -0,0 +1,247 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Support for ON Semiconductor NOA1305 ambient light sensor
> + *
> + * Copyright (C) 2016 Emcraft Systems
> + * Copyright (C) 2019 Collabora Ltd.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define NOA1305_REG_POWER_CONTROL0x0
> +#define NOA1305_REG_RESET0x1
> +#define NOA1305_REG_INTEGRATION_TIME 0x2
> +#define NOA1305_REG_INT_SELECT   0x3
> +#define NOA1305_REG_INT_THRESH_LSB   0x4
> +#define NOA1305_REG_INT_THRESH_MSB   0x5
> +#define NOA1305_REG_ALS_DATA_LSB 0x6
> +#define NOA1305_REG_ALS_DATA_MSB 0x7
> +#define NOA1305_REG_DEVICE_ID_LSB0x8
> +#define NOA1305_REG_DEVICE_ID_MSB0x9
> +
> +#define NOA1305_DEVICE_ID0x0519
> +
> +#define NOA1305_POWER_ON 0x08
> +#define NOA1305_POWER_DOWN   0x00
> +#define NOA1305_RESET0x10
It would be good to name these in a fashion that made it
obvious they were values to write to the power control register.
NOA1305_POWER_CONTROL_ON

NOA1305_POWER_CONTROL_DOWN
NOA1305_POWER_CONTROL_RESET
perhaps?

There are other conventions we tend to use in IIO such as
#define NOA1305_POWER_CONTROL_REG 0x0
#define   NOA1305_POWER_CONTROL_POWER_ON  0x08
etc..
 

> +
> +#define NOA1305_INT_ACTIVE_HIGH  0x01
> +#define NOA1305_INT_ACTIVE_LOW   0x02
> +#define NOA1305_INT_INACTIVE 0x03
> +
> +#define NOA1305_INTEGR_TIME_800MS0x00
> +#define NOA1305_INTEGR_TIME_400MS0x01
> +#define NOA1305_INTEGR_TIME_200MS0x02
> +#define NOA1305_INTEGR_TIME_100MS0x03
> +#define NOA1305_INTEGR_TIME_50MS 0x04
> +#define NOA1305_INTEGR_TIME_25MS 0x05
> +#define NOA1305_INTEGR_TIME_12_5MS   0x06
> +#define NOA1305_INTEGR_TIME_6_25MS   0x07
> +
> +#define NOA1305_DRIVER_NAME  "noa1305"
> +
> +struct noa1305_priv {
> + struct i2c_client *client;
> + struct regmap *regmap;
> + struct regulator *vin_reg;
> +};
> +
> +static int noa1305_measure(struct noa1305_priv *priv)
> +{
> + u8 data[2];
> + int ret;
> +
> + ret = regmap_bulk_read(priv->regmap, NOA1305_REG_ALS_DATA_LSB, data,
> +2);
> + if (ret < 0)
> + return ret;
> +
> + return (data[1] << 8) | data[0];
Make data an explicit __le16  and use an endian swap here as on
little endian platforms it'll be free.

> +}
> +
> +static const struct iio_chan_spec noa1305_channels[] = {
> + {
> + .type = IIO_LIGHT,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> + }
> +};
> +
> +static int noa1305_rea

[PATCH v2 2/2] iio: light: noa1305: Add support for NOA1305

2019-06-28 Thread Martyn Welch
This driver adds the initial support for the ON Semiconductor
NOA1305 Ambient Light Sensor.

Originally written by Sergei Miroshnichenko. Found here:
  
https://github.com/EmcraftSystems/linux-upstream/commit/196d6cf897e632d2cb82d45484bd7a1bfdd5b6d9

Signed-off-by: Sergei M 
Signed-off-by: Martyn Welch 
---

Changes:
v2: Correcting authorship and SOB.

 drivers/iio/light/Kconfig   |  10 ++
 drivers/iio/light/Makefile  |   1 +
 drivers/iio/light/noa1305.c | 247 
 3 files changed, 258 insertions(+)
 create mode 100644 drivers/iio/light/noa1305.c

diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 954c958cfc43..d1db0ec0d0f5 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -309,6 +309,16 @@ config MAX44009
 To compile this driver as a module, choose M here:
 the module will be called max44009.
 
+config NOA1305
+   tristate "ON Semiconductor NOA1305 ambient light sensor"
+   depends on I2C
+   help
+Say Y here if you want to build support for the ON Semiconductor
+NOA1305 ambient light sensor.
+
+To compile this driver as a module, choose M here:
+The module will be called noa1305.
+
 config OPT3001
tristate "Texas Instruments OPT3001 Light Sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index e40794fbb435..00d1f9b98f39 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_LTR501)  += ltr501.o
 obj-$(CONFIG_LV0104CS) += lv0104cs.o
 obj-$(CONFIG_MAX44000) += max44000.o
 obj-$(CONFIG_MAX44009) += max44009.o
+obj-$(CONFIG_NOA1305)  += noa1305.o
 obj-$(CONFIG_OPT3001)  += opt3001.o
 obj-$(CONFIG_PA12203001)   += pa12203001.o
 obj-$(CONFIG_RPR0521)  += rpr0521.o
diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c
new file mode 100644
index ..2c65c5c2e09a
--- /dev/null
+++ b/drivers/iio/light/noa1305.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Support for ON Semiconductor NOA1305 ambient light sensor
+ *
+ * Copyright (C) 2016 Emcraft Systems
+ * Copyright (C) 2019 Collabora Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NOA1305_REG_POWER_CONTROL  0x0
+#define NOA1305_REG_RESET  0x1
+#define NOA1305_REG_INTEGRATION_TIME   0x2
+#define NOA1305_REG_INT_SELECT 0x3
+#define NOA1305_REG_INT_THRESH_LSB 0x4
+#define NOA1305_REG_INT_THRESH_MSB 0x5
+#define NOA1305_REG_ALS_DATA_LSB   0x6
+#define NOA1305_REG_ALS_DATA_MSB   0x7
+#define NOA1305_REG_DEVICE_ID_LSB  0x8
+#define NOA1305_REG_DEVICE_ID_MSB  0x9
+
+#define NOA1305_DEVICE_ID  0x0519
+
+#define NOA1305_POWER_ON   0x08
+#define NOA1305_POWER_DOWN 0x00
+#define NOA1305_RESET  0x10
+
+#define NOA1305_INT_ACTIVE_HIGH0x01
+#define NOA1305_INT_ACTIVE_LOW 0x02
+#define NOA1305_INT_INACTIVE   0x03
+
+#define NOA1305_INTEGR_TIME_800MS  0x00
+#define NOA1305_INTEGR_TIME_400MS  0x01
+#define NOA1305_INTEGR_TIME_200MS  0x02
+#define NOA1305_INTEGR_TIME_100MS  0x03
+#define NOA1305_INTEGR_TIME_50MS   0x04
+#define NOA1305_INTEGR_TIME_25MS   0x05
+#define NOA1305_INTEGR_TIME_12_5MS 0x06
+#define NOA1305_INTEGR_TIME_6_25MS 0x07
+
+#define NOA1305_DRIVER_NAME"noa1305"
+
+struct noa1305_priv {
+   struct i2c_client *client;
+   struct regmap *regmap;
+   struct regulator *vin_reg;
+};
+
+static int noa1305_measure(struct noa1305_priv *priv)
+{
+   u8 data[2];
+   int ret;
+
+   ret = regmap_bulk_read(priv->regmap, NOA1305_REG_ALS_DATA_LSB, data,
+  2);
+   if (ret < 0)
+   return ret;
+
+   return (data[1] << 8) | data[0];
+}
+
+static const struct iio_chan_spec noa1305_channels[] = {
+   {
+   .type = IIO_LIGHT,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+   }
+};
+
+static int noa1305_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *chan,
+   int *val, int *val2, long mask)
+{
+   int ret = -EINVAL;
+   struct noa1305_priv *priv = iio_priv(indio_dev);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   switch (chan->type) {
+   case IIO_LIGHT:
+   ret = noa1305_measure(priv);
+   if (ret < 0)
+   return ret;
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+   default:
+   break;
+   }
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static const stru