forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/iio/adc/mt6577_auxadc.c
....@@ -1,15 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2016 MediaTek Inc.
34 * Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
135 */
146
157 #include <linux/clk.h>
....@@ -17,9 +9,9 @@
179 #include <linux/err.h>
1810 #include <linux/kernel.h>
1911 #include <linux/module.h>
20
-#include <linux/of.h>
21
-#include <linux/of_device.h>
12
+#include <linux/mod_devicetable.h>
2213 #include <linux/platform_device.h>
14
+#include <linux/property.h>
2315 #include <linux/iopoll.h>
2416 #include <linux/io.h>
2517 #include <linux/iio/iio.h>
....@@ -42,10 +34,26 @@
4234 #define MT6577_AUXADC_POWER_READY_MS 1
4335 #define MT6577_AUXADC_SAMPLE_READY_US 25
4436
37
+struct mtk_auxadc_compatible {
38
+ bool sample_data_cali;
39
+ bool check_global_idle;
40
+};
41
+
4542 struct mt6577_auxadc_device {
4643 void __iomem *reg_base;
4744 struct clk *adc_clk;
4845 struct mutex lock;
46
+ const struct mtk_auxadc_compatible *dev_comp;
47
+};
48
+
49
+static const struct mtk_auxadc_compatible mt8173_compat = {
50
+ .sample_data_cali = false,
51
+ .check_global_idle = true,
52
+};
53
+
54
+static const struct mtk_auxadc_compatible mt6765_compat = {
55
+ .sample_data_cali = true,
56
+ .check_global_idle = false,
4957 };
5058
5159 #define MT6577_AUXADC_CHANNEL(idx) { \
....@@ -73,6 +81,15 @@
7381 MT6577_AUXADC_CHANNEL(14),
7482 MT6577_AUXADC_CHANNEL(15),
7583 };
84
+
85
+/* For Voltage calculation */
86
+#define VOLTAGE_FULL_RANGE 1500 /* VA voltage */
87
+#define AUXADC_PRECISE 4096 /* 12 bits */
88
+
89
+static int mt_auxadc_get_cali_data(int rawdata, bool enable_cali)
90
+{
91
+ return rawdata;
92
+}
7693
7794 static inline void mt6577_auxadc_mod_reg(void __iomem *reg,
7895 u32 or_mask, u32 and_mask)
....@@ -120,15 +137,17 @@
120137 /* we must delay here for hardware sample channel data */
121138 udelay(MT6577_AUXADC_SAMPLE_READY_US);
122139
123
- /* check MTK_AUXADC_CON2 if auxadc is idle */
124
- ret = readl_poll_timeout(adc_dev->reg_base + MT6577_AUXADC_CON2, val,
125
- ((val & MT6577_AUXADC_STA) == 0),
126
- MT6577_AUXADC_SLEEP_US,
127
- MT6577_AUXADC_TIMEOUT_US);
128
- if (ret < 0) {
129
- dev_err(indio_dev->dev.parent,
130
- "wait for auxadc idle time out\n");
131
- goto err_timeout;
140
+ if (adc_dev->dev_comp->check_global_idle) {
141
+ /* check MTK_AUXADC_CON2 if auxadc is idle */
142
+ ret = readl_poll_timeout(adc_dev->reg_base + MT6577_AUXADC_CON2,
143
+ val, ((val & MT6577_AUXADC_STA) == 0),
144
+ MT6577_AUXADC_SLEEP_US,
145
+ MT6577_AUXADC_TIMEOUT_US);
146
+ if (ret < 0) {
147
+ dev_err(indio_dev->dev.parent,
148
+ "wait for auxadc idle time out\n");
149
+ goto err_timeout;
150
+ }
132151 }
133152
134153 /* read channel and make sure ready bit == 1 */
....@@ -163,6 +182,8 @@
163182 int *val2,
164183 long info)
165184 {
185
+ struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
186
+
166187 switch (info) {
167188 case IIO_CHAN_INFO_PROCESSED:
168189 *val = mt6577_auxadc_read(indio_dev, chan);
....@@ -172,6 +193,12 @@
172193 chan->channel);
173194 return *val;
174195 }
196
+ if (adc_dev->dev_comp->sample_data_cali)
197
+ *val = mt_auxadc_get_cali_data(*val, true);
198
+
199
+ /* Convert adc raw data to voltage: 0 - 1500 mV */
200
+ *val = *val * VOLTAGE_FULL_RANGE / AUXADC_PRECISE;
201
+
175202 return IIO_VAL_INT;
176203
177204 default:
....@@ -218,7 +245,6 @@
218245 {
219246 struct mt6577_auxadc_device *adc_dev;
220247 unsigned long adc_clk_rate;
221
- struct resource *res;
222248 struct iio_dev *indio_dev;
223249 int ret;
224250
....@@ -227,15 +253,13 @@
227253 return -ENOMEM;
228254
229255 adc_dev = iio_priv(indio_dev);
230
- indio_dev->dev.parent = &pdev->dev;
231256 indio_dev->name = dev_name(&pdev->dev);
232257 indio_dev->info = &mt6577_auxadc_info;
233258 indio_dev->modes = INDIO_DIRECT_MODE;
234259 indio_dev->channels = mt6577_auxadc_iio_channels;
235260 indio_dev->num_channels = ARRAY_SIZE(mt6577_auxadc_iio_channels);
236261
237
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
238
- adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
262
+ adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0);
239263 if (IS_ERR(adc_dev->reg_base)) {
240264 dev_err(&pdev->dev, "failed to get auxadc base address\n");
241265 return PTR_ERR(adc_dev->reg_base);
....@@ -259,6 +283,8 @@
259283 dev_err(&pdev->dev, "null clock rate\n");
260284 goto err_disable_clk;
261285 }
286
+
287
+ adc_dev->dev_comp = device_get_match_data(&pdev->dev);
262288
263289 mutex_init(&adc_dev->lock);
264290
....@@ -304,10 +330,11 @@
304330 mt6577_auxadc_resume);
305331
306332 static const struct of_device_id mt6577_auxadc_of_match[] = {
307
- { .compatible = "mediatek,mt2701-auxadc", },
308
- { .compatible = "mediatek,mt2712-auxadc", },
309
- { .compatible = "mediatek,mt7622-auxadc", },
310
- { .compatible = "mediatek,mt8173-auxadc", },
333
+ { .compatible = "mediatek,mt2701-auxadc", .data = &mt8173_compat},
334
+ { .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat},
335
+ { .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat},
336
+ { .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat},
337
+ { .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat},
311338 { }
312339 };
313340 MODULE_DEVICE_TABLE(of, mt6577_auxadc_of_match);