]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pwm: sophgo-sg2042: Reorganize the code structure
authorLongbin Li <looong.bin@gmail.com>
Wed, 28 May 2025 10:11:37 +0000 (18:11 +0800)
committerUwe Kleine-König <ukleinek@kernel.org>
Mon, 7 Jul 2025 06:39:34 +0000 (08:39 +0200)
As the driver logic can be used in both SG2042 and SG2044, it
will be better to reorganize the code structure.

Reviewed-by: Chen Wang <unicorn_wang@outlook.com>
Tested-by: Chen Wang <unicorn_wang@outlook.com>
Signed-off-by: Longbin Li <looong.bin@gmail.com>
Link: https://lore.kernel.org/r/20250528101139.28702-3-looong.bin@gmail.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
drivers/pwm/pwm-sophgo-sg2042.c

index ff4639d849ce1aa26371998420e6844cd99fd7ba..f3956563037faed41283238edaf8ccf66cb7c0c8 100644 (file)
@@ -53,6 +53,10 @@ struct sg2042_pwm_ddata {
        unsigned long clk_rate_hz;
 };
 
+struct sg2042_chip_data {
+       const struct pwm_ops ops;
+};
+
 /*
  * period_ticks: PERIOD
  * hlperiod_ticks: HLPERIOD
@@ -66,21 +70,13 @@ static void pwm_sg2042_config(struct sg2042_pwm_ddata *ddata, unsigned int chan,
        writel(hlperiod_ticks, base + SG2042_PWM_HLPERIOD(chan));
 }
 
-static int pwm_sg2042_apply(struct pwm_chip *chip, struct pwm_device *pwm,
-                           const struct pwm_state *state)
+static void pwm_sg2042_set_dutycycle(struct pwm_chip *chip, struct pwm_device *pwm,
+                                    const struct pwm_state *state)
 {
        struct sg2042_pwm_ddata *ddata = pwmchip_get_drvdata(chip);
        u32 hlperiod_ticks;
        u32 period_ticks;
 
-       if (state->polarity == PWM_POLARITY_INVERSED)
-               return -EINVAL;
-
-       if (!state->enabled) {
-               pwm_sg2042_config(ddata, pwm->hwpwm, 0, 0);
-               return 0;
-       }
-
        /*
         * Duration of High level (duty_cycle) = HLPERIOD x Period_of_input_clk
         * Duration of One Cycle (period) = PERIOD x Period_of_input_clk
@@ -92,6 +88,22 @@ static int pwm_sg2042_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                pwm->hwpwm, period_ticks, hlperiod_ticks);
 
        pwm_sg2042_config(ddata, pwm->hwpwm, period_ticks, hlperiod_ticks);
+}
+
+static int pwm_sg2042_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+                           const struct pwm_state *state)
+{
+       struct sg2042_pwm_ddata *ddata = pwmchip_get_drvdata(chip);
+
+       if (state->polarity == PWM_POLARITY_INVERSED)
+               return -EINVAL;
+
+       if (!state->enabled) {
+               pwm_sg2042_config(ddata, pwm->hwpwm, 0, 0);
+               return 0;
+       }
+
+       pwm_sg2042_set_dutycycle(chip, pwm, state);
 
        return 0;
 }
@@ -123,13 +135,18 @@ static int pwm_sg2042_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        return 0;
 }
 
-static const struct pwm_ops pwm_sg2042_ops = {
-       .apply = pwm_sg2042_apply,
-       .get_state = pwm_sg2042_get_state,
+static const struct sg2042_chip_data sg2042_chip_data = {
+       .ops = {
+               .apply = pwm_sg2042_apply,
+               .get_state = pwm_sg2042_get_state,
+       },
 };
 
 static const struct of_device_id sg2042_pwm_ids[] = {
-       { .compatible = "sophgo,sg2042-pwm" },
+       {
+               .compatible = "sophgo,sg2042-pwm",
+               .data = &sg2042_chip_data
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, sg2042_pwm_ids);
@@ -137,12 +154,17 @@ MODULE_DEVICE_TABLE(of, sg2042_pwm_ids);
 static int pwm_sg2042_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       const struct sg2042_chip_data *chip_data;
        struct sg2042_pwm_ddata *ddata;
        struct reset_control *rst;
        struct pwm_chip *chip;
        struct clk *clk;
        int ret;
 
+       chip_data = device_get_match_data(dev);
+       if (!chip_data)
+               return -ENODEV;
+
        chip = devm_pwmchip_alloc(dev, SG2042_PWM_CHANNELNUM, sizeof(*ddata));
        if (IS_ERR(chip))
                return PTR_ERR(chip);
@@ -170,7 +192,7 @@ static int pwm_sg2042_probe(struct platform_device *pdev)
        if (IS_ERR(rst))
                return dev_err_probe(dev, PTR_ERR(rst), "Failed to get reset\n");
 
-       chip->ops = &pwm_sg2042_ops;
+       chip->ops = &chip_data->ops;
        chip->atomic = true;
 
        ret = devm_pwmchip_add(dev, chip);