Merge pull request #4181 from vpeter4/udoo_power

projects/imx6/patches/linux: update udoo poweroff driver
This commit is contained in:
Stephan Raue 2015-06-04 11:06:04 +02:00
commit b6154364b0
3 changed files with 485 additions and 430 deletions

View File

@ -1,14 +1,14 @@
From be220380dbd0a899ff49434d1b0c68c9b07830b6 Mon Sep 17 00:00:00 2001
From 206e92e6a26ca57aff2ceba09275f5c1441a155c Mon Sep 17 00:00:00 2001
From: vpeter4 <peter.vicman@gmail.com>
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

View File

@ -1,254 +0,0 @@
From c95f6c30e3230b02e90b98ca6ec8e8c2784141eb Mon Sep 17 00:00:00 2001
From: vpeter4 <peter.vicman@gmail.com>
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 <mtx512@yahoo.co.uk>
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 <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+#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

View File

@ -0,0 +1,320 @@
From 2e1bacff999529c9b91995db5d87ad6708e7d49e Mon Sep 17 00:00:00 2001
From: vpeter4 <peter.vicman@gmail.com>
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 <mtx512@yahoo.co.uk>
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 <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+#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