1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22cb06a4fSStefan Roese /*
32cb06a4fSStefan Roese * Copyright (C) 2012 Stefan Roese <sr@denx.de>
42cb06a4fSStefan Roese */
52cb06a4fSStefan Roese
62cb06a4fSStefan Roese /*
72cb06a4fSStefan Roese * Driver for SPEAr600 GPIO controller
82cb06a4fSStefan Roese */
92cb06a4fSStefan Roese
102cb06a4fSStefan Roese #include <common.h>
112cb06a4fSStefan Roese #include <asm/arch/hardware.h>
122cb06a4fSStefan Roese #include <asm/gpio.h>
132cb06a4fSStefan Roese #include <asm/io.h>
142cb06a4fSStefan Roese #include <errno.h>
152cb06a4fSStefan Roese
gpio_direction(unsigned gpio,enum gpio_direction direction)162cb06a4fSStefan Roese static int gpio_direction(unsigned gpio,
172cb06a4fSStefan Roese enum gpio_direction direction)
182cb06a4fSStefan Roese {
192cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE;
202cb06a4fSStefan Roese u32 val;
212cb06a4fSStefan Roese
222cb06a4fSStefan Roese val = readl(®s->gpiodir);
232cb06a4fSStefan Roese
242cb06a4fSStefan Roese if (direction == GPIO_DIRECTION_OUT)
252cb06a4fSStefan Roese val |= 1 << gpio;
262cb06a4fSStefan Roese else
272cb06a4fSStefan Roese val &= ~(1 << gpio);
282cb06a4fSStefan Roese
292cb06a4fSStefan Roese writel(val, ®s->gpiodir);
302cb06a4fSStefan Roese
312cb06a4fSStefan Roese return 0;
322cb06a4fSStefan Roese }
332cb06a4fSStefan Roese
gpio_set_value(unsigned gpio,int value)342cb06a4fSStefan Roese int gpio_set_value(unsigned gpio, int value)
352cb06a4fSStefan Roese {
362cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE;
372cb06a4fSStefan Roese
38c0c37402SAxel Lin if (value)
392cb06a4fSStefan Roese writel(1 << gpio, ®s->gpiodata[DATA_REG_ADDR(gpio)]);
40c0c37402SAxel Lin else
41c0c37402SAxel Lin writel(0, ®s->gpiodata[DATA_REG_ADDR(gpio)]);
422cb06a4fSStefan Roese
432cb06a4fSStefan Roese return 0;
442cb06a4fSStefan Roese }
452cb06a4fSStefan Roese
gpio_get_value(unsigned gpio)462cb06a4fSStefan Roese int gpio_get_value(unsigned gpio)
472cb06a4fSStefan Roese {
482cb06a4fSStefan Roese struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE;
492cb06a4fSStefan Roese u32 val;
502cb06a4fSStefan Roese
512cb06a4fSStefan Roese val = readl(®s->gpiodata[DATA_REG_ADDR(gpio)]);
522cb06a4fSStefan Roese
532cb06a4fSStefan Roese return !!val;
542cb06a4fSStefan Roese }
552cb06a4fSStefan Roese
gpio_request(unsigned gpio,const char * label)562cb06a4fSStefan Roese int gpio_request(unsigned gpio, const char *label)
572cb06a4fSStefan Roese {
582cb06a4fSStefan Roese if (gpio >= SPEAR_GPIO_COUNT)
592cb06a4fSStefan Roese return -EINVAL;
602cb06a4fSStefan Roese
612cb06a4fSStefan Roese return 0;
622cb06a4fSStefan Roese }
632cb06a4fSStefan Roese
gpio_free(unsigned gpio)642cb06a4fSStefan Roese int gpio_free(unsigned gpio)
652cb06a4fSStefan Roese {
662cb06a4fSStefan Roese return 0;
672cb06a4fSStefan Roese }
682cb06a4fSStefan Roese
gpio_toggle_value(unsigned gpio)692cb06a4fSStefan Roese void gpio_toggle_value(unsigned gpio)
702cb06a4fSStefan Roese {
712cb06a4fSStefan Roese gpio_set_value(gpio, !gpio_get_value(gpio));
722cb06a4fSStefan Roese }
732cb06a4fSStefan Roese
gpio_direction_input(unsigned gpio)742cb06a4fSStefan Roese int gpio_direction_input(unsigned gpio)
752cb06a4fSStefan Roese {
762cb06a4fSStefan Roese return gpio_direction(gpio, GPIO_DIRECTION_IN);
772cb06a4fSStefan Roese }
782cb06a4fSStefan Roese
gpio_direction_output(unsigned gpio,int value)792cb06a4fSStefan Roese int gpio_direction_output(unsigned gpio, int value)
802cb06a4fSStefan Roese {
812cb06a4fSStefan Roese int ret = gpio_direction(gpio, GPIO_DIRECTION_OUT);
822cb06a4fSStefan Roese
832cb06a4fSStefan Roese if (ret < 0)
842cb06a4fSStefan Roese return ret;
852cb06a4fSStefan Roese
862cb06a4fSStefan Roese gpio_set_value(gpio, value);
872cb06a4fSStefan Roese return 0;
882cb06a4fSStefan Roese }
89