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