Add basic change for v1453

Change-Id: I9497a61bbc3717f66413794a4e7dee0347c0bc33
diff --git a/mbtk/liblynq_lib_rilv2/lynq_irq.c b/mbtk/liblynq_lib_rilv2/lynq_irq.c
new file mode 100755
index 0000000..4e42e07
--- /dev/null
+++ b/mbtk/liblynq_lib_rilv2/lynq_irq.c
@@ -0,0 +1,475 @@
+#include "lynq-irq.h"
+#include "mbtk_type.h"
+#include "mbtk_info_api.h"
+#include "mbtk_log.h"
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+// #define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <poll.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+struct libirq_info {
+	unsigned int 	line;
+	unsigned int 	type;
+	int 			wake;
+	int				fd;
+	irq_handler 	handler;
+	unsigned int 	used;
+};
+
+struct libirq_context {
+	unsigned int		inited;
+	int					fd;
+	pthread_t 			th;
+	struct libirq_info	info[SC_LIBIRQ_MAX];
+};
+static struct libirq_context irq_ctx = {0};
+
+#define irq_init()			irq_ctx.inited
+#define line_used(l)		irq_ctx.info[l].used
+#define irq_fd(l)			irq_ctx.info[l].fd
+#define libirq_fd()			irq_ctx.fd
+
+static void *libirq_loop(void *arg)
+{
+	unsigned int int_status = 0;
+	int fd = libirq_fd();
+	int ret = 0;
+	int i;
+
+	while(1) {
+	    ret = ioctl(fd, SC_IRQ_GET_STATUS, &int_status);
+		if (ret < 0) {
+			LOGE("libirq_loop get status failed:%d", ret);
+		} else {
+/*			printf("libirq_loop get status :0x%x\n", int_status); */
+		}
+
+		for (i=0; i<SC_LIBIRQ_MAX; i++) {
+			if ((int_status & (1<<i)) && line_used(i) && irq_ctx.info[i].handler) {
+				irq_ctx.info[i].handler();
+
+			    ret = ioctl(fd, SC_IRQ_CLEAR_STATUS, 0);
+				if (ret < 0) {
+					LOGE("libirq_loop clear status failed:%d", ret);
+				}
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static int libirq_init_thread(void)
+{
+	int ret = 0;
+	pthread_attr_t attribute;
+
+    pthread_attr_init(&attribute);
+    pthread_attr_setstacksize(&attribute, 32*1024);
+
+	ret = pthread_create(&irq_ctx.th, &attribute, libirq_loop, NULL);
+	if(ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ *  Add a handler for an interrupt line.
+ *
+ *  line      		:  The interrupt line
+ *  handler         :  Function to be called when the IRQ occurs.
+ *  trig_type		:  rising edge or fallling edge
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_install(unsigned int line, irq_handler handler, int trig_type)
+{
+	int fd;
+	struct libirq_info *info;
+	char *usr_name;
+	int ret = 0;
+
+	if ((line >= SC_LIBIRQ_MAX) || (handler == NULL) || (trig_type >= SC_LIBIRQ_TYPE_MAX))
+		return -EINVAL;
+
+	if (line_used(line))
+		return -EEXIST;
+
+	ret = asprintf(&usr_name, "%s%d", SC_IRQ_DEV, line);
+	if (ret < 0) {
+		return -ENOMEM;
+	}
+
+	fd = open(usr_name, O_RDWR);
+	if(fd < 0) {
+		free(usr_name);
+		return -ENODEV;
+	}
+	irq_fd(line) = fd;
+	free(usr_name);
+	info = &irq_ctx.info[line];
+	info->line = line;
+	info->type = trig_type;
+	info->handler = handler;
+
+    if (ioctl(fd, SC_IRQ_INSTALL, trig_type) < 0) {
+        return -EPERM;
+    }
+
+	line_used(line) = 1;
+
+	if (!irq_init()) {
+		ret = libirq_init_thread();
+		if (ret) {
+			LOGE("libirq_init_thread, err:%d", ret);
+			return ret;
+		}
+
+		libirq_fd() = fd;
+		irq_init() = 1;
+	}
+
+	return 0;
+}
+
+/*
+ *  free an interrupt allocated with sc_irq_install.
+ *
+ *  line      		:  The interrupt line
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_uninstall(unsigned int line)
+{
+	int fd;
+
+	if (line >= SC_LIBIRQ_MAX)
+		return -EINVAL;
+
+	if (!line_used(line))
+		return -ENODEV;
+
+    if (ioctl(irq_fd(line), SC_IRQ_UNINSTALL, 0) < 0) {
+        return -EPERM;
+    }
+
+	fd = libirq_fd();
+	if (fd)
+		close(fd);
+
+	line_used(line) = 0;
+
+	return 0;
+}
+
+/*
+ *  set the irq trigger type for an irq.
+ *
+ *  line      		:  The interrupt line
+ *  trig_type		:  edge or level type
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_set_type(unsigned int line, int trig_type)
+{
+	struct libirq_info *info;
+
+	if ((line >= SC_LIBIRQ_MAX) || (trig_type >= SC_LIBIRQ_TYPE_MAX))
+		return -EINVAL;
+
+	if (!line_used(line))
+		return -EEXIST;
+
+	info = &irq_ctx.info[line];
+	//if (info->type != trig_type) {
+	    if (ioctl(irq_fd(line), SC_IRQ_SET_TYPE, trig_type) < 0) {
+			return -EPERM;
+		}
+	//}
+
+	info->type = trig_type;
+
+	return 0;
+}
+
+/*
+ *  get the irq trigger type for an irq.
+ *
+ *  line      		:  The interrupt line
+ *  trig_type		:  edge or level type
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_get_type(unsigned int line, int *trig_type)
+{
+	struct libirq_info *info;
+
+	if ((line >= SC_LIBIRQ_MAX) || !trig_type)
+		return -EINVAL;
+
+	if (!line_used(line))
+		return -EEXIST;
+
+	info = &irq_ctx.info[line];
+	*trig_type = info->type;
+
+	return 0;
+}
+
+/*
+ *  control irq power management wakeup.
+ *
+ *  line      		:  The interrupt line
+ *  en				:  enable/disable power management wakeup
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_set_wake(unsigned int line, int en)
+{
+	struct libirq_info *info;
+
+	if (line >= SC_LIBIRQ_MAX)
+		return -EINVAL;
+
+	if (!line_used(line))
+		return -EEXIST;
+
+	info = &irq_ctx.info[line];
+	if (info->wake != en) {
+	    if (ioctl(irq_fd(line), SC_IRQ_SET_WAKE, en) < 0) {
+			return -EPERM;
+		}
+	}
+
+	info->wake = en;
+
+	return 0;
+}
+
+/*
+ *  get the irq awake status for an irq.
+ *
+ *  line      		:  The interrupt line
+ *  en				:  enable/disable power management wakeup
+ *
+ *  return 0 if succeed, others failed
+ */
+int sc_irq_get_wake(unsigned int line, int *en)
+{
+	struct libirq_info *info;
+	unsigned int wake;
+
+	if (line >= SC_LIBIRQ_MAX)
+		return -EINVAL;
+
+	if (!line_used(line))
+		return -EEXIST;
+
+	if (ioctl(irq_fd(line), SC_IRQ_GET_WAKE, &wake) < 0) {
+		return -EPERM;
+	}
+
+	info = &irq_ctx.info[line];
+	info->wake = wake;
+	*en = wake;
+
+	return 0;
+}
+
+
+
+
+/*****************************************
+* @brief:lynq_irq_install
+* @param count [IN]:2
+* @param sum [OUT]:NA
+* @return :success 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+
+int lynq_irq_install(int line, irq_handler irq_test_handler, trig_type_e trig_type)
+{
+    int ret;
+
+    if (trig_type != 0 && trig_type != 1)
+    {
+        LOGE("lynq_irq_install error trig_type:%d", trig_type);
+        return -1;
+    }
+
+    line = line-117;
+    if (line < 0)
+    {
+        LOGE("lynq_irq_install error line:%d", line);
+        return -1;
+    }
+
+    ret = sc_irq_install(line, irq_test_handler, trig_type);
+    if (ret != 0)
+    {
+        LOGE("do_install_irq failed, ret:%d", ret);
+        return ret;
+    }
+    return 0;
+}
+
+
+/*****************************************
+* @brief:lynq_irq_uninstall
+* @param count [IN]:2
+* @param sum [OUT]:NA
+* @return :success 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+
+int lynq_irq_uninstall(int line)
+{
+    int ret;
+
+	line = line-117;
+    ret = sc_irq_uninstall(line);
+    if (ret != 0)
+    {
+        LOGE("unistall failed, ret:%d", ret);
+        return ret;
+    }
+    LOGI("uninstall irq(%d) ok", line);
+    return 0;
+}
+
+
+/*****************************************
+* @brief:lynq_irq_set_type
+* @param count [IN]:2
+* @param sum [OUT]:NA
+* @return :success 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+int lynq_irq_set_type(int line, int trig_type)
+{
+    int ret;
+
+    if (trig_type != 0 && trig_type != 1)
+    {
+        LOGE("lynq_irq_set_type error trig_type:%d", trig_type);
+        return -1;
+    }
+
+	line = line-117;
+    ret = sc_irq_set_type(line, trig_type);
+    if (ret != 0)
+    {
+        LOGE("set_type failed, ret:%d", ret);
+        return ret;
+    }
+    return 0;
+
+}
+
+/*****************************************
+* @brief:lynq_irq_get_type
+* @param count [IN]:1
+* @param sum [OUT]:NA
+* @return :success >= 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+int lynq_irq_get_type(int line)
+{
+    int ret;
+    int trig_type;
+
+    line = line-117;
+    ret = sc_irq_get_type(line, &trig_type);
+    if (ret != 0)
+    {
+        LOGE("get_type failed, ret:%d", ret);
+        return ret;
+    }
+    LOGI("get_type readback(%d)", trig_type);
+    return trig_type;
+}
+
+
+/*****************************************
+* @brief:lynq_irq_set_wake
+* @param count [IN]:2
+* @param sum [OUT]:NA
+* @return :success 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+int lynq_irq_set_wake(int line, int en)
+{
+    int ret;
+
+    if((en != 0) && (en != 1))
+    {
+        LOGE("wake_state is not 0 or 1");
+        return -1;
+    }
+
+    line = line-117;
+    ret = sc_irq_set_wake(line, en);
+    if (ret != 0)
+    {
+        LOGE("set_wake failed, ret:%d", ret);
+        return ret;
+    }
+    return 0;
+}
+
+/*****************************************
+* @brief:lynq_irq_get_wake
+* @param count [IN]:1
+* @param sum [OUT]:NA
+* @return :success >= 0, failed other
+* @todo:NA
+* @see:NA
+* @warning:NA
+******************************************/
+int lynq_irq_get_wake(int line)
+{
+    int ret;
+    int en;
+
+    line = line-117;
+    ret = sc_irq_get_wake(line, &en);
+    if (ret != 0)
+    {
+        LOGE("get_wake failed, ret:%d", ret);
+        return ret;
+    }
+    LOGI("get_wake readback(%d)", en);
+    return en;
+}
+
+
+