aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 05:33:03 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 08:44:55 -0400
commit64131a87f2aae2ed9e05d8227c5b009ca6c50d98 (patch)
treefdea23fd59216120bf54a48c60ca24489a733f14 /drivers/input/misc
parent676ee36be04985062522804c2de04f0764212be6 (diff)
parent2c33ce009ca2389dbf0535d0672214d09738e35e (diff)
Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus
* 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux: (9717 commits) media-bus: Fixup RGB444_1X12, RGB565_1X16, and YUV8_1X24 media bus format hexdump: avoid warning in test function fs: take i_mutex during prepare_binprm for set[ug]id executables smp: Fix error case handling in smp_call_function_*() iommu-common: Fix PARISC compile-time warnings sparc: Make LDC use common iommu poll management functions sparc: Make sparc64 use scalable lib/iommu-common.c functions Break up monolithic iommu table/lock into finer graularity pools and lock sparc: Revert generic IOMMU allocator. tools/power turbostat: correct dumped pkg-cstate-limit value tools/power turbostat: calculate TSC frequency from CPUID(0x15) on SKL tools/power turbostat: correct DRAM RAPL units on recent Xeon processors tools/power turbostat: Initial Skylake support tools/power turbostat: Use $(CURDIR) instead of $(PWD) and add support for O= option in Makefile tools/power turbostat: modprobe msr, if needed tools/power turbostat: dump MSR_TURBO_RATIO_LIMIT2 tools/power turbostat: use new MSR_TURBO_RATIO_LIMIT names Bluetooth: hidp: Fix regression with older userspace and flags validation config: Enable NEED_DMA_MAP_STATE by default when SWIOTLB is selected perf/x86/intel/pt: Fix and clean up error handling in pt_event_add() ... That solves several merge conflicts: Documentation/DocBook/media/v4l/subdev-formats.xml Documentation/devicetree/bindings/vendor-prefixes.txt drivers/staging/media/mn88473/mn88473.c include/linux/kconfig.h include/uapi/linux/media-bus-format.h The ones at subdev-formats.xml and media-bus-format.h are not trivial. That's why we opted to merge from DRM.
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/Kconfig24
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/max77843-haptic.c358
-rw-r--r--drivers/input/misc/mma8450.c34
-rw-r--r--drivers/input/misc/palmas-pwrbutton.c2
-rw-r--r--drivers/input/misc/pm8941-pwrkey.c293
-rw-r--r--drivers/input/misc/pwm-beeper.c9
-rw-r--r--drivers/input/misc/regulator-haptic.c2
-rw-r--r--drivers/input/misc/tps65218-pwrbutton.c2
9 files changed, 689 insertions, 37 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 6deb8dae3205..4436ab1b9735 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -115,6 +115,18 @@ config INPUT_PCSPKR
115 To compile this driver as a module, choose M here: the 115 To compile this driver as a module, choose M here: the
116 module will be called pcspkr. 116 module will be called pcspkr.
117 117
118config INPUT_PM8941_PWRKEY
119 tristate "Qualcomm PM8941 power key support"
120 depends on MFD_SPMI_PMIC
121 help
122 Say Y here if you want support for the power key usually found
123 on boards using a Qualcomm PM8941 compatible PMIC.
124
125 If unsure, say Y.
126
127 To compile this driver as a module, choose M here: the module
128 will be called pm8941-pwrkey.
129
118config INPUT_PM8XXX_VIBRATOR 130config INPUT_PM8XXX_VIBRATOR
119 tristate "Qualcomm PM8XXX vibrator support" 131 tristate "Qualcomm PM8XXX vibrator support"
120 depends on MFD_PM8XXX 132 depends on MFD_PM8XXX
@@ -165,6 +177,18 @@ config INPUT_MAX77693_HAPTIC
165 To compile this driver as module, choose M here: the 177 To compile this driver as module, choose M here: the
166 module will be called max77693-haptic. 178 module will be called max77693-haptic.
167 179
180config INPUT_MAX77843_HAPTIC
181 tristate "MAXIM MAX77843 haptic controller support"
182 depends on MFD_MAX77843 && REGULATOR
183 select INPUT_FF_MEMLESS
184 help
185 This option enables support for the haptic controller on
186 MAXIM MAX77843 chip. The driver supports ff-memless interface
187 from input framework.
188
189 To compile this driver as module, choose M here: the
190 module will be called max77843-haptic.
191
168config INPUT_MAX8925_ONKEY 192config INPUT_MAX8925_ONKEY
169 tristate "MAX8925 ONKEY support" 193 tristate "MAX8925 ONKEY support"
170 depends on MFD_MAX8925 194 depends on MFD_MAX8925
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 403a1a54a76c..78ba4c1b8532 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
39obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o 39obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
40obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o 40obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
41obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o 41obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o
42obj-$(CONFIG_INPUT_MAX77843_HAPTIC) += max77843-haptic.o
42obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o 43obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
43obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o 44obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
44obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o 45obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
@@ -49,6 +50,7 @@ obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
49obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o 50obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
50obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o 51obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
51obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o 52obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
53obj-$(CONFIG_INPUT_PM8941_PWRKEY) += pm8941-pwrkey.o
52obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR) += pm8xxx-vibrator.o 54obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR) += pm8xxx-vibrator.o
53obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o 55obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
54obj-$(CONFIG_INPUT_POWERMATE) += powermate.o 56obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
diff --git a/drivers/input/misc/max77843-haptic.c b/drivers/input/misc/max77843-haptic.c
new file mode 100644
index 000000000000..dccbb465a055
--- /dev/null
+++ b/drivers/input/misc/max77843-haptic.c
@@ -0,0 +1,358 @@
1/*
2 * MAXIM MAX77693 Haptic device driver
3 *
4 * Copyright (C) 2015 Samsung Electronics
5 * Author: Jaewon Kim <jaewon02.kim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/err.h>
14#include <linux/i2c.h>
15#include <linux/init.h>
16#include <linux/input.h>
17#include <linux/mfd/max77843-private.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/pwm.h>
21#include <linux/regmap.h>
22#include <linux/regulator/consumer.h>
23#include <linux/slab.h>
24#include <linux/workqueue.h>
25
26#define MAX_MAGNITUDE_SHIFT 16
27
28enum max77843_haptic_motor_type {
29 MAX77843_HAPTIC_ERM = 0,
30 MAX77843_HAPTIC_LRA,
31};
32
33enum max77843_haptic_pwm_divisor {
34 MAX77843_HAPTIC_PWM_DIVISOR_32 = 0,
35 MAX77843_HAPTIC_PWM_DIVISOR_64,
36 MAX77843_HAPTIC_PWM_DIVISOR_128,
37 MAX77843_HAPTIC_PWM_DIVISOR_256,
38};
39
40struct max77843_haptic {
41 struct regmap *regmap_haptic;
42 struct device *dev;
43 struct input_dev *input_dev;
44 struct pwm_device *pwm_dev;
45 struct regulator *motor_reg;
46 struct work_struct work;
47 struct mutex mutex;
48
49 unsigned int magnitude;
50 unsigned int pwm_duty;
51
52 bool active;
53 bool suspended;
54
55 enum max77843_haptic_motor_type type;
56 enum max77843_haptic_pwm_divisor pwm_divisor;
57};
58
59static int max77843_haptic_set_duty_cycle(struct max77843_haptic *haptic)
60{
61 int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2;
62 int error;
63
64 error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period);
65 if (error) {
66 dev_err(haptic->dev, "failed to configure pwm: %d\n", error);
67 return error;
68 }
69
70 return 0;
71}
72
73static int max77843_haptic_bias(struct max77843_haptic *haptic, bool on)
74{
75 int error;
76
77 error = regmap_update_bits(haptic->regmap_haptic,
78 MAX77843_SYS_REG_MAINCTRL1,
79 MAX77843_MAINCTRL1_BIASEN_MASK,
80 on << MAINCTRL1_BIASEN_SHIFT);
81 if (error) {
82 dev_err(haptic->dev, "failed to %s bias: %d\n",
83 on ? "enable" : "disable", error);
84 return error;
85 }
86
87 return 0;
88}
89
90static int max77843_haptic_config(struct max77843_haptic *haptic, bool enable)
91{
92 unsigned int value;
93 int error;
94
95 value = (haptic->type << MCONFIG_MODE_SHIFT) |
96 (enable << MCONFIG_MEN_SHIFT) |
97 (haptic->pwm_divisor << MCONFIG_PDIV_SHIFT);
98
99 error = regmap_write(haptic->regmap_haptic,
100 MAX77843_HAP_REG_MCONFIG, value);
101 if (error) {
102 dev_err(haptic->dev,
103 "failed to update haptic config: %d\n", error);
104 return error;
105 }
106
107 return 0;
108}
109
110static int max77843_haptic_enable(struct max77843_haptic *haptic)
111{
112 int error;
113
114 if (haptic->active)
115 return 0;
116
117 error = pwm_enable(haptic->pwm_dev);
118 if (error) {
119 dev_err(haptic->dev,
120 "failed to enable pwm device: %d\n", error);
121 return error;
122 }
123
124 error = max77843_haptic_config(haptic, true);
125 if (error)
126 goto err_config;
127
128 haptic->active = true;
129
130 return 0;
131
132err_config:
133 pwm_disable(haptic->pwm_dev);
134
135 return error;
136}
137
138static int max77843_haptic_disable(struct max77843_haptic *haptic)
139{
140 int error;
141
142 if (!haptic->active)
143 return 0;
144
145 error = max77843_haptic_config(haptic, false);
146 if (error)
147 return error;
148
149 pwm_disable(haptic->pwm_dev);
150
151 haptic->active = false;
152
153 return 0;
154}
155
156static void max77843_haptic_play_work(struct work_struct *work)
157{
158 struct max77843_haptic *haptic =
159 container_of(work, struct max77843_haptic, work);
160 int error;
161
162 mutex_lock(&haptic->mutex);
163
164 if (haptic->suspended)
165 goto out_unlock;
166
167 if (haptic->magnitude) {
168 error = max77843_haptic_set_duty_cycle(haptic);
169 if (error) {
170 dev_err(haptic->dev,
171 "failed to set duty cycle: %d\n", error);
172 goto out_unlock;
173 }
174
175 error = max77843_haptic_enable(haptic);
176 if (error)
177 dev_err(haptic->dev,
178 "cannot enable haptic: %d\n", error);
179 } else {
180 error = max77843_haptic_disable(haptic);
181 if (error)
182 dev_err(haptic->dev,
183 "cannot disable haptic: %d\n", error);
184 }
185
186out_unlock:
187 mutex_unlock(&haptic->mutex);
188}
189
190static int max77843_haptic_play_effect(struct input_dev *dev, void *data,
191 struct ff_effect *effect)
192{
193 struct max77843_haptic *haptic = input_get_drvdata(dev);
194 u64 period_mag_multi;
195
196 haptic->magnitude = effect->u.rumble.strong_magnitude;
197 if (!haptic->magnitude)
198 haptic->magnitude = effect->u.rumble.weak_magnitude;
199
200 period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude;
201 haptic->pwm_duty = (unsigned int)(period_mag_multi >>
202 MAX_MAGNITUDE_SHIFT);
203
204 schedule_work(&haptic->work);
205
206 return 0;
207}
208
209static int max77843_haptic_open(struct input_dev *dev)
210{
211 struct max77843_haptic *haptic = input_get_drvdata(dev);
212 int error;
213
214 error = max77843_haptic_bias(haptic, true);
215 if (error)
216 return error;
217
218 error = regulator_enable(haptic->motor_reg);
219 if (error) {
220 dev_err(haptic->dev,
221 "failed to enable regulator: %d\n", error);
222 return error;
223 }
224
225 return 0;
226}
227
228static void max77843_haptic_close(struct input_dev *dev)
229{
230 struct max77843_haptic *haptic = input_get_drvdata(dev);
231 int error;
232
233 cancel_work_sync(&haptic->work);
234 max77843_haptic_disable(haptic);
235
236 error = regulator_disable(haptic->motor_reg);
237 if (error)
238 dev_err(haptic->dev,
239 "failed to disable regulator: %d\n", error);
240
241 max77843_haptic_bias(haptic, false);
242}
243
244static int max77843_haptic_probe(struct platform_device *pdev)
245{
246 struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
247 struct max77843_haptic *haptic;
248 int error;
249
250 haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
251 if (!haptic)
252 return -ENOMEM;
253
254 haptic->regmap_haptic = max77843->regmap;
255 haptic->dev = &pdev->dev;
256 haptic->type = MAX77843_HAPTIC_LRA;
257 haptic->pwm_divisor = MAX77843_HAPTIC_PWM_DIVISOR_128;
258
259 INIT_WORK(&haptic->work, max77843_haptic_play_work);
260 mutex_init(&haptic->mutex);
261
262 haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL);
263 if (IS_ERR(haptic->pwm_dev)) {
264 dev_err(&pdev->dev, "failed to get pwm device\n");
265 return PTR_ERR(haptic->pwm_dev);
266 }
267
268 haptic->motor_reg = devm_regulator_get_exclusive(&pdev->dev, "haptic");
269 if (IS_ERR(haptic->motor_reg)) {
270 dev_err(&pdev->dev, "failed to get regulator\n");
271 return PTR_ERR(haptic->motor_reg);
272 }
273
274 haptic->input_dev = devm_input_allocate_device(&pdev->dev);
275 if (!haptic->input_dev) {
276 dev_err(&pdev->dev, "failed to allocate input device\n");
277 return -ENOMEM;
278 }
279
280 haptic->input_dev->name = "max77843-haptic";
281 haptic->input_dev->id.version = 1;
282 haptic->input_dev->dev.parent = &pdev->dev;
283 haptic->input_dev->open = max77843_haptic_open;
284 haptic->input_dev->close = max77843_haptic_close;
285 input_set_drvdata(haptic->input_dev, haptic);
286 input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);
287
288 error = input_ff_create_memless(haptic->input_dev, NULL,
289 max77843_haptic_play_effect);
290 if (error) {
291 dev_err(&pdev->dev, "failed to create force-feedback\n");
292 return error;
293 }
294
295 error = input_register_device(haptic->input_dev);
296 if (error) {
297 dev_err(&pdev->dev, "failed to register input device\n");
298 return error;
299 }
300
301 platform_set_drvdata(pdev, haptic);
302
303 return 0;
304}
305
306static int __maybe_unused max77843_haptic_suspend(struct device *dev)
307{
308 struct platform_device *pdev = to_platform_device(dev);
309 struct max77843_haptic *haptic = platform_get_drvdata(pdev);
310 int error;
311
312 error = mutex_lock_interruptible(&haptic->mutex);
313 if (error)
314 return error;
315
316 max77843_haptic_disable(haptic);
317
318 haptic->suspended = true;
319
320 mutex_unlock(&haptic->mutex);
321
322 return 0;
323}
324
325static int __maybe_unused max77843_haptic_resume(struct device *dev)
326{
327 struct platform_device *pdev = to_platform_device(dev);
328 struct max77843_haptic *haptic = platform_get_drvdata(pdev);
329 unsigned int magnitude;
330
331 mutex_lock(&haptic->mutex);
332
333 haptic->suspended = false;
334
335 magnitude = ACCESS_ONCE(haptic->magnitude);
336 if (magnitude)
337 max77843_haptic_enable(haptic);
338
339 mutex_unlock(&haptic->mutex);
340
341 return 0;
342}
343
344static SIMPLE_DEV_PM_OPS(max77843_haptic_pm_ops,
345 max77843_haptic_suspend, max77843_haptic_resume);
346
347static struct platform_driver max77843_haptic_driver = {
348 .driver = {
349 .name = "max77843-haptic",
350 .pm = &max77843_haptic_pm_ops,
351 },
352 .probe = max77843_haptic_probe,
353};
354module_platform_driver(max77843_haptic_driver);
355
356MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
357MODULE_DESCRIPTION("MAXIM MAX77843 Haptic driver");
358MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c
index 59d4dcddf6de..19c73574458e 100644
--- a/drivers/input/misc/mma8450.c
+++ b/drivers/input/misc/mma8450.c
@@ -174,12 +174,13 @@ static int mma8450_probe(struct i2c_client *c,
174 struct mma8450 *m; 174 struct mma8450 *m;
175 int err; 175 int err;
176 176
177 m = kzalloc(sizeof(struct mma8450), GFP_KERNEL); 177 m = devm_kzalloc(&c->dev, sizeof(*m), GFP_KERNEL);
178 idev = input_allocate_polled_device(); 178 if (!m)
179 if (!m || !idev) { 179 return -ENOMEM;
180 err = -ENOMEM; 180
181 goto err_free_mem; 181 idev = devm_input_allocate_polled_device(&c->dev);
182 } 182 if (!idev)
183 return -ENOMEM;
183 184
184 m->client = c; 185 m->client = c;
185 m->idev = idev; 186 m->idev = idev;
@@ -201,29 +202,12 @@ static int mma8450_probe(struct i2c_client *c,
201 err = input_register_polled_device(idev); 202 err = input_register_polled_device(idev);
202 if (err) { 203 if (err) {
203 dev_err(&c->dev, "failed to register polled input device\n"); 204 dev_err(&c->dev, "failed to register polled input device\n");
204 goto err_free_mem; 205 return err;
205 } 206 }
206 207
207 i2c_set_clientdata(c, m); 208 i2c_set_clientdata(c, m);
208 209
209 return 0; 210 return 0;
210
211err_free_mem:
212 input_free_polled_device(idev);
213 kfree(m);
214 return err;
215}
216
217static int mma8450_remove(struct i2c_client *c)
218{
219 struct mma8450 *m = i2c_get_clientdata(c);
220 struct input_polled_dev *idev = m->idev;
221
222 input_unregister_polled_device(idev);
223 input_free_polled_device(idev);
224 kfree(m);
225
226 return 0;
227} 211}
228 212
229static const struct i2c_device_id mma8450_id[] = { 213static const struct i2c_device_id mma8450_id[] = {
@@ -241,11 +225,9 @@ MODULE_DEVICE_TABLE(of, mma8450_dt_ids);
241static struct i2c_driver mma8450_driver = { 225static struct i2c_driver mma8450_driver = {
242 .driver = { 226 .driver = {
243 .name = MMA8450_DRV_NAME, 227 .name = MMA8450_DRV_NAME,
244 .owner = THIS_MODULE,
245 .of_match_table = mma8450_dt_ids, 228 .of_match_table = mma8450_dt_ids,
246 }, 229 },
247 .probe = mma8450_probe, 230 .probe = mma8450_probe,
248 .remove = mma8450_remove,
249 .id_table = mma8450_id, 231 .id_table = mma8450_id,
250}; 232};
251 233
diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c
index 1f9b5ee92746..1e1baed63929 100644
--- a/drivers/input/misc/palmas-pwrbutton.c
+++ b/drivers/input/misc/palmas-pwrbutton.c
@@ -304,7 +304,7 @@ static SIMPLE_DEV_PM_OPS(palmas_pwron_pm,
304 palmas_pwron_suspend, palmas_pwron_resume); 304 palmas_pwron_suspend, palmas_pwron_resume);
305 305
306#ifdef CONFIG_OF 306#ifdef CONFIG_OF
307static struct of_device_id of_palmas_pwr_match[] = { 307static const struct of_device_id of_palmas_pwr_match[] = {
308 { .compatible = "ti,palmas-pwrbutton" }, 308 { .compatible = "ti,palmas-pwrbutton" },
309 { }, 309 { },
310}; 310};
diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
new file mode 100644
index 000000000000..867db8a91372
--- /dev/null
+++ b/drivers/input/misc/pm8941-pwrkey.c
@@ -0,0 +1,293 @@
1/*
2 * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
3 * Copyright (c) 2014, Sony Mobile Communications Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/delay.h>
16#include <linux/errno.h>
17#include <linux/input.h>
18#include <linux/interrupt.h>
19#include <linux/kernel.h>
20#include <linux/log2.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/platform_device.h>
24#include <linux/reboot.h>
25#include <linux/regmap.h>
26
27#define PON_REV2 0x01
28
29#define PON_RT_STS 0x10
30#define PON_KPDPWR_N_SET BIT(0)
31
32#define PON_PS_HOLD_RST_CTL 0x5a
33#define PON_PS_HOLD_RST_CTL2 0x5b
34#define PON_PS_HOLD_ENABLE BIT(7)
35#define PON_PS_HOLD_TYPE_MASK 0x0f
36#define PON_PS_HOLD_TYPE_SHUTDOWN 4
37#define PON_PS_HOLD_TYPE_HARD_RESET 7
38
39#define PON_PULL_CTL 0x70
40#define PON_KPDPWR_PULL_UP BIT(1)
41
42#define PON_DBC_CTL 0x71
43#define PON_DBC_DELAY_MASK 0x7
44
45
46struct pm8941_pwrkey {
47 struct device *dev;
48 int irq;
49 u32 baseaddr;
50 struct regmap *regmap;
51 struct input_dev *input;
52
53 unsigned int revision;
54 struct notifier_block reboot_notifier;
55};
56
57static int pm8941_reboot_notify(struct notifier_block *nb,
58 unsigned long code, void *unused)
59{
60 struct pm8941_pwrkey *pwrkey = container_of(nb, struct pm8941_pwrkey,
61 reboot_notifier);
62 unsigned int enable_reg;
63 unsigned int reset_type;
64 int error;
65
66 /* PMICs with revision 0 have the enable bit in same register as ctrl */
67 if (pwrkey->revision == 0)
68 enable_reg = PON_PS_HOLD_RST_CTL;
69 else
70 enable_reg = PON_PS_HOLD_RST_CTL2;
71
72 error = regmap_update_bits(pwrkey->regmap,
73 pwrkey->baseaddr + enable_reg,
74 PON_PS_HOLD_ENABLE,
75 0);
76 if (error)
77 dev_err(pwrkey->dev,
78 "unable to clear ps hold reset enable: %d\n",
79 error);
80
81 /*
82 * Updates of PON_PS_HOLD_ENABLE requires 3 sleep cycles between
83 * writes.
84 */
85 usleep_range(100, 1000);
86
87 switch (code) {
88 case SYS_HALT:
89 case SYS_POWER_OFF:
90 reset_type = PON_PS_HOLD_TYPE_SHUTDOWN;
91 break;
92 case SYS_RESTART:
93 default:
94 reset_type = PON_PS_HOLD_TYPE_HARD_RESET;
95 break;
96 };
97
98 error = regmap_update_bits(pwrkey->regmap,
99 pwrkey->baseaddr + PON_PS_HOLD_RST_CTL,
100 PON_PS_HOLD_TYPE_MASK,
101 reset_type);
102 if (error)
103 dev_err(pwrkey->dev, "unable to set ps hold reset type: %d\n",
104 error);
105
106 error = regmap_update_bits(pwrkey->regmap,
107 pwrkey->baseaddr + enable_reg,
108 PON_PS_HOLD_ENABLE,
109 PON_PS_HOLD_ENABLE);
110 if (error)
111 dev_err(pwrkey->dev, "unable to re-set enable: %d\n", error);
112
113 return NOTIFY_DONE;
114}
115
116static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
117{
118 struct pm8941_pwrkey *pwrkey = _data;
119 unsigned int sts;
120 int error;
121
122 error = regmap_read(pwrkey->regmap,
123 pwrkey->baseaddr + PON_RT_STS, &sts);
124 if (error)
125 return IRQ_HANDLED;
126
127 input_report_key(pwrkey->input, KEY_POWER, !!(sts & PON_KPDPWR_N_SET));
128 input_sync(pwrkey->input);
129
130 return IRQ_HANDLED;
131}
132
133static int __maybe_unused pm8941_pwrkey_suspend(struct device *dev)
134{
135 struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
136
137 if (device_may_wakeup(dev))
138 enable_irq_wake(pwrkey->irq);
139
140 return 0;
141}
142
143static int __maybe_unused pm8941_pwrkey_resume(struct device *dev)
144{
145 struct pm8941_pwrkey *pwrkey = dev_get_drvdata(dev);
146
147 if (device_may_wakeup(dev))
148 disable_irq_wake(pwrkey->irq);
149
150 return 0;
151}
152
153static SIMPLE_DEV_PM_OPS(pm8941_pwr_key_pm_ops,
154 pm8941_pwrkey_suspend, pm8941_pwrkey_resume);
155
156static int pm8941_pwrkey_probe(struct platform_device *pdev)
157{
158 struct pm8941_pwrkey *pwrkey;
159 bool pull_up;
160 u32 req_delay;
161 int error;
162
163 if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
164 req_delay = 15625;
165
166 if (req_delay > 2000000 || req_delay == 0) {
167 dev_err(&pdev->dev, "invalid debounce time: %u\n", req_delay);
168 return -EINVAL;
169 }
170
171 pull_up = of_property_read_bool(pdev->dev.of_node, "bias-pull-up");
172
173 pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL);
174 if (!pwrkey)
175 return -ENOMEM;
176
177 pwrkey->dev = &pdev->dev;
178
179 pwrkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
180 if (!pwrkey->regmap) {
181 dev_err(&pdev->dev, "failed to locate regmap\n");
182 return -ENODEV;
183 }
184
185 pwrkey->irq = platform_get_irq(pdev, 0);
186 if (pwrkey->irq < 0) {
187 dev_err(&pdev->dev, "failed to get irq\n");
188 return pwrkey->irq;
189 }
190
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,
197 &pwrkey->revision);
198 if (error) {
199 dev_err(&pdev->dev, "failed to set debounce: %d\n", error);
200 return error;
201 }
202
203 pwrkey->input = devm_input_allocate_device(&pdev->dev);
204 if (!pwrkey->input) {
205 dev_dbg(&pdev->dev, "unable to allocate input device\n");
206 return -ENOMEM;
207 }
208
209 input_set_capability(pwrkey->input, EV_KEY, KEY_POWER);
210
211 pwrkey->input->name = "pm8941_pwrkey";
212 pwrkey->input->phys = "pm8941_pwrkey/input0";
213
214 req_delay = (req_delay << 6) / USEC_PER_SEC;
215 req_delay = ilog2(req_delay);
216
217 error = regmap_update_bits(pwrkey->regmap,
218 pwrkey->baseaddr + PON_DBC_CTL,
219 PON_DBC_DELAY_MASK,
220 req_delay);
221 if (error) {
222 dev_err(&pdev->dev, "failed to set debounce: %d\n", error);
223 return error;
224 }
225
226 error = regmap_update_bits(pwrkey->regmap,
227 pwrkey->baseaddr + PON_PULL_CTL,
228 PON_KPDPWR_PULL_UP,
229 pull_up ? PON_KPDPWR_PULL_UP : 0);
230 if (error) {
231 dev_err(&pdev->dev, "failed to set pull: %d\n", error);
232 return error;
233 }
234
235 error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
236 NULL, pm8941_pwrkey_irq,
237 IRQF_ONESHOT,
238 "pm8941_pwrkey", pwrkey);
239 if (error) {
240 dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
241 return error;
242 }
243
244 error = input_register_device(pwrkey->input);
245 if (error) {
246 dev_err(&pdev->dev, "failed to register input device: %d\n",
247 error);
248 return error;
249 }
250
251 pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify,
252 error = register_reboot_notifier(&pwrkey->reboot_notifier);
253 if (error) {
254 dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
255 error);
256 return error;
257 }
258
259 platform_set_drvdata(pdev, pwrkey);
260 device_init_wakeup(&pdev->dev, 1);
261
262 return 0;
263}
264
265static int pm8941_pwrkey_remove(struct platform_device *pdev)
266{
267 struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
268
269 device_init_wakeup(&pdev->dev, 0);
270 unregister_reboot_notifier(&pwrkey->reboot_notifier);
271
272 return 0;
273}
274
275static const struct of_device_id pm8941_pwr_key_id_table[] = {
276 { .compatible = "qcom,pm8941-pwrkey" },
277 { }
278};
279MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
280
281static struct platform_driver pm8941_pwrkey_driver = {
282 .probe = pm8941_pwrkey_probe,
283 .remove = pm8941_pwrkey_remove,
284 .driver = {
285 .name = "pm8941-pwrkey",
286 .pm = &pm8941_pwr_key_pm_ops,
287 .of_match_table = of_match_ptr(pm8941_pwr_key_id_table),
288 },
289};
290module_platform_driver(pm8941_pwrkey_driver);
291
292MODULE_DESCRIPTION("PM8941 Power Key driver");
293MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
index a28ee70ff158..e82edf810d1f 100644
--- a/drivers/input/misc/pwm-beeper.c
+++ b/drivers/input/misc/pwm-beeper.c
@@ -50,7 +50,6 @@ static int pwm_beeper_event(struct input_dev *input,
50 } 50 }
51 51
52 if (value == 0) { 52 if (value == 0) {
53 pwm_config(beeper->pwm, 0, 0);
54 pwm_disable(beeper->pwm); 53 pwm_disable(beeper->pwm);
55 } else { 54 } else {
56 period = HZ_TO_NANOSECONDS(value); 55 period = HZ_TO_NANOSECONDS(value);
@@ -169,12 +168,6 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev)
169static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, 168static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops,
170 pwm_beeper_suspend, pwm_beeper_resume); 169 pwm_beeper_suspend, pwm_beeper_resume);
171 170
172#ifdef CONFIG_PM_SLEEP
173#define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops)
174#else
175#define PWM_BEEPER_PM_OPS NULL
176#endif
177
178#ifdef CONFIG_OF 171#ifdef CONFIG_OF
179static const struct of_device_id pwm_beeper_match[] = { 172static const struct of_device_id pwm_beeper_match[] = {
180 { .compatible = "pwm-beeper", }, 173 { .compatible = "pwm-beeper", },
@@ -187,7 +180,7 @@ static struct platform_driver pwm_beeper_driver = {
187 .remove = pwm_beeper_remove, 180 .remove = pwm_beeper_remove,
188 .driver = { 181 .driver = {
189 .name = "pwm-beeper", 182 .name = "pwm-beeper",
190 .pm = PWM_BEEPER_PM_OPS, 183 .pm = &pwm_beeper_pm_ops,
191 .of_match_table = of_match_ptr(pwm_beeper_match), 184 .of_match_table = of_match_ptr(pwm_beeper_match),
192 }, 185 },
193}; 186};
diff --git a/drivers/input/misc/regulator-haptic.c b/drivers/input/misc/regulator-haptic.c
index 132eb914ea3e..6bf3f1082f71 100644
--- a/drivers/input/misc/regulator-haptic.c
+++ b/drivers/input/misc/regulator-haptic.c
@@ -245,7 +245,7 @@ static int __maybe_unused regulator_haptic_resume(struct device *dev)
245static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops, 245static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops,
246 regulator_haptic_suspend, regulator_haptic_resume); 246 regulator_haptic_suspend, regulator_haptic_resume);
247 247
248static struct of_device_id regulator_haptic_dt_match[] = { 248static const struct of_device_id regulator_haptic_dt_match[] = {
249 { .compatible = "regulator-haptic" }, 249 { .compatible = "regulator-haptic" },
250 { /* sentinel */ }, 250 { /* sentinel */ },
251}; 251};
diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
index 54508dec4eb3..a39b62651a4b 100644
--- a/drivers/input/misc/tps65218-pwrbutton.c
+++ b/drivers/input/misc/tps65218-pwrbutton.c
@@ -106,7 +106,7 @@ static int tps65218_pwron_probe(struct platform_device *pdev)
106 return 0; 106 return 0;
107} 107}
108 108
109static struct of_device_id of_tps65218_pwr_match[] = { 109static const struct of_device_id of_tps65218_pwr_match[] = {
110 { .compatible = "ti,tps65218-pwrbutton" }, 110 { .compatible = "ti,tps65218-pwrbutton" },
111 { }, 111 { },
112}; 112};