1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * gpiolib support for different serdes chip
4 *
5 * Copyright (c) 2023-2028 Rockchip Electronics Co. Ltd.
6 *
7 * Author: luowei <lw@rock-chips.com>
8 *
9 */
10
11 #include "core.h"
12
serdes_gpio_get(struct udevice * dev,unsigned int offset)13 static int serdes_gpio_get(struct udevice *dev, unsigned int offset)
14 {
15 struct serdes_pinctrl *serdes_pinctrl = dev_get_priv(dev->parent);
16 struct serdes *serdes = serdes_pinctrl->parent;
17 int ret = 0;
18
19 if (serdes->chip_data->gpio_ops->get_level)
20 ret = serdes->chip_data->gpio_ops->get_level(serdes, offset);
21
22 SERDES_DBG_MFD("%s: %s %s gpio=%d\n", __func__,
23 serdes->dev->name,
24 serdes->chip_data->name, offset);
25 return ret;
26 }
27
serdes_gpio_set(struct udevice * dev,unsigned int offset,int value)28 static int serdes_gpio_set(struct udevice *dev,
29 unsigned int offset, int value)
30 {
31 struct serdes_pinctrl *serdes_pinctrl = dev_get_priv(dev->parent);
32 struct serdes *serdes = serdes_pinctrl->parent;
33 int ret = 0;
34
35 if (serdes->chip_data->gpio_ops->set_level)
36 ret = serdes->chip_data->gpio_ops->set_level(serdes, offset, value);
37
38 SERDES_DBG_MFD("%s: %s %s gpio=%d,val=%d\n", __func__,
39 serdes->dev->name,
40 serdes->chip_data->name, offset, value);
41 return ret;
42 }
43
serdes_gpio_direction_input(struct udevice * dev,unsigned int offset)44 static int serdes_gpio_direction_input(struct udevice *dev,
45 unsigned int offset)
46 {
47 struct serdes_pinctrl *serdes_pinctrl = dev_get_priv(dev->parent);
48 struct serdes *serdes = serdes_pinctrl->parent;
49 int ret = 0;
50
51 if (serdes->chip_data->gpio_ops->direction_input)
52 ret = serdes->chip_data->gpio_ops->direction_input(serdes, offset);
53
54 SERDES_DBG_MFD("%s: %s %s gpio=%d\n", __func__,
55 serdes->dev->name,
56 serdes->chip_data->name, offset);
57 return ret;
58 }
59
serdes_gpio_direction_output(struct udevice * dev,unsigned int offset,int value)60 static int serdes_gpio_direction_output(struct udevice *dev,
61 unsigned int offset, int value)
62 {
63 struct serdes_pinctrl *serdes_pinctrl = dev_get_priv(dev->parent);
64 struct serdes *serdes = serdes_pinctrl->parent;
65 int ret = 0;
66
67 if (serdes->chip_data->gpio_ops->direction_output)
68 ret = serdes->chip_data->gpio_ops->direction_output(serdes, offset, value);
69
70 SERDES_DBG_MFD("%s: %s %s gpio=%d,val=%d\n", __func__,
71 serdes->dev->name,
72 serdes->chip_data->name, offset, value);
73 return ret;
74 }
75
serdes_gpio_probe(struct udevice * dev)76 static int serdes_gpio_probe(struct udevice *dev)
77 {
78 struct serdes *serdes = dev_get_priv(dev->parent->parent);
79 struct serdes_pinctrl *serdes_pinctrl = serdes->serdes_pinctrl;
80 struct serdes_gpio *serdes_gpio;
81
82 serdes_gpio = calloc(1, sizeof(*serdes_gpio));
83 if (!serdes_gpio)
84 return -ENOMEM;
85
86 serdes_pinctrl->serdes_gpio = serdes_gpio;
87
88 serdes_gpio->parent = serdes_pinctrl;
89
90 SERDES_DBG_MFD("%s: %s %s\n", __func__,
91 dev->name, serdes->chip_data->name);
92 return 0;
93 }
94
95 static struct dm_gpio_ops serdes_gpio_ops = {
96 .set_value = serdes_gpio_set,
97 .get_value = serdes_gpio_get,
98 .direction_input = serdes_gpio_direction_input,
99 .direction_output = serdes_gpio_direction_output,
100 };
101
102 U_BOOT_DRIVER(serdes_gpio) = {
103 .name = "serdes-gpio",
104 .id = UCLASS_GPIO,
105 .probe = serdes_gpio_probe,
106 .ops = &serdes_gpio_ops,
107 .priv_auto_alloc_size = sizeof(struct serdes_gpio),
108 };
109
110