Re: [PATCH v2 1/3] iio: adc: add support for mcp3911

2018-08-02 Thread Marcus Folkesson
Hi Jonathan,

Sorry for the delay, I've been away from keyboard for a few days.

On Sun, Jul 29, 2018 at 12:44:22PM +0100, Jonathan Cameron wrote:
> On Tue, 24 Jul 2018 20:30:02 +0200
> Marcus Folkesson  wrote:
> 
> > MCP3911 is a dual channel Analog Front End (AFE) containing two
> > synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> > 
> > Signed-off-by: Marcus Folkesson 
> > Signed-off-by: Kent Gustavsson 
> Hi
> 
> I think you missed cleaning up the clock enable in the remove.
> If it is safe to not do so it should also be safe in the error path
> of probe.

I've actually noticed this and had it prepared in v4 :-)

> 
> A couple of trivial other things jumped out at me whilst reading.

Thank you so much, I will fix these.
> 
> Thanks,
> 
> Jonathan
> > ---
> > 
> > Notes:
> > v2:
> > - cleanups and bugfixes (thanks Peter Meerwald-Stadler)
> > - drop hardware gain
> > - use the presence or lack of regulator to indicate if we go 
> > for internal or external voltage reference
> > - do not store device node in private struct
> > - drop support to set width in devicetree
> > - use the presence or lack of clock to indicate if we go for 
> > internal or external clock
> > 
> >  drivers/iio/adc/Kconfig   |  10 ++
> >  drivers/iio/adc/Makefile  |   1 +
> >  drivers/iio/adc/mcp3911.c | 366 
> > ++
> >  3 files changed, 377 insertions(+)
> >  create mode 100644 drivers/iio/adc/mcp3911.c
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> > index 15606f237480..f9a41fa96fcc 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -501,6 +501,16 @@ config MCP3422
> >   This driver can also be built as a module. If so, the module will be
> >   called mcp3422.
> >  
> > +config MCP3911
> > +   tristate "Microchip Technology MCP3911 driver"
> > +   depends on SPI
> > +   help
> > + Say yes here to build support for Microchip Technology's MCP3911
> > + analog to digital converter.
> > +
> > + This driver can also be built as a module. If so, the module will be
> > + called mcp3911.
> > +
> >  config MEDIATEK_MT6577_AUXADC
> >  tristate "MediaTek AUXADC driver"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> > index 28a9423997f3..3cfebfff7d26 100644
> > --- a/drivers/iio/adc/Makefile
> > +++ b/drivers/iio/adc/Makefile
> > @@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
> >  obj-$(CONFIG_MAX9611) += max9611.o
> >  obj-$(CONFIG_MCP320X) += mcp320x.o
> >  obj-$(CONFIG_MCP3422) += mcp3422.o
> > +obj-$(CONFIG_MCP3911) += mcp3911.o
> >  obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
> >  obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
> >  obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
> > diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> > new file mode 100644
> > index ..29aa39930ead
> > --- /dev/null
> > +++ b/drivers/iio/adc/mcp3911.c
> > @@ -0,0 +1,366 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for Microchip MCP3911, Two-channel Analog Front End
> > + *
> > + * Copyright (C) 2018 Marcus Folkesson 
> > + * Copyright (C) 2018 Kent Gustavsson 
> > + *
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define MCP3911_REG_CHANNEL0   0x00
> > +#define MCP3911_REG_CHANNEL1   0x03
> > +#define MCP3911_REG_MOD0x06
> > +#define MCP3911_REG_PHASE  0x07
> > +#define MCP3911_REG_GAIN   0x09
> > +
> > +#define MCP3911_REG_STATUSCOM  0x0a
> > +#define MCP3911_STATUSCOM_CH1_24WIDTH  BIT(4)
> > +#define MCP3911_STATUSCOM_CH0_24WIDTH  BIT(3)
> > +#define MCP3911_STATUSCOM_EN_OFFCALBIT(2)
> > +#define MCP3911_STATUSCOM_EN_GAINCAL   BIT(1)
> > +
> > +#define MCP3911_REG_CONFIG 0x0c
> > +#define MCP3911_CONFIG_CLKEXT  BIT(1)
> > +#define MCP3911_CONFIG_VREFEXT BIT(2)
> > +
> > +#define MCP3911_REG_OFFCAL_CH0 0x0e
> > +#define MCP3911_REG_GAINCAL_CH00x11
> > +#define MCP3911_REG_OFFCAL_CH1 0x14
> > +#define MCP3911_REG_GAINCAL_CH10x17
> > +#define MCP3911_REG_VREFCAL0x1a
> > +
> > +#define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
> > +#define MCP3911_OFFCAL(x)  (MCP3911_REG_OFFCAL_CH0 + x * 6)
> > +
> > +/* Internal voltage reference in uV */
> > +#define MCP3911_INT_VREF_UV120
> > +
> > +#define MCP3911_REG_READ(reg, id)  reg) << 1) | ((id) << 5) | (1 << 
> > 0)) & 0xff)
> > +#define MCP3911_REG_WRITE(reg, id) reg) << 1) | ((id) << 5) | (0 << 
> > 0)) & 0xff)
> > +
> > +#define MCP3911_NUM_CHANNELS   2
> > +
> > +struct mcp3911 {
> > +   struct spi_device *spi;
> > 

Re: [PATCH v2 1/3] iio: adc: add support for mcp3911

2018-08-02 Thread Marcus Folkesson
Hi Jonathan,

Sorry for the delay, I've been away from keyboard for a few days.

On Sun, Jul 29, 2018 at 12:44:22PM +0100, Jonathan Cameron wrote:
> On Tue, 24 Jul 2018 20:30:02 +0200
> Marcus Folkesson  wrote:
> 
> > MCP3911 is a dual channel Analog Front End (AFE) containing two
> > synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> > 
> > Signed-off-by: Marcus Folkesson 
> > Signed-off-by: Kent Gustavsson 
> Hi
> 
> I think you missed cleaning up the clock enable in the remove.
> If it is safe to not do so it should also be safe in the error path
> of probe.

I've actually noticed this and had it prepared in v4 :-)

> 
> A couple of trivial other things jumped out at me whilst reading.

Thank you so much, I will fix these.
> 
> Thanks,
> 
> Jonathan
> > ---
> > 
> > Notes:
> > v2:
> > - cleanups and bugfixes (thanks Peter Meerwald-Stadler)
> > - drop hardware gain
> > - use the presence or lack of regulator to indicate if we go 
> > for internal or external voltage reference
> > - do not store device node in private struct
> > - drop support to set width in devicetree
> > - use the presence or lack of clock to indicate if we go for 
> > internal or external clock
> > 
> >  drivers/iio/adc/Kconfig   |  10 ++
> >  drivers/iio/adc/Makefile  |   1 +
> >  drivers/iio/adc/mcp3911.c | 366 
> > ++
> >  3 files changed, 377 insertions(+)
> >  create mode 100644 drivers/iio/adc/mcp3911.c
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> > index 15606f237480..f9a41fa96fcc 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -501,6 +501,16 @@ config MCP3422
> >   This driver can also be built as a module. If so, the module will be
> >   called mcp3422.
> >  
> > +config MCP3911
> > +   tristate "Microchip Technology MCP3911 driver"
> > +   depends on SPI
> > +   help
> > + Say yes here to build support for Microchip Technology's MCP3911
> > + analog to digital converter.
> > +
> > + This driver can also be built as a module. If so, the module will be
> > + called mcp3911.
> > +
> >  config MEDIATEK_MT6577_AUXADC
> >  tristate "MediaTek AUXADC driver"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> > index 28a9423997f3..3cfebfff7d26 100644
> > --- a/drivers/iio/adc/Makefile
> > +++ b/drivers/iio/adc/Makefile
> > @@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
> >  obj-$(CONFIG_MAX9611) += max9611.o
> >  obj-$(CONFIG_MCP320X) += mcp320x.o
> >  obj-$(CONFIG_MCP3422) += mcp3422.o
> > +obj-$(CONFIG_MCP3911) += mcp3911.o
> >  obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
> >  obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
> >  obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
> > diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> > new file mode 100644
> > index ..29aa39930ead
> > --- /dev/null
> > +++ b/drivers/iio/adc/mcp3911.c
> > @@ -0,0 +1,366 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for Microchip MCP3911, Two-channel Analog Front End
> > + *
> > + * Copyright (C) 2018 Marcus Folkesson 
> > + * Copyright (C) 2018 Kent Gustavsson 
> > + *
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define MCP3911_REG_CHANNEL0   0x00
> > +#define MCP3911_REG_CHANNEL1   0x03
> > +#define MCP3911_REG_MOD0x06
> > +#define MCP3911_REG_PHASE  0x07
> > +#define MCP3911_REG_GAIN   0x09
> > +
> > +#define MCP3911_REG_STATUSCOM  0x0a
> > +#define MCP3911_STATUSCOM_CH1_24WIDTH  BIT(4)
> > +#define MCP3911_STATUSCOM_CH0_24WIDTH  BIT(3)
> > +#define MCP3911_STATUSCOM_EN_OFFCALBIT(2)
> > +#define MCP3911_STATUSCOM_EN_GAINCAL   BIT(1)
> > +
> > +#define MCP3911_REG_CONFIG 0x0c
> > +#define MCP3911_CONFIG_CLKEXT  BIT(1)
> > +#define MCP3911_CONFIG_VREFEXT BIT(2)
> > +
> > +#define MCP3911_REG_OFFCAL_CH0 0x0e
> > +#define MCP3911_REG_GAINCAL_CH00x11
> > +#define MCP3911_REG_OFFCAL_CH1 0x14
> > +#define MCP3911_REG_GAINCAL_CH10x17
> > +#define MCP3911_REG_VREFCAL0x1a
> > +
> > +#define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
> > +#define MCP3911_OFFCAL(x)  (MCP3911_REG_OFFCAL_CH0 + x * 6)
> > +
> > +/* Internal voltage reference in uV */
> > +#define MCP3911_INT_VREF_UV120
> > +
> > +#define MCP3911_REG_READ(reg, id)  reg) << 1) | ((id) << 5) | (1 << 
> > 0)) & 0xff)
> > +#define MCP3911_REG_WRITE(reg, id) reg) << 1) | ((id) << 5) | (0 << 
> > 0)) & 0xff)
> > +
> > +#define MCP3911_NUM_CHANNELS   2
> > +
> > +struct mcp3911 {
> > +   struct spi_device *spi;
> > 

Re: [PATCH v2 1/3] iio: adc: add support for mcp3911

2018-07-29 Thread Jonathan Cameron
On Tue, 24 Jul 2018 20:30:02 +0200
Marcus Folkesson  wrote:

> MCP3911 is a dual channel Analog Front End (AFE) containing two
> synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> 
> Signed-off-by: Marcus Folkesson 
> Signed-off-by: Kent Gustavsson 
Hi

I think you missed cleaning up the clock enable in the remove.
If it is safe to not do so it should also be safe in the error path
of probe.

A couple of trivial other things jumped out at me whilst reading.

Thanks,

Jonathan
> ---
> 
> Notes:
> v2:
>   - cleanups and bugfixes (thanks Peter Meerwald-Stadler)
>   - drop hardware gain
>   - use the presence or lack of regulator to indicate if we go for 
> internal or external voltage reference
>   - do not store device node in private struct
>   - drop support to set width in devicetree
>   - use the presence or lack of clock to indicate if we go for internal 
> or external clock
> 
>  drivers/iio/adc/Kconfig   |  10 ++
>  drivers/iio/adc/Makefile  |   1 +
>  drivers/iio/adc/mcp3911.c | 366 
> ++
>  3 files changed, 377 insertions(+)
>  create mode 100644 drivers/iio/adc/mcp3911.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 15606f237480..f9a41fa96fcc 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -501,6 +501,16 @@ config MCP3422
> This driver can also be built as a module. If so, the module will be
> called mcp3422.
>  
> +config MCP3911
> + tristate "Microchip Technology MCP3911 driver"
> + depends on SPI
> + help
> +   Say yes here to build support for Microchip Technology's MCP3911
> +   analog to digital converter.
> +
> +   This driver can also be built as a module. If so, the module will be
> +   called mcp3911.
> +
>  config MEDIATEK_MT6577_AUXADC
>  tristate "MediaTek AUXADC driver"
>  depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 28a9423997f3..3cfebfff7d26 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
>  obj-$(CONFIG_MAX9611) += max9611.o
>  obj-$(CONFIG_MCP320X) += mcp320x.o
>  obj-$(CONFIG_MCP3422) += mcp3422.o
> +obj-$(CONFIG_MCP3911) += mcp3911.o
>  obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
>  obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
>  obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> new file mode 100644
> index ..29aa39930ead
> --- /dev/null
> +++ b/drivers/iio/adc/mcp3911.c
> @@ -0,0 +1,366 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Microchip MCP3911, Two-channel Analog Front End
> + *
> + * Copyright (C) 2018 Marcus Folkesson 
> + * Copyright (C) 2018 Kent Gustavsson 
> + *
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define MCP3911_REG_CHANNEL0 0x00
> +#define MCP3911_REG_CHANNEL1 0x03
> +#define MCP3911_REG_MOD  0x06
> +#define MCP3911_REG_PHASE0x07
> +#define MCP3911_REG_GAIN 0x09
> +
> +#define MCP3911_REG_STATUSCOM0x0a
> +#define MCP3911_STATUSCOM_CH1_24WIDTHBIT(4)
> +#define MCP3911_STATUSCOM_CH0_24WIDTHBIT(3)
> +#define MCP3911_STATUSCOM_EN_OFFCAL  BIT(2)
> +#define MCP3911_STATUSCOM_EN_GAINCAL BIT(1)
> +
> +#define MCP3911_REG_CONFIG   0x0c
> +#define MCP3911_CONFIG_CLKEXTBIT(1)
> +#define MCP3911_CONFIG_VREFEXT   BIT(2)
> +
> +#define MCP3911_REG_OFFCAL_CH0   0x0e
> +#define MCP3911_REG_GAINCAL_CH0  0x11
> +#define MCP3911_REG_OFFCAL_CH1   0x14
> +#define MCP3911_REG_GAINCAL_CH1  0x17
> +#define MCP3911_REG_VREFCAL  0x1a
> +
> +#define MCP3911_CHANNEL(x)   (MCP3911_REG_CHANNEL0 + x * 3)
> +#define MCP3911_OFFCAL(x)(MCP3911_REG_OFFCAL_CH0 + x * 6)
> +
> +/* Internal voltage reference in uV */
> +#define MCP3911_INT_VREF_UV  120
> +
> +#define MCP3911_REG_READ(reg, id)reg) << 1) | ((id) << 5) | (1 << 
> 0)) & 0xff)
> +#define MCP3911_REG_WRITE(reg, id)   reg) << 1) | ((id) << 5) | (0 << 
> 0)) & 0xff)
> +
> +#define MCP3911_NUM_CHANNELS 2
> +
> +struct mcp3911 {
> + struct spi_device *spi;
> + struct mutex lock;
> + struct regulator *vref;
> + struct clk *adc_clk;
> + u32 dev_addr;
> +};
> +
> +static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
> +{
> + int ret;
> +
> + reg = MCP3911_REG_READ(reg, adc->dev_addr);
> + ret = spi_write_then_read(adc->spi, , 1, val, len);
> + if (ret < 0)
> + return ret;
> +
> + be32_to_cpus(val);
> + *val >>= ((4 - len) * 8);
> + dev_dbg(>spi->dev, "reading 0x%x from register 0x%x\n", *val,
> +

Re: [PATCH v2 1/3] iio: adc: add support for mcp3911

2018-07-29 Thread Jonathan Cameron
On Tue, 24 Jul 2018 20:30:02 +0200
Marcus Folkesson  wrote:

> MCP3911 is a dual channel Analog Front End (AFE) containing two
> synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> 
> Signed-off-by: Marcus Folkesson 
> Signed-off-by: Kent Gustavsson 
Hi

I think you missed cleaning up the clock enable in the remove.
If it is safe to not do so it should also be safe in the error path
of probe.

A couple of trivial other things jumped out at me whilst reading.

Thanks,

Jonathan
> ---
> 
> Notes:
> v2:
>   - cleanups and bugfixes (thanks Peter Meerwald-Stadler)
>   - drop hardware gain
>   - use the presence or lack of regulator to indicate if we go for 
> internal or external voltage reference
>   - do not store device node in private struct
>   - drop support to set width in devicetree
>   - use the presence or lack of clock to indicate if we go for internal 
> or external clock
> 
>  drivers/iio/adc/Kconfig   |  10 ++
>  drivers/iio/adc/Makefile  |   1 +
>  drivers/iio/adc/mcp3911.c | 366 
> ++
>  3 files changed, 377 insertions(+)
>  create mode 100644 drivers/iio/adc/mcp3911.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 15606f237480..f9a41fa96fcc 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -501,6 +501,16 @@ config MCP3422
> This driver can also be built as a module. If so, the module will be
> called mcp3422.
>  
> +config MCP3911
> + tristate "Microchip Technology MCP3911 driver"
> + depends on SPI
> + help
> +   Say yes here to build support for Microchip Technology's MCP3911
> +   analog to digital converter.
> +
> +   This driver can also be built as a module. If so, the module will be
> +   called mcp3911.
> +
>  config MEDIATEK_MT6577_AUXADC
>  tristate "MediaTek AUXADC driver"
>  depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 28a9423997f3..3cfebfff7d26 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
>  obj-$(CONFIG_MAX9611) += max9611.o
>  obj-$(CONFIG_MCP320X) += mcp320x.o
>  obj-$(CONFIG_MCP3422) += mcp3422.o
> +obj-$(CONFIG_MCP3911) += mcp3911.o
>  obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
>  obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
>  obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> new file mode 100644
> index ..29aa39930ead
> --- /dev/null
> +++ b/drivers/iio/adc/mcp3911.c
> @@ -0,0 +1,366 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Microchip MCP3911, Two-channel Analog Front End
> + *
> + * Copyright (C) 2018 Marcus Folkesson 
> + * Copyright (C) 2018 Kent Gustavsson 
> + *
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define MCP3911_REG_CHANNEL0 0x00
> +#define MCP3911_REG_CHANNEL1 0x03
> +#define MCP3911_REG_MOD  0x06
> +#define MCP3911_REG_PHASE0x07
> +#define MCP3911_REG_GAIN 0x09
> +
> +#define MCP3911_REG_STATUSCOM0x0a
> +#define MCP3911_STATUSCOM_CH1_24WIDTHBIT(4)
> +#define MCP3911_STATUSCOM_CH0_24WIDTHBIT(3)
> +#define MCP3911_STATUSCOM_EN_OFFCAL  BIT(2)
> +#define MCP3911_STATUSCOM_EN_GAINCAL BIT(1)
> +
> +#define MCP3911_REG_CONFIG   0x0c
> +#define MCP3911_CONFIG_CLKEXTBIT(1)
> +#define MCP3911_CONFIG_VREFEXT   BIT(2)
> +
> +#define MCP3911_REG_OFFCAL_CH0   0x0e
> +#define MCP3911_REG_GAINCAL_CH0  0x11
> +#define MCP3911_REG_OFFCAL_CH1   0x14
> +#define MCP3911_REG_GAINCAL_CH1  0x17
> +#define MCP3911_REG_VREFCAL  0x1a
> +
> +#define MCP3911_CHANNEL(x)   (MCP3911_REG_CHANNEL0 + x * 3)
> +#define MCP3911_OFFCAL(x)(MCP3911_REG_OFFCAL_CH0 + x * 6)
> +
> +/* Internal voltage reference in uV */
> +#define MCP3911_INT_VREF_UV  120
> +
> +#define MCP3911_REG_READ(reg, id)reg) << 1) | ((id) << 5) | (1 << 
> 0)) & 0xff)
> +#define MCP3911_REG_WRITE(reg, id)   reg) << 1) | ((id) << 5) | (0 << 
> 0)) & 0xff)
> +
> +#define MCP3911_NUM_CHANNELS 2
> +
> +struct mcp3911 {
> + struct spi_device *spi;
> + struct mutex lock;
> + struct regulator *vref;
> + struct clk *adc_clk;
> + u32 dev_addr;
> +};
> +
> +static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
> +{
> + int ret;
> +
> + reg = MCP3911_REG_READ(reg, adc->dev_addr);
> + ret = spi_write_then_read(adc->spi, , 1, val, len);
> + if (ret < 0)
> + return ret;
> +
> + be32_to_cpus(val);
> + *val >>= ((4 - len) * 8);
> + dev_dbg(>spi->dev, "reading 0x%x from register 0x%x\n", *val,
> +

[PATCH v2 1/3] iio: adc: add support for mcp3911

2018-07-24 Thread Marcus Folkesson
MCP3911 is a dual channel Analog Front End (AFE) containing two
synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).

Signed-off-by: Marcus Folkesson 
Signed-off-by: Kent Gustavsson 
---

Notes:
v2:
- cleanups and bugfixes (thanks Peter Meerwald-Stadler)
- drop hardware gain
- use the presence or lack of regulator to indicate if we go for 
internal or external voltage reference
- do not store device node in private struct
- drop support to set width in devicetree
- use the presence or lack of clock to indicate if we go for internal 
or external clock

 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp3911.c | 366 ++
 3 files changed, 377 insertions(+)
 create mode 100644 drivers/iio/adc/mcp3911.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 15606f237480..f9a41fa96fcc 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -501,6 +501,16 @@ config MCP3422
  This driver can also be built as a module. If so, the module will be
  called mcp3422.
 
+config MCP3911
+   tristate "Microchip Technology MCP3911 driver"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3911
+ analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp3911.
+
 config MEDIATEK_MT6577_AUXADC
 tristate "MediaTek AUXADC driver"
 depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 28a9423997f3..3cfebfff7d26 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MAX9611) += max9611.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_MCP3422) += mcp3422.o
+obj-$(CONFIG_MCP3911) += mcp3911.o
 obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
new file mode 100644
index ..29aa39930ead
--- /dev/null
+++ b/drivers/iio/adc/mcp3911.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Microchip MCP3911, Two-channel Analog Front End
+ *
+ * Copyright (C) 2018 Marcus Folkesson 
+ * Copyright (C) 2018 Kent Gustavsson 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MCP3911_REG_CHANNEL0   0x00
+#define MCP3911_REG_CHANNEL1   0x03
+#define MCP3911_REG_MOD0x06
+#define MCP3911_REG_PHASE  0x07
+#define MCP3911_REG_GAIN   0x09
+
+#define MCP3911_REG_STATUSCOM  0x0a
+#define MCP3911_STATUSCOM_CH1_24WIDTH  BIT(4)
+#define MCP3911_STATUSCOM_CH0_24WIDTH  BIT(3)
+#define MCP3911_STATUSCOM_EN_OFFCALBIT(2)
+#define MCP3911_STATUSCOM_EN_GAINCAL   BIT(1)
+
+#define MCP3911_REG_CONFIG 0x0c
+#define MCP3911_CONFIG_CLKEXT  BIT(1)
+#define MCP3911_CONFIG_VREFEXT BIT(2)
+
+#define MCP3911_REG_OFFCAL_CH0 0x0e
+#define MCP3911_REG_GAINCAL_CH00x11
+#define MCP3911_REG_OFFCAL_CH1 0x14
+#define MCP3911_REG_GAINCAL_CH10x17
+#define MCP3911_REG_VREFCAL0x1a
+
+#define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
+#define MCP3911_OFFCAL(x)  (MCP3911_REG_OFFCAL_CH0 + x * 6)
+
+/* Internal voltage reference in uV */
+#define MCP3911_INT_VREF_UV120
+
+#define MCP3911_REG_READ(reg, id)  reg) << 1) | ((id) << 5) | (1 << 
0)) & 0xff)
+#define MCP3911_REG_WRITE(reg, id) reg) << 1) | ((id) << 5) | (0 << 
0)) & 0xff)
+
+#define MCP3911_NUM_CHANNELS   2
+
+struct mcp3911 {
+   struct spi_device *spi;
+   struct mutex lock;
+   struct regulator *vref;
+   struct clk *adc_clk;
+   u32 dev_addr;
+};
+
+static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
+{
+   int ret;
+
+   reg = MCP3911_REG_READ(reg, adc->dev_addr);
+   ret = spi_write_then_read(adc->spi, , 1, val, len);
+   if (ret < 0)
+   return ret;
+
+   be32_to_cpus(val);
+   *val >>= ((4 - len) * 8);
+   dev_dbg(>spi->dev, "reading 0x%x from register 0x%x\n", *val,
+   reg>>1);
+   return ret;
+}
+
+static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len)
+{
+   dev_dbg(>spi->dev, "writing 0x%x to register 0x%x\n", val, reg);
+
+   val <<= (3 - len) * 8;
+   cpu_to_be32s();
+   val |= MCP3911_REG_WRITE(reg, adc->dev_addr);
+
+   return spi_write(adc->spi, , len+1);
+}
+
+static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
+   u32 val, u8 len)
+{
+   u32 tmp;
+   int ret;
+
+   ret = 

[PATCH v2 1/3] iio: adc: add support for mcp3911

2018-07-24 Thread Marcus Folkesson
MCP3911 is a dual channel Analog Front End (AFE) containing two
synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).

Signed-off-by: Marcus Folkesson 
Signed-off-by: Kent Gustavsson 
---

Notes:
v2:
- cleanups and bugfixes (thanks Peter Meerwald-Stadler)
- drop hardware gain
- use the presence or lack of regulator to indicate if we go for 
internal or external voltage reference
- do not store device node in private struct
- drop support to set width in devicetree
- use the presence or lack of clock to indicate if we go for internal 
or external clock

 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp3911.c | 366 ++
 3 files changed, 377 insertions(+)
 create mode 100644 drivers/iio/adc/mcp3911.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 15606f237480..f9a41fa96fcc 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -501,6 +501,16 @@ config MCP3422
  This driver can also be built as a module. If so, the module will be
  called mcp3422.
 
+config MCP3911
+   tristate "Microchip Technology MCP3911 driver"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3911
+ analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp3911.
+
 config MEDIATEK_MT6577_AUXADC
 tristate "MediaTek AUXADC driver"
 depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 28a9423997f3..3cfebfff7d26 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MAX9611) += max9611.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_MCP3422) += mcp3422.o
+obj-$(CONFIG_MCP3911) += mcp3911.o
 obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
new file mode 100644
index ..29aa39930ead
--- /dev/null
+++ b/drivers/iio/adc/mcp3911.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Microchip MCP3911, Two-channel Analog Front End
+ *
+ * Copyright (C) 2018 Marcus Folkesson 
+ * Copyright (C) 2018 Kent Gustavsson 
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MCP3911_REG_CHANNEL0   0x00
+#define MCP3911_REG_CHANNEL1   0x03
+#define MCP3911_REG_MOD0x06
+#define MCP3911_REG_PHASE  0x07
+#define MCP3911_REG_GAIN   0x09
+
+#define MCP3911_REG_STATUSCOM  0x0a
+#define MCP3911_STATUSCOM_CH1_24WIDTH  BIT(4)
+#define MCP3911_STATUSCOM_CH0_24WIDTH  BIT(3)
+#define MCP3911_STATUSCOM_EN_OFFCALBIT(2)
+#define MCP3911_STATUSCOM_EN_GAINCAL   BIT(1)
+
+#define MCP3911_REG_CONFIG 0x0c
+#define MCP3911_CONFIG_CLKEXT  BIT(1)
+#define MCP3911_CONFIG_VREFEXT BIT(2)
+
+#define MCP3911_REG_OFFCAL_CH0 0x0e
+#define MCP3911_REG_GAINCAL_CH00x11
+#define MCP3911_REG_OFFCAL_CH1 0x14
+#define MCP3911_REG_GAINCAL_CH10x17
+#define MCP3911_REG_VREFCAL0x1a
+
+#define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
+#define MCP3911_OFFCAL(x)  (MCP3911_REG_OFFCAL_CH0 + x * 6)
+
+/* Internal voltage reference in uV */
+#define MCP3911_INT_VREF_UV120
+
+#define MCP3911_REG_READ(reg, id)  reg) << 1) | ((id) << 5) | (1 << 
0)) & 0xff)
+#define MCP3911_REG_WRITE(reg, id) reg) << 1) | ((id) << 5) | (0 << 
0)) & 0xff)
+
+#define MCP3911_NUM_CHANNELS   2
+
+struct mcp3911 {
+   struct spi_device *spi;
+   struct mutex lock;
+   struct regulator *vref;
+   struct clk *adc_clk;
+   u32 dev_addr;
+};
+
+static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
+{
+   int ret;
+
+   reg = MCP3911_REG_READ(reg, adc->dev_addr);
+   ret = spi_write_then_read(adc->spi, , 1, val, len);
+   if (ret < 0)
+   return ret;
+
+   be32_to_cpus(val);
+   *val >>= ((4 - len) * 8);
+   dev_dbg(>spi->dev, "reading 0x%x from register 0x%x\n", *val,
+   reg>>1);
+   return ret;
+}
+
+static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len)
+{
+   dev_dbg(>spi->dev, "writing 0x%x to register 0x%x\n", val, reg);
+
+   val <<= (3 - len) * 8;
+   cpu_to_be32s();
+   val |= MCP3911_REG_WRITE(reg, adc->dev_addr);
+
+   return spi_write(adc->spi, , len+1);
+}
+
+static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
+   u32 val, u8 len)
+{
+   u32 tmp;
+   int ret;
+
+   ret =