// SPDX-License-Identifier: GPL-2.0-only /* * NXP SAR-ADC driver (adapted from Freescale Vybrid vf610 ADC driver * by Fugang Duan ) * * Copyright 2013 Freescale Semiconductor, Inc. * Copyright 2017, 2020-2025 NXP * Copyright 2025, Linaro Ltd */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* SAR ADC registers. */ #define NXP_SAR_ADC_CDR(__base, __channel) (((__base) + 0x100) + ((__channel) * 0x4)) #define NXP_SAR_ADC_CDR_CDATA_MASK GENMASK(11, 0) #define NXP_SAR_ADC_CDR_VALID BIT(19) /* Main Configuration Register */ #define NXP_SAR_ADC_MCR(__base) ((__base) + 0x00) #define NXP_SAR_ADC_MCR_PWDN BIT(0) #define NXP_SAR_ADC_MCR_ACKO BIT(5) #define NXP_SAR_ADC_MCR_ADCLKSEL BIT(8) #define NXP_SAR_ADC_MCR_TSAMP_MASK GENMASK(10, 9) #define NXP_SAR_ADC_MCR_NRSMPL_MASK GENMASK(12, 11) #define NXP_SAR_ADC_MCR_AVGEN BIT(13) #define NXP_SAR_ADC_MCR_CALSTART BIT(14) #define NXP_SAR_ADC_MCR_NSTART BIT(24) #define NXP_SAR_ADC_MCR_MODE BIT(29) #define NXP_SAR_ADC_MCR_OWREN BIT(31) /* Main Status Register */ #define NXP_SAR_ADC_MSR(__base) ((__base) + 0x04) #define NXP_SAR_ADC_MSR_CALBUSY BIT(29) #define NXP_SAR_ADC_MSR_CALFAIL BIT(30) /* Interrupt Status Register */ #define NXP_SAR_ADC_ISR(__base) ((__base) + 0x10) #define NXP_SAR_ADC_ISR_ECH BIT(0) /* Channel Pending Register */ #define NXP_SAR_ADC_CEOCFR0(__base) ((__base) + 0x14) #define NXP_SAR_ADC_CEOCFR1(__base) ((__base) + 0x18) #define NXP_SAR_ADC_EOC_CH(c) BIT(c) /* Interrupt Mask Register */ #define NXP_SAR_ADC_IMR(__base) ((__base) + 0x20) /* Channel Interrupt Mask Register */ #define NXP_SAR_ADC_CIMR0(__base) ((__base) + 0x24) #define NXP_SAR_ADC_CIMR1(__base) ((__base) + 0x28) /* DMA Setting Register */ #define NXP_SAR_ADC_DMAE(__base) ((__base) + 0x40) #define NXP_SAR_ADC_DMAE_DMAEN BIT(0) #define NXP_SAR_ADC_DMAE_DCLR BIT(1) /* DMA Control register */ #define NXP_SAR_ADC_DMAR0(__base) ((__base) + 0x44) #define NXP_SAR_ADC_DMAR1(__base) ((__base) + 0x48) /* Conversion Timing Register */ #define NXP_SAR_ADC_CTR0(__base) ((__base) + 0x94) #define NXP_SAR_ADC_CTR1(__base) ((__base) + 0x98) #define NXP_SAR_ADC_CTR_INPSAMP_MIN 0x08 #define NXP_SAR_ADC_CTR_INPSAMP_MAX 0xff /* Normal Conversion Mask Register */ #define NXP_SAR_ADC_NCMR0(__base) ((__base) + 0xa4) #define NXP_SAR_ADC_NCMR1(__base) ((__base) + 0xa8) /* Normal Conversion Mask Register field define */ #define NXP_SAR_ADC_CH_MASK GENMASK(7, 0) /* Other field define */ #define NXP_SAR_ADC_CONV_TIMEOUT (msecs_to_jiffies(100)) #define NXP_SAR_ADC_CAL_TIMEOUT_US (100 * USEC_PER_MSEC) #define NXP_SAR_ADC_WAIT_US (2 * USEC_PER_MSEC) #define NXP_SAR_ADC_RESOLUTION 12 /* Duration of conversion phases */ #define NXP_SAR_ADC_TPT 2 #define NXP_SAR_ADC_DP 2 #define NXP_SAR_ADC_CT ((NXP_SAR_ADC_RESOLUTION + 2) * 4) #define NXP_SAR_ADC_CONV_TIME (NXP_SAR_ADC_TPT + NXP_SAR_ADC_CT + NXP_SAR_ADC_DP) #define NXP_SAR_ADC_NR_CHANNELS 8 #define NXP_PAGE_SIZE SZ_4K #define NXP_SAR_ADC_DMA_SAMPLE_SZ DMA_SLAVE_BUSWIDTH_4_BYTES #define NXP_SAR_ADC_DMA_BUFF_SZ (NXP_PAGE_SIZE * NXP_SAR_ADC_DMA_SAMPLE_SZ) #define NXP_SAR_ADC_DMA_SAMPLE_CNT (NXP_SAR_ADC_DMA_BUFF_SZ / NXP_SAR_ADC_DMA_SAMPLE_SZ) struct nxp_sar_adc { void __iomem *regs; phys_addr_t regs_phys; u8 current_channel; u8 channels_used; u16 value; u32 vref_mV; /* Save and restore context. */ u32 inpsamp; u32 pwdn; struct clk *clk; struct dma_chan *dma_chan; struct completion completion; struct circ_buf dma_buf; dma_addr_t rx_dma_buf; dma_cookie_t cookie; /* Protect circular buffers access. */ spinlock_t lock; /* Array of enabled channels. */ u16 buffered_chan[NXP_SAR_ADC_NR_CHANNELS]; /* Buffer to be filled by the DMA. */ IIO_DECLARE_BUFFER_WITH_TS(u16, buffer, NXP_SAR_ADC_NR_CHANNELS); }; struct nxp_sar_adc_data { u32 vref_mV; const char *model; }; #define ADC_CHAN(_idx, _chan_type) { \ .type = (_chan_type), \ .indexed = 1, \ .channel = (_idx), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (_idx), \ .scan_type = { \ .sign = 'u', \ .realbits = 12, \ .storagebits = 16, \ }, \ } static const struct iio_chan_spec nxp_sar_adc_iio_channels[] = { ADC_CHAN(0, IIO_VOLTAGE), ADC_CHAN(1, IIO_VOLTAGE), ADC_CHAN(2, IIO_VOLTAGE), ADC_CHAN(3, IIO_VOLTAGE), ADC_CHAN(4, IIO_VOLTAGE), ADC_CHAN(5, IIO_VOLTAGE), ADC_CHAN(6, IIO_VOLTAGE), ADC_CHAN(7, IIO_VOLTAGE), /* * The NXP SAR ADC documentation marks the channels 8 to 31 as * "Reserved". Reflect the same in the driver in case new ADC * variants comes with more channels. */ IIO_CHAN_SOFT_TIMESTAMP(32), }; static void nxp_sar_adc_irq_cfg(struct nxp_sar_adc *info, bool enable) { if (enable) writel(NXP_SAR_ADC_ISR_ECH, NXP_SAR_ADC_IMR(info->regs)); else writel(0, NXP_SAR_ADC_IMR(info->regs)); } static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable) { u32 mcr; bool pwdn; mcr = readl(NXP_SAR_ADC_MCR(info->regs)); /* * Get the current state and return it later. This is used for * suspend/resume to get the power state */ pwdn = FIELD_GET(NXP_SAR_ADC_MCR_PWDN, mcr); /* When the enabled flag is not set, we set the power down bit */ FIELD_MODIFY(NXP_SAR_ADC_MCR_PWDN, &mcr, !enable); writel(mcr, NXP_SAR_ADC_MCR(info->regs)); /* * Ensure there are at least three cycles between the * configuration of NCMR and the setting of NSTART. */ if (enable) ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3)); return pwdn; } static inline bool nxp_sar_adc_enable(struct nxp_sar_adc *info) { return nxp_sar_adc_set_enabled(info, true); } static inline bool nxp_sar_adc_disable(struct nxp_sar_adc *info) { return nxp_sar_adc_set_enabled(info, false); } static inline void nxp_sar_adc_calibration_start(void __iomem *base) { u32 mcr = readl(NXP_SAR_ADC_MCR(base)); FIELD_MODIFY(NXP_SAR_ADC_MCR_CALSTART, &mcr, 0x1); writel(mcr, NXP_SAR_ADC_MCR(base)); } static inline int nxp_sar_adc_calibration_wait(void __iomem *base) { u32 msr; int ret; ret = readl_poll_timeout(NXP_SAR_ADC_MSR(base), msr, !FIELD_GET(NXP_SAR_ADC_MSR_CALBUSY, msr), NXP_SAR_ADC_WAIT_US, NXP_SAR_ADC_CAL_TIMEOUT_US); if (ret) return ret; if (FIELD_GET(NXP_SAR_ADC_MSR_CALFAIL, msr)) { /* * If the calibration fails, the status register bit must be * cleared. */ FIELD_MODIFY(NXP_SAR_ADC_MSR_CALFAIL, &msr, 0x0); writel(msr, NXP_SAR_ADC_MSR(base)); return -EAGAIN; } return 0; } static int nxp_sar_adc_calibration(struct nxp_sar_adc *info) { int ret; /* Calibration works only if the ADC is powered up. */ nxp_sar_adc_enable(info); /* The calibration operation starts. */ nxp_sar_adc_calibration_start(info->regs); ret = nxp_sar_adc_calibration_wait(info->regs); /* * Calibration works only if the ADC is powered up. However * the calibration is called from the probe function where the * iio is not enabled, so we disable after the calibration. */ nxp_sar_adc_disable(info); return ret; } static void nxp_sar_adc_conversion_timing_set(struct nxp_sar_adc *info, u32 inpsamp) { inpsamp = clamp(inpsamp, NXP_SAR_ADC_CTR_INPSAMP_MIN, NXP_SAR_ADC_CTR_INPSAMP_MAX); writel(inpsamp, NXP_SAR_ADC_CTR0(info->regs)); } static u32 nxp_sar_adc_conversion_timing_get(struct nxp_sar_adc *info) { return readl(NXP_SAR_ADC_CTR0(info->regs)); } static void nxp_sar_adc_read_notify(struct nxp_sar_adc *info) { writel(NXP_SAR_ADC_CH_MASK, NXP_SAR_ADC_CEOCFR0(info->regs)); writel(NXP_SAR_ADC_CH_MASK, NXP_SAR_ADC_CEOCFR1(info->regs)); } static int nxp_sar_adc_read_data(struct nxp_sar_adc *info, unsigned int chan) { u32 ceocfr, cdr; ceocfr = readl(NXP_SAR_ADC_CEOCFR0(info->regs)); /* * FIELD_GET() can not be used here because EOC_CH is not constant. * TODO: Switch to field_get() when it will be available. */ if (!(NXP_SAR_ADC_EOC_CH(chan) & ceocfr)) return -EIO; cdr = readl(NXP_SAR_ADC_CDR(info->regs, chan)); if (!(FIELD_GET(NXP_SAR_ADC_CDR_VALID, cdr))) return -EIO; return FIELD_GET(NXP_SAR_ADC_CDR_CDATA_MASK, cdr); } static void nxp_sar_adc_isr_buffer(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); unsigned int i; int ret; for (i = 0; i < info->channels_used; i++) { ret = nxp_sar_adc_read_data(info, info->buffered_chan[i]); if (ret < 0) { nxp_sar_adc_read_notify(info); return; } info->buffer[i] = ret; } nxp_sar_adc_read_notify(info); iio_push_to_buffers_with_ts(indio_dev, info->buffer, sizeof(info->buffer), iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); } static void nxp_sar_adc_isr_read_raw(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); int ret; ret = nxp_sar_adc_read_data(info, info->current_channel); nxp_sar_adc_read_notify(info); if (ret < 0) return; info->value = ret; complete(&info->completion); } static irqreturn_t nxp_sar_adc_isr(int irq, void *dev_id) { struct iio_dev *indio_dev = dev_id; struct nxp_sar_adc *info = iio_priv(indio_dev); int isr; isr = readl(NXP_SAR_ADC_ISR(info->regs)); if (!(FIELD_GET(NXP_SAR_ADC_ISR_ECH, isr))) return IRQ_NONE; if (iio_buffer_enabled(indio_dev)) nxp_sar_adc_isr_buffer(indio_dev); else nxp_sar_adc_isr_read_raw(indio_dev); writel(NXP_SAR_ADC_ISR_ECH, NXP_SAR_ADC_ISR(info->regs)); return IRQ_HANDLED; } static void nxp_sar_adc_channels_disable(struct nxp_sar_adc *info, u32 mask) { u32 ncmr, cimr; ncmr = readl(NXP_SAR_ADC_NCMR0(info->regs)); cimr = readl(NXP_SAR_ADC_CIMR0(info->regs)); /* FIELD_MODIFY() can not be used because the mask is not constant */ ncmr &= ~mask; cimr &= ~mask; writel(ncmr, NXP_SAR_ADC_NCMR0(info->regs)); writel(cimr, NXP_SAR_ADC_CIMR0(info->regs)); } static void nxp_sar_adc_channels_enable(struct nxp_sar_adc *info, u32 mask) { u32 ncmr, cimr; ncmr = readl(NXP_SAR_ADC_NCMR0(info->regs)); cimr = readl(NXP_SAR_ADC_CIMR0(info->regs)); ncmr |= mask; cimr |= mask; writel(ncmr, NXP_SAR_ADC_NCMR0(info->regs)); writel(cimr, NXP_SAR_ADC_CIMR0(info->regs)); } static void nxp_sar_adc_dma_channels_enable(struct nxp_sar_adc *info, u32 mask) { u32 dmar; dmar = readl(NXP_SAR_ADC_DMAR0(info->regs)); dmar |= mask; writel(dmar, NXP_SAR_ADC_DMAR0(info->regs)); } static void nxp_sar_adc_dma_channels_disable(struct nxp_sar_adc *info, u32 mask) { u32 dmar; dmar = readl(NXP_SAR_ADC_DMAR0(info->regs)); dmar &= ~mask; writel(dmar, NXP_SAR_ADC_DMAR0(info->regs)); } static void nxp_sar_adc_dma_cfg(struct nxp_sar_adc *info, bool enable) { u32 dmae; dmae = readl(NXP_SAR_ADC_DMAE(info->regs)); FIELD_MODIFY(NXP_SAR_ADC_DMAE_DMAEN, &dmae, enable); writel(dmae, NXP_SAR_ADC_DMAE(info->regs)); } static void nxp_sar_adc_stop_conversion(struct nxp_sar_adc *info) { u32 mcr; mcr = readl(NXP_SAR_ADC_MCR(info->regs)); FIELD_MODIFY(NXP_SAR_ADC_MCR_NSTART, &mcr, 0x0); writel(mcr, NXP_SAR_ADC_MCR(info->regs)); /* * On disable, we have to wait for the transaction to finish. * ADC does not abort the transaction if a chain conversion is * in progress. Wait for the worst case scenario - 80 ADC clk * cycles. The clock rate is 80MHz, this routine is called * only when the capture finishes. The delay will be very * short, usec-ish, which is acceptable in the atomic context. */ ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80); } static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw) { u32 mcr; mcr = readl(NXP_SAR_ADC_MCR(info->regs)); FIELD_MODIFY(NXP_SAR_ADC_MCR_NSTART, &mcr, 0x1); FIELD_MODIFY(NXP_SAR_ADC_MCR_MODE, &mcr, raw ? 0 : 1); writel(mcr, NXP_SAR_ADC_MCR(info->regs)); return 0; } static int nxp_sar_adc_read_channel(struct nxp_sar_adc *info, int channel) { int ret; info->current_channel = channel; nxp_sar_adc_channels_enable(info, BIT(channel)); nxp_sar_adc_irq_cfg(info, true); nxp_sar_adc_enable(info); reinit_completion(&info->completion); ret = nxp_sar_adc_start_conversion(info, true); if (ret < 0) goto out_disable; if (!wait_for_completion_interruptible_timeout(&info->completion, NXP_SAR_ADC_CONV_TIMEOUT)) ret = -ETIMEDOUT; nxp_sar_adc_stop_conversion(info); out_disable: nxp_sar_adc_channels_disable(info, BIT(channel)); nxp_sar_adc_irq_cfg(info, false); nxp_sar_adc_disable(info); return ret; } static int nxp_sar_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct nxp_sar_adc *info = iio_priv(indio_dev); u32 inpsamp; int ret; switch (mask) { case IIO_CHAN_INFO_RAW: if (!iio_device_claim_direct(indio_dev)) return -EBUSY; ret = nxp_sar_adc_read_channel(info, chan->channel); iio_device_release_direct(indio_dev); if (ret) return ret; *val = info->value; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = info->vref_mV; *val2 = NXP_SAR_ADC_RESOLUTION; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_SAMP_FREQ: inpsamp = nxp_sar_adc_conversion_timing_get(info); *val = clk_get_rate(info->clk) / (inpsamp + NXP_SAR_ADC_CONV_TIME); return IIO_VAL_INT; default: return -EINVAL; } } static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct nxp_sar_adc *info = iio_priv(indio_dev); u32 inpsamp; switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: /* * Configures the sample period duration in terms of the SAR * controller clock. The minimum acceptable value is 8. * Configuring it to a value lower than 8 sets the sample period * to 8 cycles. We read the clock value and divide by the * sampling timing which gives us the number of cycles expected. * The value is 8-bit wide, consequently the max value is 0xFF. */ inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME; nxp_sar_adc_conversion_timing_set(info, inpsamp); return 0; default: return -EINVAL; } } static void nxp_sar_adc_dma_cb(void *data) { struct iio_dev *indio_dev = data; struct nxp_sar_adc *info = iio_priv(indio_dev); struct dma_tx_state state; struct circ_buf *dma_buf; struct device *dev_dma; u32 *dma_samples; s64 timestamp; int idx, ret; guard(spinlock_irqsave)(&info->lock); dma_buf = &info->dma_buf; dma_samples = (u32 *)dma_buf->buf; dev_dma = info->dma_chan->device->dev; /* * DMA in some corner cases might have already be charged for * the next transfer. Potentially there can be a race where * the residue changes while the dma engine updates the * buffer. That could be handled by using the * callback_result() instead of callback() because the residue * will be passed as a parameter to the function. However this * new callback is pretty new and the backend does not update * the residue. So let's stick to the version other drivers do * which has proven running well in production since several * years. */ dmaengine_tx_status(info->dma_chan, info->cookie, &state); dma_sync_single_for_cpu(dev_dma, info->rx_dma_buf, NXP_SAR_ADC_DMA_BUFF_SZ, DMA_FROM_DEVICE); /* Current head position. */ dma_buf->head = (NXP_SAR_ADC_DMA_BUFF_SZ - state.residue) / NXP_SAR_ADC_DMA_SAMPLE_SZ; /* If everything was transferred, avoid an off by one error. */ if (!state.residue) dma_buf->head--; /* Something went wrong and nothing transferred. */ if (state.residue != NXP_SAR_ADC_DMA_BUFF_SZ) { /* Make sure that head is multiple of info->channels_used. */ dma_buf->head -= dma_buf->head % info->channels_used; /* * dma_buf->tail != dma_buf->head condition will become false * because dma_buf->tail will be incremented with 1. */ while (dma_buf->tail != dma_buf->head) { idx = dma_buf->tail % info->channels_used; info->buffer[idx] = dma_samples[dma_buf->tail]; dma_buf->tail = (dma_buf->tail + 1) % NXP_SAR_ADC_DMA_SAMPLE_CNT; if (idx != info->channels_used - 1) continue; /* * iio_push_to_buffers_with_ts() should not be * called with dma_samples as parameter. The samples * will be smashed if timestamp is enabled. */ timestamp = iio_get_time_ns(indio_dev); ret = iio_push_to_buffers_with_ts(indio_dev, info->buffer, sizeof(info->buffer), timestamp); if (ret < 0 && ret != -EBUSY) dev_err_ratelimited(&indio_dev->dev, "failed to push iio buffer: %d", ret); } dma_buf->tail = dma_buf->head; } dma_sync_single_for_device(dev_dma, info->rx_dma_buf, NXP_SAR_ADC_DMA_BUFF_SZ, DMA_FROM_DEVICE); } static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); struct dma_slave_config config; struct dma_async_tx_descriptor *desc; int ret; info->dma_buf.head = 0; info->dma_buf.tail = 0; config.direction = DMA_DEV_TO_MEM; config.src_addr_width = NXP_SAR_ADC_DMA_SAMPLE_SZ; config.src_addr = NXP_SAR_ADC_CDR(info->regs_phys, info->buffered_chan[0]); config.src_port_window_size = info->channels_used; config.src_maxburst = info->channels_used; ret = dmaengine_slave_config(info->dma_chan, &config); if (ret < 0) return ret; desc = dmaengine_prep_dma_cyclic(info->dma_chan, info->rx_dma_buf, NXP_SAR_ADC_DMA_BUFF_SZ, NXP_SAR_ADC_DMA_BUFF_SZ / 2, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); if (!desc) return -EINVAL; desc->callback = nxp_sar_adc_dma_cb; desc->callback_param = indio_dev; info->cookie = dmaengine_submit(desc); ret = dma_submit_error(info->cookie); if (ret) { dmaengine_terminate_async(info->dma_chan); return ret; } dma_async_issue_pending(info->dma_chan); return 0; } static void nxp_sar_adc_buffer_software_do_predisable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); /* * The ADC DMAEN bit should be cleared before DMA transaction * is canceled. */ nxp_sar_adc_stop_conversion(info); dmaengine_terminate_sync(info->dma_chan); nxp_sar_adc_dma_cfg(info, false); nxp_sar_adc_dma_channels_disable(info, *indio_dev->active_scan_mask); dma_release_channel(info->dma_chan); } static int nxp_sar_adc_buffer_software_do_postenable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); int ret; info->dma_chan = dma_request_chan(indio_dev->dev.parent, "rx"); if (IS_ERR(info->dma_chan)) return PTR_ERR(info->dma_chan); nxp_sar_adc_dma_channels_enable(info, *indio_dev->active_scan_mask); nxp_sar_adc_dma_cfg(info, true); ret = nxp_sar_adc_start_cyclic_dma(indio_dev); if (ret) goto out_dma_channels_disable; ret = nxp_sar_adc_start_conversion(info, false); if (ret) goto out_stop_cyclic_dma; return 0; out_stop_cyclic_dma: dmaengine_terminate_sync(info->dma_chan); out_dma_channels_disable: nxp_sar_adc_dma_cfg(info, false); nxp_sar_adc_dma_channels_disable(info, *indio_dev->active_scan_mask); dma_release_channel(info->dma_chan); return ret; } static void nxp_sar_adc_buffer_trigger_do_predisable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); nxp_sar_adc_irq_cfg(info, false); } static int nxp_sar_adc_buffer_trigger_do_postenable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); nxp_sar_adc_irq_cfg(info, true); return 0; } static int nxp_sar_adc_buffer_postenable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); int current_mode = iio_device_get_current_mode(indio_dev); unsigned long channel; int ret; info->channels_used = 0; /* * The SAR-ADC has two groups of channels. * * - Group #0: * * bit 0-7 : channel 0 -> channel 7 * * bit 8-31 : reserved * * - Group #32: * * bit 0-7 : Internal * * bit 8-31 : reserved * * The 8 channels from group #0 are used in this driver for * ADC as described when declaring the IIO device and the * mapping is the same. That means the active_scan_mask can be * used directly to write the channel interrupt mask. */ nxp_sar_adc_channels_enable(info, *indio_dev->active_scan_mask); for_each_set_bit(channel, indio_dev->active_scan_mask, NXP_SAR_ADC_NR_CHANNELS) info->buffered_chan[info->channels_used++] = channel; nxp_sar_adc_enable(info); if (current_mode == INDIO_BUFFER_SOFTWARE) ret = nxp_sar_adc_buffer_software_do_postenable(indio_dev); else ret = nxp_sar_adc_buffer_trigger_do_postenable(indio_dev); if (ret) goto out_postenable; return 0; out_postenable: nxp_sar_adc_disable(info); nxp_sar_adc_channels_disable(info, *indio_dev->active_scan_mask); return ret; } static int nxp_sar_adc_buffer_predisable(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); int currentmode = iio_device_get_current_mode(indio_dev); if (currentmode == INDIO_BUFFER_SOFTWARE) nxp_sar_adc_buffer_software_do_predisable(indio_dev); else nxp_sar_adc_buffer_trigger_do_predisable(indio_dev); nxp_sar_adc_disable(info); nxp_sar_adc_channels_disable(info, *indio_dev->active_scan_mask); return 0; } static irqreturn_t nxp_sar_adc_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct nxp_sar_adc *info = iio_priv(indio_dev); int ret; ret = nxp_sar_adc_start_conversion(info, true); if (ret < 0) dev_dbg(&indio_dev->dev, "Failed to start conversion\n"); return IRQ_HANDLED; } static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { .postenable = nxp_sar_adc_buffer_postenable, .predisable = nxp_sar_adc_buffer_predisable, }; static const struct iio_info nxp_sar_adc_iio_info = { .read_raw = nxp_sar_adc_read_raw, .write_raw = nxp_sar_adc_write_raw, }; static int nxp_sar_adc_dma_probe(struct device *dev, struct nxp_sar_adc *info) { u8 *rx_buf; rx_buf = dmam_alloc_coherent(dev, NXP_SAR_ADC_DMA_BUFF_SZ, &info->rx_dma_buf, GFP_KERNEL); if (!rx_buf) return -ENOMEM; info->dma_buf.buf = rx_buf; return 0; } /* * The documentation describes the reset values for the registers. * However some registers do not have these values after a reset. It * is not a desirable situation. In some other SoC family * documentation NXP recommends not assuming the default values are * set and to initialize the registers conforming to the documentation * reset information to prevent this situation. Assume the same rule * applies here as there is a discrepancy between what is read from * the registers at reset time and the documentation. */ static void nxp_sar_adc_set_default_values(struct nxp_sar_adc *info) { writel(0x00003901, NXP_SAR_ADC_MCR(info->regs)); writel(0x00000001, NXP_SAR_ADC_MSR(info->regs)); writel(0x00000014, NXP_SAR_ADC_CTR0(info->regs)); writel(0x00000014, NXP_SAR_ADC_CTR1(info->regs)); writel(0x00000000, NXP_SAR_ADC_CIMR0(info->regs)); writel(0x00000000, NXP_SAR_ADC_CIMR1(info->regs)); writel(0x00000000, NXP_SAR_ADC_NCMR0(info->regs)); writel(0x00000000, NXP_SAR_ADC_NCMR1(info->regs)); } static int nxp_sar_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct nxp_sar_adc_data *data = device_get_match_data(dev); struct nxp_sar_adc *info; struct iio_dev *indio_dev; struct resource *mem; int irq, ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); if (!indio_dev) return -ENOMEM; info = iio_priv(indio_dev); info->vref_mV = data->vref_mV; spin_lock_init(&info->lock); info->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); if (IS_ERR(info->regs)) return dev_err_probe(dev, PTR_ERR(info->regs), "Failed to get and remap resource"); info->regs_phys = mem->start; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; ret = devm_request_irq(dev, irq, nxp_sar_adc_isr, 0, dev_name(dev), indio_dev); if (ret < 0) return ret; info->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(info->clk)) return dev_err_probe(dev, PTR_ERR(info->clk), "Failed to get the clock\n"); platform_set_drvdata(pdev, indio_dev); init_completion(&info->completion); indio_dev->name = data->model; indio_dev->info = &nxp_sar_adc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; indio_dev->channels = nxp_sar_adc_iio_channels; indio_dev->num_channels = ARRAY_SIZE(nxp_sar_adc_iio_channels); nxp_sar_adc_set_default_values(info); ret = nxp_sar_adc_calibration(info); if (ret) dev_err_probe(dev, ret, "Calibration failed\n"); ret = nxp_sar_adc_dma_probe(dev, info); if (ret) return dev_err_probe(dev, ret, "Failed to initialize the DMA\n"); ret = devm_iio_triggered_buffer_setup(dev, indio_dev, &iio_pollfunc_store_time, &nxp_sar_adc_trigger_handler, &iio_triggered_buffer_setup_ops); if (ret < 0) return dev_err_probe(dev, ret, "Couldn't initialise the buffer\n"); ret = devm_iio_device_register(dev, indio_dev); if (ret) return dev_err_probe(dev, ret, "Couldn't register the device\n"); return 0; } static int nxp_sar_adc_suspend(struct device *dev) { struct nxp_sar_adc *info = iio_priv(dev_get_drvdata(dev)); info->pwdn = nxp_sar_adc_disable(info); info->inpsamp = nxp_sar_adc_conversion_timing_get(info); clk_disable_unprepare(info->clk); return 0; } static int nxp_sar_adc_resume(struct device *dev) { struct nxp_sar_adc *info = iio_priv(dev_get_drvdata(dev)); int ret; ret = clk_prepare_enable(info->clk); if (ret) return ret; nxp_sar_adc_conversion_timing_set(info, info->inpsamp); if (!info->pwdn) nxp_sar_adc_enable(info); return 0; } static DEFINE_SIMPLE_DEV_PM_OPS(nxp_sar_adc_pm_ops, nxp_sar_adc_suspend, nxp_sar_adc_resume); static const struct nxp_sar_adc_data s32g2_sar_adc_data = { .vref_mV = 1800, .model = "s32g2-sar-adc", }; static const struct of_device_id nxp_sar_adc_match[] = { { .compatible = "nxp,s32g2-sar-adc", .data = &s32g2_sar_adc_data }, { } }; MODULE_DEVICE_TABLE(of, nxp_sar_adc_match); static struct platform_driver nxp_sar_adc_driver = { .probe = nxp_sar_adc_probe, .driver = { .name = "nxp-sar-adc", .of_match_table = nxp_sar_adc_match, .pm = pm_sleep_ptr(&nxp_sar_adc_pm_ops), }, }; module_platform_driver(nxp_sar_adc_driver); MODULE_AUTHOR("NXP"); MODULE_DESCRIPTION("NXP SAR-ADC driver"); MODULE_LICENSE("GPL");