pm8941-pwrkey.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2014, Sony Mobile Communications Inc.
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/errno.h>
  8. #include <linux/input.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/kernel.h>
  11. #include <linux/ktime.h>
  12. #include <linux/log2.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/of_address.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/reboot.h>
  18. #include <linux/regmap.h>
  19. #define PON_REV2 0x01
  20. #define PON_SUBTYPE 0x05
  21. #define PON_SUBTYPE_PRIMARY 0x01
  22. #define PON_SUBTYPE_SECONDARY 0x02
  23. #define PON_SUBTYPE_1REG 0x03
  24. #define PON_SUBTYPE_GEN2_PRIMARY 0x04
  25. #define PON_SUBTYPE_GEN2_SECONDARY 0x05
  26. #define PON_SUBTYPE_GEN3_PBS 0x08
  27. #define PON_SUBTYPE_GEN3_HLOS 0x09
  28. #define PON_RT_STS 0x10
  29. #define PON_KPDPWR_N_SET BIT(0)
  30. #define PON_RESIN_N_SET BIT(1)
  31. #define PON_GEN3_RESIN_N_SET BIT(6)
  32. #define PON_GEN3_KPDPWR_N_SET BIT(7)
  33. #define PON_PS_HOLD_RST_CTL 0x5a
  34. #define PON_PS_HOLD_RST_CTL2 0x5b
  35. #define PON_PS_HOLD_ENABLE BIT(7)
  36. #define PON_PS_HOLD_TYPE_MASK 0x0f
  37. #define PON_PS_HOLD_TYPE_WARM_RESET 1
  38. #define PON_PS_HOLD_TYPE_SHUTDOWN 4
  39. #define PON_PS_HOLD_TYPE_HARD_RESET 7
  40. #define PON_PULL_CTL 0x70
  41. #define PON_KPDPWR_PULL_UP BIT(1)
  42. #define PON_RESIN_PULL_UP BIT(0)
  43. #define PON_DBC_CTL 0x71
  44. #define PON_DBC_DELAY_MASK_GEN1 0x7
  45. #define PON_DBC_DELAY_MASK_GEN2 0xf
  46. #define PON_DBC_SHIFT_GEN1 6
  47. #define PON_DBC_SHIFT_GEN2 14
  48. struct pm8941_data {
  49. unsigned int pull_up_bit;
  50. unsigned int status_bit;
  51. bool supports_ps_hold_poff_config;
  52. bool supports_debounce_config;
  53. bool has_pon_pbs;
  54. const char *name;
  55. const char *phys;
  56. };
  57. struct pm8941_pwrkey {
  58. struct device *dev;
  59. int irq;
  60. u32 baseaddr;
  61. u32 pon_pbs_baseaddr;
  62. struct regmap *regmap;
  63. struct input_dev *input;
  64. unsigned int revision;
  65. unsigned int subtype;
  66. struct notifier_block reboot_notifier;
  67. u32 code;
  68. u32 sw_debounce_time_us;
  69. ktime_t sw_debounce_end_time;
  70. bool last_status;
  71. const struct pm8941_data *data;
  72. };
  73. static int pm8941_reboot_notify(struct notifier_block *nb,
  74. unsigned long code, void *unused)
  75. {
  76. struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
  77. reboot_notifier);
  78. unsigned int enable_reg;
  79. unsigned int reset_type;
  80. int error;
  81. /* PMICs with revision 0 have the enable bit in same register as ctrl */
  82. if (pwrkey->revision == 0)
  83. enable_reg = PON_PS_HOLD_RST_CTL;
  84. else
  85. enable_reg = PON_PS_HOLD_RST_CTL2;
  86. error = regmap_update_bits(pwrkey->regmap,
  87. pwrkey->baseaddr + enable_reg,
  88. PON_PS_HOLD_ENABLE,
  89. 0);
  90. if (error)
  91. dev_err(pwrkey->dev,
  92. "unable to clear ps hold reset enable: %d\n",
  93. error);
  94. /*
  95. * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
  96. * writes.
  97. */
  98. usleep_range(100, 1000);
  99. switch (code) {
  100. case SYS_HALT:
  101. case SYS_POWER_OFF:
  102. reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
  103. break;
  104. case SYS_RESTART:
  105. default:
  106. if (reboot_mode == REBOOT_WARM)
  107. reset_type = PON_PS_HOLD_TYPE_WARM_RESET;
  108. else
  109. reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
  110. break;
  111. }
  112. error = regmap_update_bits(pwrkey->regmap,
  113. pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
  114. PON_PS_HOLD_TYPE_MASK,
  115. reset_type);
  116. if (error)
  117. dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
  118. error);
  119. error = regmap_update_bits(pwrkey->regmap,
  120. pwrkey->baseaddr + enable_reg,
  121. PON_PS_HOLD_ENABLE,
  122. PON_PS_HOLD_ENABLE);
  123. if (error)
  124. dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
  125. return NOTIFY_DONE;
  126. }
  127. static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
  128. {
  129. struct pm8941_pwrkey *pwrkey = _data;
  130. unsigned int sts;
  131. int err;
  132. if (pwrkey->sw_debounce_time_us) {
  133. if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
  134. dev_dbg(pwrkey->dev,
  135. "ignoring key event received before debounce end %llu us\n",
  136. pwrkey->sw_debounce_end_time);
  137. return IRQ_HANDLED;
  138. }
  139. }
  140. err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
  141. if (err)
  142. return IRQ_HANDLED;
  143. sts &= pwrkey->data->status_bit;
  144. if (pwrkey->sw_debounce_time_us && !sts)
  145. pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
  146. pwrkey->sw_debounce_time_us);
  147. /*
  148. * Simulate a press event in case a release event occurred without a
  149. * corresponding press event.
  150. */
  151. if (!pwrkey->last_status && !sts) {
  152. input_report_key(pwrkey->input, pwrkey->code, 1);
  153. input_sync(pwrkey->input);
  154. }
  155. pwrkey->last_status = sts;
  156. input_report_key(pwrkey->input, pwrkey->code, sts);
  157. input_sync(pwrkey->input);
  158. return IRQ_HANDLED;
  159. }
  160. static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
  161. {
  162. unsigned int val, addr, mask;
  163. int error;
  164. if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
  165. dev_err(pwrkey->dev,
  166. "PON_PBS address missing, can't read HW debounce time\n");
  167. return 0;
  168. }
  169. if (pwrkey->pon_pbs_baseaddr)
  170. addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
  171. else
  172. addr = pwrkey->baseaddr + PON_DBC_CTL;
  173. error = regmap_read(pwrkey->regmap, addr, &val);
  174. if (error)
  175. return error;
  176. if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
  177. mask = 0xf;
  178. else
  179. mask = 0x7;
  180. pwrkey->sw_debounce_time_us =
  181. 2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
  182. dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
  183. pwrkey->sw_debounce_time_us);
  184. return 0;
  185. }
  186. static int pm8941_pwrkey_suspend(struct device *dev)
  187. {
  188. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  189. if (device_may_wakeup(dev))
  190. enable_irq_wake(pwrkey->irq);
  191. return 0;
  192. }
  193. static int pm8941_pwrkey_resume(struct device *dev)
  194. {
  195. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  196. if (device_may_wakeup(dev))
  197. disable_irq_wake(pwrkey->irq);
  198. return 0;
  199. }
  200. static DEFINE_SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
  201. pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
  202. static int pm8941_pwrkey_probe(struct platform_device *pdev)
  203. {
  204. struct pm8941_pwrkey *pwrkey;
  205. bool pull_up;
  206. struct device *parent;
  207. struct device_node *regmap_node;
  208. const __be32 *addr;
  209. u32 req_delay, mask, delay_shift;
  210. int error;
  211. if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
  212. req_delay = 15625;
  213. if (req_delay > 2000000 || req_delay == 0) {
  214. dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
  215. return -EINVAL;
  216. }
  217. pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
  218. pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
  219. if (!pwrkey)
  220. return -ENOMEM;
  221. pwrkey->dev = &pdev->dev;
  222. pwrkey->data = of_device_get_match_data(&pdev->dev);
  223. parent = pdev->dev.parent;
  224. regmap_node = pdev->dev.of_node;
  225. pwrkey->regmap = dev_get_regmap(parent, NULL);
  226. if (!pwrkey->regmap) {
  227. regmap_node = parent->of_node;
  228. /*
  229. * We failed to get regmap for parent. Let's see if we are
  230. * a child of pon node and read regmap and reg from its
  231. * parent.
  232. */
  233. pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
  234. if (!pwrkey->regmap) {
  235. dev_err(&pdev->dev, "failed to locate regmap\n");
  236. return -ENODEV;
  237. }
  238. }
  239. addr = of_get_address(regmap_node, 0, NULL, NULL);
  240. if (!addr) {
  241. dev_err(&pdev->dev, "reg property missing\n");
  242. return -EINVAL;
  243. }
  244. pwrkey->baseaddr = be32_to_cpup(addr);
  245. if (pwrkey->data->has_pon_pbs) {
  246. /* PON_PBS base address is optional */
  247. addr = of_get_address(regmap_node, 1, NULL, NULL);
  248. if (addr)
  249. pwrkey->pon_pbs_baseaddr = be32_to_cpup(addr);
  250. }
  251. pwrkey->irq = platform_get_irq(pdev, 0);
  252. if (pwrkey->irq < 0)
  253. return pwrkey->irq;
  254. error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
  255. &pwrkey->revision);
  256. if (error) {
  257. dev_err(&pdev->dev, "failed to read revision: %d\n", error);
  258. return error;
  259. }
  260. error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
  261. &pwrkey->subtype);
  262. if (error) {
  263. dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
  264. return error;
  265. }
  266. error = of_property_read_u32(pdev->dev.of_node, "linux,code",
  267. &pwrkey->code);
  268. if (error) {
  269. dev_dbg(&pdev->dev,
  270. "no linux,code assuming power (%d)\n", error);
  271. pwrkey->code = KEY_POWER;
  272. }
  273. pwrkey->input = devm_input_allocate_device(&pdev->dev);
  274. if (!pwrkey->input) {
  275. dev_dbg(&pdev->dev, "unable to allocate input device\n");
  276. return -ENOMEM;
  277. }
  278. input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
  279. pwrkey->input->name = pwrkey->data->name;
  280. pwrkey->input->phys = pwrkey->data->phys;
  281. if (pwrkey->data->supports_debounce_config) {
  282. if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) {
  283. mask = PON_DBC_DELAY_MASK_GEN2;
  284. delay_shift = PON_DBC_SHIFT_GEN2;
  285. } else {
  286. mask = PON_DBC_DELAY_MASK_GEN1;
  287. delay_shift = PON_DBC_SHIFT_GEN1;
  288. }
  289. req_delay = (req_delay << delay_shift) / USEC_PER_SEC;
  290. req_delay = ilog2(req_delay);
  291. error = regmap_update_bits(pwrkey->regmap,
  292. pwrkey->baseaddr + PON_DBC_CTL,
  293. mask,
  294. req_delay);
  295. if (error) {
  296. dev_err(&pdev->dev, "failed to set debounce: %d\n",
  297. error);
  298. return error;
  299. }
  300. }
  301. error = pm8941_pwrkey_sw_debounce_init(pwrkey);
  302. if (error)
  303. return error;
  304. if (pwrkey->data->pull_up_bit) {
  305. error = regmap_update_bits(pwrkey->regmap,
  306. pwrkey->baseaddr + PON_PULL_CTL,
  307. pwrkey->data->pull_up_bit,
  308. pull_up ? pwrkey->data->pull_up_bit :
  309. 0);
  310. if (error) {
  311. dev_err(&pdev->dev, "failed to set pull: %d\n", error);
  312. return error;
  313. }
  314. }
  315. error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
  316. NULL, pm8941_pwrkey_irq,
  317. IRQF_ONESHOT,
  318. pwrkey->data->name, pwrkey);
  319. if (error) {
  320. dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
  321. return error;
  322. }
  323. error = input_register_device(pwrkey->input);
  324. if (error) {
  325. dev_err(&pdev->dev, "failed to register input device: %d\n",
  326. error);
  327. return error;
  328. }
  329. if (pwrkey->data->supports_ps_hold_poff_config) {
  330. pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
  331. error = register_reboot_notifier(&pwrkey->reboot_notifier);
  332. if (error) {
  333. dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
  334. error);
  335. return error;
  336. }
  337. }
  338. platform_set_drvdata(pdev, pwrkey);
  339. device_init_wakeup(&pdev->dev, 1);
  340. return 0;
  341. }
  342. static void pm8941_pwrkey_remove(struct platform_device *pdev)
  343. {
  344. struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
  345. if (pwrkey->data->supports_ps_hold_poff_config)
  346. unregister_reboot_notifier(&pwrkey->reboot_notifier);
  347. }
  348. static const struct pm8941_data pwrkey_data = {
  349. .pull_up_bit = PON_KPDPWR_PULL_UP,
  350. .status_bit = PON_KPDPWR_N_SET,
  351. .name = "pm8941_pwrkey",
  352. .phys = "pm8941_pwrkey/input0",
  353. .supports_ps_hold_poff_config = true,
  354. .supports_debounce_config = true,
  355. .has_pon_pbs = false,
  356. };
  357. static const struct pm8941_data resin_data = {
  358. .pull_up_bit = PON_RESIN_PULL_UP,
  359. .status_bit = PON_RESIN_N_SET,
  360. .name = "pm8941_resin",
  361. .phys = "pm8941_resin/input0",
  362. .supports_ps_hold_poff_config = true,
  363. .supports_debounce_config = true,
  364. .has_pon_pbs = false,
  365. };
  366. static const struct pm8941_data pon_gen3_pwrkey_data = {
  367. .status_bit = PON_GEN3_KPDPWR_N_SET,
  368. .name = "pmic_pwrkey",
  369. .phys = "pmic_pwrkey/input0",
  370. .supports_ps_hold_poff_config = false,
  371. .supports_debounce_config = false,
  372. .has_pon_pbs = true,
  373. };
  374. static const struct pm8941_data pon_gen3_resin_data = {
  375. .status_bit = PON_GEN3_RESIN_N_SET,
  376. .name = "pmic_resin",
  377. .phys = "pmic_resin/input0",
  378. .supports_ps_hold_poff_config = false,
  379. .supports_debounce_config = false,
  380. .has_pon_pbs = true,
  381. };
  382. static const struct of_device_id pm8941_pwr_key_id_table[] = {
  383. { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
  384. { .compatible = "qcom,pm8941-resin", .data = &resin_data },
  385. { .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
  386. { .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
  387. { }
  388. };
  389. MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
  390. static struct platform_driver pm8941_pwrkey_driver = {
  391. .probe = pm8941_pwrkey_probe,
  392. .remove_new = pm8941_pwrkey_remove,
  393. .driver = {
  394. .name = "pm8941-pwrkey",
  395. .pm = pm_sleep_ptr(&pm8941_pwr_key_pm_ops),
  396. .of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
  397. },
  398. };
  399. module_platform_driver(pm8941_pwrkey_driver);
  400. MODULE_DESCRIPTION("PM8941 Power Key driver");
  401. MODULE_LICENSE("GPL v2");