^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Alexander Sverdlin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The driver uses polling to get the conversion status. According to EP93xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * datasheets, reading ADCResult register starts the conversion, but user is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * responsible for ensuring that delay between adjacent conversion triggers is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * long enough so that maximum allowed conversion rate is not exceeded. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * basically renders IRQ mode unusable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * This code could benefit from real HR Timers, but jiffy granularity would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * in such case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * HR Timers-based version loads CPU only up to 10% during back to back ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * conversion, while busy wait-based version consumes whole CPU power.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #ifdef CONFIG_HIGH_RES_TIMERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ep93xx_adc_delay(usmin, usmax) udelay(usmin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define EP93XX_ADC_RESULT 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define EP93XX_ADC_SDR BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define EP93XX_ADC_SWITCH 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define EP93XX_ADC_SW_LOCK 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct ep93xx_adc_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int lastch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define EP93XX_ADC_CH(index, dname, swcfg) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .type = IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .channel = index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .address = swcfg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .datasheet_name = dname, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) BIT(IIO_CHAN_INFO_OFFSET), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * not defined. So the last three are numbered randomly, let's say.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static const struct iio_chan_spec ep93xx_adc_channels[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) EP93XX_ADC_CH(0, "YM", 0x608),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) EP93XX_ADC_CH(1, "SXP", 0x680),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) EP93XX_ADC_CH(2, "SXM", 0x640),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EP93XX_ADC_CH(3, "SYP", 0x620),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) EP93XX_ADC_CH(4, "SYM", 0x610),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) EP93XX_ADC_CH(5, "XP", 0x601),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) EP93XX_ADC_CH(6, "XM", 0x602),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) EP93XX_ADC_CH(7, "YP", 0x604),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int ep93xx_read_raw(struct iio_dev *iiodev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct iio_chan_spec const *channel, int *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int *shift, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct ep93xx_adc_priv *priv = iio_priv(iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mutex_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (priv->lastch != channel->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) priv->lastch = channel->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Switch register is software-locked, unlocking must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * immediately followed by write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) writel_relaxed(channel->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) priv->base + EP93XX_ADC_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Settling delay depends on module clock and could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * 2ms or 500us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ep93xx_adc_delay(2000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Start the conversion, eventually discarding old result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) readl_relaxed(priv->base + EP93XX_ADC_RESULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Ensure maximum conversion rate is not exceeded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) DIV_ROUND_UP(1000000, 925));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* At this point conversion must be completed, but anyway... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) timeout = jiffies + msecs_to_jiffies(1) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) t = readl_relaxed(priv->base + EP93XX_ADC_RESULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (t & EP93XX_ADC_SDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *value = sign_extend32(t, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_err(&iiodev->dev, "Conversion timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mutex_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* According to datasheet, range is -25000..25000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *value = 25000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Typical supply voltage is 3.3v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *value = (1ULL << 32) * 3300 / 50000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *shift = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return IIO_VAL_FRACTIONAL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static const struct iio_info ep93xx_adc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .read_raw = ep93xx_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int ep93xx_adc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct iio_dev *iiodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct ep93xx_adc_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct clk *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) iiodev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (!iiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) priv = iio_priv(iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) priv->base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (IS_ERR(priv->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(&pdev->dev, "Cannot map memory resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return PTR_ERR(priv->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) iiodev->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) iiodev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) iiodev->info = &ep93xx_adc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) iiodev->channels = ep93xx_adc_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) priv->lastch = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mutex_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) platform_set_drvdata(pdev, iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) priv->clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (IS_ERR(priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev_err(&pdev->dev, "Cannot obtain clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return PTR_ERR(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pclk = clk_get_parent(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!pclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev_warn(&pdev->dev, "Cannot obtain parent clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * This is actually a place for improvement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * EP93xx ADC supports two clock divisors -- 4 and 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * resulting in conversion rates 3750 and 925 samples per second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * with 500us or 2ms settling time respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * One might find this interesting enough to be configurable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev_warn(&pdev->dev, "Cannot set clock rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * We can tolerate rate setting failure because the module should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * work in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = clk_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dev_err(&pdev->dev, "Cannot enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = iio_device_register(iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) clk_disable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int ep93xx_adc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct iio_dev *iiodev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct ep93xx_adc_priv *priv = iio_priv(iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) iio_device_unregister(iiodev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) clk_disable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static struct platform_driver ep93xx_adc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .name = "ep93xx-adc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .probe = ep93xx_adc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .remove = ep93xx_adc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) module_platform_driver(ep93xx_adc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) MODULE_ALIAS("platform:ep93xx-adc");