brintos

brintos / linux-shallow public Read only

0
0
Text · 7.6 KiB · 8183cdf Raw
353 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26/*27 * Pre-requisites: headers required by header of this unit28 */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 unit41 */42 43/*44 * This unit45 */46 47/*48 * @brief49 * Public API50 */51 52enum 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 59enum gpio_result dal_gpio_open_ex(60	struct gpio *gpio,61	enum gpio_mode mode)62{63	if (gpio->pin) {64		BREAK_TO_DEBUGGER();65		return GPIO_RESULT_ALREADY_OPENED;66	}67 68	// No action if allocation failed during gpio construct69	if (!gpio->hw_container.ddc) {70		BREAK_TO_DEBUGGER();71		return GPIO_RESULT_NON_SPECIFIC_ERROR;72	}73	gpio->mode = mode;74 75	return dal_gpio_service_open(gpio);76}77 78enum gpio_result dal_gpio_get_value(79	const struct gpio *gpio,80	uint32_t *value)81{82	if (!gpio->pin) {83		BREAK_TO_DEBUGGER();84		return GPIO_RESULT_NULL_HANDLE;85	}86 87	return gpio->pin->funcs->get_value(gpio->pin, value);88}89 90enum gpio_result dal_gpio_set_value(91	const struct gpio *gpio,92	uint32_t value)93{94	if (!gpio->pin) {95		BREAK_TO_DEBUGGER();96		return GPIO_RESULT_NULL_HANDLE;97	}98 99	return gpio->pin->funcs->set_value(gpio->pin, value);100}101 102enum gpio_mode dal_gpio_get_mode(103	const struct gpio *gpio)104{105	return gpio->mode;106}107 108enum gpio_result dal_gpio_lock_pin(109	struct gpio *gpio)110{111	return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);112}113 114enum gpio_result dal_gpio_unlock_pin(115	struct gpio *gpio)116{117	return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);118}119 120enum gpio_result dal_gpio_change_mode(121	struct gpio *gpio,122	enum gpio_mode mode)123{124	if (!gpio->pin) {125		BREAK_TO_DEBUGGER();126		return GPIO_RESULT_NULL_HANDLE;127	}128 129	return gpio->pin->funcs->change_mode(gpio->pin, mode);130}131 132enum gpio_id dal_gpio_get_id(133	const struct gpio *gpio)134{135	return gpio->id;136}137 138uint32_t dal_gpio_get_enum(139	const struct gpio *gpio)140{141	return gpio->en;142}143 144enum gpio_result dal_gpio_set_config(145	struct gpio *gpio,146	const struct gpio_config_data *config_data)147{148	if (!gpio->pin) {149		BREAK_TO_DEBUGGER();150		return GPIO_RESULT_NULL_HANDLE;151	}152 153	return gpio->pin->funcs->set_config(gpio->pin, config_data);154}155 156enum gpio_result dal_gpio_get_pin_info(157	const struct gpio *gpio,158	struct gpio_pin_info *pin_info)159{160	return gpio->service->translate.funcs->id_to_offset(161		gpio->id, gpio->en, pin_info) ?162		GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;163}164 165enum sync_source dal_gpio_get_sync_source(166	const struct gpio *gpio)167{168	switch (gpio->id) {169	case GPIO_ID_GENERIC:170		switch (gpio->en) {171		case GPIO_GENERIC_A:172			return SYNC_SOURCE_IO_GENERIC_A;173		case GPIO_GENERIC_B:174			return SYNC_SOURCE_IO_GENERIC_B;175		case GPIO_GENERIC_C:176			return SYNC_SOURCE_IO_GENERIC_C;177		case GPIO_GENERIC_D:178			return SYNC_SOURCE_IO_GENERIC_D;179		case GPIO_GENERIC_E:180			return SYNC_SOURCE_IO_GENERIC_E;181		case GPIO_GENERIC_F:182			return SYNC_SOURCE_IO_GENERIC_F;183		default:184			return SYNC_SOURCE_NONE;185		}186	break;187	case GPIO_ID_SYNC:188		switch (gpio->en) {189		case GPIO_SYNC_HSYNC_A:190			return SYNC_SOURCE_IO_HSYNC_A;191		case GPIO_SYNC_VSYNC_A:192			return SYNC_SOURCE_IO_VSYNC_A;193		case GPIO_SYNC_HSYNC_B:194			return SYNC_SOURCE_IO_HSYNC_B;195		case GPIO_SYNC_VSYNC_B:196			return SYNC_SOURCE_IO_VSYNC_B;197		default:198			return SYNC_SOURCE_NONE;199		}200	break;201	case GPIO_ID_HPD:202		switch (gpio->en) {203		case GPIO_HPD_1:204			return SYNC_SOURCE_IO_HPD1;205		case GPIO_HPD_2:206			return SYNC_SOURCE_IO_HPD2;207		default:208			return SYNC_SOURCE_NONE;209		}210	break;211	case GPIO_ID_GSL:212		switch (gpio->en) {213		case GPIO_GSL_GENLOCK_CLOCK:214			return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;215		case GPIO_GSL_GENLOCK_VSYNC:216			return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;217		case GPIO_GSL_SWAPLOCK_A:218			return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;219		case GPIO_GSL_SWAPLOCK_B:220			return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;221		default:222			return SYNC_SOURCE_NONE;223		}224	break;225	default:226		return SYNC_SOURCE_NONE;227	}228}229 230enum gpio_pin_output_state dal_gpio_get_output_state(231	const struct gpio *gpio)232{233	return gpio->output_state;234}235 236struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)237{238	return gpio->hw_container.ddc;239}240 241struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)242{243	return gpio->hw_container.hpd;244}245 246struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)247{248	return gpio->hw_container.generic;249}250 251void dal_gpio_close(252	struct gpio *gpio)253{254	if (!gpio)255		return;256 257	dal_gpio_service_close(gpio->service, &gpio->pin);258 259	gpio->mode = GPIO_MODE_UNKNOWN;260}261 262/*263 * @brief264 * Creation and destruction265 */266 267struct gpio *dal_gpio_create(268	struct gpio_service *service,269	enum gpio_id id,270	uint32_t en,271	enum gpio_pin_output_state output_state)272{273	struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);274 275	if (!gpio) {276		ASSERT_CRITICAL(false);277		return NULL;278	}279 280	gpio->service = service;281	gpio->pin = NULL;282	gpio->id = id;283	gpio->en = en;284	gpio->mode = GPIO_MODE_UNKNOWN;285	gpio->output_state = output_state;286 287	//initialize hw_container union based on id288	switch (gpio->id) {289	case GPIO_ID_DDC_DATA:290		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);291		break;292	case GPIO_ID_DDC_CLOCK:293		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);294		break;295	case GPIO_ID_GENERIC:296		gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);297		break;298	case GPIO_ID_HPD:299		gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);300		break;301	// TODO: currently gpio for sync and gsl does not get created, might need it later302	case GPIO_ID_SYNC:303		break;304	case GPIO_ID_GSL:305		break;306	default:307		ASSERT_CRITICAL(false);308		gpio->pin = NULL;309	}310 311	return gpio;312}313 314void dal_gpio_destroy(315	struct gpio **gpio)316{317	if (!gpio || !*gpio) {318		ASSERT_CRITICAL(false);319		return;320	}321 322	switch ((*gpio)->id) {323	case GPIO_ID_DDC_DATA:324		kfree((*gpio)->hw_container.ddc);325		(*gpio)->hw_container.ddc = NULL;326		break;327	case GPIO_ID_DDC_CLOCK:328		//TODO: might want to change it to init_ddc_clock329		kfree((*gpio)->hw_container.ddc);330		(*gpio)->hw_container.ddc = NULL;331		break;332	case GPIO_ID_GENERIC:333		kfree((*gpio)->hw_container.generic);334		(*gpio)->hw_container.generic = NULL;335		break;336	case GPIO_ID_HPD:337		kfree((*gpio)->hw_container.hpd);338		(*gpio)->hw_container.hpd = NULL;339		break;340	// TODO: currently gpio for sync and gsl does not get created, might need it later341	case GPIO_ID_SYNC:342		break;343	case GPIO_ID_GSL:344		break;345	default:346		break;347	}348 349	kfree(*gpio);350 351	*gpio = NULL;352}353