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