gpio_base.c (7789B)
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 54enum 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 61enum gpio_result dal_gpio_open_ex( 62 struct gpio *gpio, 63 enum gpio_mode mode) 64{ 65 if (gpio->pin) { 66 BREAK_TO_DEBUGGER(); 67 return GPIO_RESULT_ALREADY_OPENED; 68 } 69 70 // No action if allocation failed during gpio construct 71 if (!gpio->hw_container.ddc) { 72 BREAK_TO_DEBUGGER(); 73 return GPIO_RESULT_NON_SPECIFIC_ERROR; 74 } 75 gpio->mode = mode; 76 77 return dal_gpio_service_open(gpio); 78} 79 80enum gpio_result dal_gpio_get_value( 81 const struct gpio *gpio, 82 uint32_t *value) 83{ 84 if (!gpio->pin) { 85 BREAK_TO_DEBUGGER(); 86 return GPIO_RESULT_NULL_HANDLE; 87 } 88 89 return gpio->pin->funcs->get_value(gpio->pin, value); 90} 91 92enum gpio_result dal_gpio_set_value( 93 const struct gpio *gpio, 94 uint32_t value) 95{ 96 if (!gpio->pin) { 97 BREAK_TO_DEBUGGER(); 98 return GPIO_RESULT_NULL_HANDLE; 99 } 100 101 return gpio->pin->funcs->set_value(gpio->pin, value); 102} 103 104enum gpio_mode dal_gpio_get_mode( 105 const struct gpio *gpio) 106{ 107 return gpio->mode; 108} 109 110enum gpio_result dal_gpio_lock_pin( 111 struct gpio *gpio) 112{ 113 return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en); 114} 115 116enum gpio_result dal_gpio_unlock_pin( 117 struct gpio *gpio) 118{ 119 return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en); 120} 121 122enum gpio_result dal_gpio_change_mode( 123 struct gpio *gpio, 124 enum gpio_mode mode) 125{ 126 if (!gpio->pin) { 127 BREAK_TO_DEBUGGER(); 128 return GPIO_RESULT_NULL_HANDLE; 129 } 130 131 return gpio->pin->funcs->change_mode(gpio->pin, mode); 132} 133 134enum gpio_id dal_gpio_get_id( 135 const struct gpio *gpio) 136{ 137 return gpio->id; 138} 139 140uint32_t dal_gpio_get_enum( 141 const struct gpio *gpio) 142{ 143 return gpio->en; 144} 145 146enum gpio_result dal_gpio_set_config( 147 struct gpio *gpio, 148 const struct gpio_config_data *config_data) 149{ 150 if (!gpio->pin) { 151 BREAK_TO_DEBUGGER(); 152 return GPIO_RESULT_NULL_HANDLE; 153 } 154 155 return gpio->pin->funcs->set_config(gpio->pin, config_data); 156} 157 158enum gpio_result dal_gpio_get_pin_info( 159 const struct gpio *gpio, 160 struct gpio_pin_info *pin_info) 161{ 162 return gpio->service->translate.funcs->id_to_offset( 163 gpio->id, gpio->en, pin_info) ? 164 GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA; 165} 166 167enum sync_source dal_gpio_get_sync_source( 168 const struct gpio *gpio) 169{ 170 switch (gpio->id) { 171 case GPIO_ID_GENERIC: 172 switch (gpio->en) { 173 case GPIO_GENERIC_A: 174 return SYNC_SOURCE_IO_GENERIC_A; 175 case GPIO_GENERIC_B: 176 return SYNC_SOURCE_IO_GENERIC_B; 177 case GPIO_GENERIC_C: 178 return SYNC_SOURCE_IO_GENERIC_C; 179 case GPIO_GENERIC_D: 180 return SYNC_SOURCE_IO_GENERIC_D; 181 case GPIO_GENERIC_E: 182 return SYNC_SOURCE_IO_GENERIC_E; 183 case GPIO_GENERIC_F: 184 return SYNC_SOURCE_IO_GENERIC_F; 185 default: 186 return SYNC_SOURCE_NONE; 187 } 188 break; 189 case GPIO_ID_SYNC: 190 switch (gpio->en) { 191 case GPIO_SYNC_HSYNC_A: 192 return SYNC_SOURCE_IO_HSYNC_A; 193 case GPIO_SYNC_VSYNC_A: 194 return SYNC_SOURCE_IO_VSYNC_A; 195 case GPIO_SYNC_HSYNC_B: 196 return SYNC_SOURCE_IO_HSYNC_B; 197 case GPIO_SYNC_VSYNC_B: 198 return SYNC_SOURCE_IO_VSYNC_B; 199 default: 200 return SYNC_SOURCE_NONE; 201 } 202 break; 203 case GPIO_ID_HPD: 204 switch (gpio->en) { 205 case GPIO_HPD_1: 206 return SYNC_SOURCE_IO_HPD1; 207 case GPIO_HPD_2: 208 return SYNC_SOURCE_IO_HPD2; 209 default: 210 return SYNC_SOURCE_NONE; 211 } 212 break; 213 case GPIO_ID_GSL: 214 switch (gpio->en) { 215 case GPIO_GSL_GENLOCK_CLOCK: 216 return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK; 217 case GPIO_GSL_GENLOCK_VSYNC: 218 return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC; 219 case GPIO_GSL_SWAPLOCK_A: 220 return SYNC_SOURCE_GSL_IO_SWAPLOCK_A; 221 case GPIO_GSL_SWAPLOCK_B: 222 return SYNC_SOURCE_GSL_IO_SWAPLOCK_B; 223 default: 224 return SYNC_SOURCE_NONE; 225 } 226 break; 227 default: 228 return SYNC_SOURCE_NONE; 229 } 230} 231 232enum gpio_pin_output_state dal_gpio_get_output_state( 233 const struct gpio *gpio) 234{ 235 return gpio->output_state; 236} 237 238struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio) 239{ 240 return gpio->hw_container.ddc; 241} 242 243struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio) 244{ 245 return gpio->hw_container.hpd; 246} 247 248struct hw_generic *dal_gpio_get_generic(struct gpio *gpio) 249{ 250 return gpio->hw_container.generic; 251} 252 253void dal_gpio_close( 254 struct gpio *gpio) 255{ 256 if (!gpio) 257 return; 258 259 dal_gpio_service_close(gpio->service, &gpio->pin); 260 261 gpio->mode = GPIO_MODE_UNKNOWN; 262} 263 264/* 265 * @brief 266 * Creation and destruction 267 */ 268 269struct gpio *dal_gpio_create( 270 struct gpio_service *service, 271 enum gpio_id id, 272 uint32_t en, 273 enum gpio_pin_output_state output_state) 274{ 275 struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL); 276 277 if (!gpio) { 278 ASSERT_CRITICAL(false); 279 return NULL; 280 } 281 282 gpio->service = service; 283 gpio->pin = NULL; 284 gpio->id = id; 285 gpio->en = en; 286 gpio->mode = GPIO_MODE_UNKNOWN; 287 gpio->output_state = output_state; 288 289 //initialize hw_container union based on id 290 switch (gpio->id) { 291 case GPIO_ID_DDC_DATA: 292 gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); 293 break; 294 case GPIO_ID_DDC_CLOCK: 295 gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); 296 break; 297 case GPIO_ID_GENERIC: 298 gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en); 299 break; 300 case GPIO_ID_HPD: 301 gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en); 302 break; 303 // TODO: currently gpio for sync and gsl does not get created, might need it later 304 case GPIO_ID_SYNC: 305 break; 306 case GPIO_ID_GSL: 307 break; 308 default: 309 ASSERT_CRITICAL(false); 310 gpio->pin = NULL; 311 } 312 313 return gpio; 314} 315 316void dal_gpio_destroy( 317 struct gpio **gpio) 318{ 319 if (!gpio || !*gpio) { 320 ASSERT_CRITICAL(false); 321 return; 322 } 323 324 switch ((*gpio)->id) { 325 case GPIO_ID_DDC_DATA: 326 kfree((*gpio)->hw_container.ddc); 327 (*gpio)->hw_container.ddc = NULL; 328 break; 329 case GPIO_ID_DDC_CLOCK: 330 //TODO: might want to change it to init_ddc_clock 331 kfree((*gpio)->hw_container.ddc); 332 (*gpio)->hw_container.ddc = NULL; 333 break; 334 case GPIO_ID_GENERIC: 335 kfree((*gpio)->hw_container.generic); 336 (*gpio)->hw_container.generic = NULL; 337 break; 338 case GPIO_ID_HPD: 339 kfree((*gpio)->hw_container.hpd); 340 (*gpio)->hw_container.hpd = NULL; 341 break; 342 // TODO: currently gpio for sync and gsl does not get created, might need it later 343 case GPIO_ID_SYNC: 344 break; 345 case GPIO_ID_GSL: 346 break; 347 default: 348 break; 349 } 350 351 kfree(*gpio); 352 353 *gpio = NULL; 354}