[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <5514fa03-139e-456e-b522-6a774b52eac1@kernel.org>
Date: Fri, 24 Jan 2025 08:30:48 +0100
From: Krzysztof Kozlowski <krzk@...nel.org>
To: Ben Zong-You Xie <ben717@...estech.com>, linux-pwm@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org
Cc: ukleinek@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
conor+dt@...nel.org
Subject: Re: [v3 2/2] pwm: atcpit100: add Andes PWM driver support
On 23/01/2025 20:35, Ben Zong-You Xie wrote:
>
> +config PWM_ATCPIT100
> + tristate "Andes ATCPIT100 PWM support"
> + depends on OF && HAS_IOMEM
> + depends on RISCV || COMPILE_TEST
> + select REGMAP_MMIO
> + help
> + Generic PWM framework driver for ATCPIT100 on Andes AE350 platform
Is AE350 a type of a SoC? Looks like. "depends on RISCV" is wrong -
there is nothing RISC-V specific here. You must depend on given
SoC/platform.
> +
> + The ATCPIT100 Programmable Interval Timer (PIT) is a set of compact
> + multi-function timers, which can be used as pulse width
> + modulators (PWM) as well as simple timers. ATCPIT100 supports up to 4
> + PIT channels. Each PIT channel can be a simple timer or PWM, or a
> + combination of timer and PWM.
> +
> + To compile this driver as a module, choose M here: the module
...
> +static int atcpit100_pwm_get_state(struct pwm_chip *chip,
> + struct pwm_device *pwm,
> + struct pwm_state *state)
> +{
> + int clk;
> + int ret;
> + unsigned int ctrl_val;
> + unsigned int reload_val;
> + u16 pwm_high;
> + u16 pwm_low;
> + unsigned int channel = pwm->hwpwm;
> + struct atcpit100_pwm *ap = to_atcpit100_pwm(chip);
> +
> + ret = regmap_read(ap->regmap, ATCPIT100_CHANNEL_CTRL(channel),
> + &ctrl_val);
> + if (ret)
> + return ret;
> +
> + clk = (ctrl_val & ATCPIT100_CHANNEL_CTRL_CLK) ? ATCPIT100_CLK_APB
> + : ATCPIT100_CLK_EXT;
> + state->enabled =
Don't wrap here...
> + regmap_test_bits(ap->regmap, ATCPIT100_CHANNEL_ENABLE,
but wrap at arguments.
> + ATCPIT100_CHANNEL_ENABLE_PWM(channel));
> + state->polarity = PWM_POLARITY_NORMAL;
> + ret = regmap_read(ap->regmap, ATCPIT100_CHANNEL_RELOAD(channel),
> + &reload_val);
> + if (ret)
> + return ret;
> +
> + pwm_high = FIELD_GET(ATCPIT100_CHANNEL_RELOAD_HIGH, reload_val);
> + pwm_low = FIELD_GET(ATCPIT100_CHANNEL_RELOAD_LOW, reload_val);
> + state->duty_cycle =
> + DIV64_U64_ROUND_UP((pwm_high + 1) * NSEC_PER_SEC,
> + ap->clk_rate[clk]);
> + state->period =
> + state->duty_cycle +
> + DIV64_U64_ROUND_UP((pwm_low + 1) * NSEC_PER_SEC,
> + ap->clk_rate[clk]);
> +
> + return 0;
> +}
> +
> +static const struct pwm_ops atcpit_pwm_ops = {
> + .apply = atcpit100_pwm_apply,
> + .get_state = atcpit100_pwm_get_state,
> +};
> +
> +static int atcpit100_pwm_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct atcpit100_pwm *ap;
> + struct pwm_chip *chip;
> + void __iomem *base;
> + int ret;
> +
> + chip = devm_pwmchip_alloc(dev, ATCPIT100_CHANNEL_MAX, sizeof(*ap));
> + if (IS_ERR(chip))
> + return PTR_ERR(chip);
> +
> + ap = to_atcpit100_pwm(chip);
> + base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + ap->ext_clk = devm_clk_get_enabled(dev, "ext");
> + ap->clk_rate[ATCPIT100_CLK_EXT] = ap->ext_clk ?
> + clk_get_rate(ap->ext_clk) : 0;
> + ap->apb_clk = devm_clk_get_enabled(dev, "apb");
> + ap->clk_rate[ATCPIT100_CLK_APB] = ap->apb_clk ?
> + clk_get_rate(ap->apb_clk) : 0;
> + if (IS_ERR(ap->ext_clk) && IS_ERR(ap->apb_clk)) {
Drop {}. See Linux coding style.
> + return dev_err_probe(dev, PTR_ERR(ap->ext_clk),
> + "failed to obtain any clock\n");
> + }
> +
> + if (ap->clk_rate[ATCPIT100_CLK_EXT] > NSEC_PER_SEC ||
> + ap->clk_rate[ATCPIT100_CLK_APB] > NSEC_PER_SEC)
> + return dev_err_probe(dev, -EINVAL, "pwm clock out of range\n");
> +
> + ap->regmap = devm_regmap_init_mmio(dev, base,
> + &atcpit100_pwm_regmap_config);
> + if (IS_ERR(ap->regmap)) {
Drop {}. See Linux coding style.
> + return dev_err_probe(dev, PTR_ERR(ap->regmap),
> + "failed to init register map\n");
> + }
> +
> + chip->ops = &atcpit_pwm_ops;
> + ret = devm_pwmchip_add(dev, chip);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to add pwm chip\n");
> +
> + dev_info(dev, "pwm driver probed\n");
Drop all such "success" messages.
Best regards,
Krzysztof
Powered by blists - more mailing lists