commit f53330bbdc86f8b9b5a9f20f6021c9cd946e9606
Author: yougang.hu <yougang.hu@lcfuturecenter.com>
Date:   Sat Oct 9 17:05:05 2021 +0800

    add typec mode switch ,(host 0/1)--(disconnect 3)--(device 2),write value to /sys/devices/external-connection/external-connection:extcon@1/typec_state_show

diff --git a/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-fixed-regulator-p2822-1000.dtsi b/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-fixed-regulator-p2822-1000.dtsi
index e3b197830..e7d255fd9 100644
--- a/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-fixed-regulator-p2822-1000.dtsi
+++ b/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-fixed-regulator-p2822-1000.dtsi
@@ -129,7 +129,7 @@
 			regulator-name = "vdd-5v-sata";
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
-			gpio = <&tegra_main_gpio TEGRA194_MAIN_GPIO(Z, 1) 0>;
+			gpio = <&tegra_main_gpio TEGRA194_MAIN_GPIO(A, 6) 0>;
 			enable-active-high;
 			vin-supply = <&battery_reg>;
 		};
diff --git a/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi b/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
index 784118b51..a768fb974 100644
--- a/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
+++ b/sources/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi
@@ -157,8 +157,8 @@ external-connection {
 					    0x0 0x2
 					    0x1 0x2
 					    0x2 0x1>;
-		gpios = <&tegra_main_gpio TEGRA194_MAIN_GPIO(M, 3) 0
-			&tegra_main_gpio TEGRA194_MAIN_GPIO(Q, 4) 0>;
+		gpios = <&tegra_main_gpio TEGRA194_MAIN_GPIO(Q, 4) 0>;
+		usb_vbus_en0_gpio = <&tegra_main_gpio TEGRA194_MAIN_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
 		power_gpio = <&tegra_aon_gpio TEGRA194_AON_GPIO(AA, 3) GPIO_ACTIVE_LOW>;
 		extcon-gpio,out-cable-names = <EXTCON_USB EXTCON_USB_HOST EXTCON_NONE>;
 		#extcon-cells = <1>;
diff --git a/sources/kernel/kernel-4.9/drivers/extcon/extcon-gpio-states.c b/sources/kernel/kernel-4.9/drivers/extcon/extcon-gpio-states.c
index 478767bdc..f62f8de89 100644
--- a/sources/kernel/kernel-4.9/drivers/extcon/extcon-gpio-states.c
+++ b/sources/kernel/kernel-4.9/drivers/extcon/extcon-gpio-states.c
@@ -64,6 +64,7 @@ struct gpio_extcon_platform_data {
 	int cable_id;
 	bool has_extcon_none_state;
 	int power_gpio;
+	int usb_vbus_en0_gpio;
 };
 
 struct gpio_extcon_info {
@@ -82,8 +83,13 @@ struct gpio_extcon_info {
 	unsigned int wakeup_cables;
 	bool sysfs_controlled;
 	int power_gpio;
+	int test_state;
+	int usb_vbus_en0_gpio;
 };
 
+
+
+
 static void gpio_extcon_scan_work(struct work_struct *work)
 {
 	int state = 0;
@@ -172,6 +178,86 @@ static void gpio_extcon_scan_work(struct work_struct *work)
 	extcon_set_state_sync(gpex->edev, gpex->pdata->cable_id, !!cstate);
 }
 
+
+static void gpio_extcon_set_state(struct gpio_extcon_info	*gpex)
+{
+	int cstate = -1;
+	int gstate = 0;
+	int i;
+	dev_info(gpex->dev, "gpex->last_cstate:%d, gpex->edev->state:%d ,gpex->sysfs_controlled :%s\n",
+			gpex->last_cstate, gpex->edev->state , gpex->sysfs_controlled ? "true":"false");
+
+	gstate=gpex->test_state;
+
+	for (i = 0; i < gpex->pdata->n_cable_states; ++i) {
+		if (gpex->pdata->cable_states[i].gstate == gstate) {
+			cstate = gpex->pdata->cable_states[i].cstate;
+			gpex->pdata->cable_id = cstate;
+			break;
+		}
+	}
+
+	if (cstate == -1) {
+		dev_info(gpex->dev, "Cable state not found 0x%02x\n", gstate);
+		cstate = 0;
+	}
+
+	dev_info(gpex->dev, "gstate:%d, cstate:%d ,has_extcon_none_state :%s\n",
+			gstate, cstate , gpex->pdata->has_extcon_none_state ? "true":"false");
+	if (gpex->last_cstate != cstate) {
+		if (gpex->pdata->has_extcon_none_state &&
+		    gpex->last_cstate == EXTCON_USB_HOST) {
+			cstate = EXTCON_NONE;
+			gpex->pdata->cable_id = cstate;
+		}
+
+		if (gpex->last_cstate)
+			extcon_set_state_sync(gpex->edev, gpex->last_cstate, 0);
+
+		gpex->last_cstate = cstate;
+	}
+
+	dev_info(gpex->dev, "Cable state:%d, cable id:%d\n",
+			!!cstate, gpex->pdata->cable_id);
+	if (!gpex->pdata->cable_id)
+		return;
+
+	extcon_set_state_sync(gpex->edev, gpex->pdata->cable_id, !!cstate);
+}
+
+static ssize_t typec_state_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct gpio_extcon_info *gpex = dev_get_drvdata(dev);
+		return sprintf(buf, "%s %d ,(host mode :0/1) <-> (disconnect/no cable :3 ) <-> (device mode :2) \n", "typec_state_show ",gpex->test_state);
+}
+
+static ssize_t typec_state_store(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	long		value;
+	ssize_t			status;
+	struct gpio_extcon_info *gpex = dev_get_drvdata(dev);
+	gpex->sysfs_controlled=true;
+	status = kstrtol(buf, 0, &value);
+	if (status == 0) {
+		gpex->test_state=value;
+	}else{
+		gpex->test_state=0;
+	}
+
+	printk("typec_state_store %s %d \n",buf,gpex->test_state);
+	if(gpex->test_state>1){
+		   gpio_set_value(gpex->usb_vbus_en0_gpio, 0);
+	}else{
+		   gpio_set_value(gpex->usb_vbus_en0_gpio, 1);
+	}
+	gpio_extcon_set_state(gpex);
+	gpex->sysfs_controlled=false;
+	return count;
+}
+static DEVICE_ATTR_RW(typec_state);
+
 static void gpio_extcon_notifier_timer(unsigned long _data)
 {
 	struct gpio_extcon_info *gpex = (struct gpio_extcon_info *)_data;
@@ -216,6 +302,11 @@ static struct gpio_extcon_platform_data *of_get_platform_data(
             dev_err(&pdev->dev, "extcon power_gpio fail\n");
     pdata->power_gpio=gpio;
 
+    gpio = of_get_named_gpio(np, "usb_vbus_en0_gpio", 0);
+    if ((gpio < 0) && (gpio != -ENOENT))
+            dev_err(&pdev->dev, "extcon usb_vbus_en0_gpio fail\n");
+    pdata->usb_vbus_en0_gpio=gpio;
+
 	ret = of_property_read_string(np, "label", &pdata->name);
 	if ((ret < 0) || !pdata->name)
 		ret = of_property_read_string(np, "extcon-gpio,name", &pdata->name);
@@ -353,6 +444,16 @@ static int gpio_extcon_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	if (gpio_is_valid(pdata->usb_vbus_en0_gpio)) {
+		dev_err(&pdev->dev," set usb_vbus_en0_gpio 1 \n");
+		ret = gpio_request(pdata->usb_vbus_en0_gpio, "usb_vbus_en0_gpio");
+		if (ret) {
+			dev_err(&pdev->dev," Failed to get usb_vbus_en0_gpio \n");
+		}
+		gpio_direction_output(pdata->usb_vbus_en0_gpio, 1);
+		gpex->usb_vbus_en0_gpio=pdata->usb_vbus_en0_gpio;
+    }
+
 	gpex->power_gpio=pdata->power_gpio;
 	gpex->edev->name = pdata->name;
 	gpex->debounce_jiffies = msecs_to_jiffies(pdata->debounce);
@@ -421,6 +522,7 @@ static int gpio_extcon_probe(struct platform_device *pdev)
 				BIT(pdata->init_state));
 		}
 	}
+	device_create_file(gpex->dev, &dev_attr_typec_state);
 
 	return 0;
 }
