Index: /branches/rel_apv_10_7/usr/click/bin/Makefile
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/Makefile	(revision 38128)
+++ /branches/rel_apv_10_7/usr/click/bin/Makefile	(working copy)
@@ -81,6 +81,7 @@
 	aewin_cb1939 \
 	led_screen	\
 	caswell_car3080 \
+	caswell_car5060 \
 	aewin_cb1920
 .else
 SUBDIR= aaad \
Index: /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/Makefile
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/Makefile	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/Makefile	(working copy)
@@ -0,0 +1,14 @@
+.PHONY=all
+EXEC=caswell_led
+ANROOT=${.CURDIR}/../../../../anroot
+
+all: caswell_led
+
+caswell_led: nuvoton-gpio-lib.c nuvoton-gpio-lib.h caswell_led.c
+	${CC} -o caswell_led nuvoton-gpio-lib.c caswell_led.c
+
+clean:
+	rm -f *.o ${EXEC}
+
+install:
+	install -Dm 0755 ${.CURDIR}/caswell_led ${ANROOT}/ca/bin/caswell_car5060/caswell_led
Index: /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/caswell_led.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/caswell_led.c	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/caswell_led.c	(working copy)
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "nuvoton-gpio-lib.h"
+
+#define LOW 				0
+#define HIGH				1
+
+#define RUN_GPIO_1          60
+#define RUN_GPIO_2          61
+#define WARN_GPIO_1         66
+#define WARN_GPIO_2         67
+
+static void _led_init(int gpio_pin)
+{
+	gpio_select_set(gpio_pin, GPIO_SELECT);
+	gpio_direction_set(gpio_pin, GPIO_OUTPUT);
+}
+
+static void _set_led(int gpio_pin, int led_status)
+{
+	gpio_output_set(gpio_pin, led_status);
+}
+
+/*
+    ./caswell_led <run/warn> <red/green/off>
+*/
+int main(int argc, char *argv[])
+{
+	int gpio_pin1, gpio_pin2;
+
+	if(strcmp(argv[1], "run") == 0)
+	{
+		gpio_pin1 = RUN_GPIO_1;
+		gpio_pin2 = RUN_GPIO_2;
+	}
+	else if(strcmp(argv[1], "warn") == 0)
+	{
+		gpio_pin1 = WARN_GPIO_1;
+		gpio_pin2 = WARN_GPIO_2;
+	}
+
+	_led_init(gpio_pin1);
+	_led_init(gpio_pin2);
+
+	if(strcmp(argv[2], "green") == 0)
+	{
+		_set_led(gpio_pin1, HIGH);
+		_set_led(gpio_pin2, LOW);
+	}
+	else if(strcmp(argv[2], "red") == 0)
+	{
+		_set_led(gpio_pin1, LOW);
+		_set_led(gpio_pin2, HIGH);
+	}
+	else if(strcmp(argv[2], "off") == 0)
+	{
+		_set_led(gpio_pin1, LOW);
+		_set_led(gpio_pin2, LOW);
+	}
+
+	return 0;
+}
Index: /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.h
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.h	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.h	(working copy)
@@ -0,0 +1,48 @@
+/*******************************************************************************
+
+  CASwell(R) Nuvoton Super I/O GPIO Control Sample Utility
+  Copyright(c) 2019 Alan Yu <alan.yu@cas-well.com>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+*******************************************************************************/
+
+#ifndef _NUVOTON_GPIO_LIB_H_
+#define _NUVOTON_GPIO_LIB_H_
+
+#define GPIO_NUVOTON_BASEPATH		"/sys/class/misc/gpio-nuvoton/"
+#define GPIO_NUVOTON_SELECT			GPIO_NUVOTON_BASEPATH"select"
+#define GPIO_NUVOTON_DIRECTION		GPIO_NUVOTON_BASEPATH"direction"
+#define GPIO_NUVOTON_INPUT			GPIO_NUVOTON_BASEPATH"input"
+#define GPIO_NUVOTON_OUTPUT			GPIO_NUVOTON_BASEPATH"output"
+#define GPIO_NUVOTON_INVERSE		GPIO_NUVOTON_BASEPATH"inverse"
+
+#define GPIO_SELECT					1
+#define GPIO_DESELECT				0
+#define GPIO_HIGH					1
+#define GPIO_LOW					0
+#define GPIO_INPUT					1
+#define GPIO_OUTPUT					0
+
+int gpio_select_get(unsigned int pin);
+int gpio_direction_get(unsigned int pin);
+int gpio_input_get(unsigned int pin);
+int gpio_output_get(unsigned int pin);
+int gpio_inverse_get(unsigned int pin);
+int gpio_select_set(unsigned int pin, unsigned int value);
+int gpio_direction_set(unsigned int pin, unsigned int value);
+int gpio_output_set(unsigned int pin, unsigned int value);
+int gpio_inverse_set(unsigned int pin, unsigned int value);
+
+#endif /* _NUVOTON_GPIO_LIB_H_ */
Index: /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.c	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/caswell_car5060/nuvoton-gpio-lib.c	(working copy)
@@ -0,0 +1,245 @@
+/*******************************************************************************
+
+  CASwell(R) Nuvoton Super I/O GPIO Control Sample Utility
+  Copyright(c) 2019 Alan Yu <alan.yu@cas-well.com>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+*******************************************************************************/
+
+
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "nuvoton-gpio-lib.h"
+
+static int _sysfs_node_write(char *pathname, char *value)
+{
+	char	rpath[PATH_MAX] = {0};
+	int		fd = -1;
+
+	if (!pathname || !value) {
+		fprintf(stderr, "Can not to write sysfs node with incorrect parameters!\n");
+		return (-1);
+	}
+
+	if (!realpath(pathname, rpath) || strncmp("/sys/", rpath, 5)) {
+		fprintf(stderr, "Only allow to write sysfs node!\n");
+		return (-1);
+	}
+
+	if ((fd = open(rpath, O_WRONLY)) < 0) {
+		fprintf(stderr, "Fail to open the sysfs node!\n");
+		return (-1);
+	}
+
+	if (write(fd, value, sizeof(value)) < 0) {
+		fprintf(stderr, "Fail to write the sysfs node!\n");
+		close(fd);
+		return (-1);
+	}
+
+	close(fd);
+
+	return (0);
+}
+
+static int _sysfs_node_read(char *pathname, char *value, int count)
+{
+
+	char	rpath[PATH_MAX] = {0};
+	int		fd = -1;
+	int		rbytes = 0;
+
+	if (!pathname || !value) {
+		fprintf(stderr, "Can not to read sysfs node with incorrect parameters!\n");
+		return (-1);
+	}
+
+	if (!realpath(pathname, rpath) || strncmp("/sys/", rpath, 5)) {
+		fprintf(stderr, "Only allow to read sysfs node!\n");
+		return (-1);
+	}
+
+	if ((fd = open(rpath, O_RDONLY)) < 0) {
+		fprintf(stderr, "Fail to open the sysfs node!\n");
+		return (-1);
+	}
+
+	if (read(fd, value, count) < 0) {
+		fprintf(stderr, "Fail to read the sysfs node!\n");
+		close(fd);
+		return (-1);
+	}
+
+	close(fd);
+
+	return (0);
+}
+
+int gpio_select_get(unsigned int pin)
+{
+	char	value[512] = {0};
+	int		group = pin / 10;
+	int		select;
+
+	if (_sysfs_node_read(GPIO_NUVOTON_SELECT, value, sizeof(value)) == 0) {
+		sscanf(value, "GPIO Ports%*[^]]]:\t%x", &select);
+		
+		if (select & (1 << group)) {
+			return (1);
+		} else {
+			return (0);
+		}
+	}
+
+	return (-1);
+}
+
+int gpio_direction_get(unsigned int pin)
+{
+	char	value[512] = {0};
+	char	needle[16] = {0};
+	char	*line = NULL;
+	int		group = pin / 10;
+	int		bit = pin % 10;
+	int		direction;
+	
+	if (_sysfs_node_read(GPIO_NUVOTON_DIRECTION, value, sizeof(value)) == 0) {
+		sprintf(needle, "GPIO Port%d:", group);
+		if ((line = strstr(value, needle))) {
+			sscanf(line, "GPIO Port%*[0-9]:\t%x", &direction);
+
+			if (direction & (1 << bit)) {
+				return (1);
+			} else {
+				return (0);
+			}
+		}
+	}
+
+	return (-1);
+}
+
+int gpio_input_get(unsigned int pin)
+{
+	char	value[512] = {0};
+	char	needle[16] = {0};
+	char	*line = NULL;
+	int		group = pin / 10;
+	int		bit = pin % 10;
+	int		lvl;
+
+	if (_sysfs_node_read(GPIO_NUVOTON_INPUT, value, sizeof(value)) == 0) {
+		sprintf(needle, "GPIO Port%d:", group);
+		if ((line = strstr(value, needle))) {
+			sscanf(line, "GPIO Port%*[0-9]:\t%x", &lvl);
+
+			if (lvl & (1 << bit)) {
+				return (1);
+			} else {
+				return (0);
+			}
+		}
+	}
+
+	return (-1);
+}
+		
+int gpio_output_get(unsigned int pin)
+{
+	char	value[512] = {0};
+	char	needle[16] = {0};
+	char	*line = NULL;
+	int		group = pin / 10;
+	int		bit = pin % 10;
+	int		lvl;
+
+	if (_sysfs_node_read(GPIO_NUVOTON_OUTPUT, value, sizeof(value)) == 0) {
+		sprintf(needle, "GPIO Port%d:", group);
+		if ((line = strstr(value, needle))) {
+			sscanf(line, "GPIO Port%*[0-9]:\t%x", &lvl);
+
+			if (lvl & (1 << bit)) {
+				return (1);
+			} else {
+				return (0);
+			}
+		}
+	}
+
+	return (-1);
+}
+		
+int gpio_inverse_get(unsigned int pin)
+{
+	char	value[512] = {0};
+	char	needle[16] = {0};
+	char	*line = NULL;
+	int		group = pin / 10;
+	int		bit = pin % 10;
+	int		inverse;
+
+	if (_sysfs_node_read(GPIO_NUVOTON_INVERSE, value, sizeof(value)) == 0) {
+		sprintf(needle, "GPIO Port%d:", group);
+		if ((line = strstr(value, needle))) {
+			sscanf(line, "GPIO Port%*[0-9]:\t%x", &inverse);
+
+			if (inverse & (1 << bit)) {
+				return (1);
+			} else {
+				return (0);
+			}
+		}
+	}
+
+	return (-1);
+}
+
+int gpio_select_set(unsigned int pin, unsigned int value)
+{
+	char	line[8] = {0};
+
+	sprintf(line, "%d %d", pin, value);
+	return (_sysfs_node_write(GPIO_NUVOTON_SELECT, line));
+}
+
+int gpio_direction_set(unsigned int pin, unsigned int value)
+{
+	char	line[8] = {0};
+
+	sprintf(line, "%d %d", pin, value);
+	return (_sysfs_node_write(GPIO_NUVOTON_DIRECTION, line));
+}
+
+int gpio_output_set(unsigned int pin, unsigned int value)
+{
+	char	line[8] = {0};
+
+	sprintf(line, "%d %d", pin, value);
+	return (_sysfs_node_write(GPIO_NUVOTON_OUTPUT, line));
+}
+
+int gpio_inverse_set(unsigned int pin, unsigned int value)
+{
+	char	line[8] = {0};
+
+	sprintf(line, "%d %d", pin, value);
+	return (_sysfs_node_write(GPIO_NUVOTON_INVERSE, line));
+}
Index: /branches/rel_apv_10_7/usr/click/bin/check_mainboard/check_mainboard.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/check_mainboard/check_mainboard.c	(revision 38128)
+++ /branches/rel_apv_10_7/usr/click/bin/check_mainboard/check_mainboard.c	(working copy)
@@ -1373,7 +1373,7 @@
 	return;
 }
 
-// CASWELL CAR-3080 only support 1 LED. use it as warning LED.
+// CASWELL CAR-3080 supports 2 LEDs. use it as warning LED.
 #define CASWELL_CAR3080_LED_RUN 0x01
 #define CASWELL_CAR3080_LED_WARN 0x02
 
@@ -1416,6 +1416,49 @@
 	}
 }
 
+// CASWELL CAR-5060 supports 2 LEDs. use it as warning LED.
+#define CASWELL_CAR5060_LED_RUN 0x01
+#define CASWELL_CAR5060_LED_WARN 0x02
+
+#define CASWELL_CAR5060_SET_RUN_LED_ON_CMD    ("/ca/bin/caswell_car5060/caswell_led run green")
+#define CASWELL_CAR5060_SET_RUN_LED_OFF_CMD   ("/ca/bin/caswell_car5060/caswell_led run off")
+#define CASWELL_CAR5060_SET_WARN_LED_ON_CMD    ("/ca/bin/caswell_car5060/caswell_led warn red")
+#define CASWELL_CAR5060_SET_WARN_LED_OFF_CMD   ("/ca/bin/caswell_car5060/caswell_led warn off")
+int
+caswell_car5060_check_led()
+{
+	int led_status = 0;
+	size_t len = 0;
+
+	len = sizeof(led_status);
+
+	while (1) {
+		if (u_sysctlbyname("net.inet.clicktcp.u_car5060_led_status", (void *)&led_status, (size_t *)&len, NULL, 0) < 0) {
+			printf("Unable to to get u_car5060_led_status\n");
+			sleep(3);
+			continue;
+		}
+
+		if (last_led_status != led_status) {
+			last_led_status = led_status;
+
+			if (led_status & CASWELL_CAR5060_LED_RUN) {
+				system(CASWELL_CAR5060_SET_RUN_LED_ON_CMD);
+			} else {
+				system(CASWELL_CAR5060_SET_RUN_LED_OFF_CMD);
+			}
+
+			if (led_status & CASWELL_CAR5060_LED_WARN) {
+				system(CASWELL_CAR5060_SET_WARN_LED_ON_CMD);
+			} else {
+				system(CASWELL_CAR5060_SET_WARN_LED_OFF_CMD);
+			}
+		}
+
+		usleep(10000);
+	}
+}
+
 // AEWIN CB-1920 supports 2 LEDs. use it as warning LED.
 #define AEWIN_CB1920_LED_RUN 0x01
 #define AEWIN_CB1920_LED_WARN 0x02
@@ -2534,6 +2577,7 @@
 			u_chipset_id != CHIPSET_ID_FT2000_4 && 
 			u_chipset_id != CHIPSET_ID_HW_FT2004 &&
 			u_chipset_id != CHIPSET_ID_CAR3080 &&
+			u_chipset_id != CHIPSET_ID_CAR5060 &&
 			u_chipset_id != CHIPSET_ID_CB1924 &&
 			u_chipset_id != CHIPSET_ID_CB1920 &&
 			u_check_ipmi_device_valid() < 0) {
@@ -2585,6 +2629,11 @@
 			if(res) {
 				printf("thread_led create err\n");
 			}
+		}else if(u_chipset_id == CHIPSET_ID_CAR5060) {
+			res = pthread_create(&thread_led, NULL, (void *)caswell_car5060_check_led, NULL);
+			if(res) {
+				printf("thread_led create err\n");
+			}
 		}else if(u_chipset_id == CHIPSET_ID_CB1920) {
 			res = pthread_create(&thread_led, NULL, (void *)aewin_cb1920_check_led, NULL);
 			if(res) {
Index: /branches/rel_apv_10_7/usr/click/tools/sysv_click
===================================================================
--- /branches/rel_apv_10_7/usr/click/tools/sysv_click	(revision 38128)
+++ /branches/rel_apv_10_7/usr/click/tools/sysv_click	(working copy)
@@ -197,7 +197,8 @@
 
 	# install gpio kmod for CAR-3080 motherboard
 	is_car_3080=`dmidecode -t2 | grep "CAR-3080"`
-	if [ ! -z "${is_car_3080}" ]; then
+	is_car_5060=`dmidecode -t2 | grep "CAR-5060"`
+	if [ ! -z "${is_car_3080}" ] || [ ! -z "${is_car_5060}" ]; then
 		gpio_driver=`lsmod | grep gpio_nuvoton`
 		if [ ! -z "${gpio_driver}" ]; then
 			echo "Already install kmod gpio_nuvoton"
Index: /branches/rel_apv_10_7/usr/src/sys/click/netinet/click_utils.c
===================================================================
--- /branches/rel_apv_10_7/usr/src/sys/click/netinet/click_utils.c	(revision 38128)
+++ /branches/rel_apv_10_7/usr/src/sys/click/netinet/click_utils.c	(working copy)
@@ -137,6 +137,7 @@
 uint32_t u_apv1880_led_status = 0;
 uint32_t u_scb1939_led_status = 0;
 uint32_t u_car3080_led_status = 0;
+uint32_t u_car5060_led_status = 0;
 uint32_t u_cb1920_led_status = 0;
 
 
@@ -156,6 +157,7 @@
 SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, u_apv1880_led_status, CTLFLAG_RW, &u_apv1880_led_status, 0, "");
 SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, u_scb1939_led_status, CTLFLAG_RW, &u_scb1939_led_status, 0, "");
 SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, u_car3080_led_status, CTLFLAG_RW, &u_car3080_led_status, 0, "");
+SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, u_car5060_led_status, CTLFLAG_RW, &u_car5060_led_status, 0, "");
 SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, u_cb1920_led_status, CTLFLAG_RW, &u_cb1920_led_status, 0, "");
 
 static void dump_mbuf_helper(uint32_t loglevel, struct mbuf *m, int depth);
@@ -1905,6 +1907,27 @@
 	}
 }
 
+// CASWELL CAR-3080 LED for APV7900/9900 and ASI11900
+#define CASWELL5060_LED_RUN 0x01
+#define CASWELL5060_LED_WARN 0x02
+
+static void caswell_car5060_led(int led_mask, int flag)
+{
+    if (led_mask == CASWELL5060_LED_RUN) {
+        if (flag == LED_ON) {
+            u_car5060_led_status |= CASWELL5060_LED_RUN;
+        } else {
+            u_car5060_led_status &= ~(CASWELL5060_LED_RUN);
+        }
+    } else if (led_mask == CASWELL5060_LED_WARN) {
+        if (flag == LED_ON) {
+            u_car5060_led_status |= CASWELL5060_LED_WARN;
+        } else {
+            u_car5060_led_status &= ~(CASWELL5060_LED_WARN);
+        }
+    }
+}
+
 // AEWIN CB-1920 LED for APV7900/9900
 #define AEWIN1920_LED_RUN 0x01
 #define AEWIN1920_LED_WARN 0x02
@@ -1978,6 +2001,10 @@
         ledctl_mode = LEDCTL_CASWELL_CAR3080;
     }
 
+    if (chipset_id == CHIPSET_ID_CAR5060) {
+        ledctl_mode = LEDCTL_CASWELL_CAR5060;
+    }
+
 	/*
 	 *    Bug 8843, panzj, 2004-09-27
 	 *    if model_id is 6,7,8,9
@@ -2016,6 +2043,9 @@
     case LEDCTL_CASWELL_CAR3080:
         caswell_car3080_led(CASWELL3080_LED_RUN, flag);
         break;
+    case LEDCTL_CASWELL_CAR5060:
+        caswell_car5060_led(CASWELL5060_LED_RUN, flag);
+        break;
 	default:
 		break;
  	}
@@ -2067,6 +2097,10 @@
 		ledctl_mode = LEDCTL_CASWELL_CAR3080;
 	}
 
+	if (chipset_id == CHIPSET_ID_CAR5060) {
+		ledctl_mode = LEDCTL_CASWELL_CAR5060;
+	}
+
 	if (chipset_id == CHIPSET_ID_CB1920) {
 		ledctl_mode = LEDCTL_AEWIN_CB1920;
 	}
@@ -2105,8 +2139,13 @@
 		break;
 	case LEDCTL_CASWELL_CAR3080:
 		caswell_car3080_led(CASWELL3080_LED_WARN, flag);
+		break;
+	case LEDCTL_CASWELL_CAR5060:
+		caswell_car5060_led(CASWELL5060_LED_WARN, flag);
+		break;
 	case LEDCTL_AEWIN_CB1920:
 		aewin_cb1920_led(AEWIN_LED_WARN, flag);
+		break;
 	default:
 		break;
 	}
