Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 /*
0027  * Pre-requisites: headers required by header of this unit
0028  */
0029 
0030 #include "dm_services.h"
0031 
0032 #include "include/gpio_interface.h"
0033 #include "include/gpio_service_interface.h"
0034 #include "hw_gpio.h"
0035 #include "hw_translate.h"
0036 #include "hw_factory.h"
0037 #include "gpio_service.h"
0038 
0039 /*
0040  * Post-requisites: headers required by this unit
0041  */
0042 
0043 /*
0044  * This unit
0045  */
0046 
0047 /*
0048  * @brief
0049  * Public API
0050  */
0051 
0052 enum gpio_result dal_gpio_open(
0053     struct gpio *gpio,
0054     enum gpio_mode mode)
0055 {
0056     return dal_gpio_open_ex(gpio, mode);
0057 }
0058 
0059 enum gpio_result dal_gpio_open_ex(
0060     struct gpio *gpio,
0061     enum gpio_mode mode)
0062 {
0063     if (gpio->pin) {
0064         BREAK_TO_DEBUGGER();
0065         return GPIO_RESULT_ALREADY_OPENED;
0066     }
0067 
0068     // No action if allocation failed during gpio construct
0069     if (!gpio->hw_container.ddc) {
0070         BREAK_TO_DEBUGGER();
0071         return GPIO_RESULT_NON_SPECIFIC_ERROR;
0072     }
0073     gpio->mode = mode;
0074 
0075     return dal_gpio_service_open(gpio);
0076 }
0077 
0078 enum gpio_result dal_gpio_get_value(
0079     const struct gpio *gpio,
0080     uint32_t *value)
0081 {
0082     if (!gpio->pin) {
0083         BREAK_TO_DEBUGGER();
0084         return GPIO_RESULT_NULL_HANDLE;
0085     }
0086 
0087     return gpio->pin->funcs->get_value(gpio->pin, value);
0088 }
0089 
0090 enum gpio_result dal_gpio_set_value(
0091     const struct gpio *gpio,
0092     uint32_t value)
0093 {
0094     if (!gpio->pin) {
0095         BREAK_TO_DEBUGGER();
0096         return GPIO_RESULT_NULL_HANDLE;
0097     }
0098 
0099     return gpio->pin->funcs->set_value(gpio->pin, value);
0100 }
0101 
0102 enum gpio_mode dal_gpio_get_mode(
0103     const struct gpio *gpio)
0104 {
0105     return gpio->mode;
0106 }
0107 
0108 enum gpio_result dal_gpio_lock_pin(
0109     struct gpio *gpio)
0110 {
0111     return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
0112 }
0113 
0114 enum gpio_result dal_gpio_unlock_pin(
0115     struct gpio *gpio)
0116 {
0117     return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
0118 }
0119 
0120 enum gpio_result dal_gpio_change_mode(
0121     struct gpio *gpio,
0122     enum gpio_mode mode)
0123 {
0124     if (!gpio->pin) {
0125         BREAK_TO_DEBUGGER();
0126         return GPIO_RESULT_NULL_HANDLE;
0127     }
0128 
0129     return gpio->pin->funcs->change_mode(gpio->pin, mode);
0130 }
0131 
0132 enum gpio_id dal_gpio_get_id(
0133     const struct gpio *gpio)
0134 {
0135     return gpio->id;
0136 }
0137 
0138 uint32_t dal_gpio_get_enum(
0139     const struct gpio *gpio)
0140 {
0141     return gpio->en;
0142 }
0143 
0144 enum gpio_result dal_gpio_set_config(
0145     struct gpio *gpio,
0146     const struct gpio_config_data *config_data)
0147 {
0148     if (!gpio->pin) {
0149         BREAK_TO_DEBUGGER();
0150         return GPIO_RESULT_NULL_HANDLE;
0151     }
0152 
0153     return gpio->pin->funcs->set_config(gpio->pin, config_data);
0154 }
0155 
0156 enum gpio_result dal_gpio_get_pin_info(
0157     const struct gpio *gpio,
0158     struct gpio_pin_info *pin_info)
0159 {
0160     return gpio->service->translate.funcs->id_to_offset(
0161         gpio->id, gpio->en, pin_info) ?
0162         GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
0163 }
0164 
0165 enum sync_source dal_gpio_get_sync_source(
0166     const struct gpio *gpio)
0167 {
0168     switch (gpio->id) {
0169     case GPIO_ID_GENERIC:
0170         switch (gpio->en) {
0171         case GPIO_GENERIC_A:
0172             return SYNC_SOURCE_IO_GENERIC_A;
0173         case GPIO_GENERIC_B:
0174             return SYNC_SOURCE_IO_GENERIC_B;
0175         case GPIO_GENERIC_C:
0176             return SYNC_SOURCE_IO_GENERIC_C;
0177         case GPIO_GENERIC_D:
0178             return SYNC_SOURCE_IO_GENERIC_D;
0179         case GPIO_GENERIC_E:
0180             return SYNC_SOURCE_IO_GENERIC_E;
0181         case GPIO_GENERIC_F:
0182             return SYNC_SOURCE_IO_GENERIC_F;
0183         default:
0184             return SYNC_SOURCE_NONE;
0185         }
0186     break;
0187     case GPIO_ID_SYNC:
0188         switch (gpio->en) {
0189         case GPIO_SYNC_HSYNC_A:
0190             return SYNC_SOURCE_IO_HSYNC_A;
0191         case GPIO_SYNC_VSYNC_A:
0192             return SYNC_SOURCE_IO_VSYNC_A;
0193         case GPIO_SYNC_HSYNC_B:
0194             return SYNC_SOURCE_IO_HSYNC_B;
0195         case GPIO_SYNC_VSYNC_B:
0196             return SYNC_SOURCE_IO_VSYNC_B;
0197         default:
0198             return SYNC_SOURCE_NONE;
0199         }
0200     break;
0201     case GPIO_ID_HPD:
0202         switch (gpio->en) {
0203         case GPIO_HPD_1:
0204             return SYNC_SOURCE_IO_HPD1;
0205         case GPIO_HPD_2:
0206             return SYNC_SOURCE_IO_HPD2;
0207         default:
0208             return SYNC_SOURCE_NONE;
0209         }
0210     break;
0211     case GPIO_ID_GSL:
0212         switch (gpio->en) {
0213         case GPIO_GSL_GENLOCK_CLOCK:
0214             return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
0215         case GPIO_GSL_GENLOCK_VSYNC:
0216             return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
0217         case GPIO_GSL_SWAPLOCK_A:
0218             return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
0219         case GPIO_GSL_SWAPLOCK_B:
0220             return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
0221         default:
0222             return SYNC_SOURCE_NONE;
0223         }
0224     break;
0225     default:
0226         return SYNC_SOURCE_NONE;
0227     }
0228 }
0229 
0230 enum gpio_pin_output_state dal_gpio_get_output_state(
0231     const struct gpio *gpio)
0232 {
0233     return gpio->output_state;
0234 }
0235 
0236 struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)
0237 {
0238     return gpio->hw_container.ddc;
0239 }
0240 
0241 struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)
0242 {
0243     return gpio->hw_container.hpd;
0244 }
0245 
0246 struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)
0247 {
0248     return gpio->hw_container.generic;
0249 }
0250 
0251 void dal_gpio_close(
0252     struct gpio *gpio)
0253 {
0254     if (!gpio)
0255         return;
0256 
0257     dal_gpio_service_close(gpio->service, &gpio->pin);
0258 
0259     gpio->mode = GPIO_MODE_UNKNOWN;
0260 }
0261 
0262 /*
0263  * @brief
0264  * Creation and destruction
0265  */
0266 
0267 struct gpio *dal_gpio_create(
0268     struct gpio_service *service,
0269     enum gpio_id id,
0270     uint32_t en,
0271     enum gpio_pin_output_state output_state)
0272 {
0273     struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
0274 
0275     if (!gpio) {
0276         ASSERT_CRITICAL(false);
0277         return NULL;
0278     }
0279 
0280     gpio->service = service;
0281     gpio->pin = NULL;
0282     gpio->id = id;
0283     gpio->en = en;
0284     gpio->mode = GPIO_MODE_UNKNOWN;
0285     gpio->output_state = output_state;
0286 
0287     //initialize hw_container union based on id
0288     switch (gpio->id) {
0289     case GPIO_ID_DDC_DATA:
0290         gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
0291         break;
0292     case GPIO_ID_DDC_CLOCK:
0293         gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
0294         break;
0295     case GPIO_ID_GENERIC:
0296         gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);
0297         break;
0298     case GPIO_ID_HPD:
0299         gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);
0300         break;
0301     // TODO: currently gpio for sync and gsl does not get created, might need it later
0302     case GPIO_ID_SYNC:
0303         break;
0304     case GPIO_ID_GSL:
0305         break;
0306     default:
0307         ASSERT_CRITICAL(false);
0308         gpio->pin = NULL;
0309     }
0310 
0311     return gpio;
0312 }
0313 
0314 void dal_gpio_destroy(
0315     struct gpio **gpio)
0316 {
0317     if (!gpio || !*gpio) {
0318         ASSERT_CRITICAL(false);
0319         return;
0320     }
0321 
0322     switch ((*gpio)->id) {
0323     case GPIO_ID_DDC_DATA:
0324         kfree((*gpio)->hw_container.ddc);
0325         (*gpio)->hw_container.ddc = NULL;
0326         break;
0327     case GPIO_ID_DDC_CLOCK:
0328         //TODO: might want to change it to init_ddc_clock
0329         kfree((*gpio)->hw_container.ddc);
0330         (*gpio)->hw_container.ddc = NULL;
0331         break;
0332     case GPIO_ID_GENERIC:
0333         kfree((*gpio)->hw_container.generic);
0334         (*gpio)->hw_container.generic = NULL;
0335         break;
0336     case GPIO_ID_HPD:
0337         kfree((*gpio)->hw_container.hpd);
0338         (*gpio)->hw_container.hpd = NULL;
0339         break;
0340     // TODO: currently gpio for sync and gsl does not get created, might need it later
0341     case GPIO_ID_SYNC:
0342         break;
0343     case GPIO_ID_GSL:
0344         break;
0345     default:
0346         break;
0347     }
0348 
0349     kfree(*gpio);
0350 
0351     *gpio = NULL;
0352 }