Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * ECAP PWM driver
0004  *
0005  * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/io.h>
0011 #include <linux/err.h>
0012 #include <linux/clk.h>
0013 #include <linux/pm_runtime.h>
0014 #include <linux/pwm.h>
0015 #include <linux/of_device.h>
0016 
0017 /* ECAP registers and bits definitions */
0018 #define CAP1            0x08
0019 #define CAP2            0x0C
0020 #define CAP3            0x10
0021 #define CAP4            0x14
0022 #define ECCTL2          0x2A
0023 #define ECCTL2_APWM_POL_LOW BIT(10)
0024 #define ECCTL2_APWM_MODE    BIT(9)
0025 #define ECCTL2_SYNC_SEL_DISA    (BIT(7) | BIT(6))
0026 #define ECCTL2_TSCTR_FREERUN    BIT(4)
0027 
0028 struct ecap_context {
0029     u32 cap3;
0030     u32 cap4;
0031     u16 ecctl2;
0032 };
0033 
0034 struct ecap_pwm_chip {
0035     struct pwm_chip chip;
0036     unsigned int clk_rate;
0037     void __iomem *mmio_base;
0038     struct ecap_context ctx;
0039 };
0040 
0041 static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip)
0042 {
0043     return container_of(chip, struct ecap_pwm_chip, chip);
0044 }
0045 
0046 /*
0047  * period_ns = 10^9 * period_cycles / PWM_CLK_RATE
0048  * duty_ns   = 10^9 * duty_cycles / PWM_CLK_RATE
0049  */
0050 static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
0051                int duty_ns, int period_ns, int enabled)
0052 {
0053     struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
0054     u32 period_cycles, duty_cycles;
0055     unsigned long long c;
0056     u16 value;
0057 
0058     c = pc->clk_rate;
0059     c = c * period_ns;
0060     do_div(c, NSEC_PER_SEC);
0061     period_cycles = (u32)c;
0062 
0063     if (period_cycles < 1) {
0064         period_cycles = 1;
0065         duty_cycles = 1;
0066     } else {
0067         c = pc->clk_rate;
0068         c = c * duty_ns;
0069         do_div(c, NSEC_PER_SEC);
0070         duty_cycles = (u32)c;
0071     }
0072 
0073     pm_runtime_get_sync(pc->chip.dev);
0074 
0075     value = readw(pc->mmio_base + ECCTL2);
0076 
0077     /* Configure APWM mode & disable sync option */
0078     value |= ECCTL2_APWM_MODE | ECCTL2_SYNC_SEL_DISA;
0079 
0080     writew(value, pc->mmio_base + ECCTL2);
0081 
0082     if (!enabled) {
0083         /* Update active registers if not running */
0084         writel(duty_cycles, pc->mmio_base + CAP2);
0085         writel(period_cycles, pc->mmio_base + CAP1);
0086     } else {
0087         /*
0088          * Update shadow registers to configure period and
0089          * compare values. This helps current PWM period to
0090          * complete on reconfiguring
0091          */
0092         writel(duty_cycles, pc->mmio_base + CAP4);
0093         writel(period_cycles, pc->mmio_base + CAP3);
0094     }
0095 
0096     if (!enabled) {
0097         value = readw(pc->mmio_base + ECCTL2);
0098         /* Disable APWM mode to put APWM output Low */
0099         value &= ~ECCTL2_APWM_MODE;
0100         writew(value, pc->mmio_base + ECCTL2);
0101     }
0102 
0103     pm_runtime_put_sync(pc->chip.dev);
0104 
0105     return 0;
0106 }
0107 
0108 static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
0109                  enum pwm_polarity polarity)
0110 {
0111     struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
0112     u16 value;
0113 
0114     pm_runtime_get_sync(pc->chip.dev);
0115 
0116     value = readw(pc->mmio_base + ECCTL2);
0117 
0118     if (polarity == PWM_POLARITY_INVERSED)
0119         /* Duty cycle defines LOW period of PWM */
0120         value |= ECCTL2_APWM_POL_LOW;
0121     else
0122         /* Duty cycle defines HIGH period of PWM */
0123         value &= ~ECCTL2_APWM_POL_LOW;
0124 
0125     writew(value, pc->mmio_base + ECCTL2);
0126 
0127     pm_runtime_put_sync(pc->chip.dev);
0128 
0129     return 0;
0130 }
0131 
0132 static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0133 {
0134     struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
0135     u16 value;
0136 
0137     /* Leave clock enabled on enabling PWM */
0138     pm_runtime_get_sync(pc->chip.dev);
0139 
0140     /*
0141      * Enable 'Free run Time stamp counter mode' to start counter
0142      * and  'APWM mode' to enable APWM output
0143      */
0144     value = readw(pc->mmio_base + ECCTL2);
0145     value |= ECCTL2_TSCTR_FREERUN | ECCTL2_APWM_MODE;
0146     writew(value, pc->mmio_base + ECCTL2);
0147 
0148     return 0;
0149 }
0150 
0151 static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
0152 {
0153     struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
0154     u16 value;
0155 
0156     /*
0157      * Disable 'Free run Time stamp counter mode' to stop counter
0158      * and 'APWM mode' to put APWM output to low
0159      */
0160     value = readw(pc->mmio_base + ECCTL2);
0161     value &= ~(ECCTL2_TSCTR_FREERUN | ECCTL2_APWM_MODE);
0162     writew(value, pc->mmio_base + ECCTL2);
0163 
0164     /* Disable clock on PWM disable */
0165     pm_runtime_put_sync(pc->chip.dev);
0166 }
0167 
0168 static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0169               const struct pwm_state *state)
0170 {
0171     int err;
0172     int enabled = pwm->state.enabled;
0173 
0174     if (state->polarity != pwm->state.polarity) {
0175 
0176         if (enabled) {
0177             ecap_pwm_disable(chip, pwm);
0178             enabled = false;
0179         }
0180 
0181         err = ecap_pwm_set_polarity(chip, pwm, state->polarity);
0182         if (err)
0183             return err;
0184     }
0185 
0186     if (!state->enabled) {
0187         if (enabled)
0188             ecap_pwm_disable(chip, pwm);
0189         return 0;
0190     }
0191 
0192     if (state->period > NSEC_PER_SEC)
0193         return -ERANGE;
0194 
0195     err = ecap_pwm_config(chip, pwm, state->duty_cycle,
0196                   state->period, enabled);
0197     if (err)
0198         return err;
0199 
0200     if (!enabled)
0201         return ecap_pwm_enable(chip, pwm);
0202 
0203     return 0;
0204 }
0205 
0206 static const struct pwm_ops ecap_pwm_ops = {
0207     .apply = ecap_pwm_apply,
0208     .owner = THIS_MODULE,
0209 };
0210 
0211 static const struct of_device_id ecap_of_match[] = {
0212     { .compatible   = "ti,am3352-ecap" },
0213     { .compatible   = "ti,am33xx-ecap" },
0214     {},
0215 };
0216 MODULE_DEVICE_TABLE(of, ecap_of_match);
0217 
0218 static int ecap_pwm_probe(struct platform_device *pdev)
0219 {
0220     struct device_node *np = pdev->dev.of_node;
0221     struct ecap_pwm_chip *pc;
0222     struct clk *clk;
0223     int ret;
0224 
0225     pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
0226     if (!pc)
0227         return -ENOMEM;
0228 
0229     clk = devm_clk_get(&pdev->dev, "fck");
0230     if (IS_ERR(clk)) {
0231         if (of_device_is_compatible(np, "ti,am33xx-ecap")) {
0232             dev_warn(&pdev->dev, "Binding is obsolete.\n");
0233             clk = devm_clk_get(pdev->dev.parent, "fck");
0234         }
0235     }
0236 
0237     if (IS_ERR(clk)) {
0238         dev_err(&pdev->dev, "failed to get clock\n");
0239         return PTR_ERR(clk);
0240     }
0241 
0242     pc->clk_rate = clk_get_rate(clk);
0243     if (!pc->clk_rate) {
0244         dev_err(&pdev->dev, "failed to get clock rate\n");
0245         return -EINVAL;
0246     }
0247 
0248     pc->chip.dev = &pdev->dev;
0249     pc->chip.ops = &ecap_pwm_ops;
0250     pc->chip.npwm = 1;
0251 
0252     pc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
0253     if (IS_ERR(pc->mmio_base))
0254         return PTR_ERR(pc->mmio_base);
0255 
0256     ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
0257     if (ret < 0) {
0258         dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
0259         return ret;
0260     }
0261 
0262     platform_set_drvdata(pdev, pc);
0263     pm_runtime_enable(&pdev->dev);
0264 
0265     return 0;
0266 }
0267 
0268 static int ecap_pwm_remove(struct platform_device *pdev)
0269 {
0270     pm_runtime_disable(&pdev->dev);
0271 
0272     return 0;
0273 }
0274 
0275 #ifdef CONFIG_PM_SLEEP
0276 static void ecap_pwm_save_context(struct ecap_pwm_chip *pc)
0277 {
0278     pm_runtime_get_sync(pc->chip.dev);
0279     pc->ctx.ecctl2 = readw(pc->mmio_base + ECCTL2);
0280     pc->ctx.cap4 = readl(pc->mmio_base + CAP4);
0281     pc->ctx.cap3 = readl(pc->mmio_base + CAP3);
0282     pm_runtime_put_sync(pc->chip.dev);
0283 }
0284 
0285 static void ecap_pwm_restore_context(struct ecap_pwm_chip *pc)
0286 {
0287     writel(pc->ctx.cap3, pc->mmio_base + CAP3);
0288     writel(pc->ctx.cap4, pc->mmio_base + CAP4);
0289     writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2);
0290 }
0291 
0292 static int ecap_pwm_suspend(struct device *dev)
0293 {
0294     struct ecap_pwm_chip *pc = dev_get_drvdata(dev);
0295     struct pwm_device *pwm = pc->chip.pwms;
0296 
0297     ecap_pwm_save_context(pc);
0298 
0299     /* Disable explicitly if PWM is running */
0300     if (pwm_is_enabled(pwm))
0301         pm_runtime_put_sync(dev);
0302 
0303     return 0;
0304 }
0305 
0306 static int ecap_pwm_resume(struct device *dev)
0307 {
0308     struct ecap_pwm_chip *pc = dev_get_drvdata(dev);
0309     struct pwm_device *pwm = pc->chip.pwms;
0310 
0311     /* Enable explicitly if PWM was running */
0312     if (pwm_is_enabled(pwm))
0313         pm_runtime_get_sync(dev);
0314 
0315     ecap_pwm_restore_context(pc);
0316     return 0;
0317 }
0318 #endif
0319 
0320 static SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume);
0321 
0322 static struct platform_driver ecap_pwm_driver = {
0323     .driver = {
0324         .name = "ecap",
0325         .of_match_table = ecap_of_match,
0326         .pm = &ecap_pwm_pm_ops,
0327     },
0328     .probe = ecap_pwm_probe,
0329     .remove = ecap_pwm_remove,
0330 };
0331 module_platform_driver(ecap_pwm_driver);
0332 
0333 MODULE_DESCRIPTION("ECAP PWM driver");
0334 MODULE_AUTHOR("Texas Instruments");
0335 MODULE_LICENSE("GPL");