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(®s->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(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); 4577417102SVikas Manocha mask = IN_OUT_BIT_INDEX(offset); 4677417102SVikas Manocha clrsetbits_le32(®s->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(®s->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(®s->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