2 * Regulator haptic driver
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * Author: Jaewon Kim <jaewon02.kim@samsung.com>
6 * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/input.h>
14 #include <linux/module.h>
16 #include <linux/platform_data/regulator-haptic.h>
17 #include <linux/platform_device.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/slab.h>
21 #define MAX_MAGNITUDE_SHIFT 16
23 struct regulator_haptic
{
25 struct input_dev
*input_dev
;
26 struct regulator
*regulator
;
28 struct work_struct work
;
34 unsigned int max_volt
;
35 unsigned int min_volt
;
36 unsigned int magnitude
;
39 static int regulator_haptic_toggle(struct regulator_haptic
*haptic
, bool on
)
43 if (haptic
->active
!= on
) {
45 error
= on
? regulator_enable(haptic
->regulator
) :
46 regulator_disable(haptic
->regulator
);
49 "failed to switch regulator %s: %d\n",
50 on
? "on" : "off", error
);
60 static int regulator_haptic_set_voltage(struct regulator_haptic
*haptic
,
61 unsigned int magnitude
)
64 unsigned int intensity
;
67 volt_mag_multi
= (u64
)(haptic
->max_volt
- haptic
->min_volt
) * magnitude
;
68 intensity
= (unsigned int)(volt_mag_multi
>> MAX_MAGNITUDE_SHIFT
);
70 error
= regulator_set_voltage(haptic
->regulator
,
71 intensity
+ haptic
->min_volt
,
74 dev_err(haptic
->dev
, "cannot set regulator voltage to %d: %d\n",
75 intensity
+ haptic
->min_volt
, error
);
79 regulator_haptic_toggle(haptic
, !!magnitude
);
84 static void regulator_haptic_work(struct work_struct
*work
)
86 struct regulator_haptic
*haptic
= container_of(work
,
87 struct regulator_haptic
, work
);
89 mutex_lock(&haptic
->mutex
);
91 if (!haptic
->suspended
)
92 regulator_haptic_set_voltage(haptic
, haptic
->magnitude
);
94 mutex_unlock(&haptic
->mutex
);
97 static int regulator_haptic_play_effect(struct input_dev
*input
, void *data
,
98 struct ff_effect
*effect
)
100 struct regulator_haptic
*haptic
= input_get_drvdata(input
);
102 haptic
->magnitude
= effect
->u
.rumble
.strong_magnitude
;
103 if (!haptic
->magnitude
)
104 haptic
->magnitude
= effect
->u
.rumble
.weak_magnitude
;
106 schedule_work(&haptic
->work
);
111 static void regulator_haptic_close(struct input_dev
*input
)
113 struct regulator_haptic
*haptic
= input_get_drvdata(input
);
115 cancel_work_sync(&haptic
->work
);
116 regulator_haptic_set_voltage(haptic
, 0);
119 static int __maybe_unused
120 regulator_haptic_parse_dt(struct device
*dev
, struct regulator_haptic
*haptic
)
122 struct device_node
*node
;
127 dev_err(dev
, "Missing dveice tree data\n");
131 error
= of_property_read_u32(node
, "max-microvolt", &haptic
->max_volt
);
133 dev_err(dev
, "cannot parse max-microvolt\n");
137 error
= of_property_read_u32(node
, "min-microvolt", &haptic
->min_volt
);
139 dev_err(dev
, "cannot parse min-microvolt\n");
146 static int regulator_haptic_probe(struct platform_device
*pdev
)
148 const struct regulator_haptic_data
*pdata
= dev_get_platdata(&pdev
->dev
);
149 struct regulator_haptic
*haptic
;
150 struct input_dev
*input_dev
;
153 haptic
= devm_kzalloc(&pdev
->dev
, sizeof(*haptic
), GFP_KERNEL
);
157 platform_set_drvdata(pdev
, haptic
);
158 haptic
->dev
= &pdev
->dev
;
159 mutex_init(&haptic
->mutex
);
160 INIT_WORK(&haptic
->work
, regulator_haptic_work
);
163 haptic
->max_volt
= pdata
->max_volt
;
164 haptic
->min_volt
= pdata
->min_volt
;
165 } else if (IS_ENABLED(CONFIG_OF
)) {
166 error
= regulator_haptic_parse_dt(&pdev
->dev
, haptic
);
170 dev_err(&pdev
->dev
, "Missing platform data\n");
174 haptic
->regulator
= devm_regulator_get_exclusive(&pdev
->dev
, "haptic");
175 if (IS_ERR(haptic
->regulator
)) {
176 dev_err(&pdev
->dev
, "failed to get regulator\n");
177 return PTR_ERR(haptic
->regulator
);
180 input_dev
= devm_input_allocate_device(&pdev
->dev
);
184 haptic
->input_dev
= input_dev
;
185 haptic
->input_dev
->name
= "regulator-haptic";
186 haptic
->input_dev
->dev
.parent
= &pdev
->dev
;
187 haptic
->input_dev
->close
= regulator_haptic_close
;
188 input_set_drvdata(haptic
->input_dev
, haptic
);
189 input_set_capability(haptic
->input_dev
, EV_FF
, FF_RUMBLE
);
191 error
= input_ff_create_memless(input_dev
, NULL
,
192 regulator_haptic_play_effect
);
194 dev_err(&pdev
->dev
, "failed to create force-feedback\n");
198 error
= input_register_device(haptic
->input_dev
);
200 dev_err(&pdev
->dev
, "failed to register input device\n");
207 static int __maybe_unused
regulator_haptic_suspend(struct device
*dev
)
209 struct platform_device
*pdev
= to_platform_device(dev
);
210 struct regulator_haptic
*haptic
= platform_get_drvdata(pdev
);
213 error
= mutex_lock_interruptible(&haptic
->mutex
);
217 regulator_haptic_set_voltage(haptic
, 0);
219 haptic
->suspended
= true;
221 mutex_unlock(&haptic
->mutex
);
226 static int __maybe_unused
regulator_haptic_resume(struct device
*dev
)
228 struct platform_device
*pdev
= to_platform_device(dev
);
229 struct regulator_haptic
*haptic
= platform_get_drvdata(pdev
);
230 unsigned int magnitude
;
232 mutex_lock(&haptic
->mutex
);
234 haptic
->suspended
= false;
236 magnitude
= ACCESS_ONCE(haptic
->magnitude
);
238 regulator_haptic_set_voltage(haptic
, magnitude
);
240 mutex_unlock(&haptic
->mutex
);
245 static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops
,
246 regulator_haptic_suspend
, regulator_haptic_resume
);
248 static const struct of_device_id regulator_haptic_dt_match
[] = {
249 { .compatible
= "regulator-haptic" },
252 MODULE_DEVICE_TABLE(of
, regulator_haptic_dt_match
);
254 static struct platform_driver regulator_haptic_driver
= {
255 .probe
= regulator_haptic_probe
,
257 .name
= "regulator-haptic",
258 .of_match_table
= regulator_haptic_dt_match
,
259 .pm
= ®ulator_haptic_pm_ops
,
262 module_platform_driver(regulator_haptic_driver
);
264 MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
265 MODULE_AUTHOR("Hyunhee Kim <hyunhee.kim@samsung.com>");
266 MODULE_DESCRIPTION("Regulator haptic driver");
267 MODULE_LICENSE("GPL");