Lines Matching +full:init +full:- +full:b +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0+
3 * Access to GPIOs on TWL4030/TPS659x0 chips
5 * Copyright (C) 2006-2007 Texas Instruments, Inc.
8 * Code re-arranged and cleaned up by:
16 #include <linux/init.h>
30 * The GPIO "subchip" supports 18 GPIOs which can be configured as
37 * There are also two LED pins used sometimes as output-only GPIOs.
52 /* Mask for GPIO registers when aggregated into a 32-bit integer */
66 /*----------------------------------------------------------------------*/
76 /*----------------------------------------------------------------------*/
80 * PWMs A and B are dedicated to LEDs A and B, respectively.
101 /*----------------------------------------------------------------------*/
115 /*----------------------------------------------------------------------*/
205 /*----------------------------------------------------------------------*/
212 mutex_lock(&priv->mutex); in twl_request()
214 /* Support the two LED outputs as output-only GPIOs. */ in twl_request()
220 offset -= TWL4030_GPIO_MAX; in twl_request()
226 /* initialize PWM to always-drive */ in twl_request()
237 /* init LED to not-driven (high) */ in twl_request()
253 if (!priv->usage_count) { in twl_request()
257 /* optionally have the first two GPIOs switch vMMC1 in twl_request()
260 pdata = dev_get_platdata(chip->parent); in twl_request()
262 value |= pdata->mmc_cd & 0x03; in twl_request()
269 priv->usage_count |= BIT(offset); in twl_request()
271 mutex_unlock(&priv->mutex); in twl_request()
279 mutex_lock(&priv->mutex); in twl_free()
281 twl4030_led_set_value(offset - TWL4030_GPIO_MAX, 1); in twl_free()
285 priv->usage_count &= ~BIT(offset); in twl_free()
288 if (!priv->usage_count) in twl_free()
292 mutex_unlock(&priv->mutex); in twl_free()
300 mutex_lock(&priv->mutex); in twl_direction_in()
304 ret = -EINVAL; /* LED outputs can't be set as input */ in twl_direction_in()
307 priv->direction &= ~BIT(offset); in twl_direction_in()
309 mutex_unlock(&priv->mutex); in twl_direction_in()
320 mutex_lock(&priv->mutex); in twl_get()
321 if (!(priv->usage_count & BIT(offset))) { in twl_get()
322 ret = -EPERM; in twl_get()
326 if (priv->direction & BIT(offset)) in twl_get()
327 status = priv->out_state & BIT(offset); in twl_get()
333 mutex_unlock(&priv->mutex); in twl_get()
341 mutex_lock(&priv->mutex); in twl_set()
345 twl4030_led_set_value(offset - TWL4030_GPIO_MAX, value); in twl_set()
348 priv->out_state |= BIT(offset); in twl_set()
350 priv->out_state &= ~BIT(offset); in twl_set()
352 mutex_unlock(&priv->mutex); in twl_set()
360 mutex_lock(&priv->mutex); in twl_direction_out()
364 mutex_unlock(&priv->mutex); in twl_direction_out()
370 * LED gpios i.e. offset >= TWL4030_GPIO_MAX are always output in twl_direction_out()
373 priv->direction |= BIT(offset); in twl_direction_out()
374 mutex_unlock(&priv->mutex); in twl_direction_out()
386 * LED GPIOs >= TWL4030_GPIO_MAX are always output in twl_get_direction()
390 mutex_lock(&priv->mutex); in twl_get_direction()
394 mutex_unlock(&priv->mutex); in twl_get_direction()
398 mutex_unlock(&priv->mutex); in twl_get_direction()
407 return (priv->irq_base && (offset < TWL4030_GPIO_MAX)) in twl_to_irq()
408 ? (priv->irq_base + offset) in twl_to_irq()
409 : -EINVAL; in twl_to_irq()
426 /*----------------------------------------------------------------------*/
478 omap_twl_info->use_leds = of_property_read_bool(dev->of_node, in of_gpio_twl4030()
479 "ti,use-leds"); in of_gpio_twl4030()
481 of_property_read_u32(dev->of_node, "ti,debounce", in of_gpio_twl4030()
482 &omap_twl_info->debounce); in of_gpio_twl4030()
483 of_property_read_u32(dev->of_node, "ti,mmc-cd", in of_gpio_twl4030()
484 (u32 *)&omap_twl_info->mmc_cd); in of_gpio_twl4030()
485 of_property_read_u32(dev->of_node, "ti,pullups", in of_gpio_twl4030()
486 &omap_twl_info->pullups); in of_gpio_twl4030()
487 of_property_read_u32(dev->of_node, "ti,pulldowns", in of_gpio_twl4030()
488 &omap_twl_info->pulldowns); in of_gpio_twl4030()
505 struct device_node *node = pdev->dev.of_node; in gpio_twl4030_probe()
509 priv = devm_kzalloc(&pdev->dev, sizeof(struct gpio_twl4030_priv), in gpio_twl4030_probe()
512 return -ENOMEM; in gpio_twl4030_probe()
516 dev_err(&pdev->dev, "can't dispatch IRQs from modules\n"); in gpio_twl4030_probe()
520 irq_base = devm_irq_alloc_descs(&pdev->dev, -1, in gpio_twl4030_probe()
523 dev_err(&pdev->dev, "Failed to alloc irq_descs\n"); in gpio_twl4030_probe()
530 ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base); in gpio_twl4030_probe()
534 priv->irq_base = irq_base; in gpio_twl4030_probe()
537 priv->gpio_chip = template_chip; in gpio_twl4030_probe()
538 priv->gpio_chip.base = -1; in gpio_twl4030_probe()
539 priv->gpio_chip.ngpio = TWL4030_GPIO_MAX; in gpio_twl4030_probe()
540 priv->gpio_chip.parent = &pdev->dev; in gpio_twl4030_probe()
542 mutex_init(&priv->mutex); in gpio_twl4030_probe()
544 pdata = of_gpio_twl4030(&pdev->dev); in gpio_twl4030_probe()
546 dev_err(&pdev->dev, "Platform data is missing\n"); in gpio_twl4030_probe()
547 return -ENXIO; in gpio_twl4030_probe()
552 * and pulldowns correctly ... default for non-ULPI pins is in gpio_twl4030_probe()
556 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns); in gpio_twl4030_probe()
558 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n", in gpio_twl4030_probe()
559 pdata->pullups, pdata->pulldowns, ret); in gpio_twl4030_probe()
561 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); in gpio_twl4030_probe()
563 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", in gpio_twl4030_probe()
564 pdata->debounce, pdata->mmc_cd, ret); in gpio_twl4030_probe()
570 if (pdata->use_leds) in gpio_twl4030_probe()
571 priv->gpio_chip.ngpio += 2; in gpio_twl4030_probe()
573 ret = devm_gpiochip_add_data(&pdev->dev, &priv->gpio_chip, priv); in gpio_twl4030_probe()
575 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); in gpio_twl4030_probe()
576 priv->gpio_chip.ngpio = 0; in gpio_twl4030_probe()
585 of_machine_is_compatible("compulab,omap3-sbc-t3730")) { in gpio_twl4030_probe()
588 d = gpiochip_request_own_desc(&priv->gpio_chip, in gpio_twl4030_probe()
593 return dev_err_probe(&pdev->dev, PTR_ERR(d), in gpio_twl4030_probe()
598 ret = devm_add_action_or_reset(&pdev->dev, gpio_twl4030_power_off_action, d); in gpio_twl4030_probe()
600 return dev_err_probe(&pdev->dev, ret, in gpio_twl4030_probe()
609 { .compatible = "ti,twl4030-gpio", },
614 /* Note: this hardware lives inside an I2C-based multi-function device. */