--- v10
+++ v4
@@ -2,38 +2,15 @@
which include general-purpose ADC readings, battery voltage measurement,
and die temperature measurement.
-Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
-Reviewed-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
+Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
---
-Changes in v10:
- - none
-
-Changes in v9:
- - none
-
-Changes in v8:
- - rebase onto 4.9-rc1
-
-Changes in v7:
- - none
-
-Changes in v6:
- - update copyright
-
-Changes in v5:
- - add field void __iomem *base to struct mxs_lradc_adc
- - change arguments in all functions for accessing I/O memory
- to follow the previous change.
- - use devm_ioremap for mapping I/O memory
-
Changes in v4:
- update copyright
- use platform_get_irq_byname
- use irq_of_parse_and_map
Changes in v3:
- - make buffer large enough for timestamps
- - remove unnecessary blank lines
+ - nothing
Changes in v2:
- improve commit message
@@ -42,7 +19,7 @@
- remove wrapper show_scale_avail
- use correct syntax for comments
- use devm_iio_trigger_alloc
- - do not allocate buffer dynamically
+ - do not allocate buffer dynamically
- use iio_device_claim_*_mode helpers
- add spinlock in struct mxs_lradc_ts to enable locking in interrupt handler
- only grab irqs that are relevant to adc
@@ -52,15 +29,15 @@
drivers/iio/adc/Kconfig | 13 +
drivers/iio/adc/Makefile | 1 +
- drivers/iio/adc/mxs-lradc-adc.c | 845 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 859 insertions(+)
+ drivers/iio/adc/mxs-lradc-adc.c | 833 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 847 insertions(+)
create mode 100644 drivers/iio/adc/mxs-lradc-adc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
-index 57ebb99..ad6046a 100644
+index 932de1f..4ef3ad1 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
-@@ -219,6 +219,19 @@ config EXYNOS_ADC
+@@ -194,6 +194,19 @@ config EXYNOS_ADC
To compile this driver as a module, choose M here: the module will be
called exynos_adc.
@@ -77,16 +54,16 @@
+ This driver can also be built as a module. If so, the module will be
+ called mxs-lradc-adc.
+
- config FSL_MX25_ADC
- tristate "Freescale MX25 ADC driver"
- depends on MFD_MX25_TSADC
+ config HI8435
+ tristate "Holt Integrated Circuits HI-8435 threshold detector"
+ select IIO_TRIGGERED_EVENT
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
-index 96894b3..4b2cf9b 100644
+index b1aa456..9bb35c4 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
-@@ -35,6 +35,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
+@@ -29,6 +29,7 @@ obj-$(CONFIG_MAX1363) += max1363.o
+ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
- obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
+obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
@@ -94,19 +71,18 @@
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c
new file mode 100644
-index 0000000..6943220
+index 0000000..9c362ae
--- /dev/null
+++ b/drivers/iio/adc/mxs-lradc-adc.c
-@@ -0,0 +1,845 @@
+@@ -0,0 +1,833 @@
+/*
+ * Freescale MXS LRADC ADC driver
+ *
+ * Copyright (c) 2012 DENX Software Engineering, GmbH.
-+ * Copyright (c) 2016 Ksenija Stanojevic <ksenija.stanojevic-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * Authors:
-+ * Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>
-+ * Ksenija Stanojevic <ksenija.stanojevic-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
++ * Marek Vasut <marex@denx.de>
++ * Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
+ *
+ * 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
@@ -223,7 +199,6 @@
+ struct mxs_lradc *lradc;
+ struct device *dev;
+
-+ void __iomem *base;
+ u32 buffer[10];
+ struct iio_trigger *trig;
+ struct completion completion;
@@ -261,30 +236,30 @@
+ * used if doing raw sampling.
+ */
+ if (lradc->soc == IMX28_LRADC)
-+ mxs_lradc_reg_clear(adc->base, LRADC_CTRL1_LRADC_IRQ_EN(0),
++ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0),
+ LRADC_CTRL1);
-+ mxs_lradc_reg_clear(adc->base, 0x1, LRADC_CTRL0);
++ mxs_lradc_reg_clear(lradc, 0x1, LRADC_CTRL0);
+
+ /* Enable / disable the divider per requirement */
+ if (test_bit(chan, &adc->is_divided))
-+ mxs_lradc_reg_set(adc->base,
++ mxs_lradc_reg_set(lradc,
+ 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ LRADC_CTRL2);
+ else
-+ mxs_lradc_reg_clear(adc->base,
++ mxs_lradc_reg_clear(lradc,
+ 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ LRADC_CTRL2);
+
+ /* Clean the slot's previous content, then set new one. */
-+ mxs_lradc_reg_clear(adc->base, LRADC_CTRL4_LRADCSELECT_MASK(0),
++ mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0),
+ LRADC_CTRL4);
-+ mxs_lradc_reg_set(adc->base, chan, LRADC_CTRL4);
-+
-+ mxs_lradc_reg_wrt(adc->base, 0, LRADC_CH(0));
++ mxs_lradc_reg_set(lradc, chan, LRADC_CTRL4);
++
++ mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
+
+ /* Enable the IRQ and start sampling the channel. */
-+ mxs_lradc_reg_set(adc->base, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
-+ mxs_lradc_reg_set(adc->base, BIT(0), LRADC_CTRL0);
++ mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
++ mxs_lradc_reg_set(lradc, BIT(0), LRADC_CTRL0);
+
+ /* Wait for completion on the channel, 1 second max. */
+ ret = wait_for_completion_killable_timeout(&adc->completion, HZ);
@@ -294,12 +269,11 @@
+ goto err;
+
+ /* Read the data. */
-+ *val = readl(adc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK;
++ *val = readl(lradc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK;
+ ret = IIO_VAL_INT;
+
+err:
-+ mxs_lradc_reg_clear(adc->base, LRADC_CTRL1_LRADC_IRQ_EN(0),
-+ LRADC_CTRL1);
++ mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
+
+ iio_device_release_direct_mode(iio_dev);
+
@@ -496,7 +470,7 @@
+ struct iio_dev *iio = data;
+ struct mxs_lradc_adc *adc = iio_priv(iio);
+ struct mxs_lradc *lradc = adc->lradc;
-+ unsigned long reg = readl(adc->base + LRADC_CTRL1);
++ unsigned long reg = readl(lradc->base + LRADC_CTRL1);
+ unsigned long flags;
+
+ if (!(reg & mxs_lradc_irq_mask(lradc)))
@@ -512,7 +486,7 @@
+ complete(&adc->completion);
+ }
+
-+ mxs_lradc_reg_clear(adc->base, reg & mxs_lradc_irq_mask(lradc),
++ mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc),
+ LRADC_CTRL1);
+
+ return IRQ_HANDLED;
@@ -530,8 +504,8 @@
+ unsigned int i, j = 0;
+
+ for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
-+ adc->buffer[j] = readl(adc->base + LRADC_CH(j));
-+ mxs_lradc_reg_wrt(adc->base, chan_value, LRADC_CH(j));
++ adc->buffer[j] = readl(adc->lradc->base + LRADC_CH(j));
++ mxs_lradc_reg_wrt(adc->lradc, chan_value, LRADC_CH(j));
+ adc->buffer[j] &= LRADC_CH_VALUE_MASK;
+ adc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
+ j++;
@@ -550,7 +524,7 @@
+ struct mxs_lradc_adc *adc = iio_priv(iio);
+ const u32 st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
+
-+ mxs_lradc_reg_wrt(adc->base, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
++ mxs_lradc_reg_wrt(adc->lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
+
+ return 0;
+}
@@ -602,27 +576,26 @@
+ ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
+
+ if (lradc->soc == IMX28_LRADC)
-+ mxs_lradc_reg_clear(adc->base,
++ mxs_lradc_reg_clear(lradc,
+ lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
+ LRADC_CTRL1);
-+ mxs_lradc_reg_clear(adc->base, lradc->buffer_vchans, LRADC_CTRL0);
++ mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
+
+ for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
+ ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
+ ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
+ ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
-+ mxs_lradc_reg_wrt(adc->base, chan_value, LRADC_CH(ofs));
++ mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
+ bitmap_set(&enable, ofs, 1);
+ ofs++;
+ }
+
-+ mxs_lradc_reg_clear(adc->base, LRADC_DELAY_TRIGGER_LRADCS_MASK |
++ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+ LRADC_DELAY_KICK, LRADC_DELAY(0));
-+ mxs_lradc_reg_clear(adc->base, ctrl4_clr, LRADC_CTRL4);
-+ mxs_lradc_reg_set(adc->base, ctrl4_set, LRADC_CTRL4);
-+ mxs_lradc_reg_set(adc->base, ctrl1_irq, LRADC_CTRL1);
-+ mxs_lradc_reg_set(adc->base,
-+ enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
++ mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
++ mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
++ mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
++ mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+ LRADC_DELAY(0));
+
+ return 0;
@@ -633,12 +606,12 @@
+ struct mxs_lradc_adc *adc = iio_priv(iio);
+ struct mxs_lradc *lradc = adc->lradc;
+
-+ mxs_lradc_reg_clear(adc->base, LRADC_DELAY_TRIGGER_LRADCS_MASK |
++ mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+ LRADC_DELAY_KICK, LRADC_DELAY(0));
+
-+ mxs_lradc_reg_clear(adc->base, lradc->buffer_vchans, LRADC_CTRL0);
++ mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
+ if (lradc->soc == IMX28_LRADC)
-+ mxs_lradc_reg_clear(adc->base,
++ mxs_lradc_reg_clear(lradc,
+ lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
+ LRADC_CTRL1);
+
@@ -776,25 +749,27 @@
+
+static void mxs_lradc_adc_hw_init(struct mxs_lradc_adc *adc)
+{
++ struct mxs_lradc *lradc = adc->lradc;
++
+ /* The ADC always uses DELAY CHANNEL 0. */
+ const u32 adc_cfg =
+ (1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
+ (LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
+
+ /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
-+ mxs_lradc_reg_wrt(adc->base, adc_cfg, LRADC_DELAY(0));
++ mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
+
+ /*
+ * Start internal temperature sensing by clearing bit
+ * HW_LRADC_CTRL2_TEMPSENSE_PWD. This bit can be left cleared
+ * after power up.
+ */
-+ mxs_lradc_reg_wrt(adc->base, 0, LRADC_CTRL2);
++ mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
+}
+
+static void mxs_lradc_adc_hw_stop(struct mxs_lradc_adc *adc)
+{
-+ mxs_lradc_reg_wrt(adc->base, 0, LRADC_DELAY(0));
++ mxs_lradc_reg_wrt(adc->lradc, 0, LRADC_DELAY(0));
+}
+
+static int mxs_lradc_adc_probe(struct platform_device *pdev)
@@ -803,7 +778,6 @@
+ struct mxs_lradc *lradc = dev_get_platdata(dev);
+ struct mxs_lradc_adc *adc;
+ struct iio_dev *iio;
-+ struct resource *iores;
+ int ret, irq, virq, i, s, n;
+ u64 scale_uv;
+ const char **irq_name;
@@ -818,11 +792,6 @@
+ adc = iio_priv(iio);
+ adc->lradc = lradc;
+ adc->dev = dev;
-+
-+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ adc->base = devm_ioremap(dev, iores->start, resource_size(iores));
-+ if (IS_ERR(adc->base))
-+ return PTR_ERR(adc->base);
+
+ init_completion(&adc->completion);
+ spin_lock_init(&adc->lock);
@@ -847,10 +816,6 @@
+ irq_name = mx28_lradc_adc_irq_names;
+ n = ARRAY_SIZE(mx28_lradc_adc_irq_names);
+ }
-+
-+ ret = stmp_reset_block(adc->base);
-+ if (ret)
-+ return ret;
+
+ for (i = 0; i < n; i++) {
+ irq = platform_get_irq_byname(pdev, irq_name[i]);
@@ -939,7 +904,7 @@
+};
+module_platform_driver(mxs_lradc_adc_driver);
+
-+MODULE_AUTHOR("Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>");
++MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
+MODULE_DESCRIPTION("Freescale MXS LRADC driver general purpose ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mxs-lradc-adc");