123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- * arch/arm/plat-orion/gpio.c
- *
- * Marvell Orion SoC GPIO handling.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- /*
- * Based on (mostly copied from) plat-orion based Linux 2.6 kernel driver.
- * Removed orion_gpiochip struct and kernel level irq handling.
- *
- * Dieter Kiermaier dk-arm-linux@gmx.de
- */
- #include <common.h>
- #include <asm/bitops.h>
- #include <asm/io.h>
- #include <asm/arch/soc.h>
- #include <asm/arch/gpio.h>
- static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
- static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
- void __set_direction(unsigned pin, int input)
- {
- u32 u;
- u = readl(GPIO_IO_CONF(pin));
- if (input)
- u |= 1 << (pin & 31);
- else
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_IO_CONF(pin));
- u = readl(GPIO_IO_CONF(pin));
- }
- static void __set_level(unsigned pin, int high)
- {
- u32 u;
- u = readl(GPIO_OUT(pin));
- if (high)
- u |= 1 << (pin & 31);
- else
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_OUT(pin));
- }
- static void __set_blinking(unsigned pin, int blink)
- {
- u32 u;
- u = readl(GPIO_BLINK_EN(pin));
- if (blink)
- u |= 1 << (pin & 31);
- else
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_BLINK_EN(pin));
- }
- int kw_gpio_is_valid(unsigned pin, int mode)
- {
- if (pin < GPIO_MAX) {
- if ((mode & GPIO_INPUT_OK) && !test_bit(pin, gpio_valid_input))
- goto err_out;
- if ((mode & GPIO_OUTPUT_OK) && !test_bit(pin, gpio_valid_output))
- goto err_out;
- return 0;
- }
- err_out:
- printf("%s: invalid GPIO %d\n", __func__, pin);
- return 1;
- }
- void kw_gpio_set_valid(unsigned pin, int mode)
- {
- if (mode == 1)
- mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
- if (mode & GPIO_INPUT_OK)
- __set_bit(pin, gpio_valid_input);
- else
- __clear_bit(pin, gpio_valid_input);
- if (mode & GPIO_OUTPUT_OK)
- __set_bit(pin, gpio_valid_output);
- else
- __clear_bit(pin, gpio_valid_output);
- }
- /*
- * GENERIC_GPIO primitives.
- */
- int kw_gpio_direction_input(unsigned pin)
- {
- if (kw_gpio_is_valid(pin, GPIO_INPUT_OK) != 0)
- return 1;
- /* Configure GPIO direction. */
- __set_direction(pin, 1);
- return 0;
- }
- int kw_gpio_direction_output(unsigned pin, int value)
- {
- if (kw_gpio_is_valid(pin, GPIO_OUTPUT_OK) != 0)
- {
- printf("%s: invalid GPIO %d\n", __func__, pin);
- return 1;
- }
- __set_blinking(pin, 0);
- /* Configure GPIO output value. */
- __set_level(pin, value);
- /* Configure GPIO direction. */
- __set_direction(pin, 0);
- return 0;
- }
- int kw_gpio_get_value(unsigned pin)
- {
- int val;
- if (readl(GPIO_IO_CONF(pin)) & (1 << (pin & 31)))
- val = readl(GPIO_DATA_IN(pin)) ^ readl(GPIO_IN_POL(pin));
- else
- val = readl(GPIO_OUT(pin));
- return (val >> (pin & 31)) & 1;
- }
- void kw_gpio_set_value(unsigned pin, int value)
- {
- /* Configure GPIO output value. */
- __set_level(pin, value);
- }
- void kw_gpio_set_blink(unsigned pin, int blink)
- {
- /* Set output value to zero. */
- __set_level(pin, 0);
- /* Set blinking. */
- __set_blinking(pin, blink);
- }
|