xref: /openbmc/u-boot/drivers/gpio/spear_gpio.c (revision e8f80a5a)
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(&regs->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, &regs->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, &regs->gpiodata[DATA_REG_ADDR(gpio)]);
40c0c37402SAxel Lin 	else
41c0c37402SAxel Lin 		writel(0, &regs->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(&regs->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