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