//  Copyright (C) 2016, mituhiromatuura all right reserved.

#include <kernel.h>
#include "iodefine.h"
#include "gpio.h"

v32_t *bit_band(unsigned int a, int b)
{
	return BITBAND(a, b);
}

void gpio_pfr_set(int port, int bit, uint32_t d)
{
	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			*bit_band(VBAT_VBPFR, 4) = 0;
			*bit_band(VBAT_VBPFR, 3) = d;
			break;
		case 7:
			*bit_band(VBAT_VBPFR, 4) = 0;
			*bit_band(VBAT_VBPFR, 2) = d;
			break;
		case 8:
			*bit_band(VBAT_VBPFR, 0) = d;
			break;
		case 9:
			*bit_band(VBAT_VBPFR, 1) = d;
			break;
		default:
			*bit_band(GPIO_PFR + port * 4, bit) = d;
			break;
		}
	}
	else
	{
		*bit_band(GPIO_PFR + port * 4, bit) = d;
	}
	return;
}

void gpio_pcr_set(int port, int bit, uint32_t d)
{
	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			*bit_band(VBAT_VBPCR, 3) = d;
			break;
		case 7:
			*bit_band(VBAT_VBPCR, 2) = d;
			break;
		case 8:
			*bit_band(VBAT_VBPCR, 0) = d;
			break;
		case 9:
			*bit_band(VBAT_VBPCR, 1) = d;
			break;
		default:
			*bit_band(GPIO_PCR + port * 4, bit) = d;
			break;
		}
	}
	else
	{
		*bit_band(GPIO_PCR + port * 4, bit) = d;
	}
	return;
}

void gpio_ddr_set(int port, int bit, uint32_t d)
{
	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			*bit_band(VBAT_VBDDR, 3) = d;
			break;
		case 7:
			*bit_band(VBAT_VBDDR, 2) = d;
			break;
		case 8:
			*bit_band(VBAT_VBDDR, 0) = d;
			break;
		case 9:
			*bit_band(VBAT_VBDDR, 1) = d;
			break;
		default:
			*bit_band(GPIO_DDR + port * 4, bit) = d;
			break;
		}
	}
	else
	{
		*bit_band(GPIO_DDR + port * 4, bit) = d;
	}
	return;
}

v32_t gpio_pdir_get(int port, int bit)
{
	v32_t d;

	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			d = *bit_band(VBAT_VBDIR, 3);
			break;
		case 7:
			d = *bit_band(VBAT_VBDIR, 2);
			break;
		case 8:
			d = *bit_band(VBAT_VBDIR, 0);
			break;
		case 9:
			d = *bit_band(VBAT_VBDIR, 1);
			break;
		default:
			d = *bit_band(GPIO_PDIR + port * 4, bit);
			break;
		}
	}
	else
	{
		d = *bit_band(GPIO_PDIR + port * 4, bit);
	}
	return d;
}

void gpio_pdor_set(int port, int bit, uint32_t d)
{
	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			*bit_band(VBAT_VBDOR, 3) = d;
			break;
		case 7:
			*bit_band(VBAT_VBDOR, 2) = d;
			break;
		case 8:
			*bit_band(VBAT_VBDOR, 0) = d;
			break;
		case 9:
			*bit_band(VBAT_VBDOR, 1) = d;
			break;
		default:
			*bit_band(GPIO_PDOR + port * 4, bit) = d;
			break;
		}
	}
	else
	{
		*bit_band(GPIO_PDOR + port * 4, bit) = d;
	}
	return;
}

static
const uint32_t ad2gpio[][2] = {
	//port,bit
	{0x01, 0x00},	// AN00
	{0x01, 0x01},	// AN01
	{0x01, 0x02},	// AN02
	{0x01, 0x03},	// AN03
	{0x01, 0x04},	// AN04
	{0x01, 0x05},	// AN05
	{0x01, 0x06},	// AN06
	{0x01, 0x07},	// AN07
	{0x01, 0x08},	// AN08
	{0x01, 0x09},	// AN09
	{0x01, 0x0a},	// AN10
	{0x01, 0x0b},	// AN11
	{0x01, 0x0c},	// AN12
	{0x01, 0x0d},	// AN13
	{0x01, 0x0e},	// AN14
	{0x02, 0x03},	// AN15
	{0x02, 0x02},	// AN16
	{0x02, 0x01},	// AN17
	{0x02, 0x00},	// AN18
	{0x00, 0x09},	// AN19
	{0x00, 0x08},	// AN20
	{0x00, 0x07},	// AN21
	{0x00, 0x06},	// AN22
	{0x00, 0x05},	// AN23
	{0xff, 0xff}
};

void gpio_ade_set(int port, int bit, uint32_t d)
{
	int n;
	for(n = 0; 0xff != ad2gpio[n][0]; n++)
	{
		if((ad2gpio[n][0] == port)
		&& (ad2gpio[n][1] == bit))
		{
			*bit_band(GPIO_ADE, n) = d;
		}
	}
	return;
}

void gpio_pzr_set(int port, int bit, uint32_t d)
{
	if(4 == port)
	{
		switch(bit)
		{
		case 6:
			*bit_band(VBAT_VBPZR, 3) = d;
			break;
		case 7:
			*bit_band(VBAT_VBPZR, 2) = d;
			break;
		case 8:
			*bit_band(VBAT_VBPZR, 0) = d;
			break;
		case 9:
			*bit_band(VBAT_VBPZR, 1) = d;
			break;
		default:
			*bit_band(GPIO_PZR + port * 4, bit) = d;
			break;
		}
	}
	else
	{
		*bit_band(GPIO_PZR + port * 4, bit) = d;
	}
	return;
}

void init_gpio(void)
{
	return;
}
