1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * rohm-bu18rl82.c -- I2C register interface access for bu18rl82 serdes chip
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 #include "rohm-bu18rl82.h"
12
13 static int BU18RL82_GPIO0_pins[] = {0};
14 static int BU18RL82_GPIO1_pins[] = {1};
15 static int BU18RL82_GPIO2_pins[] = {2};
16 static int BU18RL82_GPIO3_pins[] = {3};
17 static int BU18RL82_GPIO4_pins[] = {4};
18 static int BU18RL82_GPIO5_pins[] = {5};
19 static int BU18RL82_GPIO6_pins[] = {6};
20 static int BU18RL82_GPIO7_pins[] = {7};
21
22 #define GROUP_DESC(nm) \
23 { \
24 .name = #nm, \
25 .pins = nm ## _pins, \
26 .num_pins = ARRAY_SIZE(nm ## _pins), \
27 }
28
29 struct serdes_function_data {
30 u8 gpio_rx_en:1;
31 u16 gpio_id;
32 u16 mdelay;
33 };
34
35 static const char *serdes_gpio_groups[] = {
36 "BU18RL82_GPIO0", "BU18RL82_GPIO1", "BU18RL82_GPIO2", "BU18RL82_GPIO3",
37 "BU18RL82_GPIO4", "BU18RL82_GPIO5", "BU18RL82_GPIO6", "BU18RL82_GPIO7",
38 };
39
40 /*des -> ser -> soc*/
41 #define FUNCTION_DESC_GPIO_INPUT(id) \
42 { \
43 .name = "DES_TO_SER_GPIO"#id, \
44 .group_names = serdes_gpio_groups, \
45 .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
46 .data = (void *)(const struct serdes_function_data []) { \
47 { .gpio_rx_en = 1, .gpio_id = id + 2 } \
48 }, \
49 } \
50
51 /*soc -> ser -> des*/
52 #define FUNCTION_DESC_GPIO_OUTPUT(id) \
53 { \
54 .name = "SER_GPIO"#id"_TO_DES", \
55 .group_names = serdes_gpio_groups, \
56 .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
57 .data = (void *)(const struct serdes_function_data []) { \
58 { .gpio_rx_en = 0, .gpio_id = id + 2 } \
59 }, \
60 } \
61
62 #define FUNCTION_DES_DELAY_MS(ms) \
63 { \
64 .name = "DELAY_"#ms"MS", \
65 .group_names = serdes_gpio_groups, \
66 .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
67 .data = (void *)(const struct serdes_function_data []) { \
68 { .mdelay = ms, } \
69 }, \
70 } \
71
72 /*des -> device*/
73 #define FUNCTION_DESC_GPIO_OUTPUT_HIGH() \
74 { \
75 .name = "DES_GPIO_OUTPUT_HIGH", \
76 .group_names = serdes_gpio_groups, \
77 .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
78 .data = (void *)(const struct serdes_function_data []) { \
79 { .gpio_rx_en = 0, .gpio_id = 1 } \
80 }, \
81 } \
82
83 #define FUNCTION_DESC_GPIO_OUTPUT_LOW() \
84 { \
85 .name = "DES_GPIO_OUTPUT_LOW", \
86 .group_names = serdes_gpio_groups, \
87 .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
88 .data = (void *)(const struct serdes_function_data []) { \
89 { .gpio_rx_en = 0, .gpio_id = 0 } \
90 }, \
91 } \
92
93 static struct pinctrl_pin_desc bu18rl82_pins_desc[] = {
94 PINCTRL_PIN(ROHM_BU18RL82_GPIO0, "BU18RL82_GPIO0"),
95 PINCTRL_PIN(ROHM_BU18RL82_GPIO1, "BU18RL82_GPIO1"),
96 PINCTRL_PIN(ROHM_BU18RL82_GPIO2, "BU18RL82_GPIO2"),
97 PINCTRL_PIN(ROHM_BU18RL82_GPIO3, "BU18RL82_GPIO3"),
98 PINCTRL_PIN(ROHM_BU18RL82_GPIO4, "BU18RL82_GPIO4"),
99 PINCTRL_PIN(ROHM_BU18RL82_GPIO5, "BU18RL82_GPIO5"),
100 PINCTRL_PIN(ROHM_BU18RL82_GPIO6, "BU18RL82_GPIO6"),
101 PINCTRL_PIN(ROHM_BU18RL82_GPIO7, "BU18RL82_GPIO7"),
102 };
103
104 static struct group_desc bu18rl82_groups_desc[] = {
105 GROUP_DESC(BU18RL82_GPIO0),
106 GROUP_DESC(BU18RL82_GPIO1),
107 GROUP_DESC(BU18RL82_GPIO2),
108 GROUP_DESC(BU18RL82_GPIO3),
109 GROUP_DESC(BU18RL82_GPIO4),
110 GROUP_DESC(BU18RL82_GPIO5),
111 GROUP_DESC(BU18RL82_GPIO6),
112 GROUP_DESC(BU18RL82_GPIO7),
113 };
114
115 static struct function_desc bu18rl82_functions_desc[] = {
116 FUNCTION_DESC_GPIO_INPUT(0),
117 FUNCTION_DESC_GPIO_INPUT(1),
118 FUNCTION_DESC_GPIO_INPUT(2),
119 FUNCTION_DESC_GPIO_INPUT(3),
120 FUNCTION_DESC_GPIO_INPUT(4),
121 FUNCTION_DESC_GPIO_INPUT(5),
122 FUNCTION_DESC_GPIO_INPUT(6),
123 FUNCTION_DESC_GPIO_INPUT(7),
124 FUNCTION_DESC_GPIO_INPUT(8),
125 FUNCTION_DESC_GPIO_INPUT(9),
126 FUNCTION_DESC_GPIO_INPUT(10),
127 FUNCTION_DESC_GPIO_INPUT(11),
128 FUNCTION_DESC_GPIO_INPUT(12),
129 FUNCTION_DESC_GPIO_INPUT(13),
130 FUNCTION_DESC_GPIO_INPUT(14),
131 FUNCTION_DESC_GPIO_INPUT(15),
132
133 FUNCTION_DESC_GPIO_OUTPUT(0),
134 FUNCTION_DESC_GPIO_OUTPUT(1),
135 FUNCTION_DESC_GPIO_OUTPUT(2),
136 FUNCTION_DESC_GPIO_OUTPUT(3),
137 FUNCTION_DESC_GPIO_OUTPUT(4),
138 FUNCTION_DESC_GPIO_OUTPUT(5),
139 FUNCTION_DESC_GPIO_OUTPUT(6),
140 FUNCTION_DESC_GPIO_OUTPUT(7),
141 FUNCTION_DESC_GPIO_OUTPUT(8),
142 FUNCTION_DESC_GPIO_OUTPUT(9),
143 FUNCTION_DESC_GPIO_OUTPUT(10),
144 FUNCTION_DESC_GPIO_OUTPUT(11),
145 FUNCTION_DESC_GPIO_OUTPUT(12),
146 FUNCTION_DESC_GPIO_OUTPUT(13),
147 FUNCTION_DESC_GPIO_OUTPUT(14),
148 FUNCTION_DESC_GPIO_OUTPUT(15),
149
150 FUNCTION_DESC_GPIO_OUTPUT_HIGH(),
151 FUNCTION_DESC_GPIO_OUTPUT_LOW(),
152
153 FUNCTION_DES_DELAY_MS(10),
154 FUNCTION_DES_DELAY_MS(50),
155 FUNCTION_DES_DELAY_MS(100),
156 FUNCTION_DES_DELAY_MS(200),
157 FUNCTION_DES_DELAY_MS(500),
158 };
159
160 static struct serdes_chip_pinctrl_info bu18rl82_pinctrl_info = {
161 .pins = bu18rl82_pins_desc,
162 .num_pins = ARRAY_SIZE(bu18rl82_pins_desc),
163 .groups = bu18rl82_groups_desc,
164 .num_groups = ARRAY_SIZE(bu18rl82_groups_desc),
165 .functions = bu18rl82_functions_desc,
166 .num_functions = ARRAY_SIZE(bu18rl82_functions_desc),
167 };
168
bu18rl82_bridge_swrst(struct serdes * serdes)169 void bu18rl82_bridge_swrst(struct serdes *serdes)
170 {
171 int ret;
172
173 ret = serdes_reg_write(serdes, BU18RL82_REG_RESET,
174 BIT(0) | BIT(1) | BIT(7));
175 if (ret < 0)
176 printf("%s: failed to reset bu18rl82 0x11 ret=%d\n",
177 __func__, ret);
178
179 mdelay(20);
180
181 SERDES_DBG_CHIP("%s: serdes %s ret=%d\n",
182 __func__, serdes->dev->name, ret);
183 }
184
bu18rl82_enable_hwint(struct serdes * serdes,int enable)185 void bu18rl82_enable_hwint(struct serdes *serdes, int enable)
186 {
187 int i, ret;
188
189 for (i = 0; i < ARRAY_SIZE(bu18rl82_reg_ien); i++) {
190 if (enable) {
191 ret = serdes_reg_write(serdes, bu18rl82_reg_ien[i].reg,
192 bu18rl82_reg_ien[i].ien);
193 if (ret)
194 printf("reg 0x%04x write error\n",
195 bu18rl82_reg_ien[i].reg);
196 } else {
197 ret = serdes_reg_write(serdes, bu18rl82_reg_ien[i].reg, 0);
198 if (ret)
199 printf("reg 0x%04x write error\n",
200 bu18rl82_reg_ien[i].reg);
201 }
202 }
203
204 SERDES_DBG_CHIP("%s: serdes %s ret=%d\n",
205 __func__,
206 serdes->dev->name, enable);
207 }
208
bu18rl82_bridge_init(struct serdes * serdes)209 int bu18rl82_bridge_init(struct serdes *serdes)
210 {
211 if (!dm_gpio_is_valid(&serdes->reset_gpio)) {
212 bu18rl82_bridge_swrst(serdes);
213 SERDES_DBG_CHIP("%s: serdes %s\n", __func__,
214 serdes->dev->name);
215 }
216
217 return 0;
218 }
219
bu18rl82_bridge_enable(struct serdes * serdes)220 int bu18rl82_bridge_enable(struct serdes *serdes)
221 {
222 int ret = 0;
223
224 /* 1:enable 0:dsiable*/
225 bu18rl82_enable_hwint(serdes, 0);
226
227 SERDES_DBG_CHIP("%s: serdes %s ret=%d\n", __func__,
228 serdes->dev->name, ret);
229 return ret;
230 }
231
bu18rl82_bridge_disable(struct serdes * serdes)232 int bu18rl82_bridge_disable(struct serdes *serdes)
233 {
234 return 0;
235 }
236
237 static struct serdes_chip_bridge_ops bu18rl82_bridge_ops = {
238 .init = bu18rl82_bridge_init,
239 .enable = bu18rl82_bridge_enable,
240 .disable = bu18rl82_bridge_disable,
241 };
242
bu18rl82_pinctrl_config_set(struct serdes * serdes,unsigned int pin_selector,unsigned int param,unsigned int argument)243 static int bu18rl82_pinctrl_config_set(struct serdes *serdes,
244 unsigned int pin_selector,
245 unsigned int param, unsigned int argument)
246 {
247 switch (param) {
248 case PIN_CONFIG_DRIVE_STRENGTH:
249 serdes_set_bits(serdes, bu18rl82_gpio_sw[pin_selector].reg,
250 bu18rl82_gpio_sw[pin_selector].mask,
251 FIELD_PREP(BIT(2) | BIT(1), argument));
252 SERDES_DBG_CHIP("%s: serdes %s pin=%d drive arg=0x%x\n",
253 __func__,
254 serdes->dev->name, pin_selector, argument);
255 break;
256 case PIN_CONFIG_BIAS_PULL_DOWN:
257 serdes_set_bits(serdes, bu18rl82_gpio_pden[pin_selector].reg,
258 bu18rl82_gpio_pden[pin_selector].mask,
259 FIELD_PREP(BIT(4), argument));
260 SERDES_DBG_CHIP("%s: serdes %s pin=%d pull-down arg=0x%x\n",
261 __func__,
262 serdes->dev->name, pin_selector, argument);
263 break;
264 case PIN_CONFIG_OUTPUT:
265 serdes_set_bits(serdes, bu18rl82_gpio_oen[pin_selector].reg,
266 bu18rl82_gpio_oen[pin_selector].mask,
267 FIELD_PREP(BIT(3), argument));
268 SERDES_DBG_CHIP("%s: serdes %s pin=%d output arg=0x%x\n",
269 __func__,
270 serdes->dev->name, pin_selector, argument);
271 break;
272 default:
273 return -EOPNOTSUPP;
274 }
275
276 return 0;
277 }
278
bu18rl82_pinctrl_set_pin_mux(struct serdes * serdes,unsigned int pin_selector,unsigned int func_selector)279 static int bu18rl82_pinctrl_set_pin_mux(struct serdes *serdes,
280 unsigned int pin_selector,
281 unsigned int func_selector)
282 {
283 struct function_desc *func;
284 struct pinctrl_pin_desc *pin;
285 int offset;
286 u16 ms;
287
288 func = &serdes->chip_data->pinctrl_info->functions[func_selector];
289 if (!func) {
290 printf("%s: func is null\n", __func__);
291 return -EINVAL;
292 }
293
294 pin = &serdes->chip_data->pinctrl_info->pins[pin_selector];
295 if (!pin) {
296 printf("%s: pin is null\n", __func__);
297 return -EINVAL;
298 }
299
300 SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p pin=%s num=%d\n",
301 __func__, serdes->dev->name,
302 func->name, func->data,
303 pin->name, pin->number);
304
305 if (func->data) {
306 struct serdes_function_data *fdata = func->data;
307 ms = fdata->mdelay;
308
309 offset = pin->number;
310 if (offset > 7)
311 dev_err(serdes->dev, "%s offset=%d > 7\n",
312 serdes->dev->name, offset);
313 else
314 SERDES_DBG_CHIP("%s: serdes %s id=0x%x off=%d\n",
315 __func__, serdes->dev->name,
316 fdata->gpio_id, offset);
317 if (!ms) {
318 serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
319 bu18rl82_gpio_oen[offset].mask,
320 FIELD_PREP(BIT(3), fdata->gpio_rx_en));
321 serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
322 bu18rl82_gpio_id_low[offset].mask,
323 FIELD_PREP(GENMASK(7, 0),
324 (fdata->gpio_id & 0xff)));
325 serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
326 bu18rl82_gpio_id_high[offset].mask,
327 FIELD_PREP(GENMASK(2, 0),
328 ((fdata->gpio_id >> 8) & 0x7)));
329 serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
330 bu18rl82_gpio_pden[offset].mask,
331 FIELD_PREP(BIT(4), 0));
332 } else {
333 mdelay(ms);
334 SERDES_DBG_CHIP("%s: delay %dms\n", __func__, ms);
335 }
336 }
337
338 return 0;
339 }
340
bu18rl82_pinctrl_set_grp_mux(struct serdes * serdes,unsigned int group_selector,unsigned int func_selector)341 static int bu18rl82_pinctrl_set_grp_mux(struct serdes *serdes,
342 unsigned int group_selector,
343 unsigned int func_selector)
344 {
345 struct serdes_pinctrl *pinctrl = serdes->serdes_pinctrl;
346 struct function_desc *func;
347 struct group_desc *grp;
348 int i, offset;
349
350 func = &serdes->chip_data->pinctrl_info->functions[func_selector];
351 if (!func) {
352 printf("%s: func is null\n", __func__);
353 return -EINVAL;
354 }
355
356 grp = &serdes->chip_data->pinctrl_info->groups[group_selector];
357 if (!grp) {
358 printf("%s: grp is null\n", __func__);
359 return -EINVAL;
360 }
361
362 SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p grp=%s data=%p, num=%d\n",
363 __func__, serdes->chip_data->name, func->name,
364 func->data, grp->name, grp->data, grp->num_pins);
365
366 if (func->data) {
367 struct serdes_function_data *fdata = func->data;
368
369 for (i = 0; i < grp->num_pins; i++) {
370 offset = grp->pins[i] - pinctrl->pin_base;
371 if (offset > 7)
372 dev_err(serdes->dev, "%s offset=%d > 7\n",
373 serdes->dev->name, offset);
374 else
375 SERDES_DBG_CHIP("%s: serdes %s id=0x%x, offset=%d\n",
376 __func__,
377 serdes->dev->name, fdata->gpio_id, offset);
378 serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
379 bu18rl82_gpio_oen[offset].mask,
380 FIELD_PREP(BIT(3), fdata->gpio_rx_en));
381 serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
382 bu18rl82_gpio_id_low[offset].mask,
383 FIELD_PREP(GENMASK(7, 0),
384 (fdata->gpio_id & 0xff)));
385 serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
386 bu18rl82_gpio_id_high[offset].mask,
387 FIELD_PREP(GENMASK(2, 0),
388 ((fdata->gpio_id >> 8) & 0x7)));
389 serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
390 bu18rl82_gpio_pden[offset].mask,
391 FIELD_PREP(BIT(4), 0));
392 }
393 }
394
395 return 0;
396 }
397
398 static struct serdes_chip_pinctrl_ops bu18rl82_pinctrl_ops = {
399 .pinconf_set = bu18rl82_pinctrl_config_set,
400 .pinmux_set = bu18rl82_pinctrl_set_pin_mux,
401 .pinmux_group_set = bu18rl82_pinctrl_set_grp_mux,
402 };
403
bu18rl82_gpio_direction_input(struct serdes * serdes,int gpio)404 static int bu18rl82_gpio_direction_input(struct serdes *serdes,
405 int gpio)
406 {
407 return 0;
408 }
409
bu18rl82_gpio_direction_output(struct serdes * serdes,int gpio,int value)410 static int bu18rl82_gpio_direction_output(struct serdes *serdes,
411 int gpio, int value)
412 {
413 return 0;
414 }
415
bu18rl82_gpio_get_level(struct serdes * serdes,int gpio)416 static int bu18rl82_gpio_get_level(struct serdes *serdes, int gpio)
417 {
418 return 0;
419 }
420
bu18rl82_gpio_set_level(struct serdes * serdes,int gpio,int value)421 int bu18rl82_gpio_set_level(struct serdes *serdes,
422 int gpio, int value)
423 {
424 return 0;
425 }
426
bu18rl82_gpio_set_config(struct serdes * serdes,int gpio,unsigned long config)427 static int bu18rl82_gpio_set_config(struct serdes *serdes,
428 int gpio, unsigned long config)
429 {
430 return 0;
431 }
432
bu18rl82_gpio_to_irq(struct serdes * serdes,int gpio)433 static int bu18rl82_gpio_to_irq(struct serdes *serdes, int gpio)
434 {
435 return 0;
436 }
437
438 static struct serdes_chip_gpio_ops bu18rl82_gpio_ops = {
439 .direction_input = bu18rl82_gpio_direction_input,
440 .direction_output = bu18rl82_gpio_direction_output,
441 .get_level = bu18rl82_gpio_get_level,
442 .set_level = bu18rl82_gpio_set_level,
443 .set_config = bu18rl82_gpio_set_config,
444 .to_irq = bu18rl82_gpio_to_irq,
445 };
446
447 struct serdes_chip_data serdes_bu18rl82_data = {
448 .name = "bu18rl82",
449 .serdes_type = TYPE_DES,
450 .serdes_id = ROHM_ID_BU18RL82,
451 .pinctrl_info = &bu18rl82_pinctrl_info,
452 .pinctrl_ops = &bu18rl82_pinctrl_ops,
453 .gpio_ops = &bu18rl82_gpio_ops,
454 .bridge_ops = &bu18rl82_bridge_ops,
455 };
456 EXPORT_SYMBOL_GPL(serdes_bu18rl82_data);
457
458 MODULE_LICENSE("GPL");
459