]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c
net: wan: Add framer framework support
[linux.git] / drivers / gpu / drm / amd / display / dc / gpio / gpio_base.c
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 /*
27  * Pre-requisites: headers required by header of this unit
28  */
29
30 #include "dm_services.h"
31
32 #include "include/gpio_interface.h"
33 #include "include/gpio_service_interface.h"
34 #include "hw_gpio.h"
35 #include "hw_translate.h"
36 #include "hw_factory.h"
37 #include "gpio_service.h"
38
39 /*
40  * Post-requisites: headers required by this unit
41  */
42
43 /*
44  * This unit
45  */
46
47 /*
48  * @brief
49  * Public API
50  */
51
52 enum gpio_result dal_gpio_open(
53         struct gpio *gpio,
54         enum gpio_mode mode)
55 {
56         return dal_gpio_open_ex(gpio, mode);
57 }
58
59 enum gpio_result dal_gpio_open_ex(
60         struct gpio *gpio,
61         enum gpio_mode mode)
62 {
63         if (gpio->pin) {
64                 BREAK_TO_DEBUGGER();
65                 return GPIO_RESULT_ALREADY_OPENED;
66         }
67
68         // No action if allocation failed during gpio construct
69         if (!gpio->hw_container.ddc) {
70                 BREAK_TO_DEBUGGER();
71                 return GPIO_RESULT_NON_SPECIFIC_ERROR;
72         }
73         gpio->mode = mode;
74
75         return dal_gpio_service_open(gpio);
76 }
77
78 enum gpio_result dal_gpio_get_value(
79         const struct gpio *gpio,
80         uint32_t *value)
81 {
82         if (!gpio->pin) {
83                 BREAK_TO_DEBUGGER();
84                 return GPIO_RESULT_NULL_HANDLE;
85         }
86
87         return gpio->pin->funcs->get_value(gpio->pin, value);
88 }
89
90 enum gpio_result dal_gpio_set_value(
91         const struct gpio *gpio,
92         uint32_t value)
93 {
94         if (!gpio->pin) {
95                 BREAK_TO_DEBUGGER();
96                 return GPIO_RESULT_NULL_HANDLE;
97         }
98
99         return gpio->pin->funcs->set_value(gpio->pin, value);
100 }
101
102 enum gpio_mode dal_gpio_get_mode(
103         const struct gpio *gpio)
104 {
105         return gpio->mode;
106 }
107
108 enum gpio_result dal_gpio_lock_pin(
109         struct gpio *gpio)
110 {
111         return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
112 }
113
114 enum gpio_result dal_gpio_unlock_pin(
115         struct gpio *gpio)
116 {
117         return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
118 }
119
120 enum gpio_result dal_gpio_change_mode(
121         struct gpio *gpio,
122         enum gpio_mode mode)
123 {
124         if (!gpio->pin) {
125                 BREAK_TO_DEBUGGER();
126                 return GPIO_RESULT_NULL_HANDLE;
127         }
128
129         return gpio->pin->funcs->change_mode(gpio->pin, mode);
130 }
131
132 enum gpio_id dal_gpio_get_id(
133         const struct gpio *gpio)
134 {
135         return gpio->id;
136 }
137
138 uint32_t dal_gpio_get_enum(
139         const struct gpio *gpio)
140 {
141         return gpio->en;
142 }
143
144 enum gpio_result dal_gpio_set_config(
145         struct gpio *gpio,
146         const struct gpio_config_data *config_data)
147 {
148         if (!gpio->pin) {
149                 BREAK_TO_DEBUGGER();
150                 return GPIO_RESULT_NULL_HANDLE;
151         }
152
153         return gpio->pin->funcs->set_config(gpio->pin, config_data);
154 }
155
156 enum gpio_result dal_gpio_get_pin_info(
157         const struct gpio *gpio,
158         struct gpio_pin_info *pin_info)
159 {
160         return gpio->service->translate.funcs->id_to_offset(
161                 gpio->id, gpio->en, pin_info) ?
162                 GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
163 }
164
165 enum sync_source dal_gpio_get_sync_source(
166         const struct gpio *gpio)
167 {
168         switch (gpio->id) {
169         case GPIO_ID_GENERIC:
170                 switch (gpio->en) {
171                 case GPIO_GENERIC_A:
172                         return SYNC_SOURCE_IO_GENERIC_A;
173                 case GPIO_GENERIC_B:
174                         return SYNC_SOURCE_IO_GENERIC_B;
175                 case GPIO_GENERIC_C:
176                         return SYNC_SOURCE_IO_GENERIC_C;
177                 case GPIO_GENERIC_D:
178                         return SYNC_SOURCE_IO_GENERIC_D;
179                 case GPIO_GENERIC_E:
180                         return SYNC_SOURCE_IO_GENERIC_E;
181                 case GPIO_GENERIC_F:
182                         return SYNC_SOURCE_IO_GENERIC_F;
183                 default:
184                         return SYNC_SOURCE_NONE;
185                 }
186         break;
187         case GPIO_ID_SYNC:
188                 switch (gpio->en) {
189                 case GPIO_SYNC_HSYNC_A:
190                         return SYNC_SOURCE_IO_HSYNC_A;
191                 case GPIO_SYNC_VSYNC_A:
192                         return SYNC_SOURCE_IO_VSYNC_A;
193                 case GPIO_SYNC_HSYNC_B:
194                         return SYNC_SOURCE_IO_HSYNC_B;
195                 case GPIO_SYNC_VSYNC_B:
196                         return SYNC_SOURCE_IO_VSYNC_B;
197                 default:
198                         return SYNC_SOURCE_NONE;
199                 }
200         break;
201         case GPIO_ID_HPD:
202                 switch (gpio->en) {
203                 case GPIO_HPD_1:
204                         return SYNC_SOURCE_IO_HPD1;
205                 case GPIO_HPD_2:
206                         return SYNC_SOURCE_IO_HPD2;
207                 default:
208                         return SYNC_SOURCE_NONE;
209                 }
210         break;
211         case GPIO_ID_GSL:
212                 switch (gpio->en) {
213                 case GPIO_GSL_GENLOCK_CLOCK:
214                         return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
215                 case GPIO_GSL_GENLOCK_VSYNC:
216                         return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
217                 case GPIO_GSL_SWAPLOCK_A:
218                         return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
219                 case GPIO_GSL_SWAPLOCK_B:
220                         return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
221                 default:
222                         return SYNC_SOURCE_NONE;
223                 }
224         break;
225         default:
226                 return SYNC_SOURCE_NONE;
227         }
228 }
229
230 enum gpio_pin_output_state dal_gpio_get_output_state(
231         const struct gpio *gpio)
232 {
233         return gpio->output_state;
234 }
235
236 struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)
237 {
238         return gpio->hw_container.ddc;
239 }
240
241 struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)
242 {
243         return gpio->hw_container.hpd;
244 }
245
246 struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)
247 {
248         return gpio->hw_container.generic;
249 }
250
251 void dal_gpio_close(
252         struct gpio *gpio)
253 {
254         if (!gpio)
255                 return;
256
257         dal_gpio_service_close(gpio->service, &gpio->pin);
258
259         gpio->mode = GPIO_MODE_UNKNOWN;
260 }
261
262 /*
263  * @brief
264  * Creation and destruction
265  */
266
267 struct gpio *dal_gpio_create(
268         struct gpio_service *service,
269         enum gpio_id id,
270         uint32_t en,
271         enum gpio_pin_output_state output_state)
272 {
273         struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
274
275         if (!gpio) {
276                 ASSERT_CRITICAL(false);
277                 return NULL;
278         }
279
280         gpio->service = service;
281         gpio->pin = NULL;
282         gpio->id = id;
283         gpio->en = en;
284         gpio->mode = GPIO_MODE_UNKNOWN;
285         gpio->output_state = output_state;
286
287         //initialize hw_container union based on id
288         switch (gpio->id) {
289         case GPIO_ID_DDC_DATA:
290                 gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
291                 break;
292         case GPIO_ID_DDC_CLOCK:
293                 gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
294                 break;
295         case GPIO_ID_GENERIC:
296                 gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);
297                 break;
298         case GPIO_ID_HPD:
299                 gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);
300                 break;
301         // TODO: currently gpio for sync and gsl does not get created, might need it later
302         case GPIO_ID_SYNC:
303                 break;
304         case GPIO_ID_GSL:
305                 break;
306         default:
307                 ASSERT_CRITICAL(false);
308                 gpio->pin = NULL;
309         }
310
311         return gpio;
312 }
313
314 void dal_gpio_destroy(
315         struct gpio **gpio)
316 {
317         if (!gpio || !*gpio) {
318                 ASSERT_CRITICAL(false);
319                 return;
320         }
321
322         switch ((*gpio)->id) {
323         case GPIO_ID_DDC_DATA:
324                 kfree((*gpio)->hw_container.ddc);
325                 (*gpio)->hw_container.ddc = NULL;
326                 break;
327         case GPIO_ID_DDC_CLOCK:
328                 //TODO: might want to change it to init_ddc_clock
329                 kfree((*gpio)->hw_container.ddc);
330                 (*gpio)->hw_container.ddc = NULL;
331                 break;
332         case GPIO_ID_GENERIC:
333                 kfree((*gpio)->hw_container.generic);
334                 (*gpio)->hw_container.generic = NULL;
335                 break;
336         case GPIO_ID_HPD:
337                 kfree((*gpio)->hw_container.hpd);
338                 (*gpio)->hw_container.hpd = NULL;
339                 break;
340         // TODO: currently gpio for sync and gsl does not get created, might need it later
341         case GPIO_ID_SYNC:
342                 break;
343         case GPIO_ID_GSL:
344                 break;
345         default:
346                 break;
347         }
348
349         kfree(*gpio);
350
351         *gpio = NULL;
352 }
This page took 0.054223 seconds and 4 git commands to generate.