/*-------------------------------------------------------------------------
   LED function copy right information

   Copyright (C) 2006-2009. Lin, Rongrong <woody@palmmicro.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-------------------------------------------------------------------------*/

#include "version.h"
#include "sfr_gpio.h"
#include "type.h"
#include "core.h"
#include "bank1.h"

#if defined SERIAL_UI && !defined OEM_BT2008

const UCHAR _pLed[] = "LED ";

void LED_Init()
{
}

void _SerialLED(UCHAR iIndex, UCHAR iType)
{
	UCHAR pBuf[7];

	strcpy(pBuf, _pLed);
	pBuf[4] = iIndex + '0';
	pBuf[5] = iType;
	pBuf[6] = 0;

	SerialSendString(pBuf);
}

void LED_On(UCHAR iIndex)
{
	_SerialLED(iIndex, '0');
}

void LED_Off(UCHAR iIndex)
{
	_SerialLED(iIndex, '1');
}

void LED_Blink(UCHAR iIndex)
{
	_SerialLED(iIndex, '2');
}

#else

void LED_Init()
{
#if defined VER_AR168E || defined VER_AR168F || defined VER_GF302 || defined VER_AR168J || defined VER_YWH201 || defined VER_GP1266 || defined VER_BT2008 || defined VER_QX900W || defined VER_FWV2800
	rGPIO_G_Enable |= 0x01;									// GPIO_G0 output enable
#elif defined VER_AR168G
	rGPIO_C_Enable = (rGPIO_C_Enable & 0xbf) | 0x04;		// GPIO_C2 output enable, 10111111, 00000100
	rGPIO_G_Enable |= 0x01;									// GPIO_G0 output enable
#elif defined VER_AR168KD || defined VER_AR168KM
	rGPIO_C_Enable = (rGPIO_C_Enable & 0xef) | 0x01;		// GPIO_C0 output enable, 11101111, 00000001
	rGPIO_C_Enable = (rGPIO_C_Enable & 0xdf) | 0x02;		// GPIO_C1 output enable, 11011111, 00000010
#elif defined VER_AR168O || defined VER_AR168P || defined VER_GP2266 || defined VER_BT2008N || defined VER_DXDT
	rGPIO_C_Enable = (rGPIO_C_Enable & 0xef) | 0x01;		// GPIO_C0 output enable, 11101111, 00000001
	rGPIO_D_Output_Enable |= 0x20;							// GPIO_D5 output enable
	rGPIO_G_Enable |= 0x01;									// GPIO_G0 output enable
#elif defined VER_AR168M && defined OEM_BT2008
	rGPIO_C_Enable = (rGPIO_C_Enable & 0xbf) | 0x04;		// GPIO_C2 output enable, 10111111, 00000100
#endif
}

void LED_On(UCHAR iIndex)
{
	switch (iIndex)
	{
#if defined VER_AR168E || defined VER_AR168F || defined VER_GF302 || defined VER_AR168J
	case LED_LCD:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_MUTE:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

#elif defined VER_YWH201
	case LED_LCD:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

	case LED_MESSAGE:
	case LED_ACTIVE:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_MUTE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

#elif defined VER_AR168G
	case LED_LCD:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_MUTE:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_HOLD:
		rGPIO_C &= 0xfb;	// GPIO_C2 On, 11111011
		break;

#elif defined VER_GP1266 || defined VER_BT2008
	case LED_LCD:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_MUTE:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_HOLD:
		Led_PRE_On();
		break;

	case LED_TRANSFER:
		Led_WP_On();
		break;

#elif defined VER_QX900W
	case LED_LCD:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

	case LED_MUTE:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

#elif defined VER_AR168I
	case LED_LCD:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

#elif defined VER_AR168K
	case LED_LCD:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

#elif defined VER_AR168KD || defined VER_AR168KM
	case LED_LCD:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_MUTE:
		rGPIO_C &= ~0x01;	// GPIO_C0 On
		break;

	case LED_HOLD:
		rGPIO_C &= ~0x02;	// GPIO_C1 On
		break;

#elif defined VER_FWV2800
	case LED_LCD:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_TRANSFER:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

#elif defined VER_AR168O || defined VER_AR168P || defined VER_GP2266 || defined VER_BT2008N || defined VER_DXDT
	case LED_LCD:
		rGPIO_A &= 0xfd;	// GPIO_A1 On
		break;

	case LED_MESSAGE:
		rGPIO_A &= 0xfb;	// GPIO_A2 On
		break;

	case LED_MUTE:
		rGPIO_D &= 0xdf;	// GPIO_D5 On
		break;

	case LED_HOLD:
		rGPIO_C &= 0xfe;	// GPIO_C0 On, 11111110
		break;

	case LED_TRANSFER:
		rGPIO_G &= 0xfe;	// GPIO_G0 On
		break;

#elif defined VER_AR168M && defined OEM_BT2008
							// AR1688 pin name		pin number	AR168M name
	case LED_HOLD:
		rGPIO_B &= ~0x10;	// GPIO_B4 low			73			GPIO3
		break;

	case LED_MUTE:
		rGPIO_C &= ~0x04;	// GPIO_C2 low			45			GPIO7
		break;

	case LED_MESSAGE:
		rGPIO_B &= ~0x20;	// GPIO_B5 low			74			SMOSI
		break;

	case LED_ACTIVE:
		rGPIO_A &= ~0x04;	// GPIO_A2 low			65			module led
		break;

	case LED_RINGING:		
		rGPIO_B &= ~0x04;	// GPIO_B2 low			48			SCLK
		break;

	case LED_KEYPAD:		
		rGPIO_B |= 0x01;	// GPIO_B0 high			43			GPIO6
		break;
#endif
	}
}

void LED_Off(UCHAR iIndex)
{
#if defined OEM_2KLABS || defined OEM_WEBNEED
	if (iIndex == LED_LCD)
	{
		return;
	}
#endif
	switch (iIndex)
	{
#if defined VER_AR168E || defined VER_AR168F || defined VER_GF302 || defined VER_AR168J
	case LED_LCD:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_MUTE:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

#elif defined VER_YWH201
	case LED_LCD:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

	case LED_MESSAGE:
	case LED_ACTIVE:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_MUTE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

#elif defined VER_AR168G
	case LED_LCD:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_MUTE:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_HOLD:
		rGPIO_C |= 0x04;	// GPIO_C2 Off, 00000100
		break;

#elif defined VER_GP1266 || defined VER_BT2008
	case LED_LCD:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_MUTE:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_HOLD:
		Led_PRE_Off();
		break;

	case LED_TRANSFER:
		Led_WP_Off();
		break;

#elif defined VER_QX900W
	case LED_LCD:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

	case LED_MUTE:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

#elif defined VER_AR168I
	case LED_LCD:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

#elif defined VER_AR168K
	case LED_LCD:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

#elif defined VER_AR168KD || defined VER_AR168KM
	case LED_LCD:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_MUTE:
		rGPIO_C |= 0x01;	// GPIO_C0 Off
		break;

	case LED_HOLD:
		rGPIO_C |= 0x02;	// GPIO_C1 Off
		break;

#elif defined VER_FWV2800
	case LED_LCD:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_TRANSFER:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

#elif defined VER_AR168O || defined VER_AR168P || defined VER_GP2266 || defined VER_BT2008N || defined VER_DXDT
	case LED_LCD:
		rGPIO_A |= 0x02;	// GPIO_A1 Off
		break;

	case LED_MESSAGE:
		rGPIO_A |= 0x04;	// GPIO_A2 Off
		break;

	case LED_MUTE:
		rGPIO_D |= 0x20;	// GPIO_D5 Off
		break;

	case LED_HOLD:
		rGPIO_C |= 0x01;	// GPIO_C0 Off, 00000001
		break;

	case LED_TRANSFER:
		rGPIO_G |= 0x01;	// GPIO_G0 Off
		break;

#elif defined VER_AR168M && defined OEM_BT2008
							// AR1688 pin name		pin number	AR168M name
	case LED_HOLD:
		rGPIO_B |= 0x10;	// GPIO_B4 high			73			GPIO3
		break;

	case LED_MUTE:
		rGPIO_C |= 0x04;	// GPIO_C2 high			45			GPIO7
		break;

	case LED_MESSAGE:
		rGPIO_B |= 0x20;	// GPIO_B5 high			74			SMOSI
		break;

	case LED_ACTIVE:
		rGPIO_A |= 0x04;	// GPIO_A2 high			65			module led
		break;

	case LED_RINGING:		
		rGPIO_B |= 0x04;	// GPIO_B2 high			48			SCLK
		break;

	case LED_KEYPAD:		
		rGPIO_B &= ~0x01;	// GPIO_B0 low			43			GPIO6
		break;
#endif
	}
}

void LED_Blink(UCHAR iIndex)
{
	switch (iIndex)
	{
	case LED_MESSAGE:
#ifdef VER_YWH201
		if (rGPIO_A & 0x02)		// GPIO_A1 Off?
#elif defined VER_AR168M && defined OEM_BT2008
		if (rGPIO_B & 0x20)		// GPIO_B5 Off?
#elif !defined VER_AR168I && !defined VER_QX900W && !defined SLIC_79R70 && !defined SYS_PROGRAMMER
		if (rGPIO_A & 0x04)		// GPIO_A2 Off?
#else
		if (iIndex)
#endif
		{
			LED_On(LED_MESSAGE);
		}
		else
		{
			LED_Off(LED_MESSAGE);
		}
		break;
#if defined VER_AR168M && defined OEM_BT2008
	case LED_RINGING:
		if (rGPIO_B & 0x04)		// GPIO_B2 Off?
		{
			LED_On(LED_RINGING);
		}
		else
		{
			LED_Off(LED_RINGING);
		}
		break;
#endif
	}
}

#endif

void LED_SetState(UCHAR iIndex, BOOLEAN bOn)
{
	if (bOn)
	{
		LED_On(iIndex);
	}
	else
	{
		LED_Off(iIndex);
	}
}

#ifdef OEM_IP20

#include "ar168.h"

#define IP20_LED_NUM	15

const UCHAR ledMap[IP20_LED_NUM][2] = {{~0x01, ~0x00}, {~0x02, ~0x00}, {~0x04, ~0x00}, {~0x08, ~0x00}, {~0x10, ~0x00}, {~0x20, ~0x00}, {~0x40, ~0x00}, {~0x80, ~0x00}, 
										{~0x00, ~0x01}, {~0x00, ~0x02}, {~0x00, ~0x04}, {~0x00, ~0x08}, {~0x00, ~0x10}, {~0x00, ~0x20}, {~0x00, ~0x40}};
void IP20_LED_On(PCHAR pMatchNumber)
{
	UCHAR i;
	UCHAR pBuf[MAX_USER_NUMBER_LEN];
	PCHAR pTemp;

	pTemp = strchr(pMatchNumber,'<');
	if (pTemp) *pTemp = 0;

	for (i = 0; i < IP20_LED_NUM; i ++)
	{
		GetPhoneBookNumber(i + 1, pBuf);
		if (!strcmp(pMatchNumber, pBuf))
		{
			IP20_LedControl(ledMap[i][0], ledMap[i][1]);		
			break;
		}
	}	
}

void IP20_LED_Off()
{
	IP20_LedControl(~0x00, ~0x00); 
}
#endif

