• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "power/axp2101.h"
30 
31 #include <linux/err.h>
32 //#include "../drivers/gpio/gpiolib.h"
33 #include "axp2202_charger.h"
34 
35 struct axp2202_usb_power {
36 	char                      *name;
37 	struct device             *dev;
38 	struct regmap             *regmap;
39 	struct power_supply       *usb_supply;
40 	struct axp_config_info  dts_info;
41 	struct delayed_work        usb_supply_mon;
42 	struct delayed_work        usb_chg_state;
43 
44 	atomic_t set_current_limit;
45 };
46 
47 static enum power_supply_property axp2202_usb_props[] = {
48 	POWER_SUPPLY_PROP_PRESENT,
49 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
50 	POWER_SUPPLY_PROP_MANUFACTURER,
51 	POWER_SUPPLY_PROP_ONLINE,
52 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
53 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
54 
55 };
56 
57 
58 
axp2202_get_vbus_vol(struct power_supply * ps,union power_supply_propval * val)59 static int axp2202_get_vbus_vol(struct power_supply *ps,
60 			     union power_supply_propval *val)
61 {
62 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
63 	struct regmap *regmap = usb_power->regmap;
64 
65 	uint8_t data[2];
66 	uint16_t vol;
67 	int ret = 0;
68 
69 	ret = regmap_bulk_read(regmap, AXP2202_VBUS_H, data, 2);
70 	if (ret < 0)
71 		return ret;
72 	vol = (((data[0] & GENMASK(5, 0)) << 8) | (data[1])); /* mA */
73 	val->intval = vol;
74 
75 	return 0;
76 }
77 
axp2202_get_vbus_online(struct power_supply * ps,union power_supply_propval * val)78 static int axp2202_get_vbus_online(struct power_supply *ps,
79 				   union power_supply_propval *val)
80 {
81 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
82 	struct regmap *regmap = usb_power->regmap;
83 
84 	unsigned int data;
85 	int ret = 0;
86 
87 	ret = regmap_read(regmap, AXP2202_COMM_STAT0, &data);
88 	if (ret < 0)
89 		return ret;
90 
91 	if (data & AXP2202_MASK_VBUS_STAT)
92 		val->intval = 1;
93 	else
94 		val->intval = 0;
95 
96 	return ret;
97 }
98 
axp2202_get_vbus_state(struct power_supply * ps,union power_supply_propval * val)99 static int axp2202_get_vbus_state(struct power_supply *ps,
100 				   union power_supply_propval *val)
101 {
102 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
103 	struct regmap *regmap = usb_power->regmap;
104 	unsigned int data;
105 	int ret = 0;
106 
107 	ret = regmap_read(regmap, AXP2202_COMM_STAT0, &data);
108 	if (ret < 0)
109 		return ret;
110 
111 	/* vbus is good when vbus state set */
112 	val->intval = !!(data & AXP2202_MASK_VBUS_STAT);
113 
114 	return ret;
115 }
116 
axp2202_get_iin_limit(struct power_supply * ps,union power_supply_propval * val)117 static int axp2202_get_iin_limit(struct power_supply *ps,
118 				   union power_supply_propval *val)
119 {
120 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
121 	struct regmap *regmap = usb_power->regmap;
122 	unsigned int data;
123 	int ret = 0;
124 
125 	ret = regmap_read(regmap, AXP2202_IIN_LIM, &data);
126 	if (ret < 0)
127 		return ret;
128 
129 	data = (data * 50) + 100;
130 	val->intval = data;
131 
132 	return ret;
133 }
134 
135 
axp2202_get_vindpm(struct power_supply * ps,union power_supply_propval * val)136 static int axp2202_get_vindpm(struct power_supply *ps,
137 				   union power_supply_propval *val)
138 {
139 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
140 	struct regmap *regmap = usb_power->regmap;
141 	unsigned int data;
142 	int ret = 0;
143 
144 	ret = regmap_read(regmap, AXP2202_VINDPM_CFG, &data);
145 	if (ret < 0)
146 		return ret;
147 
148 	data = (data * 80) + 3880;
149 	val->intval = data;
150 
151 	return ret;
152 }
153 
axp2202_get_usb_type(struct power_supply * ps,union power_supply_propval * val)154 static int axp2202_get_usb_type(struct power_supply *ps,
155 				   union power_supply_propval *val)
156 {
157 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
158 	struct axp_config_info *dinfo = &usb_power->dts_info;
159 	int ret = 0;
160 
161 	if (dinfo->pmu_usb_typec_used)
162 		val->intval = POWER_SUPPLY_TYPE_USB_TYPE_C;
163 	else
164 		val->intval = POWER_SUPPLY_TYPE_USB;
165 
166 	return ret;
167 }
168 
axp2202_get_cc_status(struct power_supply * ps,union power_supply_propval * val)169 static int axp2202_get_cc_status(struct power_supply *ps,
170 				   union power_supply_propval *val)
171 {
172 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(ps);
173 	struct axp_config_info *dinfo = &usb_power->dts_info;
174 	struct regmap *regmap = usb_power->regmap;
175 	unsigned int data;
176 	int ret = 0;
177 
178 	if (!dinfo->pmu_usb_typec_used) {
179 		val->intval = POWER_SUPPLY_SCOPE_UNKNOWN;
180 		return ret;
181 	}
182 
183 	ret = regmap_read(regmap, AXP2202_CC_STAT0, &data);
184 	if (ret < 0)
185 		return ret;
186 
187 	data &= 0x0f;
188 
189 	if (data == 5 || data == 6 || data == 9 || data == 12) {
190 		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;//source/host
191 	} else if (data == 2 || data == 3 || data == 10 || data == 11) {
192 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;//sink/
193 	} else {
194 		val->intval = POWER_SUPPLY_SCOPE_UNKNOWN;//disable
195 	}
196 
197 	return ret;
198 }
199 
axp2202_set_iin_limit(struct regmap * regmap,int mA)200 static int axp2202_set_iin_limit(struct regmap *regmap, int mA)
201 {
202 	unsigned int data;
203 	int ret = 0;
204 
205 	data = mA;
206 
207 	if (data > 3250)
208 		data = 3250;
209 	if	(data < 100)
210 		data = 100;
211 	data = ((data - 100) / 50);
212 	ret = regmap_update_bits(regmap, AXP2202_IIN_LIM, GENMASK(5, 0),
213 				 data);
214 	if (ret < 0)
215 		return ret;
216 
217 	return 0;
218 }
219 
220 
axp2202_set_vindpm(struct regmap * regmap,int mV)221 static int axp2202_set_vindpm(struct regmap *regmap, int mV)
222 {
223 	unsigned int data;
224 	int ret = 0;
225 
226 	data = mV;
227 
228 	if (data > 5080)
229 		data = 5080;
230 	if	(data < 3880)
231 		data = 3880;
232 	data = ((data - 3880) / 80);
233 	ret = regmap_update_bits(regmap, AXP2202_VINDPM_CFG, GENMASK(3, 0),
234 				 data);
235 	if (ret < 0)
236 		return ret;
237 
238 	return 0;
239 }
240 
axp2202_usb_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)241 static int axp2202_usb_get_property(struct power_supply *psy,
242 				       enum power_supply_property psp,
243 				       union power_supply_propval *val)
244 {
245 	int ret = 0;
246 
247 	switch (psp) {
248 	case POWER_SUPPLY_PROP_ONLINE:
249 		ret = axp2202_get_vbus_online(psy, val);
250 		break;
251 	case POWER_SUPPLY_PROP_PRESENT:
252 		ret = axp2202_get_vbus_state(psy, val);
253 		break;
254 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
255 		ret = axp2202_get_vbus_vol(psy, val);
256 		break;
257 	case POWER_SUPPLY_PROP_MANUFACTURER:
258 		val->strval = AXP2202_MANUFACTURER;
259 		break;
260 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
261 		ret = axp2202_get_iin_limit(psy, val);
262 		break;
263 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
264 		ret = axp2202_get_vindpm(psy, val);
265 		break;
266 	case POWER_SUPPLY_PROP_USB_TYPE:
267 		ret = axp2202_get_usb_type(psy, val);
268 		break;
269 	case POWER_SUPPLY_PROP_SCOPE:
270 		ret = axp2202_get_cc_status(psy, val);
271 		break;
272 	default:
273 		break;
274 	}
275 
276 	return ret;
277 }
278 
axp2202_usb_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)279 static int axp2202_usb_set_property(struct power_supply *psy,
280 				enum power_supply_property psp,
281 				const union power_supply_propval *val)
282 {
283 	struct axp2202_usb_power *usb_power = power_supply_get_drvdata(psy);
284 	struct regmap *regmap = usb_power->regmap;
285 	int ret = 0;
286 
287 	switch (psp) {
288 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
289 		ret = axp2202_set_iin_limit(regmap, val->intval);
290 		atomic_set(&usb_power->set_current_limit, 1);
291 		break;
292 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
293 		ret = axp2202_set_vindpm(regmap, val->intval);
294 		break;
295 	default:
296 		ret = -EINVAL;
297 	}
298 	return ret;
299 }
300 
axp2202_usb_power_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)301 static int axp2202_usb_power_property_is_writeable(struct power_supply *psy,
302 			     enum power_supply_property psp)
303 {
304 	int ret = 0;
305 	switch (psp) {
306 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
307 		ret = 0;
308 		break;
309 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
310 		ret = 0;
311 		break;
312 	default:
313 		ret = -EINVAL;
314 	}
315 	return ret;
316 
317 }
318 
319 static const struct power_supply_desc axp2202_usb_desc = {
320 	.name = "axp2202-usb",
321 	.type = POWER_SUPPLY_TYPE_USB,
322 	.get_property = axp2202_usb_get_property,
323 	.properties = axp2202_usb_props,
324 	.set_property = axp2202_usb_set_property,
325 	.num_properties = ARRAY_SIZE(axp2202_usb_props),
326 	.property_is_writeable = axp2202_usb_power_property_is_writeable,
327 };
328 
329 
axp2202_irq_handler_usb_in(int irq,void * data)330 static irqreturn_t axp2202_irq_handler_usb_in(int irq, void *data)
331 {
332 	struct axp2202_usb_power *usb_power = data;
333 	struct axp_config_info *axp_config = &usb_power->dts_info;
334 
335 	power_supply_changed(usb_power->usb_supply);
336 
337 	if (!axp_config->pmu_bc12_en) {
338 		axp2202_set_iin_limit(usb_power->regmap, axp_config->pmu_usbpc_cur);
339 		atomic_set(&usb_power->set_current_limit, 0);
340 		cancel_delayed_work_sync(&usb_power->usb_chg_state);
341 		schedule_delayed_work(&usb_power->usb_chg_state, msecs_to_jiffies(5 * 1000));
342 	}
343 
344 	return IRQ_HANDLED;
345 }
346 
axp2202_irq_handler_usb_out(int irq,void * data)347 static irqreturn_t axp2202_irq_handler_usb_out(int irq, void *data)
348 {
349 	struct axp2202_usb_power *usb_power = data;
350 
351 	power_supply_changed(usb_power->usb_supply);
352 
353 	return IRQ_HANDLED;
354 }
355 
356 enum axp2202_usb_virq_index {
357 	AXP2202_VIRQ_USB_IN,
358 	AXP2202_VIRQ_USB_OUT,
359 
360 	AXP2202_USB_VIRQ_MAX_VIRQ,
361 };
362 
363 static struct axp_interrupts axp_usb_irq[] = {
364 	[AXP2202_VIRQ_USB_IN] = { "vbus_insert", axp2202_irq_handler_usb_in },
365 	[AXP2202_VIRQ_USB_OUT] = { "vbus_remove", axp2202_irq_handler_usb_out },
366 };
367 
368 
369 
axp2202_usb_power_monitor(struct work_struct * work)370 static void axp2202_usb_power_monitor(struct work_struct *work)
371 {
372 	struct axp2202_usb_power *usb_power =
373 		container_of(work, typeof(*usb_power), usb_supply_mon.work);
374 
375 	schedule_delayed_work(&usb_power->usb_supply_mon, msecs_to_jiffies(500));
376 }
377 
378 
379 
axp2202_usb_set_current_fsm(struct work_struct * work)380 static void axp2202_usb_set_current_fsm(struct work_struct *work)
381 {
382 	struct axp2202_usb_power *usb_power =
383 		container_of(work, typeof(*usb_power), usb_chg_state.work);
384 	struct axp_config_info *axp_config = &usb_power->dts_info;
385 
386 	if (atomic_read(&usb_power->set_current_limit)) {
387 		pr_info("current limit setted: usb pc type\n");
388 	} else {
389 		axp2202_set_iin_limit(usb_power->regmap, axp_config->pmu_usbad_cur);
390 		pr_info("current limit not set: usb adapter type\n");
391 	}
392 }
393 
394 
395 
axp2202_usb_power_init(struct axp2202_usb_power * usb_power)396 static void axp2202_usb_power_init(struct axp2202_usb_power *usb_power)
397 {
398 	struct regmap *regmap = usb_power->regmap;
399 	struct axp_config_info *dinfo = &usb_power->dts_info;
400 
401 	unsigned int data = 0;
402 
403 	/* set vindpm value */
404 	axp2202_set_vindpm(regmap, dinfo->pmu_usbad_vol);
405 
406 	/* set bc12 en/disable  */
407 	if (dinfo->pmu_bc12_en) {
408 		regmap_update_bits(regmap, AXP2202_CLK_EN, BIT(4), BIT(4));
409 		regmap_update_bits(regmap, AXP2202_IIN_LIM, BIT(7), 0);
410 	} else {
411 		regmap_update_bits(regmap, AXP2202_CLK_EN, BIT(4), 0);
412 		regmap_update_bits(regmap, AXP2202_IIN_LIM, BIT(7), BIT(7));
413 	}
414 
415 	/* set cc logic en/disable  */
416 	if (dinfo->pmu_cc_logic_en)
417 		regmap_update_bits(regmap, AXP2202_CLK_EN, BIT(3), BIT(3));
418 	else
419 		regmap_update_bits(regmap, AXP2202_CLK_EN, BIT(3), 0);
420 
421 	/* set boost vol  */
422 	data = (dinfo->pmu_boost_vol - 4550) / 64;
423 	regmap_update_bits(regmap, AXP2202_BST_CFG0, GENMASK(7, 4), data << 4);
424 	regmap_write(regmap, AXP2202_BST_CFG1, 0x03);
425 
426 	/* set type-c en/disable & mode */
427 	if (dinfo->pmu_usb_typec_used) {
428 		regmap_update_bits(regmap, AXP2202_CC_GLB_CTRL, BIT(2), 0);
429 		regmap_update_bits(regmap, AXP2202_CC_MODE_CTRL, BIT(1), BIT(1));
430 		regmap_update_bits(regmap, AXP2202_CC_MODE_CTRL, BIT(0), BIT(0));
431 	} else {
432 		regmap_update_bits(regmap, AXP2202_CC_MODE_CTRL, BIT(1), 0);
433 		regmap_update_bits(regmap, AXP2202_CC_MODE_CTRL, BIT(0), 0);
434 	}
435 }
436 
437 
axp2202_usb_dt_parse(struct device_node * node,struct axp_config_info * axp_config)438 int axp2202_usb_dt_parse(struct device_node *node,
439 			 struct axp_config_info *axp_config)
440 {
441 	if (!of_device_is_available(node)) {
442 		pr_err("%s: failed\n", __func__);
443 		return -1;
444 	}
445 
446 
447 	AXP_OF_PROP_READ(pmu_usbpc_vol,                    4600);
448 	AXP_OF_PROP_READ(pmu_usbpc_cur,                    500);
449 	AXP_OF_PROP_READ(pmu_usbad_vol,                    4600);
450 	AXP_OF_PROP_READ(pmu_usbad_cur,                    1500);
451 	AXP_OF_PROP_READ(pmu_bc12_en,                         0);
452 	AXP_OF_PROP_READ(pmu_cc_logic_en,                     1);
453 	AXP_OF_PROP_READ(pmu_boost_en,                        0);
454 	AXP_OF_PROP_READ(pmu_boost_vol,                    5126);
455 	AXP_OF_PROP_READ(pmu_usb_typec_used,                  0);
456 
457 	axp_config->wakeup_usb_in =
458 		of_property_read_bool(node, "wakeup_usb_in");
459 	axp_config->wakeup_usb_out =
460 		of_property_read_bool(node, "wakeup_usb_out");
461 
462 	return 0;
463 }
464 
axp2202_usb_parse_device_tree(struct axp2202_usb_power * usb_power)465 static void axp2202_usb_parse_device_tree(struct axp2202_usb_power *usb_power)
466 {
467 	int ret;
468 	struct axp_config_info *cfg;
469 
470 	/* set input current limit */
471 	if (!usb_power->dev->of_node) {
472 		pr_info("can not find device tree\n");
473 		return;
474 	}
475 
476 	cfg = &usb_power->dts_info;
477 	ret = axp2202_usb_dt_parse(usb_power->dev->of_node, cfg);
478 	if (ret) {
479 		pr_info("can not parse device tree err\n");
480 		return;
481 	}
482 
483 	/*init axp2202 usb by device tree*/
484 	axp2202_usb_power_init(usb_power);
485 }
486 
487 
axp2202_usb_probe(struct platform_device * pdev)488 static int axp2202_usb_probe(struct platform_device *pdev)
489 {
490 	int ret = 0;
491 	int i = 0, irq;
492 
493 	struct axp2202_usb_power *usb_power;
494 
495 	struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
496 	struct power_supply_config psy_cfg = {};
497 
498 	if (!axp_dev->irq) {
499 		pr_err("can not register axp2202-usb without irq\n");
500 		return -EINVAL;
501 	}
502 
503 	usb_power = devm_kzalloc(&pdev->dev, sizeof(*usb_power), GFP_KERNEL);
504 	if (usb_power == NULL) {
505 		pr_err("axp2202_usb_power alloc failed\n");
506 		ret = -ENOMEM;
507 		goto err;
508 	}
509 
510 	usb_power->name = "axp2202_usb";
511 	usb_power->dev = &pdev->dev;
512 	usb_power->regmap = axp_dev->regmap;
513 
514 	/* parse device tree and set register */
515 	axp2202_usb_parse_device_tree(usb_power);
516 
517 	psy_cfg.of_node = pdev->dev.of_node;
518 	psy_cfg.drv_data = usb_power;
519 
520 	usb_power->usb_supply = devm_power_supply_register(usb_power->dev,
521 			&axp2202_usb_desc, &psy_cfg);
522 
523 	if (IS_ERR(usb_power->usb_supply)) {
524 		pr_err("axp2202 failed to register usb power\n");
525 		ret = PTR_ERR(usb_power->usb_supply);
526 		return ret;
527 	}
528 
529 	for (i = 0; i < ARRAY_SIZE(axp_usb_irq); i++) {
530 		irq = platform_get_irq_byname(pdev, axp_usb_irq[i].name);
531 		if (irq < 0)
532 			continue;
533 
534 		irq = regmap_irq_get_virq(axp_dev->regmap_irqc, irq);
535 		if (irq < 0) {
536 			dev_err(&pdev->dev, "can not get irq\n");
537 			return irq;
538 		}
539 		/* we use this variable to suspend irq */
540 		axp_usb_irq[i].irq = irq;
541 		ret = devm_request_any_context_irq(&pdev->dev, irq,
542 						   axp_usb_irq[i].isr, 0,
543 						   axp_usb_irq[i].name, usb_power);
544 		if (ret < 0) {
545 			dev_err(&pdev->dev, "failed to request %s IRQ %d: %d\n",
546 				axp_usb_irq[i].name, irq, ret);
547 			return ret;
548 		} else {
549 			ret = 0;
550 		}
551 
552 		dev_dbg(&pdev->dev, "Requested %s IRQ %d: %d\n",
553 			axp_usb_irq[i].name, irq, ret);
554 	}
555 	platform_set_drvdata(pdev, usb_power);
556 
557 	if (!usb_power->dts_info.pmu_bc12_en) {
558 		INIT_DELAYED_WORK(&usb_power->usb_supply_mon, axp2202_usb_power_monitor);
559 		schedule_delayed_work(&usb_power->usb_supply_mon, msecs_to_jiffies(500));
560 
561 		INIT_DELAYED_WORK(&usb_power->usb_chg_state, axp2202_usb_set_current_fsm);
562 		schedule_delayed_work(&usb_power->usb_chg_state, msecs_to_jiffies(20 * 1000));
563 	}
564 
565 	return ret;
566 
567 
568 err:
569 	pr_err("%s,probe fail, ret = %d\n", __func__, ret);
570 
571 	return ret;
572 }
573 
axp2202_usb_remove(struct platform_device * pdev)574 static int axp2202_usb_remove(struct platform_device *pdev)
575 {
576 	struct axp2202_usb_power *usb_power = platform_get_drvdata(pdev);
577 
578 	cancel_delayed_work_sync(&usb_power->usb_supply_mon);
579 	cancel_delayed_work_sync(&usb_power->usb_chg_state);
580 
581 	dev_dbg(&pdev->dev, "==============AXP2202 usb unegister==============\n");
582 	if (usb_power->usb_supply)
583 		power_supply_unregister(usb_power->usb_supply);
584 	dev_dbg(&pdev->dev, "axp2202 teardown usb dev\n");
585 
586 	return 0;
587 }
588 
589 
590 
axp2202_usb_irq_set(unsigned int irq,bool enable)591 static inline void axp2202_usb_irq_set(unsigned int irq, bool enable)
592 {
593 	if (enable)
594 		enable_irq(irq);
595 	else
596 		disable_irq(irq);
597 }
598 
axp2202_usb_virq_dts_set(struct axp2202_usb_power * usb_power,bool enable)599 static void axp2202_usb_virq_dts_set(struct axp2202_usb_power *usb_power, bool enable)
600 {
601 	struct axp_config_info *dts_info = &usb_power->dts_info;
602 
603 	if (!dts_info->wakeup_usb_in)
604 		axp2202_usb_irq_set(axp_usb_irq[AXP2202_VIRQ_USB_IN].irq,
605 				enable);
606 	if (!dts_info->wakeup_usb_out)
607 		axp2202_usb_irq_set(axp_usb_irq[AXP2202_VIRQ_USB_OUT].irq,
608 				enable);
609 
610 }
611 
612 
613 
axp2202_usb_suspend(struct platform_device * p,pm_message_t state)614 static int axp2202_usb_suspend(struct platform_device *p, pm_message_t state)
615 {
616 	struct axp2202_usb_power *usb_power = platform_get_drvdata(p);
617 
618 
619 	axp2202_usb_virq_dts_set(usb_power, false);
620 	return 0;
621 }
622 
axp2202_usb_resume(struct platform_device * p)623 static int axp2202_usb_resume(struct platform_device *p)
624 {
625 	struct axp2202_usb_power *usb_power = platform_get_drvdata(p);
626 
627 
628 	axp2202_usb_virq_dts_set(usb_power, true);
629 
630 	return 0;
631 }
632 
633 static const struct of_device_id axp2202_usb_power_match[] = {
634 	{
635 		.compatible = "x-powers,axp2202-usb-power-supply",
636 		.data = (void *)AXP2202_ID,
637 	}, {/* sentinel */}
638 };
639 MODULE_DEVICE_TABLE(of, axp2202_usb_power_match);
640 
641 static struct platform_driver axp2202_usb_power_driver = {
642 	.driver = {
643 		.name = "axp2202-usb-power-supply",
644 		.of_match_table = axp2202_usb_power_match,
645 	},
646 	.probe = axp2202_usb_probe,
647 	.remove = axp2202_usb_remove,
648 	.suspend = axp2202_usb_suspend,
649 	.resume = axp2202_usb_resume,
650 };
651 
652 module_platform_driver(axp2202_usb_power_driver);
653 
654 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
655 MODULE_DESCRIPTION("axp2202 usb driver");
656 MODULE_LICENSE("GPL");
657 
658