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 ASSERT_CRITICAL(false); 65 return GPIO_RESULT_ALREADY_OPENED; 66 } 67 68 gpio->mode = mode; 69 70 return dal_gpio_service_open( 71 gpio->service, gpio->id, gpio->en, mode, &gpio->pin); 72 } 73 74 enum gpio_result dal_gpio_get_value( 75 const struct gpio *gpio, 76 uint32_t *value) 77 { 78 if (!gpio->pin) { 79 BREAK_TO_DEBUGGER(); 80 return GPIO_RESULT_NULL_HANDLE; 81 } 82 83 return gpio->pin->funcs->get_value(gpio->pin, value); 84 } 85 86 enum gpio_result dal_gpio_set_value( 87 const struct gpio *gpio, 88 uint32_t value) 89 { 90 if (!gpio->pin) { 91 BREAK_TO_DEBUGGER(); 92 return GPIO_RESULT_NULL_HANDLE; 93 } 94 95 return gpio->pin->funcs->set_value(gpio->pin, value); 96 } 97 98 enum gpio_mode dal_gpio_get_mode( 99 const struct gpio *gpio) 100 { 101 return gpio->mode; 102 } 103 104 enum gpio_result dal_gpio_lock_pin( 105 struct gpio *gpio) 106 { 107 return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en); 108 } 109 110 enum gpio_result dal_gpio_unlock_pin( 111 struct gpio *gpio) 112 { 113 return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en); 114 } 115 116 enum gpio_result dal_gpio_change_mode( 117 struct gpio *gpio, 118 enum gpio_mode mode) 119 { 120 if (!gpio->pin) { 121 BREAK_TO_DEBUGGER(); 122 return GPIO_RESULT_NULL_HANDLE; 123 } 124 125 return gpio->pin->funcs->change_mode(gpio->pin, mode); 126 } 127 128 enum gpio_id dal_gpio_get_id( 129 const struct gpio *gpio) 130 { 131 return gpio->id; 132 } 133 134 uint32_t dal_gpio_get_enum( 135 const struct gpio *gpio) 136 { 137 return gpio->en; 138 } 139 140 enum gpio_result dal_gpio_set_config( 141 struct gpio *gpio, 142 const struct gpio_config_data *config_data) 143 { 144 if (!gpio->pin) { 145 BREAK_TO_DEBUGGER(); 146 return GPIO_RESULT_NULL_HANDLE; 147 } 148 149 return gpio->pin->funcs->set_config(gpio->pin, config_data); 150 } 151 152 enum gpio_result dal_gpio_get_pin_info( 153 const struct gpio *gpio, 154 struct gpio_pin_info *pin_info) 155 { 156 return gpio->service->translate.funcs->id_to_offset( 157 gpio->id, gpio->en, pin_info) ? 158 GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA; 159 } 160 161 enum sync_source dal_gpio_get_sync_source( 162 const struct gpio *gpio) 163 { 164 switch (gpio->id) { 165 case GPIO_ID_GENERIC: 166 switch (gpio->en) { 167 case GPIO_GENERIC_A: 168 return SYNC_SOURCE_IO_GENERIC_A; 169 case GPIO_GENERIC_B: 170 return SYNC_SOURCE_IO_GENERIC_B; 171 case GPIO_GENERIC_C: 172 return SYNC_SOURCE_IO_GENERIC_C; 173 case GPIO_GENERIC_D: 174 return SYNC_SOURCE_IO_GENERIC_D; 175 case GPIO_GENERIC_E: 176 return SYNC_SOURCE_IO_GENERIC_E; 177 case GPIO_GENERIC_F: 178 return SYNC_SOURCE_IO_GENERIC_F; 179 default: 180 return SYNC_SOURCE_NONE; 181 } 182 break; 183 case GPIO_ID_SYNC: 184 switch (gpio->en) { 185 case GPIO_SYNC_HSYNC_A: 186 return SYNC_SOURCE_IO_HSYNC_A; 187 case GPIO_SYNC_VSYNC_A: 188 return SYNC_SOURCE_IO_VSYNC_A; 189 case GPIO_SYNC_HSYNC_B: 190 return SYNC_SOURCE_IO_HSYNC_B; 191 case GPIO_SYNC_VSYNC_B: 192 return SYNC_SOURCE_IO_VSYNC_B; 193 default: 194 return SYNC_SOURCE_NONE; 195 } 196 break; 197 case GPIO_ID_HPD: 198 switch (gpio->en) { 199 case GPIO_HPD_1: 200 return SYNC_SOURCE_IO_HPD1; 201 case GPIO_HPD_2: 202 return SYNC_SOURCE_IO_HPD2; 203 default: 204 return SYNC_SOURCE_NONE; 205 } 206 break; 207 case GPIO_ID_GSL: 208 switch (gpio->en) { 209 case GPIO_GSL_GENLOCK_CLOCK: 210 return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK; 211 case GPIO_GSL_GENLOCK_VSYNC: 212 return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC; 213 case GPIO_GSL_SWAPLOCK_A: 214 return SYNC_SOURCE_GSL_IO_SWAPLOCK_A; 215 case GPIO_GSL_SWAPLOCK_B: 216 return SYNC_SOURCE_GSL_IO_SWAPLOCK_B; 217 default: 218 return SYNC_SOURCE_NONE; 219 } 220 break; 221 default: 222 return SYNC_SOURCE_NONE; 223 } 224 } 225 226 enum gpio_pin_output_state dal_gpio_get_output_state( 227 const struct gpio *gpio) 228 { 229 return gpio->output_state; 230 } 231 232 void dal_gpio_close( 233 struct gpio *gpio) 234 { 235 if (!gpio) 236 return; 237 238 dal_gpio_service_close(gpio->service, &gpio->pin); 239 240 gpio->mode = GPIO_MODE_UNKNOWN; 241 } 242 243 /* 244 * @brief 245 * Creation and destruction 246 */ 247 248 struct gpio *dal_gpio_create( 249 struct gpio_service *service, 250 enum gpio_id id, 251 uint32_t en, 252 enum gpio_pin_output_state output_state) 253 { 254 struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL); 255 256 if (!gpio) { 257 ASSERT_CRITICAL(false); 258 return NULL; 259 } 260 261 gpio->service = service; 262 gpio->pin = NULL; 263 gpio->id = id; 264 gpio->en = en; 265 gpio->mode = GPIO_MODE_UNKNOWN; 266 gpio->output_state = output_state; 267 268 return gpio; 269 } 270 271 void dal_gpio_destroy( 272 struct gpio **gpio) 273 { 274 if (!gpio || !*gpio) { 275 ASSERT_CRITICAL(false); 276 return; 277 } 278 279 dal_gpio_close(*gpio); 280 281 kfree(*gpio); 282 283 *gpio = NULL; 284 } 285