diff --git a/projects/imx6/patches/linux/linux-332-udoo-device_tree.patch b/projects/imx6/patches/linux/linux-331-udoo-device_tree.patch similarity index 61% rename from projects/imx6/patches/linux/linux-332-udoo-device_tree.patch rename to projects/imx6/patches/linux/linux-331-udoo-device_tree.patch index 7d6216cde0..35cf1ac14a 100644 --- a/projects/imx6/patches/linux/linux-332-udoo-device_tree.patch +++ b/projects/imx6/patches/linux/linux-331-udoo-device_tree.patch @@ -1,14 +1,14 @@ -From be220380dbd0a899ff49434d1b0c68c9b07830b6 Mon Sep 17 00:00:00 2001 +From 206e92e6a26ca57aff2ceba09275f5c1441a155c Mon Sep 17 00:00:00 2001 From: vpeter4 -Date: Thu, 11 Dec 2014 18:37:24 +0100 +Date: Wed, 3 Jun 2015 17:58:54 +0200 Subject: [PATCH] udoo quad device tree --- - arch/arm/boot/dts/imx6q-udoo.dts | 350 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 343 insertions(+), 7 deletions(-) + arch/arm/boot/dts/imx6q-udoo.dts | 348 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 342 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts -index 1b8cce1..83b9a62 100644 +index 7cc0267..d4f6acb 100644 --- a/arch/arm/boot/dts/imx6q-udoo.dts +++ b/arch/arm/boot/dts/imx6q-udoo.dts @@ -2,6 +2,10 @@ @@ -22,179 +22,171 @@ index 1b8cce1..83b9a62 100644 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as -@@ -16,14 +20,166 @@ - model = "Udoo i.MX6 Quad Board"; +@@ -17,12 +21,213 @@ compatible = "udoo,imx6q-udoo", "fsl,imx6q"; -- chosen { + chosen { - stdout-path = &uart2; -+ aliases { -+ mxcfb0 = &mxcfb1; -+ mxcfb1 = &mxcfb2; -+ mxcfb2 = &mxcfb3; -+ mxcfb3 = &mxcfb4; ++ stdout-path = &uart1; }; -+ chosen { -+ stdout-path = &uart1; -+ }; -+ ++ aliases { ++ mxcfb0 = &mxcfb1; ++ mxcfb1 = &mxcfb2; ++ mxcfb2 = &mxcfb3; ++ mxcfb3 = &mxcfb4; ++ }; ++ memory { reg = <0x10000000 0x40000000>; }; - -+ regulators { -+ compatible = "simple-bus"; + -+ reg_2p5v: 2p5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "2P5V"; -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: 3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "3P3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ aux_5v: aux5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "AUX_5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ gpio = <&gpio6 10 1>; -+ regulator-boot-on; -+ enable-active-high; -+ }; -+ -+ reg_sensor: sensor_supply { -+ compatible = "regulator-fixed"; -+ regulator-name = "sensor-SUPPLY"; -+ enable-active-high; -+ }; -+ -+ reg_usb_otg_vbus: usb_otg_vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb_otg_vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ }; -+ -+ reg_usb_h1_vbus: usb_h1_vbus { -+ compatible = "regulator-fixed"; -+ regulator-name = "usb_h1_vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */ -+ gpio = <&gpio7 12 0>; -+ }; -+ }; ++ regulators { ++ compatible = "simple-bus"; + -+ mxcfb1: fb@0 { -+ compatible = "fsl,mxc_sdc_fb"; -+ disp_dev = "hdmi"; -+ interface_pix_fmt = "RGB24"; -+ mode_str ="1920x1080M@60"; -+ default_bpp = <24>; -+ int_clk = <0>; -+ late_init = <0>; -+ status = "okay"; -+ }; -+ -+ mxcfb2: fb@1 { -+ compatible = "fsl,mxc_sdc_fb"; -+ disp_dev = "hdmi"; -+ interface_pix_fmt = "RGB24"; -+ mode_str ="1920x1080M@60"; -+ default_bpp = <24>; -+ int_clk = <0>; -+ late_init = <0>; -+ status = "disabled"; -+ }; -+ -+ mxcfb3: fb@2 { -+ compatible = "fsl,mxc_sdc_fb"; -+ disp_dev = "hdmi"; -+ interface_pix_fmt = "RGB24"; -+ mode_str ="1920x1080M@60"; -+ default_bpp = <24>; -+ int_clk = <0>; -+ late_init = <0>; -+ status = "disabled"; -+ }; -+ -+ mxcfb4: fb@3 { -+ compatible = "fsl,mxc_sdc_fb"; -+ disp_dev = "hdmi"; -+ interface_pix_fmt = "RGB24"; -+ mode_str ="1920x1080M@60"; -+ default_bpp = <24>; -+ int_clk = <0>; -+ late_init = <0>; -+ status = "disabled"; -+ }; ++ reg_2p5v: 2p5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "2P5V"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-always-on; ++ }; + -+ codec: vt1613 { -+ compatible = "wlf,vt1613"; -+ amic-mono; -+ }; ++ reg_3p3v: 3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "3P3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; + -+ sound { -+ compatible = "fsl,imx6q-udoo-vt1613", -+ "fsl,imx-audio-vt1613"; -+ model = "vt1613-audio"; -+ ssi-controller = <&ssi1>; -+ audio-codec = <&codec>; -+ audio-routing = -+ "Headphone Jack", "HPOUTL", -+ "Headphone Jack", "HPOUTR", -+ "Ext Spk", "SPKOUTL", -+ "Ext Spk", "SPKOUTR", -+ "MICBIAS", "AMIC", -+ "IN3R", "MICBIAS", -+ "DMIC", "MICBIAS", -+ "DMICDAT", "DMIC"; -+ mux-int-port = <1>; -+ mux-ext-port = <6>; -+ }; -+// hp-det-gpios = <&gpio7 8 1>; -+// mic-det-gpios = <&gpio1 9 1>; ++ aux_5v: aux5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "AUX_5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ gpio = <&gpio6 10 1>; ++ regulator-boot-on; ++ enable-active-high; ++ }; + -+ sound-hdmi { -+ compatible = "fsl,imx6q-audio-hdmi", -+ "fsl,imx-audio-hdmi"; -+ model = "imx-audio-hdmi"; -+ hdmi-controller = <&hdmi_audio>; -+ }; ++ reg_sensor: sensor_supply { ++ compatible = "regulator-fixed"; ++ regulator-name = "sensor-SUPPLY"; ++ enable-active-high; ++ }; + -+ sound-spdif { -+ compatible = "fsl,imx-audio-spdif", -+ "fsl,imx-sabreauto-spdif"; -+ model = "imx-spdif"; -+ spdif-controller = <&spdif>; -+ spdif-in; -+ status = "disabled"; -+ }; -+ -+ v4l2_out { -+ compatible = "fsl,mxc_v4l2_output"; -+ status = "okay"; -+ }; ++ reg_usb_otg_vbus: usb_otg_vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb_otg_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ }; ++ ++ reg_usb_h1_vbus: usb_h1_vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb_h1_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */ ++ gpio = <&gpio7 12 0>; ++ }; ++ }; ++ ++ mxcfb1: fb@0 { ++ compatible = "fsl,mxc_sdc_fb"; ++ disp_dev = "hdmi"; ++ interface_pix_fmt = "RGB24"; ++ mode_str ="1920x1080M@60"; ++ default_bpp = <24>; ++ int_clk = <0>; ++ late_init = <0>; ++ status = "okay"; ++ }; ++ ++ mxcfb2: fb@1 { ++ compatible = "fsl,mxc_sdc_fb"; ++ disp_dev = "hdmi"; ++ interface_pix_fmt = "RGB24"; ++ mode_str ="1920x1080M@60"; ++ default_bpp = <24>; ++ int_clk = <0>; ++ late_init = <0>; ++ status = "disabled"; ++ }; ++ ++ mxcfb3: fb@2 { ++ compatible = "fsl,mxc_sdc_fb"; ++ disp_dev = "hdmi"; ++ interface_pix_fmt = "RGB24"; ++ mode_str ="1920x1080M@60"; ++ default_bpp = <24>; ++ int_clk = <0>; ++ late_init = <0>; ++ status = "disabled"; ++ }; ++ ++ mxcfb4: fb@3 { ++ compatible = "fsl,mxc_sdc_fb"; ++ disp_dev = "hdmi"; ++ interface_pix_fmt = "RGB24"; ++ mode_str ="1920x1080M@60"; ++ default_bpp = <24>; ++ int_clk = <0>; ++ late_init = <0>; ++ status = "disabled"; ++ }; ++ ++ codec: vt1613 { ++ compatible = "wlf,vt1613"; ++ amic-mono; ++ }; ++ ++ sound { ++ compatible = "fsl,imx6q-udoo-vt1613", ++ "fsl,imx-audio-vt1613"; ++ model = "vt1613-audio"; ++ ssi-controller = <&ssi1>; ++ audio-codec = <&codec>; ++ audio-routing = ++ "Headphone Jack", "HPOUTL", ++ "Headphone Jack", "HPOUTR", ++ "Ext Spk", "SPKOUTL", ++ "Ext Spk", "SPKOUTR", ++ "MICBIAS", "AMIC", ++ "IN3R", "MICBIAS", ++ "DMIC", "MICBIAS", ++ "DMICDAT", "DMIC"; ++ mux-int-port = <1>; ++ mux-ext-port = <6>; ++ }; ++// hp-det-gpios = <&gpio7 8 1>; ++// mic-det-gpios = <&gpio1 9 1>; ++ ++ sound-hdmi { ++ compatible = "fsl,imx6q-audio-hdmi", ++ "fsl,imx-audio-hdmi"; ++ model = "imx-audio-hdmi"; ++ hdmi-controller = <&hdmi_audio>; ++ }; ++ ++ sound-spdif { ++ compatible = "fsl,imx-audio-spdif", ++ "fsl,imx-sabreauto-spdif"; ++ model = "imx-spdif"; ++ spdif-controller = <&spdif>; ++ spdif-in; ++ status = "disabled"; ++ }; ++ ++ v4l2_out { ++ compatible = "fsl,mxc_v4l2_output"; ++ status = "okay"; ++ }; ++}; + - poweroff { - compatible = "udoo,poweroff"; - sam3x_rst_gpio = <&gpio1 0 0>; -@@ -31,6 +187,55 @@ - }; - }; - +&hdmi_audio { + status = "okay"; +}; @@ -223,7 +215,7 @@ index 1b8cce1..83b9a62 100644 + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2_2>; + status = "okay"; -+ ++/* + egalax_ts@04 { + compatible = "eeti,egalax_ts"; + reg = <0x04>; @@ -231,7 +223,7 @@ index 1b8cce1..83b9a62 100644 + interrupts = <28 2>; + wakeup-gpios = <&gpio2 28 0>; + }; -+ ++*/ + hdmi: edid@50 { + compatible = "fsl,imx6-hdmi-i2c"; + reg = <0x50>; @@ -242,12 +234,10 @@ index 1b8cce1..83b9a62 100644 + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_5>; + status = "okay"; -+}; -+ + }; + &fec { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet>; -@@ -39,9 +244,68 @@ +@@ -33,9 +238,68 @@ }; &iomuxc { @@ -257,7 +247,7 @@ index 1b8cce1..83b9a62 100644 imx6q-udoo { - pinctrl_enet: enetgrp { + pinctrl_hog: hoggrp { - fsl,pins = < ++ fsl,pins = < + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x80000000 /* 5v enable */ + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000 /* Vtt suspend */ + MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x80000000 /* touch reset */ @@ -292,7 +282,7 @@ index 1b8cce1..83b9a62 100644 + }; + + pinctrl_i2c1_2: i2c1grp-2 { -+ fsl,pins = < + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + >; @@ -317,7 +307,7 @@ index 1b8cce1..83b9a62 100644 MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 -@@ -57,10 +321,10 @@ +@@ -51,10 +315,10 @@ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 @@ -330,7 +320,7 @@ index 1b8cce1..83b9a62 100644 pinctrl_uart2: uart2grp { fsl,pins = < MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1 -@@ -68,19 +332,51 @@ +@@ -62,19 +326,51 @@ >; }; @@ -384,7 +374,7 @@ index 1b8cce1..83b9a62 100644 &sata { status = "okay"; }; -@@ -91,9 +387,49 @@ +@@ -85,9 +381,49 @@ status = "okay"; }; @@ -436,4 +426,3 @@ index 1b8cce1..83b9a62 100644 }; -- 1.8.1.2 - diff --git a/projects/imx6/patches/linux/linux-331-udoo-poweroff-driver.patch b/projects/imx6/patches/linux/linux-331-udoo-poweroff-driver.patch deleted file mode 100644 index f1c39fef29..0000000000 --- a/projects/imx6/patches/linux/linux-331-udoo-poweroff-driver.patch +++ /dev/null @@ -1,254 +0,0 @@ -From c95f6c30e3230b02e90b98ca6ec8e8c2784141eb Mon Sep 17 00:00:00 2001 -From: vpeter4 -Date: Thu, 21 May 2015 20:42:22 +0200 -Subject: [PATCH] Add poweroff driver. - -Use original power_off function from rtc-snvs if set. -Arduino operation is controled by device tree parameter. - -From 1bc304cd507fe9eb5673223f0d76ec0aa4ff55f3 Mon Sep 17 00:00:00 2001 -From: mxt512 -Date: Thu, 13 Feb 2014 20:13:27 +0000 -Subject: [PATCH] Add poweroff driver. - -Existing pm_power_off function was in rtc-snvs. Given we need to reset the SAM3X and turn off -the 5v supply on power down, lets implement a power-off driver to do this for now. - -TODO: Not the cleanest solution but it works, should revisit. - Overwriting power_off function with udoo_power_off in case uddo is used. - ---- - arch/arm/boot/dts/imx6q-udoo.dts | 12 ++++ - arch/arm/mach-imx/mach-imx6q.c | 44 ++++++++++++++ - drivers/power/reset/Kconfig | 8 +++ - drivers/power/reset/Makefile | 1 + - drivers/power/reset/udoo-poweroff.c | 113 ++++++++++++++++++++++++++++++++++++ - 5 files changed, 178 insertions(+) - create mode 100644 drivers/power/reset/udoo-poweroff.c - -diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts -index 7cc0267..6c9d46f 100644 ---- a/arch/arm/boot/dts/imx6q-udoo.dts -+++ b/arch/arm/boot/dts/imx6q-udoo.dts -@@ -23,6 +23,13 @@ - memory { - reg = <0x10000000 0x40000000>; - }; -+ -+ poweroff { -+ compatible = "udoo,poweroff"; -+ sam3x_rst_gpio = <&gpio1 0 GPIO_ACTIVE_LOW>; -+ pwr_5v_gpio = <&gpio2 4 GPIO_ACTIVE_HIGH>; -+ arduino_mode = <0>; -+ }; - }; - - &fec { -diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c -index a466891..ed49659 100644 ---- a/arch/arm/mach-imx/mach-imx6q.c -+++ b/arch/arm/mach-imx/mach-imx6q.c -@@ -280,6 +280,46 @@ static inline void imx6q_enet_init(void) - imx6q_1588_init(); - } - -+#ifdef CONFIG_POWER_RESET_UDOO -+#define ARDUINO_MODE_STOPPED 1 /* does arduino starts at boot */ -+#define ARDUINO_MODE_LEAVE_POWER 2 /* leave 5V power on after shutdown (to keep arduino reset) */ -+ -+static inline void imx6q_udoo_gpio_init(void) -+{ -+ struct device_node *pwr_off_np; -+ int sam3x_rst_gpio = -EINVAL; -+ u32 arduino_mode = -EINVAL; -+ int ret; -+ -+ pwr_off_np = of_find_compatible_node(NULL, NULL, "udoo,poweroff"); -+ if (pwr_off_np == NULL) -+ return; -+ -+ pr_emerg("%s: setup sam3x reset gpio\n", __func__); -+ -+ ret = of_property_read_u32(pwr_off_np, "arduino_mode", &arduino_mode); -+ if (ret != 0) { -+ pr_err("%s: arduino mode not found in dtb\n", __func__); -+ arduino_mode = 0; -+ } -+ -+ pr_emerg("%s: arduino_mode set to %d\n", __func__, arduino_mode); -+ sam3x_rst_gpio = of_get_named_gpio(pwr_off_np, "sam3x_rst_gpio", 0); -+ of_node_put(pwr_off_np); -+ -+ if (gpio_is_valid(sam3x_rst_gpio)) { -+ if (arduino_mode & ARDUINO_MODE_STOPPED) { -+ pr_emerg("%s: arduino stopped\n", __func__); -+ ret = gpio_request_one(sam3x_rst_gpio, GPIOF_OUT_INIT_LOW, "sam3x_rst_gpio"); -+ } else { -+ ret = gpio_request_one(sam3x_rst_gpio, GPIOF_OUT_INIT_HIGH, "sam3x_rst_gpio"); -+ } -+ -+ ret = gpio_export(sam3x_rst_gpio, false); -+ } -+} -+#endif -+ - static void __init imx6q_init_machine(void) - { - struct device *parent; -@@ -299,6 +339,10 @@ static void __init imx6q_init_machine(void) - imx_anatop_init(); - cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init(); - imx6q_csi_mux_init(); -+ -+#ifdef CONFIG_POWER_RESET_UDOO -+ imx6q_udoo_gpio_init(); -+#endif - } - - #define OCOTP_CFG3 0x440 -diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig -index 6d452a7..1a0620f 100644 ---- a/drivers/power/reset/Kconfig -+++ b/drivers/power/reset/Kconfig -@@ -57,3 +57,11 @@ config POWER_RESET_XGENE - depends on POWER_RESET - help - Reboot support for the APM SoC X-Gene Eval boards. -+ -+config POWER_RESET_UDOO -+ bool "UDOO power-off driver" -+ depends on POWER_RESET -+ help -+ This driver supports powering down the UDOO. -+ Say Y if you have a UDOO. -+ -diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile -index a5b4a77..9b8e1b0 100644 ---- a/drivers/power/reset/Makefile -+++ b/drivers/power/reset/Makefile -@@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o - obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o - obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o - obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o -+obj-$(CONFIG_POWER_RESET_UDOO) += udoo-poweroff.o -diff --git a/drivers/power/reset/udoo-poweroff.c b/drivers/power/reset/udoo-poweroff.c -new file mode 100644 -index 0000000..2a2aecf ---- /dev/null -+++ b/drivers/power/reset/udoo-poweroff.c -@@ -0,0 +1,113 @@ -+/* -+ * UDOO board power off -+ * -+ * -+ * Copyright (C) 2014 Jasbir Matharu -+ * Copyright (C) 2015 vpeter -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ARDUINO_MODE_STOPPED 1 /* does arduino starts at boot */ -+#define ARDUINO_MODE_LEAVE_POWER 2 /* leave 5V power on after shutdown (to keep arduino reset) */ -+ -+static void (*pm_power_off_orig)(void) = NULL; -+static int sam3x_rst_gpio = -EINVAL; -+static int pwr_5v_gpio = -EINVAL; -+static u32 arduino_mode = -EINVAL; -+ -+static void udoo_power_off(void) { -+ int ret; -+ -+ pr_emerg("%s: powering off\n", __func__); -+ if (pm_power_off_orig != NULL) -+ pm_power_off_orig(); -+ -+ if (gpio_is_valid(sam3x_rst_gpio)) { -+ pr_emerg("%s: sam3x reset\n", __func__); -+ ret = gpio_direction_output(sam3x_rst_gpio, 0); -+ if (ret) -+ pr_emerg("%s: sam3x reset unsuccessful\n", __func__); -+ -+ msleep(50); -+ } -+ -+ if (gpio_is_valid(pwr_5v_gpio) && (arduino_mode & ARDUINO_MODE_LEAVE_POWER) == 0) { -+ pr_emerg("%s: 5V power down\n", __func__); -+ ret = gpio_request_one(pwr_5v_gpio, GPIOF_OUT_INIT_HIGH, "pwr_5v_gpio"); -+ if (ret) -+ pr_emerg("%s: 5V power down unsuccessful\n", __func__); -+ } else -+ pr_emerg("%s: 5V power still on, sam3x reset\n", __func__); -+} -+ -+static int udoo_power_off_probe(struct platform_device *pdev) -+{ -+ struct device_node *pwr_off_np; -+ int ret; -+ -+ pr_emerg("%s: power-off probe\n", __func__); -+ -+ pwr_off_np = of_find_compatible_node(NULL, NULL, "udoo,poweroff"); -+ if (pwr_off_np) { -+ ret = of_property_read_u32(pwr_off_np, "arduino_mode", &arduino_mode); -+ if (ret != 0) { -+ pr_emerg("%s: arduino mode not found in dtb\n", __func__); -+ arduino_mode = 0; -+ } -+ -+ sam3x_rst_gpio = of_get_named_gpio(pwr_off_np, "sam3x_rst_gpio", 0); -+ pwr_5v_gpio = of_get_named_gpio(pwr_off_np, "pwr_5v_gpio", 0); -+ of_node_put(pwr_off_np); -+ -+ pm_power_off_orig = pm_power_off; -+ pm_power_off = udoo_power_off; -+ return 0; -+ } -+ -+ /* If a pm_power_off function has already been added, leave it alone */ -+ if (pm_power_off != NULL) { -+ pr_emerg("%s: pm_power_off function already registered\n", __func__); -+ return -EBUSY; -+ } -+ -+ return -ENODEV; -+} -+ -+static int udoo_power_off_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+static const struct of_device_id power_off_dt_ids[] = { -+ { .compatible = "udoo,poweroff", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, power_off_dt_ids); -+ -+static struct platform_driver udoo_power_off_driver = { -+ .driver = { -+ .name = "udoo_power_off", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(power_off_dt_ids), -+ }, -+ .probe = udoo_power_off_probe, -+ .remove = udoo_power_off_remove, -+}; -+module_platform_driver(udoo_power_off_driver); -+ -+MODULE_AUTHOR("Jasbir Matharu, vpeter"); -+MODULE_DESCRIPTION("UDOO Power off driver v2"); -+MODULE_LICENSE("GPL v2"); --- -1.8.1.2 diff --git a/projects/imx6/patches/linux/linux-333-udoo-ts-poweroff-driver.patch b/projects/imx6/patches/linux/linux-333-udoo-ts-poweroff-driver.patch new file mode 100644 index 0000000000..c5f91070bd --- /dev/null +++ b/projects/imx6/patches/linux/linux-333-udoo-ts-poweroff-driver.patch @@ -0,0 +1,320 @@ +From 2e1bacff999529c9b91995db5d87ad6708e7d49e Mon Sep 17 00:00:00 2001 +From: vpeter4 +Date: Wed, 3 Jun 2015 19:09:09 +0200 +Subject: [PATCH] Add poweroff driver, enable touchscreen + +Use original power_off function from rtc-snvs if set. +Arduino operation is controled by device tree parameter. + +From 1bc304cd507fe9eb5673223f0d76ec0aa4ff55f3 Mon Sep 17 00:00:00 2001 +From: mxt512 +Date: Thu, 13 Feb 2014 20:13:27 +0000 +Subject: [PATCH] Add poweroff driver. + +Existing pm_power_off function was in rtc-snvs. Given we need to reset the SAM3X and turn off +the 5v supply on power down, lets implement a power-off driver to do this for now. + +TODO: Not the cleanest solution but it works, should revisit. + Overwriting power_off function with udoo_power_off in case uddo is used. + +--- + arch/arm/boot/dts/imx6q-udoo.dts | 83 +++++++++++++++++++ + drivers/power/reset/Kconfig | 8 ++ + drivers/power/reset/Makefile | 1 + + drivers/power/reset/udoo-poweroff.c | 159 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 251 insertions(+) + create mode 100644 drivers/power/reset/udoo-poweroff.c + +diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts +index d4f6acb..078a983 100644 +--- a/arch/arm/boot/dts/imx6q-udoo.dts ++++ b/arch/arm/boot/dts/imx6q-udoo.dts +@@ -179,6 +179,78 @@ + compatible = "fsl,mxc_v4l2_output"; + status = "okay"; + }; ++ ++ poweroff { ++ compatible = "udoo,poweroff"; ++ sam3x_rst_gpio = <&gpio1 0 GPIO_ACTIVE_LOW>; ++ pwr_5v_gpio = <&gpio2 4 GPIO_ACTIVE_HIGH>; ++ arduino_mode = <0>; ++ }; ++}; ++ ++&ldb { ++ ipu_id = <1>; ++ disp_id = <0>; ++ ext_ref = <1>; ++ mode = "sep0"; ++ sec_ipu_id = <1>; ++ sec_disp_id = <1>; ++ status = "okay"; ++ ++ lvds0: lvds-channel@0 { ++ fsl,data-mapping = "spwg"; ++ fsl,data-width = <18>; ++ status = "okay"; ++ ++ display-timings { ++ native-mode = <&timing0>; ++ timing0: 800x480 { /* 60 Hz */ ++ clock-frequency = <30000000>; ++ hactive = <800>; ++ vactive = <480>; ++ hback-porch = <50>; ++ hfront-porch = <50>; ++ vback-porch = <21>; ++ vfront-porch = <7>; ++ hsync-len = <60>; ++ vsync-len = <10>; ++ }; ++ ++ timing1: 1024x768 { /* 60 Hz */ ++ /* from u-boot-unico/board/udoo/udoo.c */ ++ /* Rif. Panel 1024x768 - UMSH-8596MD-15T - G156XW01V0 */ ++ clock-frequency = <65000000>; ++ hactive = <1024>; ++ vactive = <768>; ++ hback-porch = <220>; ++ hfront-porch = <40>; ++ vback-porch = <21>; ++ vfront-porch = <7>; ++ hsync-len = <60>; ++ vsync-len = <10>; ++ de-active = <0>; ++ pixelclk-active = <1>; ++ interlaced = <0>; ++ }; ++ ++ timing2: 1366x768 { /* 59 Hz */ ++ /* from u-boot-unico/board/udoo/udoo.c */ ++ /* Rif. 1366x768 Panel CHIMEI M156B3-LA1 */ ++ clock-frequency = <72000000>; ++ hactive = <1368>; ++ vactive = <768>; ++ hback-porch = <93>; ++ hfront-porch = <33>; ++ vback-porch = <22>; ++ vfront-porch = <7>; ++ hsync-len = <40>; ++ vsync-len = <4>; ++ de-active = <0>; ++ pixelclk-active = <1>; ++ interlaced = <0>; ++ }; ++ }; ++ }; + }; + + &hdmi_audio { +@@ -228,6 +300,17 @@ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_5>; + status = "okay"; ++ ++ touchscreen: st1232@55 { ++ compatible = "sitronix,st1232"; ++ reg = <0x55>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <13 IRQ_TYPE_LEVEL_LOW>; ++ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; ++ /* udoo poweroff driver */ ++ lcd_panel_on_gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; ++ lcd_backlight_gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>; ++ }; + }; + + &fec { +diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig +index 6d452a7..1a0620f 100644 +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -57,3 +57,11 @@ config POWER_RESET_XGENE + depends on POWER_RESET + help + Reboot support for the APM SoC X-Gene Eval boards. ++ ++config POWER_RESET_UDOO ++ bool "UDOO power-off driver" ++ depends on POWER_RESET ++ help ++ This driver supports powering down the UDOO. ++ Say Y if you have a UDOO. ++ +diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile +index a5b4a77..9b8e1b0 100644 +--- a/drivers/power/reset/Makefile ++++ b/drivers/power/reset/Makefile +@@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o + obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o + obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o + obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o ++obj-$(CONFIG_POWER_RESET_UDOO) += udoo-poweroff.o +diff --git a/drivers/power/reset/udoo-poweroff.c b/drivers/power/reset/udoo-poweroff.c +new file mode 100644 +index 0000000..b3f8db8 +--- /dev/null ++++ b/drivers/power/reset/udoo-poweroff.c +@@ -0,0 +1,159 @@ ++/* ++ * UDOO board power off ++ * ++ * Copyright (C) 2014 Jasbir Matharu ++ * Copyright (C) 2015 Peter Vicman ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ARDUINO_MODE_STOPPED 1 /* does arduino starts at boot */ ++#define ARDUINO_MODE_LEAVE_POWER 2 /* leave 5V power on after shutdown (to keep arduino reset) */ ++ ++static void (*pm_power_off_orig)(void) = NULL; ++static int sam3x_rst_gpio = -EINVAL; ++static int pwr_5v_gpio = -EINVAL; ++static u32 arduino_mode = -EINVAL; ++static int lcd_touch_reset_gpio = -EINVAL; ++static int lcd_panel_on_gpio = -EINVAL; ++static int lcd_backlight_gpio = -EINVAL; ++ ++static void udoo_set_gpio(unsigned gpio, int value) { ++ int ret; ++ ++ if (! gpio_is_valid(gpio)) ++ return; ++ ++ ret = gpio_direction_output(gpio, value); ++ if (ret) ++ pr_err("%s: gpio %u/%d failed\n", __func__, gpio, value); ++} ++ ++static void udoo_request_gpio(struct device *dev, unsigned gpio, unsigned long flags, const char *label) { ++ int ret; ++ ++ if (! gpio_is_valid(gpio)) ++ return; ++ ++ ret = devm_gpio_request_one(dev, gpio, flags, label); ++ if (ret) ++ dev_err(dev, "request of gpio %s %u failed with %d\n", label, gpio, ret); ++} ++ ++static void udoo_power_off(void) { ++ pr_emerg("%s: powering off\n", __func__); ++ ++ if (pm_power_off_orig != NULL) ++ pm_power_off_orig(); ++ ++ udoo_set_gpio(lcd_touch_reset_gpio, 1); ++ udoo_set_gpio(lcd_panel_on_gpio, 0); ++ udoo_set_gpio(lcd_backlight_gpio, 0); ++ ++ udoo_set_gpio(sam3x_rst_gpio, 0); ++ msleep(50); /* stop sam3x safely */ ++ ++ if (gpio_is_valid(pwr_5v_gpio) && (arduino_mode & ARDUINO_MODE_LEAVE_POWER) == 0) { ++ pr_emerg("%s: 5V power down\n", __func__); ++ udoo_set_gpio(pwr_5v_gpio, 1); ++ } else ++ pr_emerg("%s: 5V power still on, sam3x reset\n", __func__); ++} ++ ++static int udoo_power_off_probe(struct platform_device *pdev) ++{ ++ struct device_node *pwr_off_np; ++ int ret; ++ ++ dev_err(&pdev->dev, "%s: power-off probe\n", __func__); ++ ++ pwr_off_np = of_find_compatible_node(NULL, NULL, "sitronix,st1232"); ++ if (pwr_off_np) { ++ lcd_touch_reset_gpio = of_get_named_gpio(pwr_off_np, "gpios", 0); ++ lcd_panel_on_gpio = of_get_named_gpio(pwr_off_np, "lcd_panel_on_gpio", 0); ++ lcd_backlight_gpio = of_get_named_gpio(pwr_off_np, "lcd_backlight_gpio", 0); ++ of_node_put(pwr_off_np); ++ ++ udoo_request_gpio(&pdev->dev, lcd_panel_on_gpio, GPIOF_OUT_INIT_HIGH, "lcd_panel_on_gpio"); ++ udoo_request_gpio(&pdev->dev, lcd_backlight_gpio, GPIOF_OUT_INIT_HIGH, "lcd_backlight_gpio"); ++ ++ ret = gpio_export(lcd_backlight_gpio, false); ++ } ++ ++ pwr_off_np = of_find_compatible_node(NULL, NULL, "udoo,poweroff"); ++ if (pwr_off_np) { ++ ret = of_property_read_u32(pwr_off_np, "arduino_mode", &arduino_mode); ++ if (ret != 0) { ++ dev_err(&pdev->dev, "%s: arduino mode not found in dtb\n", __func__); ++ arduino_mode = 0; ++ } ++ ++ sam3x_rst_gpio = of_get_named_gpio(pwr_off_np, "sam3x_rst_gpio", 0); ++ pwr_5v_gpio = of_get_named_gpio(pwr_off_np, "pwr_5v_gpio", 0); ++ of_node_put(pwr_off_np); ++ ++ udoo_request_gpio(&pdev->dev, pwr_5v_gpio, GPIOF_OUT_INIT_LOW, "pwr_5v_gpio"); ++ ++ if (gpio_is_valid(sam3x_rst_gpio)) { ++ ret = gpio_export(sam3x_rst_gpio, false); ++ ++ if (arduino_mode & ARDUINO_MODE_STOPPED) { ++ dev_err(&pdev->dev, "%s: arduino stopped\n", __func__); ++ udoo_set_gpio(sam3x_rst_gpio, 0); ++ } else { ++ dev_err(&pdev->dev, "%s: arduino running\n", __func__); ++ udoo_set_gpio(sam3x_rst_gpio, 1); ++ } ++ } ++ ++ pm_power_off_orig = pm_power_off; ++ pm_power_off = udoo_power_off; ++ return 0; ++ } ++ ++ /* If a pm_power_off function has already been added, leave it alone */ ++ if (pm_power_off != NULL) { ++ dev_err(&pdev->dev, "%s: pm_power_off function already registered\n", __func__); ++ return -EBUSY; ++ } ++ ++ return -ENODEV; ++} ++ ++static int udoo_power_off_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static const struct of_device_id power_off_dt_ids[] = { ++ { .compatible = "udoo,poweroff", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, power_off_dt_ids); ++ ++static struct platform_driver udoo_power_off_driver = { ++ .driver = { ++ .name = "udoo_power_off", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(power_off_dt_ids), ++ }, ++ .probe = udoo_power_off_probe, ++ .remove = udoo_power_off_remove, ++}; ++module_platform_driver(udoo_power_off_driver); ++ ++MODULE_AUTHOR("Jasbir Matharu, Peter Vicman"); ++MODULE_DESCRIPTION("UDOO Power off driver v3"); ++MODULE_LICENSE("GPL v2"); +-- +1.8.1.2