1 #define pr_fmt(x) KBUILD_MODNAME ": " x "\n"
2
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/init.h>
6 #include "linux/irq.h"
7 #include <linux/slab.h>
8 #include <linux/interrupt.h>
9 #include <linux/device.h>
10 #include <linux/mutex.h>
11 #include <linux/param.h>
12 #include <linux/jiffies.h>
13 #include <linux/platform_device.h>
14 #include <linux/power_supply.h>
15 #include <linux/fs.h>
16 #include <linux/kernel.h>
17 #include <linux/ktime.h>
18 #include <linux/of.h>
19 #include <linux/timekeeping.h>
20 #include <linux/types.h>
21 #include <linux/string.h>
22 #include <asm/irq.h>
23 #include <linux/cdev.h>
24 #include <linux/delay.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/kthread.h>
27 #include <linux/freezer.h>
28 #include <linux/err.h>
29 #include <sunxi-gpio.h>
30 #include <pinctrl/pinctrl-sunxi.h>
31 #include <linux/of_gpio.h>
32 #include "power/axp2101.h"
33
34 #include <linux/err.h>
35 //#include "../drivers/gpio/gpiolib.h"
36 #include "axp2202_charger.h"
37
38 struct axp2202_gpio_power {
39 char *name;
40 struct device *dev;
41 struct regmap *regmap;
42 struct power_supply *gpio_supply;
43 struct axp_config_info dts_info;
44 struct delayed_work gpio_supply_mon;
45 struct delayed_work gpio_chg_state;
46 struct gpio_config axp_acin_det;
47 struct gpio_config usbid_drv;
48 struct gpio_config axp_vbus_det;
49 int acin_det_gpio_value;
50 };
51
52 int ac_in_flag;
53 int vbus_in_flag;
54
55 static enum power_supply_property axp2202_gpio_props[] = {
56 POWER_SUPPLY_PROP_MODEL_NAME,
57 };
58
axp2202_gpio_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)59 static int axp2202_gpio_get_property(struct power_supply *psy,
60 enum power_supply_property psp,
61 union power_supply_propval *val)
62 {
63 int ret = 0;
64
65 switch (psp) {
66 case POWER_SUPPLY_PROP_MODEL_NAME:
67 val->strval = psy->desc->name;
68 break;
69 default:
70 ret = -EINVAL;
71 }
72
73 return ret;
74 }
75
76 static const struct power_supply_desc axp2202_gpio_desc = {
77 .name = "axp2202-gpio",
78 .type = POWER_SUPPLY_TYPE_MAINS,
79 .get_property = axp2202_gpio_get_property,
80 .properties = axp2202_gpio_props,
81 .num_properties = ARRAY_SIZE(axp2202_gpio_props),
82 };
83
84
axp2202_irq_handler_gpio_in(void * data)85 int axp2202_irq_handler_gpio_in(void *data)
86 {
87 struct axp2202_gpio_power *gpio_power = data;
88
89 power_supply_changed(gpio_power->gpio_supply);
90 ac_in_flag = 1;
91
92 return 0;
93 }
94
axp2202_irq_handler_gpio_out(void * data)95 int axp2202_irq_handler_gpio_out(void *data)
96 {
97 struct axp2202_gpio_power *gpio_power = data;
98
99 power_supply_changed(gpio_power->gpio_supply);
100 ac_in_flag = 0;
101
102 return 0;
103 }
104
axp_acin_gpio_isr(int irq,void * data)105 static irqreturn_t axp_acin_gpio_isr(int irq, void *data)
106 {
107 struct axp2202_gpio_power *chg_dev = data;
108 chg_dev->acin_det_gpio_value = __gpio_get_value(
109 chg_dev->axp_acin_det.gpio);
110
111 if (chg_dev->acin_det_gpio_value == 1) {
112 pr_info("[acin_irq] ac_in_flag = %d\n",
113 ac_in_flag);
114 pr_info("acin_det_gpio_value == 1\n\n");
115 axp2202_irq_handler_gpio_in(chg_dev);
116 } else {
117 pr_info("[acout_irq] ac_in_flag = %d\n",
118 ac_in_flag);
119 pr_info("nacin_det_gpio_value == 0\n\n");
120 axp2202_irq_handler_gpio_out(chg_dev);
121 }
122
123 return IRQ_HANDLED;
124 }
125
axp_vbus_det_isr(int irq,void * data)126 static irqreturn_t axp_vbus_det_isr(int irq, void *data)
127 {
128 struct axp2202_gpio_power *chg_dev = data;
129 chg_dev->acin_det_gpio_value = __gpio_get_value(
130 chg_dev->axp_vbus_det.gpio);
131
132 if (chg_dev->acin_det_gpio_value == 1) {
133 vbus_in_flag = 1;
134 pr_info("[acin_irq] vbus_dev_flag = %d\n",
135 vbus_in_flag);
136 pr_info("vbus_det_gpio_value == 1\n\n");
137 } else {
138 vbus_in_flag = 0;
139 pr_info("[acout_irq] vbus_dev_flag = %d\n",
140 vbus_in_flag);
141 pr_info("vbus_det_gpio_value == 0\n\n");
142 }
143
144 return IRQ_HANDLED;
145 }
146
147 enum axp2202_gpio_virq_index {
148 AXP2202_VIRQ_GPIO,
149 AXP2202_VBUS_DET,
150 };
151
152 static struct axp_interrupts axp_gpio_irq[] = {
153 [AXP2202_VIRQ_GPIO] = { "pmu_acin_det_gpio", axp_acin_gpio_isr },
154 [AXP2202_VBUS_DET] = { "pmu_acin_det_gpio", axp_vbus_det_isr },
155 };
156
axp_acin_gpio_init(struct axp2202_gpio_power * chg_dev)157 static int axp_acin_gpio_init(struct axp2202_gpio_power *chg_dev)
158 {
159 unsigned long int config_set;
160 int pull = 0;
161
162 int id_irq_num = 0;
163 unsigned long irq_flags = 0;
164 int ret = 0;
165
166 if (!gpio_is_valid(chg_dev->axp_acin_det.gpio)) {
167 pr_err("ERR: get pmu_acin_det_gpio is fail\n");
168 return -EINVAL;
169 }
170
171 if (!gpio_is_valid(chg_dev->usbid_drv.gpio)) {
172 pr_err("ERR: get pmu_usbid_drv_gpio is fail\n");
173 return -EINVAL;
174 }
175
176 if (!gpio_is_valid(chg_dev->axp_vbus_det.gpio)) {
177 pr_err("ERR: get axp_vbus_det_gpio is fail\n");
178 return -EINVAL;
179 }
180
181 pr_info("axp_acin_gpio_init:%d, usbid_drv:%d, axp_vbus_det:%d\n",
182 chg_dev->axp_acin_det.gpio, chg_dev->usbid_drv.gpio, chg_dev->axp_vbus_det.gpio);
183
184 ret = gpio_request(
185 chg_dev->axp_acin_det.gpio,
186 "pmu_acin_det_gpio");
187
188 if (ret != 0) {
189 pr_err("ERR: pmu_acin_det gpio_request failed\n");
190 return -EINVAL;
191 }
192
193 ret = gpio_request(
194 chg_dev->usbid_drv.gpio,
195 "pmu_acin_usbid_drv");
196
197 if (ret != 0) {
198 pr_err("ERR: pmu_usbid_drv gpio_request failed\n");
199 return -EINVAL;
200 }
201
202 ret = gpio_request(
203 chg_dev->axp_vbus_det.gpio,
204 "pmu_vbus_det_gpio");
205
206 if (ret != 0) {
207 pr_err("ERR: pmu_vbus_det_gpio gpio_request failed\n");
208 return -EINVAL;
209 }
210
211
212 /* set acin input usbid output */
213
214 gpio_direction_input(chg_dev->axp_acin_det.gpio);
215 gpio_direction_output(chg_dev->usbid_drv.gpio, 1);
216 gpio_direction_input(chg_dev->axp_vbus_det.gpio);
217
218 /* set id gpio pull up */
219 config_set = SUNXI_PINCFG_PACK(
220 PIN_CONFIG_BIAS_PULL_UP,
221 pull);
222 pinctrl_gpio_set_config(chg_dev->axp_acin_det.gpio,
223 config_set);
224
225 id_irq_num = gpio_to_irq(chg_dev->axp_acin_det.gpio);
226
227 if (IS_ERR_VALUE((unsigned long)id_irq_num)) {
228 pr_err("ERR: map pmu_acin_det gpio to virq failed, err %d\n",
229 id_irq_num);
230 return -EINVAL;
231 }
232
233 axp_gpio_irq[0].irq = id_irq_num;
234
235 pr_info("acin_id_irq_num:%d, %d \n", axp_gpio_irq[0].irq, id_irq_num);
236
237 irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
238 IRQF_ONESHOT | IRQF_NO_SUSPEND;
239 ret = request_irq(id_irq_num, axp_gpio_irq[0].isr, irq_flags,
240 axp_gpio_irq[0].name, chg_dev);
241
242
243 if (IS_ERR_VALUE((unsigned long)ret)) {
244 pr_err("ERR: request pmu_acin_det virq %d failed, err %d\n",
245 id_irq_num, ret);
246 return -EINVAL;
247 }
248
249 dev_dbg(chg_dev->dev, "Requested %s IRQ %d: %d\n",
250 axp_gpio_irq[0].name, id_irq_num, ret);
251
252 /* set id vbus_det pull up */
253 config_set = SUNXI_PINCFG_PACK(
254 PIN_CONFIG_BIAS_PULL_UP,
255 pull);
256 pinctrl_gpio_set_config(chg_dev->axp_vbus_det.gpio,
257 config_set);
258
259 id_irq_num = gpio_to_irq(chg_dev->axp_vbus_det.gpio);
260
261 if (IS_ERR_VALUE((unsigned long)id_irq_num)) {
262 pr_err("ERR: map pmu_vbus_det gpio to virq failed, err %d\n",
263 id_irq_num);
264 return -EINVAL;
265 }
266
267 axp_gpio_irq[1].irq = id_irq_num;
268
269 pr_info("vbus_det_irq_num:%d, %d \n", axp_gpio_irq[1].irq, id_irq_num);
270
271 irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
272 IRQF_ONESHOT | IRQF_NO_SUSPEND;
273 ret = request_irq(id_irq_num, axp_gpio_irq[1].isr, irq_flags,
274 axp_gpio_irq[1].name, chg_dev);
275
276
277 if (IS_ERR_VALUE((unsigned long)ret)) {
278 pr_err("ERR: request pmu_vbus_det virq %d failed, err %d\n",
279 id_irq_num, ret);
280 return -EINVAL;
281 }
282
283 dev_dbg(chg_dev->dev, "Requested %s IRQ %d: %d\n",
284 axp_gpio_irq[1].name, id_irq_num, ret);
285
286 return 0;
287 }
288
289
axp2202_gpio_power_monitor(struct work_struct * work)290 static void axp2202_gpio_power_monitor(struct work_struct *work)
291 {
292 struct axp2202_gpio_power *gpio_power =
293 container_of(work, typeof(*gpio_power), gpio_supply_mon.work);
294
295 unsigned int reg_value;
296 int gpio_value;
297
298 gpio_value = __gpio_get_value(gpio_power->axp_acin_det.gpio);
299 regmap_read(gpio_power->regmap, AXP2202_CC_STAT0, ®_value);
300 reg_value &= AXP2202_OTG_MARK;
301
302 if ((reg_value == 0x06) | (reg_value == 0x09) | (reg_value == 0x0c)) {
303 pr_info("\n\nset_otg_type: %s , %d \n", __func__, __LINE__);
304 if (!gpio_value) {
305 regmap_update_bits(gpio_power->regmap, AXP2202_MODULE_EN, AXP2202_CHARGER_ENABLE_MARK, 0);
306 pr_info("\n\nset_otg_type_disable_charger: %s , %d \n", __func__, __LINE__);
307 }
308 gpio_direction_output(gpio_power->usbid_drv.gpio, 0);
309 } else {
310 regmap_update_bits(gpio_power->regmap, AXP2202_MODULE_EN, AXP2202_CHARGER_ENABLE_MARK, AXP2202_CHARGER_ENABLE_MARK);
311 pr_info("\n\nset_no_otg_type_enable_charger: %s , %d \n", __func__, __LINE__);
312
313 gpio_direction_output(gpio_power->usbid_drv.gpio, 1);
314
315 }
316
317 schedule_delayed_work(&gpio_power->gpio_supply_mon, msecs_to_jiffies(500));
318 }
319
320
axp2202_gpio_power_init(struct axp2202_gpio_power * gpio_power)321 static void axp2202_gpio_power_init(struct axp2202_gpio_power *gpio_power)
322 {
323
324 }
325
326
axp2202_gpio_dt_parse(struct device_node * node,struct axp_config_info * axp_config)327 int axp2202_gpio_dt_parse(struct device_node *node,
328 struct axp_config_info *axp_config)
329 {
330 axp_config->wakeup_gpio =
331 of_property_read_bool(node, "wakeup_gpio");
332
333 return 0;
334 }
335
axp2202_gpio_parse_device_tree(struct axp2202_gpio_power * gpio_power)336 static void axp2202_gpio_parse_device_tree(struct axp2202_gpio_power *gpio_power)
337 {
338 int ret;
339 struct axp_config_info *cfg;
340
341 /* set input current limit */
342 if (!gpio_power->dev->of_node) {
343 pr_info("can not find device tree\n");
344 return;
345 }
346
347 cfg = &gpio_power->dts_info;
348 ret = axp2202_gpio_dt_parse(gpio_power->dev->of_node, cfg);
349 if (ret) {
350 pr_info("can not parse device tree err\n");
351 return;
352 }
353
354 /*init axp2202 gpio by device tree*/
355 axp2202_gpio_power_init(gpio_power);
356 }
357
358
axp2202_gpio_probe(struct platform_device * pdev)359 static int axp2202_gpio_probe(struct platform_device *pdev)
360 {
361 int ret = 0;
362
363 struct axp2202_gpio_power *gpio_power;
364
365 struct device_node *node = pdev->dev.of_node;
366 struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
367 struct power_supply_config psy_cfg = {};
368
369 if (!of_device_is_available(node)) {
370 pr_err("axp2202-gpio device is not configed\n");
371 return -ENODEV;
372 }
373
374 if (!axp_dev->irq) {
375 pr_err("can not register axp2202-gpio without irq\n");
376 return -EINVAL;
377 }
378
379 gpio_power = devm_kzalloc(&pdev->dev, sizeof(*gpio_power), GFP_KERNEL);
380 if (gpio_power == NULL) {
381 pr_err("axp2202_gpio_power alloc failed\n");
382 ret = -ENOMEM;
383 goto err;
384 }
385
386 gpio_power->name = "axp2202_gpio";
387 gpio_power->dev = &pdev->dev;
388 gpio_power->regmap = axp_dev->regmap;
389
390 /* parse device tree and set register */
391 axp2202_gpio_parse_device_tree(gpio_power);
392
393 psy_cfg.of_node = pdev->dev.of_node;
394 psy_cfg.drv_data = gpio_power;
395
396 gpio_power->gpio_supply = devm_power_supply_register(gpio_power->dev,
397 &axp2202_gpio_desc, &psy_cfg);
398
399 if (IS_ERR(gpio_power->gpio_supply)) {
400 pr_err("axp2202 failed to register gpio power\n");
401 ret = PTR_ERR(gpio_power->gpio_supply);
402 return ret;
403 }
404
405 gpio_power->axp_acin_det.gpio =
406 of_get_named_gpio(pdev->dev.of_node,
407 "pmu_acin_det_gpio", 0);
408
409 gpio_power->usbid_drv.gpio =
410 of_get_named_gpio(pdev->dev.of_node,
411 "pmu_acin_usbid_drv", 0);
412
413 gpio_power->axp_vbus_det.gpio =
414 of_get_named_gpio(pdev->dev.of_node,
415 "pmu_vbus_det_gpio", 0);
416
417 if (gpio_is_valid(gpio_power->axp_acin_det.gpio)) {
418 if (gpio_is_valid(gpio_power->usbid_drv.gpio)) {
419 if (gpio_is_valid(gpio_power->axp_vbus_det.gpio)) {
420 ret = axp_acin_gpio_init(gpio_power);
421 if (ret != 0)
422 pr_err("axp acin init failed\n");
423 } else {
424 pr_info("get pmu_vbus_det_gpio is fail\n");
425 }
426 } else {
427 pr_info("get pmu_acin_usbid_drv is fail\n");
428 }
429 } else {
430 pr_info("get pmu_acin_det_gpio is fail\n");
431 }
432
433 platform_set_drvdata(pdev, gpio_power);
434 printk("axp2202_gpio_probe: %s , %d \n", __func__, __LINE__);
435
436 INIT_DELAYED_WORK(&gpio_power->gpio_supply_mon, axp2202_gpio_power_monitor);
437 schedule_delayed_work(&gpio_power->gpio_supply_mon, msecs_to_jiffies(500));
438
439 return ret;
440
441 err:
442 pr_err("%s,probe fail, ret = %d\n", __func__, ret);
443
444 return ret;
445 }
446
447
axp2202_gpio_remove(struct platform_device * pdev)448 static int axp2202_gpio_remove(struct platform_device *pdev)
449 {
450 struct axp2202_gpio_power *gpio_power = platform_get_drvdata(pdev);
451
452 cancel_delayed_work_sync(&gpio_power->gpio_supply_mon);
453 cancel_delayed_work_sync(&gpio_power->gpio_chg_state);
454
455 dev_dbg(&pdev->dev, "==============AXP2202 gpio unegister==============\n");
456 if (gpio_power->gpio_supply)
457 power_supply_unregister(gpio_power->gpio_supply);
458 dev_dbg(&pdev->dev, "axp2202 teardown gpio dev\n");
459
460 return 0;
461 }
462
463
464
axp2202_gpio_irq_set(unsigned int irq,bool enable)465 static inline void axp2202_gpio_irq_set(unsigned int irq, bool enable)
466 {
467 if (enable)
468 enable_irq(irq);
469 else
470 disable_irq(irq);
471 }
472
axp2202_gpio_virq_dts_set(struct axp2202_gpio_power * gpio_power,bool enable)473 static void axp2202_gpio_virq_dts_set(struct axp2202_gpio_power *gpio_power, bool enable)
474 {
475 struct axp_config_info *dts_info = &gpio_power->dts_info;
476
477 if (!dts_info->wakeup_gpio)
478 axp2202_gpio_irq_set(axp_gpio_irq[AXP2202_VIRQ_GPIO].irq,
479 enable);
480 }
481
axp2202_gpio_suspend(struct platform_device * p,pm_message_t state)482 static int axp2202_gpio_suspend(struct platform_device *p, pm_message_t state)
483 {
484 struct axp2202_gpio_power *gpio_power = platform_get_drvdata(p);
485
486
487 axp2202_gpio_virq_dts_set(gpio_power, false);
488 return 0;
489 }
490
axp2202_gpio_resume(struct platform_device * p)491 static int axp2202_gpio_resume(struct platform_device *p)
492 {
493 struct axp2202_gpio_power *gpio_power = platform_get_drvdata(p);
494
495
496 axp2202_gpio_virq_dts_set(gpio_power, true);
497
498 return 0;
499 }
500
501 static const struct of_device_id axp2202_gpio_power_match[] = {
502 {
503 .compatible = "x-powers,gpio-supply",
504 .data = (void *)AXP2202_ID,
505 }, {/* sentinel */}
506 };
507 MODULE_DEVICE_TABLE(of, axp2202_gpio_power_match);
508
509 static struct platform_driver axp2202_gpio_power_driver = {
510 .driver = {
511 .name = "gpio-supply",
512 .of_match_table = axp2202_gpio_power_match,
513 },
514 .probe = axp2202_gpio_probe,
515 .remove = axp2202_gpio_remove,
516 .suspend = axp2202_gpio_suspend,
517 .resume = axp2202_gpio_resume,
518 };
519
520 module_platform_driver(axp2202_gpio_power_driver);
521
522 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
523 MODULE_DESCRIPTION("axp2202 gpio driver");
524 MODULE_LICENSE("GPL");
525
526