0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/kthread.h>
0019 #include <linux/irq.h>
0020 #include <linux/gpio/driver.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/of.h>
0023 #include <linux/irqdomain.h>
0024
0025 #include <linux/mfd/twl.h>
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifdef MODULE
0040 #define is_module() true
0041 #else
0042 #define is_module() false
0043 #endif
0044
0045
0046 #define MASK_GPIO_CTRL_GPIO0CD1 BIT(0)
0047 #define MASK_GPIO_CTRL_GPIO1CD2 BIT(1)
0048 #define MASK_GPIO_CTRL_GPIO_ON BIT(2)
0049
0050
0051 #define GPIO_32_MASK 0x0003ffff
0052
0053 struct gpio_twl4030_priv {
0054 struct gpio_chip gpio_chip;
0055 struct mutex mutex;
0056 int irq_base;
0057
0058
0059 unsigned int usage_count;
0060 unsigned int direction;
0061 unsigned int out_state;
0062 };
0063
0064
0065
0066
0067
0068
0069 static inline int gpio_twl4030_write(u8 address, u8 data)
0070 {
0071 return twl_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081 #define TWL4030_LED_LEDEN_REG 0x00
0082 #define TWL4030_PWMAON_REG 0x01
0083 #define TWL4030_PWMAOFF_REG 0x02
0084 #define TWL4030_PWMBON_REG 0x03
0085 #define TWL4030_PWMBOFF_REG 0x04
0086
0087
0088 #define LEDEN_LEDAON BIT(0)
0089 #define LEDEN_LEDBON BIT(1)
0090 #define LEDEN_LEDAEXT BIT(2)
0091 #define LEDEN_LEDBEXT BIT(3)
0092 #define LEDEN_LEDAPWM BIT(4)
0093 #define LEDEN_LEDBPWM BIT(5)
0094 #define LEDEN_PWM_LENGTHA BIT(6)
0095 #define LEDEN_PWM_LENGTHB BIT(7)
0096
0097 #define PWMxON_LENGTH BIT(7)
0098
0099
0100
0101
0102
0103
0104 static inline int gpio_twl4030_read(u8 address)
0105 {
0106 u8 data;
0107 int ret = 0;
0108
0109 ret = twl_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
0110 return (ret < 0) ? ret : data;
0111 }
0112
0113
0114
0115 static u8 cached_leden;
0116
0117
0118
0119
0120
0121 static void twl4030_led_set_value(int led, int value)
0122 {
0123 u8 mask = LEDEN_LEDAON | LEDEN_LEDAPWM;
0124
0125 if (led)
0126 mask <<= 1;
0127
0128 if (value)
0129 cached_leden &= ~mask;
0130 else
0131 cached_leden |= mask;
0132
0133 WARN_ON_ONCE(twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
0134 TWL4030_LED_LEDEN_REG));
0135 }
0136
0137 static int twl4030_set_gpio_direction(int gpio, int is_input)
0138 {
0139 u8 d_bnk = gpio >> 3;
0140 u8 d_msk = BIT(gpio & 0x7);
0141 u8 reg = 0;
0142 u8 base = REG_GPIODATADIR1 + d_bnk;
0143 int ret = 0;
0144
0145 ret = gpio_twl4030_read(base);
0146 if (ret >= 0) {
0147 if (is_input)
0148 reg = ret & ~d_msk;
0149 else
0150 reg = ret | d_msk;
0151
0152 ret = gpio_twl4030_write(base, reg);
0153 }
0154 return ret;
0155 }
0156
0157 static int twl4030_get_gpio_direction(int gpio)
0158 {
0159 u8 d_bnk = gpio >> 3;
0160 u8 d_msk = BIT(gpio & 0x7);
0161 u8 base = REG_GPIODATADIR1 + d_bnk;
0162 int ret = 0;
0163
0164 ret = gpio_twl4030_read(base);
0165 if (ret < 0)
0166 return ret;
0167
0168 if (ret & d_msk)
0169 return GPIO_LINE_DIRECTION_OUT;
0170
0171 return GPIO_LINE_DIRECTION_IN;
0172 }
0173
0174 static int twl4030_set_gpio_dataout(int gpio, int enable)
0175 {
0176 u8 d_bnk = gpio >> 3;
0177 u8 d_msk = BIT(gpio & 0x7);
0178 u8 base = 0;
0179
0180 if (enable)
0181 base = REG_SETGPIODATAOUT1 + d_bnk;
0182 else
0183 base = REG_CLEARGPIODATAOUT1 + d_bnk;
0184
0185 return gpio_twl4030_write(base, d_msk);
0186 }
0187
0188 static int twl4030_get_gpio_datain(int gpio)
0189 {
0190 u8 d_bnk = gpio >> 3;
0191 u8 d_off = gpio & 0x7;
0192 u8 base = 0;
0193 int ret = 0;
0194
0195 base = REG_GPIODATAIN1 + d_bnk;
0196 ret = gpio_twl4030_read(base);
0197 if (ret > 0)
0198 ret = (ret >> d_off) & 0x1;
0199
0200 return ret;
0201 }
0202
0203
0204
0205 static int twl_request(struct gpio_chip *chip, unsigned offset)
0206 {
0207 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0208 int status = 0;
0209
0210 mutex_lock(&priv->mutex);
0211
0212
0213 if (offset >= TWL4030_GPIO_MAX) {
0214 u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT
0215 | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA;
0216 u8 reg = TWL4030_PWMAON_REG;
0217
0218 offset -= TWL4030_GPIO_MAX;
0219 if (offset) {
0220 ledclr_mask <<= 1;
0221 reg = TWL4030_PWMBON_REG;
0222 }
0223
0224
0225
0226 status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1);
0227 if (status < 0)
0228 goto done;
0229
0230
0231 status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg);
0232 if (status < 0)
0233 goto done;
0234
0235
0236 status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden,
0237 TWL4030_LED_LEDEN_REG);
0238 if (status < 0)
0239 goto done;
0240 cached_leden &= ~ledclr_mask;
0241 status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
0242 TWL4030_LED_LEDEN_REG);
0243 if (status < 0)
0244 goto done;
0245
0246 status = 0;
0247 goto done;
0248 }
0249
0250
0251 if (!priv->usage_count) {
0252 struct twl4030_gpio_platform_data *pdata;
0253 u8 value = MASK_GPIO_CTRL_GPIO_ON;
0254
0255
0256
0257
0258 pdata = dev_get_platdata(chip->parent);
0259 if (pdata)
0260 value |= pdata->mmc_cd & 0x03;
0261
0262 status = gpio_twl4030_write(REG_GPIO_CTRL, value);
0263 }
0264
0265 done:
0266 if (!status)
0267 priv->usage_count |= BIT(offset);
0268
0269 mutex_unlock(&priv->mutex);
0270 return status;
0271 }
0272
0273 static void twl_free(struct gpio_chip *chip, unsigned offset)
0274 {
0275 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0276
0277 mutex_lock(&priv->mutex);
0278 if (offset >= TWL4030_GPIO_MAX) {
0279 twl4030_led_set_value(offset - TWL4030_GPIO_MAX, 1);
0280 goto out;
0281 }
0282
0283 priv->usage_count &= ~BIT(offset);
0284
0285
0286 if (!priv->usage_count)
0287 gpio_twl4030_write(REG_GPIO_CTRL, 0x0);
0288
0289 out:
0290 mutex_unlock(&priv->mutex);
0291 }
0292
0293 static int twl_direction_in(struct gpio_chip *chip, unsigned offset)
0294 {
0295 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0296 int ret;
0297
0298 mutex_lock(&priv->mutex);
0299 if (offset < TWL4030_GPIO_MAX)
0300 ret = twl4030_set_gpio_direction(offset, 1);
0301 else
0302 ret = -EINVAL;
0303
0304 if (!ret)
0305 priv->direction &= ~BIT(offset);
0306
0307 mutex_unlock(&priv->mutex);
0308
0309 return ret;
0310 }
0311
0312 static int twl_get(struct gpio_chip *chip, unsigned offset)
0313 {
0314 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0315 int ret;
0316 int status = 0;
0317
0318 mutex_lock(&priv->mutex);
0319 if (!(priv->usage_count & BIT(offset))) {
0320 ret = -EPERM;
0321 goto out;
0322 }
0323
0324 if (priv->direction & BIT(offset))
0325 status = priv->out_state & BIT(offset);
0326 else
0327 status = twl4030_get_gpio_datain(offset);
0328
0329 ret = (status < 0) ? status : !!status;
0330 out:
0331 mutex_unlock(&priv->mutex);
0332 return ret;
0333 }
0334
0335 static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
0336 {
0337 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0338
0339 mutex_lock(&priv->mutex);
0340 if (offset < TWL4030_GPIO_MAX)
0341 twl4030_set_gpio_dataout(offset, value);
0342 else
0343 twl4030_led_set_value(offset - TWL4030_GPIO_MAX, value);
0344
0345 if (value)
0346 priv->out_state |= BIT(offset);
0347 else
0348 priv->out_state &= ~BIT(offset);
0349
0350 mutex_unlock(&priv->mutex);
0351 }
0352
0353 static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
0354 {
0355 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0356 int ret = 0;
0357
0358 mutex_lock(&priv->mutex);
0359 if (offset < TWL4030_GPIO_MAX) {
0360 ret = twl4030_set_gpio_direction(offset, 0);
0361 if (ret) {
0362 mutex_unlock(&priv->mutex);
0363 return ret;
0364 }
0365 }
0366
0367
0368
0369
0370
0371 priv->direction |= BIT(offset);
0372 mutex_unlock(&priv->mutex);
0373
0374 twl_set(chip, offset, value);
0375
0376 return ret;
0377 }
0378
0379 static int twl_get_direction(struct gpio_chip *chip, unsigned offset)
0380 {
0381 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0382
0383
0384
0385
0386 int ret = GPIO_LINE_DIRECTION_OUT;
0387
0388 mutex_lock(&priv->mutex);
0389 if (offset < TWL4030_GPIO_MAX) {
0390 ret = twl4030_get_gpio_direction(offset);
0391 if (ret) {
0392 mutex_unlock(&priv->mutex);
0393 return ret;
0394 }
0395 }
0396 mutex_unlock(&priv->mutex);
0397
0398 return ret;
0399 }
0400
0401 static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
0402 {
0403 struct gpio_twl4030_priv *priv = gpiochip_get_data(chip);
0404
0405 return (priv->irq_base && (offset < TWL4030_GPIO_MAX))
0406 ? (priv->irq_base + offset)
0407 : -EINVAL;
0408 }
0409
0410 static const struct gpio_chip template_chip = {
0411 .label = "twl4030",
0412 .owner = THIS_MODULE,
0413 .request = twl_request,
0414 .free = twl_free,
0415 .direction_input = twl_direction_in,
0416 .direction_output = twl_direction_out,
0417 .get_direction = twl_get_direction,
0418 .get = twl_get,
0419 .set = twl_set,
0420 .to_irq = twl_to_irq,
0421 .can_sleep = true,
0422 };
0423
0424
0425
0426 static int gpio_twl4030_pulls(u32 ups, u32 downs)
0427 {
0428 u8 message[5];
0429 unsigned i, gpio_bit;
0430
0431
0432
0433
0434 for (gpio_bit = 1, i = 0; i < 5; i++) {
0435 u8 bit_mask;
0436 unsigned j;
0437
0438 for (bit_mask = 0, j = 0; j < 8; j += 2, gpio_bit <<= 1) {
0439 if (ups & gpio_bit)
0440 bit_mask |= 1 << (j + 1);
0441 else if (downs & gpio_bit)
0442 bit_mask |= 1 << (j + 0);
0443 }
0444 message[i] = bit_mask;
0445 }
0446
0447 return twl_i2c_write(TWL4030_MODULE_GPIO, message,
0448 REG_GPIOPUPDCTR1, 5);
0449 }
0450
0451 static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
0452 {
0453 u8 message[3];
0454
0455
0456
0457
0458 message[0] = (debounce & 0xff) | (mmc_cd & 0x03);
0459 debounce >>= 8;
0460 message[1] = (debounce & 0xff);
0461 debounce >>= 8;
0462 message[2] = (debounce & 0x03);
0463
0464 return twl_i2c_write(TWL4030_MODULE_GPIO, message,
0465 REG_GPIO_DEBEN1, 3);
0466 }
0467
0468 static int gpio_twl4030_remove(struct platform_device *pdev);
0469
0470 static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
0471 struct twl4030_gpio_platform_data *pdata)
0472 {
0473 struct twl4030_gpio_platform_data *omap_twl_info;
0474
0475 omap_twl_info = devm_kzalloc(dev, sizeof(*omap_twl_info), GFP_KERNEL);
0476 if (!omap_twl_info)
0477 return NULL;
0478
0479 if (pdata)
0480 *omap_twl_info = *pdata;
0481
0482 omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
0483 "ti,use-leds");
0484
0485 of_property_read_u32(dev->of_node, "ti,debounce",
0486 &omap_twl_info->debounce);
0487 of_property_read_u32(dev->of_node, "ti,mmc-cd",
0488 (u32 *)&omap_twl_info->mmc_cd);
0489 of_property_read_u32(dev->of_node, "ti,pullups",
0490 &omap_twl_info->pullups);
0491 of_property_read_u32(dev->of_node, "ti,pulldowns",
0492 &omap_twl_info->pulldowns);
0493
0494 return omap_twl_info;
0495 }
0496
0497 static int gpio_twl4030_probe(struct platform_device *pdev)
0498 {
0499 struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
0500 struct device_node *node = pdev->dev.of_node;
0501 struct gpio_twl4030_priv *priv;
0502 int ret, irq_base;
0503
0504 priv = devm_kzalloc(&pdev->dev, sizeof(struct gpio_twl4030_priv),
0505 GFP_KERNEL);
0506 if (!priv)
0507 return -ENOMEM;
0508
0509
0510 if (is_module()) {
0511 dev_err(&pdev->dev, "can't dispatch IRQs from modules\n");
0512 goto no_irqs;
0513 }
0514
0515 irq_base = devm_irq_alloc_descs(&pdev->dev, -1,
0516 0, TWL4030_GPIO_MAX, 0);
0517 if (irq_base < 0) {
0518 dev_err(&pdev->dev, "Failed to alloc irq_descs\n");
0519 return irq_base;
0520 }
0521
0522 irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
0523 &irq_domain_simple_ops, NULL);
0524
0525 ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
0526 if (ret < 0)
0527 return ret;
0528
0529 priv->irq_base = irq_base;
0530
0531 no_irqs:
0532 priv->gpio_chip = template_chip;
0533 priv->gpio_chip.base = -1;
0534 priv->gpio_chip.ngpio = TWL4030_GPIO_MAX;
0535 priv->gpio_chip.parent = &pdev->dev;
0536
0537 mutex_init(&priv->mutex);
0538
0539 if (node)
0540 pdata = of_gpio_twl4030(&pdev->dev, pdata);
0541
0542 if (pdata == NULL) {
0543 dev_err(&pdev->dev, "Platform data is missing\n");
0544 return -ENXIO;
0545 }
0546
0547
0548
0549
0550
0551
0552
0553 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
0554 if (ret)
0555 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
0556 pdata->pullups, pdata->pulldowns, ret);
0557
0558 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
0559 if (ret)
0560 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
0561 pdata->debounce, pdata->mmc_cd, ret);
0562
0563
0564
0565
0566
0567 if (pdata->use_leds)
0568 priv->gpio_chip.ngpio += 2;
0569
0570 ret = gpiochip_add_data(&priv->gpio_chip, priv);
0571 if (ret < 0) {
0572 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
0573 priv->gpio_chip.ngpio = 0;
0574 gpio_twl4030_remove(pdev);
0575 goto out;
0576 }
0577
0578 platform_set_drvdata(pdev, priv);
0579
0580 if (pdata->setup) {
0581 int status;
0582
0583 status = pdata->setup(&pdev->dev, priv->gpio_chip.base,
0584 TWL4030_GPIO_MAX);
0585 if (status)
0586 dev_dbg(&pdev->dev, "setup --> %d\n", status);
0587 }
0588
0589 out:
0590 return ret;
0591 }
0592
0593
0594 static int gpio_twl4030_remove(struct platform_device *pdev)
0595 {
0596 struct gpio_twl4030_priv *priv = platform_get_drvdata(pdev);
0597
0598 gpiochip_remove(&priv->gpio_chip);
0599
0600
0601 WARN_ON(!is_module());
0602 return 0;
0603 }
0604
0605 static const struct of_device_id twl_gpio_match[] = {
0606 { .compatible = "ti,twl4030-gpio", },
0607 { },
0608 };
0609 MODULE_DEVICE_TABLE(of, twl_gpio_match);
0610
0611
0612 MODULE_ALIAS("platform:twl4030_gpio");
0613
0614 static struct platform_driver gpio_twl4030_driver = {
0615 .driver = {
0616 .name = "twl4030_gpio",
0617 .of_match_table = twl_gpio_match,
0618 },
0619 .probe = gpio_twl4030_probe,
0620 .remove = gpio_twl4030_remove,
0621 };
0622
0623 static int __init gpio_twl4030_init(void)
0624 {
0625 return platform_driver_register(&gpio_twl4030_driver);
0626 }
0627 subsys_initcall(gpio_twl4030_init);
0628
0629 static void __exit gpio_twl4030_exit(void)
0630 {
0631 platform_driver_unregister(&gpio_twl4030_driver);
0632 }
0633 module_exit(gpio_twl4030_exit);
0634
0635 MODULE_AUTHOR("Texas Instruments, Inc.");
0636 MODULE_DESCRIPTION("GPIO interface for TWL4030");
0637 MODULE_LICENSE("GPL");