aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorVinod Koul <vkoul@kernel.org>2018-07-31 01:57:33 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-07-31 02:11:16 -0400
commit2049a9e56a01ddedc2528ea42284e60d0e448cce (patch)
tree0231a630e6c4dd9d1175b7745be6a1ca25805ba9 /drivers/input
parent0b64fa0a0ee31501d546c775a88922f3cf51fef3 (diff)
Input: pm8941-pwrkey - abstract register offsets and event code
In order to support resin thru the pwrkey driver (they are very similar in nature) we need to abstract the handling in this driver. First we abstract pull_up_bit and status_bit along in driver data. The event code sent for key events is quiried from DT. Since the device can be child of pon lookup regmap and reg from parent if lookup fails (we are child). Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: Vinod Koul <vkoul@kernel.org> Reviewed-by: Rob Herring <robh@kernel.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/misc/pm8941-pwrkey.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
index 18ad956454f1..e1b3914b141e 100644
--- a/drivers/input/misc/pm8941-pwrkey.c
+++ b/drivers/input/misc/pm8941-pwrkey.c
@@ -20,6 +20,7 @@
20#include <linux/log2.h> 20#include <linux/log2.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_device.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24#include <linux/reboot.h> 25#include <linux/reboot.h>
25#include <linux/regmap.h> 26#include <linux/regmap.h>
@@ -42,6 +43,10 @@
42#define PON_DBC_CTL 0x71 43#define PON_DBC_CTL 0x71
43#define PON_DBC_DELAY_MASK 0x7 44#define PON_DBC_DELAY_MASK 0x7
44 45
46struct pm8941_data {
47 unsigned int pull_up_bit;
48 unsigned int status_bit;
49};
45 50
46struct pm8941_pwrkey { 51struct pm8941_pwrkey {
47 struct device *dev; 52 struct device *dev;
@@ -52,6 +57,9 @@ struct pm8941_pwrkey {
52 57
53 unsigned int revision; 58 unsigned int revision;
54 struct notifier_block reboot_notifier; 59 struct notifier_block reboot_notifier;
60
61 u32 code;
62 const struct pm8941_data *data;
55}; 63};
56 64
57static int pm8941_reboot_notify(struct notifier_block *nb, 65static int pm8941_reboot_notify(struct notifier_block *nb,
@@ -124,7 +132,8 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
124 if (error) 132 if (error)
125 return IRQ_HANDLED; 133 return IRQ_HANDLED;
126 134
127 input_report_key(pwrkey->input, KEY_POWER, !!(sts & PON_KPDPWR_N_SET)); 135 input_report_key(pwrkey->input, pwrkey->code,
136 sts & pwrkey->data->status_bit);
128 input_sync(pwrkey->input); 137 input_sync(pwrkey->input);
129 138
130 return IRQ_HANDLED; 139 return IRQ_HANDLED;
@@ -157,6 +166,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
157{ 166{
158 struct pm8941_pwrkey *pwrkey; 167 struct pm8941_pwrkey *pwrkey;
159 bool pull_up; 168 bool pull_up;
169 struct device *parent;
160 u32 req_delay; 170 u32 req_delay;
161 int error; 171 int error;
162 172
@@ -175,12 +185,30 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
175 return -ENOMEM; 185 return -ENOMEM;
176 186
177 pwrkey->dev = &pdev->dev; 187 pwrkey->dev = &pdev->dev;
188 pwrkey->data = of_device_get_match_data(&pdev->dev);
178 189
179 pwrkey->regmap = dev_get_regmap(pdev->dev.parent, NULL); 190 parent = pdev->dev.parent;
191 pwrkey->regmap = dev_get_regmap(parent, NULL);
180 if (!pwrkey->regmap) { 192 if (!pwrkey->regmap) {
181 dev_err(&pdev->dev, "failed to locate regmap\n"); 193 /*
182 return -ENODEV; 194 * We failed to get regmap for parent. Let's see if we are
195 * a child of pon node and read regmap and reg from its
196 * parent.
197 */
198 pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
199 if (!pwrkey->regmap) {
200 dev_err(&pdev->dev, "failed to locate regmap\n");
201 return -ENODEV;
202 }
203
204 error = of_property_read_u32(parent->of_node,
205 "reg", &pwrkey->baseaddr);
206 } else {
207 error = of_property_read_u32(pdev->dev.of_node, "reg",
208 &pwrkey->baseaddr);
183 } 209 }
210 if (error)
211 return error;
184 212
185 pwrkey->irq = platform_get_irq(pdev, 0); 213 pwrkey->irq = platform_get_irq(pdev, 0);
186 if (pwrkey->irq < 0) { 214 if (pwrkey->irq < 0) {
@@ -188,11 +216,6 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
188 return pwrkey->irq; 216 return pwrkey->irq;
189 } 217 }
190 218
191 error = of_property_read_u32(pdev->dev.of_node, "reg",
192 &pwrkey->baseaddr);
193 if (error)
194 return error;
195
196 error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2, 219 error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
197 &pwrkey->revision); 220 &pwrkey->revision);
198 if (error) { 221 if (error) {
@@ -200,13 +223,21 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
200 return error; 223 return error;
201 } 224 }
202 225
226 error = of_property_read_u32(pdev->dev.of_node, "linux,code",
227 &pwrkey->code);
228 if (error) {
229 dev_dbg(&pdev->dev,
230 "no linux,code assuming power (%d)\n", error);
231 pwrkey->code = KEY_POWER;
232 }
233
203 pwrkey->input = devm_input_allocate_device(&pdev->dev); 234 pwrkey->input = devm_input_allocate_device(&pdev->dev);
204 if (!pwrkey->input) { 235 if (!pwrkey->input) {
205 dev_dbg(&pdev->dev, "unable to allocate input device\n"); 236 dev_dbg(&pdev->dev, "unable to allocate input device\n");
206 return -ENOMEM; 237 return -ENOMEM;
207 } 238 }
208 239
209 input_set_capability(pwrkey->input, EV_KEY, KEY_POWER); 240 input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
210 241
211 pwrkey->input->name = "pm8941_pwrkey"; 242 pwrkey->input->name = "pm8941_pwrkey";
212 pwrkey->input->phys = "pm8941_pwrkey/input0"; 243 pwrkey->input->phys = "pm8941_pwrkey/input0";
@@ -225,8 +256,8 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
225 256
226 error = regmap_update_bits(pwrkey->regmap, 257 error = regmap_update_bits(pwrkey->regmap,
227 pwrkey->baseaddr + PON_PULL_CTL, 258 pwrkey->baseaddr + PON_PULL_CTL,
228 PON_KPDPWR_PULL_UP, 259 pwrkey->data->pull_up_bit,
229 pull_up ? PON_KPDPWR_PULL_UP : 0); 260 pull_up ? pwrkey->data->pull_up_bit : 0);
230 if (error) { 261 if (error) {
231 dev_err(&pdev->dev, "failed to set pull: %d\n", error); 262 dev_err(&pdev->dev, "failed to set pull: %d\n", error);
232 return error; 263 return error;
@@ -271,8 +302,13 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev)
271 return 0; 302 return 0;
272} 303}
273 304
305static const struct pm8941_data pwrkey_data = {
306 .pull_up_bit = PON_KPDPWR_PULL_UP,
307 .status_bit = PON_KPDPWR_N_SET,
308};
309
274static const struct of_device_id pm8941_pwr_key_id_table[] = { 310static const struct of_device_id pm8941_pwr_key_id_table[] = {
275 { .compatible = "qcom,pm8941-pwrkey" }, 311 { .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
276 { } 312 { }
277}; 313};
278MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table); 314MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);