xref: /dflybsd-src/sys/dev/drm/amd/display/dc/gpio/gpio_base.c (revision b843c749addef9340ee7d4e250b09fdd492602a1)
1*b843c749SSergey Zigachev /*
2*b843c749SSergey Zigachev  * Copyright 2012-15 Advanced Micro Devices, Inc.
3*b843c749SSergey Zigachev  *
4*b843c749SSergey Zigachev  * Permission is hereby granted, free of charge, to any person obtaining a
5*b843c749SSergey Zigachev  * copy of this software and associated documentation files (the "Software"),
6*b843c749SSergey Zigachev  * to deal in the Software without restriction, including without limitation
7*b843c749SSergey Zigachev  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*b843c749SSergey Zigachev  * and/or sell copies of the Software, and to permit persons to whom the
9*b843c749SSergey Zigachev  * Software is furnished to do so, subject to the following conditions:
10*b843c749SSergey Zigachev  *
11*b843c749SSergey Zigachev  * The above copyright notice and this permission notice shall be included in
12*b843c749SSergey Zigachev  * all copies or substantial portions of the Software.
13*b843c749SSergey Zigachev  *
14*b843c749SSergey Zigachev  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*b843c749SSergey Zigachev  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*b843c749SSergey Zigachev  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*b843c749SSergey Zigachev  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*b843c749SSergey Zigachev  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*b843c749SSergey Zigachev  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*b843c749SSergey Zigachev  * OTHER DEALINGS IN THE SOFTWARE.
21*b843c749SSergey Zigachev  *
22*b843c749SSergey Zigachev  * Authors: AMD
23*b843c749SSergey Zigachev  *
24*b843c749SSergey Zigachev  */
25*b843c749SSergey Zigachev 
26*b843c749SSergey Zigachev /*
27*b843c749SSergey Zigachev  * Pre-requisites: headers required by header of this unit
28*b843c749SSergey Zigachev  */
29*b843c749SSergey Zigachev 
30*b843c749SSergey Zigachev #include "dm_services.h"
31*b843c749SSergey Zigachev 
32*b843c749SSergey Zigachev #include "include/gpio_interface.h"
33*b843c749SSergey Zigachev #include "include/gpio_service_interface.h"
34*b843c749SSergey Zigachev #include "hw_gpio.h"
35*b843c749SSergey Zigachev #include "hw_translate.h"
36*b843c749SSergey Zigachev #include "hw_factory.h"
37*b843c749SSergey Zigachev #include "gpio_service.h"
38*b843c749SSergey Zigachev 
39*b843c749SSergey Zigachev /*
40*b843c749SSergey Zigachev  * Post-requisites: headers required by this unit
41*b843c749SSergey Zigachev  */
42*b843c749SSergey Zigachev 
43*b843c749SSergey Zigachev /*
44*b843c749SSergey Zigachev  * This unit
45*b843c749SSergey Zigachev  */
46*b843c749SSergey Zigachev 
47*b843c749SSergey Zigachev /*
48*b843c749SSergey Zigachev  * @brief
49*b843c749SSergey Zigachev  * Public API
50*b843c749SSergey Zigachev  */
51*b843c749SSergey Zigachev 
dal_gpio_open(struct gpio * gpio,enum gpio_mode mode)52*b843c749SSergey Zigachev enum gpio_result dal_gpio_open(
53*b843c749SSergey Zigachev 	struct gpio *gpio,
54*b843c749SSergey Zigachev 	enum gpio_mode mode)
55*b843c749SSergey Zigachev {
56*b843c749SSergey Zigachev 	return dal_gpio_open_ex(gpio, mode);
57*b843c749SSergey Zigachev }
58*b843c749SSergey Zigachev 
dal_gpio_open_ex(struct gpio * gpio,enum gpio_mode mode)59*b843c749SSergey Zigachev enum gpio_result dal_gpio_open_ex(
60*b843c749SSergey Zigachev 	struct gpio *gpio,
61*b843c749SSergey Zigachev 	enum gpio_mode mode)
62*b843c749SSergey Zigachev {
63*b843c749SSergey Zigachev 	if (gpio->pin) {
64*b843c749SSergey Zigachev 		ASSERT_CRITICAL(false);
65*b843c749SSergey Zigachev 		return GPIO_RESULT_ALREADY_OPENED;
66*b843c749SSergey Zigachev 	}
67*b843c749SSergey Zigachev 
68*b843c749SSergey Zigachev 	gpio->mode = mode;
69*b843c749SSergey Zigachev 
70*b843c749SSergey Zigachev 	return dal_gpio_service_open(
71*b843c749SSergey Zigachev 		gpio->service, gpio->id, gpio->en, mode, &gpio->pin);
72*b843c749SSergey Zigachev }
73*b843c749SSergey Zigachev 
dal_gpio_get_value(const struct gpio * gpio,uint32_t * value)74*b843c749SSergey Zigachev enum gpio_result dal_gpio_get_value(
75*b843c749SSergey Zigachev 	const struct gpio *gpio,
76*b843c749SSergey Zigachev 	uint32_t *value)
77*b843c749SSergey Zigachev {
78*b843c749SSergey Zigachev 	if (!gpio->pin) {
79*b843c749SSergey Zigachev 		BREAK_TO_DEBUGGER();
80*b843c749SSergey Zigachev 		return GPIO_RESULT_NULL_HANDLE;
81*b843c749SSergey Zigachev 	}
82*b843c749SSergey Zigachev 
83*b843c749SSergey Zigachev 	return gpio->pin->funcs->get_value(gpio->pin, value);
84*b843c749SSergey Zigachev }
85*b843c749SSergey Zigachev 
dal_gpio_set_value(const struct gpio * gpio,uint32_t value)86*b843c749SSergey Zigachev enum gpio_result dal_gpio_set_value(
87*b843c749SSergey Zigachev 	const struct gpio *gpio,
88*b843c749SSergey Zigachev 	uint32_t value)
89*b843c749SSergey Zigachev {
90*b843c749SSergey Zigachev 	if (!gpio->pin) {
91*b843c749SSergey Zigachev 		BREAK_TO_DEBUGGER();
92*b843c749SSergey Zigachev 		return GPIO_RESULT_NULL_HANDLE;
93*b843c749SSergey Zigachev 	}
94*b843c749SSergey Zigachev 
95*b843c749SSergey Zigachev 	return gpio->pin->funcs->set_value(gpio->pin, value);
96*b843c749SSergey Zigachev }
97*b843c749SSergey Zigachev 
dal_gpio_get_mode(const struct gpio * gpio)98*b843c749SSergey Zigachev enum gpio_mode dal_gpio_get_mode(
99*b843c749SSergey Zigachev 	const struct gpio *gpio)
100*b843c749SSergey Zigachev {
101*b843c749SSergey Zigachev 	return gpio->mode;
102*b843c749SSergey Zigachev }
103*b843c749SSergey Zigachev 
dal_gpio_change_mode(struct gpio * gpio,enum gpio_mode mode)104*b843c749SSergey Zigachev enum gpio_result dal_gpio_change_mode(
105*b843c749SSergey Zigachev 	struct gpio *gpio,
106*b843c749SSergey Zigachev 	enum gpio_mode mode)
107*b843c749SSergey Zigachev {
108*b843c749SSergey Zigachev 	if (!gpio->pin) {
109*b843c749SSergey Zigachev 		BREAK_TO_DEBUGGER();
110*b843c749SSergey Zigachev 		return GPIO_RESULT_NULL_HANDLE;
111*b843c749SSergey Zigachev 	}
112*b843c749SSergey Zigachev 
113*b843c749SSergey Zigachev 	return gpio->pin->funcs->change_mode(gpio->pin, mode);
114*b843c749SSergey Zigachev }
115*b843c749SSergey Zigachev 
dal_gpio_get_id(const struct gpio * gpio)116*b843c749SSergey Zigachev enum gpio_id dal_gpio_get_id(
117*b843c749SSergey Zigachev 	const struct gpio *gpio)
118*b843c749SSergey Zigachev {
119*b843c749SSergey Zigachev 	return gpio->id;
120*b843c749SSergey Zigachev }
121*b843c749SSergey Zigachev 
dal_gpio_get_enum(const struct gpio * gpio)122*b843c749SSergey Zigachev uint32_t dal_gpio_get_enum(
123*b843c749SSergey Zigachev 	const struct gpio *gpio)
124*b843c749SSergey Zigachev {
125*b843c749SSergey Zigachev 	return gpio->en;
126*b843c749SSergey Zigachev }
127*b843c749SSergey Zigachev 
dal_gpio_set_config(struct gpio * gpio,const struct gpio_config_data * config_data)128*b843c749SSergey Zigachev enum gpio_result dal_gpio_set_config(
129*b843c749SSergey Zigachev 	struct gpio *gpio,
130*b843c749SSergey Zigachev 	const struct gpio_config_data *config_data)
131*b843c749SSergey Zigachev {
132*b843c749SSergey Zigachev 	if (!gpio->pin) {
133*b843c749SSergey Zigachev 		BREAK_TO_DEBUGGER();
134*b843c749SSergey Zigachev 		return GPIO_RESULT_NULL_HANDLE;
135*b843c749SSergey Zigachev 	}
136*b843c749SSergey Zigachev 
137*b843c749SSergey Zigachev 	return gpio->pin->funcs->set_config(gpio->pin, config_data);
138*b843c749SSergey Zigachev }
139*b843c749SSergey Zigachev 
dal_gpio_get_pin_info(const struct gpio * gpio,struct gpio_pin_info * pin_info)140*b843c749SSergey Zigachev enum gpio_result dal_gpio_get_pin_info(
141*b843c749SSergey Zigachev 	const struct gpio *gpio,
142*b843c749SSergey Zigachev 	struct gpio_pin_info *pin_info)
143*b843c749SSergey Zigachev {
144*b843c749SSergey Zigachev 	return gpio->service->translate.funcs->id_to_offset(
145*b843c749SSergey Zigachev 		gpio->id, gpio->en, pin_info) ?
146*b843c749SSergey Zigachev 		GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
147*b843c749SSergey Zigachev }
148*b843c749SSergey Zigachev 
dal_gpio_get_sync_source(const struct gpio * gpio)149*b843c749SSergey Zigachev enum sync_source dal_gpio_get_sync_source(
150*b843c749SSergey Zigachev 	const struct gpio *gpio)
151*b843c749SSergey Zigachev {
152*b843c749SSergey Zigachev 	switch (gpio->id) {
153*b843c749SSergey Zigachev 	case GPIO_ID_GENERIC:
154*b843c749SSergey Zigachev 		switch (gpio->en) {
155*b843c749SSergey Zigachev 		case GPIO_GENERIC_A:
156*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_A;
157*b843c749SSergey Zigachev 		case GPIO_GENERIC_B:
158*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_B;
159*b843c749SSergey Zigachev 		case GPIO_GENERIC_C:
160*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_C;
161*b843c749SSergey Zigachev 		case GPIO_GENERIC_D:
162*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_D;
163*b843c749SSergey Zigachev 		case GPIO_GENERIC_E:
164*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_E;
165*b843c749SSergey Zigachev 		case GPIO_GENERIC_F:
166*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_GENERIC_F;
167*b843c749SSergey Zigachev 		default:
168*b843c749SSergey Zigachev 			return SYNC_SOURCE_NONE;
169*b843c749SSergey Zigachev 		}
170*b843c749SSergey Zigachev 	break;
171*b843c749SSergey Zigachev 	case GPIO_ID_SYNC:
172*b843c749SSergey Zigachev 		switch (gpio->en) {
173*b843c749SSergey Zigachev 		case GPIO_SYNC_HSYNC_A:
174*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_HSYNC_A;
175*b843c749SSergey Zigachev 		case GPIO_SYNC_VSYNC_A:
176*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_VSYNC_A;
177*b843c749SSergey Zigachev 		case GPIO_SYNC_HSYNC_B:
178*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_HSYNC_B;
179*b843c749SSergey Zigachev 		case GPIO_SYNC_VSYNC_B:
180*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_VSYNC_B;
181*b843c749SSergey Zigachev 		default:
182*b843c749SSergey Zigachev 			return SYNC_SOURCE_NONE;
183*b843c749SSergey Zigachev 		}
184*b843c749SSergey Zigachev 	break;
185*b843c749SSergey Zigachev 	case GPIO_ID_HPD:
186*b843c749SSergey Zigachev 		switch (gpio->en) {
187*b843c749SSergey Zigachev 		case GPIO_HPD_1:
188*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_HPD1;
189*b843c749SSergey Zigachev 		case GPIO_HPD_2:
190*b843c749SSergey Zigachev 			return SYNC_SOURCE_IO_HPD2;
191*b843c749SSergey Zigachev 		default:
192*b843c749SSergey Zigachev 			return SYNC_SOURCE_NONE;
193*b843c749SSergey Zigachev 		}
194*b843c749SSergey Zigachev 	break;
195*b843c749SSergey Zigachev 	case GPIO_ID_GSL:
196*b843c749SSergey Zigachev 		switch (gpio->en) {
197*b843c749SSergey Zigachev 		case GPIO_GSL_GENLOCK_CLOCK:
198*b843c749SSergey Zigachev 			return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
199*b843c749SSergey Zigachev 		case GPIO_GSL_GENLOCK_VSYNC:
200*b843c749SSergey Zigachev 			return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
201*b843c749SSergey Zigachev 		case GPIO_GSL_SWAPLOCK_A:
202*b843c749SSergey Zigachev 			return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
203*b843c749SSergey Zigachev 		case GPIO_GSL_SWAPLOCK_B:
204*b843c749SSergey Zigachev 			return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
205*b843c749SSergey Zigachev 		default:
206*b843c749SSergey Zigachev 			return SYNC_SOURCE_NONE;
207*b843c749SSergey Zigachev 		}
208*b843c749SSergey Zigachev 	break;
209*b843c749SSergey Zigachev 	default:
210*b843c749SSergey Zigachev 		return SYNC_SOURCE_NONE;
211*b843c749SSergey Zigachev 	}
212*b843c749SSergey Zigachev }
213*b843c749SSergey Zigachev 
dal_gpio_get_output_state(const struct gpio * gpio)214*b843c749SSergey Zigachev enum gpio_pin_output_state dal_gpio_get_output_state(
215*b843c749SSergey Zigachev 	const struct gpio *gpio)
216*b843c749SSergey Zigachev {
217*b843c749SSergey Zigachev 	return gpio->output_state;
218*b843c749SSergey Zigachev }
219*b843c749SSergey Zigachev 
dal_gpio_close(struct gpio * gpio)220*b843c749SSergey Zigachev void dal_gpio_close(
221*b843c749SSergey Zigachev 	struct gpio *gpio)
222*b843c749SSergey Zigachev {
223*b843c749SSergey Zigachev 	if (!gpio)
224*b843c749SSergey Zigachev 		return;
225*b843c749SSergey Zigachev 
226*b843c749SSergey Zigachev 	dal_gpio_service_close(gpio->service, &gpio->pin);
227*b843c749SSergey Zigachev 
228*b843c749SSergey Zigachev 	gpio->mode = GPIO_MODE_UNKNOWN;
229*b843c749SSergey Zigachev }
230*b843c749SSergey Zigachev 
231*b843c749SSergey Zigachev /*
232*b843c749SSergey Zigachev  * @brief
233*b843c749SSergey Zigachev  * Creation and destruction
234*b843c749SSergey Zigachev  */
235*b843c749SSergey Zigachev 
dal_gpio_create(struct gpio_service * service,enum gpio_id id,uint32_t en,enum gpio_pin_output_state output_state)236*b843c749SSergey Zigachev struct gpio *dal_gpio_create(
237*b843c749SSergey Zigachev 	struct gpio_service *service,
238*b843c749SSergey Zigachev 	enum gpio_id id,
239*b843c749SSergey Zigachev 	uint32_t en,
240*b843c749SSergey Zigachev 	enum gpio_pin_output_state output_state)
241*b843c749SSergey Zigachev {
242*b843c749SSergey Zigachev 	struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
243*b843c749SSergey Zigachev 
244*b843c749SSergey Zigachev 	if (!gpio) {
245*b843c749SSergey Zigachev 		ASSERT_CRITICAL(false);
246*b843c749SSergey Zigachev 		return NULL;
247*b843c749SSergey Zigachev 	}
248*b843c749SSergey Zigachev 
249*b843c749SSergey Zigachev 	gpio->service = service;
250*b843c749SSergey Zigachev 	gpio->pin = NULL;
251*b843c749SSergey Zigachev 	gpio->id = id;
252*b843c749SSergey Zigachev 	gpio->en = en;
253*b843c749SSergey Zigachev 	gpio->mode = GPIO_MODE_UNKNOWN;
254*b843c749SSergey Zigachev 	gpio->output_state = output_state;
255*b843c749SSergey Zigachev 
256*b843c749SSergey Zigachev 	return gpio;
257*b843c749SSergey Zigachev }
258*b843c749SSergey Zigachev 
dal_gpio_destroy(struct gpio ** gpio)259*b843c749SSergey Zigachev void dal_gpio_destroy(
260*b843c749SSergey Zigachev 	struct gpio **gpio)
261*b843c749SSergey Zigachev {
262*b843c749SSergey Zigachev 	if (!gpio || !*gpio) {
263*b843c749SSergey Zigachev 		ASSERT_CRITICAL(false);
264*b843c749SSergey Zigachev 		return;
265*b843c749SSergey Zigachev 	}
266*b843c749SSergey Zigachev 
267*b843c749SSergey Zigachev 	dal_gpio_close(*gpio);
268*b843c749SSergey Zigachev 
269*b843c749SSergey Zigachev 	kfree(*gpio);
270*b843c749SSergey Zigachev 
271*b843c749SSergey Zigachev 	*gpio = NULL;
272*b843c749SSergey Zigachev }
273