353 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26/*27 * Pre-requisites: headers required by header of this unit28 */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 unit41 */42 43/*44 * This unit45 */46 47/*48 * @brief49 * Public API50 */51 52enum 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 59enum 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 construct69 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 78enum 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 90enum 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 102enum gpio_mode dal_gpio_get_mode(103 const struct gpio *gpio)104{105 return gpio->mode;106}107 108enum 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 114enum 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 120enum 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 132enum gpio_id dal_gpio_get_id(133 const struct gpio *gpio)134{135 return gpio->id;136}137 138uint32_t dal_gpio_get_enum(139 const struct gpio *gpio)140{141 return gpio->en;142}143 144enum 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 156enum 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 165enum 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 230enum gpio_pin_output_state dal_gpio_get_output_state(231 const struct gpio *gpio)232{233 return gpio->output_state;234}235 236struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)237{238 return gpio->hw_container.ddc;239}240 241struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)242{243 return gpio->hw_container.hpd;244}245 246struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)247{248 return gpio->hw_container.generic;249}250 251void 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 * @brief264 * Creation and destruction265 */266 267struct 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 id288 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 later302 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 314void 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_clock329 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 later341 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}353