1 /*
2  * Copyright (c) 2023 Cirrus Logic, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "zephyr/sys/printk.h"
8 #include <zephyr/kernel.h>
9 #include <zephyr/device.h>
10 #include <zephyr/devicetree.h>
11 #include <zephyr/drivers/charger.h>
12 #include <sys/errno.h>
13 
14 static const struct device *chgdev = DEVICE_DT_GET(DT_NODELABEL(charger));
15 
main(void)16 int main(void)
17 {
18 	union charger_propval val;
19 	int ret;
20 
21 	if (chgdev == NULL) {
22 		printk("Error: no charger device found.\n");
23 		return 0;
24 	}
25 
26 	if (!device_is_ready(chgdev)) {
27 		printk("Error: Device \"%s\" is not ready; "
28 		       "check the driver initialization logs for errors.\n",
29 		       chgdev->name);
30 		return 0;
31 	}
32 
33 	printk("Found device \"%s\", getting charger data\n", chgdev->name);
34 
35 #ifdef CONFIG_CHARGER_DISCHARGE_CURRENT_NOTIFICATIONS
36 	val.discharge_current_notification.current_ua =
37 		CONFIG_APP_DISCHARGE_CURRENT_NOTIFICATION_THRESHOLD_UA;
38 	val.discharge_current_notification.severity = CHARGER_SEVERITY_WARNING;
39 	val.discharge_current_notification.duration_us =
40 		CONFIG_APP_DISCHARGE_CURRENT_NOTIFICATION_DURATION_US;
41 
42 	ret = charger_set_prop(chgdev, CHARGER_PROP_DISCHARGE_CURRENT_NOTIFICATION, &val);
43 	if (ret < 0) {
44 		return ret;
45 	}
46 #endif
47 
48 #ifdef CONFIG_CHARGER_SYSTEM_VOLTAGE_NOTIFICATIONS
49 	val.system_voltage_notification =
50 		CONFIG_APP_SYSTEM_VOLTAGE_NOTIFICATION_THRESHOLD_UV;
51 
52 	ret = charger_set_prop(chgdev, CHARGER_PROP_SYSTEM_VOLTAGE_NOTIFICATION_UV, &val);
53 	if (ret < 0) {
54 		return ret;
55 	}
56 #endif
57 
58 	while (1) {
59 		/* Poll until external power is presented to the charger */
60 		do {
61 			ret = charger_get_prop(chgdev, CHARGER_PROP_ONLINE, &val);
62 			if (ret < 0) {
63 				return ret;
64 			}
65 
66 			k_msleep(100);
67 		} while (val.online == CHARGER_ONLINE_OFFLINE);
68 
69 		val.status = CHARGER_STATUS_CHARGING;
70 
71 		ret = charger_charge_enable(chgdev, true);
72 		if (ret == -ENOTSUP) {
73 			printk("Enabling charge not supported, assuming auto charge enable\n");
74 			continue;
75 		} else if (ret < 0) {
76 			return ret;
77 		}
78 
79 		k_msleep(500);
80 
81 		ret = charger_get_prop(chgdev, CHARGER_PROP_STATUS, &val);
82 		if (ret < 0) {
83 			return ret;
84 		}
85 
86 		switch (val.status) {
87 		case CHARGER_STATUS_CHARGING:
88 			printk("Charging in progress...\n");
89 
90 			ret = charger_get_prop(chgdev, CHARGER_PROP_CHARGE_TYPE, &val);
91 			if (ret < 0) {
92 				return ret;
93 			}
94 
95 			printk("Device \"%s\" charge type is %d\n", chgdev->name, val.charge_type);
96 			break;
97 		case CHARGER_STATUS_NOT_CHARGING:
98 			printk("Charging halted...\n");
99 
100 			ret = charger_get_prop(chgdev, CHARGER_PROP_HEALTH, &val);
101 			if (ret < 0) {
102 				return ret;
103 			}
104 
105 			printk("Device \"%s\" health is %d\n", chgdev->name, val.health);
106 			break;
107 		case CHARGER_STATUS_FULL:
108 			printk("Charging complete!");
109 			return 0;
110 		case CHARGER_STATUS_DISCHARGING:
111 			printk("External power removed, discharging\n");
112 
113 			ret = charger_get_prop(chgdev, CHARGER_PROP_ONLINE, &val);
114 			if (ret < 0) {
115 				return ret;
116 			}
117 			break;
118 		default:
119 			return -EIO;
120 		}
121 
122 		k_msleep(500);
123 	}
124 }
125