Merge tag 'io_uring-5.15-2021-09-11' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / pwm / pwm-twl.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for TWL4030/6030 Generic Pulse Width Modulator
4  *
5  * Copyright (C) 2012 Texas Instruments
6  * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7  */
8
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
12 #include <linux/pwm.h>
13 #include <linux/mfd/twl.h>
14 #include <linux/slab.h>
15
16 /*
17  * This driver handles the PWMs of TWL4030 and TWL6030.
18  * The TRM names for the PWMs on TWL4030 are: PWM0, PWM1
19  * TWL6030 also have two PWMs named in the TRM as PWM1, PWM2
20  */
21
22 #define TWL_PWM_MAX             0x7f
23
24 /* Registers, bits and macro for TWL4030 */
25 #define TWL4030_GPBR1_REG       0x0c
26 #define TWL4030_PMBR1_REG       0x0d
27
28 /* GPBR1 register bits */
29 #define TWL4030_PWMXCLK_ENABLE  (1 << 0)
30 #define TWL4030_PWMX_ENABLE     (1 << 2)
31 #define TWL4030_PWMX_BITS       (TWL4030_PWMX_ENABLE | TWL4030_PWMXCLK_ENABLE)
32 #define TWL4030_PWM_TOGGLE(pwm, x)      ((x) << (pwm))
33
34 /* PMBR1 register bits */
35 #define TWL4030_GPIO6_PWM0_MUTE_MASK            (0x03 << 2)
36 #define TWL4030_GPIO6_PWM0_MUTE_PWM0            (0x01 << 2)
37 #define TWL4030_GPIO7_VIBRASYNC_PWM1_MASK       (0x03 << 4)
38 #define TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1       (0x03 << 4)
39
40 /* Register, bits and macro for TWL6030 */
41 #define TWL6030_TOGGLE3_REG     0x92
42
43 #define TWL6030_PWMXR           (1 << 0)
44 #define TWL6030_PWMXS           (1 << 1)
45 #define TWL6030_PWMXEN          (1 << 2)
46 #define TWL6030_PWM_TOGGLE(pwm, x)      ((x) << (pwm * 3))
47
48 struct twl_pwm_chip {
49         struct pwm_chip chip;
50         struct mutex mutex;
51         u8 twl6030_toggle3;
52         u8 twl4030_pwm_mux;
53 };
54
55 static inline struct twl_pwm_chip *to_twl(struct pwm_chip *chip)
56 {
57         return container_of(chip, struct twl_pwm_chip, chip);
58 }
59
60 static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
61                               int duty_ns, int period_ns)
62 {
63         int duty_cycle = DIV_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1;
64         u8 pwm_config[2] = { 1, 0 };
65         int base, ret;
66
67         /*
68          * To configure the duty period:
69          * On-cycle is set to 1 (the minimum allowed value)
70          * The off time of 0 is not configurable, so the mapping is:
71          * 0 -> off cycle = 2,
72          * 1 -> off cycle = 2,
73          * 2 -> off cycle = 3,
74          * 126 - > off cycle 127,
75          * 127 - > off cycle 1
76          * When on cycle == off cycle the PWM will be always on
77          */
78         if (duty_cycle == 1)
79                 duty_cycle = 2;
80         else if (duty_cycle > TWL_PWM_MAX)
81                 duty_cycle = 1;
82
83         base = pwm->hwpwm * 3;
84
85         pwm_config[1] = duty_cycle;
86
87         ret = twl_i2c_write(TWL_MODULE_PWM, pwm_config, base, 2);
88         if (ret < 0)
89                 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
90
91         return ret;
92 }
93
94 static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
95 {
96         struct twl_pwm_chip *twl = to_twl(chip);
97         int ret;
98         u8 val;
99
100         mutex_lock(&twl->mutex);
101         ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG);
102         if (ret < 0) {
103                 dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label);
104                 goto out;
105         }
106
107         val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE);
108
109         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
110         if (ret < 0)
111                 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
112
113         val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE);
114
115         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
116         if (ret < 0)
117                 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
118
119 out:
120         mutex_unlock(&twl->mutex);
121         return ret;
122 }
123
124 static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
125 {
126         struct twl_pwm_chip *twl = to_twl(chip);
127         int ret;
128         u8 val;
129
130         mutex_lock(&twl->mutex);
131         ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG);
132         if (ret < 0) {
133                 dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label);
134                 goto out;
135         }
136
137         val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE);
138
139         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
140         if (ret < 0)
141                 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
142
143         val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE);
144
145         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG);
146         if (ret < 0)
147                 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
148
149 out:
150         mutex_unlock(&twl->mutex);
151 }
152
153 static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
154 {
155         struct twl_pwm_chip *twl = to_twl(chip);
156         int ret;
157         u8 val, mask, bits;
158
159         if (pwm->hwpwm == 1) {
160                 mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK;
161                 bits = TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1;
162         } else {
163                 mask = TWL4030_GPIO6_PWM0_MUTE_MASK;
164                 bits = TWL4030_GPIO6_PWM0_MUTE_PWM0;
165         }
166
167         mutex_lock(&twl->mutex);
168         ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG);
169         if (ret < 0) {
170                 dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label);
171                 goto out;
172         }
173
174         /* Save the current MUX configuration for the PWM */
175         twl->twl4030_pwm_mux &= ~mask;
176         twl->twl4030_pwm_mux |= (val & mask);
177
178         /* Select PWM functionality */
179         val &= ~mask;
180         val |= bits;
181
182         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG);
183         if (ret < 0)
184                 dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label);
185
186 out:
187         mutex_unlock(&twl->mutex);
188         return ret;
189 }
190
191 static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
192 {
193         struct twl_pwm_chip *twl = to_twl(chip);
194         int ret;
195         u8 val, mask;
196
197         if (pwm->hwpwm == 1)
198                 mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK;
199         else
200                 mask = TWL4030_GPIO6_PWM0_MUTE_MASK;
201
202         mutex_lock(&twl->mutex);
203         ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG);
204         if (ret < 0) {
205                 dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label);
206                 goto out;
207         }
208
209         /* Restore the MUX configuration for the PWM */
210         val &= ~mask;
211         val |= (twl->twl4030_pwm_mux & mask);
212
213         ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG);
214         if (ret < 0)
215                 dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label);
216
217 out:
218         mutex_unlock(&twl->mutex);
219 }
220
221 static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
222 {
223         struct twl_pwm_chip *twl = to_twl(chip);
224         int ret;
225         u8 val;
226
227         mutex_lock(&twl->mutex);
228         val = twl->twl6030_toggle3;
229         val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN);
230         val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR);
231
232         ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
233         if (ret < 0) {
234                 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
235                 goto out;
236         }
237
238         twl->twl6030_toggle3 = val;
239 out:
240         mutex_unlock(&twl->mutex);
241         return ret;
242 }
243
244 static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
245 {
246         struct twl_pwm_chip *twl = to_twl(chip);
247         int ret;
248         u8 val;
249
250         mutex_lock(&twl->mutex);
251         val = twl->twl6030_toggle3;
252         val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR);
253         val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN);
254
255         ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
256         if (ret < 0) {
257                 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
258                 goto out;
259         }
260
261         val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
262
263         ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
264         if (ret < 0) {
265                 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
266                 goto out;
267         }
268
269         val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN);
270
271         ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG);
272         if (ret < 0) {
273                 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
274                 goto out;
275         }
276
277         twl->twl6030_toggle3 = val;
278 out:
279         mutex_unlock(&twl->mutex);
280 }
281
282 static const struct pwm_ops twl4030_pwm_ops = {
283         .config = twl_pwm_config,
284         .enable = twl4030_pwm_enable,
285         .disable = twl4030_pwm_disable,
286         .request = twl4030_pwm_request,
287         .free = twl4030_pwm_free,
288         .owner = THIS_MODULE,
289 };
290
291 static const struct pwm_ops twl6030_pwm_ops = {
292         .config = twl_pwm_config,
293         .enable = twl6030_pwm_enable,
294         .disable = twl6030_pwm_disable,
295         .owner = THIS_MODULE,
296 };
297
298 static int twl_pwm_probe(struct platform_device *pdev)
299 {
300         struct twl_pwm_chip *twl;
301
302         twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
303         if (!twl)
304                 return -ENOMEM;
305
306         if (twl_class_is_4030())
307                 twl->chip.ops = &twl4030_pwm_ops;
308         else
309                 twl->chip.ops = &twl6030_pwm_ops;
310
311         twl->chip.dev = &pdev->dev;
312         twl->chip.npwm = 2;
313
314         mutex_init(&twl->mutex);
315
316         return devm_pwmchip_add(&pdev->dev, &twl->chip);
317 }
318
319 #ifdef CONFIG_OF
320 static const struct of_device_id twl_pwm_of_match[] = {
321         { .compatible = "ti,twl4030-pwm" },
322         { .compatible = "ti,twl6030-pwm" },
323         { },
324 };
325 MODULE_DEVICE_TABLE(of, twl_pwm_of_match);
326 #endif
327
328 static struct platform_driver twl_pwm_driver = {
329         .driver = {
330                 .name = "twl-pwm",
331                 .of_match_table = of_match_ptr(twl_pwm_of_match),
332         },
333         .probe = twl_pwm_probe,
334 };
335 module_platform_driver(twl_pwm_driver);
336
337 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
338 MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030");
339 MODULE_ALIAS("platform:twl-pwm");
340 MODULE_LICENSE("GPL");