pm8941-pwrkey.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  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. * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  6. */
  7. #include <linux/delay.h>
  8. #include <linux/errno.h>
  9. #include <linux/input.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/kernel.h>
  12. #include <linux/ktime.h>
  13. #include <linux/log2.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_device.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/reboot.h>
  20. #include <linux/regmap.h>
  21. #include <linux/suspend.h>
  22. #if IS_ENABLED(CONFIG_SEC_PM)
  23. #include <linux/mfd/sec_ap_pmic.h>
  24. #define PON_PBS_KPDPWR_S2_CNTL2 0x43
  25. #define PON_PBS_KPDPWR_RESIN_S2_CNTL2 0x4B
  26. #define PON_PBS_S2_CNTL_EN BIT(7)
  27. #endif
  28. #define PON_REV2 0x01
  29. #define PON_SUBTYPE 0x05
  30. #define PON_SUBTYPE_PRIMARY 0x01
  31. #define PON_SUBTYPE_SECONDARY 0x02
  32. #define PON_SUBTYPE_1REG 0x03
  33. #define PON_SUBTYPE_GEN2_PRIMARY 0x04
  34. #define PON_SUBTYPE_GEN2_SECONDARY 0x05
  35. #define PON_SUBTYPE_GEN3_PBS 0x08
  36. #define PON_SUBTYPE_GEN3_HLOS 0x09
  37. #define PON_RT_STS 0x10
  38. #define PON_KPDPWR_N_SET BIT(0)
  39. #define PON_RESIN_N_SET BIT(1)
  40. #define PON_GEN3_RESIN_N_SET BIT(6)
  41. #define PON_GEN3_KPDPWR_N_SET BIT(7)
  42. #define PON_PS_HOLD_RST_CTL 0x5a
  43. #define PON_PS_HOLD_RST_CTL2 0x5b
  44. #define PON_PS_HOLD_ENABLE BIT(7)
  45. #define PON_PS_HOLD_TYPE_MASK 0x0f
  46. #define PON_PS_HOLD_TYPE_WARM_RESET 1
  47. #define PON_PS_HOLD_TYPE_SHUTDOWN 4
  48. #define PON_PS_HOLD_TYPE_HARD_RESET 7
  49. #define PON_PULL_CTL 0x70
  50. #define PON_KPDPWR_PULL_UP BIT(1)
  51. #define PON_RESIN_PULL_UP BIT(0)
  52. #define PON_DBC_CTL 0x71
  53. #define PON_DBC_DELAY_MASK_GEN1 0x7
  54. #define PON_DBC_DELAY_MASK_GEN2 0xf
  55. #define PON_DBC_SHIFT_GEN1 6
  56. #define PON_DBC_SHIFT_GEN2 14
  57. struct pm8941_data {
  58. unsigned int pull_up_bit;
  59. unsigned int status_bit;
  60. bool supports_ps_hold_poff_config;
  61. bool supports_debounce_config;
  62. bool has_pon_pbs;
  63. const char *name;
  64. const char *phys;
  65. };
  66. struct pm8941_pwrkey {
  67. struct device *dev;
  68. int irq;
  69. u32 baseaddr;
  70. u32 pon_pbs_baseaddr;
  71. struct regmap *regmap;
  72. struct input_dev *input;
  73. unsigned int revision;
  74. unsigned int subtype;
  75. struct notifier_block reboot_notifier;
  76. u32 code;
  77. u32 sw_debounce_time_us;
  78. ktime_t sw_debounce_end_time;
  79. u32 req_delay;
  80. bool last_status;
  81. bool pull_up;
  82. bool log_kpd_event;
  83. const struct pm8941_data *data;
  84. #if IS_ENABLED(CONFIG_SEC_PM)
  85. int wake_enabled;
  86. #endif
  87. };
  88. #if IS_ENABLED(CONFIG_SEC_PM)
  89. static struct _sec_pon {
  90. struct pm8941_pwrkey *key_dev[SEC_PON_KEY_CNT];
  91. struct pm8941_pwrkey *reset_dev;
  92. } sec_pon;
  93. int sec_get_s2_reset(enum sec_pon_type type)
  94. {
  95. int rc;
  96. unsigned int en;
  97. struct pm8941_pwrkey *pwrkey = sec_pon.reset_dev;
  98. unsigned int offset;
  99. if (type != SEC_PON_KPDPWR && type != SEC_PON_KPDPWR_RESIN)
  100. return -EINVAL;
  101. if (!pwrkey)
  102. return -ENXIO;
  103. offset = (type == SEC_PON_KPDPWR) ?
  104. PON_PBS_KPDPWR_S2_CNTL2 : PON_PBS_KPDPWR_RESIN_S2_CNTL2;
  105. rc = regmap_read(pwrkey->regmap,
  106. pwrkey->pon_pbs_baseaddr + offset, &en);
  107. if (rc) {
  108. pr_err("Unable to get S2 reset on/off for type %d\n", type);
  109. return rc;
  110. }
  111. return (en & PON_PBS_S2_CNTL_EN) ? true : false;
  112. }
  113. EXPORT_SYMBOL_GPL(sec_get_s2_reset);
  114. // Key wakeup enable for (SEC_PON_KPDPWR, SEC_PON_RESIN)
  115. int sec_set_pm_key_wk_init(enum sec_pon_type type, int en)
  116. {
  117. struct pm8941_pwrkey *pwrkey;
  118. if (type != SEC_PON_KPDPWR && type != SEC_PON_RESIN)
  119. return -EINVAL;
  120. pwrkey = sec_pon.key_dev[type];
  121. if (!pwrkey)
  122. return -ENXIO;
  123. if (pwrkey->wake_enabled != en) {
  124. pwrkey->wake_enabled = en;
  125. pr_info("%s: wk_int (type:%d, en:%d)\n", __func__, type, en);
  126. }
  127. else {
  128. pr_info("%s: already wk_int (type:%d, en:%d)\n", __func__, type, en);
  129. }
  130. return 0;
  131. }
  132. EXPORT_SYMBOL_GPL(sec_set_pm_key_wk_init);
  133. int sec_get_pm_key_wk_init(enum sec_pon_type type)
  134. {
  135. if (type != SEC_PON_KPDPWR && type != SEC_PON_RESIN)
  136. return -EINVAL;
  137. return sec_pon.key_dev[type]->wake_enabled;
  138. }
  139. EXPORT_SYMBOL_GPL(sec_get_pm_key_wk_init);
  140. #endif
  141. static int pm8941_reboot_notify(struct notifier_block *nb,
  142. unsigned long code, void *unused)
  143. {
  144. struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
  145. reboot_notifier);
  146. unsigned int enable_reg;
  147. unsigned int reset_type;
  148. int error;
  149. /* PMICs with revision 0 have the enable bit in same register as ctrl */
  150. if (pwrkey->revision == 0)
  151. enable_reg = PON_PS_HOLD_RST_CTL;
  152. else
  153. enable_reg = PON_PS_HOLD_RST_CTL2;
  154. error = regmap_update_bits(pwrkey->regmap,
  155. pwrkey->baseaddr + enable_reg,
  156. PON_PS_HOLD_ENABLE,
  157. 0);
  158. if (error)
  159. dev_err(pwrkey->dev,
  160. "unable to clear ps hold reset enable: %d\n",
  161. error);
  162. /*
  163. * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
  164. * writes.
  165. */
  166. usleep_range(100, 1000);
  167. switch (code) {
  168. case SYS_HALT:
  169. case SYS_POWER_OFF:
  170. reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
  171. break;
  172. case SYS_RESTART:
  173. default:
  174. if (reboot_mode == REBOOT_WARM)
  175. reset_type = PON_PS_HOLD_TYPE_WARM_RESET;
  176. else
  177. reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
  178. break;
  179. }
  180. error = regmap_update_bits(pwrkey->regmap,
  181. pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
  182. PON_PS_HOLD_TYPE_MASK,
  183. reset_type);
  184. if (error)
  185. dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
  186. error);
  187. error = regmap_update_bits(pwrkey->regmap,
  188. pwrkey->baseaddr + enable_reg,
  189. PON_PS_HOLD_ENABLE,
  190. PON_PS_HOLD_ENABLE);
  191. if (error)
  192. dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
  193. return NOTIFY_DONE;
  194. }
  195. static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
  196. {
  197. struct pm8941_pwrkey *pwrkey = _data;
  198. unsigned int sts;
  199. int err;
  200. if (pwrkey->sw_debounce_time_us) {
  201. if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
  202. dev_dbg(pwrkey->dev,
  203. "ignoring key event received before debounce end %llu us\n",
  204. pwrkey->sw_debounce_end_time);
  205. return IRQ_HANDLED;
  206. }
  207. }
  208. err = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_RT_STS, &sts);
  209. if (err)
  210. return IRQ_HANDLED;
  211. sts &= pwrkey->data->status_bit;
  212. if (pwrkey->sw_debounce_time_us && !sts)
  213. pwrkey->sw_debounce_end_time = ktime_add_us(ktime_get(),
  214. pwrkey->sw_debounce_time_us);
  215. if (pwrkey->log_kpd_event)
  216. pr_info_ratelimited("PMIC input: KPDPWR status=0x%02x, KPDPWR_ON=%d\n",
  217. sts, (sts & PON_KPDPWR_N_SET));
  218. /*
  219. * Simulate a press event in case a release event occurred without a
  220. * corresponding press event.
  221. */
  222. if (!pwrkey->last_status && !sts) {
  223. input_report_key(pwrkey->input, pwrkey->code, 1);
  224. input_sync(pwrkey->input);
  225. }
  226. pwrkey->last_status = sts;
  227. input_report_key(pwrkey->input, pwrkey->code, sts);
  228. input_sync(pwrkey->input);
  229. return IRQ_HANDLED;
  230. }
  231. static int pm8941_pwrkey_sw_debounce_init(struct pm8941_pwrkey *pwrkey)
  232. {
  233. unsigned int val, addr, mask;
  234. int error;
  235. if (pwrkey->data->has_pon_pbs && !pwrkey->pon_pbs_baseaddr) {
  236. dev_err(pwrkey->dev,
  237. "PON_PBS address missing, can't read HW debounce time\n");
  238. return 0;
  239. }
  240. if (pwrkey->pon_pbs_baseaddr)
  241. addr = pwrkey->pon_pbs_baseaddr + PON_DBC_CTL;
  242. else
  243. addr = pwrkey->baseaddr + PON_DBC_CTL;
  244. error = regmap_read(pwrkey->regmap, addr, &val);
  245. if (error)
  246. return error;
  247. if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY)
  248. mask = 0xf;
  249. else
  250. mask = 0x7;
  251. pwrkey->sw_debounce_time_us =
  252. 2 * USEC_PER_SEC / (1 << (mask - (val & mask)));
  253. dev_dbg(pwrkey->dev, "SW debounce time = %u us\n",
  254. pwrkey->sw_debounce_time_us);
  255. return 0;
  256. }
  257. static int pm8941_pwrkey_hw_init(struct pm8941_pwrkey *pwrkey)
  258. {
  259. u32 req_delay = 0, mask, delay_shift;
  260. int error;
  261. if (pwrkey->data->supports_debounce_config) {
  262. if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) {
  263. mask = PON_DBC_DELAY_MASK_GEN2;
  264. delay_shift = PON_DBC_SHIFT_GEN2;
  265. } else {
  266. mask = PON_DBC_DELAY_MASK_GEN1;
  267. delay_shift = PON_DBC_SHIFT_GEN1;
  268. }
  269. req_delay = (req_delay << delay_shift) / USEC_PER_SEC;
  270. req_delay = ilog2(req_delay);
  271. error = regmap_update_bits(pwrkey->regmap,
  272. pwrkey->baseaddr + PON_DBC_CTL,
  273. mask,
  274. req_delay);
  275. if (error) {
  276. dev_err(pwrkey->dev, "failed to set debounce config: %d\n",
  277. error);
  278. return error;
  279. }
  280. }
  281. if (pwrkey->data->pull_up_bit) {
  282. error = regmap_update_bits(pwrkey->regmap,
  283. pwrkey->baseaddr + PON_PULL_CTL,
  284. pwrkey->data->pull_up_bit,
  285. pwrkey->pull_up ? pwrkey->data->pull_up_bit :
  286. 0);
  287. if (error) {
  288. dev_err(pwrkey->dev, "failed to set pull-up config: %d\n",
  289. error);
  290. return error;
  291. }
  292. }
  293. return 0;
  294. }
  295. static int pm8941_pwrkey_freeze(struct device *dev)
  296. {
  297. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  298. if (pwrkey->irq > 0) {
  299. pr_debug("Disabling and freeing pwrkey interrupts\n");
  300. disable_irq(pwrkey->irq);
  301. devm_free_irq(dev, pwrkey->irq, pwrkey);
  302. }
  303. return 0;
  304. }
  305. static int pm8941_pwrkey_restore(struct device *dev)
  306. {
  307. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  308. int error = 0;
  309. error = pm8941_pwrkey_hw_init(pwrkey);
  310. if (error) {
  311. dev_err(dev, "Failed to initialize H/W error :%d\n", error);
  312. return error;
  313. }
  314. error = devm_request_threaded_irq(dev, pwrkey->irq,
  315. NULL, pm8941_pwrkey_irq,
  316. IRQF_ONESHOT,
  317. pwrkey->data->name, pwrkey);
  318. if (error) {
  319. dev_err(dev, "failed requesting IRQ: %d\n", error);
  320. return error;
  321. }
  322. return 0;
  323. }
  324. static int pm8941_pwrkey_suspend(struct device *dev)
  325. {
  326. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  327. if (pm_suspend_via_firmware())
  328. return pm8941_pwrkey_freeze(dev);
  329. if (device_may_wakeup(dev))
  330. {
  331. #if IS_ENABLED(CONFIG_SEC_PM)
  332. if (!pwrkey->wake_enabled) {
  333. pr_info("%s: enable_irq_wake skip by sec_ap_pmic\n", pwrkey->input->name);
  334. return 0;
  335. }
  336. #endif
  337. enable_irq_wake(pwrkey->irq);
  338. }
  339. return 0;
  340. }
  341. static int pm8941_pwrkey_resume(struct device *dev)
  342. {
  343. struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
  344. if (pm_suspend_via_firmware())
  345. return pm8941_pwrkey_restore(dev);
  346. if (device_may_wakeup(dev))
  347. {
  348. #if IS_ENABLED(CONFIG_SEC_PM)
  349. if (!pwrkey->wake_enabled) {
  350. pr_info("%s: disable_irq_wake skip by sec_ap_pmic\n", pwrkey->input->name);
  351. return 0;
  352. }
  353. #endif
  354. disable_irq_wake(pwrkey->irq);
  355. }
  356. return 0;
  357. }
  358. static const struct dev_pm_ops pm8941_pwr_key_pm_ops = {
  359. .freeze = pm8941_pwrkey_freeze,
  360. .restore = pm8941_pwrkey_restore,
  361. .suspend = pm8941_pwrkey_suspend,
  362. .resume = pm8941_pwrkey_resume,
  363. };
  364. static int pm8941_pwrkey_probe(struct platform_device *pdev)
  365. {
  366. struct pm8941_pwrkey *pwrkey;
  367. bool pull_up;
  368. struct device *parent;
  369. struct device_node *regmap_node;
  370. const __be32 *addr;
  371. u32 req_delay;
  372. unsigned int sts;
  373. int error;
  374. if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
  375. req_delay = 15625;
  376. if (req_delay > 2000000 || req_delay == 0) {
  377. dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
  378. return -EINVAL;
  379. }
  380. pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
  381. pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
  382. if (!pwrkey)
  383. return -ENOMEM;
  384. pwrkey->dev = &pdev->dev;
  385. pwrkey->data = of_device_get_match_data(&pdev->dev);
  386. if (!pwrkey->data) {
  387. dev_err(&pdev->dev, "match data not found\n");
  388. return -ENODEV;
  389. }
  390. parent = pdev->dev.parent;
  391. regmap_node = pdev->dev.of_node;
  392. pwrkey->regmap = dev_get_regmap(parent, NULL);
  393. if (!pwrkey->regmap) {
  394. regmap_node = parent->of_node;
  395. /*
  396. * We failed to get regmap for parent. Let's see if we are
  397. * a child of pon node and read regmap and reg from its
  398. * parent.
  399. */
  400. pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
  401. if (!pwrkey->regmap) {
  402. dev_err(&pdev->dev, "failed to locate regmap\n");
  403. return -ENODEV;
  404. }
  405. }
  406. pwrkey->req_delay = req_delay;
  407. pwrkey->pull_up = pull_up;
  408. addr = of_get_address(regmap_node, 0, NULL, NULL);
  409. if (!addr) {
  410. dev_err(&pdev->dev, "reg property missing\n");
  411. return -EINVAL;
  412. }
  413. pwrkey->baseaddr = be32_to_cpup(addr);
  414. if (pwrkey->data->has_pon_pbs) {
  415. /* PON_PBS base address is optional */
  416. addr = of_get_address(regmap_node, 1, NULL, NULL);
  417. if (addr)
  418. pwrkey->pon_pbs_baseaddr = be32_to_cpup(addr);
  419. }
  420. pwrkey->irq = platform_get_irq(pdev, 0);
  421. if (pwrkey->irq < 0)
  422. return pwrkey->irq;
  423. error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
  424. &pwrkey->revision);
  425. if (error) {
  426. dev_err(&pdev->dev, "failed to read revision: %d\n", error);
  427. return error;
  428. }
  429. error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_SUBTYPE,
  430. &pwrkey->subtype);
  431. if (error) {
  432. dev_err(&pdev->dev, "failed to read subtype: %d\n", error);
  433. return error;
  434. }
  435. error = of_property_read_u32(pdev->dev.of_node, "linux,code",
  436. &pwrkey->code);
  437. if (error) {
  438. dev_dbg(&pdev->dev,
  439. "no linux,code assuming power (%d)\n", error);
  440. pwrkey->code = KEY_POWER;
  441. }
  442. pwrkey->input = devm_input_allocate_device(&pdev->dev);
  443. if (!pwrkey->input) {
  444. dev_dbg(&pdev->dev, "unable to allocate input device\n");
  445. return -ENOMEM;
  446. }
  447. input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
  448. pwrkey->input->name = pwrkey->data->name;
  449. pwrkey->input->phys = pwrkey->data->phys;
  450. error = pm8941_pwrkey_hw_init(pwrkey);
  451. if (error) {
  452. dev_err(&pdev->dev, "Failed to initialize H/W : %d\n", error);
  453. return error;
  454. }
  455. error = pm8941_pwrkey_sw_debounce_init(pwrkey);
  456. if (error)
  457. return error;
  458. pwrkey->log_kpd_event = of_property_read_bool(pdev->dev.of_node, "qcom,log-kpd-event");
  459. if (pwrkey->log_kpd_event) {
  460. error = regmap_read(pwrkey->regmap,
  461. pwrkey->baseaddr + PON_RT_STS, &sts);
  462. if (error)
  463. dev_err(&pdev->dev, "failed to read PON_RT_STS rc=%d\n", error);
  464. else
  465. pr_info("KPDPWR status at init=0x%02x, KPDPWR_ON=%d\n",
  466. sts, (sts & PON_KPDPWR_N_SET));
  467. }
  468. error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
  469. NULL, pm8941_pwrkey_irq,
  470. IRQF_ONESHOT,
  471. pwrkey->data->name, pwrkey);
  472. if (error) {
  473. dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
  474. return error;
  475. }
  476. error = input_register_device(pwrkey->input);
  477. if (error) {
  478. dev_err(&pdev->dev, "failed to register input device: %d\n",
  479. error);
  480. return error;
  481. }
  482. if (pwrkey->data->supports_ps_hold_poff_config) {
  483. pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify;
  484. error = register_reboot_notifier(&pwrkey->reboot_notifier);
  485. if (error) {
  486. dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
  487. error);
  488. return error;
  489. }
  490. }
  491. platform_set_drvdata(pdev, pwrkey);
  492. device_init_wakeup(&pdev->dev, 1);
  493. #if IS_ENABLED(CONFIG_SEC_PM)
  494. if (pwrkey->data->has_pon_pbs) {
  495. if (!strncmp(pwrkey->data->name, "pmic_pwrkey", 11)) {
  496. pr_info("%s: pon_kpdpwr", __func__);
  497. sec_pon.key_dev[SEC_PON_KPDPWR] = pwrkey;
  498. sec_pon.reset_dev = pwrkey;
  499. pm8941_pwrkey_irq(pwrkey->irq, pwrkey);
  500. } else if (!strncmp(pwrkey->data->name, "pmic_resin", 10)) {
  501. pr_info("%s: pon_resin", __func__);
  502. sec_pon.key_dev[SEC_PON_RESIN] = pwrkey;
  503. pm8941_pwrkey_irq(pwrkey->irq, pwrkey);
  504. }
  505. }
  506. pwrkey->wake_enabled = true;
  507. #endif
  508. return 0;
  509. }
  510. static int pm8941_pwrkey_remove(struct platform_device *pdev)
  511. {
  512. struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
  513. if (pwrkey->data->supports_ps_hold_poff_config)
  514. unregister_reboot_notifier(&pwrkey->reboot_notifier);
  515. return 0;
  516. }
  517. static const struct pm8941_data pwrkey_data = {
  518. .pull_up_bit = PON_KPDPWR_PULL_UP,
  519. .status_bit = PON_KPDPWR_N_SET,
  520. .name = "pm8941_pwrkey",
  521. .phys = "pm8941_pwrkey/input0",
  522. .supports_ps_hold_poff_config = true,
  523. .supports_debounce_config = true,
  524. .has_pon_pbs = false,
  525. };
  526. static const struct pm8941_data resin_data = {
  527. .pull_up_bit = PON_RESIN_PULL_UP,
  528. .status_bit = PON_RESIN_N_SET,
  529. .name = "pm8941_resin",
  530. .phys = "pm8941_resin/input0",
  531. .supports_ps_hold_poff_config = true,
  532. .supports_debounce_config = true,
  533. .has_pon_pbs = false,
  534. };
  535. static const struct pm8941_data pon_gen3_pwrkey_data = {
  536. .status_bit = PON_GEN3_KPDPWR_N_SET,
  537. .name = "pmic_pwrkey",
  538. .phys = "pmic_pwrkey/input0",
  539. .supports_ps_hold_poff_config = false,
  540. .supports_debounce_config = false,
  541. .has_pon_pbs = true,
  542. };
  543. static const struct pm8941_data pon_gen3_resin_data = {
  544. .status_bit = PON_GEN3_RESIN_N_SET,
  545. .name = "pmic_resin",
  546. .phys = "pmic_resin/input0",
  547. .supports_ps_hold_poff_config = false,
  548. .supports_debounce_config = false,
  549. .has_pon_pbs = true,
  550. };
  551. static const struct pm8941_data pon_gen3_resin_data_flex = {
  552. .status_bit = PON_GEN3_RESIN_N_SET,
  553. .name = "pmic_resin_flex",
  554. .phys = "pmic_resin/input0",
  555. .supports_ps_hold_poff_config = false,
  556. .supports_debounce_config = false,
  557. .has_pon_pbs = true,
  558. };
  559. static const struct of_device_id pm8941_pwr_key_id_table[] = {
  560. { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
  561. { .compatible = "qcom,pm8941-resin", .data = &resin_data },
  562. { .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
  563. { .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
  564. { .compatible = "qcom,pmk8350-resin_flex", .data = &pon_gen3_resin_data_flex },
  565. { }
  566. };
  567. MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
  568. static struct platform_driver pm8941_pwrkey_driver = {
  569. .probe = pm8941_pwrkey_probe,
  570. .remove = pm8941_pwrkey_remove,
  571. .driver = {
  572. .name = "pm8941-pwrkey",
  573. .pm = &pm8941_pwr_key_pm_ops,
  574. .of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
  575. },
  576. };
  577. module_platform_driver(pm8941_pwrkey_driver);
  578. MODULE_DESCRIPTION("PM8941 Power Key driver");
  579. MODULE_LICENSE("GPL v2");