xref: /openbmc/u-boot/drivers/gpio/stm32f7_gpio.c (revision d876eaf2)
177417102SVikas Manocha /*
23bc599c9SPatrice Chotard  * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
33bc599c9SPatrice Chotard  * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
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 STM32_GPIOS_PER_BANK		16
2077417102SVikas Manocha #define MODE_BITS(gpio_pin)		(gpio_pin * 2)
2177417102SVikas Manocha #define MODE_BITS_MASK			3
2277417102SVikas Manocha #define IN_OUT_BIT_INDEX(gpio_pin)	(1UL << (gpio_pin))
2377417102SVikas Manocha 
2477417102SVikas Manocha static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
2577417102SVikas Manocha {
2677417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
2777417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
2877417102SVikas Manocha 	int bits_index = MODE_BITS(offset);
2977417102SVikas Manocha 	int mask = MODE_BITS_MASK << bits_index;
3077417102SVikas Manocha 
3177417102SVikas Manocha 	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
3277417102SVikas Manocha 
3377417102SVikas Manocha 	return 0;
3477417102SVikas Manocha }
3577417102SVikas Manocha 
3677417102SVikas Manocha static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
3777417102SVikas Manocha 				       int value)
3877417102SVikas Manocha {
3977417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
4077417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
4177417102SVikas Manocha 	int bits_index = MODE_BITS(offset);
4277417102SVikas Manocha 	int mask = MODE_BITS_MASK << bits_index;
4377417102SVikas Manocha 
4477417102SVikas Manocha 	clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
4577417102SVikas Manocha 	mask = IN_OUT_BIT_INDEX(offset);
4677417102SVikas Manocha 	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
4777417102SVikas Manocha 
4877417102SVikas Manocha 	return 0;
4977417102SVikas Manocha }
5077417102SVikas Manocha 
5177417102SVikas Manocha static int stm32_gpio_get_value(struct udevice *dev, unsigned offset)
5277417102SVikas Manocha {
5377417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
5477417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
5577417102SVikas Manocha 
5677417102SVikas Manocha 	return readl(&regs->idr) & IN_OUT_BIT_INDEX(offset) ? 1 : 0;
5777417102SVikas Manocha }
5877417102SVikas Manocha 
5977417102SVikas Manocha static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value)
6077417102SVikas Manocha {
6177417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
6277417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
6377417102SVikas Manocha 	int mask = IN_OUT_BIT_INDEX(offset);
6477417102SVikas Manocha 
6577417102SVikas Manocha 	clrsetbits_le32(&regs->odr, mask, value ? mask : 0);
6677417102SVikas Manocha 
6777417102SVikas Manocha 	return 0;
6877417102SVikas Manocha }
6977417102SVikas Manocha 
7077417102SVikas Manocha static const struct dm_gpio_ops gpio_stm32_ops = {
7177417102SVikas Manocha 	.direction_input	= stm32_gpio_direction_input,
7277417102SVikas Manocha 	.direction_output	= stm32_gpio_direction_output,
7377417102SVikas Manocha 	.get_value		= stm32_gpio_get_value,
7477417102SVikas Manocha 	.set_value		= stm32_gpio_set_value,
7577417102SVikas Manocha };
7677417102SVikas Manocha 
7777417102SVikas Manocha static int gpio_stm32_probe(struct udevice *dev)
7877417102SVikas Manocha {
7977417102SVikas Manocha 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
8077417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
8177417102SVikas Manocha 	fdt_addr_t addr;
82*d876eaf2SPatrick Delaunay 	const char *name;
8377417102SVikas Manocha 
84*d876eaf2SPatrick Delaunay 	addr = dev_read_addr(dev);
8577417102SVikas Manocha 	if (addr == FDT_ADDR_T_NONE)
8677417102SVikas Manocha 		return -EINVAL;
8777417102SVikas Manocha 
8877417102SVikas Manocha 	priv->regs = (struct stm32_gpio_regs *)addr;
89*d876eaf2SPatrick Delaunay 	name = dev_read_string(dev, "st,bank-name");
9077417102SVikas Manocha 	if (!name)
9177417102SVikas Manocha 		return -EINVAL;
9277417102SVikas Manocha 	uc_priv->bank_name = name;
9377417102SVikas Manocha 	uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
9477417102SVikas Manocha 	debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs,
9577417102SVikas Manocha 	      uc_priv->bank_name);
9677417102SVikas Manocha 
9777417102SVikas Manocha #ifdef CONFIG_CLK
9877417102SVikas Manocha 	struct clk clk;
9977417102SVikas Manocha 	int ret;
10077417102SVikas Manocha 	ret = clk_get_by_index(dev, 0, &clk);
10177417102SVikas Manocha 	if (ret < 0)
10277417102SVikas Manocha 		return ret;
10377417102SVikas Manocha 
10477417102SVikas Manocha 	ret = clk_enable(&clk);
10577417102SVikas Manocha 
10677417102SVikas Manocha 	if (ret) {
10777417102SVikas Manocha 		dev_err(dev, "failed to enable clock\n");
10877417102SVikas Manocha 		return ret;
10977417102SVikas Manocha 	}
11077417102SVikas Manocha 	debug("clock enabled for device %s\n", dev->name);
11177417102SVikas Manocha #endif
11277417102SVikas Manocha 
11377417102SVikas Manocha 	return 0;
11477417102SVikas Manocha }
11577417102SVikas Manocha 
11677417102SVikas Manocha static const struct udevice_id stm32_gpio_ids[] = {
11777417102SVikas Manocha 	{ .compatible = "st,stm32-gpio" },
11877417102SVikas Manocha 	{ }
11977417102SVikas Manocha };
12077417102SVikas Manocha 
12177417102SVikas Manocha U_BOOT_DRIVER(gpio_stm32) = {
12277417102SVikas Manocha 	.name	= "gpio_stm32",
12377417102SVikas Manocha 	.id	= UCLASS_GPIO,
12477417102SVikas Manocha 	.of_match = stm32_gpio_ids,
12577417102SVikas Manocha 	.probe	= gpio_stm32_probe,
12677417102SVikas Manocha 	.ops	= &gpio_stm32_ops,
12777417102SVikas Manocha 	.flags	= DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS,
12877417102SVikas Manocha 	.priv_auto_alloc_size	= sizeof(struct stm32_gpio_priv),
12977417102SVikas Manocha };
130