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 302 twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); 303 if (!twl) 304 return -ENOMEM; 305 306 if (twl_class_is_4030()) 307 twl->chip.ops = &twl4030_pwm_ops; 308 else 309 twl->chip.ops = &twl6030_pwm_ops; 310 311 twl->chip.dev = &pdev->dev; 312 twl->chip.npwm = 2; 313 314 mutex_init(&twl->mutex); 315 316 return devm_pwmchip_add(&pdev->dev, &twl->chip); 317 } 318 319 #ifdef CONFIG_OF 320 static const struct of_device_id twl_pwm_of_match[] = { 321 { .compatible = "ti,twl4030-pwm" }, 322 { .compatible = "ti,twl6030-pwm" }, 323 { }, 324 }; 325 MODULE_DEVICE_TABLE(of, twl_pwm_of_match); 326 #endif 327 328 static struct platform_driver twl_pwm_driver = { 329 .driver = { 330 .name = "twl-pwm", 331 .of_match_table = of_match_ptr(twl_pwm_of_match), 332 }, 333 .probe = twl_pwm_probe, 334 }; 335 module_platform_driver(twl_pwm_driver); 336 337 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 338 MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030"); 339 MODULE_ALIAS("platform:twl-pwm"); 340 MODULE_LICENSE("GPL"); 341