1 /* 2 * PWM device driver for ST SoCs. 3 * Author: Ajit Pal Singh <ajitpal.singh@st.com> 4 * 5 * Copyright (C) 2013-2014 STMicroelectronics (R&D) Limited 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 #include <linux/bsearch.h> 14 #include <linux/clk.h> 15 #include <linux/math64.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/module.h> 18 #include <linux/of.h> 19 #include <linux/platform_device.h> 20 #include <linux/pwm.h> 21 #include <linux/regmap.h> 22 #include <linux/slab.h> 23 #include <linux/time.h> 24 25 #define STI_DS_REG(ch) (4 * (ch)) /* Channel's Duty Cycle register */ 26 #define STI_PWMCR 0x50 /* Control/Config register */ 27 #define STI_INTEN 0x54 /* Interrupt Enable/Disable register */ 28 29 /* Regfield IDs */ 30 enum { 31 PWMCLK_PRESCALE, 32 PWM_EN, 33 PWM_INT_EN, 34 35 /* Keep last */ 36 MAX_REGFIELDS 37 }; 38 39 struct sti_pwm_compat_data { 40 const struct reg_field *reg_fields; 41 unsigned int num_chan; 42 unsigned int max_pwm_cnt; 43 unsigned int max_prescale; 44 }; 45 46 struct sti_pwm_chip { 47 struct device *dev; 48 struct clk *clk; 49 unsigned long clk_rate; 50 struct regmap *regmap; 51 struct sti_pwm_compat_data *cdata; 52 struct regmap_field *prescale; 53 struct regmap_field *pwm_en; 54 struct regmap_field *pwm_int_en; 55 unsigned long *pwm_periods; 56 struct pwm_chip chip; 57 void __iomem *mmio; 58 }; 59 60 static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { 61 [PWMCLK_PRESCALE] = REG_FIELD(STI_PWMCR, 0, 3), 62 [PWM_EN] = REG_FIELD(STI_PWMCR, 9, 9), 63 [PWM_INT_EN] = REG_FIELD(STI_INTEN, 0, 0), 64 }; 65 66 static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) 67 { 68 return container_of(chip, struct sti_pwm_chip, chip); 69 } 70 71 /* 72 * Calculate the period values supported by the PWM for the 73 * current clock rate. 74 */ 75 static void sti_pwm_calc_periods(struct sti_pwm_chip *pc) 76 { 77 struct sti_pwm_compat_data *cdata = pc->cdata; 78 struct device *dev = pc->dev; 79 unsigned long val; 80 int i; 81 82 /* 83 * period_ns = (10^9 * (prescaler + 1) * (MAX_PWM_COUNT + 1)) / CLK_RATE 84 */ 85 val = NSEC_PER_SEC / pc->clk_rate; 86 val *= cdata->max_pwm_cnt + 1; 87 88 dev_dbg(dev, "possible periods for clkrate[HZ]:%lu\n", pc->clk_rate); 89 90 for (i = 0; i <= cdata->max_prescale; i++) { 91 pc->pwm_periods[i] = val * (i + 1); 92 dev_dbg(dev, "prescale:%d, period[ns]:%lu\n", 93 i, pc->pwm_periods[i]); 94 } 95 } 96 97 static int sti_pwm_cmp_periods(const void *key, const void *elt) 98 { 99 unsigned long i = *(unsigned long *)key; 100 unsigned long j = *(unsigned long *)elt; 101 102 if (i < j) 103 return -1; 104 else 105 return i == j ? 0 : 1; 106 } 107 108 /* 109 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. 110 * The only way to change the period (apart from changing the PWM input clock) 111 * is to change the PWM clock prescaler. 112 * The prescaler is of 4 bits, so only 16 prescaler values and hence only 113 * 16 possible period values are supported (for a particular clock rate). 114 * The requested period will be applied only if it matches one of these 115 * 16 values. 116 */ 117 static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 118 int duty_ns, int period_ns) 119 { 120 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 121 struct sti_pwm_compat_data *cdata = pc->cdata; 122 struct device *dev = pc->dev; 123 unsigned int prescale, pwmvalx; 124 unsigned long *found; 125 int ret; 126 127 /* 128 * Search for matching period value. The corresponding index is our 129 * prescale value 130 */ 131 found = bsearch(&period_ns, &pc->pwm_periods[0], 132 cdata->max_prescale + 1, sizeof(unsigned long), 133 sti_pwm_cmp_periods); 134 if (!found) { 135 dev_err(dev, "failed to find matching period\n"); 136 return -EINVAL; 137 } 138 139 prescale = found - &pc->pwm_periods[0]; 140 141 /* 142 * When PWMVal == 0, PWM pulse = 1 local clock cycle. 143 * When PWMVal == max_pwm_count, 144 * PWM pulse = (max_pwm_count + 1) local cycles, 145 * that is continuous pulse: signal never goes low. 146 */ 147 pwmvalx = cdata->max_pwm_cnt * duty_ns / period_ns; 148 149 dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", 150 prescale, period_ns, duty_ns, pwmvalx); 151 152 /* Enable clock before writing to PWM registers */ 153 ret = clk_enable(pc->clk); 154 if (ret) 155 return ret; 156 157 ret = regmap_field_write(pc->prescale, prescale); 158 if (ret) 159 goto clk_dis; 160 161 ret = regmap_write(pc->regmap, STI_PWMVAL(pwm->hwpwm), pwmvalx); 162 if (ret) 163 goto clk_dis; 164 165 ret = regmap_field_write(pc->pwm_int_en, 0); 166 167 clk_dis: 168 clk_disable(pc->clk); 169 return ret; 170 } 171 172 static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 173 { 174 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 175 struct device *dev = pc->dev; 176 int ret; 177 178 ret = clk_enable(pc->clk); 179 if (ret) 180 return ret; 181 182 ret = regmap_field_write(pc->pwm_en, 1); 183 if (ret) 184 dev_err(dev, "%s,pwm_en write failed\n", __func__); 185 186 return ret; 187 } 188 189 static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 190 { 191 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 192 struct device *dev = pc->dev; 193 unsigned int val; 194 195 regmap_field_write(pc->pwm_en, 0); 196 197 regmap_read(pc->regmap, STI_CNT, &val); 198 199 dev_dbg(dev, "pwm counter :%u\n", val); 200 201 clk_disable(pc->clk); 202 } 203 204 static const struct pwm_ops sti_pwm_ops = { 205 .config = sti_pwm_config, 206 .enable = sti_pwm_enable, 207 .disable = sti_pwm_disable, 208 .owner = THIS_MODULE, 209 }; 210 211 static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) 212 { 213 struct device *dev = pc->dev; 214 const struct reg_field *reg_fields; 215 struct device_node *np = dev->of_node; 216 struct sti_pwm_compat_data *cdata = pc->cdata; 217 u32 num_chan; 218 219 of_property_read_u32(np, "st,pwm-num-chan", &num_chan); 220 if (num_chan) 221 cdata->num_chan = num_chan; 222 223 reg_fields = cdata->reg_fields; 224 225 pc->prescale = devm_regmap_field_alloc(dev, pc->regmap, 226 reg_fields[PWMCLK_PRESCALE]); 227 if (IS_ERR(pc->prescale)) 228 return PTR_ERR(pc->prescale); 229 230 pc->pwm_en = devm_regmap_field_alloc(dev, pc->regmap, 231 reg_fields[PWM_EN]); 232 if (IS_ERR(pc->pwm_en)) 233 return PTR_ERR(pc->pwm_en); 234 235 pc->pwm_int_en = devm_regmap_field_alloc(dev, pc->regmap, 236 reg_fields[PWM_INT_EN]); 237 if (IS_ERR(pc->pwm_int_en)) 238 return PTR_ERR(pc->pwm_int_en); 239 240 return 0; 241 } 242 243 static const struct regmap_config sti_pwm_regmap_config = { 244 .reg_bits = 32, 245 .val_bits = 32, 246 .reg_stride = 4, 247 }; 248 249 static int sti_pwm_probe(struct platform_device *pdev) 250 { 251 struct device *dev = &pdev->dev; 252 struct sti_pwm_compat_data *cdata; 253 struct sti_pwm_chip *pc; 254 struct resource *res; 255 int ret; 256 257 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); 258 if (!pc) 259 return -ENOMEM; 260 261 cdata = devm_kzalloc(dev, sizeof(*cdata), GFP_KERNEL); 262 if (!cdata) 263 return -ENOMEM; 264 265 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 266 267 pc->mmio = devm_ioremap_resource(dev, res); 268 if (IS_ERR(pc->mmio)) 269 return PTR_ERR(pc->mmio); 270 271 pc->regmap = devm_regmap_init_mmio(dev, pc->mmio, 272 &sti_pwm_regmap_config); 273 if (IS_ERR(pc->regmap)) 274 return PTR_ERR(pc->regmap); 275 276 /* 277 * Setup PWM data with default values: some values could be replaced 278 * with specific ones provided from Device Tree. 279 */ 280 cdata->reg_fields = &sti_pwm_regfields[0]; 281 cdata->max_prescale = 0xff; 282 cdata->max_pwm_cnt = 255; 283 cdata->num_chan = 1; 284 285 pc->cdata = cdata; 286 pc->dev = dev; 287 288 ret = sti_pwm_probe_dt(pc); 289 if (ret) 290 return ret; 291 292 pc->pwm_periods = devm_kzalloc(dev, 293 sizeof(unsigned long) * (pc->cdata->max_prescale + 1), 294 GFP_KERNEL); 295 if (!pc->pwm_periods) 296 return -ENOMEM; 297 298 pc->clk = of_clk_get_by_name(dev->of_node, "pwm"); 299 if (IS_ERR(pc->clk)) { 300 dev_err(dev, "failed to get PWM clock\n"); 301 return PTR_ERR(pc->clk); 302 } 303 304 pc->clk_rate = clk_get_rate(pc->clk); 305 if (!pc->clk_rate) { 306 dev_err(dev, "failed to get clock rate\n"); 307 return -EINVAL; 308 } 309 310 ret = clk_prepare(pc->clk); 311 if (ret) { 312 dev_err(dev, "failed to prepare clock\n"); 313 return ret; 314 } 315 316 sti_pwm_calc_periods(pc); 317 318 pc->chip.dev = dev; 319 pc->chip.ops = &sti_pwm_ops; 320 pc->chip.base = -1; 321 pc->chip.npwm = pc->cdata->num_chan; 322 pc->chip.can_sleep = true; 323 324 ret = pwmchip_add(&pc->chip); 325 if (ret < 0) { 326 clk_unprepare(pc->clk); 327 return ret; 328 } 329 330 platform_set_drvdata(pdev, pc); 331 332 return 0; 333 } 334 335 static int sti_pwm_remove(struct platform_device *pdev) 336 { 337 struct sti_pwm_chip *pc = platform_get_drvdata(pdev); 338 unsigned int i; 339 340 for (i = 0; i < pc->cdata->num_chan; i++) 341 pwm_disable(&pc->chip.pwms[i]); 342 343 clk_unprepare(pc->clk); 344 345 return pwmchip_remove(&pc->chip); 346 } 347 348 static const struct of_device_id sti_pwm_of_match[] = { 349 { .compatible = "st,sti-pwm", }, 350 { /* sentinel */ } 351 }; 352 MODULE_DEVICE_TABLE(of, sti_pwm_of_match); 353 354 static struct platform_driver sti_pwm_driver = { 355 .driver = { 356 .name = "sti-pwm", 357 .of_match_table = sti_pwm_of_match, 358 }, 359 .probe = sti_pwm_probe, 360 .remove = sti_pwm_remove, 361 }; 362 module_platform_driver(sti_pwm_driver); 363 364 MODULE_AUTHOR("Ajit Pal Singh <ajitpal.singh@st.com>"); 365 MODULE_DESCRIPTION("STMicroelectronics ST PWM driver"); 366 MODULE_LICENSE("GPL"); 367