• 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/slab.h>
7 #include <linux/interrupt.h>
8 #include <linux/device.h>
9 #include <linux/mutex.h>
10 #include <linux/param.h>
11 #include <linux/jiffies.h>
12 #include <linux/platform_device.h>
13 #include <linux/power_supply.h>
14 #include <linux/fs.h>
15 #include <linux/ktime.h>
16 #include <linux/of.h>
17 #include <linux/timekeeping.h>
18 #include <linux/types.h>
19 #include <linux/string.h>
20 #include <asm/irq.h>
21 #include <linux/cdev.h>
22 #include <linux/delay.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/gpio/consumer.h>
25 #include <linux/kthread.h>
26 #include <linux/freezer.h>
27 #include <linux/err.h>
28 #include "power/axp2101.h"
29 #include "axp803_charger.h"
30 
31 struct axp803_usb_power {
32 	char                      *name;
33 	struct device             *dev;
34 	struct axp_config_info     dts_info;
35 	struct regmap             *regmap;
36 	struct power_supply       *usb_supply;
37 	struct delayed_work        usb_supply_mon;
38 	struct delayed_work        usb_chg_state;
39 
40 	atomic_t set_current_limit;
41 };
42 
43 #ifdef CONFIG_AW_AXP_BC_EN
axp803_usb_set_ihold(struct axp803_usb_power * usb_power,int cur)44 static int axp803_usb_set_ihold(struct axp803_usb_power *usb_power, int cur)
45 {
46 	struct regmap *map = usb_power->regmap;
47 
48 	if (cur) {
49 		if (cur < 1500)
50 			regmap_update_bits(map, AXP803_IPS_SET, 0x03, 0x00);
51 		else if (cur >= 1500 && cur < 2000)
52 			regmap_update_bits(map, AXP803_IPS_SET, 0x03, 0x01);
53 		else if (cur >= 2000 && cur < 2500)
54 			regmap_update_bits(map, AXP803_IPS_SET, 0x03, 0x02);
55 		else
56 			regmap_update_bits(map, AXP803_IPS_SET, 0x03, 0x03);
57 	} else {
58 		regmap_update_bits(map, AXP803_IPS_SET, 0x03, 0x03);
59 	}
60 
61 	return 0;
62 }
63 
axp803_usb_get_ihold(struct axp803_usb_power * usb_power)64 static int axp803_usb_get_ihold(struct axp803_usb_power *usb_power)
65 {
66 	unsigned int tmp;
67 	struct regmap *map = usb_power->regmap;
68 
69 	regmap_read(map, AXP803_IPS_SET, &tmp);
70 	tmp = tmp & 0x3;
71 	if (tmp == 0x0)
72 		return 900;
73 	else if (tmp == 0x1)
74 		return 1500;
75 	else if (tmp == 0x2)
76 		return 2000;
77 	else
78 		return 2500;
79 }
80 #else
axp803_usb_set_ihold(struct axp803_usb_power * usb_power,int cur)81 static int axp803_usb_set_ihold(struct axp803_usb_power *usb_power, int cur)
82 {
83 	struct regmap *map = usb_power->regmap;
84 
85 	if (cur) {
86 		if (cur < 500)
87 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x00);
88 		else if (cur < 900)
89 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x10);
90 		else if (cur < 1500)
91 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x20);
92 		else if (cur < 2000)
93 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x30);
94 		else if (cur < 2500)
95 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x40);
96 		else if (cur < 3000)
97 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x50);
98 		else if (cur < 3500)
99 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x60);
100 		else if (cur < 4000)
101 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x70);
102 		else
103 			regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x80);
104 	} else {
105 		regmap_update_bits(map, AXP803_CHARGE3, 0xf0, 0x30);
106 	}
107 
108 	return 0;
109 }
110 
axp803_usb_get_ihold(struct axp803_usb_power * usb_power)111 static int axp803_usb_get_ihold(struct axp803_usb_power *usb_power)
112 {
113 	unsigned int tmp;
114 	struct regmap *map = usb_power->regmap;
115 
116 	regmap_read(map, AXP803_CHARGE3, &tmp);
117 	tmp = tmp & 0xf0;
118 	if (tmp == 0x00)
119 		return 100;
120 	else if (tmp == 0x10)
121 		return 500;
122 	else if (tmp == 0x20)
123 		return 900;
124 	else if (tmp == 0x30)
125 		return 1500;
126 	else if (tmp == 0x40)
127 		return 2000;
128 	else if (tmp == 0x50)
129 		return 2500;
130 	else if (tmp == 0x60)
131 		return 3000;
132 	else if (tmp == 0x70)
133 		return 3500;
134 	else
135 		return 4000;
136 }
137 #endif
138 
axp803_usb_set_current_fsm(struct work_struct * work)139 static void axp803_usb_set_current_fsm(struct work_struct *work)
140 {
141 	struct axp803_usb_power *usb_power =
142 		container_of(work, typeof(*usb_power), usb_chg_state.work);
143 	struct axp_config_info *axp_config = &usb_power->dts_info;
144 
145 	if (atomic_read(&usb_power->set_current_limit)) {
146 		pr_info("current limit setted: usb pc type\n");
147 	} else {
148 		axp803_usb_set_ihold(usb_power, axp_config->pmu_usbad_cur);
149 		pr_info("current limit not set: usb adapter type\n");
150 	}
151 }
152 
153 static enum power_supply_property axp803_usb_props[] = {
154 	POWER_SUPPLY_PROP_MODEL_NAME,
155 	POWER_SUPPLY_PROP_PRESENT,
156 	POWER_SUPPLY_PROP_ONLINE,
157 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
158 };
159 
axp803_usb_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)160 static int axp803_usb_get_property(struct power_supply *psy,
161 					enum power_supply_property psp,
162 					union power_supply_propval *val)
163 {
164 	int ret = 0;
165 	unsigned int reg_value;
166 	struct axp803_usb_power *usb_power = power_supply_get_drvdata(psy);
167 
168 	switch (psp) {
169 	case POWER_SUPPLY_PROP_MODEL_NAME:
170 		val->strval = psy->desc->name;
171 		break;
172 	case POWER_SUPPLY_PROP_PRESENT:
173 		ret = regmap_read(usb_power->regmap, AXP803_STATUS, &reg_value);
174 		if (ret)
175 			return ret;
176 		val->intval = !!(reg_value & AXP803_STATUS_VBUS_PRESENT);
177 		break;
178 	case POWER_SUPPLY_PROP_ONLINE:
179 		ret = regmap_read(usb_power->regmap, AXP803_STATUS, &reg_value);
180 		if (ret)
181 			return ret;
182 		val->intval = !!(reg_value & AXP803_STATUS_VBUS_USED);
183 		break;
184 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
185 		ret = axp803_usb_get_ihold(usb_power);
186 		if (ret < 0)
187 			return ret;
188 		val->intval = ret;
189 		break;
190 	default:
191 		ret = -EINVAL;
192 		break;
193 	}
194 
195 	return ret;
196 }
197 
axp803_usb_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)198 static int axp803_usb_set_property(struct power_supply *psy,
199 				    enum power_supply_property psp,
200 				    const union power_supply_propval *val)
201 {
202 	int ret = 0;
203 	struct axp803_usb_power *usb_power = power_supply_get_drvdata(psy);
204 
205 	switch (psp) {
206 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
207 		ret = axp803_usb_set_ihold(usb_power, val->intval);
208 		atomic_set(&usb_power->set_current_limit, 1);
209 		break;
210 	default:
211 		ret = -EINVAL;
212 	}
213 
214 	return ret;
215 }
216 
axp803_usb_power_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)217 static int axp803_usb_power_property_is_writeable(struct power_supply *psy,
218 		enum power_supply_property psp)
219 {
220 	int ret;
221 
222 	switch (psp) {
223 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
224 		ret = 1;
225 		break;
226 	default:
227 		ret = 0;
228 	}
229 
230 	return ret;
231 }
232 
233 static const struct power_supply_desc axp803_usb_desc = {
234 	.name = "axp803-usb",
235 	.type = POWER_SUPPLY_TYPE_USB,
236 	.get_property = axp803_usb_get_property,
237 	.properties = axp803_usb_props,
238 	.set_property = axp803_usb_set_property,
239 	.num_properties = ARRAY_SIZE(axp803_usb_props),
240 	.property_is_writeable = axp803_usb_power_property_is_writeable,
241 };
242 
axp803_usb_power_init(struct axp803_usb_power * usb_power)243 static int axp803_usb_power_init(struct axp803_usb_power *usb_power)
244 {
245 	struct axp_config_info *axp_config = &usb_power->dts_info;
246 
247 	axp803_usb_set_ihold(usb_power, axp_config->pmu_usbad_cur);
248 
249 	return 0;
250 }
251 
axp803_usb_power_in_irq(int irq,void * data)252 static irqreturn_t axp803_usb_power_in_irq(int irq, void *data)
253 {
254 	struct axp803_usb_power *usb_power = data;
255 	struct axp_config_info *axp_config = &usb_power->dts_info;
256 
257 	power_supply_changed(usb_power->usb_supply);
258 
259 	axp803_usb_set_ihold(usb_power, axp_config->pmu_usbpc_cur);
260 	atomic_set(&usb_power->set_current_limit, 0);
261 
262 	cancel_delayed_work_sync(&usb_power->usb_chg_state);
263 	schedule_delayed_work(&usb_power->usb_chg_state, msecs_to_jiffies(5 * 1000));
264 
265 	return IRQ_HANDLED;
266 }
267 
axp803_usb_power_out_irq(int irq,void * data)268 static irqreturn_t axp803_usb_power_out_irq(int irq, void *data)
269 {
270 	struct axp803_usb_power *usb_power = data;
271 
272 	power_supply_changed(usb_power->usb_supply);
273 
274 	return IRQ_HANDLED;
275 }
276 
277 enum axp803_usb_power_virqs {
278 	AXP803_VIRQ_USBIN,
279 	AXP803_VIRQ_USBRE,
280 
281 	AXP803_USB_VIRQ_MAX_VIRQ,
282 };
283 
284 static struct axp_interrupts axp803_usb_irq[] = {
285 	[AXP803_VIRQ_USBIN] = {"usb in", axp803_usb_power_in_irq},
286 	[AXP803_VIRQ_USBRE] = {"usb out", axp803_usb_power_out_irq},
287 };
288 
axp803_usb_power_monitor(struct work_struct * work)289 static void axp803_usb_power_monitor(struct work_struct *work)
290 {
291 	struct axp803_usb_power *usb_power =
292 		container_of(work, typeof(*usb_power), usb_supply_mon.work);
293 
294 	schedule_delayed_work(&usb_power->usb_supply_mon, msecs_to_jiffies(500));
295 }
296 
axp803_usb_power_dt_parse(struct axp803_usb_power * usb_power)297 static int axp803_usb_power_dt_parse(struct axp803_usb_power *usb_power)
298 {
299 	struct axp_config_info *axp_config = &usb_power->dts_info;
300 	struct device_node *node = usb_power->dev->of_node;
301 
302 	if (!of_device_is_available(node)) {
303 		pr_err("%s: failed\n", __func__);
304 		return -1;
305 	}
306 
307 	AXP_OF_PROP_READ(pmu_usbpc_vol,                  4400);
308 	AXP_OF_PROP_READ(pmu_usbpc_cur,                     0);
309 	AXP_OF_PROP_READ(pmu_usbad_vol,                  4400);
310 	AXP_OF_PROP_READ(pmu_usbad_cur,                     0);
311 
312 	axp_config->wakeup_usb_in =
313 		of_property_read_bool(node, "wakeup_usb_in");
314 	axp_config->wakeup_usb_out =
315 		of_property_read_bool(node, "wakeup_usb_out");
316 
317 	return 0;
318 }
319 
axp803_usb_power_probe(struct platform_device * pdev)320 static int axp803_usb_power_probe(struct platform_device *pdev)
321 {
322 	struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
323 	struct power_supply_config psy_cfg = {};
324 	struct axp803_usb_power *usb_power;
325 	int i, irq;
326 	int ret = 0;
327 
328 	if (!axp_dev->irq) {
329 		pr_err("can not register axp803 usb without irq\n");
330 		return -EINVAL;
331 	}
332 
333 	usb_power = devm_kzalloc(&pdev->dev, sizeof(*usb_power), GFP_KERNEL);
334 	if (!usb_power) {
335 		pr_err("axp803 usb power alloc failed\n");
336 		ret = -ENOMEM;
337 		return ret;
338 	}
339 
340 	usb_power->name = "axp803-usb-power";
341 	usb_power->dev = &pdev->dev;
342 	usb_power->regmap = axp_dev->regmap;
343 
344 	platform_set_drvdata(pdev, usb_power);
345 
346 	ret = axp803_usb_power_dt_parse(usb_power);
347 	if (ret) {
348 		pr_err("%s parse device tree err\n", __func__);
349 		ret = -EINVAL;
350 		return ret;
351 	}
352 
353 	ret = axp803_usb_power_init(usb_power);
354 	if (ret < 0) {
355 		pr_err("axp803 init usb power fail!\n");
356 		ret = -ENODEV;
357 		return ret;
358 	}
359 
360 	psy_cfg.of_node = pdev->dev.of_node;
361 	psy_cfg.drv_data = usb_power;
362 
363 	usb_power->usb_supply = devm_power_supply_register(usb_power->dev,
364 			&axp803_usb_desc, &psy_cfg);
365 
366 	if (IS_ERR(usb_power->usb_supply)) {
367 		pr_err("axp803 failed to register usb power\n");
368 		ret = PTR_ERR(usb_power->usb_supply);
369 		return ret;
370 	}
371 
372 	for (i = 0; i < ARRAY_SIZE(axp803_usb_irq); i++) {
373 		irq = platform_get_irq_byname(pdev, axp803_usb_irq[i].name);
374 		if (irq < 0) {
375 			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
376 				 axp803_usb_irq[i].name, irq);
377 			continue;
378 		}
379 		irq = regmap_irq_get_virq(axp_dev->regmap_irqc, irq);
380 		ret = devm_request_any_context_irq(&pdev->dev, irq,
381 						   axp803_usb_irq[i].isr, 0,
382 						   axp803_usb_irq[i].name, usb_power);
383 		if (ret < 0)
384 			dev_warn(&pdev->dev, "Error requesting %s IRQ %d: %d\n",
385 				axp803_usb_irq[i].name, irq, ret);
386 
387 		dev_dbg(&pdev->dev, "Requested %s IRQ %d: %d\n",
388 			axp803_usb_irq[i].name, irq, ret);
389 
390 		/* we use this variable to suspend irq */
391 		axp803_usb_irq[i].irq = irq;
392 	}
393 
394 	INIT_DELAYED_WORK(&usb_power->usb_supply_mon, axp803_usb_power_monitor);
395 	schedule_delayed_work(&usb_power->usb_supply_mon, msecs_to_jiffies(500));
396 
397 	INIT_DELAYED_WORK(&usb_power->usb_chg_state, axp803_usb_set_current_fsm);
398 	schedule_delayed_work(&usb_power->usb_chg_state, msecs_to_jiffies(20 * 1000));
399 
400 	return 0;
401 }
402 
axp803_usb_power_remove(struct platform_device * pdev)403 static int axp803_usb_power_remove(struct platform_device *pdev)
404 {
405 	struct axp803_usb_power *usb_power = platform_get_drvdata(pdev);
406 
407 	cancel_delayed_work_sync(&usb_power->usb_supply_mon);
408 	cancel_delayed_work_sync(&usb_power->usb_chg_state);
409 
410 	return 0;
411 }
412 
axp_irq_set(unsigned int irq,bool enable)413 static inline void axp_irq_set(unsigned int irq, bool enable)
414 {
415 	if (enable)
416 		enable_irq(irq);
417 	else
418 		disable_irq(irq);
419 }
420 
axp803_usb_virq_dts_set(struct axp803_usb_power * usb_power,bool enable)421 static void axp803_usb_virq_dts_set(struct axp803_usb_power *usb_power, bool enable)
422 {
423 	struct axp_config_info *dts_info = &usb_power->dts_info;
424 
425 	if (!dts_info->wakeup_usb_in)
426 		axp_irq_set(axp803_usb_irq[AXP803_VIRQ_USBIN].irq,
427 				enable);
428 	if (!dts_info->wakeup_usb_out)
429 		axp_irq_set(axp803_usb_irq[AXP803_VIRQ_USBRE].irq,
430 				enable);
431 }
432 
axp803_usb_power_suspend(struct platform_device * pdev,pm_message_t state)433 static int axp803_usb_power_suspend(struct platform_device *pdev, pm_message_t state)
434 {
435 	struct axp803_usb_power *usb_power = platform_get_drvdata(pdev);
436 
437 	axp803_usb_virq_dts_set(usb_power, false);
438 
439 	return 0;
440 }
441 
axp803_usb_power_resume(struct platform_device * pdev)442 static int axp803_usb_power_resume(struct platform_device *pdev)
443 {
444 	struct axp803_usb_power *usb_power = platform_get_drvdata(pdev);
445 
446 	axp803_usb_virq_dts_set(usb_power, true);
447 
448 	return 0;
449 }
450 
451 static const struct of_device_id axp803_usb_power_match[] = {
452 	{
453 		.compatible = "x-powers,axp803-usb-power-supply",
454 		.data = (void *)AXP803_ID,
455 	}, { /* sentinel */ }
456 };
457 MODULE_DEVICE_TABLE(of, axp803_usb_power_match);
458 
459 static struct platform_driver axp803_usb_power_driver = {
460 	.driver = {
461 		.name = "axp803-usb-power-supply",
462 		.of_match_table = axp803_usb_power_match,
463 	},
464 	.probe = axp803_usb_power_probe,
465 	.remove = axp803_usb_power_remove,
466 	.suspend = axp803_usb_power_suspend,
467 	.resume = axp803_usb_power_resume,
468 };
469 
470 module_platform_driver(axp803_usb_power_driver);
471 
472 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
473 MODULE_DESCRIPTION("axp803 usb power driver");
474 MODULE_LICENSE("GPL");
475