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