0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/module.h>
0029 #include <linux/of.h>
0030 #include <linux/platform_device.h>
0031 #include <linux/pwm.h>
0032 #include <linux/mfd/twl.h>
0033 #include <linux/slab.h>
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #define TWL4030_LED_MAX 0x7f
0044 #define TWL6030_LED_MAX 0xff
0045
0046
0047 #define TWL4030_LEDEN_REG 0x00
0048 #define TWL4030_PWMA_REG 0x01
0049
0050 #define TWL4030_LEDXON (1 << 0)
0051 #define TWL4030_LEDXPWM (1 << 4)
0052 #define TWL4030_LED_PINS (TWL4030_LEDXON | TWL4030_LEDXPWM)
0053 #define TWL4030_LED_TOGGLE(led, x) ((x) << (led))
0054
0055
0056 #define TWL6030_LED_PWM_CTRL1 0xf4
0057 #define TWL6030_LED_PWM_CTRL2 0xf5
0058
0059 #define TWL6040_LED_MODE_HW 0x00
0060 #define TWL6040_LED_MODE_ON 0x01
0061 #define TWL6040_LED_MODE_OFF 0x02
0062 #define TWL6040_LED_MODE_MASK 0x03
0063
0064 struct twl_pwmled_chip {
0065 struct pwm_chip chip;
0066 struct mutex mutex;
0067 };
0068
0069 static inline struct twl_pwmled_chip *to_twl(struct pwm_chip *chip)
0070 {
0071 return container_of(chip, struct twl_pwmled_chip, chip);
0072 }
0073
0074 static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm,
0075 int duty_ns, int period_ns)
0076 {
0077 int duty_cycle = DIV_ROUND_UP(duty_ns * TWL4030_LED_MAX, period_ns) + 1;
0078 u8 pwm_config[2] = { 1, 0 };
0079 int base, ret;
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 if (duty_cycle == 1)
0093 duty_cycle = 2;
0094 else if (duty_cycle > TWL4030_LED_MAX)
0095 duty_cycle = 1;
0096
0097 base = pwm->hwpwm * 2 + TWL4030_PWMA_REG;
0098
0099 pwm_config[1] = duty_cycle;
0100
0101 ret = twl_i2c_write(TWL4030_MODULE_LED, pwm_config, base, 2);
0102 if (ret < 0)
0103 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
0104
0105 return ret;
0106 }
0107
0108 static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0109 {
0110 struct twl_pwmled_chip *twl = to_twl(chip);
0111 int ret;
0112 u8 val;
0113
0114 mutex_lock(&twl->mutex);
0115 ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG);
0116 if (ret < 0) {
0117 dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label);
0118 goto out;
0119 }
0120
0121 val |= TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS);
0122
0123 ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG);
0124 if (ret < 0)
0125 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
0126
0127 out:
0128 mutex_unlock(&twl->mutex);
0129 return ret;
0130 }
0131
0132 static void twl4030_pwmled_disable(struct pwm_chip *chip,
0133 struct pwm_device *pwm)
0134 {
0135 struct twl_pwmled_chip *twl = to_twl(chip);
0136 int ret;
0137 u8 val;
0138
0139 mutex_lock(&twl->mutex);
0140 ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG);
0141 if (ret < 0) {
0142 dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label);
0143 goto out;
0144 }
0145
0146 val &= ~TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS);
0147
0148 ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG);
0149 if (ret < 0)
0150 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
0151
0152 out:
0153 mutex_unlock(&twl->mutex);
0154 }
0155
0156 static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0157 const struct pwm_state *state)
0158 {
0159 int ret;
0160
0161 if (state->polarity != PWM_POLARITY_NORMAL)
0162 return -EINVAL;
0163
0164 if (!state->enabled) {
0165 if (pwm->state.enabled)
0166 twl4030_pwmled_disable(chip, pwm);
0167
0168 return 0;
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178 ret = twl4030_pwmled_config(pwm->chip, pwm,
0179 state->duty_cycle, state->period);
0180 if (ret)
0181 return ret;
0182
0183 if (!pwm->state.enabled)
0184 ret = twl4030_pwmled_enable(chip, pwm);
0185
0186 return ret;
0187 }
0188
0189
0190 static const struct pwm_ops twl4030_pwmled_ops = {
0191 .apply = twl4030_pwmled_apply,
0192 .owner = THIS_MODULE,
0193 };
0194
0195 static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm,
0196 int duty_ns, int period_ns)
0197 {
0198 int duty_cycle = (duty_ns * TWL6030_LED_MAX) / period_ns;
0199 u8 on_time;
0200 int ret;
0201
0202 on_time = duty_cycle & 0xff;
0203
0204 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, on_time,
0205 TWL6030_LED_PWM_CTRL1);
0206 if (ret < 0)
0207 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label);
0208
0209 return ret;
0210 }
0211
0212 static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0213 {
0214 struct twl_pwmled_chip *twl = to_twl(chip);
0215 int ret;
0216 u8 val;
0217
0218 mutex_lock(&twl->mutex);
0219 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
0220 if (ret < 0) {
0221 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
0222 pwm->label);
0223 goto out;
0224 }
0225
0226 val &= ~TWL6040_LED_MODE_MASK;
0227 val |= TWL6040_LED_MODE_ON;
0228
0229 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
0230 if (ret < 0)
0231 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label);
0232
0233 out:
0234 mutex_unlock(&twl->mutex);
0235 return ret;
0236 }
0237
0238 static void twl6030_pwmled_disable(struct pwm_chip *chip,
0239 struct pwm_device *pwm)
0240 {
0241 struct twl_pwmled_chip *twl = to_twl(chip);
0242 int ret;
0243 u8 val;
0244
0245 mutex_lock(&twl->mutex);
0246 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
0247 if (ret < 0) {
0248 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
0249 pwm->label);
0250 goto out;
0251 }
0252
0253 val &= ~TWL6040_LED_MODE_MASK;
0254 val |= TWL6040_LED_MODE_OFF;
0255
0256 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
0257 if (ret < 0)
0258 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label);
0259
0260 out:
0261 mutex_unlock(&twl->mutex);
0262 }
0263
0264 static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0265 const struct pwm_state *state)
0266 {
0267 int err;
0268
0269 if (state->polarity != pwm->state.polarity)
0270 return -EINVAL;
0271
0272 if (!state->enabled) {
0273 if (pwm->state.enabled)
0274 twl6030_pwmled_disable(chip, pwm);
0275
0276 return 0;
0277 }
0278
0279 err = twl6030_pwmled_config(pwm->chip, pwm,
0280 state->duty_cycle, state->period);
0281 if (err)
0282 return err;
0283
0284 if (!pwm->state.enabled)
0285 err = twl6030_pwmled_enable(chip, pwm);
0286
0287 return err;
0288 }
0289
0290 static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm)
0291 {
0292 struct twl_pwmled_chip *twl = to_twl(chip);
0293 int ret;
0294 u8 val;
0295
0296 mutex_lock(&twl->mutex);
0297 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
0298 if (ret < 0) {
0299 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
0300 pwm->label);
0301 goto out;
0302 }
0303
0304 val &= ~TWL6040_LED_MODE_MASK;
0305 val |= TWL6040_LED_MODE_OFF;
0306
0307 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
0308 if (ret < 0)
0309 dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label);
0310
0311 out:
0312 mutex_unlock(&twl->mutex);
0313 return ret;
0314 }
0315
0316 static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm)
0317 {
0318 struct twl_pwmled_chip *twl = to_twl(chip);
0319 int ret;
0320 u8 val;
0321
0322 mutex_lock(&twl->mutex);
0323 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2);
0324 if (ret < 0) {
0325 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n",
0326 pwm->label);
0327 goto out;
0328 }
0329
0330 val &= ~TWL6040_LED_MODE_MASK;
0331 val |= TWL6040_LED_MODE_HW;
0332
0333 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2);
0334 if (ret < 0)
0335 dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label);
0336
0337 out:
0338 mutex_unlock(&twl->mutex);
0339 }
0340
0341 static const struct pwm_ops twl6030_pwmled_ops = {
0342 .apply = twl6030_pwmled_apply,
0343 .request = twl6030_pwmled_request,
0344 .free = twl6030_pwmled_free,
0345 .owner = THIS_MODULE,
0346 };
0347
0348 static int twl_pwmled_probe(struct platform_device *pdev)
0349 {
0350 struct twl_pwmled_chip *twl;
0351
0352 twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
0353 if (!twl)
0354 return -ENOMEM;
0355
0356 if (twl_class_is_4030()) {
0357 twl->chip.ops = &twl4030_pwmled_ops;
0358 twl->chip.npwm = 2;
0359 } else {
0360 twl->chip.ops = &twl6030_pwmled_ops;
0361 twl->chip.npwm = 1;
0362 }
0363
0364 twl->chip.dev = &pdev->dev;
0365
0366 mutex_init(&twl->mutex);
0367
0368 return devm_pwmchip_add(&pdev->dev, &twl->chip);
0369 }
0370
0371 #ifdef CONFIG_OF
0372 static const struct of_device_id twl_pwmled_of_match[] = {
0373 { .compatible = "ti,twl4030-pwmled" },
0374 { .compatible = "ti,twl6030-pwmled" },
0375 { },
0376 };
0377 MODULE_DEVICE_TABLE(of, twl_pwmled_of_match);
0378 #endif
0379
0380 static struct platform_driver twl_pwmled_driver = {
0381 .driver = {
0382 .name = "twl-pwmled",
0383 .of_match_table = of_match_ptr(twl_pwmled_of_match),
0384 },
0385 .probe = twl_pwmled_probe,
0386 };
0387 module_platform_driver(twl_pwmled_driver);
0388
0389 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
0390 MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030 LED outputs");
0391 MODULE_ALIAS("platform:twl-pwmled");
0392 MODULE_LICENSE("GPL");