1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * serdes-pinctrl.c -- serdes pin control driver. 4 * 5 * Copyright (c) 2023-2028 Rockchip Electronics Co. Ltd. 6 * 7 * Author: luowei <lw@rock-chips.com> 8 */ 9 10 #include "core.h" 11 12 static const struct pinconf_param serdes_conf_params[] = { 13 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, 14 { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 }, 15 { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, 16 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, 17 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, 18 { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, 19 { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 }, 20 { "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 }, 21 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, 22 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, 23 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, 24 }; 25 26 static int serdes_pinctrl_get_pins_count(struct udevice *dev) 27 { 28 struct serdes *serdes = dev_get_priv(dev->parent); 29 30 if (serdes->chip_data->pinctrl_info->num_pins) 31 return serdes->chip_data->pinctrl_info->num_pins; 32 else 33 return 0; 34 } 35 36 static const char *serdes_pinctrl_get_pin_name(struct udevice *dev, 37 unsigned int selector) 38 { 39 struct serdes *serdes = dev_get_priv(dev->parent); 40 41 if (serdes->chip_data->pinctrl_info->pins[selector].name) 42 return serdes->chip_data->pinctrl_info->pins[selector].name; 43 else 44 return "unknow-pin"; 45 } 46 47 static int serdes_pinctrl_get_groups_count(struct udevice *dev) 48 { 49 struct serdes *serdes = dev_get_priv(dev->parent); 50 51 if (serdes->chip_data->pinctrl_info->num_groups) 52 return serdes->chip_data->pinctrl_info->num_groups; 53 else 54 return 0; 55 } 56 57 static const char *serdes_pinctrl_get_group_name(struct udevice *dev, 58 unsigned int selector) 59 { 60 struct serdes *serdes = dev_get_priv(dev->parent); 61 62 if (serdes->chip_data->pinctrl_info->groups[selector].name) 63 return serdes->chip_data->pinctrl_info->groups[selector].name; 64 else 65 return "unknow-group"; 66 } 67 68 static int serdes_pinctrl_get_functions_count(struct udevice *dev) 69 { 70 struct serdes *serdes = dev_get_priv(dev->parent); 71 72 if (serdes->chip_data->pinctrl_info->num_functions) 73 return serdes->chip_data->pinctrl_info->num_functions; 74 else 75 return 0; 76 } 77 78 static const char *serdes_pinctrl_get_function_name(struct udevice *dev, 79 unsigned int selector) 80 { 81 struct serdes *serdes = dev_get_priv(dev->parent); 82 83 if (serdes->chip_data->pinctrl_info->functions[selector].name) 84 return serdes->chip_data->pinctrl_info->functions[selector].name; 85 else 86 return "unknow-function"; 87 } 88 89 static int serdes_pinmux_set_mux(struct udevice *dev, 90 unsigned int pin_selector, 91 unsigned int func_selector) 92 { 93 struct serdes *serdes = dev_get_priv(dev->parent); 94 int ret = 0; 95 96 if (serdes->chip_data->pinctrl_ops->pinmux_set) 97 ret = serdes->chip_data->pinctrl_ops->pinmux_set(serdes, 98 pin_selector, func_selector); 99 100 SERDES_DBG_MFD("%s: %s pin=%d,func=%d\n", __func__, 101 serdes->chip_data->name, pin_selector, func_selector); 102 return ret; 103 } 104 105 static int serdes_pinmux_group_set_mux(struct udevice *dev, 106 unsigned int group_selector, 107 unsigned int func_selector) 108 { 109 struct serdes *serdes = dev_get_priv(dev->parent); 110 int ret = 0; 111 112 if (serdes->chip_data->pinctrl_ops->pinmux_group_set) 113 ret = serdes->chip_data->pinctrl_ops->pinmux_group_set(serdes, 114 group_selector, func_selector); 115 116 SERDES_DBG_MFD("%s: %s function=%d,group=%d\n", __func__, 117 serdes->chip_data->name, func_selector, group_selector); 118 return ret; 119 } 120 121 static int serdes_pinconf_set(struct udevice *dev, unsigned int pin_selector, 122 unsigned int param, unsigned int argument) 123 { 124 int ret = 0; 125 struct serdes *serdes = dev_get_priv(dev->parent); 126 127 if (serdes->chip_data->pinctrl_ops->pinconf_set) 128 ret = serdes->chip_data->pinctrl_ops->pinconf_set(serdes, 129 pin_selector, param, argument); 130 131 SERDES_DBG_MFD("serdes: pin = %d (%s), param = %d, arg = %d\n", 132 pin_selector, 133 serdes_pinctrl_get_pin_name(dev, pin_selector), 134 param, argument); 135 136 return ret; 137 } 138 139 static int serdes_pinconf_group_set(struct udevice *dev, 140 unsigned int group_selector, 141 unsigned int param, unsigned int argument) 142 { 143 int ret = 0; 144 struct serdes *serdes = dev_get_priv(dev->parent); 145 146 if (serdes->chip_data->pinctrl_ops->pinconf_group_set) 147 ret = serdes->chip_data->pinctrl_ops->pinconf_group_set(serdes, 148 group_selector, param, argument); 149 150 SERDES_DBG_MFD("serdes: group = %d (%s), param = %d, arg = %d\n", 151 group_selector, 152 serdes_pinctrl_get_group_name(dev, group_selector), 153 param, argument); 154 return ret; 155 } 156 157 static struct pinctrl_ops serdes_pinctrl_ops = { 158 .get_pins_count = serdes_pinctrl_get_pins_count, 159 .get_pin_name = serdes_pinctrl_get_pin_name, 160 .get_groups_count = serdes_pinctrl_get_groups_count, 161 .get_group_name = serdes_pinctrl_get_group_name, 162 .get_functions_count = serdes_pinctrl_get_functions_count, 163 .get_function_name = serdes_pinctrl_get_function_name, 164 .set_state = pinctrl_generic_set_state, 165 .pinmux_set = serdes_pinmux_set_mux, 166 .pinmux_group_set = serdes_pinmux_group_set_mux, 167 .pinconf_num_params = ARRAY_SIZE(serdes_conf_params), 168 .pinconf_params = serdes_conf_params, 169 .pinconf_set = serdes_pinconf_set, 170 .pinconf_group_set = serdes_pinconf_group_set, 171 }; 172 173 int serdes_pinctrl_probe(struct udevice *dev) 174 { 175 struct serdes *serdes = dev_get_priv(dev->parent); 176 struct serdes_pinctrl *serdes_pinctrl; 177 int ret = 0; 178 179 SERDES_DBG_MFD("%s: %s %s start\n", __func__, dev->name, 180 serdes->chip_data->name); 181 182 serdes_pinctrl = calloc(1, sizeof(*serdes_pinctrl)); 183 if (!serdes_pinctrl) 184 return -ENOMEM; 185 186 serdes->serdes_pinctrl = serdes_pinctrl; 187 188 serdes_pinctrl->parent = serdes; 189 190 ret = serdes_gpio_register(dev); 191 if (ret) 192 return ret; 193 194 return 0; 195 } 196 197 static const struct udevice_id serdes_of_match[] = { 198 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82) 199 { .compatible = "rohm,bu18tl82-pinctrl" }, 200 #endif 201 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82) 202 { .compatible = "rohm,bu18rl82-pinctrl" }, 203 #endif 204 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745) 205 { .compatible = "maxim,max96745-pinctrl", }, 206 #endif 207 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96755) 208 { .compatible = "maxim,max96755-pinctrl" }, 209 #endif 210 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111) 211 { .compatible = "rockchip,rkx111-pinctrl" }, 212 #endif 213 { } 214 }; 215 216 U_BOOT_DRIVER(serdes_pinctrl) = { 217 .name = "serdes-pinctrl", 218 .id = UCLASS_PINCTRL, 219 .of_match = serdes_of_match, 220 .probe = serdes_pinctrl_probe, 221 .ops = &serdes_pinctrl_ops, 222 .priv_auto_alloc_size = sizeof(struct serdes_pinctrl), 223 }; 224