0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/err.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pwm.h>
0013
0014 #define PWM_CONTROL 0x000
0015 #define PWM_CONTROL_SHIFT(x) ((x) * 8)
0016 #define PWM_CONTROL_MASK 0xff
0017 #define PWM_MODE 0x80
0018 #define PWM_ENABLE (1 << 0)
0019 #define PWM_POLARITY (1 << 4)
0020
0021 #define PERIOD(x) (((x) * 0x10) + 0x10)
0022 #define DUTY(x) (((x) * 0x10) + 0x14)
0023
0024 #define PERIOD_MIN 0x2
0025
0026 struct bcm2835_pwm {
0027 struct pwm_chip chip;
0028 struct device *dev;
0029 void __iomem *base;
0030 struct clk *clk;
0031 };
0032
0033 static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip)
0034 {
0035 return container_of(chip, struct bcm2835_pwm, chip);
0036 }
0037
0038 static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
0039 {
0040 struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
0041 u32 value;
0042
0043 value = readl(pc->base + PWM_CONTROL);
0044 value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm));
0045 value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm));
0046 writel(value, pc->base + PWM_CONTROL);
0047
0048 return 0;
0049 }
0050
0051 static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
0052 {
0053 struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
0054 u32 value;
0055
0056 value = readl(pc->base + PWM_CONTROL);
0057 value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm));
0058 writel(value, pc->base + PWM_CONTROL);
0059 }
0060
0061 static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0062 const struct pwm_state *state)
0063 {
0064
0065 struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
0066 unsigned long rate = clk_get_rate(pc->clk);
0067 unsigned long long period_cycles;
0068 u64 max_period;
0069
0070 u32 val;
0071
0072 if (!rate) {
0073 dev_err(pc->dev, "failed to get clock rate\n");
0074 return -EINVAL;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 max_period = DIV_ROUND_UP_ULL((u64)U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2, rate) - 1;
0092
0093 if (state->period > max_period)
0094 return -EINVAL;
0095
0096
0097 period_cycles = DIV_ROUND_CLOSEST_ULL(state->period * rate, NSEC_PER_SEC);
0098
0099
0100 if (period_cycles < PERIOD_MIN)
0101 return -EINVAL;
0102
0103 writel(period_cycles, pc->base + PERIOD(pwm->hwpwm));
0104
0105
0106 val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * rate, NSEC_PER_SEC);
0107 writel(val, pc->base + DUTY(pwm->hwpwm));
0108
0109
0110 val = readl(pc->base + PWM_CONTROL);
0111
0112 if (state->polarity == PWM_POLARITY_NORMAL)
0113 val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm));
0114 else
0115 val |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm);
0116
0117
0118 if (state->enabled)
0119 val |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm);
0120 else
0121 val &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm));
0122
0123 writel(val, pc->base + PWM_CONTROL);
0124
0125 return 0;
0126 }
0127
0128 static const struct pwm_ops bcm2835_pwm_ops = {
0129 .request = bcm2835_pwm_request,
0130 .free = bcm2835_pwm_free,
0131 .apply = bcm2835_pwm_apply,
0132 .owner = THIS_MODULE,
0133 };
0134
0135 static int bcm2835_pwm_probe(struct platform_device *pdev)
0136 {
0137 struct bcm2835_pwm *pc;
0138 int ret;
0139
0140 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
0141 if (!pc)
0142 return -ENOMEM;
0143
0144 pc->dev = &pdev->dev;
0145
0146 pc->base = devm_platform_ioremap_resource(pdev, 0);
0147 if (IS_ERR(pc->base))
0148 return PTR_ERR(pc->base);
0149
0150 pc->clk = devm_clk_get(&pdev->dev, NULL);
0151 if (IS_ERR(pc->clk))
0152 return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
0153 "clock not found\n");
0154
0155 ret = clk_prepare_enable(pc->clk);
0156 if (ret)
0157 return ret;
0158
0159 pc->chip.dev = &pdev->dev;
0160 pc->chip.ops = &bcm2835_pwm_ops;
0161 pc->chip.npwm = 2;
0162
0163 platform_set_drvdata(pdev, pc);
0164
0165 ret = pwmchip_add(&pc->chip);
0166 if (ret < 0)
0167 goto add_fail;
0168
0169 return 0;
0170
0171 add_fail:
0172 clk_disable_unprepare(pc->clk);
0173 return ret;
0174 }
0175
0176 static int bcm2835_pwm_remove(struct platform_device *pdev)
0177 {
0178 struct bcm2835_pwm *pc = platform_get_drvdata(pdev);
0179
0180 pwmchip_remove(&pc->chip);
0181
0182 clk_disable_unprepare(pc->clk);
0183
0184 return 0;
0185 }
0186
0187 static const struct of_device_id bcm2835_pwm_of_match[] = {
0188 { .compatible = "brcm,bcm2835-pwm", },
0189 { }
0190 };
0191 MODULE_DEVICE_TABLE(of, bcm2835_pwm_of_match);
0192
0193 static struct platform_driver bcm2835_pwm_driver = {
0194 .driver = {
0195 .name = "bcm2835-pwm",
0196 .of_match_table = bcm2835_pwm_of_match,
0197 },
0198 .probe = bcm2835_pwm_probe,
0199 .remove = bcm2835_pwm_remove,
0200 };
0201 module_platform_driver(bcm2835_pwm_driver);
0202
0203 MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be>");
0204 MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver");
0205 MODULE_LICENSE("GPL v2");