[Feature][ZXW-295]add driver:lynq_gpio_init, init status(gpio 127)output high

Only Configure: No
Affected branch: master
Affected module: gpio
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I3988f3637ef80b1593a580fa77005a05b23bb33a
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
index 4f4e580..ca14eb2 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc_ref.dts
@@ -204,6 +204,14 @@
 	linux,code = <KEY_WAKEUP>;
 	status = "disabled";//jb.qi change on 20231204
 };
-
+//xf.li add for status init start
+&gpio_init {
+       status_127{
+                gpio_num = <127>;
+                gpio_dir = <1>;
+                gpio_dout = <1>;
+        };
+//xf.li add for status init end
+};
 
 
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
index 006a945..9d2cb3c 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
@@ -905,7 +905,6 @@
 			status = "disabled";
 		};
 
-
 	};
 	firmware {
 		optee {
@@ -913,6 +912,11 @@
 			method = "icp";
 		};
 	};
+//xf.li add for status init start
+	gpio_init: gpio_init {
+		compatible = "lynq,gpio_init";
+	};
+//xf.li add for status init end
 };
 
 #include "zx297520v3-pinctrl.dtsi"
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/Makefile b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/Makefile
index 5762280..f920c5e 100644
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/Makefile
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/Makefile
@@ -22,7 +22,9 @@
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
 obj-y				+= video/
 obj-y				+= idle/
-
+#xf.li add for status init start
+obj-y				+= lynq_gpio_init/
+#xf.li add for status init end
 # IPMI must come before ACPI in order to provide IPMI opregion support
 obj-y				+= char/ipmi/
 
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/Makefile b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/Makefile
new file mode 100644
index 0000000..0f7ff3d
--- /dev/null
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/Makefile
@@ -0,0 +1,2 @@
+
+obj-y	+= lynq_gpio_init.o
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.c
new file mode 100755
index 0000000..5216ddb
--- /dev/null
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.c
@@ -0,0 +1,52 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include "lynq_gpio_init.h"
+
+static int __init lynq_gpio_init(void)
+{
+	struct device_node *gpio_device_node = NULL;
+    struct device_node *gpio_next_node = NULL;
+    int ret = 0;
+	int node_num = 0;
+    int i;
+
+    printk("GPIO_INIT:init start");
+    //find the dts node
+    gpio_device_node = of_find_node_by_path("/gpio_init");
+    if(gpio_device_node == NULL)
+    {
+        printk("GPIO_INIT: get DTS property failed!\n");
+        return 0;
+    }
+    //get the number of gpio_init child node
+    node_num = of_get_child_count(gpio_device_node);
+//set each gpio
+   for(i = 0; i < node_num; i++)
+   {
+        gpio_next_node = of_get_next_child(gpio_device_node, gpio_next_node);
+        if(gpio_next_node)
+        {
+            printk("GPIO_INIT: exist this node");
+        }
+        else
+        {
+            printk("GPIO_INIT: no more node");
+            break;
+        }
+        ret = set_gpio(gpio_next_node, i);        
+    }
+
+    printk("GPIO_INIT:END");
+    return 0;
+}
+device_initcall(lynq_gpio_init);
+MODULE_AUTHOR("Mobiletek");
+MODULE_DESCRIPTION("driver for init gpio");
+MODULE_LICENSE("GPL");
+
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.h b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.h
new file mode 100755
index 0000000..6025e98
--- /dev/null
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/lynq_gpio_init/lynq_gpio_init.h
@@ -0,0 +1,136 @@
+#include <linux/init.h>

+#include <linux/kernel.h>

+#include <linux/module.h>

+#include <linux/gpio.h>

+#include <linux/of.h>

+#include <linux/of_gpio.h>

+#include <linux/kobject.h>

+#include <linux/platform_device.h>

+#include <linux/device.h> 

+#include <linux/string.h> 

+#include <linux/sysfs.h> 

+#include <linux/stat.h> 

+#include <linux/slab.h>

+#include <linux/delay.h>

+

+struct gpio_node{

+    unsigned gpio_num;

+	int gpio_dir;

+	int gpio_dout;

+    int pre_mdelay_time;

+    int post_mdelay_time;

+};

+

+int set_gpio(struct device_node *gpio_node, int num);

+

+int set_gpio(struct device_node *gpio_node, int num)

+{

+    int ret = 0;

+    unsigned int gpio_num, gpio_dir, gpio_dout, pre_mdelay_time, post_mdelay_time;

+

+    ret = of_property_read_u32(gpio_node, "pre_mdelay_time", &pre_mdelay_time);

+    if(ret == -EINVAL || ret == -ENODATA)

+    {

+        printk("no value or no node");

+    }

+    else if(ret < 0)

+    {

+        printk("GPIO_INIT:READ ERROR: %d", ret);

+        return ret;

+    }

+    else

+    {

+        mdelay(pre_mdelay_time);

+    }

+

+    //get the gpio num

+    ret = of_property_read_u32(gpio_node, "gpio_num", &gpio_num);

+    if(ret == -EINVAL || ret == -ENODATA)

+    {

+        printk("no value or no node");

+        return 0;

+    }

+    else if(ret < 0)

+    {

+        printk("GPIO_INIT:READ ERROR: %d", ret);

+        return ret;

+    }

+

+    printk("GPIO_INIT: the gpio_num is %u", gpio_num);

+    //end of get gpio num

+

+//set gpio dir

+    ret = of_property_read_u32(gpio_node, "gpio_dir", &gpio_dir);

+    if(ret == -EINVAL || ret == -ENODATA)

+    {

+        printk("no value or no node");

+        return ret;

+    }

+    else if(ret < 0)

+    {

+        printk("GPIO_INIT:READ ERROR: %d", ret);

+        return ret;

+    }

+    if(gpio_dir == 0)

+    {

+        printk("GPIO_INIT: gpio_dir is 0, input");

+        gpio_direction_input(gpio_num);

+    }

+    else if (gpio_dir == 1)

+    {

+        //set gpio dout

+        printk("GPIO_INIT: gpio_dir is 1, output");

+        ret = of_property_read_u32(gpio_node, "gpio_dout", &gpio_dout);

+        if(ret == -EINVAL || ret == -ENODATA)

+        {

+            printk("no value or no node");;

+        }

+        else if(ret < 0)

+        {

+            printk("GPIO_INIT:READ ERROR: %d", ret);

+            return ret;

+        }

+        else

+        {

+            printk("GPIO_INIT: the gpio_dout is %u", gpio_dout);

+            if(gpio_dout == 0 || gpio_dout == 1)

+            {

+                ret = gpio_direction_output(gpio_num, gpio_dout);

+                if(ret == 0)

+                {

+                    printk("GPIO_INIT: modify successfully"); 

+                }

+                else

+                {

+                    printk("GPIO_INIT: SET REEOR %d", ret);

+                    return ret;

+                }

+            }

+            else

+            {

+                printk("GPIO_INIT: dout: %u out of the range 0-1\n", gpio_dout);

+            }

+        }

+    }

+    else

+    {

+        printk("GPIO_INIT: gpio_dir: %u out of the range 0-1\n", gpio_dir);

+    }

+

+    ret = of_property_read_u32(gpio_node, "post_mdelay_time", &post_mdelay_time);

+    if(ret == -EINVAL || ret == -ENODATA)

+    {

+        printk("no value or no node");

+    }

+    else if(ret < 0)

+    {

+        printk("GPIO_INIT:READ ERROR: %d", ret);

+        return ret;

+    }

+    else

+    {

+        mdelay(post_mdelay_time);

+    }

+

+    return ret;

+}