1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2014 Bart Tanghe <bart.tanghe@thomasmore.be> 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/err.h> 8 #include <linux/io.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pwm.h> 13 14 #define PWM_CONTROL 0x000 15 #define PWM_CONTROL_SHIFT(x) ((x) * 8) 16 #define PWM_CONTROL_MASK 0xff 17 #define PWM_MODE 0x80 /* set timer in PWM mode */ 18 #define PWM_ENABLE (1 << 0) 19 #define PWM_POLARITY (1 << 4) 20 21 #define PERIOD(x) (((x) * 0x10) + 0x10) 22 #define DUTY(x) (((x) * 0x10) + 0x14) 23 24 #define PERIOD_MIN 0x2 25 26 struct bcm2835_pwm { 27 void __iomem *base; 28 struct clk *clk; 29 unsigned long rate; 30 }; 31 32 static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) 33 { 34 return pwmchip_get_drvdata(chip); 35 } 36 37 static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 38 const struct pwm_state *state) 39 { 40 41 struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); 42 unsigned long long period_cycles; 43 u64 max_period; 44 45 u32 val; 46 47 /* 48 * period_cycles must be a 32 bit value, so period * rate / NSEC_PER_SEC 49 * must be <= U32_MAX. As U32_MAX * NSEC_PER_SEC < U64_MAX the 50 * multiplication period * rate doesn't overflow. 51 * To calculate the maximal possible period that guarantees the 52 * above inequality: 53 * 54 * round(period * rate / NSEC_PER_SEC) <= U32_MAX 55 * <=> period * rate / NSEC_PER_SEC < U32_MAX + 0.5 56 * <=> period * rate < (U32_MAX + 0.5) * NSEC_PER_SEC 57 * <=> period < ((U32_MAX + 0.5) * NSEC_PER_SEC) / rate 58 * <=> period < ((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate 59 * <=> period <= ceil((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate) - 1 60 */ 61 max_period = DIV_ROUND_UP_ULL((u64)U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2, pc->rate) - 1; 62 63 if (state->period > max_period) 64 return -EINVAL; 65 66 /* set period */ 67 period_cycles = DIV_ROUND_CLOSEST_ULL(state->period * pc->rate, NSEC_PER_SEC); 68 69 /* don't accept a period that is too small */ 70 if (period_cycles < PERIOD_MIN) 71 return -EINVAL; 72 73 writel(period_cycles, pc->base + PERIOD(pwm->hwpwm)); 74 75 /* set duty cycle */ 76 val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * pc->rate, NSEC_PER_SEC); 77 writel(val, pc->base + DUTY(pwm->hwpwm)); 78 79 /* set polarity */ 80 val = readl(pc->base + PWM_CONTROL); 81 82 val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); 83 val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); 84 85 if (state->polarity == PWM_POLARITY_NORMAL) 86 val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); 87 else 88 val |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm); 89 90 /* enable/disable */ 91 if (state->enabled) 92 val |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm); 93 else 94 val &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm)); 95 96 writel(val, pc->base + PWM_CONTROL); 97 98 return 0; 99 } 100 101 static const struct pwm_ops bcm2835_pwm_ops = { 102 .apply = bcm2835_pwm_apply, 103 }; 104 105 static int bcm2835_pwm_probe(struct platform_device *pdev) 106 { 107 struct device *dev = &pdev->dev; 108 struct pwm_chip *chip; 109 struct bcm2835_pwm *pc; 110 int ret; 111 112 chip = devm_pwmchip_alloc(dev, 2, sizeof(*pc)); 113 if (IS_ERR(chip)) 114 return PTR_ERR(chip); 115 pc = to_bcm2835_pwm(chip); 116 117 pc->base = devm_platform_ioremap_resource(pdev, 0); 118 if (IS_ERR(pc->base)) 119 return PTR_ERR(pc->base); 120 121 pc->clk = devm_clk_get_enabled(dev, NULL); 122 if (IS_ERR(pc->clk)) 123 return dev_err_probe(dev, PTR_ERR(pc->clk), 124 "clock not found\n"); 125 126 ret = devm_clk_rate_exclusive_get(dev, pc->clk); 127 if (ret) 128 return dev_err_probe(dev, ret, 129 "fail to get exclusive rate\n"); 130 131 pc->rate = clk_get_rate(pc->clk); 132 if (!pc->rate) 133 return dev_err_probe(dev, -EINVAL, 134 "failed to get clock rate\n"); 135 136 chip->ops = &bcm2835_pwm_ops; 137 chip->atomic = true; 138 139 platform_set_drvdata(pdev, pc); 140 141 ret = devm_pwmchip_add(dev, chip); 142 if (ret < 0) 143 return dev_err_probe(dev, ret, "failed to add pwmchip\n"); 144 145 return 0; 146 } 147 148 static int bcm2835_pwm_suspend(struct device *dev) 149 { 150 struct bcm2835_pwm *pc = dev_get_drvdata(dev); 151 152 clk_disable_unprepare(pc->clk); 153 154 return 0; 155 } 156 157 static int bcm2835_pwm_resume(struct device *dev) 158 { 159 struct bcm2835_pwm *pc = dev_get_drvdata(dev); 160 161 return clk_prepare_enable(pc->clk); 162 } 163 164 static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835_pwm_pm_ops, bcm2835_pwm_suspend, 165 bcm2835_pwm_resume); 166 167 static const struct of_device_id bcm2835_pwm_of_match[] = { 168 { .compatible = "brcm,bcm2835-pwm", }, 169 { /* sentinel */ } 170 }; 171 MODULE_DEVICE_TABLE(of, bcm2835_pwm_of_match); 172 173 static struct platform_driver bcm2835_pwm_driver = { 174 .driver = { 175 .name = "bcm2835-pwm", 176 .of_match_table = bcm2835_pwm_of_match, 177 .pm = pm_ptr(&bcm2835_pwm_pm_ops), 178 }, 179 .probe = bcm2835_pwm_probe, 180 }; 181 module_platform_driver(bcm2835_pwm_driver); 182 183 MODULE_AUTHOR("Bart Tanghe <bart.tanghe@thomasmore.be>"); 184 MODULE_DESCRIPTION("Broadcom BCM2835 PWM driver"); 185 MODULE_LICENSE("GPL v2"); 186