Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
0004  *  JZ4740 platform PWM support
0005  *
0006  * Limitations:
0007  * - The .apply callback doesn't complete the currently running period before
0008  *   reconfiguring the hardware.
0009  */
0010 
0011 #include <linux/clk.h>
0012 #include <linux/err.h>
0013 #include <linux/gpio.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mfd/ingenic-tcu.h>
0016 #include <linux/mfd/syscon.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/pwm.h>
0021 #include <linux/regmap.h>
0022 
0023 struct soc_info {
0024     unsigned int num_pwms;
0025 };
0026 
0027 struct jz4740_pwm_chip {
0028     struct pwm_chip chip;
0029     struct regmap *map;
0030 };
0031 
0032 static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
0033 {
0034     return container_of(chip, struct jz4740_pwm_chip, chip);
0035 }
0036 
0037 static bool jz4740_pwm_can_use_chn(struct jz4740_pwm_chip *jz,
0038                    unsigned int channel)
0039 {
0040     /* Enable all TCU channels for PWM use by default except channels 0/1 */
0041     u32 pwm_channels_mask = GENMASK(jz->chip.npwm - 1, 2);
0042 
0043     device_property_read_u32(jz->chip.dev->parent,
0044                  "ingenic,pwm-channels-mask",
0045                  &pwm_channels_mask);
0046 
0047     return !!(pwm_channels_mask & BIT(channel));
0048 }
0049 
0050 static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
0051 {
0052     struct jz4740_pwm_chip *jz = to_jz4740(chip);
0053     struct clk *clk;
0054     char name[16];
0055     int err;
0056 
0057     if (!jz4740_pwm_can_use_chn(jz, pwm->hwpwm))
0058         return -EBUSY;
0059 
0060     snprintf(name, sizeof(name), "timer%u", pwm->hwpwm);
0061 
0062     clk = clk_get(chip->dev, name);
0063     if (IS_ERR(clk))
0064         return dev_err_probe(chip->dev, PTR_ERR(clk),
0065                      "Failed to get clock\n");
0066 
0067     err = clk_prepare_enable(clk);
0068     if (err < 0) {
0069         clk_put(clk);
0070         return err;
0071     }
0072 
0073     pwm_set_chip_data(pwm, clk);
0074 
0075     return 0;
0076 }
0077 
0078 static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
0079 {
0080     struct clk *clk = pwm_get_chip_data(pwm);
0081 
0082     clk_disable_unprepare(clk);
0083     clk_put(clk);
0084 }
0085 
0086 static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0087 {
0088     struct jz4740_pwm_chip *jz = to_jz4740(chip);
0089 
0090     /* Enable PWM output */
0091     regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
0092                TCU_TCSR_PWM_EN, TCU_TCSR_PWM_EN);
0093 
0094     /* Start counter */
0095     regmap_write(jz->map, TCU_REG_TESR, BIT(pwm->hwpwm));
0096 
0097     return 0;
0098 }
0099 
0100 static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
0101 {
0102     struct jz4740_pwm_chip *jz = to_jz4740(chip);
0103 
0104     /*
0105      * Set duty > period. This trick allows the TCU channels in TCU2 mode to
0106      * properly return to their init level.
0107      */
0108     regmap_write(jz->map, TCU_REG_TDHRc(pwm->hwpwm), 0xffff);
0109     regmap_write(jz->map, TCU_REG_TDFRc(pwm->hwpwm), 0x0);
0110 
0111     /*
0112      * Disable PWM output.
0113      * In TCU2 mode (channel 1/2 on JZ4750+), this must be done before the
0114      * counter is stopped, while in TCU1 mode the order does not matter.
0115      */
0116     regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
0117                TCU_TCSR_PWM_EN, 0);
0118 
0119     /* Stop counter */
0120     regmap_write(jz->map, TCU_REG_TECR, BIT(pwm->hwpwm));
0121 }
0122 
0123 static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0124                 const struct pwm_state *state)
0125 {
0126     struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
0127     unsigned long long tmp = 0xffffull * NSEC_PER_SEC;
0128     struct clk *clk = pwm_get_chip_data(pwm);
0129     unsigned long period, duty;
0130     long rate;
0131     int err;
0132 
0133     /*
0134      * Limit the clock to a maximum rate that still gives us a period value
0135      * which fits in 16 bits.
0136      */
0137     do_div(tmp, state->period);
0138 
0139     /*
0140      * /!\ IMPORTANT NOTE:
0141      * -------------------
0142      * This code relies on the fact that clk_round_rate() will always round
0143      * down, which is not a valid assumption given by the clk API, but only
0144      * happens to be true with the clk drivers used for Ingenic SoCs.
0145      *
0146      * Right now, there is no alternative as the clk API does not have a
0147      * round-down function (and won't have one for a while), but if it ever
0148      * comes to light, a round-down function should be used instead.
0149      */
0150     rate = clk_round_rate(clk, tmp);
0151     if (rate < 0) {
0152         dev_err(chip->dev, "Unable to round rate: %ld", rate);
0153         return rate;
0154     }
0155 
0156     /* Calculate period value */
0157     tmp = (unsigned long long)rate * state->period;
0158     do_div(tmp, NSEC_PER_SEC);
0159     period = tmp;
0160 
0161     /* Calculate duty value */
0162     tmp = (unsigned long long)rate * state->duty_cycle;
0163     do_div(tmp, NSEC_PER_SEC);
0164     duty = tmp;
0165 
0166     if (duty >= period)
0167         duty = period - 1;
0168 
0169     jz4740_pwm_disable(chip, pwm);
0170 
0171     err = clk_set_rate(clk, rate);
0172     if (err) {
0173         dev_err(chip->dev, "Unable to set rate: %d", err);
0174         return err;
0175     }
0176 
0177     /* Reset counter to 0 */
0178     regmap_write(jz4740->map, TCU_REG_TCNTc(pwm->hwpwm), 0);
0179 
0180     /* Set duty */
0181     regmap_write(jz4740->map, TCU_REG_TDHRc(pwm->hwpwm), duty);
0182 
0183     /* Set period */
0184     regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
0185 
0186     /* Set abrupt shutdown */
0187     regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0188                TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
0189 
0190     /*
0191      * Set polarity.
0192      *
0193      * The PWM starts in inactive state until the internal timer reaches the
0194      * duty value, then becomes active until the timer reaches the period
0195      * value. In theory, we should then use (period - duty) as the real duty
0196      * value, as a high duty value would otherwise result in the PWM pin
0197      * being inactive most of the time.
0198      *
0199      * Here, we don't do that, and instead invert the polarity of the PWM
0200      * when it is active. This trick makes the PWM start with its active
0201      * state instead of its inactive state.
0202      */
0203     if ((state->polarity == PWM_POLARITY_NORMAL) ^ state->enabled)
0204         regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0205                    TCU_TCSR_PWM_INITL_HIGH, 0);
0206     else
0207         regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0208                    TCU_TCSR_PWM_INITL_HIGH,
0209                    TCU_TCSR_PWM_INITL_HIGH);
0210 
0211     if (state->enabled)
0212         jz4740_pwm_enable(chip, pwm);
0213 
0214     return 0;
0215 }
0216 
0217 static const struct pwm_ops jz4740_pwm_ops = {
0218     .request = jz4740_pwm_request,
0219     .free = jz4740_pwm_free,
0220     .apply = jz4740_pwm_apply,
0221     .owner = THIS_MODULE,
0222 };
0223 
0224 static int jz4740_pwm_probe(struct platform_device *pdev)
0225 {
0226     struct device *dev = &pdev->dev;
0227     struct jz4740_pwm_chip *jz4740;
0228     const struct soc_info *info;
0229 
0230     info = device_get_match_data(dev);
0231     if (!info)
0232         return -EINVAL;
0233 
0234     jz4740 = devm_kzalloc(dev, sizeof(*jz4740), GFP_KERNEL);
0235     if (!jz4740)
0236         return -ENOMEM;
0237 
0238     jz4740->map = device_node_to_regmap(dev->parent->of_node);
0239     if (IS_ERR(jz4740->map)) {
0240         dev_err(dev, "regmap not found: %ld\n", PTR_ERR(jz4740->map));
0241         return PTR_ERR(jz4740->map);
0242     }
0243 
0244     jz4740->chip.dev = dev;
0245     jz4740->chip.ops = &jz4740_pwm_ops;
0246     jz4740->chip.npwm = info->num_pwms;
0247 
0248     return devm_pwmchip_add(dev, &jz4740->chip);
0249 }
0250 
0251 static const struct soc_info __maybe_unused jz4740_soc_info = {
0252     .num_pwms = 8,
0253 };
0254 
0255 static const struct soc_info __maybe_unused jz4725b_soc_info = {
0256     .num_pwms = 6,
0257 };
0258 
0259 static const struct soc_info __maybe_unused x1000_soc_info = {
0260     .num_pwms = 5,
0261 };
0262 
0263 #ifdef CONFIG_OF
0264 static const struct of_device_id jz4740_pwm_dt_ids[] = {
0265     { .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
0266     { .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
0267     { .compatible = "ingenic,x1000-pwm", .data = &x1000_soc_info },
0268     {},
0269 };
0270 MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
0271 #endif
0272 
0273 static struct platform_driver jz4740_pwm_driver = {
0274     .driver = {
0275         .name = "jz4740-pwm",
0276         .of_match_table = of_match_ptr(jz4740_pwm_dt_ids),
0277     },
0278     .probe = jz4740_pwm_probe,
0279 };
0280 module_platform_driver(jz4740_pwm_driver);
0281 
0282 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0283 MODULE_DESCRIPTION("Ingenic JZ4740 PWM driver");
0284 MODULE_ALIAS("platform:jz4740-pwm");
0285 MODULE_LICENSE("GPL");