Merge tag 'irq_urgent_for_v6.5_rc4' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / drivers / mfd / tps65217.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * tps65217.c
4  *
5  * TPS65217 chip family multi-function driver
6  *
7  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
8  */
9
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/i2c.h>
15 #include <linux/irq.h>
16 #include <linux/irqdomain.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/of_device.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 #include <linux/slab.h>
24
25 #include <linux/mfd/core.h>
26 #include <linux/mfd/tps65217.h>
27
28 static const struct resource charger_resources[] = {
29         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_AC, "AC"),
30         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_USB, "USB"),
31 };
32
33 static const struct resource pb_resources[] = {
34         DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
35 };
36
37 static void tps65217_irq_lock(struct irq_data *data)
38 {
39         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
40
41         mutex_lock(&tps->irq_lock);
42 }
43
44 static void tps65217_irq_sync_unlock(struct irq_data *data)
45 {
46         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
47         int ret;
48
49         ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
50                                 tps->irq_mask, TPS65217_PROTECT_NONE);
51         if (ret != 0)
52                 dev_err(tps->dev, "Failed to sync IRQ masks\n");
53
54         mutex_unlock(&tps->irq_lock);
55 }
56
57 static void tps65217_irq_enable(struct irq_data *data)
58 {
59         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
60         u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
61
62         tps->irq_mask &= ~mask;
63 }
64
65 static void tps65217_irq_disable(struct irq_data *data)
66 {
67         struct tps65217 *tps = irq_data_get_irq_chip_data(data);
68         u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
69
70         tps->irq_mask |= mask;
71 }
72
73 static struct irq_chip tps65217_irq_chip = {
74         .name                   = "tps65217",
75         .irq_bus_lock           = tps65217_irq_lock,
76         .irq_bus_sync_unlock    = tps65217_irq_sync_unlock,
77         .irq_enable             = tps65217_irq_enable,
78         .irq_disable            = tps65217_irq_disable,
79 };
80
81 static struct mfd_cell tps65217s[] = {
82         {
83                 .name = "tps65217-pmic",
84                 .of_compatible = "ti,tps65217-pmic",
85         },
86         {
87                 .name = "tps65217-bl",
88                 .of_compatible = "ti,tps65217-bl",
89         },
90         {
91                 .name = "tps65217-charger",
92                 .num_resources = ARRAY_SIZE(charger_resources),
93                 .resources = charger_resources,
94                 .of_compatible = "ti,tps65217-charger",
95         },
96         {
97                 .name = "tps65217-pwrbutton",
98                 .num_resources = ARRAY_SIZE(pb_resources),
99                 .resources = pb_resources,
100                 .of_compatible = "ti,tps65217-pwrbutton",
101         },
102 };
103
104 static irqreturn_t tps65217_irq_thread(int irq, void *data)
105 {
106         struct tps65217 *tps = data;
107         unsigned int status;
108         bool handled = false;
109         int i;
110         int ret;
111
112         ret = tps65217_reg_read(tps, TPS65217_REG_INT, &status);
113         if (ret < 0) {
114                 dev_err(tps->dev, "Failed to read IRQ status: %d\n",
115                         ret);
116                 return IRQ_NONE;
117         }
118
119         for (i = 0; i < TPS65217_NUM_IRQ; i++) {
120                 if (status & BIT(i)) {
121                         handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
122                         handled = true;
123                 }
124         }
125
126         if (handled)
127                 return IRQ_HANDLED;
128
129         return IRQ_NONE;
130 }
131
132 static int tps65217_irq_map(struct irq_domain *h, unsigned int virq,
133                         irq_hw_number_t hw)
134 {
135         struct tps65217 *tps = h->host_data;
136
137         irq_set_chip_data(virq, tps);
138         irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq);
139         irq_set_nested_thread(virq, 1);
140         irq_set_parent(virq, tps->irq);
141         irq_set_noprobe(virq);
142
143         return 0;
144 }
145
146 static const struct irq_domain_ops tps65217_irq_domain_ops = {
147         .map = tps65217_irq_map,
148 };
149
150 static int tps65217_irq_init(struct tps65217 *tps, int irq)
151 {
152         int ret;
153
154         mutex_init(&tps->irq_lock);
155         tps->irq = irq;
156
157         /* Mask all interrupt sources */
158         tps->irq_mask = TPS65217_INT_MASK;
159         tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
160                           TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
161
162         tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
163                 TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
164         if (!tps->irq_domain) {
165                 dev_err(tps->dev, "Could not create IRQ domain\n");
166                 return -ENOMEM;
167         }
168
169         ret = devm_request_threaded_irq(tps->dev, irq, NULL,
170                                         tps65217_irq_thread, IRQF_ONESHOT,
171                                         "tps65217-irq", tps);
172         if (ret) {
173                 dev_err(tps->dev, "Failed to request IRQ %d: %d\n",
174                         irq, ret);
175                 return ret;
176         }
177
178         enable_irq_wake(irq);
179
180         return 0;
181 }
182
183 /**
184  * tps65217_reg_read: Read a single tps65217 register.
185  *
186  * @tps: Device to read from.
187  * @reg: Register to read.
188  * @val: Contians the value
189  */
190 int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
191                         unsigned int *val)
192 {
193         return regmap_read(tps->regmap, reg, val);
194 }
195 EXPORT_SYMBOL_GPL(tps65217_reg_read);
196
197 /**
198  * tps65217_reg_write: Write a single tps65217 register.
199  *
200  * @tps: Device to write to.
201  * @reg: Register to write to.
202  * @val: Value to write.
203  * @level: Password protected level
204  */
205 int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
206                         unsigned int val, unsigned int level)
207 {
208         int ret;
209         unsigned int xor_reg_val;
210
211         switch (level) {
212         case TPS65217_PROTECT_NONE:
213                 return regmap_write(tps->regmap, reg, val);
214         case TPS65217_PROTECT_L1:
215                 xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
216                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
217                                                         xor_reg_val);
218                 if (ret < 0)
219                         return ret;
220
221                 return regmap_write(tps->regmap, reg, val);
222         case TPS65217_PROTECT_L2:
223                 xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
224                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
225                                                         xor_reg_val);
226                 if (ret < 0)
227                         return ret;
228                 ret = regmap_write(tps->regmap, reg, val);
229                 if (ret < 0)
230                         return ret;
231                 ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
232                                                         xor_reg_val);
233                 if (ret < 0)
234                         return ret;
235                 return regmap_write(tps->regmap, reg, val);
236         default:
237                 return -EINVAL;
238         }
239 }
240 EXPORT_SYMBOL_GPL(tps65217_reg_write);
241
242 /**
243  * tps65217_update_bits: Modify bits w.r.t mask, val and level.
244  *
245  * @tps: Device to write to.
246  * @reg: Register to read-write to.
247  * @mask: Mask.
248  * @val: Value to write.
249  * @level: Password protected level
250  */
251 static int tps65217_update_bits(struct tps65217 *tps, unsigned int reg,
252                 unsigned int mask, unsigned int val, unsigned int level)
253 {
254         int ret;
255         unsigned int data;
256
257         ret = tps65217_reg_read(tps, reg, &data);
258         if (ret) {
259                 dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
260                 return ret;
261         }
262
263         data &= ~mask;
264         data |= val & mask;
265
266         ret = tps65217_reg_write(tps, reg, data, level);
267         if (ret)
268                 dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
269
270         return ret;
271 }
272
273 int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
274                 unsigned int mask, unsigned int val, unsigned int level)
275 {
276         return tps65217_update_bits(tps, reg, mask, val, level);
277 }
278 EXPORT_SYMBOL_GPL(tps65217_set_bits);
279
280 int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
281                 unsigned int mask, unsigned int level)
282 {
283         return tps65217_update_bits(tps, reg, mask, 0, level);
284 }
285 EXPORT_SYMBOL_GPL(tps65217_clear_bits);
286
287 static bool tps65217_volatile_reg(struct device *dev, unsigned int reg)
288 {
289         switch (reg) {
290         case TPS65217_REG_INT:
291                 return true;
292         default:
293                 return false;
294         }
295 }
296
297 static const struct regmap_config tps65217_regmap_config = {
298         .reg_bits = 8,
299         .val_bits = 8,
300
301         .max_register = TPS65217_REG_MAX,
302         .volatile_reg = tps65217_volatile_reg,
303 };
304
305 static const struct of_device_id tps65217_of_match[] = {
306         { .compatible = "ti,tps65217"},
307         { /* sentinel */ },
308 };
309 MODULE_DEVICE_TABLE(of, tps65217_of_match);
310
311 static int tps65217_probe(struct i2c_client *client)
312 {
313         struct tps65217 *tps;
314         unsigned int version;
315         bool status_off = false;
316         int ret;
317
318         status_off = of_property_read_bool(client->dev.of_node,
319                                            "ti,pmic-shutdown-controller");
320
321         tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
322         if (!tps)
323                 return -ENOMEM;
324
325         i2c_set_clientdata(client, tps);
326         tps->dev = &client->dev;
327
328         tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);
329         if (IS_ERR(tps->regmap)) {
330                 ret = PTR_ERR(tps->regmap);
331                 dev_err(tps->dev, "Failed to allocate register map: %d\n",
332                         ret);
333                 return ret;
334         }
335
336         if (client->irq) {
337                 tps65217_irq_init(tps, client->irq);
338         } else {
339                 int i;
340
341                 /* Don't tell children about IRQ resources which won't fire */
342                 for (i = 0; i < ARRAY_SIZE(tps65217s); i++)
343                         tps65217s[i].num_resources = 0;
344         }
345
346         ret = devm_mfd_add_devices(tps->dev, -1, tps65217s,
347                                    ARRAY_SIZE(tps65217s), NULL, 0,
348                                    tps->irq_domain);
349         if (ret < 0) {
350                 dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
351                 return ret;
352         }
353
354         ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
355         if (ret < 0) {
356                 dev_err(tps->dev, "Failed to read revision register: %d\n",
357                         ret);
358                 return ret;
359         }
360
361         /* Set the PMIC to shutdown on PWR_EN toggle */
362         if (status_off) {
363                 ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
364                                 TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
365                                 TPS65217_PROTECT_NONE);
366                 if (ret)
367                         dev_warn(tps->dev, "unable to set the status OFF\n");
368         }
369
370         dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
371                         (version & TPS65217_CHIPID_CHIP_MASK) >> 4,
372                         version & TPS65217_CHIPID_REV_MASK);
373
374         return 0;
375 }
376
377 static void tps65217_remove(struct i2c_client *client)
378 {
379         struct tps65217 *tps = i2c_get_clientdata(client);
380         unsigned int virq;
381         int i;
382
383         for (i = 0; i < TPS65217_NUM_IRQ; i++) {
384                 virq = irq_find_mapping(tps->irq_domain, i);
385                 if (virq)
386                         irq_dispose_mapping(virq);
387         }
388
389         irq_domain_remove(tps->irq_domain);
390         tps->irq_domain = NULL;
391 }
392
393 static const struct i2c_device_id tps65217_id_table[] = {
394         {"tps65217", TPS65217},
395         { /* sentinel */ }
396 };
397 MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
398
399 static struct i2c_driver tps65217_driver = {
400         .driver         = {
401                 .name   = "tps65217",
402                 .of_match_table = tps65217_of_match,
403         },
404         .id_table       = tps65217_id_table,
405         .probe          = tps65217_probe,
406         .remove         = tps65217_remove,
407 };
408
409 static int __init tps65217_init(void)
410 {
411         return i2c_add_driver(&tps65217_driver);
412 }
413 subsys_initcall(tps65217_init);
414
415 static void __exit tps65217_exit(void)
416 {
417         i2c_del_driver(&tps65217_driver);
418 }
419 module_exit(tps65217_exit);
420
421 MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
422 MODULE_DESCRIPTION("TPS65217 chip family multi-function driver");
423 MODULE_LICENSE("GPL v2");