hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/mfd/mt6397-core.c
....@@ -1,46 +1,48 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2014 MediaTek Inc.
34 * Author: Flora Fu, MediaTek
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/interrupt.h>
8
+#include <linux/ioport.h>
169 #include <linux/module.h>
1710 #include <linux/of_device.h>
1811 #include <linux/of_irq.h>
1912 #include <linux/regmap.h>
2013 #include <linux/mfd/core.h>
21
-#include <linux/mfd/mt6397/core.h>
2214 #include <linux/mfd/mt6323/core.h>
23
-#include <linux/mfd/mt6397/registers.h>
15
+#include <linux/mfd/mt6358/core.h>
16
+#include <linux/mfd/mt6397/core.h>
2417 #include <linux/mfd/mt6323/registers.h>
18
+#include <linux/mfd/mt6358/registers.h>
19
+#include <linux/mfd/mt6397/registers.h>
20
+
21
+#define MT6323_RTC_BASE 0x8000
22
+#define MT6323_RTC_SIZE 0x40
23
+
24
+#define MT6358_RTC_BASE 0x0588
25
+#define MT6358_RTC_SIZE 0x3c
2526
2627 #define MT6397_RTC_BASE 0xe000
2728 #define MT6397_RTC_SIZE 0x3e
2829
29
-#define MT6323_CID_CODE 0x23
30
-#define MT6391_CID_CODE 0x91
31
-#define MT6397_CID_CODE 0x97
30
+#define MT6323_PWRC_BASE 0x8000
31
+#define MT6323_PWRC_SIZE 0x40
32
+
33
+static const struct resource mt6323_rtc_resources[] = {
34
+ DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
35
+ DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
36
+};
37
+
38
+static const struct resource mt6358_rtc_resources[] = {
39
+ DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
40
+ DEFINE_RES_IRQ(MT6358_IRQ_RTC),
41
+};
3242
3343 static const struct resource mt6397_rtc_resources[] = {
34
- {
35
- .start = MT6397_RTC_BASE,
36
- .end = MT6397_RTC_BASE + MT6397_RTC_SIZE,
37
- .flags = IORESOURCE_MEM,
38
- },
39
- {
40
- .start = MT6397_IRQ_RTC,
41
- .end = MT6397_IRQ_RTC,
42
- .flags = IORESOURCE_IRQ,
43
- },
44
+ DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
45
+ DEFINE_RES_IRQ(MT6397_IRQ_RTC),
4446 };
4547
4648 static const struct resource mt6323_keys_resources[] = {
....@@ -53,8 +55,17 @@
5355 DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
5456 };
5557
58
+static const struct resource mt6323_pwrc_resources[] = {
59
+ DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
60
+};
61
+
5662 static const struct mfd_cell mt6323_devs[] = {
5763 {
64
+ .name = "mt6323-rtc",
65
+ .num_resources = ARRAY_SIZE(mt6323_rtc_resources),
66
+ .resources = mt6323_rtc_resources,
67
+ .of_compatible = "mediatek,mt6323-rtc",
68
+ }, {
5869 .name = "mt6323-regulator",
5970 .of_compatible = "mediatek,mt6323-regulator"
6071 }, {
....@@ -65,6 +76,26 @@
6576 .num_resources = ARRAY_SIZE(mt6323_keys_resources),
6677 .resources = mt6323_keys_resources,
6778 .of_compatible = "mediatek,mt6323-keys"
79
+ }, {
80
+ .name = "mt6323-pwrc",
81
+ .num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
82
+ .resources = mt6323_pwrc_resources,
83
+ .of_compatible = "mediatek,mt6323-pwrc"
84
+ },
85
+};
86
+
87
+static const struct mfd_cell mt6358_devs[] = {
88
+ {
89
+ .name = "mt6358-regulator",
90
+ .of_compatible = "mediatek,mt6358-regulator"
91
+ }, {
92
+ .name = "mt6358-rtc",
93
+ .num_resources = ARRAY_SIZE(mt6358_rtc_resources),
94
+ .resources = mt6358_rtc_resources,
95
+ .of_compatible = "mediatek,mt6358-rtc",
96
+ }, {
97
+ .name = "mt6358-sound",
98
+ .of_compatible = "mediatek,mt6358-sound"
6899 },
69100 };
70101
....@@ -94,182 +125,44 @@
94125 }
95126 };
96127
97
-static void mt6397_irq_lock(struct irq_data *data)
98
-{
99
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
100
-
101
- mutex_lock(&mt6397->irqlock);
102
-}
103
-
104
-static void mt6397_irq_sync_unlock(struct irq_data *data)
105
-{
106
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
107
-
108
- regmap_write(mt6397->regmap, mt6397->int_con[0],
109
- mt6397->irq_masks_cur[0]);
110
- regmap_write(mt6397->regmap, mt6397->int_con[1],
111
- mt6397->irq_masks_cur[1]);
112
-
113
- mutex_unlock(&mt6397->irqlock);
114
-}
115
-
116
-static void mt6397_irq_disable(struct irq_data *data)
117
-{
118
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
119
- int shift = data->hwirq & 0xf;
120
- int reg = data->hwirq >> 4;
121
-
122
- mt6397->irq_masks_cur[reg] &= ~BIT(shift);
123
-}
124
-
125
-static void mt6397_irq_enable(struct irq_data *data)
126
-{
127
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
128
- int shift = data->hwirq & 0xf;
129
- int reg = data->hwirq >> 4;
130
-
131
- mt6397->irq_masks_cur[reg] |= BIT(shift);
132
-}
133
-
134
-#ifdef CONFIG_PM_SLEEP
135
-static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
136
-{
137
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
138
- int shift = irq_data->hwirq & 0xf;
139
- int reg = irq_data->hwirq >> 4;
140
-
141
- if (on)
142
- mt6397->wake_mask[reg] |= BIT(shift);
143
- else
144
- mt6397->wake_mask[reg] &= ~BIT(shift);
145
-
146
- return 0;
147
-}
148
-#else
149
-#define mt6397_irq_set_wake NULL
150
-#endif
151
-
152
-static struct irq_chip mt6397_irq_chip = {
153
- .name = "mt6397-irq",
154
- .irq_bus_lock = mt6397_irq_lock,
155
- .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
156
- .irq_enable = mt6397_irq_enable,
157
- .irq_disable = mt6397_irq_disable,
158
- .irq_set_wake = mt6397_irq_set_wake,
128
+struct chip_data {
129
+ u32 cid_addr;
130
+ u32 cid_shift;
131
+ const struct mfd_cell *cells;
132
+ int cell_size;
133
+ int (*irq_init)(struct mt6397_chip *chip);
159134 };
160135
161
-static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
162
- int irqbase)
163
-{
164
- unsigned int status;
165
- int i, irq, ret;
166
-
167
- ret = regmap_read(mt6397->regmap, reg, &status);
168
- if (ret) {
169
- dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
170
- return;
171
- }
172
-
173
- for (i = 0; i < 16; i++) {
174
- if (status & BIT(i)) {
175
- irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
176
- if (irq)
177
- handle_nested_irq(irq);
178
- }
179
- }
180
-
181
- regmap_write(mt6397->regmap, reg, status);
182
-}
183
-
184
-static irqreturn_t mt6397_irq_thread(int irq, void *data)
185
-{
186
- struct mt6397_chip *mt6397 = data;
187
-
188
- mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
189
- mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
190
-
191
- return IRQ_HANDLED;
192
-}
193
-
194
-static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
195
- irq_hw_number_t hw)
196
-{
197
- struct mt6397_chip *mt6397 = d->host_data;
198
-
199
- irq_set_chip_data(irq, mt6397);
200
- irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
201
- irq_set_nested_thread(irq, 1);
202
- irq_set_noprobe(irq);
203
-
204
- return 0;
205
-}
206
-
207
-static const struct irq_domain_ops mt6397_irq_domain_ops = {
208
- .map = mt6397_irq_domain_map,
136
+static const struct chip_data mt6323_core = {
137
+ .cid_addr = MT6323_CID,
138
+ .cid_shift = 0,
139
+ .cells = mt6323_devs,
140
+ .cell_size = ARRAY_SIZE(mt6323_devs),
141
+ .irq_init = mt6397_irq_init,
209142 };
210143
211
-static int mt6397_irq_init(struct mt6397_chip *mt6397)
212
-{
213
- int ret;
144
+static const struct chip_data mt6358_core = {
145
+ .cid_addr = MT6358_SWCID,
146
+ .cid_shift = 8,
147
+ .cells = mt6358_devs,
148
+ .cell_size = ARRAY_SIZE(mt6358_devs),
149
+ .irq_init = mt6358_irq_init,
150
+};
214151
215
- mutex_init(&mt6397->irqlock);
216
-
217
- /* Mask all interrupt sources */
218
- regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
219
- regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
220
-
221
- mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
222
- MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
223
- if (!mt6397->irq_domain) {
224
- dev_err(mt6397->dev, "could not create irq domain\n");
225
- return -ENOMEM;
226
- }
227
-
228
- ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
229
- mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
230
- if (ret) {
231
- dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
232
- mt6397->irq, ret);
233
- return ret;
234
- }
235
-
236
- return 0;
237
-}
238
-
239
-#ifdef CONFIG_PM_SLEEP
240
-static int mt6397_irq_suspend(struct device *dev)
241
-{
242
- struct mt6397_chip *chip = dev_get_drvdata(dev);
243
-
244
- regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
245
- regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
246
-
247
- enable_irq_wake(chip->irq);
248
-
249
- return 0;
250
-}
251
-
252
-static int mt6397_irq_resume(struct device *dev)
253
-{
254
- struct mt6397_chip *chip = dev_get_drvdata(dev);
255
-
256
- regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
257
- regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
258
-
259
- disable_irq_wake(chip->irq);
260
-
261
- return 0;
262
-}
263
-#endif
264
-
265
-static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
266
- mt6397_irq_resume);
152
+static const struct chip_data mt6397_core = {
153
+ .cid_addr = MT6397_CID,
154
+ .cid_shift = 0,
155
+ .cells = mt6397_devs,
156
+ .cell_size = ARRAY_SIZE(mt6397_devs),
157
+ .irq_init = mt6397_irq_init,
158
+};
267159
268160 static int mt6397_probe(struct platform_device *pdev)
269161 {
270162 int ret;
271
- unsigned int id;
163
+ unsigned int id = 0;
272164 struct mt6397_chip *pmic;
165
+ const struct chip_data *pmic_core;
273166
274167 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
275168 if (!pmic)
....@@ -285,53 +178,31 @@
285178 if (!pmic->regmap)
286179 return -ENODEV;
287180
288
- platform_set_drvdata(pdev, pmic);
181
+ pmic_core = of_device_get_match_data(&pdev->dev);
182
+ if (!pmic_core)
183
+ return -ENODEV;
289184
290
- ret = regmap_read(pmic->regmap, MT6397_CID, &id);
185
+ ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
291186 if (ret) {
292
- dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
187
+ dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
293188 return ret;
294189 }
190
+
191
+ pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
192
+
193
+ platform_set_drvdata(pdev, pmic);
295194
296195 pmic->irq = platform_get_irq(pdev, 0);
297196 if (pmic->irq <= 0)
298197 return pmic->irq;
299198
300
- switch (id & 0xff) {
301
- case MT6323_CID_CODE:
302
- pmic->int_con[0] = MT6323_INT_CON0;
303
- pmic->int_con[1] = MT6323_INT_CON1;
304
- pmic->int_status[0] = MT6323_INT_STATUS0;
305
- pmic->int_status[1] = MT6323_INT_STATUS1;
306
- ret = mt6397_irq_init(pmic);
307
- if (ret)
308
- return ret;
199
+ ret = pmic_core->irq_init(pmic);
200
+ if (ret)
201
+ return ret;
309202
310
- ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
311
- ARRAY_SIZE(mt6323_devs), NULL,
312
- 0, pmic->irq_domain);
313
- break;
314
-
315
- case MT6397_CID_CODE:
316
- case MT6391_CID_CODE:
317
- pmic->int_con[0] = MT6397_INT_CON0;
318
- pmic->int_con[1] = MT6397_INT_CON1;
319
- pmic->int_status[0] = MT6397_INT_STATUS0;
320
- pmic->int_status[1] = MT6397_INT_STATUS1;
321
- ret = mt6397_irq_init(pmic);
322
- if (ret)
323
- return ret;
324
-
325
- ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
326
- ARRAY_SIZE(mt6397_devs), NULL,
327
- 0, pmic->irq_domain);
328
- break;
329
-
330
- default:
331
- dev_err(&pdev->dev, "unsupported chip: %d\n", id);
332
- return -ENODEV;
333
- }
334
-
203
+ ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
204
+ pmic_core->cells, pmic_core->cell_size,
205
+ NULL, 0, pmic->irq_domain);
335206 if (ret) {
336207 irq_domain_remove(pmic->irq_domain);
337208 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
....@@ -341,9 +212,18 @@
341212 }
342213
343214 static const struct of_device_id mt6397_of_match[] = {
344
- { .compatible = "mediatek,mt6397" },
345
- { .compatible = "mediatek,mt6323" },
346
- { }
215
+ {
216
+ .compatible = "mediatek,mt6323",
217
+ .data = &mt6323_core,
218
+ }, {
219
+ .compatible = "mediatek,mt6358",
220
+ .data = &mt6358_core,
221
+ }, {
222
+ .compatible = "mediatek,mt6397",
223
+ .data = &mt6397_core,
224
+ }, {
225
+ /* sentinel */
226
+ }
347227 };
348228 MODULE_DEVICE_TABLE(of, mt6397_of_match);
349229
....@@ -358,7 +238,6 @@
358238 .driver = {
359239 .name = "mt6397",
360240 .of_match_table = of_match_ptr(mt6397_of_match),
361
- .pm = &mt6397_pm_ops,
362241 },
363242 .id_table = mt6397_id,
364243 };