• Home
  • Raw
  • Download

Lines Matching +full:pwm +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/pwm.h>
43 * The list of clocks required by PWM channels, and each channel has 2 clocks:
44 * enable clock and pwm clock.
55 u32 offset = reg + (hwid << SPRD_PWM_REGS_SHIFT); in sprd_pwm_read() local
57 return readl_relaxed(spc->base + offset); in sprd_pwm_read()
63 u32 offset = reg + (hwid << SPRD_PWM_REGS_SHIFT); in sprd_pwm_write() local
65 writel_relaxed(val, spc->base + offset); in sprd_pwm_write()
68 static void sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in sprd_pwm_get_state() argument
73 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_get_state()
79 * The clocks to PWM channel has to be enabled first before in sprd_pwm_get_state()
82 ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_get_state()
84 dev_err(spc->dev, "failed to enable pwm%u clocks\n", in sprd_pwm_get_state()
85 pwm->hwpwm); in sprd_pwm_get_state()
89 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_ENABLE); in sprd_pwm_get_state()
91 state->enabled = true; in sprd_pwm_get_state()
93 state->enabled = false; in sprd_pwm_get_state()
103 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_PRESCALE); in sprd_pwm_get_state()
106 state->period = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); in sprd_pwm_get_state()
108 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_DUTY); in sprd_pwm_get_state()
111 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); in sprd_pwm_get_state()
112 state->polarity = PWM_POLARITY_NORMAL; in sprd_pwm_get_state()
114 /* Disable PWM clocks if the PWM channel is not in enable state. */ in sprd_pwm_get_state()
115 if (!state->enabled) in sprd_pwm_get_state()
116 clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_get_state()
119 static int sprd_pwm_config(struct sprd_pwm_chip *spc, struct pwm_device *pwm, in sprd_pwm_config() argument
122 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_config()
138 tmp = (u64)chn->clk_rate * period_ns; in sprd_pwm_config()
140 prescale = DIV_ROUND_CLOSEST_ULL(tmp, SPRD_PWM_MOD_MAX) - 1; in sprd_pwm_config()
152 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_PRESCALE, prescale); in sprd_pwm_config()
153 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_MOD, SPRD_PWM_MOD_MAX); in sprd_pwm_config()
154 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_DUTY, duty); in sprd_pwm_config()
159 static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in sprd_pwm_apply() argument
164 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_apply()
165 struct pwm_state *cstate = &pwm->state; in sprd_pwm_apply()
168 if (state->enabled) { in sprd_pwm_apply()
169 if (!cstate->enabled) { in sprd_pwm_apply()
171 * The clocks to PWM channel has to be enabled first in sprd_pwm_apply()
175 chn->clks); in sprd_pwm_apply()
177 dev_err(spc->dev, in sprd_pwm_apply()
178 "failed to enable pwm%u clocks\n", in sprd_pwm_apply()
179 pwm->hwpwm); in sprd_pwm_apply()
184 ret = sprd_pwm_config(spc, pwm, state->duty_cycle, in sprd_pwm_apply()
185 state->period); in sprd_pwm_apply()
189 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1); in sprd_pwm_apply()
190 } else if (cstate->enabled) { in sprd_pwm_apply()
194 * will stop the PWM channel immediately. in sprd_pwm_apply()
196 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 0); in sprd_pwm_apply()
198 clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_apply()
216 struct sprd_pwm_chn *chn = &spc->chn[i]; in sprd_pwm_clk_init()
220 chn->clks[j].id = in sprd_pwm_clk_init()
223 ret = devm_clk_bulk_get(spc->dev, SPRD_PWM_CHN_CLKS_NUM, in sprd_pwm_clk_init()
224 chn->clks); in sprd_pwm_clk_init()
226 if (ret == -ENOENT) in sprd_pwm_clk_init()
229 return dev_err_probe(spc->dev, ret, in sprd_pwm_clk_init()
233 clk_pwm = chn->clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; in sprd_pwm_clk_init()
234 chn->clk_rate = clk_get_rate(clk_pwm); in sprd_pwm_clk_init()
238 dev_err(spc->dev, "no available PWM channels\n"); in sprd_pwm_clk_init()
239 return -ENODEV; in sprd_pwm_clk_init()
242 spc->num_pwms = i; in sprd_pwm_clk_init()
252 spc = devm_kzalloc(&pdev->dev, sizeof(*spc), GFP_KERNEL); in sprd_pwm_probe()
254 return -ENOMEM; in sprd_pwm_probe()
256 spc->base = devm_platform_ioremap_resource(pdev, 0); in sprd_pwm_probe()
257 if (IS_ERR(spc->base)) in sprd_pwm_probe()
258 return PTR_ERR(spc->base); in sprd_pwm_probe()
260 spc->dev = &pdev->dev; in sprd_pwm_probe()
267 spc->chip.dev = &pdev->dev; in sprd_pwm_probe()
268 spc->chip.ops = &sprd_pwm_ops; in sprd_pwm_probe()
269 spc->chip.base = -1; in sprd_pwm_probe()
270 spc->chip.npwm = spc->num_pwms; in sprd_pwm_probe()
272 ret = pwmchip_add(&spc->chip); in sprd_pwm_probe()
274 dev_err(&pdev->dev, "failed to add PWM chip\n"); in sprd_pwm_probe()
283 return pwmchip_remove(&spc->chip); in sprd_pwm_remove()
287 { .compatible = "sprd,ums512-pwm", },
294 .name = "sprd-pwm",
303 MODULE_DESCRIPTION("Spreadtrum PWM Driver");