ac.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $)
  4. *
  5. * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  6. * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/slab.h>
  11. #include <linux/init.h>
  12. #include <linux/types.h>
  13. #include <linux/dmi.h>
  14. #include <linux/delay.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/power_supply.h>
  17. #include <linux/acpi.h>
  18. #include <acpi/battery.h>
  19. #define PREFIX "ACPI: "
  20. #define ACPI_AC_CLASS "ac_adapter"
  21. #define ACPI_AC_DEVICE_NAME "AC Adapter"
  22. #define ACPI_AC_FILE_STATE "state"
  23. #define ACPI_AC_NOTIFY_STATUS 0x80
  24. #define ACPI_AC_STATUS_OFFLINE 0x00
  25. #define ACPI_AC_STATUS_ONLINE 0x01
  26. #define ACPI_AC_STATUS_UNKNOWN 0xFF
  27. #define _COMPONENT ACPI_AC_COMPONENT
  28. ACPI_MODULE_NAME("ac");
  29. MODULE_AUTHOR("Paul Diefenbaugh");
  30. MODULE_DESCRIPTION("ACPI AC Adapter Driver");
  31. MODULE_LICENSE("GPL");
  32. static int acpi_ac_add(struct acpi_device *device);
  33. static int acpi_ac_remove(struct acpi_device *device);
  34. static void acpi_ac_notify(struct acpi_device *device, u32 event);
  35. struct acpi_ac_bl {
  36. const char *hid;
  37. int hrv;
  38. };
  39. static const struct acpi_device_id ac_device_ids[] = {
  40. {"ACPI0003", 0},
  41. {"", 0},
  42. };
  43. MODULE_DEVICE_TABLE(acpi, ac_device_ids);
  44. /* Lists of PMIC ACPI HIDs with an (often better) native charger driver */
  45. static const struct acpi_ac_bl acpi_ac_blacklist[] = {
  46. { "INT33F4", -1 }, /* X-Powers AXP288 PMIC */
  47. { "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */
  48. };
  49. #ifdef CONFIG_PM_SLEEP
  50. static int acpi_ac_resume(struct device *dev);
  51. #endif
  52. static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
  53. static int ac_sleep_before_get_state_ms;
  54. static int ac_check_pmic = 1;
  55. static int ac_only;
  56. static struct acpi_driver acpi_ac_driver = {
  57. .name = "ac",
  58. .class = ACPI_AC_CLASS,
  59. .ids = ac_device_ids,
  60. .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
  61. .ops = {
  62. .add = acpi_ac_add,
  63. .remove = acpi_ac_remove,
  64. .notify = acpi_ac_notify,
  65. },
  66. .drv.pm = &acpi_ac_pm,
  67. };
  68. struct acpi_ac {
  69. struct power_supply *charger;
  70. struct power_supply_desc charger_desc;
  71. struct acpi_device * device;
  72. unsigned long long state;
  73. struct notifier_block battery_nb;
  74. };
  75. #define to_acpi_ac(x) power_supply_get_drvdata(x)
  76. /* --------------------------------------------------------------------------
  77. AC Adapter Management
  78. -------------------------------------------------------------------------- */
  79. static int acpi_ac_get_state(struct acpi_ac *ac)
  80. {
  81. acpi_status status = AE_OK;
  82. if (!ac)
  83. return -EINVAL;
  84. if (ac_only) {
  85. ac->state = 1;
  86. return 0;
  87. }
  88. status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,
  89. &ac->state);
  90. if (ACPI_FAILURE(status)) {
  91. ACPI_EXCEPTION((AE_INFO, status,
  92. "Error reading AC Adapter state"));
  93. ac->state = ACPI_AC_STATUS_UNKNOWN;
  94. return -ENODEV;
  95. }
  96. return 0;
  97. }
  98. /* --------------------------------------------------------------------------
  99. sysfs I/F
  100. -------------------------------------------------------------------------- */
  101. static int get_ac_property(struct power_supply *psy,
  102. enum power_supply_property psp,
  103. union power_supply_propval *val)
  104. {
  105. struct acpi_ac *ac = to_acpi_ac(psy);
  106. if (!ac)
  107. return -ENODEV;
  108. if (acpi_ac_get_state(ac))
  109. return -ENODEV;
  110. switch (psp) {
  111. case POWER_SUPPLY_PROP_ONLINE:
  112. val->intval = ac->state;
  113. break;
  114. default:
  115. return -EINVAL;
  116. }
  117. return 0;
  118. }
  119. static enum power_supply_property ac_props[] = {
  120. POWER_SUPPLY_PROP_ONLINE,
  121. };
  122. /* --------------------------------------------------------------------------
  123. Driver Model
  124. -------------------------------------------------------------------------- */
  125. static void acpi_ac_notify(struct acpi_device *device, u32 event)
  126. {
  127. struct acpi_ac *ac = acpi_driver_data(device);
  128. if (!ac)
  129. return;
  130. switch (event) {
  131. default:
  132. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  133. "Unsupported event [0x%x]\n", event));
  134. fallthrough;
  135. case ACPI_AC_NOTIFY_STATUS:
  136. case ACPI_NOTIFY_BUS_CHECK:
  137. case ACPI_NOTIFY_DEVICE_CHECK:
  138. /*
  139. * A buggy BIOS may notify AC first and then sleep for
  140. * a specific time before doing actual operations in the
  141. * EC event handler (_Qxx). This will cause the AC state
  142. * reported by the ACPI event to be incorrect, so wait for a
  143. * specific time for the EC event handler to make progress.
  144. */
  145. if (ac_sleep_before_get_state_ms > 0)
  146. msleep(ac_sleep_before_get_state_ms);
  147. acpi_ac_get_state(ac);
  148. acpi_bus_generate_netlink_event(device->pnp.device_class,
  149. dev_name(&device->dev), event,
  150. (u32) ac->state);
  151. acpi_notifier_call_chain(device, event, (u32) ac->state);
  152. kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
  153. }
  154. return;
  155. }
  156. static int acpi_ac_battery_notify(struct notifier_block *nb,
  157. unsigned long action, void *data)
  158. {
  159. struct acpi_ac *ac = container_of(nb, struct acpi_ac, battery_nb);
  160. struct acpi_bus_event *event = (struct acpi_bus_event *)data;
  161. /*
  162. * On HP Pavilion dv6-6179er AC status notifications aren't triggered
  163. * when adapter is plugged/unplugged. However, battery status
  164. * notifcations are triggered when battery starts charging or
  165. * discharging. Re-reading AC status triggers lost AC notifications,
  166. * if AC status has changed.
  167. */
  168. if (strcmp(event->device_class, ACPI_BATTERY_CLASS) == 0 &&
  169. event->type == ACPI_BATTERY_NOTIFY_STATUS)
  170. acpi_ac_get_state(ac);
  171. return NOTIFY_OK;
  172. }
  173. static int __init thinkpad_e530_quirk(const struct dmi_system_id *d)
  174. {
  175. ac_sleep_before_get_state_ms = 1000;
  176. return 0;
  177. }
  178. static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
  179. {
  180. ac_check_pmic = 0;
  181. return 0;
  182. }
  183. static int __init ac_only_quirk(const struct dmi_system_id *d)
  184. {
  185. ac_only = 1;
  186. return 0;
  187. }
  188. /* Please keep this list alphabetically sorted */
  189. static const struct dmi_system_id ac_dmi_table[] __initconst = {
  190. {
  191. /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
  192. .callback = ac_do_not_check_pmic_quirk,
  193. .matches = {
  194. DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
  195. },
  196. },
  197. {
  198. /* Kodlix GK45 returning incorrect state */
  199. .callback = ac_only_quirk,
  200. .matches = {
  201. DMI_MATCH(DMI_PRODUCT_NAME, "GK45"),
  202. },
  203. },
  204. {
  205. /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
  206. .callback = ac_do_not_check_pmic_quirk,
  207. .matches = {
  208. DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
  209. DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
  210. DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
  211. },
  212. },
  213. {
  214. /* Lenovo Thinkpad e530, see comment in acpi_ac_notify() */
  215. .callback = thinkpad_e530_quirk,
  216. .matches = {
  217. DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
  218. DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
  219. },
  220. },
  221. {},
  222. };
  223. static int acpi_ac_add(struct acpi_device *device)
  224. {
  225. struct power_supply_config psy_cfg = {};
  226. int result = 0;
  227. struct acpi_ac *ac = NULL;
  228. if (!device)
  229. return -EINVAL;
  230. ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
  231. if (!ac)
  232. return -ENOMEM;
  233. ac->device = device;
  234. strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
  235. strcpy(acpi_device_class(device), ACPI_AC_CLASS);
  236. device->driver_data = ac;
  237. result = acpi_ac_get_state(ac);
  238. if (result)
  239. goto end;
  240. psy_cfg.drv_data = ac;
  241. ac->charger_desc.name = acpi_device_bid(device);
  242. ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
  243. ac->charger_desc.properties = ac_props;
  244. ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
  245. ac->charger_desc.get_property = get_ac_property;
  246. ac->charger = power_supply_register(&ac->device->dev,
  247. &ac->charger_desc, &psy_cfg);
  248. if (IS_ERR(ac->charger)) {
  249. result = PTR_ERR(ac->charger);
  250. goto end;
  251. }
  252. printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
  253. acpi_device_name(device), acpi_device_bid(device),
  254. ac->state ? "on-line" : "off-line");
  255. ac->battery_nb.notifier_call = acpi_ac_battery_notify;
  256. register_acpi_notifier(&ac->battery_nb);
  257. end:
  258. if (result) {
  259. kfree(ac);
  260. }
  261. return result;
  262. }
  263. #ifdef CONFIG_PM_SLEEP
  264. static int acpi_ac_resume(struct device *dev)
  265. {
  266. struct acpi_ac *ac;
  267. unsigned old_state;
  268. if (!dev)
  269. return -EINVAL;
  270. ac = acpi_driver_data(to_acpi_device(dev));
  271. if (!ac)
  272. return -EINVAL;
  273. old_state = ac->state;
  274. if (acpi_ac_get_state(ac))
  275. return 0;
  276. if (old_state != ac->state)
  277. kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
  278. return 0;
  279. }
  280. #else
  281. #define acpi_ac_resume NULL
  282. #endif
  283. static int acpi_ac_remove(struct acpi_device *device)
  284. {
  285. struct acpi_ac *ac = NULL;
  286. if (!device || !acpi_driver_data(device))
  287. return -EINVAL;
  288. ac = acpi_driver_data(device);
  289. power_supply_unregister(ac->charger);
  290. unregister_acpi_notifier(&ac->battery_nb);
  291. kfree(ac);
  292. return 0;
  293. }
  294. static int __init acpi_ac_init(void)
  295. {
  296. unsigned int i;
  297. int result;
  298. if (acpi_disabled)
  299. return -ENODEV;
  300. dmi_check_system(ac_dmi_table);
  301. if (ac_check_pmic) {
  302. for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
  303. if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
  304. acpi_ac_blacklist[i].hrv)) {
  305. pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
  306. acpi_ac_blacklist[i].hid);
  307. return -ENODEV;
  308. }
  309. }
  310. result = acpi_bus_register_driver(&acpi_ac_driver);
  311. if (result < 0) {
  312. return -ENODEV;
  313. }
  314. return 0;
  315. }
  316. static void __exit acpi_ac_exit(void)
  317. {
  318. acpi_bus_unregister_driver(&acpi_ac_driver);
  319. }
  320. module_init(acpi_ac_init);
  321. module_exit(acpi_ac_exit);