xref: /rk3399_rockchip-uboot/drivers/gpio/stm32f7_gpio.c (revision a821c4af79e4f5ce9b629b20473863397bbe9b10)
177417102SVikas Manocha /*
277417102SVikas Manocha  * (C) Copyright 2017
377417102SVikas Manocha  * Vikas Manocha, <vikas.manocha@st.com>
477417102SVikas Manocha  *
577417102SVikas Manocha  * SPDX-License-Identifier:	GPL-2.0+
677417102SVikas Manocha  */
777417102SVikas Manocha 
877417102SVikas Manocha #include <common.h>
977417102SVikas Manocha #include <clk.h>
1077417102SVikas Manocha #include <dm.h>
1177417102SVikas Manocha #include <fdtdec.h>
1277417102SVikas Manocha #include <asm/arch/gpio.h>
1377417102SVikas Manocha #include <asm/arch/stm32.h>
1477417102SVikas Manocha #include <asm/gpio.h>
1577417102SVikas Manocha #include <asm/io.h>
1677417102SVikas Manocha #include <linux/errno.h>
1777417102SVikas Manocha #include <linux/io.h>
1877417102SVikas Manocha 
1977417102SVikas Manocha #define MAX_SIZE_BANK_NAME		5
2077417102SVikas Manocha #define STM32_GPIOS_PER_BANK		16
2177417102SVikas Manocha #define MODE_BITS(gpio_pin)		(gpio_pin * 2)
2277417102SVikas Manocha #define MODE_BITS_MASK			3
2377417102SVikas Manocha #define IN_OUT_BIT_INDEX(gpio_pin)	(1UL << (gpio_pin))
2477417102SVikas Manocha 
2577417102SVikas Manocha DECLARE_GLOBAL_DATA_PTR;
2677417102SVikas Manocha 
stm32_gpio_direction_input(struct udevice * dev,unsigned offset)2777417102SVikas Manocha static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
2877417102SVikas Manocha {
2977417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
3077417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
3177417102SVikas Manocha 	int bits_index = MODE_BITS(offset);
3277417102SVikas Manocha 	int mask = MODE_BITS_MASK << bits_index;
3377417102SVikas Manocha 
3477417102SVikas Manocha 	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
3577417102SVikas Manocha 
3677417102SVikas Manocha 	return 0;
3777417102SVikas Manocha }
3877417102SVikas Manocha 
stm32_gpio_direction_output(struct udevice * dev,unsigned offset,int value)3977417102SVikas Manocha static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
4077417102SVikas Manocha 				       int value)
4177417102SVikas Manocha {
4277417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
4377417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
4477417102SVikas Manocha 	int bits_index = MODE_BITS(offset);
4577417102SVikas Manocha 	int mask = MODE_BITS_MASK << bits_index;
4677417102SVikas Manocha 
4777417102SVikas Manocha 	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
4877417102SVikas Manocha 	mask = IN_OUT_BIT_INDEX(offset);
4977417102SVikas Manocha 	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
5077417102SVikas Manocha 
5177417102SVikas Manocha 	return 0;
5277417102SVikas Manocha }
5377417102SVikas Manocha 
stm32_gpio_get_value(struct udevice * dev,unsigned offset)5477417102SVikas Manocha static int stm32_gpio_get_value(struct udevice *dev, unsigned offset)
5577417102SVikas Manocha {
5677417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
5777417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
5877417102SVikas Manocha 
5977417102SVikas Manocha 	return readl(&regs->idr) & IN_OUT_BIT_INDEX(offset) ? 1 : 0;
6077417102SVikas Manocha }
6177417102SVikas Manocha 
stm32_gpio_set_value(struct udevice * dev,unsigned offset,int value)6277417102SVikas Manocha static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value)
6377417102SVikas Manocha {
6477417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
6577417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
6677417102SVikas Manocha 	int mask = IN_OUT_BIT_INDEX(offset);
6777417102SVikas Manocha 
6877417102SVikas Manocha 	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
6977417102SVikas Manocha 
7077417102SVikas Manocha 	return 0;
7177417102SVikas Manocha }
7277417102SVikas Manocha 
7377417102SVikas Manocha static const struct dm_gpio_ops gpio_stm32_ops = {
7477417102SVikas Manocha 	.direction_input	= stm32_gpio_direction_input,
7577417102SVikas Manocha 	.direction_output	= stm32_gpio_direction_output,
7677417102SVikas Manocha 	.get_value		= stm32_gpio_get_value,
7777417102SVikas Manocha 	.set_value		= stm32_gpio_set_value,
7877417102SVikas Manocha };
7977417102SVikas Manocha 
gpio_stm32_probe(struct udevice * dev)8077417102SVikas Manocha static int gpio_stm32_probe(struct udevice *dev)
8177417102SVikas Manocha {
8277417102SVikas Manocha 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
8377417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
8477417102SVikas Manocha 	fdt_addr_t addr;
8577417102SVikas Manocha 	char *name;
8677417102SVikas Manocha 
87*a821c4afSSimon Glass 	addr = devfdt_get_addr(dev);
8877417102SVikas Manocha 	if (addr == FDT_ADDR_T_NONE)
8977417102SVikas Manocha 		return -EINVAL;
9077417102SVikas Manocha 
9177417102SVikas Manocha 	priv->regs = (struct stm32_gpio_regs *)addr;
9277417102SVikas Manocha 	name = (char *)fdtdec_locate_byte_array(gd->fdt_blob,
9377417102SVikas Manocha 						dev_of_offset(dev),
9477417102SVikas Manocha 						"st,bank-name",
9577417102SVikas Manocha 						MAX_SIZE_BANK_NAME);
9677417102SVikas Manocha 	if (!name)
9777417102SVikas Manocha 		return -EINVAL;
9877417102SVikas Manocha 	uc_priv->bank_name = name;
9977417102SVikas Manocha 	uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
10077417102SVikas Manocha 	debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs,
10177417102SVikas Manocha 	      uc_priv->bank_name);
10277417102SVikas Manocha 
10377417102SVikas Manocha #ifdef CONFIG_CLK
10477417102SVikas Manocha 	struct clk clk;
10577417102SVikas Manocha 	int ret;
10677417102SVikas Manocha 	ret = clk_get_by_index(dev, 0, &clk);
10777417102SVikas Manocha 	if (ret < 0)
10877417102SVikas Manocha 		return ret;
10977417102SVikas Manocha 
11077417102SVikas Manocha 	ret = clk_enable(&clk);
11177417102SVikas Manocha 
11277417102SVikas Manocha 	if (ret) {
11377417102SVikas Manocha 		dev_err(dev, "failed to enable clock\n");
11477417102SVikas Manocha 		return ret;
11577417102SVikas Manocha 	}
11677417102SVikas Manocha 	debug("clock enabled for device %s\n", dev->name);
11777417102SVikas Manocha #endif
11877417102SVikas Manocha 
11977417102SVikas Manocha 	return 0;
12077417102SVikas Manocha }
12177417102SVikas Manocha 
12277417102SVikas Manocha static const struct udevice_id stm32_gpio_ids[] = {
12377417102SVikas Manocha 	{ .compatible = "st,stm32-gpio" },
12477417102SVikas Manocha 	{ }
12577417102SVikas Manocha };
12677417102SVikas Manocha 
12777417102SVikas Manocha U_BOOT_DRIVER(gpio_stm32) = {
12877417102SVikas Manocha 	.name	= "gpio_stm32",
12977417102SVikas Manocha 	.id	= UCLASS_GPIO,
13077417102SVikas Manocha 	.of_match = stm32_gpio_ids,
13177417102SVikas Manocha 	.probe	= gpio_stm32_probe,
13277417102SVikas Manocha 	.ops	= &gpio_stm32_ops,
13377417102SVikas Manocha 	.flags	= DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS,
13477417102SVikas Manocha 	.priv_auto_alloc_size	= sizeof(struct stm32_gpio_priv),
13577417102SVikas Manocha };
136