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