/*
 * Copyright (C) 2018 Synaptics Incorporated. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND
 * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY
 * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR
 * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND
 * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF
 * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT
 * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY
 * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS.
 */

#include "Galois_memmap.h"
#include "global.h"
#include "pinmux.h"
#include "gpio.h"
#include "io.h"
#include "SysMgr.h"
#include "apbRegBase.h"

#include "board_config.h"

#include "util.h"
#include "lgpl_printf.h"

#define	RA_SET_BITS_GENERIC(ra_base, ra_name, ra_class, bf_name, val) \
	io32_set_bits(ra_base + RA_##ra_name, val, LSb32##ra_class##_##bf_name, b##ra_class##_##bf_name)

#define	RA_SET_BITS_SIMPLE(ra_base, ra_name, bf_name, val) RA_SET_BITS_GENERIC(ra_base, ra_name, ra_name, bf_name, val)

#define	SOC_SET_PINMUX(ra_name, bf_name, val) RA_SET_BITS_GENERIC(MEMMAP_CHIP_CTRL_REG_BASE, ra_name, Gbl_pinMuxCntlBus, bf_name, val)
#define	SM_SET_PINMUX(ra_name, bf_name, val) RA_SET_BITS_GENERIC(SOC_SM_SYS_CTRL_REG_BASE, ra_name, smSysCtl_smPinMuxCntlBus, bf_name, val)

void pin_init(void)
{
	GPIO_PortSetInOut(5, 1); // TOUCH_IRQ_L Input, active low
	GPIO_PortSetInOut(11, 1); // MIC_MUTE_STATUS Input, active high
	GPIO_PortWrite(17, 0); // AMP_EN Output, active high, default=inactive low
	GPIO_PortWrite(62, 0); // WLAN0_BT_EN
	GPIO_PortWrite(63, 0); // WLAN0_WL_EN Output, active high, default=inactive low
	GPIO_PortWrite(45, 0); // WALN1_PWD_L
	GPIO_PortWrite(6, 0);// SOC_THREAD_RES_N

	GPIO_PortWrite(7, 0);// WLAN0_PCIE_RST_L
	GPIO_PortWrite(40, 0);// WLAN1_PCIE_RST_L

	GPIO_PortSetInOut(26, 1);// WLAN0_PCIE_CLI_REQ
	GPIO_PortSetInOut(8, 1);// WLAN0_PCIE_WAKE_L
	GPIO_PortSetInOut(43, 1);// WLAN1_PCIE_CLI_REQ
	GPIO_PortSetInOut(44, 1);// WLAN1_PCIE_WAKE_L

	GPIO_PortSetInOut(16, 1);// THREAD_SOC_INT_N

	// reset the peripherals for 20ms, no i2c commands allowed during the reset pulse
	// Set PER_RST_L output low
	GPIO_PortWrite(4, 0);
	// Wait 20ms
	berlin_delay_us(20000);
	// Set PER_RST_L output high
	GPIO_PortWrite(4, 1);

	GPIO_PortWrite(62, 1);// WLAN0_BT_EN

	GPIO_PortWrite(6, 1);// SOC_THREAD_RES_N

	// end of low level initialisation
}
