--- v5
+++ v4
@@ -4,20 +4,13 @@
Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
---
-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
@@ -36,8 +29,8 @@
drivers/iio/adc/Kconfig | 13 +
drivers/iio/adc/Makefile | 1 +
- drivers/iio/adc/mxs-lradc-adc.c | 844 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 858 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
@@ -78,10 +71,10 @@
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..bfbc051
+index 0000000..9c362ae
--- /dev/null
+++ b/drivers/iio/adc/mxs-lradc-adc.c
-@@ -0,0 +1,844 @@
+@@ -0,0 +1,833 @@
+/*
+ * Freescale MXS LRADC ADC driver
+ *
@@ -206,7 +199,6 @@
+ struct mxs_lradc *lradc;
+ struct device *dev;
+
-+ void __iomem *base;
+ u32 buffer[10];
+ struct iio_trigger *trig;
+ struct completion completion;
@@ -244,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);
@@ -277,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);
+
@@ -479,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)))
@@ -495,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;
@@ -513,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++;
@@ -533,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;
+}
@@ -585,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;
@@ -616,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);
+
@@ -759,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)
@@ -786,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;
@@ -801,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);
@@ -830,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]);