treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / input / misc / msm-vibrator.c
blobb60f1aaee70531e42b401a91566b5ad143d24628
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Qualcomm MSM vibrator driver
5 * Copyright (c) 2018 Brian Masney <masneyb@onstation.org>
7 * Based on qcom,pwm-vibrator.c from:
8 * Copyright (c) 2018 Jonathan Marek <jonathan@marek.ca>
10 * Based on msm_pwm_vibrator.c from downstream Android sources:
11 * Copyright (C) 2009-2014 LGE, Inc.
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/input.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/platform_device.h>
22 #include <linux/regulator/consumer.h>
24 #define REG_CMD_RCGR 0x00
25 #define REG_CFG_RCGR 0x04
26 #define REG_M 0x08
27 #define REG_N 0x0C
28 #define REG_D 0x10
29 #define REG_CBCR 0x24
30 #define MMSS_CC_M_DEFAULT 1
32 struct msm_vibrator {
33 struct input_dev *input;
34 struct mutex mutex;
35 struct work_struct worker;
36 void __iomem *base;
37 struct regulator *vcc;
38 struct clk *clk;
39 struct gpio_desc *enable_gpio;
40 u16 magnitude;
41 bool enabled;
44 static void msm_vibrator_write(struct msm_vibrator *vibrator, int offset,
45 u32 value)
47 writel(value, vibrator->base + offset);
50 static int msm_vibrator_start(struct msm_vibrator *vibrator)
52 int d_reg_val, ret = 0;
54 mutex_lock(&vibrator->mutex);
56 if (!vibrator->enabled) {
57 ret = clk_set_rate(vibrator->clk, 24000);
58 if (ret) {
59 dev_err(&vibrator->input->dev,
60 "Failed to set clock rate: %d\n", ret);
61 goto unlock;
64 ret = clk_prepare_enable(vibrator->clk);
65 if (ret) {
66 dev_err(&vibrator->input->dev,
67 "Failed to enable clock: %d\n", ret);
68 goto unlock;
71 ret = regulator_enable(vibrator->vcc);
72 if (ret) {
73 dev_err(&vibrator->input->dev,
74 "Failed to enable regulator: %d\n", ret);
75 clk_disable(vibrator->clk);
76 goto unlock;
79 gpiod_set_value_cansleep(vibrator->enable_gpio, 1);
81 vibrator->enabled = true;
84 d_reg_val = 127 - ((126 * vibrator->magnitude) / 0xffff);
85 msm_vibrator_write(vibrator, REG_CFG_RCGR,
86 (2 << 12) | /* dual edge mode */
87 (0 << 8) | /* cxo */
88 (7 << 0));
89 msm_vibrator_write(vibrator, REG_M, 1);
90 msm_vibrator_write(vibrator, REG_N, 128);
91 msm_vibrator_write(vibrator, REG_D, d_reg_val);
92 msm_vibrator_write(vibrator, REG_CMD_RCGR, 1);
93 msm_vibrator_write(vibrator, REG_CBCR, 1);
95 unlock:
96 mutex_unlock(&vibrator->mutex);
98 return ret;
101 static void msm_vibrator_stop(struct msm_vibrator *vibrator)
103 mutex_lock(&vibrator->mutex);
105 if (vibrator->enabled) {
106 gpiod_set_value_cansleep(vibrator->enable_gpio, 0);
107 regulator_disable(vibrator->vcc);
108 clk_disable(vibrator->clk);
109 vibrator->enabled = false;
112 mutex_unlock(&vibrator->mutex);
115 static void msm_vibrator_worker(struct work_struct *work)
117 struct msm_vibrator *vibrator = container_of(work,
118 struct msm_vibrator,
119 worker);
121 if (vibrator->magnitude)
122 msm_vibrator_start(vibrator);
123 else
124 msm_vibrator_stop(vibrator);
127 static int msm_vibrator_play_effect(struct input_dev *dev, void *data,
128 struct ff_effect *effect)
130 struct msm_vibrator *vibrator = input_get_drvdata(dev);
132 mutex_lock(&vibrator->mutex);
134 if (effect->u.rumble.strong_magnitude > 0)
135 vibrator->magnitude = effect->u.rumble.strong_magnitude;
136 else
137 vibrator->magnitude = effect->u.rumble.weak_magnitude;
139 mutex_unlock(&vibrator->mutex);
141 schedule_work(&vibrator->worker);
143 return 0;
146 static void msm_vibrator_close(struct input_dev *input)
148 struct msm_vibrator *vibrator = input_get_drvdata(input);
150 cancel_work_sync(&vibrator->worker);
151 msm_vibrator_stop(vibrator);
154 static int msm_vibrator_probe(struct platform_device *pdev)
156 struct msm_vibrator *vibrator;
157 struct resource *res;
158 int ret;
160 vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
161 if (!vibrator)
162 return -ENOMEM;
164 vibrator->input = devm_input_allocate_device(&pdev->dev);
165 if (!vibrator->input)
166 return -ENOMEM;
168 vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
169 if (IS_ERR(vibrator->vcc)) {
170 if (PTR_ERR(vibrator->vcc) != -EPROBE_DEFER)
171 dev_err(&pdev->dev, "Failed to get regulator: %ld\n",
172 PTR_ERR(vibrator->vcc));
173 return PTR_ERR(vibrator->vcc);
176 vibrator->enable_gpio = devm_gpiod_get(&pdev->dev, "enable",
177 GPIOD_OUT_LOW);
178 if (IS_ERR(vibrator->enable_gpio)) {
179 if (PTR_ERR(vibrator->enable_gpio) != -EPROBE_DEFER)
180 dev_err(&pdev->dev, "Failed to get enable gpio: %ld\n",
181 PTR_ERR(vibrator->enable_gpio));
182 return PTR_ERR(vibrator->enable_gpio);
185 vibrator->clk = devm_clk_get(&pdev->dev, "pwm");
186 if (IS_ERR(vibrator->clk)) {
187 if (PTR_ERR(vibrator->clk) != -EPROBE_DEFER)
188 dev_err(&pdev->dev, "Failed to lookup pwm clock: %ld\n",
189 PTR_ERR(vibrator->clk));
190 return PTR_ERR(vibrator->clk);
193 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
194 if (!res) {
195 dev_err(&pdev->dev, "Failed to get platform resource\n");
196 return -ENODEV;
199 vibrator->base = devm_ioremap(&pdev->dev, res->start,
200 resource_size(res));
201 if (!vibrator->base) {
202 dev_err(&pdev->dev, "Failed to iomap resource.\n");
203 return -ENOMEM;
206 vibrator->enabled = false;
207 mutex_init(&vibrator->mutex);
208 INIT_WORK(&vibrator->worker, msm_vibrator_worker);
210 vibrator->input->name = "msm-vibrator";
211 vibrator->input->id.bustype = BUS_HOST;
212 vibrator->input->close = msm_vibrator_close;
214 input_set_drvdata(vibrator->input, vibrator);
215 input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
217 ret = input_ff_create_memless(vibrator->input, NULL,
218 msm_vibrator_play_effect);
219 if (ret) {
220 dev_err(&pdev->dev, "Failed to create ff memless: %d", ret);
221 return ret;
224 ret = input_register_device(vibrator->input);
225 if (ret) {
226 dev_err(&pdev->dev, "Failed to register input device: %d", ret);
227 return ret;
230 platform_set_drvdata(pdev, vibrator);
232 return 0;
235 static int __maybe_unused msm_vibrator_suspend(struct device *dev)
237 struct platform_device *pdev = to_platform_device(dev);
238 struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
240 cancel_work_sync(&vibrator->worker);
242 if (vibrator->enabled)
243 msm_vibrator_stop(vibrator);
245 return 0;
248 static int __maybe_unused msm_vibrator_resume(struct device *dev)
250 struct platform_device *pdev = to_platform_device(dev);
251 struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
253 if (vibrator->enabled)
254 msm_vibrator_start(vibrator);
256 return 0;
259 static SIMPLE_DEV_PM_OPS(msm_vibrator_pm_ops, msm_vibrator_suspend,
260 msm_vibrator_resume);
262 static const struct of_device_id msm_vibrator_of_match[] = {
263 { .compatible = "qcom,msm8226-vibrator" },
264 { .compatible = "qcom,msm8974-vibrator" },
267 MODULE_DEVICE_TABLE(of, msm_vibrator_of_match);
269 static struct platform_driver msm_vibrator_driver = {
270 .probe = msm_vibrator_probe,
271 .driver = {
272 .name = "msm-vibrator",
273 .pm = &msm_vibrator_pm_ops,
274 .of_match_table = of_match_ptr(msm_vibrator_of_match),
277 module_platform_driver(msm_vibrator_driver);
279 MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
280 MODULE_DESCRIPTION("Qualcomm MSM vibrator driver");
281 MODULE_LICENSE("GPL");