1 /* 2 * Copyright (C) 2016 Stefan Roese <sr@denx.de> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <asm/gpio.h> 10 #include <asm/io.h> 11 #include <errno.h> 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 #define MVEBU_GPIOS_PER_BANK 32 16 17 struct mvebu_gpio_regs { 18 u32 data_out; 19 u32 io_conf; 20 u32 blink_en; 21 u32 in_pol; 22 u32 data_in; 23 }; 24 25 struct mvebu_gpio_priv { 26 struct mvebu_gpio_regs *regs; 27 char name[2]; 28 }; 29 30 static int mvebu_gpio_direction_input(struct udevice *dev, unsigned int gpio) 31 { 32 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 33 struct mvebu_gpio_regs *regs = priv->regs; 34 35 setbits_le32(®s->io_conf, BIT(gpio)); 36 37 return 0; 38 } 39 40 static int mvebu_gpio_direction_output(struct udevice *dev, unsigned gpio, 41 int value) 42 { 43 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 44 struct mvebu_gpio_regs *regs = priv->regs; 45 46 clrbits_le32(®s->io_conf, BIT(gpio)); 47 48 return 0; 49 } 50 51 static int mvebu_gpio_get_function(struct udevice *dev, unsigned gpio) 52 { 53 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 54 struct mvebu_gpio_regs *regs = priv->regs; 55 u32 val; 56 57 val = readl(®s->io_conf) & BIT(gpio); 58 if (val) 59 return GPIOF_INPUT; 60 else 61 return GPIOF_OUTPUT; 62 } 63 64 static int mvebu_gpio_set_value(struct udevice *dev, unsigned gpio, 65 int value) 66 { 67 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 68 struct mvebu_gpio_regs *regs = priv->regs; 69 70 if (value) 71 setbits_le32(®s->data_out, BIT(gpio)); 72 else 73 clrbits_le32(®s->data_out, BIT(gpio)); 74 75 return 0; 76 } 77 78 static int mvebu_gpio_get_value(struct udevice *dev, unsigned gpio) 79 { 80 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 81 struct mvebu_gpio_regs *regs = priv->regs; 82 83 return !!(readl(®s->data_in) & BIT(gpio)); 84 } 85 86 static int mvebu_gpio_probe(struct udevice *dev) 87 { 88 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 89 struct mvebu_gpio_priv *priv = dev_get_priv(dev); 90 91 priv->regs = (struct mvebu_gpio_regs *)dev_get_addr(dev); 92 uc_priv->gpio_count = MVEBU_GPIOS_PER_BANK; 93 priv->name[0] = 'A' + dev->req_seq; 94 uc_priv->bank_name = priv->name; 95 96 return 0; 97 } 98 99 static const struct dm_gpio_ops mvebu_gpio_ops = { 100 .direction_input = mvebu_gpio_direction_input, 101 .direction_output = mvebu_gpio_direction_output, 102 .get_function = mvebu_gpio_get_function, 103 .get_value = mvebu_gpio_get_value, 104 .set_value = mvebu_gpio_set_value, 105 }; 106 107 static const struct udevice_id mvebu_gpio_ids[] = { 108 { .compatible = "marvell,orion-gpio" }, 109 { } 110 }; 111 112 U_BOOT_DRIVER(gpio_mvebu) = { 113 .name = "gpio_mvebu", 114 .id = UCLASS_GPIO, 115 .of_match = mvebu_gpio_ids, 116 .ops = &mvebu_gpio_ops, 117 .probe = mvebu_gpio_probe, 118 .priv_auto_alloc_size = sizeof(struct mvebu_gpio_priv), 119 }; 120