Re: [PATCH 3/3] iio: adc: Add MEN 16z188 ADC driver
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
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
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
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
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
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
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
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
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
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) +