^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) * Copyright (c) 2016 MediaTek Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Register definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MT6577_AUXADC_CON0 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MT6577_AUXADC_CON1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MT6577_AUXADC_CON2 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MT6577_AUXADC_STA BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MT6577_AUXADC_DAT0 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define MT6577_AUXADC_RDY0 BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MT6577_AUXADC_MISC 0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MT6577_AUXADC_PDN_EN BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MT6577_AUXADC_DAT_MASK 0xfff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MT6577_AUXADC_SLEEP_US 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MT6577_AUXADC_TIMEOUT_US 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MT6577_AUXADC_POWER_READY_MS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MT6577_AUXADC_SAMPLE_READY_US 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct mtk_auxadc_compatible {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) bool sample_data_cali;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) bool check_global_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct mt6577_auxadc_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct clk *adc_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const struct mtk_auxadc_compatible *dev_comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const struct mtk_auxadc_compatible mt8173_compat = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .sample_data_cali = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .check_global_idle = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const struct mtk_auxadc_compatible mt6765_compat = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .sample_data_cali = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .check_global_idle = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MT6577_AUXADC_CHANNEL(idx) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .type = IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .channel = (idx), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) MT6577_AUXADC_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MT6577_AUXADC_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MT6577_AUXADC_CHANNEL(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MT6577_AUXADC_CHANNEL(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) MT6577_AUXADC_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MT6577_AUXADC_CHANNEL(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MT6577_AUXADC_CHANNEL(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MT6577_AUXADC_CHANNEL(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MT6577_AUXADC_CHANNEL(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MT6577_AUXADC_CHANNEL(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MT6577_AUXADC_CHANNEL(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MT6577_AUXADC_CHANNEL(11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MT6577_AUXADC_CHANNEL(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MT6577_AUXADC_CHANNEL(13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MT6577_AUXADC_CHANNEL(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) MT6577_AUXADC_CHANNEL(15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* For Voltage calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define VOLTAGE_FULL_RANGE 1500 /* VA voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define AUXADC_PRECISE 4096 /* 12 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int mt_auxadc_get_cali_data(int rawdata, bool enable_cali)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return rawdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline void mt6577_auxadc_mod_reg(void __iomem *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 or_mask, u32 and_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) val = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) val |= or_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) val &= ~and_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) writel(val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int mt6577_auxadc_read(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct iio_chan_spec const *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void __iomem *reg_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) reg_channel = adc_dev->reg_base + MT6577_AUXADC_DAT0 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) chan->channel * 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mutex_lock(&adc_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 0, 1 << chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* read channel and make sure old ready bit == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret = readl_poll_timeout(reg_channel, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ((val & MT6577_AUXADC_RDY0) == 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) MT6577_AUXADC_SLEEP_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) MT6577_AUXADC_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev_err(indio_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) "wait for channel[%d] ready bit clear time out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) goto err_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* set bit to trigger sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 1 << chan->channel, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* we must delay here for hardware sample channel data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) udelay(MT6577_AUXADC_SAMPLE_READY_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (adc_dev->dev_comp->check_global_idle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* check MTK_AUXADC_CON2 if auxadc is idle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ret = readl_poll_timeout(adc_dev->reg_base + MT6577_AUXADC_CON2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) val, ((val & MT6577_AUXADC_STA) == 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) MT6577_AUXADC_SLEEP_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) MT6577_AUXADC_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_err(indio_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "wait for auxadc idle time out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto err_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^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) /* read channel and make sure ready bit == 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ret = readl_poll_timeout(reg_channel, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ((val & MT6577_AUXADC_RDY0) != 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) MT6577_AUXADC_SLEEP_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) MT6577_AUXADC_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err(indio_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) "wait for channel[%d] data ready time out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) goto err_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* read data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) val = readl(reg_channel) & MT6577_AUXADC_DAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mutex_unlock(&adc_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) err_timeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mutex_unlock(&adc_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *val = mt6577_auxadc_read(indio_dev, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (*val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_err(indio_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "failed to sample data on channel[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (adc_dev->dev_comp->sample_data_cali)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *val = mt_auxadc_get_cali_data(*val, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Convert adc raw data to voltage: 0 - 1500 mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *val = *val * VOLTAGE_FULL_RANGE / AUXADC_PRECISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^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) static const struct iio_info mt6577_auxadc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .read_raw = &mt6577_auxadc_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int __maybe_unused mt6577_auxadc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = clk_prepare_enable(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) pr_err("failed to enable auxadc clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) MT6577_AUXADC_PDN_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mdelay(MT6577_AUXADC_POWER_READY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int __maybe_unused mt6577_auxadc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 0, MT6577_AUXADC_PDN_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) clk_disable_unprepare(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int mt6577_auxadc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct mt6577_auxadc_device *adc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long adc_clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) indio_dev->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) indio_dev->info = &mt6577_auxadc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) indio_dev->channels = mt6577_auxadc_iio_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) indio_dev->num_channels = ARRAY_SIZE(mt6577_auxadc_iio_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (IS_ERR(adc_dev->reg_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(&pdev->dev, "failed to get auxadc base address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return PTR_ERR(adc_dev->reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) adc_dev->adc_clk = devm_clk_get(&pdev->dev, "main");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (IS_ERR(adc_dev->adc_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_err(&pdev->dev, "failed to get auxadc clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return PTR_ERR(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = clk_prepare_enable(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_err(&pdev->dev, "failed to enable auxadc clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!adc_clk_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dev_err(&pdev->dev, "null clock rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto err_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) adc_dev->dev_comp = device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mutex_init(&adc_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) MT6577_AUXADC_PDN_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mdelay(MT6577_AUXADC_POWER_READY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) platform_set_drvdata(pdev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dev_err(&pdev->dev, "failed to register iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) goto err_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) err_power_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 0, MT6577_AUXADC_PDN_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) err_disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) clk_disable_unprepare(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int mt6577_auxadc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct iio_dev *indio_dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 0, MT6577_AUXADC_PDN_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) clk_disable_unprepare(adc_dev->adc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static SIMPLE_DEV_PM_OPS(mt6577_auxadc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mt6577_auxadc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mt6577_auxadc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static const struct of_device_id mt6577_auxadc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { .compatible = "mediatek,mt2701-auxadc", .data = &mt8173_compat},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) { .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) { .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) { .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) MODULE_DEVICE_TABLE(of, mt6577_auxadc_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static struct platform_driver mt6577_auxadc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .name = "mt6577-auxadc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .of_match_table = mt6577_auxadc_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .pm = &mt6577_auxadc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .probe = mt6577_auxadc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .remove = mt6577_auxadc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) module_platform_driver(mt6577_auxadc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) MODULE_AUTHOR("Zhiyong Tao <zhiyong.tao@mediatek.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) MODULE_DESCRIPTION("MTK AUXADC Device Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) MODULE_LICENSE("GPL v2");