Lines Matching +full:sg2042 +full:- +full:pwm
1 // SPDX-License-Identifier: GPL-2.0
3 * Sophgo SG2042 PWM Controller Driver
9 * - After reset, the output of the PWM channel is always high.
11 * - When HLPERIOD or PERIOD is reconfigured, PWM will start to
14 * - When PERIOD and HLPERIOD is set to 0, the PWM wave output will
17 * [1]:https://github.com/sophgo/sophgo-doc/tree/main/SG2042/TRM
26 #include <linux/pwm.h>
47 * struct sg2042_pwm_ddata - private driver data
48 * @base: base address of mapped PWM registers
63 void __iomem *base = ddata->base; in pwm_sg2042_config()
69 static int pwm_sg2042_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_sg2042_apply() argument
76 if (state->polarity == PWM_POLARITY_INVERSED) in pwm_sg2042_apply()
77 return -EINVAL; in pwm_sg2042_apply()
79 if (!state->enabled) { in pwm_sg2042_apply()
80 pwm_sg2042_config(ddata, pwm->hwpwm, 0, 0); in pwm_sg2042_apply()
88 period_ticks = min(mul_u64_u64_div_u64(ddata->clk_rate_hz, state->period, NSEC_PER_SEC), U32_MAX); in pwm_sg2042_apply()
89 …hlperiod_ticks = min(mul_u64_u64_div_u64(ddata->clk_rate_hz, state->duty_cycle, NSEC_PER_SEC), U32… in pwm_sg2042_apply()
92 pwm->hwpwm, period_ticks, hlperiod_ticks); in pwm_sg2042_apply()
94 pwm_sg2042_config(ddata, pwm->hwpwm, period_ticks, hlperiod_ticks); in pwm_sg2042_apply()
99 static int pwm_sg2042_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_sg2042_get_state() argument
103 unsigned int chan = pwm->hwpwm; in pwm_sg2042_get_state()
107 period_ticks = readl(ddata->base + SG2042_PWM_PERIOD(chan)); in pwm_sg2042_get_state()
108 hlperiod_ticks = readl(ddata->base + SG2042_PWM_HLPERIOD(chan)); in pwm_sg2042_get_state()
111 state->enabled = false; in pwm_sg2042_get_state()
118 state->enabled = true; in pwm_sg2042_get_state()
119 state->period = DIV_ROUND_UP_ULL((u64)period_ticks * NSEC_PER_SEC, ddata->clk_rate_hz); in pwm_sg2042_get_state()
120 state->duty_cycle = DIV_ROUND_UP_ULL((u64)hlperiod_ticks * NSEC_PER_SEC, ddata->clk_rate_hz); in pwm_sg2042_get_state()
121 state->polarity = PWM_POLARITY_NORMAL; in pwm_sg2042_get_state()
132 { .compatible = "sophgo,sg2042-pwm" },
139 struct device *dev = &pdev->dev; in pwm_sg2042_probe()
151 ddata->base = devm_platform_ioremap_resource(pdev, 0); in pwm_sg2042_probe()
152 if (IS_ERR(ddata->base)) in pwm_sg2042_probe()
153 return PTR_ERR(ddata->base); in pwm_sg2042_probe()
163 ddata->clk_rate_hz = clk_get_rate(clk); in pwm_sg2042_probe()
165 if (!ddata->clk_rate_hz || ddata->clk_rate_hz > NSEC_PER_SEC) in pwm_sg2042_probe()
166 return dev_err_probe(dev, -EINVAL, in pwm_sg2042_probe()
167 "Invalid clock rate: %lu\n", ddata->clk_rate_hz); in pwm_sg2042_probe()
173 chip->ops = &pwm_sg2042_ops; in pwm_sg2042_probe()
174 chip->atomic = true; in pwm_sg2042_probe()
178 return dev_err_probe(dev, ret, "Failed to register PWM chip\n"); in pwm_sg2042_probe()
185 .name = "sg2042-pwm",
193 MODULE_DESCRIPTION("Sophgo SG2042 PWM driver");