xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/maxim/maxim-max96752.c (revision c5ff44bc8ebec81979fbcd4aacb56e0ca3b2fb53)
1a00ee452SLuo Wei // SPDX-License-Identifier: GPL-2.0-or-later
2a00ee452SLuo Wei /*
3a00ee452SLuo Wei  * maxim-max96752.c  --  I2C register interface access for max96752 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  */
9fb0c3269SLuo Wei #include "../core.h"
10a00ee452SLuo Wei #include "maxim-max96752.h"
11a00ee452SLuo Wei 
12fb0c3269SLuo Wei struct config_desc {
13fb0c3269SLuo Wei 	u16 reg;
14fb0c3269SLuo Wei 	u8 mask;
15fb0c3269SLuo Wei 	u8 val;
16fb0c3269SLuo Wei };
17fb0c3269SLuo Wei 
18fb0c3269SLuo Wei struct serdes_group_data {
19fb0c3269SLuo Wei 	const struct config_desc *configs;
20fb0c3269SLuo Wei 	int num_configs;
21fb0c3269SLuo Wei };
22fb0c3269SLuo Wei 
23fb0c3269SLuo Wei static int MAX96752_GPIO0_pins[] = {0};
24fb0c3269SLuo Wei static int MAX96752_GPIO1_pins[] = {1};
25fb0c3269SLuo Wei static int MAX96752_GPIO2_pins[] = {2};
26fb0c3269SLuo Wei static int MAX96752_GPIO3_pins[] = {3};
27fb0c3269SLuo Wei static int MAX96752_GPIO4_pins[] = {4};
28fb0c3269SLuo Wei static int MAX96752_GPIO5_pins[] = {5};
29fb0c3269SLuo Wei static int MAX96752_GPIO6_pins[] = {6};
30fb0c3269SLuo Wei static int MAX96752_GPIO7_pins[] = {7};
31fb0c3269SLuo Wei 
32fb0c3269SLuo Wei static int MAX96752_GPIO8_pins[] = {8};
33fb0c3269SLuo Wei static int MAX96752_GPIO9_pins[] = {9};
34fb0c3269SLuo Wei static int MAX96752_GPIO10_pins[] = {10};
35fb0c3269SLuo Wei static int MAX96752_GPIO11_pins[] = {11};
36fb0c3269SLuo Wei static int MAX96752_GPIO12_pins[] = {12};
37fb0c3269SLuo Wei static int MAX96752_GPIO13_pins[] = {13};
38fb0c3269SLuo Wei static int MAX96752_GPIO14_pins[] = {14};
39fb0c3269SLuo Wei static int MAX96752_GPIO15_pins[] = {15};
40fb0c3269SLuo Wei 
41fb0c3269SLuo Wei #define GROUP_DESC(nm) \
42fb0c3269SLuo Wei { \
43fb0c3269SLuo Wei 	.name = #nm, \
44fb0c3269SLuo Wei 	.pins = nm ## _pins, \
45fb0c3269SLuo Wei 	.num_pins = ARRAY_SIZE(nm ## _pins), \
46fb0c3269SLuo Wei }
47fb0c3269SLuo Wei 
48fb0c3269SLuo Wei struct serdes_function_data {
49fb0c3269SLuo Wei 	u8 gpio_out_dis:1;
50fb0c3269SLuo Wei 	u8 gpio_tx_en:1;
51fb0c3269SLuo Wei 	u8 gpio_rx_en:1;
52fb0c3269SLuo Wei 	u8 gpio_in_level:1;
53fb0c3269SLuo Wei 	u8 gpio_out_level:1;
54fb0c3269SLuo Wei 	u8 gpio_tx_id;
55fb0c3269SLuo Wei 	u8 gpio_rx_id;
56fb0c3269SLuo Wei 	u16 mdelay;
57fb0c3269SLuo Wei };
58fb0c3269SLuo Wei 
59fb0c3269SLuo Wei static const char *serdes_gpio_groups[] = {
60fb0c3269SLuo Wei 	"MAX96752_GPIO0", "MAX96752_GPIO1", "MAX96752_GPIO2", "MAX96752_GPIO3",
61fb0c3269SLuo Wei 	"MAX96752_GPIO4", "MAX96752_GPIO5", "MAX96752_GPIO6", "MAX96752_GPIO7",
62fb0c3269SLuo Wei 
63fb0c3269SLuo Wei 	"MAX96752_GPIO8", "MAX96752_GPIO9", "MAX96752_GPIO10", "MAX96752_GPIO11",
64fb0c3269SLuo Wei 	"MAX96752_GPIO12", "MAX96752_GPIO13", "MAX96752_GPIO14", "MAX96752_GPIO15",
65fb0c3269SLuo Wei };
66fb0c3269SLuo Wei 
67fb0c3269SLuo Wei #define FUNCTION_DESC_GPIO_INPUT_BYPASS(id) \
68fb0c3269SLuo Wei { \
69fb0c3269SLuo Wei 	.name = "SER_TO_DES_RXID"#id, \
70fb0c3269SLuo Wei 	.group_names = serdes_gpio_groups, \
71fb0c3269SLuo Wei 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
72fb0c3269SLuo Wei 	.data = (void *)(const struct serdes_function_data []) { \
73fb0c3269SLuo Wei 		{ .gpio_rx_en = 1, .gpio_rx_id = id } \
74fb0c3269SLuo Wei 	}, \
75fb0c3269SLuo Wei } \
76fb0c3269SLuo Wei 
77fb0c3269SLuo Wei #define FUNCTION_DESC_GPIO_OUTPUT_BYPASS(id) \
78fb0c3269SLuo Wei { \
79fb0c3269SLuo Wei 	.name = "DES_TXID"#id"_TO_SER", \
80fb0c3269SLuo Wei 	.group_names = serdes_gpio_groups, \
81fb0c3269SLuo Wei 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
82fb0c3269SLuo Wei 	.data = (void *)(const struct serdes_function_data []) { \
83fb0c3269SLuo Wei 		{ .gpio_out_dis = 1, .gpio_tx_en = 1, .gpio_tx_id = id } \
84fb0c3269SLuo Wei 	}, \
85fb0c3269SLuo Wei } \
86fb0c3269SLuo Wei 
87fb0c3269SLuo Wei #define FUNCTION_DESC_GPIO_OUTPUT_LOW(id) \
88fb0c3269SLuo Wei { \
89fb0c3269SLuo Wei 	.name = "DES_TXID"#id"_OUTPUT_LOW", \
90fb0c3269SLuo Wei 	.group_names = serdes_gpio_groups, \
91fb0c3269SLuo Wei 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
92fb0c3269SLuo Wei 	.data = (void *)(const struct serdes_function_data []) { \
93fb0c3269SLuo Wei 		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
94fb0c3269SLuo Wei 		  .gpio_rx_en = 0, .gpio_out_level = 0, .gpio_tx_id = id } \
95fb0c3269SLuo Wei 	}, \
96fb0c3269SLuo Wei } \
97fb0c3269SLuo Wei 
98fb0c3269SLuo Wei #define FUNCTION_DESC_GPIO_OUTPUT_HIGH(id) \
99fb0c3269SLuo Wei { \
100fb0c3269SLuo Wei 	.name = "DES_TXID"#id"_OUTPUT_HIGH", \
101fb0c3269SLuo Wei 	.group_names = serdes_gpio_groups, \
102fb0c3269SLuo Wei 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
103fb0c3269SLuo Wei 	.data = (void *)(const struct serdes_function_data []) { \
104fb0c3269SLuo Wei 		{ .gpio_out_dis = 0, .gpio_tx_en = 0, \
105fb0c3269SLuo Wei 		  .gpio_rx_en = 0, .gpio_out_level = 1, .gpio_tx_id = id } \
106fb0c3269SLuo Wei 	}, \
107fb0c3269SLuo Wei } \
108fb0c3269SLuo Wei 
109fb0c3269SLuo Wei #define FUNCTION_DES_DELAY_MS(ms) \
110fb0c3269SLuo Wei { \
111fb0c3269SLuo Wei 	.name = "DELAY_"#ms"MS", \
112fb0c3269SLuo Wei 	.group_names = serdes_gpio_groups, \
113fb0c3269SLuo Wei 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
114fb0c3269SLuo Wei 	.data = (void *)(const struct serdes_function_data []) { \
115fb0c3269SLuo Wei 		{ .mdelay = ms, } \
116fb0c3269SLuo Wei 	}, \
117fb0c3269SLuo Wei } \
118fb0c3269SLuo Wei 
119fb0c3269SLuo Wei static struct pinctrl_pin_desc max96752_pins_desc[] = {
120fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO0, "MAX96752_GPIO0"),
121fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO1, "MAX96752_GPIO1"),
122fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO2, "MAX96752_GPIO2"),
123fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO3, "MAX96752_GPIO3"),
124fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO4, "MAX96752_GPIO4"),
125fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO5, "MAX96752_GPIO5"),
126fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO6, "MAX96752_GPIO6"),
127fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO7, "MAX96752_GPIO7"),
128fb0c3269SLuo Wei 
129fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO8, "MAX96752_GPIO8"),
130fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO9, "MAX96752_GPIO9"),
131fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO10, "MAX96752_GPIO10"),
132fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO11, "MAX96752_GPIO11"),
133fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO12, "MAX96752_GPIO12"),
134fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO13, "MAX96752_GPIO13"),
135fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO14, "MAX96752_GPIO14"),
136fb0c3269SLuo Wei 	PINCTRL_PIN(MAXIM_MAX96752_GPIO15, "MAX96752_GPIO15"),
137fb0c3269SLuo Wei };
138fb0c3269SLuo Wei 
139fb0c3269SLuo Wei static struct group_desc max96752_groups_desc[] = {
140fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO0),
141fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO1),
142fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO2),
143fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO3),
144fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO4),
145fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO5),
146fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO6),
147fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO7),
148fb0c3269SLuo Wei 
149fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO8),
150fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO9),
151fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO10),
152fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO11),
153fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO12),
154fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO13),
155fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO14),
156fb0c3269SLuo Wei 	GROUP_DESC(MAX96752_GPIO15),
157fb0c3269SLuo Wei };
158fb0c3269SLuo Wei 
159fb0c3269SLuo Wei static struct function_desc max96752_functions_desc[] = {
160fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(0),
161fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(1),
162fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(2),
163fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(3),
164fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(4),
165fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(5),
166fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(6),
167fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(7),
168fb0c3269SLuo Wei 
169fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(8),
170fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(9),
171fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(10),
172fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(11),
173fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(12),
174fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(13),
175fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(14),
176fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_INPUT_BYPASS(15),
177fb0c3269SLuo Wei 
178fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(0),
179fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(1),
180fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(2),
181fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(3),
182fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(4),
183fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(5),
184fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(6),
185fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(7),
186fb0c3269SLuo Wei 
187fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(8),
188fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(9),
189fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(10),
190fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(11),
191fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(12),
192fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(13),
193fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(14),
194fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_BYPASS(15),
195fb0c3269SLuo Wei 
196fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(0),
197fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(1),
198fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(2),
199fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(3),
200fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(4),
201fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(5),
202fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(6),
203fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(7),
204fb0c3269SLuo Wei 
205fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(8),
206fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(9),
207fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(10),
208fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(11),
209fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(12),
210fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(13),
211fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(14),
212fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_LOW(15),
213fb0c3269SLuo Wei 
214fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(0),
215fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(1),
216fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(2),
217fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(3),
218fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(4),
219fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(5),
220fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(6),
221fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(7),
222fb0c3269SLuo Wei 
223fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(8),
224fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(9),
225fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(10),
226fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(11),
227fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(12),
228fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(13),
229fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(14),
230fb0c3269SLuo Wei 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(15),
231fb0c3269SLuo Wei 
232fb0c3269SLuo Wei 	FUNCTION_DES_DELAY_MS(10),
233*c5ff44bcSLuo Wei 	FUNCTION_DES_DELAY_MS(20),
234*c5ff44bcSLuo Wei 	FUNCTION_DES_DELAY_MS(30),
235*c5ff44bcSLuo Wei 	FUNCTION_DES_DELAY_MS(40),
236fb0c3269SLuo Wei 	FUNCTION_DES_DELAY_MS(50),
237fb0c3269SLuo Wei 	FUNCTION_DES_DELAY_MS(100),
238fb0c3269SLuo Wei 	FUNCTION_DES_DELAY_MS(200),
239fb0c3269SLuo Wei 	FUNCTION_DES_DELAY_MS(500),
240fb0c3269SLuo Wei };
241fb0c3269SLuo Wei 
242fb0c3269SLuo Wei static struct serdes_chip_pinctrl_info max96752_pinctrl_info = {
243fb0c3269SLuo Wei 	.pins = max96752_pins_desc,
244fb0c3269SLuo Wei 	.num_pins = ARRAY_SIZE(max96752_pins_desc),
245fb0c3269SLuo Wei 	.groups = max96752_groups_desc,
246fb0c3269SLuo Wei 	.num_groups = ARRAY_SIZE(max96752_groups_desc),
247fb0c3269SLuo Wei 	.functions = max96752_functions_desc,
248fb0c3269SLuo Wei 	.num_functions = ARRAY_SIZE(max96752_functions_desc),
249fb0c3269SLuo Wei };
250fb0c3269SLuo Wei 
max96752_panel_prepare(struct serdes * serdes)251fb0c3269SLuo Wei static int max96752_panel_prepare(struct serdes *serdes)
252a00ee452SLuo Wei {
253a00ee452SLuo Wei 	return 0;
254a00ee452SLuo Wei }
255a00ee452SLuo Wei 
max96752_panel_unprepare(struct serdes * serdes)256fb0c3269SLuo Wei static int max96752_panel_unprepare(struct serdes *serdes)
257fb0c3269SLuo Wei {
258fb0c3269SLuo Wei 	//serdes_reg_write(serdes, 0x0215, 0x80);	/* lcd_en */
259fb0c3269SLuo Wei 
260fb0c3269SLuo Wei 	return 0;
261fb0c3269SLuo Wei }
262fb0c3269SLuo Wei 
max96752_panel_enable(struct serdes * serdes)263fb0c3269SLuo Wei static int max96752_panel_enable(struct serdes *serdes)
264a00ee452SLuo Wei {
265a00ee452SLuo Wei 	return 0;
266a00ee452SLuo Wei }
267a00ee452SLuo Wei 
max96752_panel_disable(struct serdes * serdes)268fb0c3269SLuo Wei static int max96752_panel_disable(struct serdes *serdes)
269a00ee452SLuo Wei {
270a00ee452SLuo Wei 	return 0;
271a00ee452SLuo Wei }
272a00ee452SLuo Wei 
max96752_panel_backlight_enable(struct serdes * serdes)273fb0c3269SLuo Wei static int max96752_panel_backlight_enable(struct serdes *serdes)
274a00ee452SLuo Wei {
275a00ee452SLuo Wei 	return 0;
276a00ee452SLuo Wei }
277a00ee452SLuo Wei 
max96752_panel_backlight_disable(struct serdes * serdes)278fb0c3269SLuo Wei static int max96752_panel_backlight_disable(struct serdes *serdes)
279a00ee452SLuo Wei {
280a00ee452SLuo Wei 	return 0;
281a00ee452SLuo Wei }
282a00ee452SLuo Wei 
283a00ee452SLuo Wei static struct serdes_chip_panel_ops max96752_panel_ops = {
284a00ee452SLuo Wei 	.prepare	= max96752_panel_prepare,
285a00ee452SLuo Wei 	.unprepare	= max96752_panel_unprepare,
286a00ee452SLuo Wei 	.enable		= max96752_panel_enable,
287a00ee452SLuo Wei 	.disable	= max96752_panel_disable,
288a00ee452SLuo Wei 	.backlight_enable	= max96752_panel_backlight_enable,
289a00ee452SLuo Wei 	.backlight_disable	= max96752_panel_backlight_disable,
290a00ee452SLuo Wei };
291a00ee452SLuo Wei 
max96752_pinctrl_set_pin_mux(struct serdes * serdes,unsigned int pin_selector,unsigned int func_selector)292fb0c3269SLuo Wei static int max96752_pinctrl_set_pin_mux(struct serdes *serdes,
293fb0c3269SLuo Wei 					unsigned int pin_selector,
294fb0c3269SLuo Wei 					unsigned int func_selector)
295fb0c3269SLuo Wei {
296fb0c3269SLuo Wei 	struct function_desc *func;
297fb0c3269SLuo Wei 	struct pinctrl_pin_desc *pin;
298fb0c3269SLuo Wei 	int offset;
299fb0c3269SLuo Wei 	u16 ms;
300fb0c3269SLuo Wei 
301fb0c3269SLuo Wei 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
302fb0c3269SLuo Wei 	if (!func) {
303fb0c3269SLuo Wei 		printf("%s: func is null\n", __func__);
304fb0c3269SLuo Wei 		return -EINVAL;
305fb0c3269SLuo Wei 	}
306fb0c3269SLuo Wei 
307fb0c3269SLuo Wei 	pin = &serdes->chip_data->pinctrl_info->pins[pin_selector];
308fb0c3269SLuo Wei 	if (!pin) {
309fb0c3269SLuo Wei 		printf("%s: pin is null\n", __func__);
310fb0c3269SLuo Wei 		return -EINVAL;
311fb0c3269SLuo Wei 	}
312fb0c3269SLuo Wei 
313fb0c3269SLuo Wei 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p pin=%s num=%d\n",
314fb0c3269SLuo Wei 			__func__, serdes->dev->name,
315fb0c3269SLuo Wei 			func->name, func->data,
316fb0c3269SLuo Wei 			pin->name, pin->number);
317fb0c3269SLuo Wei 
318fb0c3269SLuo Wei 	if (func->data) {
319fb0c3269SLuo Wei 		struct serdes_function_data *fdata = func->data;
320fb0c3269SLuo Wei 
321fb0c3269SLuo Wei 		ms = fdata->mdelay;
322fb0c3269SLuo Wei 		offset = pin->number;
323fb0c3269SLuo Wei 		if (offset > 32)
324fb0c3269SLuo Wei 			dev_err(serdes->dev, "%s offset=%d > 32\n",
325fb0c3269SLuo Wei 				serdes->dev->name, offset);
326fb0c3269SLuo Wei 		else
327fb0c3269SLuo Wei 			SERDES_DBG_CHIP("%s: serdes %s txid=%d rxid=%d off=%d\n",
328fb0c3269SLuo Wei 					__func__, serdes->dev->name,
329fb0c3269SLuo Wei 					fdata->gpio_tx_id, fdata->gpio_rx_id, offset);
330fb0c3269SLuo Wei 
331fb0c3269SLuo Wei 		if (!ms) {
332fb0c3269SLuo Wei 			serdes_set_bits(serdes, GPIO_A_REG(offset),
333fb0c3269SLuo Wei 					GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN | GPIO_OUT,
334fb0c3269SLuo Wei 					FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) |
335fb0c3269SLuo Wei 					FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) |
336fb0c3269SLuo Wei 					FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en) |
337fb0c3269SLuo Wei 					FIELD_PREP(GPIO_OUT, fdata->gpio_out_level));
338fb0c3269SLuo Wei 			if (fdata->gpio_tx_en)
339fb0c3269SLuo Wei 				serdes_set_bits(serdes,
340fb0c3269SLuo Wei 						GPIO_B_REG(offset),
341fb0c3269SLuo Wei 						GPIO_TX_ID,
342fb0c3269SLuo Wei 						FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id));
343fb0c3269SLuo Wei 			if (fdata->gpio_rx_en)
344fb0c3269SLuo Wei 				serdes_set_bits(serdes,
345fb0c3269SLuo Wei 						GPIO_C_REG(offset),
346fb0c3269SLuo Wei 						GPIO_RX_ID,
347fb0c3269SLuo Wei 						FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id));
348fb0c3269SLuo Wei 		} else {
349fb0c3269SLuo Wei 			mdelay(ms);
350fb0c3269SLuo Wei 			SERDES_DBG_CHIP("%s: delay %dms\n", __func__, ms);
351fb0c3269SLuo Wei 		}
352fb0c3269SLuo Wei 	}
353fb0c3269SLuo Wei 
354fb0c3269SLuo Wei 	return 0;
355fb0c3269SLuo Wei }
356fb0c3269SLuo Wei 
max96752_pinctrl_set_grp_mux(struct serdes * serdes,unsigned int group_selector,unsigned int func_selector)357fb0c3269SLuo Wei static int max96752_pinctrl_set_grp_mux(struct serdes *serdes,
358fb0c3269SLuo Wei 					unsigned int group_selector,
359fb0c3269SLuo Wei 					unsigned int func_selector)
360fb0c3269SLuo Wei {
361fb0c3269SLuo Wei 	struct serdes_pinctrl *pinctrl = serdes->serdes_pinctrl;
362fb0c3269SLuo Wei 	struct function_desc *func;
363fb0c3269SLuo Wei 	struct group_desc *grp;
364fb0c3269SLuo Wei 	int i, offset;
365fb0c3269SLuo Wei 	u16 ms;
366fb0c3269SLuo Wei 
367fb0c3269SLuo Wei 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
368fb0c3269SLuo Wei 	if (!func) {
369fb0c3269SLuo Wei 		printf("%s: func is null\n", __func__);
370fb0c3269SLuo Wei 		return -EINVAL;
371fb0c3269SLuo Wei 	}
372fb0c3269SLuo Wei 
373fb0c3269SLuo Wei 	grp = &serdes->chip_data->pinctrl_info->groups[group_selector];
374fb0c3269SLuo Wei 	if (!grp) {
375fb0c3269SLuo Wei 		printf("%s: grp is null\n", __func__);
376fb0c3269SLuo Wei 		return -EINVAL;
377fb0c3269SLuo Wei 	}
378fb0c3269SLuo Wei 
379fb0c3269SLuo Wei 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p grp=%s data=%p, num=%d\n",
380fb0c3269SLuo Wei 			__func__, serdes->chip_data->name, func->name,
381fb0c3269SLuo Wei 			func->data, grp->name, grp->data, grp->num_pins);
382fb0c3269SLuo Wei 
383fb0c3269SLuo Wei 	if (func->data) {
384fb0c3269SLuo Wei 		struct serdes_function_data *fdata = func->data;
385fb0c3269SLuo Wei 
386fb0c3269SLuo Wei 		ms = fdata->mdelay;
387fb0c3269SLuo Wei 
388fb0c3269SLuo Wei 		for (i = 0; i < grp->num_pins; i++) {
389fb0c3269SLuo Wei 			offset = grp->pins[i] - pinctrl->pin_base;
390fb0c3269SLuo Wei 			if (offset > 32)
391fb0c3269SLuo Wei 				dev_err(serdes->dev, "%s offset=%d > 32\n",
392fb0c3269SLuo Wei 					serdes->dev->name, offset);
393fb0c3269SLuo Wei 			else
394fb0c3269SLuo Wei 				SERDES_DBG_CHIP("%s: serdes %s txid=%d rxid=%d off=%d\n",
395fb0c3269SLuo Wei 						__func__, serdes->dev->name,
396fb0c3269SLuo Wei 						fdata->gpio_tx_id, fdata->gpio_rx_id, offset);
397fb0c3269SLuo Wei 
398fb0c3269SLuo Wei 			if (!ms) {
399fb0c3269SLuo Wei 				serdes_set_bits(serdes, GPIO_A_REG(offset),
400fb0c3269SLuo Wei 						GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN | GPIO_OUT,
401fb0c3269SLuo Wei 						FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) |
402fb0c3269SLuo Wei 						FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) |
403fb0c3269SLuo Wei 						FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en) |
404fb0c3269SLuo Wei 						FIELD_PREP(GPIO_OUT, fdata->gpio_out_level));
405fb0c3269SLuo Wei 				if (fdata->gpio_tx_en)
406fb0c3269SLuo Wei 					serdes_set_bits(serdes,
407fb0c3269SLuo Wei 							GPIO_B_REG(offset),
408fb0c3269SLuo Wei 							GPIO_TX_ID,
409fb0c3269SLuo Wei 							FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id));
410fb0c3269SLuo Wei 				if (fdata->gpio_rx_en)
411fb0c3269SLuo Wei 					serdes_set_bits(serdes,
412fb0c3269SLuo Wei 							GPIO_C_REG(offset),
413fb0c3269SLuo Wei 							GPIO_RX_ID,
414fb0c3269SLuo Wei 							FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id));
415fb0c3269SLuo Wei 			} else {
416fb0c3269SLuo Wei 				mdelay(ms);
417fb0c3269SLuo Wei 				SERDES_DBG_CHIP("%s: delay %dms\n", __func__, ms);
418fb0c3269SLuo Wei 			}
419fb0c3269SLuo Wei 		}
420fb0c3269SLuo Wei 	}
421fb0c3269SLuo Wei 
422fb0c3269SLuo Wei 	if (grp->data) {
423fb0c3269SLuo Wei 		struct serdes_group_data *gdata = grp->data;
424fb0c3269SLuo Wei 
425fb0c3269SLuo Wei 		for (i = 0; i < gdata->num_configs; i++) {
426fb0c3269SLuo Wei 			const struct config_desc *config = &gdata->configs[i];
427fb0c3269SLuo Wei 
428fb0c3269SLuo Wei 			serdes_set_bits(serdes, config->reg,
429fb0c3269SLuo Wei 					config->mask, config->val);
430fb0c3269SLuo Wei 		}
431fb0c3269SLuo Wei 	}
432fb0c3269SLuo Wei 
433fb0c3269SLuo Wei 	return 0;
434fb0c3269SLuo Wei }
435fb0c3269SLuo Wei 
max96752_pinctrl_config_set(struct serdes * serdes,unsigned int pin_selector,unsigned int param,unsigned int argument)436fb0c3269SLuo Wei static int max96752_pinctrl_config_set(struct serdes *serdes,
437fb0c3269SLuo Wei 				       unsigned int pin_selector,
438fb0c3269SLuo Wei 				       unsigned int param,
439fb0c3269SLuo Wei 				       unsigned int argument)
440fb0c3269SLuo Wei {
441fb0c3269SLuo Wei 	u8 res_cfg;
442fb0c3269SLuo Wei 
443fb0c3269SLuo Wei 	switch (param) {
444fb0c3269SLuo Wei 	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
445fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_B_REG(pin_selector),
446fb0c3269SLuo Wei 				OUT_TYPE, FIELD_PREP(OUT_TYPE, 0));
447fb0c3269SLuo Wei 		break;
448fb0c3269SLuo Wei 	case PIN_CONFIG_DRIVE_PUSH_PULL:
449fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_B_REG(pin_selector),
450fb0c3269SLuo Wei 				OUT_TYPE, FIELD_PREP(OUT_TYPE, 1));
451fb0c3269SLuo Wei 		break;
452fb0c3269SLuo Wei 	case PIN_CONFIG_BIAS_DISABLE:
453fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_C_REG(pin_selector),
454fb0c3269SLuo Wei 				PULL_UPDN_SEL,
455fb0c3269SLuo Wei 				FIELD_PREP(PULL_UPDN_SEL, 0));
456fb0c3269SLuo Wei 		break;
457fb0c3269SLuo Wei 	case PIN_CONFIG_BIAS_PULL_UP:
458fb0c3269SLuo Wei 		switch (argument) {
459fb0c3269SLuo Wei 		case 40000:
460fb0c3269SLuo Wei 			res_cfg = 0;
461fb0c3269SLuo Wei 			break;
462fb0c3269SLuo Wei 		case 1000000:
463fb0c3269SLuo Wei 			res_cfg = 1;
464fb0c3269SLuo Wei 			break;
465fb0c3269SLuo Wei 		default:
466fb0c3269SLuo Wei 			return -EINVAL;
467fb0c3269SLuo Wei 		}
468fb0c3269SLuo Wei 
469fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_A_REG(pin_selector),
470fb0c3269SLuo Wei 				RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
471fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_C_REG(pin_selector),
472fb0c3269SLuo Wei 				PULL_UPDN_SEL,
473fb0c3269SLuo Wei 				FIELD_PREP(PULL_UPDN_SEL, 1));
474fb0c3269SLuo Wei 		break;
475fb0c3269SLuo Wei 	case PIN_CONFIG_BIAS_PULL_DOWN:
476fb0c3269SLuo Wei 		switch (argument) {
477fb0c3269SLuo Wei 		case 40000:
478fb0c3269SLuo Wei 			res_cfg = 0;
479fb0c3269SLuo Wei 			break;
480fb0c3269SLuo Wei 		case 1000000:
481fb0c3269SLuo Wei 			res_cfg = 1;
482fb0c3269SLuo Wei 			break;
483fb0c3269SLuo Wei 		default:
484fb0c3269SLuo Wei 			return -EINVAL;
485fb0c3269SLuo Wei 		}
486fb0c3269SLuo Wei 
487fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_A_REG(pin_selector),
488fb0c3269SLuo Wei 				RES_CFG, FIELD_PREP(RES_CFG, res_cfg));
489fb0c3269SLuo Wei 		serdes_set_bits(serdes, GPIO_C_REG(pin_selector),
490fb0c3269SLuo Wei 				PULL_UPDN_SEL,
491fb0c3269SLuo Wei 				FIELD_PREP(PULL_UPDN_SEL, 2));
492fb0c3269SLuo Wei 		break;
493fb0c3269SLuo Wei 	case PIN_CONFIG_OUTPUT:
494fb0c3269SLuo Wei 			serdes_set_bits(serdes, GPIO_A_REG(pin_selector),
495fb0c3269SLuo Wei 					GPIO_OUT_DIS | GPIO_OUT,
496fb0c3269SLuo Wei 					FIELD_PREP(GPIO_OUT_DIS, 0) |
497fb0c3269SLuo Wei 					FIELD_PREP(GPIO_OUT, argument));
498fb0c3269SLuo Wei 		break;
499fb0c3269SLuo Wei 	default:
500fb0c3269SLuo Wei 		return -EOPNOTSUPP;
501fb0c3269SLuo Wei 	}
502fb0c3269SLuo Wei 
503fb0c3269SLuo Wei 	return 0;
504fb0c3269SLuo Wei }
505fb0c3269SLuo Wei 
506fb0c3269SLuo Wei static struct serdes_chip_pinctrl_ops max96752_pinctrl_ops = {
507fb0c3269SLuo Wei 	.pinconf_set = max96752_pinctrl_config_set,
508fb0c3269SLuo Wei 	.pinmux_set = max96752_pinctrl_set_pin_mux,
509fb0c3269SLuo Wei 	.pinmux_group_set = max96752_pinctrl_set_grp_mux,
510fb0c3269SLuo Wei };
511fb0c3269SLuo Wei 
max96752_gpio_direction_input(struct serdes * serdes,int gpio)512fb0c3269SLuo Wei static int max96752_gpio_direction_input(struct serdes *serdes, int gpio)
513fb0c3269SLuo Wei {
514fb0c3269SLuo Wei 	return 0;
515fb0c3269SLuo Wei }
516fb0c3269SLuo Wei 
max96752_gpio_direction_output(struct serdes * serdes,int gpio,int value)517fb0c3269SLuo Wei static int max96752_gpio_direction_output(struct serdes *serdes,
518fb0c3269SLuo Wei 					  int gpio, int value)
519fb0c3269SLuo Wei {
520fb0c3269SLuo Wei 	return 0;
521fb0c3269SLuo Wei }
522fb0c3269SLuo Wei 
max96752_gpio_get_level(struct serdes * serdes,int gpio)523fb0c3269SLuo Wei static int max96752_gpio_get_level(struct serdes *serdes, int gpio)
524fb0c3269SLuo Wei {
525fb0c3269SLuo Wei 	return 0;
526fb0c3269SLuo Wei }
527fb0c3269SLuo Wei 
max96752_gpio_set_level(struct serdes * serdes,int gpio,int value)528fb0c3269SLuo Wei static int max96752_gpio_set_level(struct serdes *serdes, int gpio, int value)
529fb0c3269SLuo Wei {
530fb0c3269SLuo Wei 	return 0;
531fb0c3269SLuo Wei }
532fb0c3269SLuo Wei 
max96752_gpio_set_config(struct serdes * serdes,int gpio,unsigned long config)533fb0c3269SLuo Wei static int max96752_gpio_set_config(struct serdes *serdes,
534fb0c3269SLuo Wei 				    int gpio, unsigned long config)
535fb0c3269SLuo Wei {
536fb0c3269SLuo Wei 	return 0;
537fb0c3269SLuo Wei }
538fb0c3269SLuo Wei 
max96752_gpio_to_irq(struct serdes * serdes,int gpio)539fb0c3269SLuo Wei static int max96752_gpio_to_irq(struct serdes *serdes, int gpio)
540fb0c3269SLuo Wei {
541fb0c3269SLuo Wei 	return 0;
542fb0c3269SLuo Wei }
543fb0c3269SLuo Wei 
544fb0c3269SLuo Wei static struct serdes_chip_gpio_ops max96752_gpio_ops = {
545fb0c3269SLuo Wei 	.direction_input = max96752_gpio_direction_input,
546fb0c3269SLuo Wei 	.direction_output = max96752_gpio_direction_output,
547fb0c3269SLuo Wei 	.get_level = max96752_gpio_get_level,
548fb0c3269SLuo Wei 	.set_level = max96752_gpio_set_level,
549fb0c3269SLuo Wei 	.set_config = max96752_gpio_set_config,
550fb0c3269SLuo Wei 	.to_irq = max96752_gpio_to_irq,
551fb0c3269SLuo Wei };
552fb0c3269SLuo Wei 
max96752_set_i2c_addr(struct serdes * serdes,int address,int link)553fb0c3269SLuo Wei static int max96752_set_i2c_addr(struct serdes *serdes, int address, int link)
554fb0c3269SLuo Wei {
555fb0c3269SLuo Wei 	int ret;
556fb0c3269SLuo Wei 
557fb0c3269SLuo Wei 	if (link == LINKA) {
558fb0c3269SLuo Wei 		/* TX_SRC_ID[1] = 0 */
559fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x73, 0x31);
560fb0c3269SLuo Wei 		/* Receive packets with this stream ID = 0 */
561fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x50, 0x00);
562fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x00, address << 1);
563fb0c3269SLuo Wei 	} else if (link == LINKB) {
564fb0c3269SLuo Wei 		/* TX_SRC_ID[1] = 1 */
565fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x73, 0x32);
566fb0c3269SLuo Wei 		/* Receive packets with this stream ID = 1 */
567fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x50, 0x01);
568fb0c3269SLuo Wei 		ret = serdes_reg_write(serdes, 0x00, address << 1);
569fb0c3269SLuo Wei 	} else {
570fb0c3269SLuo Wei 		dev_info(serdes->dev, "link %d is error\n", link);
571fb0c3269SLuo Wei 		ret = -1;
572fb0c3269SLuo Wei 	}
573fb0c3269SLuo Wei 
574fb0c3269SLuo Wei 	SERDES_DBG_CHIP("%s: set serdes chip %s i2c 7bit address to 0x%x\n", __func__,
575fb0c3269SLuo Wei 			serdes->chip_data->name, address);
576fb0c3269SLuo Wei 
577fb0c3269SLuo Wei 	return ret;
578fb0c3269SLuo Wei }
579fb0c3269SLuo Wei 
580fb0c3269SLuo Wei static struct serdes_chip_split_ops max96752_split_ops = {
581fb0c3269SLuo Wei 	.set_i2c_addr = max96752_set_i2c_addr,
582fb0c3269SLuo Wei };
583fb0c3269SLuo Wei 
584a00ee452SLuo Wei struct serdes_chip_data serdes_max96752_data = {
585a00ee452SLuo Wei 	.name		= "max96752",
586a00ee452SLuo Wei 	.serdes_type	= TYPE_DES,
587a00ee452SLuo Wei 	.serdes_id	= MAXIM_ID_MAX96752,
588fb0c3269SLuo Wei 	.connector_type	= DRM_MODE_CONNECTOR_LVDS,
589fb0c3269SLuo Wei 	.pinctrl_info	= &max96752_pinctrl_info,
590a00ee452SLuo Wei 	.panel_ops	= &max96752_panel_ops,
591fb0c3269SLuo Wei 	.pinctrl_ops	= &max96752_pinctrl_ops,
592fb0c3269SLuo Wei 	.split_ops	= &max96752_split_ops,
593fb0c3269SLuo Wei 	.gpio_ops	= &max96752_gpio_ops,
594a00ee452SLuo Wei };
595a00ee452SLuo Wei EXPORT_SYMBOL_GPL(serdes_max96752_data);
596fb0c3269SLuo Wei 
597fb0c3269SLuo Wei MODULE_LICENSE("GPL");
598