/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

/*
 * Pre-requisites: headers required by header of this unit
 */

#include <linux/slab.h>

#include "dm_services.h"
#include "include/gpio_interface.h"
#include "include/gpio_service_interface.h"
#include "hw_translate.h"
#include "hw_factory.h"

/*
 * Header of this unit
 */

#include "gpio_service.h"

/*
 * Post-requisites: headers required by this unit
 */

#include "hw_gpio.h"

/*
 * @brief
 * Public API.
 */

struct gpio_service *dal_gpio_service_create(
	enum dce_version dce_version_major,
	enum dce_version dce_version_minor,
	struct dc_context *ctx)
{
	struct gpio_service *service;
	uint32_t index_of_id;

	service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);

	if (!service) {
		BREAK_TO_DEBUGGER();
		return NULL;
	}

	if (!dal_hw_translate_init(&service->translate, dce_version_major,
			dce_version_minor)) {
		BREAK_TO_DEBUGGER();
		goto failure_1;
	}

	if (!dal_hw_factory_init(&service->factory, dce_version_major,
			dce_version_minor)) {
		BREAK_TO_DEBUGGER();
		goto failure_1;
	}

	/* allocate and initialize busyness storage */
	{
		index_of_id = 0;
		service->ctx = ctx;

		do {
			uint32_t number_of_bits =
				service->factory.number_of_pins[index_of_id];
			uint32_t i = 0;

			if (number_of_bits)  {
				service->busyness[index_of_id] =
					kcalloc(number_of_bits, sizeof(char),
						GFP_KERNEL);

				if (!service->busyness[index_of_id]) {
					BREAK_TO_DEBUGGER();
					goto failure_2;
				}

				do {
					service->busyness[index_of_id][i] = 0;
					++i;
				} while (i < number_of_bits);
			} else {
				service->busyness[index_of_id] = NULL;
			}

			++index_of_id;
		} while (index_of_id < GPIO_ID_COUNT);
	}

	return service;

failure_2:
	while (index_of_id) {
		--index_of_id;
		kfree(service->busyness[index_of_id]);
	}

failure_1:
	kfree(service);

	return NULL;
}

struct gpio *dal_gpio_service_create_irq(
	struct gpio_service *service,
	uint32_t offset,
	uint32_t mask)
{
	enum gpio_id id;
	uint32_t en;

	if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
		ASSERT_CRITICAL(false);
		return NULL;
	}

	return dal_gpio_create_irq(service, id, en);
}

struct gpio *dal_gpio_service_create_generic_mux(
	struct gpio_service *service,
	uint32_t offset,
	uint32_t mask)
{
	enum gpio_id id;
	uint32_t en;
	struct gpio *generic;

	if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
		ASSERT_CRITICAL(false);
		return NULL;
	}

	generic = dal_gpio_create(
		service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);

	return generic;
}

void dal_gpio_destroy_generic_mux(
	struct gpio **mux)
{
	if (!mux || !*mux) {
		ASSERT_CRITICAL(false);
		return;
	}

	dal_gpio_close(*mux);
	dal_gpio_destroy(mux);
	kfree(*mux);

	*mux = NULL;
}

struct gpio_pin_info dal_gpio_get_generic_pin_info(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	struct gpio_pin_info pin;

	if (service->translate.funcs->id_to_offset) {
		service->translate.funcs->id_to_offset(id, en, &pin);
	} else {
		pin.mask = 0xFFFFFFFF;
		pin.offset = 0xFFFFFFFF;
	}

	return pin;
}

void dal_gpio_service_destroy(
	struct gpio_service **ptr)
{
	if (!ptr || !*ptr) {
		BREAK_TO_DEBUGGER();
		return;
	}

	/* free business storage */
	{
		uint32_t index_of_id = 0;

		do {
			kfree((*ptr)->busyness[index_of_id]);

			++index_of_id;
		} while (index_of_id < GPIO_ID_COUNT);
	}

	kfree(*ptr);

	*ptr = NULL;
}

enum gpio_result dal_mux_setup_config(
	struct gpio *mux,
	struct gpio_generic_mux_config *config)
{
	struct gpio_config_data config_data;

	if (!config)
		return GPIO_RESULT_INVALID_DATA;

	config_data.config.generic_mux = *config;
	config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX;

	return dal_gpio_set_config(mux, &config_data);
}

/*
 * @brief
 * Private API.
 */

static bool is_pin_busy(
	const struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	return service->busyness[id][en];
}

static void set_pin_busy(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	service->busyness[id][en] = true;
}

static void set_pin_free(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	service->busyness[id][en] = false;
}

enum gpio_result dal_gpio_service_lock(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	if (!service->busyness[id]) {
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_OPEN_FAILED;
	}

	set_pin_busy(service, id, en);
	return GPIO_RESULT_OK;
}

enum gpio_result dal_gpio_service_unlock(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	if (!service->busyness[id]) {
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_OPEN_FAILED;
	}

	set_pin_free(service, id, en);
	return GPIO_RESULT_OK;
}

enum gpio_result dal_gpio_service_open(
	struct gpio *gpio)
{
	struct gpio_service *service = gpio->service;
	enum gpio_id id = gpio->id;
	uint32_t en = gpio->en;
	enum gpio_mode mode = gpio->mode;

	struct hw_gpio_pin **pin = &gpio->pin;


	if (!service->busyness[id]) {
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_OPEN_FAILED;
	}

	if (is_pin_busy(service, id, en)) {
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_DEVICE_BUSY;
	}

	switch (id) {
	case GPIO_ID_DDC_DATA:
		*pin = service->factory.funcs->get_ddc_pin(gpio);
		service->factory.funcs->define_ddc_registers(*pin, en);
	break;
	case GPIO_ID_DDC_CLOCK:
		*pin = service->factory.funcs->get_ddc_pin(gpio);
		service->factory.funcs->define_ddc_registers(*pin, en);
	break;
	case GPIO_ID_GENERIC:
		*pin = service->factory.funcs->get_generic_pin(gpio);
		service->factory.funcs->define_generic_registers(*pin, en);
	break;
	case GPIO_ID_HPD:
		*pin = service->factory.funcs->get_hpd_pin(gpio);
		service->factory.funcs->define_hpd_registers(*pin, en);
	break;

	//TODO: gsl and sync support? create_sync and create_gsl are NULL
	case GPIO_ID_SYNC:
	case GPIO_ID_GSL:
	break;
	default:
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_NON_SPECIFIC_ERROR;
	}

	if (!*pin) {
		ASSERT_CRITICAL(false);
		return GPIO_RESULT_NON_SPECIFIC_ERROR;
	}

	if (!(*pin)->funcs->open(*pin, mode)) {
		ASSERT_CRITICAL(false);
		dal_gpio_service_close(service, pin);
		return GPIO_RESULT_OPEN_FAILED;
	}

	set_pin_busy(service, id, en);
	return GPIO_RESULT_OK;
}

void dal_gpio_service_close(
	struct gpio_service *service,
	struct hw_gpio_pin **ptr)
{
	struct hw_gpio_pin *pin;

	if (!ptr) {
		ASSERT_CRITICAL(false);
		return;
	}

	pin = *ptr;

	if (pin) {
		set_pin_free(service, pin->id, pin->en);

		pin->funcs->close(pin);

		*ptr = NULL;
	}
}

enum dc_irq_source dal_irq_get_source(
	const struct gpio *irq)
{
	enum gpio_id id = dal_gpio_get_id(irq);

	switch (id) {
	case GPIO_ID_HPD:
		return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 +
			dal_gpio_get_enum(irq));
	case GPIO_ID_GPIO_PAD:
		return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 +
			dal_gpio_get_enum(irq));
	default:
		return DC_IRQ_SOURCE_INVALID;
	}
}

enum dc_irq_source dal_irq_get_rx_source(
	const struct gpio *irq)
{
	enum gpio_id id = dal_gpio_get_id(irq);

	switch (id) {
	case GPIO_ID_HPD:
		return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
			dal_gpio_get_enum(irq));
	default:
		return DC_IRQ_SOURCE_INVALID;
	}
}

enum gpio_result dal_irq_setup_hpd_filter(
	struct gpio *irq,
	struct gpio_hpd_config *config)
{
	struct gpio_config_data config_data;

	if (!config)
		return GPIO_RESULT_INVALID_DATA;

	config_data.type = GPIO_CONFIG_TYPE_HPD;
	config_data.config.hpd = *config;

	return dal_gpio_set_config(irq, &config_data);
}

/*
 * @brief
 * Creation and destruction
 */

struct gpio *dal_gpio_create_irq(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	struct gpio *irq;

	switch (id) {
	case GPIO_ID_HPD:
	case GPIO_ID_GPIO_PAD:
	break;
	default:
		id = GPIO_ID_HPD;
		ASSERT_CRITICAL(false);
		return NULL;
	}

	irq = dal_gpio_create(
		service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);

	if (irq)
		return irq;

	ASSERT_CRITICAL(false);
	return NULL;
}

void dal_gpio_destroy_irq(
	struct gpio **irq)
{
	if (!irq || !*irq) {
		ASSERT_CRITICAL(false);
		return;
	}

	dal_gpio_close(*irq);
	dal_gpio_destroy(irq);
	kfree(*irq);

	*irq = NULL;
}

struct ddc *dal_gpio_create_ddc(
	struct gpio_service *service,
	uint32_t offset,
	uint32_t mask,
	struct gpio_ddc_hw_info *info)
{
	enum gpio_id id;
	uint32_t en;
	struct ddc *ddc;

	if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
		return NULL;

	ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL);

	if (!ddc) {
		BREAK_TO_DEBUGGER();
		return NULL;
	}

	ddc->pin_data = dal_gpio_create(
		service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);

	if (!ddc->pin_data) {
		BREAK_TO_DEBUGGER();
		goto failure_1;
	}

	ddc->pin_clock = dal_gpio_create(
		service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);

	if (!ddc->pin_clock) {
		BREAK_TO_DEBUGGER();
		goto failure_2;
	}

	ddc->hw_info = *info;

	ddc->ctx = service->ctx;

	return ddc;

failure_2:
	dal_gpio_destroy(&ddc->pin_data);

failure_1:
	kfree(ddc);

	return NULL;
}

void dal_gpio_destroy_ddc(
	struct ddc **ddc)
{
	if (!ddc || !*ddc) {
		BREAK_TO_DEBUGGER();
		return;
	}

	dal_ddc_close(*ddc);
	dal_gpio_destroy(&(*ddc)->pin_data);
	dal_gpio_destroy(&(*ddc)->pin_clock);
	kfree(*ddc);

	*ddc = NULL;
}

enum gpio_result dal_ddc_open(
	struct ddc *ddc,
	enum gpio_mode mode,
	enum gpio_ddc_config_type config_type)
{
	enum gpio_result result;

	struct gpio_config_data config_data;
	struct hw_gpio *hw_data;
	struct hw_gpio *hw_clock;

	result = dal_gpio_open_ex(ddc->pin_data, mode);

	if (result != GPIO_RESULT_OK) {
		BREAK_TO_DEBUGGER();
		return result;
	}

	result = dal_gpio_open_ex(ddc->pin_clock, mode);

	if (result != GPIO_RESULT_OK) {
		BREAK_TO_DEBUGGER();
		goto failure;
	}

	/* DDC clock and data pins should belong
	 * to the same DDC block id,
	 * we use the data pin to set the pad mode. */

	if (mode == GPIO_MODE_INPUT)
		/* this is from detect_sink_type,
		 * we need extra delay there */
		config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
	else
		config_data.type = GPIO_CONFIG_TYPE_DDC;

	config_data.config.ddc.type = config_type;

	hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin);
	hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin);

	config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0;
	config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0;

	result = dal_gpio_set_config(ddc->pin_data, &config_data);

	if (result == GPIO_RESULT_OK)
		return result;

	BREAK_TO_DEBUGGER();

	dal_gpio_close(ddc->pin_clock);

failure:
	dal_gpio_close(ddc->pin_data);

	return result;
}

enum gpio_result dal_ddc_change_mode(
	struct ddc *ddc,
	enum gpio_mode mode)
{
	enum gpio_result result;

	enum gpio_mode original_mode =
		dal_gpio_get_mode(ddc->pin_data);

	result = dal_gpio_change_mode(ddc->pin_data, mode);

	/* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR
	 * in case of failures;
	 * set_mode() is so that, in case of failure,
	 * we must explicitly set original mode */

	if (result != GPIO_RESULT_OK)
		goto failure;

	result = dal_gpio_change_mode(ddc->pin_clock, mode);

	if (result == GPIO_RESULT_OK)
		return result;

	dal_gpio_change_mode(ddc->pin_clock, original_mode);

failure:
	dal_gpio_change_mode(ddc->pin_data, original_mode);

	return result;
}

enum gpio_ddc_line dal_ddc_get_line(
	const struct ddc *ddc)
{
	return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
}

enum gpio_result dal_ddc_set_config(
	struct ddc *ddc,
	enum gpio_ddc_config_type config_type)
{
	struct gpio_config_data config_data;

	config_data.type = GPIO_CONFIG_TYPE_DDC;

	config_data.config.ddc.type = config_type;
	config_data.config.ddc.data_en_bit_present = false;
	config_data.config.ddc.clock_en_bit_present = false;

	return dal_gpio_set_config(ddc->pin_data, &config_data);
}

void dal_ddc_close(
	struct ddc *ddc)
{
	dal_gpio_close(ddc->pin_clock);
	dal_gpio_close(ddc->pin_data);
}

