Merge tag 'reset-for-v5.3' of git://git.pengutronix.de/git/pza/linux into arm/drivers
[sfrench/cifs-2.6.git] / drivers / input / misc / pm8xxx-vibrator.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
3  */
4
5 #include <linux/errno.h>
6 #include <linux/input.h>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/of.h>
10 #include <linux/of_device.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/slab.h>
14
15 #define VIB_MAX_LEVEL_mV        (3100)
16 #define VIB_MIN_LEVEL_mV        (1200)
17 #define VIB_MAX_LEVELS          (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
18
19 #define MAX_FF_SPEED            0xff
20
21 struct pm8xxx_regs {
22         unsigned int enable_addr;
23         unsigned int enable_mask;
24
25         unsigned int drv_addr;
26         unsigned int drv_mask;
27         unsigned int drv_shift;
28         unsigned int drv_en_manual_mask;
29 };
30
31 static const struct pm8xxx_regs pm8058_regs = {
32         .drv_addr = 0x4A,
33         .drv_mask = 0xf8,
34         .drv_shift = 3,
35         .drv_en_manual_mask = 0xfc,
36 };
37
38 static struct pm8xxx_regs pm8916_regs = {
39         .enable_addr = 0xc046,
40         .enable_mask = BIT(7),
41         .drv_addr = 0xc041,
42         .drv_mask = 0x1F,
43         .drv_shift = 0,
44         .drv_en_manual_mask = 0,
45 };
46
47 /**
48  * struct pm8xxx_vib - structure to hold vibrator data
49  * @vib_input_dev: input device supporting force feedback
50  * @work: work structure to set the vibration parameters
51  * @regmap: regmap for register read/write
52  * @regs: registers' info
53  * @speed: speed of vibration set from userland
54  * @active: state of vibrator
55  * @level: level of vibration to set in the chip
56  * @reg_vib_drv: regs->drv_addr register value
57  */
58 struct pm8xxx_vib {
59         struct input_dev *vib_input_dev;
60         struct work_struct work;
61         struct regmap *regmap;
62         const struct pm8xxx_regs *regs;
63         int speed;
64         int level;
65         bool active;
66         u8  reg_vib_drv;
67 };
68
69 /**
70  * pm8xxx_vib_set - handler to start/stop vibration
71  * @vib: pointer to vibrator structure
72  * @on: state to set
73  */
74 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
75 {
76         int rc;
77         unsigned int val = vib->reg_vib_drv;
78         const struct pm8xxx_regs *regs = vib->regs;
79
80         if (on)
81                 val |= (vib->level << regs->drv_shift) & regs->drv_mask;
82         else
83                 val &= ~regs->drv_mask;
84
85         rc = regmap_write(vib->regmap, regs->drv_addr, val);
86         if (rc < 0)
87                 return rc;
88
89         vib->reg_vib_drv = val;
90
91         if (regs->enable_mask)
92                 rc = regmap_update_bits(vib->regmap, regs->enable_addr,
93                                         on ? regs->enable_mask : 0, val);
94
95         return rc;
96 }
97
98 /**
99  * pm8xxx_work_handler - worker to set vibration level
100  * @work: pointer to work_struct
101  */
102 static void pm8xxx_work_handler(struct work_struct *work)
103 {
104         struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
105         const struct pm8xxx_regs *regs = vib->regs;
106         int rc;
107         unsigned int val;
108
109         rc = regmap_read(vib->regmap, regs->drv_addr, &val);
110         if (rc < 0)
111                 return;
112
113         /*
114          * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
115          * scale the level to fit into these ranges.
116          */
117         if (vib->speed) {
118                 vib->active = true;
119                 vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
120                                                 VIB_MIN_LEVEL_mV;
121                 vib->level /= 100;
122         } else {
123                 vib->active = false;
124                 vib->level = VIB_MIN_LEVEL_mV / 100;
125         }
126
127         pm8xxx_vib_set(vib, vib->active);
128 }
129
130 /**
131  * pm8xxx_vib_close - callback of input close callback
132  * @dev: input device pointer
133  *
134  * Turns off the vibrator.
135  */
136 static void pm8xxx_vib_close(struct input_dev *dev)
137 {
138         struct pm8xxx_vib *vib = input_get_drvdata(dev);
139
140         cancel_work_sync(&vib->work);
141         if (vib->active)
142                 pm8xxx_vib_set(vib, false);
143 }
144
145 /**
146  * pm8xxx_vib_play_effect - function to handle vib effects.
147  * @dev: input device pointer
148  * @data: data of effect
149  * @effect: effect to play
150  *
151  * Currently this driver supports only rumble effects.
152  */
153 static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
154                                   struct ff_effect *effect)
155 {
156         struct pm8xxx_vib *vib = input_get_drvdata(dev);
157
158         vib->speed = effect->u.rumble.strong_magnitude >> 8;
159         if (!vib->speed)
160                 vib->speed = effect->u.rumble.weak_magnitude >> 9;
161
162         schedule_work(&vib->work);
163
164         return 0;
165 }
166
167 static int pm8xxx_vib_probe(struct platform_device *pdev)
168 {
169         struct pm8xxx_vib *vib;
170         struct input_dev *input_dev;
171         int error;
172         unsigned int val;
173         const struct pm8xxx_regs *regs;
174
175         vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
176         if (!vib)
177                 return -ENOMEM;
178
179         vib->regmap = dev_get_regmap(pdev->dev.parent, NULL);
180         if (!vib->regmap)
181                 return -ENODEV;
182
183         input_dev = devm_input_allocate_device(&pdev->dev);
184         if (!input_dev)
185                 return -ENOMEM;
186
187         INIT_WORK(&vib->work, pm8xxx_work_handler);
188         vib->vib_input_dev = input_dev;
189
190         regs = of_device_get_match_data(&pdev->dev);
191
192         /* operate in manual mode */
193         error = regmap_read(vib->regmap, regs->drv_addr, &val);
194         if (error < 0)
195                 return error;
196
197         val &= regs->drv_en_manual_mask;
198         error = regmap_write(vib->regmap, regs->drv_addr, val);
199         if (error < 0)
200                 return error;
201
202         vib->regs = regs;
203         vib->reg_vib_drv = val;
204
205         input_dev->name = "pm8xxx_vib_ffmemless";
206         input_dev->id.version = 1;
207         input_dev->close = pm8xxx_vib_close;
208         input_set_drvdata(input_dev, vib);
209         input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
210
211         error = input_ff_create_memless(input_dev, NULL,
212                                         pm8xxx_vib_play_effect);
213         if (error) {
214                 dev_err(&pdev->dev,
215                         "couldn't register vibrator as FF device\n");
216                 return error;
217         }
218
219         error = input_register_device(input_dev);
220         if (error) {
221                 dev_err(&pdev->dev, "couldn't register input device\n");
222                 return error;
223         }
224
225         platform_set_drvdata(pdev, vib);
226         return 0;
227 }
228
229 static int __maybe_unused pm8xxx_vib_suspend(struct device *dev)
230 {
231         struct pm8xxx_vib *vib = dev_get_drvdata(dev);
232
233         /* Turn off the vibrator */
234         pm8xxx_vib_set(vib, false);
235
236         return 0;
237 }
238
239 static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
240
241 static const struct of_device_id pm8xxx_vib_id_table[] = {
242         { .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
243         { .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
244         { .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
245         { }
246 };
247 MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table);
248
249 static struct platform_driver pm8xxx_vib_driver = {
250         .probe          = pm8xxx_vib_probe,
251         .driver         = {
252                 .name   = "pm8xxx-vib",
253                 .pm     = &pm8xxx_vib_pm_ops,
254                 .of_match_table = pm8xxx_vib_id_table,
255         },
256 };
257 module_platform_driver(pm8xxx_vib_driver);
258
259 MODULE_ALIAS("platform:pm8xxx_vib");
260 MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
261 MODULE_LICENSE("GPL v2");
262 MODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");