Merge tag 'for-5.13/parisc' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux-2.6-microblaze.git] / drivers / staging / hikey9xx / hi6421-spmi-pmic.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Device driver for regulators in HISI PMIC IC
4  *
5  * Copyright (c) 2013 Linaro Ltd.
6  * Copyright (c) 2011 Hisilicon.
7  * Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
8  */
9
10 #include <linux/bitops.h>
11 #include <linux/interrupt.h>
12 #include <linux/irq.h>
13 #include <linux/mfd/core.h>
14 #include <linux/mfd/hi6421-spmi-pmic.h>
15 #include <linux/module.h>
16 #include <linux/of_gpio.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include <linux/spmi.h>
20
21 enum hi6421_spmi_pmic_irq_list {
22         OTMP = 0,
23         VBUS_CONNECT,
24         VBUS_DISCONNECT,
25         ALARMON_R,
26         HOLD_6S,
27         HOLD_1S,
28         POWERKEY_UP,
29         POWERKEY_DOWN,
30         OCP_SCP_R,
31         COUL_R,
32         SIM0_HPD_R,
33         SIM0_HPD_F,
34         SIM1_HPD_R,
35         SIM1_HPD_F,
36         PMIC_IRQ_LIST_MAX,
37 };
38
39 #define HISI_IRQ_ARRAY                  2
40 #define HISI_IRQ_NUM                    (HISI_IRQ_ARRAY * 8)
41
42 #define HISI_IRQ_KEY_NUM                0
43
44 #define HISI_BITS                       8
45 #define HISI_IRQ_KEY_VALUE              (BIT(POWERKEY_DOWN) | BIT(POWERKEY_UP))
46 #define HISI_MASK                       GENMASK(HISI_BITS - 1, 0)
47
48 /*
49  * The IRQs are mapped as:
50  *
51  *      ======================  =============   ============    =====
52  *      IRQ                     MASK REGISTER   IRQ REGISTER    BIT
53  *      ======================  =============   ============    =====
54  *      OTMP                    0x0202          0x212           bit 0
55  *      VBUS_CONNECT            0x0202          0x212           bit 1
56  *      VBUS_DISCONNECT         0x0202          0x212           bit 2
57  *      ALARMON_R               0x0202          0x212           bit 3
58  *      HOLD_6S                 0x0202          0x212           bit 4
59  *      HOLD_1S                 0x0202          0x212           bit 5
60  *      POWERKEY_UP             0x0202          0x212           bit 6
61  *      POWERKEY_DOWN           0x0202          0x212           bit 7
62  *
63  *      OCP_SCP_R               0x0203          0x213           bit 0
64  *      COUL_R                  0x0203          0x213           bit 1
65  *      SIM0_HPD_R              0x0203          0x213           bit 2
66  *      SIM0_HPD_F              0x0203          0x213           bit 3
67  *      SIM1_HPD_R              0x0203          0x213           bit 4
68  *      SIM1_HPD_F              0x0203          0x213           bit 5
69  *      ======================  =============   ============    =====
70  */
71 #define SOC_PMIC_IRQ_MASK_0_ADDR        0x0202
72 #define SOC_PMIC_IRQ0_ADDR              0x0212
73
74 #define IRQ_MASK_REGISTER(irq_data)     (SOC_PMIC_IRQ_MASK_0_ADDR + \
75                                          (irqd_to_hwirq(irq_data) >> 3))
76 #define IRQ_MASK_BIT(irq_data)          BIT(irqd_to_hwirq(irq_data) & 0x07)
77
78 static const struct mfd_cell hi6421v600_devs[] = {
79         { .name = "hi6421v600-regulator", },
80 };
81
82 static irqreturn_t hi6421_spmi_irq_handler(int irq, void *priv)
83 {
84         struct hi6421_spmi_pmic *ddata = (struct hi6421_spmi_pmic *)priv;
85         unsigned long pending;
86         unsigned int in;
87         int i, offset;
88
89         for (i = 0; i < HISI_IRQ_ARRAY; i++) {
90                 regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &in);
91                 pending = HISI_MASK & in;
92                 regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, pending);
93
94                 if (i == HISI_IRQ_KEY_NUM &&
95                     (pending & HISI_IRQ_KEY_VALUE) == HISI_IRQ_KEY_VALUE) {
96                         generic_handle_irq(ddata->irqs[POWERKEY_DOWN]);
97                         generic_handle_irq(ddata->irqs[POWERKEY_UP]);
98                         pending &= (~HISI_IRQ_KEY_VALUE);
99                 }
100
101                 if (!pending)
102                         continue;
103
104                 for_each_set_bit(offset, &pending, HISI_BITS)
105                         generic_handle_irq(ddata->irqs[offset + i * HISI_BITS]);
106         }
107
108         return IRQ_HANDLED;
109 }
110
111 static void hi6421_spmi_irq_mask(struct irq_data *d)
112 {
113         struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
114         unsigned long flags;
115         unsigned int data;
116         u32 offset;
117
118         offset = IRQ_MASK_REGISTER(d);
119
120         spin_lock_irqsave(&ddata->lock, flags);
121
122         regmap_read(ddata->regmap, offset, &data);
123         data |= IRQ_MASK_BIT(d);
124         regmap_write(ddata->regmap, offset, data);
125
126         spin_unlock_irqrestore(&ddata->lock, flags);
127 }
128
129 static void hi6421_spmi_irq_unmask(struct irq_data *d)
130 {
131         struct hi6421_spmi_pmic *ddata = irq_data_get_irq_chip_data(d);
132         u32 data, offset;
133         unsigned long flags;
134
135         offset = (irqd_to_hwirq(d) >> 3);
136         offset += SOC_PMIC_IRQ_MASK_0_ADDR;
137
138         spin_lock_irqsave(&ddata->lock, flags);
139
140         regmap_read(ddata->regmap, offset, &data);
141         data &= ~(1 << (irqd_to_hwirq(d) & 0x07));
142         regmap_write(ddata->regmap, offset, data);
143
144         spin_unlock_irqrestore(&ddata->lock, flags);
145 }
146
147 static struct irq_chip hi6421_spmi_pmu_irqchip = {
148         .name           = "hisi-irq",
149         .irq_mask       = hi6421_spmi_irq_mask,
150         .irq_unmask     = hi6421_spmi_irq_unmask,
151         .irq_disable    = hi6421_spmi_irq_mask,
152         .irq_enable     = hi6421_spmi_irq_unmask,
153 };
154
155 static int hi6421_spmi_irq_map(struct irq_domain *d, unsigned int virq,
156                                irq_hw_number_t hw)
157 {
158         struct hi6421_spmi_pmic *ddata = d->host_data;
159
160         irq_set_chip_and_handler_name(virq, &hi6421_spmi_pmu_irqchip,
161                                       handle_simple_irq, "hisi");
162         irq_set_chip_data(virq, ddata);
163         irq_set_irq_type(virq, IRQ_TYPE_NONE);
164
165         return 0;
166 }
167
168 static const struct irq_domain_ops hi6421_spmi_domain_ops = {
169         .map    = hi6421_spmi_irq_map,
170         .xlate  = irq_domain_xlate_twocell,
171 };
172
173 static void hi6421_spmi_pmic_irq_init(struct hi6421_spmi_pmic *ddata)
174 {
175         int i;
176         unsigned int pending;
177
178         for (i = 0; i < HISI_IRQ_ARRAY; i++)
179                 regmap_write(ddata->regmap, SOC_PMIC_IRQ_MASK_0_ADDR + i,
180                              HISI_MASK);
181
182         for (i = 0; i < HISI_IRQ_ARRAY; i++) {
183                 regmap_read(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i, &pending);
184                 regmap_write(ddata->regmap, SOC_PMIC_IRQ0_ADDR + i,
185                              HISI_MASK);
186         }
187 }
188
189 static const struct regmap_config regmap_config = {
190         .reg_bits               = 16,
191         .val_bits               = HISI_BITS,
192         .max_register           = 0xffff,
193         .fast_io                = true
194 };
195
196 static int hi6421_spmi_pmic_probe(struct spmi_device *pdev)
197 {
198         struct device *dev = &pdev->dev;
199         struct device_node *np = dev->of_node;
200         struct hi6421_spmi_pmic *ddata;
201         unsigned int virq;
202         int ret, i;
203
204         ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
205         if (!ddata)
206                 return -ENOMEM;
207
208         ddata->regmap = devm_regmap_init_spmi_ext(pdev, &regmap_config);
209         if (IS_ERR(ddata->regmap))
210                 return PTR_ERR(ddata->regmap);
211
212         spin_lock_init(&ddata->lock);
213
214         ddata->dev = dev;
215
216         ddata->gpio = of_get_gpio(np, 0);
217         if (ddata->gpio < 0)
218                 return ddata->gpio;
219
220         if (!gpio_is_valid(ddata->gpio))
221                 return -EINVAL;
222
223         ret = devm_gpio_request_one(dev, ddata->gpio, GPIOF_IN, "pmic");
224         if (ret < 0) {
225                 dev_err(dev, "Failed to request gpio%d\n", ddata->gpio);
226                 return ret;
227         }
228
229         ddata->irq = gpio_to_irq(ddata->gpio);
230
231         hi6421_spmi_pmic_irq_init(ddata);
232
233         ddata->irqs = devm_kzalloc(dev, HISI_IRQ_NUM * sizeof(int), GFP_KERNEL);
234         if (!ddata->irqs)
235                 return -ENOMEM;
236
237         ddata->domain = irq_domain_add_simple(np, HISI_IRQ_NUM, 0,
238                                               &hi6421_spmi_domain_ops, ddata);
239         if (!ddata->domain) {
240                 dev_err(dev, "Failed to create IRQ domain\n");
241                 return -ENODEV;
242         }
243
244         for (i = 0; i < HISI_IRQ_NUM; i++) {
245                 virq = irq_create_mapping(ddata->domain, i);
246                 if (!virq) {
247                         dev_err(dev, "Failed to map H/W IRQ\n");
248                         return -ENOSPC;
249                 }
250                 ddata->irqs[i] = virq;
251         }
252
253         ret = request_threaded_irq(ddata->irq, hi6421_spmi_irq_handler, NULL,
254                                    IRQF_TRIGGER_LOW | IRQF_SHARED | IRQF_NO_SUSPEND,
255                                    "pmic", ddata);
256         if (ret < 0) {
257                 dev_err(dev, "Failed to start IRQ handling thread: error %d\n",
258                         ret);
259                 return ret;
260         }
261
262         dev_set_drvdata(&pdev->dev, ddata);
263
264         ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
265                                    hi6421v600_devs, ARRAY_SIZE(hi6421v600_devs),
266                                    NULL, 0, NULL);
267         if (ret < 0)
268                 dev_err(dev, "Failed to add child devices: %d\n", ret);
269
270         return ret;
271 }
272
273 static void hi6421_spmi_pmic_remove(struct spmi_device *pdev)
274 {
275         struct hi6421_spmi_pmic *ddata = dev_get_drvdata(&pdev->dev);
276
277         free_irq(ddata->irq, ddata);
278 }
279
280 static const struct of_device_id pmic_spmi_id_table[] = {
281         { .compatible = "hisilicon,hi6421-spmi" },
282         { }
283 };
284 MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
285
286 static struct spmi_driver hi6421_spmi_pmic_driver = {
287         .driver = {
288                 .name   = "hi6421-spmi-pmic",
289                 .of_match_table = pmic_spmi_id_table,
290         },
291         .probe  = hi6421_spmi_pmic_probe,
292         .remove = hi6421_spmi_pmic_remove,
293 };
294 module_spmi_driver(hi6421_spmi_pmic_driver);
295
296 MODULE_DESCRIPTION("HiSilicon Hi6421v600 SPMI PMIC driver");
297 MODULE_LICENSE("GPL v2");