]>
Commit | Line | Data |
---|---|---|
15efe0f3 KR |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * slg7xl45106_i2c_gpo driver | |
4 | * | |
5 | * Copyright (C) 2021 Xilinx, Inc. | |
6 | */ | |
7 | ||
15efe0f3 KR |
8 | #include <errno.h> |
9 | #include <asm/io.h> | |
10 | #include <asm/gpio.h> | |
11 | #include <dm.h> | |
12 | #include <i2c.h> | |
e949e789 | 13 | #include <dt-bindings/gpio/gpio.h> |
15efe0f3 KR |
14 | #include <asm/arch/hardware.h> |
15 | ||
16 | #define SLG7XL45106_REG 0xdb | |
17 | ||
18 | static int slg7xl45106_i2c_gpo_direction_input(struct udevice *dev, | |
19 | unsigned int offset) | |
20 | { | |
21 | return 0; | |
22 | } | |
23 | ||
24 | static int slg7xl45106_i2c_gpo_xlate(struct udevice *dev, | |
25 | struct gpio_desc *desc, | |
26 | struct ofnode_phandle_args *args) | |
27 | { | |
28 | desc->offset = (unsigned int)args->args[0]; | |
e949e789 | 29 | desc->flags = (args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0); |
15efe0f3 KR |
30 | |
31 | return 0; | |
32 | } | |
33 | ||
34 | static int slg7xl45106_i2c_gpo_set_value(struct udevice *dev, | |
35 | unsigned int offset, int value) | |
36 | { | |
37 | int ret; | |
38 | u8 val; | |
39 | ||
40 | ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1); | |
41 | if (ret) | |
42 | return ret; | |
43 | ||
44 | if (value) | |
45 | val |= BIT(offset); | |
46 | else | |
47 | val &= ~BIT(offset); | |
48 | ||
49 | return dm_i2c_write(dev, SLG7XL45106_REG, &val, 1); | |
50 | } | |
51 | ||
52 | static int slg7xl45106_i2c_gpo_direction_output(struct udevice *dev, | |
53 | unsigned int offset, int value) | |
54 | { | |
55 | return slg7xl45106_i2c_gpo_set_value(dev, offset, value); | |
56 | } | |
57 | ||
58 | static int slg7xl45106_i2c_gpo_get_value(struct udevice *dev, | |
59 | unsigned int offset) | |
60 | { | |
61 | int ret; | |
62 | u8 val; | |
63 | ||
64 | ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1); | |
65 | if (ret) | |
66 | return ret; | |
67 | ||
68 | return !!(val & BIT(offset)); | |
69 | } | |
70 | ||
71 | static int slg7xl45106_i2c_gpo_get_function(struct udevice *dev, | |
72 | unsigned int offset) | |
73 | { | |
74 | return GPIOF_OUTPUT; | |
75 | } | |
76 | ||
77 | static const struct dm_gpio_ops slg7xl45106_i2c_gpo_ops = { | |
78 | .direction_input = slg7xl45106_i2c_gpo_direction_input, | |
79 | .direction_output = slg7xl45106_i2c_gpo_direction_output, | |
80 | .get_value = slg7xl45106_i2c_gpo_get_value, | |
81 | .set_value = slg7xl45106_i2c_gpo_set_value, | |
82 | .get_function = slg7xl45106_i2c_gpo_get_function, | |
83 | .xlate = slg7xl45106_i2c_gpo_xlate, | |
84 | }; | |
85 | ||
86 | static int slg7xl45106_i2c_gpo_probe(struct udevice *dev) | |
87 | { | |
88 | struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
89 | const void *label_ptr; | |
90 | ||
91 | label_ptr = dev_read_prop(dev, "label", NULL); | |
92 | if (label_ptr) { | |
93 | uc_priv->bank_name = strdup(label_ptr); | |
94 | if (!uc_priv->bank_name) | |
95 | return -ENOMEM; | |
96 | } else { | |
97 | uc_priv->bank_name = dev->name; | |
98 | } | |
99 | ||
100 | uc_priv->gpio_count = 8; | |
101 | ||
102 | return 0; | |
103 | } | |
104 | ||
105 | static const struct udevice_id slg7xl45106_i2c_gpo_ids[] = { | |
106 | { .compatible = "dlg,slg7xl45106",}, | |
107 | { } | |
108 | }; | |
109 | ||
110 | U_BOOT_DRIVER(slg7xl45106_i2c_gpo) = { | |
111 | .name = "slg7xl45106_i2c_gpo", | |
112 | .id = UCLASS_GPIO, | |
113 | .ops = &slg7xl45106_i2c_gpo_ops, | |
114 | .of_match = slg7xl45106_i2c_gpo_ids, | |
115 | .probe = slg7xl45106_i2c_gpo_probe, | |
116 | }; |