Lines Matching +full:pwm +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * PWM Controller Driver for HiSilicon BVT SoCs
15 #include <linux/pwm.h>
70 static void hibvt_pwm_set_bits(void __iomem *base, u32 offset, in hibvt_pwm_set_bits() argument
73 void __iomem *address = base + offset; in hibvt_pwm_set_bits()
82 static void hibvt_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in hibvt_pwm_enable() argument
86 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), in hibvt_pwm_enable()
90 static void hibvt_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in hibvt_pwm_disable() argument
94 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), in hibvt_pwm_disable()
98 static void hibvt_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in hibvt_pwm_config() argument
104 freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000); in hibvt_pwm_config()
109 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm), in hibvt_pwm_config()
112 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm), in hibvt_pwm_config()
117 struct pwm_device *pwm, in hibvt_pwm_set_polarity() argument
123 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), in hibvt_pwm_set_polarity()
126 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), in hibvt_pwm_set_polarity()
130 static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in hibvt_pwm_get_state() argument
137 freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000); in hibvt_pwm_get_state()
138 base = hi_pwm_chip->base; in hibvt_pwm_get_state()
140 value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm)); in hibvt_pwm_get_state()
141 state->period = div_u64(value * 1000, freq); in hibvt_pwm_get_state()
143 value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm)); in hibvt_pwm_get_state()
144 state->duty_cycle = div_u64(value * 1000, freq); in hibvt_pwm_get_state()
146 value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); in hibvt_pwm_get_state()
147 state->enabled = (PWM_ENABLE_MASK & value); in hibvt_pwm_get_state()
148 state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; in hibvt_pwm_get_state()
153 static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in hibvt_pwm_apply() argument
158 if (state->polarity != pwm->state.polarity) in hibvt_pwm_apply()
159 hibvt_pwm_set_polarity(chip, pwm, state->polarity); in hibvt_pwm_apply()
161 if (state->period != pwm->state.period || in hibvt_pwm_apply()
162 state->duty_cycle != pwm->state.duty_cycle) { in hibvt_pwm_apply()
163 hibvt_pwm_config(chip, pwm, state->duty_cycle, state->period); in hibvt_pwm_apply()
166 * Some implementations require the PWM to be enabled twice in hibvt_pwm_apply()
169 if (hi_pwm_chip->soc->quirk_force_enable && state->enabled) in hibvt_pwm_apply()
170 hibvt_pwm_enable(chip, pwm); in hibvt_pwm_apply()
173 if (state->enabled != pwm->state.enabled) { in hibvt_pwm_apply()
174 if (state->enabled) in hibvt_pwm_apply()
175 hibvt_pwm_enable(chip, pwm); in hibvt_pwm_apply()
177 hibvt_pwm_disable(chip, pwm); in hibvt_pwm_apply()
192 of_device_get_match_data(&pdev->dev); in hibvt_pwm_probe()
197 chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*hi_pwm_chip)); in hibvt_pwm_probe()
202 hi_pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); in hibvt_pwm_probe()
203 if (IS_ERR(hi_pwm_chip->clk)) { in hibvt_pwm_probe()
204 dev_err(&pdev->dev, "getting clock failed with %ld\n", in hibvt_pwm_probe()
205 PTR_ERR(hi_pwm_chip->clk)); in hibvt_pwm_probe()
206 return PTR_ERR(hi_pwm_chip->clk); in hibvt_pwm_probe()
209 chip->ops = &hibvt_pwm_ops; in hibvt_pwm_probe()
210 hi_pwm_chip->soc = soc; in hibvt_pwm_probe()
212 hi_pwm_chip->base = devm_platform_ioremap_resource(pdev, 0); in hibvt_pwm_probe()
213 if (IS_ERR(hi_pwm_chip->base)) in hibvt_pwm_probe()
214 return PTR_ERR(hi_pwm_chip->base); in hibvt_pwm_probe()
216 ret = clk_prepare_enable(hi_pwm_chip->clk); in hibvt_pwm_probe()
220 hi_pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in hibvt_pwm_probe()
221 if (IS_ERR(hi_pwm_chip->rstc)) { in hibvt_pwm_probe()
222 clk_disable_unprepare(hi_pwm_chip->clk); in hibvt_pwm_probe()
223 return PTR_ERR(hi_pwm_chip->rstc); in hibvt_pwm_probe()
226 reset_control_assert(hi_pwm_chip->rstc); in hibvt_pwm_probe()
228 reset_control_deassert(hi_pwm_chip->rstc); in hibvt_pwm_probe()
232 clk_disable_unprepare(hi_pwm_chip->clk); in hibvt_pwm_probe()
236 for (i = 0; i < chip->npwm; i++) { in hibvt_pwm_probe()
237 hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(i), in hibvt_pwm_probe()
253 reset_control_assert(hi_pwm_chip->rstc); in hibvt_pwm_remove()
255 reset_control_deassert(hi_pwm_chip->rstc); in hibvt_pwm_remove()
257 clk_disable_unprepare(hi_pwm_chip->clk); in hibvt_pwm_remove()
261 { .compatible = "hisilicon,hi3516cv300-pwm",
263 { .compatible = "hisilicon,hi3519v100-pwm",
265 { .compatible = "hisilicon,hi3559v100-shub-pwm",
267 { .compatible = "hisilicon,hi3559v100-pwm",
275 .name = "hibvt-pwm",
284 MODULE_DESCRIPTION("HiSilicon BVT SoCs PWM driver");