11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2ace4cdfeSZhiyong Tao /*
3ace4cdfeSZhiyong Tao * Copyright (c) 2016 MediaTek Inc.
4ace4cdfeSZhiyong Tao * Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
5ace4cdfeSZhiyong Tao */
6ace4cdfeSZhiyong Tao
7ace4cdfeSZhiyong Tao #include <linux/clk.h>
8ace4cdfeSZhiyong Tao #include <linux/delay.h>
9ace4cdfeSZhiyong Tao #include <linux/err.h>
10ace4cdfeSZhiyong Tao #include <linux/kernel.h>
11ace4cdfeSZhiyong Tao #include <linux/module.h>
1215207a92SFabien Parent #include <linux/mod_devicetable.h>
13ace4cdfeSZhiyong Tao #include <linux/platform_device.h>
1415207a92SFabien Parent #include <linux/property.h>
15ace4cdfeSZhiyong Tao #include <linux/iopoll.h>
16ace4cdfeSZhiyong Tao #include <linux/io.h>
17ace4cdfeSZhiyong Tao #include <linux/iio/iio.h>
18ace4cdfeSZhiyong Tao
19ace4cdfeSZhiyong Tao /* Register definitions */
20ace4cdfeSZhiyong Tao #define MT6577_AUXADC_CON0 0x00
21ace4cdfeSZhiyong Tao #define MT6577_AUXADC_CON1 0x04
22ace4cdfeSZhiyong Tao #define MT6577_AUXADC_CON2 0x10
23ace4cdfeSZhiyong Tao #define MT6577_AUXADC_STA BIT(0)
24ace4cdfeSZhiyong Tao
25ace4cdfeSZhiyong Tao #define MT6577_AUXADC_DAT0 0x14
26ace4cdfeSZhiyong Tao #define MT6577_AUXADC_RDY0 BIT(12)
27ace4cdfeSZhiyong Tao
28ace4cdfeSZhiyong Tao #define MT6577_AUXADC_MISC 0x94
29ace4cdfeSZhiyong Tao #define MT6577_AUXADC_PDN_EN BIT(14)
30ace4cdfeSZhiyong Tao
31ace4cdfeSZhiyong Tao #define MT6577_AUXADC_DAT_MASK 0xfff
32ace4cdfeSZhiyong Tao #define MT6577_AUXADC_SLEEP_US 1000
33ace4cdfeSZhiyong Tao #define MT6577_AUXADC_TIMEOUT_US 10000
34ace4cdfeSZhiyong Tao #define MT6577_AUXADC_POWER_READY_MS 1
35ace4cdfeSZhiyong Tao #define MT6577_AUXADC_SAMPLE_READY_US 25
36ace4cdfeSZhiyong Tao
376d97024dSChun-Hung Wu struct mtk_auxadc_compatible {
386d97024dSChun-Hung Wu bool sample_data_cali;
396d97024dSChun-Hung Wu bool check_global_idle;
406d97024dSChun-Hung Wu };
416d97024dSChun-Hung Wu
42ace4cdfeSZhiyong Tao struct mt6577_auxadc_device {
43ace4cdfeSZhiyong Tao void __iomem *reg_base;
44ace4cdfeSZhiyong Tao struct clk *adc_clk;
45ace4cdfeSZhiyong Tao struct mutex lock;
466d97024dSChun-Hung Wu const struct mtk_auxadc_compatible *dev_comp;
476d97024dSChun-Hung Wu };
486d97024dSChun-Hung Wu
49ff04eb47SGuodong Liu static const struct mtk_auxadc_compatible mt8186_compat = {
50ff04eb47SGuodong Liu .sample_data_cali = false,
51ff04eb47SGuodong Liu .check_global_idle = false,
52ff04eb47SGuodong Liu };
53ff04eb47SGuodong Liu
546d97024dSChun-Hung Wu static const struct mtk_auxadc_compatible mt8173_compat = {
556d97024dSChun-Hung Wu .sample_data_cali = false,
566d97024dSChun-Hung Wu .check_global_idle = true,
576d97024dSChun-Hung Wu };
586d97024dSChun-Hung Wu
596d97024dSChun-Hung Wu static const struct mtk_auxadc_compatible mt6765_compat = {
606d97024dSChun-Hung Wu .sample_data_cali = true,
616d97024dSChun-Hung Wu .check_global_idle = false,
62ace4cdfeSZhiyong Tao };
63ace4cdfeSZhiyong Tao
64ace4cdfeSZhiyong Tao #define MT6577_AUXADC_CHANNEL(idx) { \
65ace4cdfeSZhiyong Tao .type = IIO_VOLTAGE, \
66ace4cdfeSZhiyong Tao .indexed = 1, \
67ace4cdfeSZhiyong Tao .channel = (idx), \
68ace4cdfeSZhiyong Tao .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
69ace4cdfeSZhiyong Tao }
70ace4cdfeSZhiyong Tao
71ace4cdfeSZhiyong Tao static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
72ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(0),
73ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(1),
74ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(2),
75ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(3),
76ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(4),
77ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(5),
78ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(6),
79ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(7),
80ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(8),
81ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(9),
82ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(10),
83ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(11),
84ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(12),
85ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(13),
86ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(14),
87ace4cdfeSZhiyong Tao MT6577_AUXADC_CHANNEL(15),
88ace4cdfeSZhiyong Tao };
89ace4cdfeSZhiyong Tao
90c2980c64SHui Liu /* For Voltage calculation */
91c2980c64SHui Liu #define VOLTAGE_FULL_RANGE 1500 /* VA voltage */
92c2980c64SHui Liu #define AUXADC_PRECISE 4096 /* 12 bits */
93c2980c64SHui Liu
mt_auxadc_get_cali_data(int rawdata,bool enable_cali)946d97024dSChun-Hung Wu static int mt_auxadc_get_cali_data(int rawdata, bool enable_cali)
956d97024dSChun-Hung Wu {
966d97024dSChun-Hung Wu return rawdata;
976d97024dSChun-Hung Wu }
986d97024dSChun-Hung Wu
mt6577_auxadc_mod_reg(void __iomem * reg,u32 or_mask,u32 and_mask)99ace4cdfeSZhiyong Tao static inline void mt6577_auxadc_mod_reg(void __iomem *reg,
100ace4cdfeSZhiyong Tao u32 or_mask, u32 and_mask)
101ace4cdfeSZhiyong Tao {
102ace4cdfeSZhiyong Tao u32 val;
103ace4cdfeSZhiyong Tao
104ace4cdfeSZhiyong Tao val = readl(reg);
105ace4cdfeSZhiyong Tao val |= or_mask;
106ace4cdfeSZhiyong Tao val &= ~and_mask;
107ace4cdfeSZhiyong Tao writel(val, reg);
108ace4cdfeSZhiyong Tao }
109ace4cdfeSZhiyong Tao
mt6577_auxadc_read(struct iio_dev * indio_dev,struct iio_chan_spec const * chan)110ace4cdfeSZhiyong Tao static int mt6577_auxadc_read(struct iio_dev *indio_dev,
111ace4cdfeSZhiyong Tao struct iio_chan_spec const *chan)
112ace4cdfeSZhiyong Tao {
113ace4cdfeSZhiyong Tao u32 val;
114ace4cdfeSZhiyong Tao void __iomem *reg_channel;
115ace4cdfeSZhiyong Tao int ret;
116ace4cdfeSZhiyong Tao struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
117ace4cdfeSZhiyong Tao
118ace4cdfeSZhiyong Tao reg_channel = adc_dev->reg_base + MT6577_AUXADC_DAT0 +
119ace4cdfeSZhiyong Tao chan->channel * 0x04;
120ace4cdfeSZhiyong Tao
121ace4cdfeSZhiyong Tao mutex_lock(&adc_dev->lock);
122ace4cdfeSZhiyong Tao
123ace4cdfeSZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
124ace4cdfeSZhiyong Tao 0, 1 << chan->channel);
125ace4cdfeSZhiyong Tao
126ace4cdfeSZhiyong Tao /* read channel and make sure old ready bit == 0 */
127ace4cdfeSZhiyong Tao ret = readl_poll_timeout(reg_channel, val,
128ace4cdfeSZhiyong Tao ((val & MT6577_AUXADC_RDY0) == 0),
129ace4cdfeSZhiyong Tao MT6577_AUXADC_SLEEP_US,
130ace4cdfeSZhiyong Tao MT6577_AUXADC_TIMEOUT_US);
131ace4cdfeSZhiyong Tao if (ret < 0) {
132ace4cdfeSZhiyong Tao dev_err(indio_dev->dev.parent,
133ace4cdfeSZhiyong Tao "wait for channel[%d] ready bit clear time out\n",
134ace4cdfeSZhiyong Tao chan->channel);
135ace4cdfeSZhiyong Tao goto err_timeout;
136ace4cdfeSZhiyong Tao }
137ace4cdfeSZhiyong Tao
138ace4cdfeSZhiyong Tao /* set bit to trigger sample */
139ace4cdfeSZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
140ace4cdfeSZhiyong Tao 1 << chan->channel, 0);
141ace4cdfeSZhiyong Tao
142ace4cdfeSZhiyong Tao /* we must delay here for hardware sample channel data */
143ace4cdfeSZhiyong Tao udelay(MT6577_AUXADC_SAMPLE_READY_US);
144ace4cdfeSZhiyong Tao
1456d97024dSChun-Hung Wu if (adc_dev->dev_comp->check_global_idle) {
146ace4cdfeSZhiyong Tao /* check MTK_AUXADC_CON2 if auxadc is idle */
1476d97024dSChun-Hung Wu ret = readl_poll_timeout(adc_dev->reg_base + MT6577_AUXADC_CON2,
1486d97024dSChun-Hung Wu val, ((val & MT6577_AUXADC_STA) == 0),
149ace4cdfeSZhiyong Tao MT6577_AUXADC_SLEEP_US,
150ace4cdfeSZhiyong Tao MT6577_AUXADC_TIMEOUT_US);
151ace4cdfeSZhiyong Tao if (ret < 0) {
152ace4cdfeSZhiyong Tao dev_err(indio_dev->dev.parent,
153ace4cdfeSZhiyong Tao "wait for auxadc idle time out\n");
154ace4cdfeSZhiyong Tao goto err_timeout;
155ace4cdfeSZhiyong Tao }
1566d97024dSChun-Hung Wu }
157ace4cdfeSZhiyong Tao
158ace4cdfeSZhiyong Tao /* read channel and make sure ready bit == 1 */
159ace4cdfeSZhiyong Tao ret = readl_poll_timeout(reg_channel, val,
160ace4cdfeSZhiyong Tao ((val & MT6577_AUXADC_RDY0) != 0),
161ace4cdfeSZhiyong Tao MT6577_AUXADC_SLEEP_US,
162ace4cdfeSZhiyong Tao MT6577_AUXADC_TIMEOUT_US);
163ace4cdfeSZhiyong Tao if (ret < 0) {
164ace4cdfeSZhiyong Tao dev_err(indio_dev->dev.parent,
165ace4cdfeSZhiyong Tao "wait for channel[%d] data ready time out\n",
166ace4cdfeSZhiyong Tao chan->channel);
167ace4cdfeSZhiyong Tao goto err_timeout;
168ace4cdfeSZhiyong Tao }
169ace4cdfeSZhiyong Tao
170ace4cdfeSZhiyong Tao /* read data */
171ace4cdfeSZhiyong Tao val = readl(reg_channel) & MT6577_AUXADC_DAT_MASK;
172ace4cdfeSZhiyong Tao
173ace4cdfeSZhiyong Tao mutex_unlock(&adc_dev->lock);
174ace4cdfeSZhiyong Tao
175ace4cdfeSZhiyong Tao return val;
176ace4cdfeSZhiyong Tao
177ace4cdfeSZhiyong Tao err_timeout:
178ace4cdfeSZhiyong Tao
179ace4cdfeSZhiyong Tao mutex_unlock(&adc_dev->lock);
180ace4cdfeSZhiyong Tao
181ace4cdfeSZhiyong Tao return -ETIMEDOUT;
182ace4cdfeSZhiyong Tao }
183ace4cdfeSZhiyong Tao
mt6577_auxadc_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)184ace4cdfeSZhiyong Tao static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
185ace4cdfeSZhiyong Tao struct iio_chan_spec const *chan,
186ace4cdfeSZhiyong Tao int *val,
187ace4cdfeSZhiyong Tao int *val2,
188ace4cdfeSZhiyong Tao long info)
189ace4cdfeSZhiyong Tao {
1906d97024dSChun-Hung Wu struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
1916d97024dSChun-Hung Wu
192ace4cdfeSZhiyong Tao switch (info) {
193ace4cdfeSZhiyong Tao case IIO_CHAN_INFO_PROCESSED:
194ace4cdfeSZhiyong Tao *val = mt6577_auxadc_read(indio_dev, chan);
195ace4cdfeSZhiyong Tao if (*val < 0) {
196ace4cdfeSZhiyong Tao dev_err(indio_dev->dev.parent,
197ace4cdfeSZhiyong Tao "failed to sample data on channel[%d]\n",
198ace4cdfeSZhiyong Tao chan->channel);
199ace4cdfeSZhiyong Tao return *val;
200ace4cdfeSZhiyong Tao }
2016d97024dSChun-Hung Wu if (adc_dev->dev_comp->sample_data_cali)
2026d97024dSChun-Hung Wu *val = mt_auxadc_get_cali_data(*val, true);
203c2980c64SHui Liu
204c2980c64SHui Liu /* Convert adc raw data to voltage: 0 - 1500 mV */
205c2980c64SHui Liu *val = *val * VOLTAGE_FULL_RANGE / AUXADC_PRECISE;
206c2980c64SHui Liu
207ace4cdfeSZhiyong Tao return IIO_VAL_INT;
208ace4cdfeSZhiyong Tao
209ace4cdfeSZhiyong Tao default:
210ace4cdfeSZhiyong Tao return -EINVAL;
211ace4cdfeSZhiyong Tao }
212ace4cdfeSZhiyong Tao }
213ace4cdfeSZhiyong Tao
214ace4cdfeSZhiyong Tao static const struct iio_info mt6577_auxadc_info = {
215ace4cdfeSZhiyong Tao .read_raw = &mt6577_auxadc_read_raw,
216ace4cdfeSZhiyong Tao };
217ace4cdfeSZhiyong Tao
mt6577_auxadc_resume(struct device * dev)218*7ff1d28cSJonathan Cameron static int mt6577_auxadc_resume(struct device *dev)
2195236bbc6SZhiyong Tao {
2205236bbc6SZhiyong Tao struct iio_dev *indio_dev = dev_get_drvdata(dev);
2215236bbc6SZhiyong Tao struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
2225236bbc6SZhiyong Tao int ret;
2235236bbc6SZhiyong Tao
2245236bbc6SZhiyong Tao ret = clk_prepare_enable(adc_dev->adc_clk);
2255236bbc6SZhiyong Tao if (ret) {
2265236bbc6SZhiyong Tao pr_err("failed to enable auxadc clock\n");
2275236bbc6SZhiyong Tao return ret;
2285236bbc6SZhiyong Tao }
2295236bbc6SZhiyong Tao
2305236bbc6SZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
2315236bbc6SZhiyong Tao MT6577_AUXADC_PDN_EN, 0);
2325236bbc6SZhiyong Tao mdelay(MT6577_AUXADC_POWER_READY_MS);
2335236bbc6SZhiyong Tao
2345236bbc6SZhiyong Tao return 0;
2355236bbc6SZhiyong Tao }
2365236bbc6SZhiyong Tao
mt6577_auxadc_suspend(struct device * dev)237*7ff1d28cSJonathan Cameron static int mt6577_auxadc_suspend(struct device *dev)
2385236bbc6SZhiyong Tao {
2395236bbc6SZhiyong Tao struct iio_dev *indio_dev = dev_get_drvdata(dev);
2405236bbc6SZhiyong Tao struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
2415236bbc6SZhiyong Tao
2425236bbc6SZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
2435236bbc6SZhiyong Tao 0, MT6577_AUXADC_PDN_EN);
2445236bbc6SZhiyong Tao clk_disable_unprepare(adc_dev->adc_clk);
2455236bbc6SZhiyong Tao
2465236bbc6SZhiyong Tao return 0;
2475236bbc6SZhiyong Tao }
2485236bbc6SZhiyong Tao
mt6577_auxadc_probe(struct platform_device * pdev)249ace4cdfeSZhiyong Tao static int mt6577_auxadc_probe(struct platform_device *pdev)
250ace4cdfeSZhiyong Tao {
251ace4cdfeSZhiyong Tao struct mt6577_auxadc_device *adc_dev;
252ace4cdfeSZhiyong Tao unsigned long adc_clk_rate;
253ace4cdfeSZhiyong Tao struct iio_dev *indio_dev;
254ace4cdfeSZhiyong Tao int ret;
255ace4cdfeSZhiyong Tao
256ace4cdfeSZhiyong Tao indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
257ace4cdfeSZhiyong Tao if (!indio_dev)
258ace4cdfeSZhiyong Tao return -ENOMEM;
259ace4cdfeSZhiyong Tao
260ace4cdfeSZhiyong Tao adc_dev = iio_priv(indio_dev);
261ace4cdfeSZhiyong Tao indio_dev->name = dev_name(&pdev->dev);
262ace4cdfeSZhiyong Tao indio_dev->info = &mt6577_auxadc_info;
263ace4cdfeSZhiyong Tao indio_dev->modes = INDIO_DIRECT_MODE;
264ace4cdfeSZhiyong Tao indio_dev->channels = mt6577_auxadc_iio_channels;
265ace4cdfeSZhiyong Tao indio_dev->num_channels = ARRAY_SIZE(mt6577_auxadc_iio_channels);
266ace4cdfeSZhiyong Tao
26738877a37SJonathan Cameron adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0);
268ace4cdfeSZhiyong Tao if (IS_ERR(adc_dev->reg_base)) {
269ace4cdfeSZhiyong Tao dev_err(&pdev->dev, "failed to get auxadc base address\n");
270ace4cdfeSZhiyong Tao return PTR_ERR(adc_dev->reg_base);
271ace4cdfeSZhiyong Tao }
272ace4cdfeSZhiyong Tao
273ace4cdfeSZhiyong Tao adc_dev->adc_clk = devm_clk_get(&pdev->dev, "main");
274ace4cdfeSZhiyong Tao if (IS_ERR(adc_dev->adc_clk)) {
275ace4cdfeSZhiyong Tao dev_err(&pdev->dev, "failed to get auxadc clock\n");
276ace4cdfeSZhiyong Tao return PTR_ERR(adc_dev->adc_clk);
277ace4cdfeSZhiyong Tao }
278ace4cdfeSZhiyong Tao
279ace4cdfeSZhiyong Tao ret = clk_prepare_enable(adc_dev->adc_clk);
280ace4cdfeSZhiyong Tao if (ret) {
281ace4cdfeSZhiyong Tao dev_err(&pdev->dev, "failed to enable auxadc clock\n");
282ace4cdfeSZhiyong Tao return ret;
283ace4cdfeSZhiyong Tao }
284ace4cdfeSZhiyong Tao
285ace4cdfeSZhiyong Tao adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
286ace4cdfeSZhiyong Tao if (!adc_clk_rate) {
287ace4cdfeSZhiyong Tao ret = -EINVAL;
288ace4cdfeSZhiyong Tao dev_err(&pdev->dev, "null clock rate\n");
289ace4cdfeSZhiyong Tao goto err_disable_clk;
290ace4cdfeSZhiyong Tao }
291ace4cdfeSZhiyong Tao
29215207a92SFabien Parent adc_dev->dev_comp = device_get_match_data(&pdev->dev);
29315207a92SFabien Parent
294ace4cdfeSZhiyong Tao mutex_init(&adc_dev->lock);
295ace4cdfeSZhiyong Tao
296ace4cdfeSZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
297ace4cdfeSZhiyong Tao MT6577_AUXADC_PDN_EN, 0);
298ace4cdfeSZhiyong Tao mdelay(MT6577_AUXADC_POWER_READY_MS);
299ace4cdfeSZhiyong Tao
300ace4cdfeSZhiyong Tao platform_set_drvdata(pdev, indio_dev);
301ace4cdfeSZhiyong Tao
302ace4cdfeSZhiyong Tao ret = iio_device_register(indio_dev);
303ace4cdfeSZhiyong Tao if (ret < 0) {
304ace4cdfeSZhiyong Tao dev_err(&pdev->dev, "failed to register iio device\n");
305ace4cdfeSZhiyong Tao goto err_power_off;
306ace4cdfeSZhiyong Tao }
307ace4cdfeSZhiyong Tao
308ace4cdfeSZhiyong Tao return 0;
309ace4cdfeSZhiyong Tao
310ace4cdfeSZhiyong Tao err_power_off:
311ace4cdfeSZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
312ace4cdfeSZhiyong Tao 0, MT6577_AUXADC_PDN_EN);
313ace4cdfeSZhiyong Tao err_disable_clk:
314ace4cdfeSZhiyong Tao clk_disable_unprepare(adc_dev->adc_clk);
315ace4cdfeSZhiyong Tao return ret;
316ace4cdfeSZhiyong Tao }
317ace4cdfeSZhiyong Tao
mt6577_auxadc_remove(struct platform_device * pdev)318ace4cdfeSZhiyong Tao static int mt6577_auxadc_remove(struct platform_device *pdev)
319ace4cdfeSZhiyong Tao {
320ace4cdfeSZhiyong Tao struct iio_dev *indio_dev = platform_get_drvdata(pdev);
321ace4cdfeSZhiyong Tao struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
322ace4cdfeSZhiyong Tao
323ace4cdfeSZhiyong Tao iio_device_unregister(indio_dev);
324ace4cdfeSZhiyong Tao
325ace4cdfeSZhiyong Tao mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
326ace4cdfeSZhiyong Tao 0, MT6577_AUXADC_PDN_EN);
327ace4cdfeSZhiyong Tao
328ace4cdfeSZhiyong Tao clk_disable_unprepare(adc_dev->adc_clk);
329ace4cdfeSZhiyong Tao
330ace4cdfeSZhiyong Tao return 0;
331ace4cdfeSZhiyong Tao }
332ace4cdfeSZhiyong Tao
333*7ff1d28cSJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(mt6577_auxadc_pm_ops,
3345236bbc6SZhiyong Tao mt6577_auxadc_suspend,
3355236bbc6SZhiyong Tao mt6577_auxadc_resume);
3365236bbc6SZhiyong Tao
337ace4cdfeSZhiyong Tao static const struct of_device_id mt6577_auxadc_of_match[] = {
3386d97024dSChun-Hung Wu { .compatible = "mediatek,mt2701-auxadc", .data = &mt8173_compat },
3396d97024dSChun-Hung Wu { .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat },
3406d97024dSChun-Hung Wu { .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat },
3416d97024dSChun-Hung Wu { .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat },
342ff04eb47SGuodong Liu { .compatible = "mediatek,mt8186-auxadc", .data = &mt8186_compat },
3436d97024dSChun-Hung Wu { .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat },
344ace4cdfeSZhiyong Tao { }
345ace4cdfeSZhiyong Tao };
346ace4cdfeSZhiyong Tao MODULE_DEVICE_TABLE(of, mt6577_auxadc_of_match);
347ace4cdfeSZhiyong Tao
348ace4cdfeSZhiyong Tao static struct platform_driver mt6577_auxadc_driver = {
349ace4cdfeSZhiyong Tao .driver = {
350ace4cdfeSZhiyong Tao .name = "mt6577-auxadc",
351ace4cdfeSZhiyong Tao .of_match_table = mt6577_auxadc_of_match,
352*7ff1d28cSJonathan Cameron .pm = pm_sleep_ptr(&mt6577_auxadc_pm_ops),
353ace4cdfeSZhiyong Tao },
354ace4cdfeSZhiyong Tao .probe = mt6577_auxadc_probe,
355ace4cdfeSZhiyong Tao .remove = mt6577_auxadc_remove,
356ace4cdfeSZhiyong Tao };
357ace4cdfeSZhiyong Tao module_platform_driver(mt6577_auxadc_driver);
358ace4cdfeSZhiyong Tao
359ace4cdfeSZhiyong Tao MODULE_AUTHOR("Zhiyong Tao <zhiyong.tao@mediatek.com>");
360ace4cdfeSZhiyong Tao MODULE_DESCRIPTION("MTK AUXADC Device Driver");
361ace4cdfeSZhiyong Tao MODULE_LICENSE("GPL v2");
362