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 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 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 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 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 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