Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-19 Thread Johannes Thumshirn
On Tue, Feb 18, 2014 at 07:17:04PM +, Jonathan Cameron wrote:
>
>
> On February 18, 2014 3:34:14 PM GMT+00:00, Johannes Thumshirn 
>  wrote:
> >Add support for MEN 16z188 ADC IP Core on MCB FPGAs.
> >
> >Signed-off-by: Johannes Thumshirn 
> Looks pretty good apart from the nitpicks. One more little thing...

Thanks, I'll rework this and the comments from Peter Meerwald and Lars-Peter
Clausen in v2 of the patch series as well.

I think it'll be done by monday.

Thanks,
Johannes
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-19 Thread Johannes Thumshirn
On Tue, Feb 18, 2014 at 07:17:04PM +, Jonathan Cameron wrote:


 On February 18, 2014 3:34:14 PM GMT+00:00, Johannes Thumshirn 
 johannes.thumsh...@men.de wrote:
 Add support for MEN 16z188 ADC IP Core on MCB FPGAs.
 
 Signed-off-by: Johannes Thumshirn johannes.thumsh...@men.de
 Looks pretty good apart from the nitpicks. One more little thing...

Thanks, I'll rework this and the comments from Peter Meerwald and Lars-Peter
Clausen in v2 of the patch series as well.

I think it'll be done by monday.

Thanks,
Johannes
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Jonathan Cameron


On February 18, 2014 3:34:14 PM GMT+00:00, Johannes Thumshirn 
 wrote:
>Add support for MEN 16z188 ADC IP Core on MCB FPGAs.
>
>Signed-off-by: Johannes Thumshirn 
Looks pretty good apart from the nitpicks. One more little thing...
>---
> drivers/iio/adc/Kconfig|  10 +++
> drivers/iio/adc/Makefile   |   1 +
>drivers/iio/adc/men_z188_adc.c | 172
>+
> 3 files changed, 183 insertions(+)
> create mode 100644 drivers/iio/adc/men_z188_adc.c
>
>diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>index 2209f28..5209437 100644
>--- a/drivers/iio/adc/Kconfig
>+++ b/drivers/iio/adc/Kconfig
>@@ -204,4 +204,14 @@ config VIPERBOARD_ADC
> Say yes here to access the ADC part of the Nano River
> Technologies Viperboard.
> 
Alphabetical order please.
>+config MEN_Z188_ADC
>+  tristate "MEN 16z188 ADC IP Core support"
>+  depends on MCB
>+  help
>+Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
>+carrier.
>+
>+This driver can also be built as a module. If so, the module will
>be
>+called men_z188_adc.
>+
> endmenu
>diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
>index ba9a10a..1584391 100644
>--- a/drivers/iio/adc/Makefile
>+++ b/drivers/iio/adc/Makefile
>@@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
> obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
> obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
> obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
And alphabetical order here as well.
>+obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
>diff --git a/drivers/iio/adc/men_z188_adc.c
>b/drivers/iio/adc/men_z188_adc.c
>new file mode 100644
>index 000..8bc66cf
>--- /dev/null
>+++ b/drivers/iio/adc/men_z188_adc.c
>@@ -0,0 +1,172 @@
>+/*
>+ * MEN 16z188 Analoge to Digial Converter
>+ *
>+ * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
>+ * Author: Johannes Thumshirn 
>+ *
>+ * This program is free software; you can redistribute it and/or
>modify it
>+ * under the terms of the GNU General Public License as published by
>the Free
>+ * Software Foundation; version 2 of the License.
>+ */
>+#include 
>+#include 
>+#include 
>+#include 
>+
>+#define Z188_ADC_MAX_CHAN 8
>+#define Z188_ADC_GAIN 0x070
>+#define Z188_MODE_VOLTAGE BIT(27)
>+#define Z188_CFG_AUTO 0x1
>+#define Z188_CTRL_REG 0x40
>+
>+#define ADC_DATA(x) (((x) >> 2) & 0x7c)
>+#define ADC_OVR(x) ((x) & 0x1)
>+
>+struct z188_adc {
>+  struct resource *mem;
>+  void __iomem *base;
>+};
>+
>+#define Z188_ADC_CHANNEL(idx) {   \
>+  .type = IIO_VOLTAGE,\
>+  .indexed = 1,   \
>+  .channel = (idx),   \
>+  .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
>+}
>+
>+static struct iio_chan_spec z188_adc_iio_channels[] = {
>+  Z188_ADC_CHANNEL(0),
>+  Z188_ADC_CHANNEL(1),
>+  Z188_ADC_CHANNEL(2),
>+  Z188_ADC_CHANNEL(3),
>+  Z188_ADC_CHANNEL(4),
>+  Z188_ADC_CHANNEL(5),
>+  Z188_ADC_CHANNEL(6),
>+  Z188_ADC_CHANNEL(7),
>+};
>+
>+static int z188_iio_read_raw(struct iio_dev *iio_dev,
>+  struct iio_chan_spec const *chan,
>+  int *val,
>+  int *val2,
>+  long info)
>+{
>+  struct z188_adc *adc = iio_priv(iio_dev);
>+  int ret = 0;
>+  u16 tmp = 0;
>+
>+
>+  switch (info) {
>+  case IIO_CHAN_INFO_RAW:
>+  tmp = readw(adc->base + chan->channel * 4);
>+
>+  if (ADC_OVR(tmp)) {
>+  dev_info(_dev->dev,
>+  "Oversampling error on ADC channel %d\n",
>+  chan->channel);
>+  return -EIO;
>+  }
>+  *val = ADC_DATA(tmp);
>+  ret = IIO_VAL_INT;
>+  break;
>+  default:
>+  ret = -EINVAL;
>+  break;
>+  }
>+
>+  return ret;
>+}
>+
>+static struct iio_info z188_adc_info = {
>+  .read_raw = _iio_read_raw,
>+  .driver_module = THIS_MODULE,
>+};
>+
>+static void men_z188_config_channels(void __iomem *addr)
>+{
>+  int i;
>+  u32 cfg;
>+  u32 ctl;
>+
>+  ctl = readl(addr + Z188_CTRL_REG);
>+  ctl |= Z188_CFG_AUTO;
>+  writel(ctl, addr + Z188_CTRL_REG);
>+
>+  for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
>+  cfg = readl(addr + i);
>+  cfg &= ~Z188_ADC_GAIN;
>+  cfg |= Z188_MODE_VOLTAGE;
>+  writel(cfg, addr + i);
>+  }
>+}
>+
>+static int men_z188_probe(struct mcb_device *dev,
>+  const struct mcb_device_id *id)
>+{
>+  struct z188_adc *adc;
>+  struct iio_dev *indio_dev;
>+  struct resource *mem;
>+
>+  indio_dev = devm_iio_device_alloc(>dev, sizeof(struct

Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Lars-Peter Clausen

On top of what Peter said. Just some nitpicks...
[...]

+static struct iio_chan_spec z188_adc_iio_channels[] = {


const


+   Z188_ADC_CHANNEL(0),
+   Z188_ADC_CHANNEL(1),
+   Z188_ADC_CHANNEL(2),
+   Z188_ADC_CHANNEL(3),
+   Z188_ADC_CHANNEL(4),
+   Z188_ADC_CHANNEL(5),
+   Z188_ADC_CHANNEL(6),
+   Z188_ADC_CHANNEL(7),
+};
+

[...]

+static struct iio_info z188_adc_info = {


const


+   .read_raw = _iio_read_raw,
+   .driver_module = THIS_MODULE,
+};


> +
> +static void men_z188_remove(struct mcb_device *dev)
> +{
[...]
> +  mcb_set_drvdata(dev, NULL);

This is already done by the device driver core.

> +}
[...]
> +static struct mcb_device_id men_z188_ids[] = {

const

> +  { .device = 0xbc },
> +};
> +MODULE_DEVICE_TABLE(mcb, men_z188_ids);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Peter Meerwald

some quick comments below...

> Add support for MEN 16z188 ADC IP Core on MCB FPGAs.
 
> Signed-off-by: Johannes Thumshirn 
> ---
>  drivers/iio/adc/Kconfig|  10 +++
>  drivers/iio/adc/Makefile   |   1 +
>  drivers/iio/adc/men_z188_adc.c | 172 
> +
>  3 files changed, 183 insertions(+)
>  create mode 100644 drivers/iio/adc/men_z188_adc.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 2209f28..5209437 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -204,4 +204,14 @@ config VIPERBOARD_ADC
> Say yes here to access the ADC part of the Nano River
> Technologies Viperboard.
>  
> +config MEN_Z188_ADC
> + tristate "MEN 16z188 ADC IP Core support"
> + depends on MCB
> + help
> +   Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
> +   carrier.

support _for_ the 

> +
> +   This driver can also be built as a module. If so, the module will be
> +   called men_z188_adc.
> +
>  endmenu
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index ba9a10a..1584391 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>  obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
>  obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
>  obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
> +obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
> diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
> new file mode 100644
> index 000..8bc66cf
> --- /dev/null
> +++ b/drivers/iio/adc/men_z188_adc.c
> @@ -0,0 +1,172 @@
> +/*
> + * MEN 16z188 Analoge to Digial Converter

Analog

> + *
> + * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
> + * Author: Johannes Thumshirn 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the Free
> + * Software Foundation; version 2 of the License.
> + */

newline

> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define Z188_ADC_MAX_CHAN8
> +#define Z188_ADC_GAIN0x070
> +#define Z188_MODE_VOLTAGEBIT(27)
> +#define Z188_CFG_AUTO0x1
> +#define Z188_CTRL_REG0x40
> +
> +#define ADC_DATA(x) (((x) >> 2) & 0x7c)
> +#define ADC_OVR(x) ((x) & 0x1)
> +
> +struct z188_adc {
> + struct resource *mem;
> + void __iomem *base;
> +};
> +
> +#define Z188_ADC_CHANNEL(idx) {  \
> + .type = IIO_VOLTAGE,\
> + .indexed = 1,   \
> + .channel = (idx),   \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
> +}
> +
> +static struct iio_chan_spec z188_adc_iio_channels[] = {
> + Z188_ADC_CHANNEL(0),
> + Z188_ADC_CHANNEL(1),
> + Z188_ADC_CHANNEL(2),
> + Z188_ADC_CHANNEL(3),
> + Z188_ADC_CHANNEL(4),
> + Z188_ADC_CHANNEL(5),
> + Z188_ADC_CHANNEL(6),
> + Z188_ADC_CHANNEL(7),
> +};
> +
> +static int z188_iio_read_raw(struct iio_dev *iio_dev,
> + struct iio_chan_spec const *chan,
> + int *val,
> + int *val2,
> + long info)
> +{
> + struct z188_adc *adc = iio_priv(iio_dev);
> + int ret = 0;
> + u16 tmp = 0;
> +

no need to init ret, tmp
delete extra newline

> +
> + switch (info) {
> + case IIO_CHAN_INFO_RAW:
> + tmp = readw(adc->base + chan->channel * 4);
> +
> + if (ADC_OVR(tmp)) {
> + dev_info(_dev->dev,
> + "Oversampling error on ADC channel %d\n",
> + chan->channel);
> + return -EIO;
> + }
> + *val = ADC_DATA(tmp);
> + ret = IIO_VAL_INT;
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static struct iio_info z188_adc_info = {
> + .read_raw = _iio_read_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +static void men_z188_config_channels(void __iomem *addr)
> +{
> + int i;
> + u32 cfg;
> + u32 ctl;
> +
> + ctl = readl(addr + Z188_CTRL_REG);
> + ctl |= Z188_CFG_AUTO;
> + writel(ctl, addr + Z188_CTRL_REG);
> +
> + for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
> + cfg = readl(addr + i);
> + cfg &= ~Z188_ADC_GAIN;
> + cfg |= Z188_MODE_VOLTAGE;
> + writel(cfg, addr + i);
> + }
> +}
> +
> +static int men_z188_probe(struct mcb_device *dev,
> + const struct mcb_device_id *id)
> +{
> + struct z188_adc *adc;
> + struct iio_dev *indio_dev;
> + struct resource *mem;
> +
> + indio_dev = devm_iio_device_alloc(>dev, 

[PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Johannes Thumshirn
Add support for MEN 16z188 ADC IP Core on MCB FPGAs.

Signed-off-by: Johannes Thumshirn 
---
 drivers/iio/adc/Kconfig|  10 +++
 drivers/iio/adc/Makefile   |   1 +
 drivers/iio/adc/men_z188_adc.c | 172 +
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/iio/adc/men_z188_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 2209f28..5209437 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -204,4 +204,14 @@ config VIPERBOARD_ADC
  Say yes here to access the ADC part of the Nano River
  Technologies Viperboard.
 
+config MEN_Z188_ADC
+   tristate "MEN 16z188 ADC IP Core support"
+   depends on MCB
+   help
+ Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
+ carrier.
+
+ This driver can also be built as a module. If so, the module will be
+ called men_z188_adc.
+
 endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index ba9a10a..1584391 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
+obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
new file mode 100644
index 000..8bc66cf
--- /dev/null
+++ b/drivers/iio/adc/men_z188_adc.c
@@ -0,0 +1,172 @@
+/*
+ * MEN 16z188 Analoge to Digial Converter
+ *
+ * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
+ * Author: Johannes Thumshirn 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ */
+#include 
+#include 
+#include 
+#include 
+
+#define Z188_ADC_MAX_CHAN  8
+#define Z188_ADC_GAIN  0x070
+#define Z188_MODE_VOLTAGE  BIT(27)
+#define Z188_CFG_AUTO  0x1
+#define Z188_CTRL_REG  0x40
+
+#define ADC_DATA(x) (((x) >> 2) & 0x7c)
+#define ADC_OVR(x) ((x) & 0x1)
+
+struct z188_adc {
+   struct resource *mem;
+   void __iomem *base;
+};
+
+#define Z188_ADC_CHANNEL(idx) {\
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (idx),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+}
+
+static struct iio_chan_spec z188_adc_iio_channels[] = {
+   Z188_ADC_CHANNEL(0),
+   Z188_ADC_CHANNEL(1),
+   Z188_ADC_CHANNEL(2),
+   Z188_ADC_CHANNEL(3),
+   Z188_ADC_CHANNEL(4),
+   Z188_ADC_CHANNEL(5),
+   Z188_ADC_CHANNEL(6),
+   Z188_ADC_CHANNEL(7),
+};
+
+static int z188_iio_read_raw(struct iio_dev *iio_dev,
+   struct iio_chan_spec const *chan,
+   int *val,
+   int *val2,
+   long info)
+{
+   struct z188_adc *adc = iio_priv(iio_dev);
+   int ret = 0;
+   u16 tmp = 0;
+
+
+   switch (info) {
+   case IIO_CHAN_INFO_RAW:
+   tmp = readw(adc->base + chan->channel * 4);
+
+   if (ADC_OVR(tmp)) {
+   dev_info(_dev->dev,
+   "Oversampling error on ADC channel %d\n",
+   chan->channel);
+   return -EIO;
+   }
+   *val = ADC_DATA(tmp);
+   ret = IIO_VAL_INT;
+   break;
+   default:
+   ret = -EINVAL;
+   break;
+   }
+
+   return ret;
+}
+
+static struct iio_info z188_adc_info = {
+   .read_raw = _iio_read_raw,
+   .driver_module = THIS_MODULE,
+};
+
+static void men_z188_config_channels(void __iomem *addr)
+{
+   int i;
+   u32 cfg;
+   u32 ctl;
+
+   ctl = readl(addr + Z188_CTRL_REG);
+   ctl |= Z188_CFG_AUTO;
+   writel(ctl, addr + Z188_CTRL_REG);
+
+   for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
+   cfg = readl(addr + i);
+   cfg &= ~Z188_ADC_GAIN;
+   cfg |= Z188_MODE_VOLTAGE;
+   writel(cfg, addr + i);
+   }
+}
+
+static int men_z188_probe(struct mcb_device *dev,
+   const struct mcb_device_id *id)
+{
+   struct z188_adc *adc;
+   struct iio_dev *indio_dev;
+   struct resource *mem;
+
+   indio_dev = devm_iio_device_alloc(>dev, sizeof(struct z188_adc));
+   if (!indio_dev)
+   return -ENOMEM;
+
+   adc = iio_priv(indio_dev);
+   indio_dev->name = "z188-adc";
+   indio_dev->dev.parent = >dev;
+   indio_dev->info = _adc_info;
+   indio_dev->modes = INDIO_DIRECT_MODE;
+   indio_dev->channels = 

[PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Johannes Thumshirn
Add support for MEN 16z188 ADC IP Core on MCB FPGAs.

Signed-off-by: Johannes Thumshirn johannes.thumsh...@men.de
---
 drivers/iio/adc/Kconfig|  10 +++
 drivers/iio/adc/Makefile   |   1 +
 drivers/iio/adc/men_z188_adc.c | 172 +
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/iio/adc/men_z188_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 2209f28..5209437 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -204,4 +204,14 @@ config VIPERBOARD_ADC
  Say yes here to access the ADC part of the Nano River
  Technologies Viperboard.
 
+config MEN_Z188_ADC
+   tristate MEN 16z188 ADC IP Core support
+   depends on MCB
+   help
+ Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
+ carrier.
+
+ This driver can also be built as a module. If so, the module will be
+ called men_z188_adc.
+
 endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index ba9a10a..1584391 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
+obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
new file mode 100644
index 000..8bc66cf
--- /dev/null
+++ b/drivers/iio/adc/men_z188_adc.c
@@ -0,0 +1,172 @@
+/*
+ * MEN 16z188 Analoge to Digial Converter
+ *
+ * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
+ * Author: Johannes Thumshirn johannes.thumsh...@men.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ */
+#include linux/kernel.h
+#include linux/module.h
+#include linux/mcb.h
+#include linux/iio/iio.h
+
+#define Z188_ADC_MAX_CHAN  8
+#define Z188_ADC_GAIN  0x070
+#define Z188_MODE_VOLTAGE  BIT(27)
+#define Z188_CFG_AUTO  0x1
+#define Z188_CTRL_REG  0x40
+
+#define ADC_DATA(x) (((x)  2)  0x7c)
+#define ADC_OVR(x) ((x)  0x1)
+
+struct z188_adc {
+   struct resource *mem;
+   void __iomem *base;
+};
+
+#define Z188_ADC_CHANNEL(idx) {\
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (idx),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+}
+
+static struct iio_chan_spec z188_adc_iio_channels[] = {
+   Z188_ADC_CHANNEL(0),
+   Z188_ADC_CHANNEL(1),
+   Z188_ADC_CHANNEL(2),
+   Z188_ADC_CHANNEL(3),
+   Z188_ADC_CHANNEL(4),
+   Z188_ADC_CHANNEL(5),
+   Z188_ADC_CHANNEL(6),
+   Z188_ADC_CHANNEL(7),
+};
+
+static int z188_iio_read_raw(struct iio_dev *iio_dev,
+   struct iio_chan_spec const *chan,
+   int *val,
+   int *val2,
+   long info)
+{
+   struct z188_adc *adc = iio_priv(iio_dev);
+   int ret = 0;
+   u16 tmp = 0;
+
+
+   switch (info) {
+   case IIO_CHAN_INFO_RAW:
+   tmp = readw(adc-base + chan-channel * 4);
+
+   if (ADC_OVR(tmp)) {
+   dev_info(iio_dev-dev,
+   Oversampling error on ADC channel %d\n,
+   chan-channel);
+   return -EIO;
+   }
+   *val = ADC_DATA(tmp);
+   ret = IIO_VAL_INT;
+   break;
+   default:
+   ret = -EINVAL;
+   break;
+   }
+
+   return ret;
+}
+
+static struct iio_info z188_adc_info = {
+   .read_raw = z188_iio_read_raw,
+   .driver_module = THIS_MODULE,
+};
+
+static void men_z188_config_channels(void __iomem *addr)
+{
+   int i;
+   u32 cfg;
+   u32 ctl;
+
+   ctl = readl(addr + Z188_CTRL_REG);
+   ctl |= Z188_CFG_AUTO;
+   writel(ctl, addr + Z188_CTRL_REG);
+
+   for (i = 0; i  Z188_ADC_MAX_CHAN; i++) {
+   cfg = readl(addr + i);
+   cfg = ~Z188_ADC_GAIN;
+   cfg |= Z188_MODE_VOLTAGE;
+   writel(cfg, addr + i);
+   }
+}
+
+static int men_z188_probe(struct mcb_device *dev,
+   const struct mcb_device_id *id)
+{
+   struct z188_adc *adc;
+   struct iio_dev *indio_dev;
+   struct resource *mem;
+
+   indio_dev = devm_iio_device_alloc(dev-dev, sizeof(struct z188_adc));
+   if (!indio_dev)
+   return -ENOMEM;
+
+   adc = iio_priv(indio_dev);
+   indio_dev-name = z188-adc;
+   indio_dev-dev.parent = dev-dev;
+   

Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Peter Meerwald

some quick comments below...

 Add support for MEN 16z188 ADC IP Core on MCB FPGAs.
 
 Signed-off-by: Johannes Thumshirn johannes.thumsh...@men.de
 ---
  drivers/iio/adc/Kconfig|  10 +++
  drivers/iio/adc/Makefile   |   1 +
  drivers/iio/adc/men_z188_adc.c | 172 
 +
  3 files changed, 183 insertions(+)
  create mode 100644 drivers/iio/adc/men_z188_adc.c
 
 diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
 index 2209f28..5209437 100644
 --- a/drivers/iio/adc/Kconfig
 +++ b/drivers/iio/adc/Kconfig
 @@ -204,4 +204,14 @@ config VIPERBOARD_ADC
 Say yes here to access the ADC part of the Nano River
 Technologies Viperboard.
  
 +config MEN_Z188_ADC
 + tristate MEN 16z188 ADC IP Core support
 + depends on MCB
 + help
 +   Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
 +   carrier.

support _for_ the 

 +
 +   This driver can also be built as a module. If so, the module will be
 +   called men_z188_adc.
 +
  endmenu
 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
 index ba9a10a..1584391 100644
 --- a/drivers/iio/adc/Makefile
 +++ b/drivers/iio/adc/Makefile
 @@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
  obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
  obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
  obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
 +obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
 new file mode 100644
 index 000..8bc66cf
 --- /dev/null
 +++ b/drivers/iio/adc/men_z188_adc.c
 @@ -0,0 +1,172 @@
 +/*
 + * MEN 16z188 Analoge to Digial Converter

Analog

 + *
 + * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
 + * Author: Johannes Thumshirn johannes.thumsh...@men.de
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License as published by the Free
 + * Software Foundation; version 2 of the License.
 + */

newline

 +#include linux/kernel.h
 +#include linux/module.h
 +#include linux/mcb.h
 +#include linux/iio/iio.h
 +
 +#define Z188_ADC_MAX_CHAN8
 +#define Z188_ADC_GAIN0x070
 +#define Z188_MODE_VOLTAGEBIT(27)
 +#define Z188_CFG_AUTO0x1
 +#define Z188_CTRL_REG0x40
 +
 +#define ADC_DATA(x) (((x)  2)  0x7c)
 +#define ADC_OVR(x) ((x)  0x1)
 +
 +struct z188_adc {
 + struct resource *mem;
 + void __iomem *base;
 +};
 +
 +#define Z188_ADC_CHANNEL(idx) {  \
 + .type = IIO_VOLTAGE,\
 + .indexed = 1,   \
 + .channel = (idx),   \
 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 +}
 +
 +static struct iio_chan_spec z188_adc_iio_channels[] = {
 + Z188_ADC_CHANNEL(0),
 + Z188_ADC_CHANNEL(1),
 + Z188_ADC_CHANNEL(2),
 + Z188_ADC_CHANNEL(3),
 + Z188_ADC_CHANNEL(4),
 + Z188_ADC_CHANNEL(5),
 + Z188_ADC_CHANNEL(6),
 + Z188_ADC_CHANNEL(7),
 +};
 +
 +static int z188_iio_read_raw(struct iio_dev *iio_dev,
 + struct iio_chan_spec const *chan,
 + int *val,
 + int *val2,
 + long info)
 +{
 + struct z188_adc *adc = iio_priv(iio_dev);
 + int ret = 0;
 + u16 tmp = 0;
 +

no need to init ret, tmp
delete extra newline

 +
 + switch (info) {
 + case IIO_CHAN_INFO_RAW:
 + tmp = readw(adc-base + chan-channel * 4);
 +
 + if (ADC_OVR(tmp)) {
 + dev_info(iio_dev-dev,
 + Oversampling error on ADC channel %d\n,
 + chan-channel);
 + return -EIO;
 + }
 + *val = ADC_DATA(tmp);
 + ret = IIO_VAL_INT;
 + break;
 + default:
 + ret = -EINVAL;
 + break;
 + }
 +
 + return ret;
 +}
 +
 +static struct iio_info z188_adc_info = {
 + .read_raw = z188_iio_read_raw,
 + .driver_module = THIS_MODULE,
 +};
 +
 +static void men_z188_config_channels(void __iomem *addr)
 +{
 + int i;
 + u32 cfg;
 + u32 ctl;
 +
 + ctl = readl(addr + Z188_CTRL_REG);
 + ctl |= Z188_CFG_AUTO;
 + writel(ctl, addr + Z188_CTRL_REG);
 +
 + for (i = 0; i  Z188_ADC_MAX_CHAN; i++) {
 + cfg = readl(addr + i);
 + cfg = ~Z188_ADC_GAIN;
 + cfg |= Z188_MODE_VOLTAGE;
 + writel(cfg, addr + i);
 + }
 +}
 +
 +static int men_z188_probe(struct mcb_device *dev,
 + const struct mcb_device_id *id)
 +{
 + struct z188_adc *adc;
 + struct iio_dev *indio_dev;
 + struct resource *mem;
 +
 + indio_dev = devm_iio_device_alloc(dev-dev, sizeof(struct z188_adc));
 + if (!indio_dev)
 +

Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Lars-Peter Clausen

On top of what Peter said. Just some nitpicks...
[...]

+static struct iio_chan_spec z188_adc_iio_channels[] = {


const


+   Z188_ADC_CHANNEL(0),
+   Z188_ADC_CHANNEL(1),
+   Z188_ADC_CHANNEL(2),
+   Z188_ADC_CHANNEL(3),
+   Z188_ADC_CHANNEL(4),
+   Z188_ADC_CHANNEL(5),
+   Z188_ADC_CHANNEL(6),
+   Z188_ADC_CHANNEL(7),
+};
+

[...]

+static struct iio_info z188_adc_info = {


const


+   .read_raw = z188_iio_read_raw,
+   .driver_module = THIS_MODULE,
+};


 +
 +static void men_z188_remove(struct mcb_device *dev)
 +{
[...]
 +  mcb_set_drvdata(dev, NULL);

This is already done by the device driver core.

 +}
[...]
 +static struct mcb_device_id men_z188_ids[] = {

const

 +  { .device = 0xbc },
 +};
 +MODULE_DEVICE_TABLE(mcb, men_z188_ids);
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver

2014-02-18 Thread Jonathan Cameron


On February 18, 2014 3:34:14 PM GMT+00:00, Johannes Thumshirn 
johannes.thumsh...@men.de wrote:
Add support for MEN 16z188 ADC IP Core on MCB FPGAs.

Signed-off-by: Johannes Thumshirn johannes.thumsh...@men.de
Looks pretty good apart from the nitpicks. One more little thing...
---
 drivers/iio/adc/Kconfig|  10 +++
 drivers/iio/adc/Makefile   |   1 +
drivers/iio/adc/men_z188_adc.c | 172
+
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/iio/adc/men_z188_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 2209f28..5209437 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -204,4 +204,14 @@ config VIPERBOARD_ADC
 Say yes here to access the ADC part of the Nano River
 Technologies Viperboard.
 
Alphabetical order please.
+config MEN_Z188_ADC
+  tristate MEN 16z188 ADC IP Core support
+  depends on MCB
+  help
+Say yes here to access support the MEN 16z188 ADC IP-Core on a MCB
+carrier.
+
+This driver can also be built as a module. If so, the module will
be
+called men_z188_adc.
+
 endmenu
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index ba9a10a..1584391 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
And alphabetical order here as well.
+obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
diff --git a/drivers/iio/adc/men_z188_adc.c
b/drivers/iio/adc/men_z188_adc.c
new file mode 100644
index 000..8bc66cf
--- /dev/null
+++ b/drivers/iio/adc/men_z188_adc.c
@@ -0,0 +1,172 @@
+/*
+ * MEN 16z188 Analoge to Digial Converter
+ *
+ * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
+ * Author: Johannes Thumshirn johannes.thumsh...@men.de
+ *
+ * This program is free software; you can redistribute it and/or
modify it
+ * under the terms of the GNU General Public License as published by
the Free
+ * Software Foundation; version 2 of the License.
+ */
+#include linux/kernel.h
+#include linux/module.h
+#include linux/mcb.h
+#include linux/iio/iio.h
+
+#define Z188_ADC_MAX_CHAN 8
+#define Z188_ADC_GAIN 0x070
+#define Z188_MODE_VOLTAGE BIT(27)
+#define Z188_CFG_AUTO 0x1
+#define Z188_CTRL_REG 0x40
+
+#define ADC_DATA(x) (((x)  2)  0x7c)
+#define ADC_OVR(x) ((x)  0x1)
+
+struct z188_adc {
+  struct resource *mem;
+  void __iomem *base;
+};
+
+#define Z188_ADC_CHANNEL(idx) {   \
+  .type = IIO_VOLTAGE,\
+  .indexed = 1,   \
+  .channel = (idx),   \
+  .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+}
+
+static struct iio_chan_spec z188_adc_iio_channels[] = {
+  Z188_ADC_CHANNEL(0),
+  Z188_ADC_CHANNEL(1),
+  Z188_ADC_CHANNEL(2),
+  Z188_ADC_CHANNEL(3),
+  Z188_ADC_CHANNEL(4),
+  Z188_ADC_CHANNEL(5),
+  Z188_ADC_CHANNEL(6),
+  Z188_ADC_CHANNEL(7),
+};
+
+static int z188_iio_read_raw(struct iio_dev *iio_dev,
+  struct iio_chan_spec const *chan,
+  int *val,
+  int *val2,
+  long info)
+{
+  struct z188_adc *adc = iio_priv(iio_dev);
+  int ret = 0;
+  u16 tmp = 0;
+
+
+  switch (info) {
+  case IIO_CHAN_INFO_RAW:
+  tmp = readw(adc-base + chan-channel * 4);
+
+  if (ADC_OVR(tmp)) {
+  dev_info(iio_dev-dev,
+  Oversampling error on ADC channel %d\n,
+  chan-channel);
+  return -EIO;
+  }
+  *val = ADC_DATA(tmp);
+  ret = IIO_VAL_INT;
+  break;
+  default:
+  ret = -EINVAL;
+  break;
+  }
+
+  return ret;
+}
+
+static struct iio_info z188_adc_info = {
+  .read_raw = z188_iio_read_raw,
+  .driver_module = THIS_MODULE,
+};
+
+static void men_z188_config_channels(void __iomem *addr)
+{
+  int i;
+  u32 cfg;
+  u32 ctl;
+
+  ctl = readl(addr + Z188_CTRL_REG);
+  ctl |= Z188_CFG_AUTO;
+  writel(ctl, addr + Z188_CTRL_REG);
+
+  for (i = 0; i  Z188_ADC_MAX_CHAN; i++) {
+  cfg = readl(addr + i);
+  cfg = ~Z188_ADC_GAIN;
+  cfg |= Z188_MODE_VOLTAGE;
+  writel(cfg, addr + i);
+  }
+}
+
+static int men_z188_probe(struct mcb_device *dev,
+  const struct mcb_device_id *id)
+{
+  struct z188_adc *adc;
+  struct iio_dev *indio_dev;
+  struct resource *mem;
+
+  indio_dev = devm_iio_device_alloc(dev-dev, sizeof(struct
z188_adc));
+  if (!indio_dev)
+