]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
152f4898 PG |
2 | /* |
3 | * Copyright (C) 2015 Linaro | |
4 | * Peter Griffin <[email protected]> | |
152f4898 PG |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <dm.h> | |
9 | #include <asm/gpio.h> | |
10 | #include <asm/io.h> | |
11 | #include <errno.h> | |
cd93d625 | 12 | #include <linux/bitops.h> |
152f4898 PG |
13 | |
14 | static int hi6220_gpio_direction_input(struct udevice *dev, unsigned int gpio) | |
15 | { | |
16 | struct gpio_bank *bank = dev_get_priv(dev); | |
17 | u8 data; | |
18 | ||
19 | data = readb(bank->base + HI6220_GPIO_DIR); | |
20 | data &= ~(1 << gpio); | |
21 | writeb(data, bank->base + HI6220_GPIO_DIR); | |
22 | ||
23 | return 0; | |
24 | } | |
25 | ||
26 | static int hi6220_gpio_set_value(struct udevice *dev, unsigned gpio, | |
27 | int value) | |
28 | { | |
29 | struct gpio_bank *bank = dev_get_priv(dev); | |
30 | ||
31 | writeb(!!value << gpio, bank->base + (BIT(gpio + 2))); | |
32 | return 0; | |
33 | } | |
34 | ||
35 | static int hi6220_gpio_direction_output(struct udevice *dev, unsigned gpio, | |
36 | int value) | |
37 | { | |
38 | struct gpio_bank *bank = dev_get_priv(dev); | |
39 | u8 data; | |
40 | ||
41 | data = readb(bank->base + HI6220_GPIO_DIR); | |
42 | data |= 1 << gpio; | |
43 | writeb(data, bank->base + HI6220_GPIO_DIR); | |
44 | ||
45 | hi6220_gpio_set_value(dev, gpio, value); | |
46 | ||
47 | return 0; | |
48 | } | |
49 | ||
50 | static int hi6220_gpio_get_value(struct udevice *dev, unsigned gpio) | |
51 | { | |
52 | struct gpio_bank *bank = dev_get_priv(dev); | |
53 | ||
54 | return !!readb(bank->base + (BIT(gpio + 2))); | |
55 | } | |
56 | ||
57 | ||
58 | ||
59 | static const struct dm_gpio_ops gpio_hi6220_ops = { | |
60 | .direction_input = hi6220_gpio_direction_input, | |
61 | .direction_output = hi6220_gpio_direction_output, | |
62 | .get_value = hi6220_gpio_get_value, | |
63 | .set_value = hi6220_gpio_set_value, | |
64 | }; | |
65 | ||
66 | static int hi6220_gpio_probe(struct udevice *dev) | |
67 | { | |
68 | struct gpio_bank *bank = dev_get_priv(dev); | |
8a8d24bd | 69 | struct hikey_gpio_plat *plat = dev_get_plat(dev); |
152f4898 PG |
70 | struct gpio_dev_priv *uc_priv = dev->uclass_priv; |
71 | char name[18], *str; | |
72 | ||
73 | sprintf(name, "GPIO%d_", plat->bank_index); | |
74 | ||
75 | str = strdup(name); | |
76 | if (!str) | |
77 | return -ENOMEM; | |
78 | ||
79 | uc_priv->bank_name = str; | |
80 | uc_priv->gpio_count = HI6220_GPIO_PER_BANK; | |
81 | ||
82 | bank->base = (u8 *)plat->base; | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
87 | U_BOOT_DRIVER(gpio_hi6220) = { | |
88 | .name = "gpio_hi6220", | |
89 | .id = UCLASS_GPIO, | |
90 | .ops = &gpio_hi6220_ops, | |
91 | .probe = hi6220_gpio_probe, | |
41575d8e | 92 | .priv_auto = sizeof(struct gpio_bank), |
152f4898 PG |
93 | }; |
94 | ||
95 |