0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/err.h>
0008 #include <linux/io.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/pwm.h>
0015 #include <linux/slab.h>
0016
0017 struct lpc32xx_pwm_chip {
0018 struct pwm_chip chip;
0019 struct clk *clk;
0020 void __iomem *base;
0021 };
0022
0023 #define PWM_ENABLE BIT(31)
0024 #define PWM_PIN_LEVEL BIT(30)
0025
0026 #define to_lpc32xx_pwm_chip(_chip) \
0027 container_of(_chip, struct lpc32xx_pwm_chip, chip)
0028
0029 static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
0030 int duty_ns, int period_ns)
0031 {
0032 struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
0033 unsigned long long c;
0034 int period_cycles, duty_cycles;
0035 u32 val;
0036 c = clk_get_rate(lpc32xx->clk);
0037
0038
0039 period_cycles = div64_u64(c * period_ns,
0040 (unsigned long long)NSEC_PER_SEC * 256);
0041 if (!period_cycles || period_cycles > 256)
0042 return -ERANGE;
0043 if (period_cycles == 256)
0044 period_cycles = 0;
0045
0046
0047 duty_cycles = div64_u64((unsigned long long)(period_ns - duty_ns) * 256,
0048 period_ns);
0049 if (!duty_cycles)
0050 duty_cycles = 1;
0051 if (duty_cycles > 255)
0052 duty_cycles = 255;
0053
0054 val = readl(lpc32xx->base + (pwm->hwpwm << 2));
0055 val &= ~0xFFFF;
0056 val |= (period_cycles << 8) | duty_cycles;
0057 writel(val, lpc32xx->base + (pwm->hwpwm << 2));
0058
0059 return 0;
0060 }
0061
0062 static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0063 {
0064 struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
0065 u32 val;
0066 int ret;
0067
0068 ret = clk_prepare_enable(lpc32xx->clk);
0069 if (ret)
0070 return ret;
0071
0072 val = readl(lpc32xx->base + (pwm->hwpwm << 2));
0073 val |= PWM_ENABLE;
0074 writel(val, lpc32xx->base + (pwm->hwpwm << 2));
0075
0076 return 0;
0077 }
0078
0079 static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
0080 {
0081 struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
0082 u32 val;
0083
0084 val = readl(lpc32xx->base + (pwm->hwpwm << 2));
0085 val &= ~PWM_ENABLE;
0086 writel(val, lpc32xx->base + (pwm->hwpwm << 2));
0087
0088 clk_disable_unprepare(lpc32xx->clk);
0089 }
0090
0091 static int lpc32xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0092 const struct pwm_state *state)
0093 {
0094 int err;
0095
0096 if (state->polarity != PWM_POLARITY_NORMAL)
0097 return -EINVAL;
0098
0099 if (!state->enabled) {
0100 if (pwm->state.enabled)
0101 lpc32xx_pwm_disable(chip, pwm);
0102
0103 return 0;
0104 }
0105
0106 err = lpc32xx_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period);
0107 if (err)
0108 return err;
0109
0110 if (!pwm->state.enabled)
0111 err = lpc32xx_pwm_enable(chip, pwm);
0112
0113 return err;
0114 }
0115
0116 static const struct pwm_ops lpc32xx_pwm_ops = {
0117 .apply = lpc32xx_pwm_apply,
0118 .owner = THIS_MODULE,
0119 };
0120
0121 static int lpc32xx_pwm_probe(struct platform_device *pdev)
0122 {
0123 struct lpc32xx_pwm_chip *lpc32xx;
0124 int ret;
0125 u32 val;
0126
0127 lpc32xx = devm_kzalloc(&pdev->dev, sizeof(*lpc32xx), GFP_KERNEL);
0128 if (!lpc32xx)
0129 return -ENOMEM;
0130
0131 lpc32xx->base = devm_platform_ioremap_resource(pdev, 0);
0132 if (IS_ERR(lpc32xx->base))
0133 return PTR_ERR(lpc32xx->base);
0134
0135 lpc32xx->clk = devm_clk_get(&pdev->dev, NULL);
0136 if (IS_ERR(lpc32xx->clk))
0137 return PTR_ERR(lpc32xx->clk);
0138
0139 lpc32xx->chip.dev = &pdev->dev;
0140 lpc32xx->chip.ops = &lpc32xx_pwm_ops;
0141 lpc32xx->chip.npwm = 1;
0142
0143
0144 val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
0145 val &= ~PWM_PIN_LEVEL;
0146 writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
0147
0148 ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip);
0149 if (ret < 0) {
0150 dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret);
0151 return ret;
0152 }
0153
0154 return 0;
0155 }
0156
0157 static const struct of_device_id lpc32xx_pwm_dt_ids[] = {
0158 { .compatible = "nxp,lpc3220-pwm", },
0159 { }
0160 };
0161 MODULE_DEVICE_TABLE(of, lpc32xx_pwm_dt_ids);
0162
0163 static struct platform_driver lpc32xx_pwm_driver = {
0164 .driver = {
0165 .name = "lpc32xx-pwm",
0166 .of_match_table = lpc32xx_pwm_dt_ids,
0167 },
0168 .probe = lpc32xx_pwm_probe,
0169 };
0170 module_platform_driver(lpc32xx_pwm_driver);
0171
0172 MODULE_ALIAS("platform:lpc32xx-pwm");
0173 MODULE_AUTHOR("Alexandre Pereira da Silva <aletes.xgr@gmail.com>");
0174 MODULE_DESCRIPTION("LPC32XX PWM Driver");
0175 MODULE_LICENSE("GPL v2");