Line data Source code
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 0 : enum gpio_result dal_gpio_open(
53 : struct gpio *gpio,
54 : enum gpio_mode mode)
55 : {
56 0 : return dal_gpio_open_ex(gpio, mode);
57 : }
58 :
59 0 : enum gpio_result dal_gpio_open_ex(
60 : struct gpio *gpio,
61 : enum gpio_mode mode)
62 : {
63 0 : if (gpio->pin) {
64 0 : BREAK_TO_DEBUGGER();
65 0 : return GPIO_RESULT_ALREADY_OPENED;
66 : }
67 :
68 : // No action if allocation failed during gpio construct
69 0 : if (!gpio->hw_container.ddc) {
70 0 : BREAK_TO_DEBUGGER();
71 0 : return GPIO_RESULT_NON_SPECIFIC_ERROR;
72 : }
73 0 : gpio->mode = mode;
74 :
75 0 : return dal_gpio_service_open(gpio);
76 : }
77 :
78 0 : enum gpio_result dal_gpio_get_value(
79 : const struct gpio *gpio,
80 : uint32_t *value)
81 : {
82 0 : if (!gpio->pin) {
83 0 : BREAK_TO_DEBUGGER();
84 0 : return GPIO_RESULT_NULL_HANDLE;
85 : }
86 :
87 0 : return gpio->pin->funcs->get_value(gpio->pin, value);
88 : }
89 :
90 0 : enum gpio_result dal_gpio_set_value(
91 : const struct gpio *gpio,
92 : uint32_t value)
93 : {
94 0 : if (!gpio->pin) {
95 0 : BREAK_TO_DEBUGGER();
96 0 : return GPIO_RESULT_NULL_HANDLE;
97 : }
98 :
99 0 : return gpio->pin->funcs->set_value(gpio->pin, value);
100 : }
101 :
102 0 : enum gpio_mode dal_gpio_get_mode(
103 : const struct gpio *gpio)
104 : {
105 0 : return gpio->mode;
106 : }
107 :
108 0 : enum gpio_result dal_gpio_lock_pin(
109 : struct gpio *gpio)
110 : {
111 0 : return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
112 : }
113 :
114 0 : enum gpio_result dal_gpio_unlock_pin(
115 : struct gpio *gpio)
116 : {
117 0 : return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
118 : }
119 :
120 0 : enum gpio_result dal_gpio_change_mode(
121 : struct gpio *gpio,
122 : enum gpio_mode mode)
123 : {
124 0 : if (!gpio->pin) {
125 0 : BREAK_TO_DEBUGGER();
126 0 : return GPIO_RESULT_NULL_HANDLE;
127 : }
128 :
129 0 : return gpio->pin->funcs->change_mode(gpio->pin, mode);
130 : }
131 :
132 0 : enum gpio_id dal_gpio_get_id(
133 : const struct gpio *gpio)
134 : {
135 0 : return gpio->id;
136 : }
137 :
138 0 : uint32_t dal_gpio_get_enum(
139 : const struct gpio *gpio)
140 : {
141 0 : return gpio->en;
142 : }
143 :
144 0 : enum gpio_result dal_gpio_set_config(
145 : struct gpio *gpio,
146 : const struct gpio_config_data *config_data)
147 : {
148 0 : if (!gpio->pin) {
149 0 : BREAK_TO_DEBUGGER();
150 0 : return GPIO_RESULT_NULL_HANDLE;
151 : }
152 :
153 0 : return gpio->pin->funcs->set_config(gpio->pin, config_data);
154 : }
155 :
156 0 : enum gpio_result dal_gpio_get_pin_info(
157 : const struct gpio *gpio,
158 : struct gpio_pin_info *pin_info)
159 : {
160 0 : return gpio->service->translate.funcs->id_to_offset(
161 : gpio->id, gpio->en, pin_info) ?
162 0 : GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
163 : }
164 :
165 0 : enum sync_source dal_gpio_get_sync_source(
166 : const struct gpio *gpio)
167 : {
168 0 : switch (gpio->id) {
169 : case GPIO_ID_GENERIC:
170 0 : 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 0 : 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 0 : switch (gpio->en) {
203 : case GPIO_HPD_1:
204 : return SYNC_SOURCE_IO_HPD1;
205 : case GPIO_HPD_2:
206 0 : return SYNC_SOURCE_IO_HPD2;
207 : default:
208 0 : return SYNC_SOURCE_NONE;
209 : }
210 : break;
211 : case GPIO_ID_GSL:
212 0 : 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 0 : enum gpio_pin_output_state dal_gpio_get_output_state(
231 : const struct gpio *gpio)
232 : {
233 0 : return gpio->output_state;
234 : }
235 :
236 0 : struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)
237 : {
238 0 : return gpio->hw_container.ddc;
239 : }
240 :
241 0 : struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)
242 : {
243 0 : return gpio->hw_container.hpd;
244 : }
245 :
246 0 : struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)
247 : {
248 0 : return gpio->hw_container.generic;
249 : }
250 :
251 0 : void dal_gpio_close(
252 : struct gpio *gpio)
253 : {
254 0 : if (!gpio)
255 : return;
256 :
257 0 : dal_gpio_service_close(gpio->service, &gpio->pin);
258 :
259 0 : gpio->mode = GPIO_MODE_UNKNOWN;
260 : }
261 :
262 : /*
263 : * @brief
264 : * Creation and destruction
265 : */
266 :
267 0 : 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 0 : struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
274 :
275 0 : if (!gpio) {
276 0 : ASSERT_CRITICAL(false);
277 0 : return NULL;
278 : }
279 :
280 0 : gpio->service = service;
281 0 : gpio->pin = NULL;
282 0 : gpio->id = id;
283 0 : gpio->en = en;
284 0 : gpio->mode = GPIO_MODE_UNKNOWN;
285 0 : gpio->output_state = output_state;
286 :
287 : //initialize hw_container union based on id
288 0 : switch (gpio->id) {
289 : case GPIO_ID_DDC_DATA:
290 0 : gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
291 0 : break;
292 : case GPIO_ID_DDC_CLOCK:
293 0 : gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
294 0 : break;
295 : case GPIO_ID_GENERIC:
296 0 : gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);
297 0 : break;
298 : case GPIO_ID_HPD:
299 0 : gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);
300 0 : 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 0 : ASSERT_CRITICAL(false);
308 0 : gpio->pin = NULL;
309 : }
310 :
311 : return gpio;
312 : }
313 :
314 0 : void dal_gpio_destroy(
315 : struct gpio **gpio)
316 : {
317 0 : if (!gpio || !*gpio) {
318 0 : ASSERT_CRITICAL(false);
319 0 : return;
320 : }
321 :
322 0 : switch ((*gpio)->id) {
323 : case GPIO_ID_DDC_DATA:
324 0 : kfree((*gpio)->hw_container.ddc);
325 0 : (*gpio)->hw_container.ddc = NULL;
326 0 : break;
327 : case GPIO_ID_DDC_CLOCK:
328 : //TODO: might want to change it to init_ddc_clock
329 0 : kfree((*gpio)->hw_container.ddc);
330 0 : (*gpio)->hw_container.ddc = NULL;
331 0 : break;
332 : case GPIO_ID_GENERIC:
333 0 : kfree((*gpio)->hw_container.generic);
334 0 : (*gpio)->hw_container.generic = NULL;
335 0 : break;
336 : case GPIO_ID_HPD:
337 0 : kfree((*gpio)->hw_container.hpd);
338 0 : (*gpio)->hw_container.hpd = NULL;
339 0 : 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 0 : kfree(*gpio);
350 :
351 0 : *gpio = NULL;
352 : }
|