1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for TWL4030/6030 Generic Pulse Width Modulator 4 * 5 * Copyright (C) 2012 Texas Instruments 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pwm.h> 13 #include <linux/mfd/twl.h> 14 #include <linux/slab.h> 15 16 /* 17 * This driver handles the PWMs of TWL4030 and TWL6030. 18 * The TRM names for the PWMs on TWL4030 are: PWM0, PWM1 19 * TWL6030 also have two PWMs named in the TRM as PWM1, PWM2 20 */ 21 22 #define TWL_PWM_MAX 0x7f 23 24 /* Registers, bits and macro for TWL4030 */ 25 #define TWL4030_GPBR1_REG 0x0c 26 #define TWL4030_PMBR1_REG 0x0d 27 28 /* GPBR1 register bits */ 29 #define TWL4030_PWMXCLK_ENABLE (1 << 0) 30 #define TWL4030_PWMX_ENABLE (1 << 2) 31 #define TWL4030_PWMX_BITS (TWL4030_PWMX_ENABLE | TWL4030_PWMXCLK_ENABLE) 32 #define TWL4030_PWM_TOGGLE(pwm, x) ((x) << (pwm)) 33 34 /* PMBR1 register bits */ 35 #define TWL4030_GPIO6_PWM0_MUTE_MASK (0x03 << 2) 36 #define TWL4030_GPIO6_PWM0_MUTE_PWM0 (0x01 << 2) 37 #define TWL4030_GPIO7_VIBRASYNC_PWM1_MASK (0x03 << 4) 38 #define TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1 (0x03 << 4) 39 40 /* Register, bits and macro for TWL6030 */ 41 #define TWL6030_TOGGLE3_REG 0x92 42 43 #define TWL6030_PWMXR (1 << 0) 44 #define TWL6030_PWMXS (1 << 1) 45 #define TWL6030_PWMXEN (1 << 2) 46 #define TWL6030_PWM_TOGGLE(pwm, x) ((x) << (pwm * 3)) 47 48 struct twl_pwm_chip { 49 struct pwm_chip chip; 50 struct mutex mutex; 51 u8 twl6030_toggle3; 52 u8 twl4030_pwm_mux; 53 }; 54 55 static inline struct twl_pwm_chip *to_twl(struct pwm_chip *chip) 56 { 57 return container_of(chip, struct twl_pwm_chip, chip); 58 } 59 60 static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 61 int duty_ns, int period_ns) 62 { 63 int duty_cycle = DIV_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1; 64 u8 pwm_config[2] = { 1, 0 }; 65 int base, ret; 66 67 /* 68 * To configure the duty period: 69 * On-cycle is set to 1 (the minimum allowed value) 70 * The off time of 0 is not configurable, so the mapping is: 71 * 0 -> off cycle = 2, 72 * 1 -> off cycle = 2, 73 * 2 -> off cycle = 3, 74 * 126 - > off cycle 127, 75 * 127 - > off cycle 1 76 * When on cycle == off cycle the PWM will be always on 77 */ 78 if (duty_cycle == 1) 79 duty_cycle = 2; 80 else if (duty_cycle > TWL_PWM_MAX) 81 duty_cycle = 1; 82 83 base = pwm->hwpwm * 3; 84 85 pwm_config[1] = duty_cycle; 86 87 ret = twl_i2c_write(TWL_MODULE_PWM, pwm_config, base, 2); 88 if (ret < 0) 89 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); 90 91 return ret; 92 } 93 94 static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 95 { 96 struct twl_pwm_chip *twl = to_twl(chip); 97 int ret; 98 u8 val; 99 100 mutex_lock(&twl->mutex); 101 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); 102 if (ret < 0) { 103 dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); 104 goto out; 105 } 106 107 val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE); 108 109 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); 110 if (ret < 0) 111 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); 112 113 val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE); 114 115 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); 116 if (ret < 0) 117 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); 118 119 out: 120 mutex_unlock(&twl->mutex); 121 return ret; 122 } 123 124 static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 125 { 126 struct twl_pwm_chip *twl = to_twl(chip); 127 int ret; 128 u8 val; 129 130 mutex_lock(&twl->mutex); 131 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); 132 if (ret < 0) { 133 dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); 134 goto out; 135 } 136 137 val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE); 138 139 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); 140 if (ret < 0) 141 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); 142 143 val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE); 144 145 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); 146 if (ret < 0) 147 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); 148 149 out: 150 mutex_unlock(&twl->mutex); 151 } 152 153 static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) 154 { 155 struct twl_pwm_chip *twl = to_twl(chip); 156 int ret; 157 u8 val, mask, bits; 158 159 if (pwm->hwpwm == 1) { 160 mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK; 161 bits = TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1; 162 } else { 163 mask = TWL4030_GPIO6_PWM0_MUTE_MASK; 164 bits = TWL4030_GPIO6_PWM0_MUTE_PWM0; 165 } 166 167 mutex_lock(&twl->mutex); 168 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); 169 if (ret < 0) { 170 dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); 171 goto out; 172 } 173 174 /* Save the current MUX configuration for the PWM */ 175 twl->twl4030_pwm_mux &= ~mask; 176 twl->twl4030_pwm_mux |= (val & mask); 177 178 /* Select PWM functionality */ 179 val &= ~mask; 180 val |= bits; 181 182 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); 183 if (ret < 0) 184 dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); 185 186 out: 187 mutex_unlock(&twl->mutex); 188 return ret; 189 } 190 191 static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 192 { 193 struct twl_pwm_chip *twl = to_twl(chip); 194 int ret; 195 u8 val, mask; 196 197 if (pwm->hwpwm == 1) 198 mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK; 199 else 200 mask = TWL4030_GPIO6_PWM0_MUTE_MASK; 201 202 mutex_lock(&twl->mutex); 203 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); 204 if (ret < 0) { 205 dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); 206 goto out; 207 } 208 209 /* Restore the MUX configuration for the PWM */ 210 val &= ~mask; 211 val |= (twl->twl4030_pwm_mux & mask); 212 213 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); 214 if (ret < 0) 215 dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); 216 217 out: 218 mutex_unlock(&twl->mutex); 219 } 220 221 static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 222 { 223 struct twl_pwm_chip *twl = to_twl(chip); 224 int ret; 225 u8 val; 226 227 mutex_lock(&twl->mutex); 228 val = twl->twl6030_toggle3; 229 val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); 230 val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR); 231 232 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); 233 if (ret < 0) { 234 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); 235 goto out; 236 } 237 238 twl->twl6030_toggle3 = val; 239 out: 240 mutex_unlock(&twl->mutex); 241 return ret; 242 } 243 244 static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 245 { 246 struct twl_pwm_chip *twl = to_twl(chip); 247 int ret; 248 u8 val; 249 250 mutex_lock(&twl->mutex); 251 val = twl->twl6030_toggle3; 252 val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR); 253 val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); 254 255 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); 256 if (ret < 0) { 257 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); 258 goto out; 259 } 260 261 val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN); 262 263 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); 264 if (ret < 0) { 265 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); 266 goto out; 267 } 268 269 val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXEN); 270 271 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); 272 if (ret < 0) { 273 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); 274 goto out; 275 } 276 277 twl->twl6030_toggle3 = val; 278 out: 279 mutex_unlock(&twl->mutex); 280 } 281 282 static const struct pwm_ops twl4030_pwm_ops = { 283 .config = twl_pwm_config, 284 .enable = twl4030_pwm_enable, 285 .disable = twl4030_pwm_disable, 286 .request = twl4030_pwm_request, 287 .free = twl4030_pwm_free, 288 .owner = THIS_MODULE, 289 }; 290 291 static const struct pwm_ops twl6030_pwm_ops = { 292 .config = twl_pwm_config, 293 .enable = twl6030_pwm_enable, 294 .disable = twl6030_pwm_disable, 295 .owner = THIS_MODULE, 296 }; 297 298 static int twl_pwm_probe(struct platform_device *pdev) 299 { 300 struct twl_pwm_chip *twl; 301 int ret; 302 303 twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); 304 if (!twl) 305 return -ENOMEM; 306 307 if (twl_class_is_4030()) 308 twl->chip.ops = &twl4030_pwm_ops; 309 else 310 twl->chip.ops = &twl6030_pwm_ops; 311 312 twl->chip.dev = &pdev->dev; 313 twl->chip.npwm = 2; 314 315 mutex_init(&twl->mutex); 316 317 ret = pwmchip_add(&twl->chip); 318 if (ret < 0) 319 return ret; 320 321 platform_set_drvdata(pdev, twl); 322 323 return 0; 324 } 325 326 static int twl_pwm_remove(struct platform_device *pdev) 327 { 328 struct twl_pwm_chip *twl = platform_get_drvdata(pdev); 329 330 return pwmchip_remove(&twl->chip); 331 } 332 333 #ifdef CONFIG_OF 334 static const struct of_device_id twl_pwm_of_match[] = { 335 { .compatible = "ti,twl4030-pwm" }, 336 { .compatible = "ti,twl6030-pwm" }, 337 { }, 338 }; 339 MODULE_DEVICE_TABLE(of, twl_pwm_of_match); 340 #endif 341 342 static struct platform_driver twl_pwm_driver = { 343 .driver = { 344 .name = "twl-pwm", 345 .of_match_table = of_match_ptr(twl_pwm_of_match), 346 }, 347 .probe = twl_pwm_probe, 348 .remove = twl_pwm_remove, 349 }; 350 module_platform_driver(twl_pwm_driver); 351 352 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 353 MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030"); 354 MODULE_ALIAS("platform:twl-pwm"); 355 MODULE_LICENSE("GPL"); 356