Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: pm8941-pwrkey - add support for PMK8350 PON_HLOS PMIC peripheral

On Qualcomm Technologies, Inc. PMIC PMK8350, the PON peripheral
is split into two peripherals: PON_HLOS and PON_PBS. The
application processor only has write access to PON_HLOS which
limits it to only receiving PON interrupts.

Add support for the PMK8350 PON_HLOS peripheral so that its
KPDPWR_N and RESIN_N interrupts can be used to detect key
presses.

Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: satya priya <skakit@codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/1620630064-16354-2-git-send-email-skakit@codeaurora.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

David Collins and committed by
Dmitry Torokhov
2fcbda9a 595c238a

+70 -29
+70 -29
drivers/input/misc/pm8941-pwrkey.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. 3 + * Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved. 4 4 * Copyright (c) 2014, Sony Mobile Communications Inc. 5 5 */ 6 6 ··· 22 22 #define PON_RT_STS 0x10 23 23 #define PON_KPDPWR_N_SET BIT(0) 24 24 #define PON_RESIN_N_SET BIT(1) 25 + #define PON_GEN3_RESIN_N_SET BIT(6) 26 + #define PON_GEN3_KPDPWR_N_SET BIT(7) 25 27 26 28 #define PON_PS_HOLD_RST_CTL 0x5a 27 29 #define PON_PS_HOLD_RST_CTL2 0x5b ··· 40 38 #define PON_DBC_DELAY_MASK 0x7 41 39 42 40 struct pm8941_data { 43 - unsigned int pull_up_bit; 44 - unsigned int status_bit; 41 + unsigned int pull_up_bit; 42 + unsigned int status_bit; 43 + bool supports_ps_hold_poff_config; 44 + bool supports_debounce_config; 45 + const char *name; 46 + const char *phys; 45 47 }; 46 48 47 49 struct pm8941_pwrkey { ··· 237 231 238 232 input_set_capability(pwrkey->input, EV_KEY, pwrkey->code); 239 233 240 - pwrkey->input->name = "pm8941_pwrkey"; 241 - pwrkey->input->phys = "pm8941_pwrkey/input0"; 234 + pwrkey->input->name = pwrkey->data->name; 235 + pwrkey->input->phys = pwrkey->data->phys; 242 236 243 - req_delay = (req_delay << 6) / USEC_PER_SEC; 244 - req_delay = ilog2(req_delay); 237 + if (pwrkey->data->supports_debounce_config) { 238 + req_delay = (req_delay << 6) / USEC_PER_SEC; 239 + req_delay = ilog2(req_delay); 245 240 246 - error = regmap_update_bits(pwrkey->regmap, 247 - pwrkey->baseaddr + PON_DBC_CTL, 248 - PON_DBC_DELAY_MASK, 249 - req_delay); 250 - if (error) { 251 - dev_err(&pdev->dev, "failed to set debounce: %d\n", error); 252 - return error; 241 + error = regmap_update_bits(pwrkey->regmap, 242 + pwrkey->baseaddr + PON_DBC_CTL, 243 + PON_DBC_DELAY_MASK, 244 + req_delay); 245 + if (error) { 246 + dev_err(&pdev->dev, "failed to set debounce: %d\n", 247 + error); 248 + return error; 249 + } 253 250 } 254 251 255 - error = regmap_update_bits(pwrkey->regmap, 256 - pwrkey->baseaddr + PON_PULL_CTL, 257 - pwrkey->data->pull_up_bit, 258 - pull_up ? pwrkey->data->pull_up_bit : 0); 259 - if (error) { 260 - dev_err(&pdev->dev, "failed to set pull: %d\n", error); 261 - return error; 252 + if (pwrkey->data->pull_up_bit) { 253 + error = regmap_update_bits(pwrkey->regmap, 254 + pwrkey->baseaddr + PON_PULL_CTL, 255 + pwrkey->data->pull_up_bit, 256 + pull_up ? pwrkey->data->pull_up_bit : 257 + 0); 258 + if (error) { 259 + dev_err(&pdev->dev, "failed to set pull: %d\n", error); 260 + return error; 261 + } 262 262 } 263 263 264 264 error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq, 265 265 NULL, pm8941_pwrkey_irq, 266 266 IRQF_ONESHOT, 267 - "pm8941_pwrkey", pwrkey); 267 + pwrkey->data->name, pwrkey); 268 268 if (error) { 269 269 dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error); 270 270 return error; ··· 283 271 return error; 284 272 } 285 273 286 - pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify, 287 - error = register_reboot_notifier(&pwrkey->reboot_notifier); 288 - if (error) { 289 - dev_err(&pdev->dev, "failed to register reboot notifier: %d\n", 290 - error); 291 - return error; 274 + if (pwrkey->data->supports_ps_hold_poff_config) { 275 + pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify, 276 + error = register_reboot_notifier(&pwrkey->reboot_notifier); 277 + if (error) { 278 + dev_err(&pdev->dev, "failed to register reboot notifier: %d\n", 279 + error); 280 + return error; 281 + } 292 282 } 293 283 294 284 platform_set_drvdata(pdev, pwrkey); ··· 303 289 { 304 290 struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev); 305 291 306 - unregister_reboot_notifier(&pwrkey->reboot_notifier); 292 + if (pwrkey->data->supports_ps_hold_poff_config) 293 + unregister_reboot_notifier(&pwrkey->reboot_notifier); 307 294 308 295 return 0; 309 296 } ··· 312 297 static const struct pm8941_data pwrkey_data = { 313 298 .pull_up_bit = PON_KPDPWR_PULL_UP, 314 299 .status_bit = PON_KPDPWR_N_SET, 300 + .name = "pm8941_pwrkey", 301 + .phys = "pm8941_pwrkey/input0", 302 + .supports_ps_hold_poff_config = true, 303 + .supports_debounce_config = true, 315 304 }; 316 305 317 306 static const struct pm8941_data resin_data = { 318 307 .pull_up_bit = PON_RESIN_PULL_UP, 319 308 .status_bit = PON_RESIN_N_SET, 309 + .name = "pm8941_resin", 310 + .phys = "pm8941_resin/input0", 311 + .supports_ps_hold_poff_config = true, 312 + .supports_debounce_config = true, 313 + }; 314 + 315 + static const struct pm8941_data pon_gen3_pwrkey_data = { 316 + .status_bit = PON_GEN3_KPDPWR_N_SET, 317 + .name = "pmic_pwrkey", 318 + .phys = "pmic_pwrkey/input0", 319 + .supports_ps_hold_poff_config = false, 320 + .supports_debounce_config = false, 321 + }; 322 + 323 + static const struct pm8941_data pon_gen3_resin_data = { 324 + .status_bit = PON_GEN3_RESIN_N_SET, 325 + .name = "pmic_resin", 326 + .phys = "pmic_resin/input0", 327 + .supports_ps_hold_poff_config = false, 328 + .supports_debounce_config = false, 320 329 }; 321 330 322 331 static const struct of_device_id pm8941_pwr_key_id_table[] = { 323 332 { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data }, 324 333 { .compatible = "qcom,pm8941-resin", .data = &resin_data }, 334 + { .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data }, 335 + { .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data }, 325 336 { } 326 337 }; 327 338 MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);