blob: dd40e07fec044136ec3e9ae48d63d4ac11f1accb [file] [log] [blame]
Googlerb48fa912023-03-17 12:40:29 +05301/* Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/pwm.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <asm/div64.h>
26#include <linux/of_device.h>
27
28#ifdef CONFIG_SND_SOC_IPQ_ADSS
29#include "ipq-adss.h"
30#else
31#define ADSS_GLB_PWM0_CTRL_REG 0x20
32#define ADSS_GLB_PWM1_CTRL_REG 0x24
33#define ADSS_GLB_PWM2_CTRL_REG 0x28
34#define ADSS_GLB_PWM3_CTRL_REG 0x2C
35#endif
36
37#define SRC_FREQ (200*1000*1000)
38#define MAX_PWM_DEVICES 4
39
40/* The default period and duty cycle values to be configured. */
41#define DEFAULT_PERIOD_NS 10
42#define DEFAULT_DUTY_CYCLE_NS 5
43
44/* The frequency range supported is 762Hz to 100MHz. */
45#define MIN_PERIOD_NS 10
46#define MAX_PERIOD_NS 1312335
47
48/* The max value specified for each field is based on the number of bits
49 * in the pwm control regitser for that filed
50 */
51#define MAX_PRE_DIV 0xFF
52#define MAX_PWM_DIV 0x3FF
53#define MAX_HI_DUR 0x7FF
54
55/* Enable bit is set to enable output toggling in pwm device.
56 * Update bit is set to reflect the changed divider and high duration
57 * values in register. Update bit is auto cleared after the update
58 */
59#define PWM_ENABLE 0x80000000
60#define PWM_UPDATE 0x40000000
61
62#define PWM_CTRL_PRE_DIV_SHIFT 22
63#define PWM_CTRL_DIV_SHIFT 0
64#define PWM_CTRL_HI_SHIFT 10
65
66/* The frequency range supported is 1Hz to 100MHz in V2. */
67#define MIN_PERIOD_NS_V2 10
68#define MAX_PERIOD_NS_V2 1000000000
69
70/* The max value specified for each field is based on the number of bits
71 * in the pwm control regitser for that filed in V2
72 */
73#define MAX_PWM_CFG_V2 0xFFFF
74
75#define PWM_CTRL_HI_SHIFT_V2 16
76
77#define PWM0_CTRL_REG0 0x0
78#define PWM0_CTRL_REG1 0x4
79#define PWM1_CTRL_REG0 0x8
80#define PWM1_CTRL_REG1 0xc
81#define PWM2_CTRL_REG0 0x10
82#define PWM2_CTRL_REG1 0x14
83#define PWM3_CTRL_REG0 0x18
84#define PWM3_CTRL_REG1 0x1C
85
86#define PWM_CFG_REG0 0 /*PWM_DIV PWM_HI*/
87#define PWM_CFG_REG1 1 /*ENABLE UPDATE PWM_PRE_DIV*/
88
89enum pwm_version {
90 PWM_V1,
91 PWM_V2,
92};
93
94struct ipq_pwm_ops {
95 void (*pwm_writel)(struct pwm_device*, uint32_t, uint32_t);
96 uint32_t (*pwm_readl)(struct pwm_device*, uint32_t);
97 u32 max_pre_div;
98 u32 max_pwm_div;
99 u32 max_period_ns;
100 u32 min_period_ns;
101 enum pwm_version version;
102};
103
104struct ipq_pwm_chip {
105 struct pwm_chip chip;
106 struct clk *clk;
107 void __iomem *mem;
108 struct ipq_pwm_ops *ops;
109};
110
111static ssize_t count;
112static uint32_t used_pwm[MAX_PWM_DEVICES];
113
114static const uint32_t pwm_ctrl_register[] = {
115 ADSS_GLB_PWM0_CTRL_REG,
116 ADSS_GLB_PWM1_CTRL_REG,
117 ADSS_GLB_PWM2_CTRL_REG,
118 ADSS_GLB_PWM3_CTRL_REG,
119};
120
121static const uint32_t pwm_ctrl_register_v2[] = {
122 PWM0_CTRL_REG0,
123 PWM0_CTRL_REG1,
124 PWM1_CTRL_REG0,
125 PWM1_CTRL_REG1,
126 PWM2_CTRL_REG0,
127 PWM2_CTRL_REG1,
128 PWM3_CTRL_REG0,
129 PWM3_CTRL_REG1,
130};
131
132static struct ipq_pwm_chip *to_ipq_pwm_chip(struct pwm_chip *chip)
133{
134 return container_of(chip, struct ipq_pwm_chip, chip);
135}
136
137#ifdef CONFIG_SND_SOC_IPQ_ADSS
138static void pwm_writel_v1(struct pwm_device *pwm, uint32_t val, uint32_t cfg_reg)
139{
140 ipq_audio_adss_writel(val, pwm_ctrl_register[pwm->hwpwm]);
141}
142
143static uint32_t pwm_readl_v1(struct pwm_device *pwm, uint32_t cfg_reg)
144{
145 return ipq_audio_adss_readl(pwm_ctrl_register[pwm->hwpwm]);
146}
147#else
148static void pwm_writel_v1(struct pwm_device *pwm, uint32_t val, uint32_t cfg_reg)
149{
150 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
151
152 writel(val, ipq_chip->mem + pwm_ctrl_register[pwm->hwpwm]);
153 return;
154}
155
156static uint32_t pwm_readl_v1(struct pwm_device *pwm, uint32_t cfg_reg)
157{
158 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
159
160 return readl(ipq_chip->mem + pwm_ctrl_register[pwm->hwpwm]);
161}
162#endif
163
164static void pwm_writel_v2(struct pwm_device *pwm, uint32_t val, uint32_t cfg_reg)
165{
166 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
167 uint32_t offset;
168
169 offset = pwm_ctrl_register_v2[(pwm->hwpwm * 2) + cfg_reg];
170 writel(val, ipq_chip->mem + offset);
171}
172
173static uint32_t pwm_readl_v2(struct pwm_device *pwm, uint32_t cfg_reg)
174{
175 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
176 uint32_t offset;
177
178 offset = pwm_ctrl_register_v2[(pwm->hwpwm * 2) + cfg_reg];
179 return readl(ipq_chip->mem + offset);
180}
181
182static void config_div_and_duty(struct pwm_device *pwm, int pre_div,
183 unsigned long long pwm_div, unsigned long period_ns,
184 unsigned long long duty_ns)
185{
186 unsigned long hi_dur;
187 unsigned long long quotient;
188 unsigned long ctrl_reg_val = 0;
189 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
190
191 /* high duration = pwm duty * ( pwm div + 1)
192 * pwm duty = duty_ns / period_ns
193 */
194 quotient = (pwm_div + 1) * duty_ns;
195 do_div(quotient, period_ns);
196 hi_dur = quotient;
197
198 if (ipq_chip->ops->version == PWM_V1) {
199 ctrl_reg_val |= ((pre_div & ipq_chip->ops->max_pre_div)
200 << PWM_CTRL_PRE_DIV_SHIFT);
201 ctrl_reg_val |= ((hi_dur & MAX_HI_DUR) << PWM_CTRL_HI_SHIFT);
202 ctrl_reg_val |= ((pwm_div & ipq_chip->ops->max_pwm_div)
203 << PWM_CTRL_DIV_SHIFT);
204 } else {
205 ctrl_reg_val |= ((hi_dur & MAX_PWM_CFG_V2)
206 << PWM_CTRL_HI_SHIFT_V2);
207 ctrl_reg_val |= (pwm_div & ipq_chip->ops->max_pwm_div);
208 ipq_chip->ops->pwm_writel(pwm, ctrl_reg_val, PWM_CFG_REG0);
209 ctrl_reg_val = pre_div & ipq_chip->ops->max_pre_div;
210 }
211 ipq_chip->ops->pwm_writel(pwm, ctrl_reg_val, PWM_CFG_REG1);
212}
213
214static int ipq_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
215{
216 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
217 unsigned long ctrl_reg_val;
218
219 ctrl_reg_val = ipq_chip->ops->pwm_readl(pwm, PWM_CFG_REG1);
220 ctrl_reg_val |= (PWM_ENABLE | PWM_UPDATE);
221 ipq_chip->ops->pwm_writel(pwm, ctrl_reg_val, PWM_CFG_REG1);
222
223 return 0;
224}
225
226static void ipq_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
227{
228 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
229 unsigned long ctrl_reg_val;
230
231 ctrl_reg_val = ipq_chip->ops->pwm_readl(pwm, PWM_CFG_REG1);
232 ctrl_reg_val &= ~PWM_ENABLE;
233 ipq_chip->ops->pwm_writel(pwm, ctrl_reg_val, PWM_CFG_REG1);
234}
235
236static int ipq_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
237 int duty_ns, int period_ns)
238{
239 struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
240 unsigned long freq;
241 int pre_div, close_pre_div, close_pwm_div;
242 int pwm_div;
243 long long diff;
244 unsigned long rate = clk_get_rate(ipq_chip->clk);
245 unsigned long min_diff = rate;
246 uint64_t fin_ps;
247
248 if (period_ns > ipq_chip->ops->max_period_ns ||
249 period_ns < ipq_chip->ops->min_period_ns) {
250 pr_err("PWM Frequency range supported is %dHz to %dHz\n"
251 "Switching to default configuration values\n",
252 (int)NSEC_PER_SEC / ipq_chip->ops->max_period_ns,
253 (int)NSEC_PER_SEC / ipq_chip->ops->min_period_ns);
254 period_ns = DEFAULT_PERIOD_NS;
255 duty_ns = DEFAULT_DUTY_CYCLE_NS;
256 pwm->state.period = period_ns;
257 pwm->state.duty_cycle = duty_ns;
258 }
259
260 /* freq in Hz for period in nano second*/
261 freq = NSEC_PER_SEC / period_ns;
262 fin_ps = (uint64_t)NSEC_PER_SEC * 1000;
263 do_div(fin_ps, rate);
264 close_pre_div = ipq_chip->ops->max_pre_div;
265 close_pwm_div = ipq_chip->ops->max_pwm_div;
266
267 ipq_pwm_disable(chip, pwm);
268
269 for (pre_div = 0; pre_div <= ipq_chip->ops->max_pre_div ; pre_div++) {
270 pwm_div = DIV_ROUND_CLOSEST_ULL((uint64_t)period_ns * 1000,
271 fin_ps * (pre_div + 1));
272 pwm_div--;
273 if (pwm_div <= ipq_chip->ops->max_pwm_div) {
274 diff = (uint64_t)rate - ((uint64_t)freq * (pre_div + 1) * (pwm_div + 1));
275
276 if (diff < 0)
277 diff = -diff;
278 if (!diff) {
279 close_pre_div = pre_div;
280 close_pwm_div = pwm_div;
281 break;
282 }
283 if (diff < min_diff) {
284 min_diff = diff;
285 close_pre_div = pre_div;
286 close_pwm_div = pwm_div;
287 }
288 }
289 }
290
291 /* config divider values for the closest possible frequency */
292 config_div_and_duty(pwm, close_pre_div, close_pwm_div,
293 period_ns, duty_ns);
294 ipq_pwm_enable(chip, pwm);
295
296 return 0;
297}
298
299static int ipq_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
300{
301 if (!used_pwm[pwm->hwpwm])
302 return -EINVAL;
303
304 pwm->state.period = DEFAULT_PERIOD_NS;
305 pwm->state.duty_cycle = DEFAULT_DUTY_CYCLE_NS;
306
307 ipq_pwm_config(chip, pwm, pwm->state.duty_cycle, pwm->state.period);
308
309 return 0;
310}
311
312static void ipq_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
313{
314 ipq_pwm_disable(chip, pwm);
315}
316
317
318static struct pwm_ops ipq_pwm_ops = {
319 .request = ipq_pwm_request,
320 .free = ipq_pwm_free,
321 .config = ipq_pwm_config,
322 .enable = ipq_pwm_enable,
323 .disable = ipq_pwm_disable,
324 .owner = THIS_MODULE,
325};
326
327static int ipq_pwm_probe(struct platform_device *pdev)
328{
329 struct ipq_pwm_chip *pwm;
330 struct device *dev;
331 unsigned int base_index;
332 int ret;
333 const void *dev_data;
334 unsigned long src_freq = SRC_FREQ;
335 struct resource *res = NULL;
336
337 dev = &pdev->dev;
338 pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
339 if (!pwm) {
340 dev_err(dev, "failed to allocate memory\n");
341 return -ENOMEM;
342 }
343
344 platform_set_drvdata(pdev, pwm);
345 dev_data = of_device_get_match_data(dev);
346 if (!dev_data) {
347 dev_err(&pdev->dev, "failed to get device data\n");
348 return -ENODEV;
349 }
350
351 pwm->ops = (struct ipq_pwm_ops*) dev_data;
352 of_property_read_u64(dev->of_node, "src-freq", (u64 *)src_freq);
353
354 pwm->clk = devm_clk_get(dev, "core");
355 if (!IS_ERR(pwm->clk)) {
356 ret = clk_set_rate(pwm->clk, src_freq);
357 if (ret)
358 return ret;
359 ret = clk_prepare_enable(pwm->clk);
360 if (ret)
361 return ret;
362 }
363
364 if (pwm->ops->version == PWM_V2 || !IS_ENABLED(CONFIG_SND_SOC_IPQ_ADSS)) {
365 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
366 pwm->mem = devm_ioremap_resource(&pdev->dev, res);
367 if (IS_ERR(pwm->mem))
368 return PTR_ERR(pwm->mem);
369 }
370
371 if (of_property_read_u32(dev->of_node, "pwm-base-index", &base_index))
372 base_index = 0;
373
374 count = of_property_count_u32_elems(dev->of_node, "used-pwm-indices");
375
376 if (of_property_read_u32_array(dev->of_node, "used-pwm-indices",
377 used_pwm, count))
378 return -EINVAL;
379
380 pwm->chip.dev = dev;
381 pwm->chip.ops = &ipq_pwm_ops;
382 pwm->chip.base = base_index;
383 pwm->chip.npwm = count;
384
385 ret = pwmchip_add(&pwm->chip);
386 if (ret < 0) {
387 dev_err(dev, "pwmchip_add() failed: %d\n", ret);
388 return ret;
389 }
390
391 return 0;
392}
393
394static int ipq_pwm_remove(struct platform_device *pdev)
395{
396 struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev);
397
398 return pwmchip_remove(&pwm->chip);
399}
400
401static const struct ipq_pwm_ops ops_v1 = {
402 .pwm_writel = pwm_writel_v1,
403 .pwm_readl = pwm_readl_v1,
404 .max_pre_div = MAX_PRE_DIV,
405 .max_pwm_div = MAX_PWM_DIV,
406 .max_period_ns = MAX_PERIOD_NS,
407 .min_period_ns = MIN_PERIOD_NS,
408 .version = PWM_V1
409};
410
411static const struct ipq_pwm_ops ops_v2 = {
412 .pwm_writel = pwm_writel_v2,
413 .pwm_readl = pwm_readl_v2,
414 .max_pre_div = MAX_PWM_CFG_V2,
415 .max_pwm_div = MAX_PWM_CFG_V2,
416 .max_period_ns = MAX_PERIOD_NS_V2,
417 .min_period_ns = MIN_PERIOD_NS_V2,
418 .version = PWM_V2
419};
420
421static const struct of_device_id pwm_msm_dt_match[] = {
422 { .compatible = "qti,ipq-pwm", .data = &ops_v1 },
423 { .compatible = "qti,ipq6018-pwm", .data = &ops_v2 },
424 {}
425};
426MODULE_DEVICE_TABLE(of, pwm_msm_dt_match);
427
428static struct platform_driver ipq_pwm_driver = {
429 .driver = {
430 .name = "qti,ipq-pwm",
431 .owner = THIS_MODULE,
432 .of_match_table = pwm_msm_dt_match,
433 },
434 .probe = ipq_pwm_probe,
435 .remove = ipq_pwm_remove,
436};
437
438module_platform_driver(ipq_pwm_driver);
439
440MODULE_LICENSE("Dual BSD/GPL");