sunxi: add initial 3.18 support
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@43337 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
6dd99a3912
commit
d9d14f267c
|
@ -0,0 +1,28 @@
|
|||
From 0253d14782f80cfd1741d4ddd82b83dd7d44a91e Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 28 Jul 2014 22:44:59 +0200
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add spi0_pins_a pinctrl setting
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
index 82097c9..4fb8930 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -784,6 +784,13 @@
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
+ spi0_pins_a: spi0@0 {
|
||||
+ allwinner,pins = "PI10", "PI11", "PI12", "PI13", "PI14";
|
||||
+ allwinner,function = "spi0";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
+
|
||||
spi1_pins_a: spi1@0 {
|
||||
allwinner,pins = "PI16", "PI17", "PI18", "PI19";
|
||||
allwinner,function = "spi1";
|
|
@ -0,0 +1,31 @@
|
|||
From e37ccbcd4587b7a2b943e23a9943b8917010b336 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Oct 2014 08:39:58 +0200
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add uart3_pins_b pinctrl setting
|
||||
|
||||
The uart3_pins_a multiplexes the uart3 pins to port G, add a pinctrl entry
|
||||
for mapping them to port H (as used on the Bananapi).
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
index 4fb8930..cecf32c 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -677,6 +677,13 @@
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
+ uart3_pins_b: uart3@1 {
|
||||
+ allwinner,pins = "PH0", "PH1";
|
||||
+ allwinner,function = "uart3";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
+
|
||||
uart4_pins_a: uart4@0 {
|
||||
allwinner,pins = "PG10", "PG11";
|
||||
allwinner,function = "uart4";
|
|
@ -0,0 +1,28 @@
|
|||
From f65624ca1b67c5683317b75da2c09ffadc22fa2e Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Oct 2014 00:40:57 +0200
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add mmc2_pins_a pinctrl definition
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
index cecf32c..f0a75c6 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -833,6 +833,13 @@
|
||||
allwinner,pull = <1>;
|
||||
};
|
||||
|
||||
+ mmc2_pins_a: mmc2@0 {
|
||||
+ allwinner,pins = "PC6","PC7","PC8","PC9","PC10","PC11";
|
||||
+ allwinner,function = "mmc2";
|
||||
+ allwinner,drive = <2>;
|
||||
+ allwinner,pull = <1>;
|
||||
+ };
|
||||
+
|
||||
mmc3_pins_a: mmc3@0 {
|
||||
allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
|
||||
allwinner,function = "mmc3";
|
|
@ -0,0 +1,412 @@
|
|||
From 2c1fab89e83245a520871e807e233e66cbdb7c57 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Jan 2014 19:44:49 +0100
|
||||
Subject: [PATCH] input: Add new sun4i-lradc-keys driver
|
||||
|
||||
Allwinnner sunxi SoCs have a low resolution adc (called lradc) which is
|
||||
specifically designed to have various (tablet) keys (ie home, back, search,
|
||||
etc). attached to it using a resistor network. This adds a driver for this.
|
||||
|
||||
There are 2 channels, currently this driver only supports chan0 since there
|
||||
are no boards known to use chan1.
|
||||
|
||||
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and
|
||||
a20-olinuxino-micro.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
--
|
||||
Changes in v2:
|
||||
-Change devicetree bindings to use a per key subnode, like gpio-keys does
|
||||
---
|
||||
.../devicetree/bindings/input/sun4i-lradc-keys.txt | 62 +++++
|
||||
MAINTAINERS | 7 +
|
||||
drivers/input/keyboard/Kconfig | 10 +
|
||||
drivers/input/keyboard/Makefile | 1 +
|
||||
drivers/input/keyboard/sun4i-lradc-keys.c | 258 +++++++++++++++++++++
|
||||
5 files changed, 338 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
|
||||
create mode 100644 drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
|
||||
new file mode 100644
|
||||
index 0000000..b9c32f6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
|
||||
@@ -0,0 +1,62 @@
|
||||
+Allwinner sun4i low res adc attached tablet keys
|
||||
+------------------------------------------------
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible: "allwinner,sun4i-a10-lradc-keys"
|
||||
+ - reg: mmio address range of the chip
|
||||
+ - interrupts: interrupt to which the chip is connected
|
||||
+ - vref-supply: powersupply for the lradc reference voltage
|
||||
+
|
||||
+Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys":
|
||||
+
|
||||
+Required subnode-properties:
|
||||
+ - label: Descriptive name of the key.
|
||||
+ - linux,code: Keycode to emit.
|
||||
+ - channel: Channel this key is attached to, mut be 0 or 1.
|
||||
+ - voltage: Voltage in µV at lradc input when this key is pressed.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+#include <dt-bindings/input/input.h>
|
||||
+
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01c22800 0x100>;
|
||||
+ interrupts = <31>;
|
||||
+ vref-supply = <®_vcc3v0>;
|
||||
+
|
||||
+ button@191 {
|
||||
+ label = "Volume Up";
|
||||
+ linux,code = <KEY_VOLUMEUP>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <191274>;
|
||||
+ };
|
||||
+
|
||||
+ button@392 {
|
||||
+ label = "Volume Down";
|
||||
+ linux,code = <KEY_VOLUMEDOWN>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <392644>;
|
||||
+ };
|
||||
+
|
||||
+ button@601 {
|
||||
+ label = "Menu";
|
||||
+ linux,code = <KEY_MENU>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <601151>;
|
||||
+ };
|
||||
+
|
||||
+ button@795 {
|
||||
+ label = "Enter";
|
||||
+ linux,code = <KEY_ENTER>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <795090>;
|
||||
+ };
|
||||
+
|
||||
+ button@987 {
|
||||
+ label = "Home";
|
||||
+ linux,code = <KEY_HOMEPAGE>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <987387>;
|
||||
+ };
|
||||
+ };
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index a20df9b..73d1aef 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -8932,6 +8932,13 @@ F: arch/m68k/sun3*/
|
||||
F: arch/m68k/include/asm/sun3*
|
||||
F: drivers/net/ethernet/i825xx/sun3*
|
||||
|
||||
+SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER
|
||||
+M: Hans de Goede <hdegoede@redhat.com>
|
||||
+L: linux-input@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
|
||||
+F: drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
+
|
||||
SUNDANCE NETWORK DRIVER
|
||||
M: Denis Kirjanov <kda@linux-powerpc.org>
|
||||
L: netdev@vger.kernel.org
|
||||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
|
||||
index a3958c6..2d11b44 100644
|
||||
--- a/drivers/input/keyboard/Kconfig
|
||||
+++ b/drivers/input/keyboard/Kconfig
|
||||
@@ -567,6 +567,16 @@ config KEYBOARD_STMPE
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called stmpe-keypad.
|
||||
|
||||
+config KEYBOARD_SUN4I_LRADC
|
||||
+ tristate "Allwinner sun4i low res adc attached tablet keys support"
|
||||
+ depends on ARCH_SUNXI
|
||||
+ help
|
||||
+ This selects support for the Allwinner low res adc attached tablet
|
||||
+ keys found on Allwinner sunxi SoCs.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called sun4i-lradc-keys.
|
||||
+
|
||||
config KEYBOARD_DAVINCI
|
||||
tristate "TI DaVinci Key Scan"
|
||||
depends on ARCH_DAVINCI_DM365
|
||||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
|
||||
index 0a33456..a35269a 100644
|
||||
--- a/drivers/input/keyboard/Makefile
|
||||
+++ b/drivers/input/keyboard/Makefile
|
||||
@@ -53,6 +53,7 @@ obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
|
||||
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
|
||||
obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.o
|
||||
+obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
|
||||
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
|
||||
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
new file mode 100644
|
||||
index 0000000..f11f002
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
@@ -0,0 +1,258 @@
|
||||
+/*
|
||||
+ * Allwinner sun4i low res adc attached tablet keys driver
|
||||
+ *
|
||||
+ * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Allwinnner sunxi SoCs have a lradc which is specifically designed to have
|
||||
+ * various (tablet) keys (ie home, back, search, etc). attached to it using
|
||||
+ * a resistor network. This driver is for the keys on such boards.
|
||||
+ *
|
||||
+ * There are 2 channels, currently this driver only supports channel 0 since
|
||||
+ * there are no boards known to use channel 1.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define LRADC_CTRL 0x00
|
||||
+#define LRADC_INTC 0x04
|
||||
+#define LRADC_INTS 0x08
|
||||
+#define LRADC_DATA0 0x0c
|
||||
+#define LRADC_DATA1 0x10
|
||||
+
|
||||
+/* LRADC_CTRL bits */
|
||||
+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
|
||||
+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
|
||||
+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
|
||||
+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
|
||||
+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
|
||||
+#define HOLD_EN(x) ((x) << 6)
|
||||
+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
|
||||
+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
|
||||
+#define ENABLE(x) ((x) << 0)
|
||||
+
|
||||
+/* LRADC_INTC and LRADC_INTS bits */
|
||||
+#define CHAN1_KEYUP_IRQ BIT(12)
|
||||
+#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
|
||||
+#define CHAN1_HOLD_IRQ BIT(10)
|
||||
+#define CHAN1_KEYDOWN_IRQ BIT(9)
|
||||
+#define CHAN1_DATA_IRQ BIT(8)
|
||||
+#define CHAN0_KEYUP_IRQ BIT(4)
|
||||
+#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
|
||||
+#define CHAN0_HOLD_IRQ BIT(2)
|
||||
+#define CHAN0_KEYDOWN_IRQ BIT(1)
|
||||
+#define CHAN0_DATA_IRQ BIT(0)
|
||||
+
|
||||
+struct sun4i_lradc_keymap {
|
||||
+ u32 voltage;
|
||||
+ u32 keycode;
|
||||
+};
|
||||
+
|
||||
+struct sun4i_lradc_data {
|
||||
+ struct device *dev;
|
||||
+ struct input_dev *input;
|
||||
+ void __iomem *base;
|
||||
+ struct regulator *vref_supply;
|
||||
+ struct sun4i_lradc_keymap *chan0_map;
|
||||
+ u32 chan0_map_count;
|
||||
+ u32 chan0_keycode;
|
||||
+ u32 vref;
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct sun4i_lradc_data *lradc = dev_id;
|
||||
+ u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff;
|
||||
+
|
||||
+ ints = readl(lradc->base + LRADC_INTS);
|
||||
+
|
||||
+ /*
|
||||
+ * lradc supports only one keypress at a time, release does not give
|
||||
+ * any info as to which key was released, so we cache the keycode.
|
||||
+ */
|
||||
+ if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
|
||||
+ val = readl(lradc->base + LRADC_DATA0) & 0x3f;
|
||||
+ voltage = val * lradc->vref / 63;
|
||||
+
|
||||
+ for (i = 0; i < lradc->chan0_map_count; i++) {
|
||||
+ diff = abs(lradc->chan0_map[i].voltage - voltage);
|
||||
+ if (diff < closest) {
|
||||
+ closest = diff;
|
||||
+ keycode = lradc->chan0_map[i].keycode;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ lradc->chan0_keycode = keycode;
|
||||
+ input_report_key(lradc->input, lradc->chan0_keycode, 1);
|
||||
+ }
|
||||
+
|
||||
+ if (ints & CHAN0_KEYUP_IRQ) {
|
||||
+ input_report_key(lradc->input, lradc->chan0_keycode, 0);
|
||||
+ lradc->chan0_keycode = 0;
|
||||
+ }
|
||||
+
|
||||
+ input_sync(lradc->input);
|
||||
+
|
||||
+ writel(ints, lradc->base + LRADC_INTS);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_lradc_open(struct input_dev *dev)
|
||||
+{
|
||||
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regulator_enable(lradc->vref_supply);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* lradc Vref internally is divided by 2/3 */
|
||||
+ lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3;
|
||||
+
|
||||
+ /*
|
||||
+ * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
|
||||
+ * stabilize on press, wait (1 + 1) * 4 ms for key release
|
||||
+ */
|
||||
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
|
||||
+ SAMPLE_RATE(0) | ENABLE(1), lradc->base + LRADC_CTRL);
|
||||
+
|
||||
+ writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void sun4i_lradc_close(struct input_dev *dev)
|
||||
+{
|
||||
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
|
||||
+
|
||||
+ /* Disable lradc, leave other settings unchanged */
|
||||
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
|
||||
+ SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
|
||||
+ writel(0, lradc->base + LRADC_INTC);
|
||||
+
|
||||
+ regulator_disable(lradc->vref_supply);
|
||||
+}
|
||||
+
|
||||
+static int sun4i_lradc_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun4i_lradc_data *lradc;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct device_node *pp, *np = dev->of_node;
|
||||
+ u32 channel;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
|
||||
+ if (!lradc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ lradc->chan0_map_count = of_get_child_count(np);
|
||||
+ lradc->chan0_map = devm_kmalloc(dev, lradc->chan0_map_count *
|
||||
+ sizeof(struct sun4i_lradc_keymap), GFP_KERNEL);
|
||||
+ if (!lradc->chan0_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i = 0;
|
||||
+ for_each_child_of_node(np, pp) {
|
||||
+ struct sun4i_lradc_keymap *map = &lradc->chan0_map[i];
|
||||
+
|
||||
+ ret = of_property_read_u32(pp, "channel", &channel);
|
||||
+ if (ret || channel != 0) {
|
||||
+ dev_err(dev, "%s: Inval channel prop\n", pp->name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_u32(pp, "voltage", &map->voltage);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "%s: Inval voltage prop\n", pp->name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_u32(pp, "linux,code", &map->keycode);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ lradc->vref_supply = devm_regulator_get(dev, "vref");
|
||||
+ if (IS_ERR(lradc->vref_supply))
|
||||
+ return PTR_ERR(lradc->vref_supply);
|
||||
+
|
||||
+ lradc->dev = dev;
|
||||
+ lradc->input = devm_input_allocate_device(dev);
|
||||
+ if (!lradc->input)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ lradc->input->name = pdev->name;
|
||||
+ lradc->input->phys = "sun4i_lradc/input0";
|
||||
+ lradc->input->open = sun4i_lradc_open;
|
||||
+ lradc->input->close = sun4i_lradc_close;
|
||||
+ lradc->input->id.bustype = BUS_HOST;
|
||||
+ lradc->input->id.vendor = 0x0001;
|
||||
+ lradc->input->id.product = 0x0001;
|
||||
+ lradc->input->id.version = 0x0100;
|
||||
+ lradc->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY);
|
||||
+ for (i = 0; i < lradc->chan0_map_count; i++)
|
||||
+ set_bit(lradc->chan0_map[i].keycode, lradc->input->keybit);
|
||||
+ input_set_drvdata(lradc->input, lradc);
|
||||
+
|
||||
+ lradc->base = devm_ioremap_resource(dev,
|
||||
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
|
||||
+ if (IS_ERR(lradc->base))
|
||||
+ return PTR_ERR(lradc->base);
|
||||
+
|
||||
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), sun4i_lradc_irq,
|
||||
+ 0, "sun4i-a10-lradc-keys", lradc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = input_register_device(lradc->input);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, lradc);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sun4i_lradc_of_match[] = {
|
||||
+ { .compatible = "allwinner,sun4i-a10-lradc-keys", },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
|
||||
+
|
||||
+static struct platform_driver sun4i_lradc_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "sun4i-a10-lradc-keys",
|
||||
+ .of_match_table = of_match_ptr(sun4i_lradc_of_match),
|
||||
+ },
|
||||
+ .probe = sun4i_lradc_probe,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(sun4i_lradc_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver");
|
||||
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,28 @@
|
|||
From f39ea4358d2e4b939b8ca55ee344d3c8fdfc0a6a Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Jan 2014 19:51:36 +0100
|
||||
Subject: [PATCH] ARM: dts: sun4i: Add lradc node
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun4i-a10.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
|
||||
index 380f914..1ef7d57 100644
|
||||
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
|
||||
@@ -669,6 +669,13 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01c22800 0x100>;
|
||||
+ interrupts = <31>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sid: eeprom@01c23800 {
|
||||
compatible = "allwinner,sun4i-a10-sid";
|
||||
reg = <0x01c23800 0x10>;
|
|
@ -0,0 +1,175 @@
|
|||
From 3bf1194692f3a275e0776d3c0b6f17826cc01baa Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Jan 2014 19:50:33 +0100
|
||||
Subject: [PATCH] ARM: dts: sun5i: Add lradc node
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 45 ++++++++++++++++++++++--
|
||||
arch/arm/boot/dts/sun5i-a10s.dtsi | 7 ++++
|
||||
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 45 ++++++++++++++++++++++--
|
||||
arch/arm/boot/dts/sun5i-a13.dtsi | 7 ++++
|
||||
4 files changed, 100 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
|
||||
index ea9519d..0b82d20 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
|
||||
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
|
||||
@@ -12,8 +12,9 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
-/include/ "sun5i-a10s.dtsi"
|
||||
-/include/ "sunxi-common-regulators.dtsi"
|
||||
+#include "sun5i-a10s.dtsi"
|
||||
+#include "sunxi-common-regulators.dtsi"
|
||||
+#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "Olimex A10s-Olinuxino Micro";
|
||||
@@ -98,6 +99,46 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ vref-supply = <®_vcc3v0>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ button@191 {
|
||||
+ label = "Volume Up";
|
||||
+ linux,code = <KEY_VOLUMEUP>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <191274>;
|
||||
+ };
|
||||
+
|
||||
+ button@392 {
|
||||
+ label = "Volume Down";
|
||||
+ linux,code = <KEY_VOLUMEDOWN>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <392644>;
|
||||
+ };
|
||||
+
|
||||
+ button@601 {
|
||||
+ label = "Menu";
|
||||
+ linux,code = <KEY_MENU>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <601151>;
|
||||
+ };
|
||||
+
|
||||
+ button@795 {
|
||||
+ label = "Enter";
|
||||
+ linux,code = <KEY_ENTER>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <795090>;
|
||||
+ };
|
||||
+
|
||||
+ button@987 {
|
||||
+ label = "Home";
|
||||
+ linux,code = <KEY_HOMEPAGE>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <987387>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
uart0: serial@01c28000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
index 531272c..7c6c883 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
@@ -520,6 +520,13 @@
|
||||
reg = <0x01c20c90 0x10>;
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01c22800 0x100>;
|
||||
+ interrupts = <31>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sid: eeprom@01c23800 {
|
||||
compatible = "allwinner,sun4i-a10-sid";
|
||||
reg = <0x01c23800 0x10>;
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
|
||||
index 429994e..b4ec8eb 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
|
||||
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
|
||||
@@ -12,8 +12,9 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
-/include/ "sun5i-a13.dtsi"
|
||||
-/include/ "sunxi-common-regulators.dtsi"
|
||||
+#include "sun5i-a13.dtsi"
|
||||
+#include "sunxi-common-regulators.dtsi"
|
||||
+#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "Olimex A13-Olinuxino";
|
||||
@@ -66,6 +67,46 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ vref-supply = <®_vcc3v0>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ button@191 {
|
||||
+ label = "Volume Up";
|
||||
+ linux,code = <KEY_VOLUMEUP>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <191274>;
|
||||
+ };
|
||||
+
|
||||
+ button@392 {
|
||||
+ label = "Volume Down";
|
||||
+ linux,code = <KEY_VOLUMEDOWN>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <392644>;
|
||||
+ };
|
||||
+
|
||||
+ button@601 {
|
||||
+ label = "Menu";
|
||||
+ linux,code = <KEY_MENU>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <601151>;
|
||||
+ };
|
||||
+
|
||||
+ button@795 {
|
||||
+ label = "Enter";
|
||||
+ linux,code = <KEY_ENTER>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <795090>;
|
||||
+ };
|
||||
+
|
||||
+ button@987 {
|
||||
+ label = "Home";
|
||||
+ linux,code = <KEY_HOMEPAGE>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <987387>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
uart1: serial@01c28400 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pins_b>;
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
index b131068..aa0482c 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
@@ -468,6 +468,13 @@
|
||||
reg = <0x01c20c90 0x10>;
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01c22800 0x100>;
|
||||
+ interrupts = <31>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sid: eeprom@01c23800 {
|
||||
compatible = "allwinner,sun4i-a10-sid";
|
||||
reg = <0x01c23800 0x10>;
|
|
@ -0,0 +1,106 @@
|
|||
From a735a9b354ebc1a17b648ef8c3482c71fdbf40da Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 1 Jan 2014 20:26:21 +0100
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add lradc node
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 59 ++++++++++++++++++++++++-
|
||||
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++
|
||||
2 files changed, 64 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
|
||||
index 9d669cdf..c00badd 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
|
||||
@@ -12,8 +12,9 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
-/include/ "sun7i-a20.dtsi"
|
||||
-/include/ "sunxi-common-regulators.dtsi"
|
||||
+#include "sun7i-a20.dtsi"
|
||||
+#include "sunxi-common-regulators.dtsi"
|
||||
+#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "Olimex A20-Olinuxino Micro";
|
||||
@@ -100,6 +101,60 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ vref-supply = <®_vcc3v0>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ button@191 {
|
||||
+ label = "Volume Up";
|
||||
+ linux,code = <KEY_VOLUMEUP>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <191274>;
|
||||
+ };
|
||||
+
|
||||
+ button@392 {
|
||||
+ label = "Volume Down";
|
||||
+ linux,code = <KEY_VOLUMEDOWN>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <392644>;
|
||||
+ };
|
||||
+
|
||||
+ button@601 {
|
||||
+ label = "Menu";
|
||||
+ linux,code = <KEY_MENU>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <601151>;
|
||||
+ };
|
||||
+
|
||||
+ button@795 {
|
||||
+ label = "Search";
|
||||
+ linux,code = <KEY_SEARCH>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <795090>;
|
||||
+ };
|
||||
+
|
||||
+ button@987 {
|
||||
+ label = "Home";
|
||||
+ linux,code = <KEY_HOMEPAGE>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <987387>;
|
||||
+ };
|
||||
+
|
||||
+ button@1184 {
|
||||
+ label = "Esc";
|
||||
+ linux,code = <KEY_ESC>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <1184678>;
|
||||
+ };
|
||||
+
|
||||
+ button@1398 {
|
||||
+ label = "Enter";
|
||||
+ linux,code = <KEY_ENTER>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <1398804>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
uart0: serial@01c28000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
index f0a75c6..9174423 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -911,6 +911,13 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ lradc: lradc@01c22800 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01c22800 0x100>;
|
||||
+ interrupts = <0 31 4>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sid: eeprom@01c23800 {
|
||||
compatible = "allwinner,sun7i-a20-sid";
|
||||
reg = <0x01c23800 0x200>;
|
|
@ -0,0 +1,83 @@
|
|||
From 2e2493cd07405dfa88e53199b47bdbbb5336fdce Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 16 Jun 2014 20:01:12 +0200
|
||||
Subject: [PATCH] touchscreen: sun4i-ts: A10 (sun4i) has a different
|
||||
temperature curve
|
||||
|
||||
Testing has revealed that the temperature in the rtp controller of the A10
|
||||
(sun4i) SoC has a different curve then on the A13 (sun5i) and later models.
|
||||
|
||||
Add a new sun5i-a13-ts compatible to differentiate the newer models and
|
||||
set the curve based on the compatible string.
|
||||
|
||||
This fixes the temperature reported on the A10 being much higher then
|
||||
expected.
|
||||
|
||||
Note the new curve is still not ideal on all A10-s, that seems to have to
|
||||
do with there being a large spread between different A10-s out there.
|
||||
|
||||
Reported-by: Tong Zhang <lovewilliam@gmail.com>
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
.../devicetree/bindings/input/touchscreen/sun4i.txt | 2 +-
|
||||
drivers/input/touchscreen/sun4i-ts.c | 13 ++++++++++++-
|
||||
2 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
|
||||
index aef5779..5106709 100644
|
||||
--- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
|
||||
+++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
|
||||
@@ -2,7 +2,7 @@ sun4i resistive touchscreen controller
|
||||
--------------------------------------
|
||||
|
||||
Required properties:
|
||||
- - compatible: "allwinner,sun4i-a10-ts"
|
||||
+ - compatible: "allwinner,sun4i-a10-ts" or "allwinner,sun5i-a13-ts"
|
||||
- reg: mmio address range of the chip
|
||||
- interrupts: interrupt to which the chip is connected
|
||||
|
||||
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c
|
||||
index 2ba8260..52b7114 100644
|
||||
--- a/drivers/input/touchscreen/sun4i-ts.c
|
||||
+++ b/drivers/input/touchscreen/sun4i-ts.c
|
||||
@@ -111,6 +111,8 @@ struct sun4i_ts_data {
|
||||
unsigned int irq;
|
||||
bool ignore_fifo_data;
|
||||
int temp_data;
|
||||
+ int temp_offset;
|
||||
+ int temp_step;
|
||||
};
|
||||
|
||||
static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val)
|
||||
@@ -189,7 +191,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
|
||||
if (ts->temp_data == -1)
|
||||
return -EAGAIN;
|
||||
|
||||
- return sprintf(buf, "%d\n", (ts->temp_data - 1447) * 100);
|
||||
+ return sprintf(buf, "%d\n",
|
||||
+ (ts->temp_data - ts->temp_offset) * ts->temp_step);
|
||||
}
|
||||
|
||||
static ssize_t show_temp_label(struct device *dev,
|
||||
@@ -224,6 +227,13 @@ static int sun4i_ts_probe(struct platform_device *pdev)
|
||||
ts->dev = dev;
|
||||
ts->ignore_fifo_data = true;
|
||||
ts->temp_data = -1;
|
||||
+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) {
|
||||
+ ts->temp_offset = 1900;
|
||||
+ ts->temp_step = 100;
|
||||
+ } else {
|
||||
+ ts->temp_offset = 1447;
|
||||
+ ts->temp_step = 100;
|
||||
+ }
|
||||
|
||||
ts_attached = of_property_read_bool(np, "allwinner,ts-attached");
|
||||
if (ts_attached) {
|
||||
@@ -318,6 +328,7 @@ static int sun4i_ts_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id sun4i_ts_of_match[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-ts", },
|
||||
+ { .compatible = "allwinner,sun5i-a13-ts", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_ts_of_match);
|
|
@ -0,0 +1,57 @@
|
|||
From ff774d842a2bf9136b9c7ddd7f5085a9062705ac Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 16 Jun 2014 20:06:43 +0200
|
||||
Subject: [PATCH] ARM: dts: sunxi: Adjust touchscreen compatible for sun5i and
|
||||
later
|
||||
|
||||
The touchscreen controller in the A13 and later has a different temperature
|
||||
curve than the one in the original A10, change the compatible for the A13 and
|
||||
later so that the kernel will use the correct curve.
|
||||
|
||||
Reported-by: Tong Zhang <lovewilliam@gmail.com>
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun5i-a13.dtsi | 2 +-
|
||||
arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
index 7c6c883..7089284 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
|
||||
@@ -533,7 +533,7 @@
|
||||
};
|
||||
|
||||
rtp: rtp@01c25000 {
|
||||
- compatible = "allwinner,sun4i-a10-ts";
|
||||
+ compatible = "allwinner,sun5i-a13-ts";
|
||||
reg = <0x01c25000 0x100>;
|
||||
interrupts = <29>;
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
index aa0482c..b05ab04 100644
|
||||
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
|
||||
@@ -481,7 +481,7 @@
|
||||
};
|
||||
|
||||
rtp: rtp@01c25000 {
|
||||
- compatible = "allwinner,sun4i-a10-ts";
|
||||
+ compatible = "allwinner,sun5i-a13-ts";
|
||||
reg = <0x01c25000 0x100>;
|
||||
interrupts = <29>;
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
index 9174423..81d4e55 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -924,7 +924,7 @@
|
||||
};
|
||||
|
||||
rtp: rtp@01c25000 {
|
||||
- compatible = "allwinner,sun4i-a10-ts";
|
||||
+ compatible = "allwinner,sun5i-a13-ts";
|
||||
reg = <0x01c25000 0x100>;
|
||||
interrupts = <0 29 4>;
|
||||
};
|
|
@ -0,0 +1,339 @@
|
|||
From 63d559304a15ffead2fa1014b93dbcabf516c257 Mon Sep 17 00:00:00 2001
|
||||
From: Carlo Caione <carlo@caione.org>
|
||||
Date: Mon, 19 May 2014 21:47:45 +0200
|
||||
Subject: [PATCH] input: misc: Add driver for AXP20x Power Enable Key
|
||||
|
||||
This patch add support for the Power Enable Key found on MFD AXP202 and
|
||||
AXP209. Besides the basic support for the button, the driver adds two
|
||||
entries in sysfs to configure the time delay for power on/off.
|
||||
|
||||
Signed-off-by: Carlo Caione <carlo@caione.org>
|
||||
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||
---
|
||||
drivers/input/misc/Kconfig | 11 ++
|
||||
drivers/input/misc/Makefile | 1 +
|
||||
drivers/input/misc/axp20x-pek.c | 281 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 293 insertions(+)
|
||||
create mode 100644 drivers/input/misc/axp20x-pek.c
|
||||
|
||||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
|
||||
index 23297ab..a49bcd3 100644
|
||||
--- a/drivers/input/misc/Kconfig
|
||||
+++ b/drivers/input/misc/Kconfig
|
||||
@@ -404,6 +404,17 @@ config INPUT_RETU_PWRBUTTON
|
||||
To compile this driver as a module, choose M here. The module will
|
||||
be called retu-pwrbutton.
|
||||
|
||||
+config INPUT_AXP20X_PEK
|
||||
+ tristate "X-Powers AXP20X power button driver"
|
||||
+ depends on MFD_AXP20X
|
||||
+ help
|
||||
+ Say Y here if you want to enable power key reporting via the
|
||||
+ AXP20X PMIC.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here. The module will
|
||||
+ be called axp20x-pek.
|
||||
+
|
||||
+
|
||||
config INPUT_TWL4030_PWRBUTTON
|
||||
tristate "TWL4030 Power button Driver"
|
||||
depends on TWL4030_CORE
|
||||
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
|
||||
index 19c7603..04ea87f 100644
|
||||
--- a/drivers/input/misc/Makefile
|
||||
+++ b/drivers/input/misc/Makefile
|
||||
@@ -54,6 +54,7 @@ obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
|
||||
obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
|
||||
obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
|
||||
obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
|
||||
+obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o
|
||||
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
|
||||
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
|
||||
obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
|
||||
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
|
||||
new file mode 100644
|
||||
index 0000000..0fba252
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/misc/axp20x-pek.c
|
||||
@@ -0,0 +1,281 @@
|
||||
+/*
|
||||
+ * axp20x power button driver.
|
||||
+ *
|
||||
+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
|
||||
+ *
|
||||
+ * This file is subject to the terms and conditions of the GNU General
|
||||
+ * Public License. See the file "COPYING" in the main directory of this
|
||||
+ * archive for more details.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/axp20x.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define AXP20X_PEK_STARTUP_MASK (0xc0)
|
||||
+#define AXP20X_PEK_SHUTDOWN_MASK (0x03)
|
||||
+
|
||||
+struct axp20x_pek {
|
||||
+ struct axp20x_dev *axp20x;
|
||||
+ struct input_dev *input;
|
||||
+ int irq_dbr;
|
||||
+ int irq_dbf;
|
||||
+};
|
||||
+
|
||||
+struct axp20x_time {
|
||||
+ unsigned int time;
|
||||
+ unsigned int idx;
|
||||
+};
|
||||
+
|
||||
+static const struct axp20x_time startup_time[] = {
|
||||
+ { .time = 128, .idx = 0 },
|
||||
+ { .time = 1000, .idx = 2 },
|
||||
+ { .time = 3000, .idx = 1 },
|
||||
+ { .time = 2000, .idx = 3 },
|
||||
+};
|
||||
+
|
||||
+static const struct axp20x_time shutdown_time[] = {
|
||||
+ { .time = 4000, .idx = 0 },
|
||||
+ { .time = 6000, .idx = 1 },
|
||||
+ { .time = 8000, .idx = 2 },
|
||||
+ { .time = 10000, .idx = 3 },
|
||||
+};
|
||||
+
|
||||
+struct axp20x_pek_ext_attr {
|
||||
+ const struct axp20x_time *p_time;
|
||||
+ unsigned int mask;
|
||||
+};
|
||||
+
|
||||
+static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
|
||||
+ .p_time = startup_time,
|
||||
+ .mask = AXP20X_PEK_STARTUP_MASK,
|
||||
+};
|
||||
+
|
||||
+static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
|
||||
+ .p_time = shutdown_time,
|
||||
+ .mask = AXP20X_PEK_SHUTDOWN_MASK,
|
||||
+};
|
||||
+
|
||||
+static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
|
||||
+{
|
||||
+ return container_of(attr, struct dev_ext_attribute, attr)->var;
|
||||
+}
|
||||
+
|
||||
+static ssize_t axp20x_show_ext_attr(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
|
||||
+ struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
|
||||
+ unsigned int val;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val);
|
||||
+ if (ret != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ val &= axp20x_ea->mask;
|
||||
+ val >>= ffs(axp20x_ea->mask) - 1;
|
||||
+
|
||||
+ for (i = 0; i < 4; i++)
|
||||
+ if (val == axp20x_ea->p_time[i].idx)
|
||||
+ val = axp20x_ea->p_time[i].time;
|
||||
+
|
||||
+ return sprintf(buf, "%u\n", val);
|
||||
+}
|
||||
+
|
||||
+static ssize_t axp20x_store_ext_attr(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
|
||||
+ struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
|
||||
+ char val_str[20];
|
||||
+ size_t len;
|
||||
+ int ret, i;
|
||||
+ unsigned int val, idx = 0;
|
||||
+ unsigned int best_err = UINT_MAX;
|
||||
+
|
||||
+ val_str[sizeof(val_str) - 1] = '\0';
|
||||
+ strncpy(val_str, buf, sizeof(val_str) - 1);
|
||||
+ len = strlen(val_str);
|
||||
+
|
||||
+ if (len && val_str[len - 1] == '\n')
|
||||
+ val_str[len - 1] = '\0';
|
||||
+
|
||||
+ ret = kstrtouint(val_str, 10, &val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 3; i >= 0; i--) {
|
||||
+ unsigned int err;
|
||||
+
|
||||
+ err = abs(axp20x_ea->p_time[i].time - val);
|
||||
+ if (err < best_err) {
|
||||
+ best_err = err;
|
||||
+ idx = axp20x_ea->p_time[i].idx;
|
||||
+ }
|
||||
+
|
||||
+ if (!err)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ idx <<= ffs(axp20x_ea->mask) - 1;
|
||||
+ ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
|
||||
+ AXP20X_PEK_KEY,
|
||||
+ axp20x_ea->mask, idx);
|
||||
+ if (ret != 0)
|
||||
+ return -EINVAL;
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static struct dev_ext_attribute axp20x_dev_attr_startup = {
|
||||
+ .attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
|
||||
+ .var = &axp20x_pek_startup_ext_attr
|
||||
+};
|
||||
+
|
||||
+static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
|
||||
+ .attr = __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
|
||||
+ .var = &axp20x_pek_shutdown_ext_attr
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
|
||||
+{
|
||||
+ struct input_dev *idev = pwr;
|
||||
+ struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
|
||||
+
|
||||
+ if (irq == axp20x_pek->irq_dbr)
|
||||
+ input_report_key(idev, KEY_POWER, true);
|
||||
+ else if (irq == axp20x_pek->irq_dbf)
|
||||
+ input_report_key(idev, KEY_POWER, false);
|
||||
+
|
||||
+ input_sync(idev);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int axp20x_pek_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct axp20x_pek *axp20x_pek;
|
||||
+ struct axp20x_dev *axp20x;
|
||||
+ struct input_dev *idev;
|
||||
+ int error;
|
||||
+
|
||||
+ axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!axp20x_pek)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
+ axp20x = axp20x_pek->axp20x;
|
||||
+
|
||||
+ axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
|
||||
+ if (axp20x_pek->irq_dbr < 0) {
|
||||
+ dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
|
||||
+ axp20x_pek->irq_dbr);
|
||||
+ return axp20x_pek->irq_dbr;
|
||||
+ }
|
||||
+ axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
|
||||
+ axp20x_pek->irq_dbr);
|
||||
+
|
||||
+ axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
|
||||
+ if (axp20x_pek->irq_dbf < 0) {
|
||||
+ dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
|
||||
+ axp20x_pek->irq_dbf);
|
||||
+ return axp20x_pek->irq_dbf;
|
||||
+ }
|
||||
+ axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
|
||||
+ axp20x_pek->irq_dbf);
|
||||
+
|
||||
+ axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
|
||||
+ if (!axp20x_pek->input)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ idev = axp20x_pek->input;
|
||||
+
|
||||
+ idev->name = "axp20x-pek";
|
||||
+ idev->phys = "m1kbd/input2";
|
||||
+ idev->dev.parent = &pdev->dev;
|
||||
+
|
||||
+ input_set_capability(idev, EV_KEY, KEY_POWER);
|
||||
+
|
||||
+ input_set_drvdata(idev, axp20x_pek);
|
||||
+
|
||||
+ error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
|
||||
+ axp20x_pek_irq, 0,
|
||||
+ "axp20x-pek-dbr", idev);
|
||||
+ if (error < 0) {
|
||||
+ dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
|
||||
+ axp20x_pek->irq_dbr, error);
|
||||
+
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
|
||||
+ axp20x_pek_irq, 0,
|
||||
+ "axp20x-pek-dbf", idev);
|
||||
+ if (error < 0) {
|
||||
+ dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
|
||||
+ axp20x_pek->irq_dbf, error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = device_create_file(&pdev->dev, &axp20x_dev_attr_startup.attr);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
+ error = device_create_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr);
|
||||
+ if (error)
|
||||
+ goto clear_startup_attr;
|
||||
+
|
||||
+ error = input_register_device(idev);
|
||||
+ if (error) {
|
||||
+ dev_err(axp20x->dev, "Can't register input device: %d\n", error);
|
||||
+ goto clear_attr;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, axp20x_pek);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+clear_attr:
|
||||
+ device_remove_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr);
|
||||
+
|
||||
+clear_startup_attr:
|
||||
+ device_remove_file(&pdev->dev, &axp20x_dev_attr_startup.attr);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+int axp20x_pek_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ device_remove_file(&pdev->dev, &axp20x_dev_attr_shutdown.attr);
|
||||
+ device_remove_file(&pdev->dev, &axp20x_dev_attr_startup.attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver axp20x_pek_driver = {
|
||||
+ .probe = axp20x_pek_probe,
|
||||
+ .remove = axp20x_pek_remove,
|
||||
+ .driver = {
|
||||
+ .name = "axp20x-pek",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(axp20x_pek_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("axp20x Power Button");
|
||||
+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
+MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,97 @@
|
|||
From 4bfd40ed0046299e4a5ffba31bfbbcc39cf74e03 Mon Sep 17 00:00:00 2001
|
||||
From: Marc Zyngier <marc.zyngier@arm.com>
|
||||
Date: Thu, 23 Oct 2014 17:49:30 +0100
|
||||
Subject: [PATCH] AHCI: Fix threaded interrupt setup
|
||||
|
||||
Commit 18dcf433f3de (AHCI: Optimize single IRQ interrupt processing)
|
||||
switched the single IRQ case of the AHCI driver to use threaded
|
||||
threaded interrupts.
|
||||
|
||||
During this conversion, only the IRQF_SHARED flag was provided. The net
|
||||
effect of this in the presence of level interrupts is that the
|
||||
interrupt will not be masked during the execution of the treaded
|
||||
handler, leading to a screaming interrupt if the thread is not
|
||||
scheduled quickly enough, specially in error conditions:
|
||||
|
||||
[ 2.728051] ahci-sunxi 1c18000.sata: controller can't do PMP, turning off CAP_PMP
|
||||
[ 2.735578] ahci-sunxi 1c18000.sata: SSS flag set, parallel bus scan disabled
|
||||
[ 2.742792] ahci-sunxi 1c18000.sata: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl platform mode
|
||||
[ 2.751789] ahci-sunxi 1c18000.sata: flags: ncq sntf stag pm led clo only pio slum part ccc
|
||||
[ 2.761539] scsi host0: ahci_platform
|
||||
[ 2.765754] ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 88
|
||||
[...]
|
||||
[ 3.127977] ata1: SATA link down (SStatus 0 SControl 300)
|
||||
[...]
|
||||
[ 3.162035] Waiting for root device /dev/sda1...
|
||||
[ 3.163700] random: nonblocking pool is initialized
|
||||
[ 3.326593] irq 88: nobody cared (try booting with the "irqpoll" option)
|
||||
[ 3.333296] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc1+ #3077
|
||||
[ 3.339936] [<c002b318>] (unwind_backtrace) from [<c0026980>] (show_stack+0x20/0x24)
|
||||
[ 3.347681] [<c0026980>] (show_stack) from [<c067dd18>] (dump_stack+0x9c/0xd4)
|
||||
[ 3.354904] [<c067dd18>] (dump_stack) from [<c007ac08>] (__report_bad_irq+0x38/0xd4)
|
||||
[ 3.362643] [<c007ac08>] (__report_bad_irq) from [<c007b1dc>] (note_interrupt+0x280/0x2d0)
|
||||
[ 3.370903] [<c007b1dc>] (note_interrupt) from [<c0078a70>] (handle_irq_event_percpu+0x210/0x27c)
|
||||
[ 3.379771] [<c0078a70>] (handle_irq_event_percpu) from [<c0078b28>] (handle_irq_event+0x4c/0x6c)
|
||||
[ 3.388636] [<c0078b28>] (handle_irq_event) from [<c007b860>] (handle_fasteoi_irq+0xbc/0x1a0)
|
||||
[ 3.397156] [<c007b860>] (handle_fasteoi_irq) from [<c0077f5c>] (generic_handle_irq+0x3c/0x4c)
|
||||
[ 3.405764] [<c0077f5c>] (generic_handle_irq) from [<c0078220>] (__handle_domain_irq+0x6c/0xb4)
|
||||
[ 3.414456] [<c0078220>] (__handle_domain_irq) from [<c0008754>] (gic_handle_irq+0x34/0x6c)
|
||||
[ 3.422802] [<c0008754>] (gic_handle_irq) from [<c0027540>] (__irq_svc+0x40/0x74)
|
||||
[ 3.430274] Exception stack(0xc09c1df8 to 0xc09c1e40)
|
||||
[ 3.435321] 1de0: 00000001 c0a27ec0
|
||||
[ 3.443491] 1e00: 00000000 00000000 c09c0028 0000001e 00000282 00000000 ee00c400 c0a239f8
|
||||
[ 3.451660] 1e20: c09c0000 c09c1ea4 c0a27ec0 c09c1e40 00200000 c003c7cc 20000113 ffffffff
|
||||
[ 3.459835] [<c0027540>] (__irq_svc) from [<c003c7cc>] (__do_softirq+0xbc/0x34c)
|
||||
[ 3.467229] [<c003c7cc>] (__do_softirq) from [<c003cd44>] (irq_exit+0xbc/0x104)
|
||||
[ 3.474536] [<c003cd44>] (irq_exit) from [<c0078224>] (__handle_domain_irq+0x70/0xb4)
|
||||
[ 3.482362] [<c0078224>] (__handle_domain_irq) from [<c0008754>] (gic_handle_x74)
|
||||
[ 3.498169] Exception stack(0xc09c1f10 to 0xc09c1f58)
|
||||
[ 3.503216] 1f00: ee7ca310 00000000 00000ab4 c0035560
|
||||
[ 3.511386] 1f20: c09c0000 00000000 c0a23f84 c09c8474 c09c84bc c09c0000 c0688bf8 c09c1f64
|
||||
[ 3.519554] 1f40: c09c1f68 c09c1f58 c00235d8 c00235dc 60000113 ffffffff
|
||||
[ 3.526165] [<c0027540>] (__irq_svc) from [<c00235dc>] (arch_cpu_idle+0x48/0x4c)
|
||||
[ 3.533557] [<c00235dc>] (arch_cpu_idle) from [<c00701fc>] (cpu_startup_entry+0x13c/0x27c)
|
||||
[ 3.541816] [<c00701fc>] (cpu_startup_entry) from [<c067af1c>] (rest_init+0x94/0x98)
|
||||
[ 3.549557] [<c067af1c>] (rest_init) from [<c093dd38>] (start_kernel+0x3f0/0x3fc)
|
||||
[ 3.557036] [<c093dd38>] (start_kernel) from [<40008084>] (0x40008084)
|
||||
[ 3.563555] handlers:
|
||||
[ 3.565830] [<c03a1a80>] ahci_single_irq_intr threaded [<c03a223c>] ahci_thread_fn
|
||||
[ 3.573415] Disabling IRQ #88
|
||||
[ 3.576532] ata1: exception Emask 0x10 SAct 0x0 SErr 0x4050002 action 0xe frozen
|
||||
[ 3.583977] ata1: irq_stat 0x00400040, connection status changed
|
||||
[ 3.590006] ata1: SError: { RecovComm PHYRdyChg CommWake DevExch }
|
||||
[ 3.596209] ata1: hard resetting link
|
||||
[...]
|
||||
|
||||
Not good. The culprit is a missing IRQF_ONESHOT flag, which addition
|
||||
solves the problem entierly. The number of interrupts drops radically:
|
||||
|
||||
[Booting Debian Jessie to a prompt]
|
||||
Before fix:
|
||||
88: 3562 0 GIC 88 ahci-sunxi
|
||||
After fix:
|
||||
88: 1992 0 GIC 88 ahci-sunxi
|
||||
|
||||
Tested on a A20 board (ahci-sunxi).
|
||||
|
||||
Cc: Alexander Gordeev <agordeev@redhat.com>
|
||||
Cc: Tejun Heo <tj@kernel.org>
|
||||
Cc: linux-ide@vger.kernel.org
|
||||
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
|
||||
---
|
||||
drivers/ata/libahci.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
|
||||
index 5eb61c9..49c649f 100644
|
||||
--- a/drivers/ata/libahci.c
|
||||
+++ b/drivers/ata/libahci.c
|
||||
@@ -2492,7 +2492,7 @@ static int ahci_host_activate_single_irq(struct ata_host *host, int irq,
|
||||
return rc;
|
||||
|
||||
rc = devm_request_threaded_irq(host->dev, irq, ahci_single_irq_intr,
|
||||
- ahci_thread_fn, IRQF_SHARED,
|
||||
+ ahci_thread_fn, IRQF_SHARED | IRQF_ONESHOT,
|
||||
dev_driver_string(host->dev), host);
|
||||
if (rc)
|
||||
return rc;
|
|
@ -0,0 +1,409 @@
|
|||
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
|
||||
index 3865dfb9ed08..424359d3cbb1 100644
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -262,6 +262,15 @@ config PWM_STI
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-sti.
|
||||
|
||||
+config PWM_SUN4I
|
||||
+ tristate "Allwinner sun4i PWM support"
|
||||
+ depends on ARCH_SUNXI || COMPILE_TEST
|
||||
+ help
|
||||
+ Generic PWM framework driver for Allwinner sun4i and sun7i SoCs.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-sun4i.
|
||||
+
|
||||
config PWM_TEGRA
|
||||
tristate "NVIDIA Tegra PWM support"
|
||||
depends on ARCH_TEGRA
|
||||
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
|
||||
index c458606c3755..d607804deea1 100644
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
|
||||
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
|
||||
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
|
||||
obj-$(CONFIG_PWM_STI) += pwm-sti.o
|
||||
+obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
|
||||
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
|
||||
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
|
||||
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
|
||||
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
|
||||
new file mode 100644
|
||||
index 000000000000..918f8ee79b51
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-sun4i.c
|
||||
@@ -0,0 +1,371 @@
|
||||
+/*
|
||||
+ * Driver for Allwinner sun4i Pulse Width Modulation Controller
|
||||
+ *
|
||||
+ * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
|
||||
+ *
|
||||
+ * Licensed under GPLv2.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/time.h>
|
||||
+
|
||||
+#define PWM_CTRL_REG 0x0
|
||||
+
|
||||
+#define PWM_CH_PRD_BASE 0x4
|
||||
+#define PWM_CH_PRD_OFFSET 0x4
|
||||
+#define PWM_CH_PRD(ch) (PWM_CH_PRD_BASE + PWM_CH_PRD_OFFSET * (ch))
|
||||
+
|
||||
+#define PWMCH_OFFSET 15
|
||||
+#define PWM_PRESCAL_MASK GENMASK(3, 0)
|
||||
+#define PWM_PRESCAL_OFF 0
|
||||
+#define PWM_EN BIT(4)
|
||||
+#define PWM_ACT_STATE BIT(5)
|
||||
+#define PWM_CLK_GATING BIT(6)
|
||||
+#define PWM_MODE BIT(7)
|
||||
+#define PWM_PULSE BIT(8)
|
||||
+#define PWM_BYPASS BIT(9)
|
||||
+
|
||||
+#define PWM_RDY_BASE 28
|
||||
+#define PWM_RDY_OFFSET 1
|
||||
+#define PWM_RDY(ch) BIT(PWM_RDY_BASE + PWM_RDY_OFFSET * (ch))
|
||||
+
|
||||
+#define PWM_PRD(prd) (((prd) - 1) << 16)
|
||||
+#define PWM_PRD_MASK GENMASK(15, 0)
|
||||
+
|
||||
+#define PWM_DTY_MASK GENMASK(15, 0)
|
||||
+
|
||||
+#define BIT_CH(bit, chan) ((bit) << ((chan) * PWMCH_OFFSET))
|
||||
+
|
||||
+static const u32 prescaler_table[] = {
|
||||
+ 120,
|
||||
+ 180,
|
||||
+ 240,
|
||||
+ 360,
|
||||
+ 480,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 12000,
|
||||
+ 24000,
|
||||
+ 36000,
|
||||
+ 48000,
|
||||
+ 72000,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0, /* Actually 1 but tested separately */
|
||||
+};
|
||||
+
|
||||
+struct sun4i_pwm_data {
|
||||
+ bool has_prescaler_bypass;
|
||||
+ bool has_rdy;
|
||||
+};
|
||||
+
|
||||
+struct sun4i_pwm_chip {
|
||||
+ struct pwm_chip chip;
|
||||
+ struct clk *clk;
|
||||
+ void __iomem *base;
|
||||
+ struct mutex ctrl_lock;
|
||||
+ const struct sun4i_pwm_data *data;
|
||||
+};
|
||||
+
|
||||
+static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct sun4i_pwm_chip, chip);
|
||||
+}
|
||||
+
|
||||
+static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
|
||||
+ unsigned long offset)
|
||||
+{
|
||||
+ return readl(chip->base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
|
||||
+ u32 val, unsigned long offset)
|
||||
+{
|
||||
+ writel(val, chip->base + offset);
|
||||
+}
|
||||
+
|
||||
+static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ int duty_ns, int period_ns)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
|
||||
+ u32 clk_rate, prd, dty, val, clk_gate;
|
||||
+ u64 div = 0;
|
||||
+ unsigned int prescaler = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ clk_rate = clk_get_rate(sun4i_pwm->clk);
|
||||
+
|
||||
+ if (sun4i_pwm->data->has_prescaler_bypass) {
|
||||
+ /* First, test without any prescaler when available */
|
||||
+ prescaler = PWM_PRESCAL_MASK;
|
||||
+ /*
|
||||
+ * When not using any prescaler, the clock period in nanoseconds
|
||||
+ * is not an integer so round it half up instead of
|
||||
+ * truncating to get less surprising values.
|
||||
+ */
|
||||
+ div = clk_rate * (u64)period_ns + NSEC_PER_SEC/2;
|
||||
+ do_div(div, NSEC_PER_SEC);
|
||||
+ if (div - 1 > PWM_PRD_MASK)
|
||||
+ prescaler = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (prescaler == 0) {
|
||||
+ /* Go up from the first divider */
|
||||
+ for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) {
|
||||
+ if (!prescaler_table[prescaler])
|
||||
+ continue;
|
||||
+ div = clk_rate / prescaler_table[prescaler];
|
||||
+ div = div * (u64)period_ns;
|
||||
+ do_div(div, NSEC_PER_SEC);
|
||||
+ if (div - 1 <= PWM_PRD_MASK)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (div - 1 > PWM_PRD_MASK) {
|
||||
+ dev_err(chip->dev, "period exceeds the maximum value\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ prd = div;
|
||||
+ div *= duty_ns;
|
||||
+ do_div(div, period_ns);
|
||||
+ dty = div;
|
||||
+
|
||||
+ err = clk_prepare_enable(sun4i_pwm->clk);
|
||||
+ if (err) {
|
||||
+ dev_err(chip->dev, "failed to enable PWM clock\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&sun4i_pwm->ctrl_lock);
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+
|
||||
+ if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
|
||||
+ mutex_unlock(&sun4i_pwm->ctrl_lock);
|
||||
+ clk_disable_unprepare(sun4i_pwm->clk);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
|
||||
+ if (clk_gate) {
|
||||
+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+ }
|
||||
+
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+ val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
|
||||
+ val |= BIT_CH(prescaler, pwm->hwpwm);
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+
|
||||
+ val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
|
||||
+
|
||||
+ if (clk_gate) {
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+ val |= clk_gate;
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&sun4i_pwm->ctrl_lock);
|
||||
+ clk_disable_unprepare(sun4i_pwm->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ enum pwm_polarity polarity)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(sun4i_pwm->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(chip->dev, "failed to enable PWM clock\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&sun4i_pwm->ctrl_lock);
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+
|
||||
+ if (polarity != PWM_POLARITY_NORMAL)
|
||||
+ val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
|
||||
+ else
|
||||
+ val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
|
||||
+
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+
|
||||
+ mutex_unlock(&sun4i_pwm->ctrl_lock);
|
||||
+ clk_disable_unprepare(sun4i_pwm->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(sun4i_pwm->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(chip->dev, "failed to enable PWM clock\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&sun4i_pwm->ctrl_lock);
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+ val |= BIT_CH(PWM_EN, pwm->hwpwm);
|
||||
+ val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+ mutex_unlock(&sun4i_pwm->ctrl_lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
|
||||
+ u32 val;
|
||||
+
|
||||
+ mutex_lock(&sun4i_pwm->ctrl_lock);
|
||||
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
|
||||
+ val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
|
||||
+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
|
||||
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
|
||||
+ mutex_unlock(&sun4i_pwm->ctrl_lock);
|
||||
+
|
||||
+ clk_disable_unprepare(sun4i_pwm->clk);
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops sun4i_pwm_ops = {
|
||||
+ .config = sun4i_pwm_config,
|
||||
+ .set_polarity = sun4i_pwm_set_polarity,
|
||||
+ .enable = sun4i_pwm_enable,
|
||||
+ .disable = sun4i_pwm_disable,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
|
||||
+ .has_prescaler_bypass = false,
|
||||
+ .has_rdy = false,
|
||||
+};
|
||||
+
|
||||
+static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
|
||||
+ .has_prescaler_bypass = true,
|
||||
+ .has_rdy = true,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id sun4i_pwm_dt_ids[] = {
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun4i-a10-pwm",
|
||||
+ .data = &sun4i_pwm_data_a10,
|
||||
+ }, {
|
||||
+ .compatible = "allwinner,sun7i-a20-pwm",
|
||||
+ .data = &sun4i_pwm_data_a20,
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
|
||||
+
|
||||
+static int sun4i_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *pwm;
|
||||
+ struct resource *res;
|
||||
+ u32 val;
|
||||
+ int i, ret;
|
||||
+ const struct of_device_id *match;
|
||||
+
|
||||
+ match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
|
||||
+
|
||||
+ pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
|
||||
+ if (!pwm)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ pwm->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(pwm->base))
|
||||
+ return PTR_ERR(pwm->base);
|
||||
+
|
||||
+ pwm->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(pwm->clk))
|
||||
+ return PTR_ERR(pwm->clk);
|
||||
+
|
||||
+ pwm->chip.dev = &pdev->dev;
|
||||
+ pwm->chip.ops = &sun4i_pwm_ops;
|
||||
+ pwm->chip.base = -1;
|
||||
+ pwm->chip.npwm = 2;
|
||||
+ pwm->chip.can_sleep = true;
|
||||
+ pwm->chip.of_xlate = of_pwm_xlate_with_flags;
|
||||
+ pwm->chip.of_pwm_n_cells = 3;
|
||||
+ pwm->data = match->data;
|
||||
+
|
||||
+ mutex_init(&pwm->ctrl_lock);
|
||||
+
|
||||
+ ret = pwmchip_add(&pwm->chip);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pwm);
|
||||
+
|
||||
+ ret = clk_prepare_enable(pwm->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable PWM clock\n");
|
||||
+ goto clk_error;
|
||||
+ }
|
||||
+
|
||||
+ val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
|
||||
+ for (i = 0; i < pwm->chip.npwm; i++) {
|
||||
+ if (!(val & BIT_CH(PWM_ACT_STATE, i)))
|
||||
+ pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED;
|
||||
+ }
|
||||
+ clk_disable_unprepare(pwm->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+clk_error:
|
||||
+ pwmchip_remove(&pwm->chip);
|
||||
+
|
||||
+error:
|
||||
+ mutex_destroy(&pwm->ctrl_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ mutex_destroy(&pwm->ctrl_lock);
|
||||
+
|
||||
+ return pwmchip_remove(&pwm->chip);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver sun4i_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "sun4i-pwm",
|
||||
+ .of_match_table = sun4i_pwm_dt_ids,
|
||||
+ },
|
||||
+ .probe = sun4i_pwm_probe,
|
||||
+ .remove = sun4i_pwm_remove,
|
||||
+};
|
||||
+module_platform_driver(sun4i_pwm_driver);
|
||||
+
|
||||
+MODULE_ALIAS("platform:sun4i-pwm");
|
||||
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
|
||||
+MODULE_DESCRIPTION("Allwinner sun4i PWM driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,148 @@
|
|||
From 8c2057afe84c074ef7cd3ee2ec8e9bed835b9e93 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 21 May 2014 19:50:04 +0200
|
||||
Subject: [PATCH] mmc: Add SDIO function devicetree subnode parsing
|
||||
|
||||
This adds SDIO devicetree subnode parsing to the mmc core. While
|
||||
SDIO devices are runtime probable they sometimes need nonprobable
|
||||
additional information on embedded systems, like an additional gpio
|
||||
interrupt or a clock. This patch makes it possible to supply this
|
||||
information from the devicetree. SDIO drivers will find a pointer
|
||||
to the devicenode in their devices of_node pointer.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
[hdegoede@redhat.com: Misc. cleanups]
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/mmc/core/bus.c | 4 ++++
|
||||
drivers/mmc/core/core.c | 28 ++++++++++++++++++++++++++++
|
||||
drivers/mmc/core/core.h | 3 +++
|
||||
drivers/mmc/core/sdio_bus.c | 11 +++++++++++
|
||||
4 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
|
||||
index 8a1f124..7868565 100644
|
||||
--- a/drivers/mmc/core/bus.c
|
||||
+++ b/drivers/mmc/core/bus.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <linux/mmc/card.h>
|
||||
@@ -352,6 +353,8 @@ int mmc_add_card(struct mmc_card *card)
|
||||
#endif
|
||||
mmc_init_context_info(card->host);
|
||||
|
||||
+ card->dev.of_node = mmc_of_find_child_device(card->host, 0);
|
||||
+
|
||||
ret = device_add(&card->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -380,6 +383,7 @@ void mmc_remove_card(struct mmc_card *card)
|
||||
mmc_hostname(card->host), card->rca);
|
||||
}
|
||||
device_del(&card->dev);
|
||||
+ of_node_put(card->dev.of_node);
|
||||
}
|
||||
|
||||
put_device(&card->dev);
|
||||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
|
||||
index f26a5f1..7f7f66c 100644
|
||||
--- a/drivers/mmc/core/core.c
|
||||
+++ b/drivers/mmc/core/core.c
|
||||
@@ -1205,6 +1205,34 @@ EXPORT_SYMBOL(mmc_of_parse_voltage);
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
+static int mmc_of_get_func_num(struct device_node *node)
|
||||
+{
|
||||
+ u32 reg;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = of_property_read_u32(node, "reg", ®);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return reg;
|
||||
+}
|
||||
+
|
||||
+struct device_node *mmc_of_find_child_device(struct mmc_host *host,
|
||||
+ unsigned func_num)
|
||||
+{
|
||||
+ struct device_node *node;
|
||||
+
|
||||
+ if (!host->parent || !host->parent->of_node)
|
||||
+ return NULL;
|
||||
+
|
||||
+ for_each_child_of_node(host->parent->of_node, node) {
|
||||
+ if (mmc_of_get_func_num(node) == func_num)
|
||||
+ return node;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_REGULATOR
|
||||
|
||||
/**
|
||||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
|
||||
index 443a5846..f712f6e 100644
|
||||
--- a/drivers/mmc/core/core.h
|
||||
+++ b/drivers/mmc/core/core.h
|
||||
@@ -32,6 +32,9 @@ struct mmc_bus_ops {
|
||||
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
|
||||
void mmc_detach_bus(struct mmc_host *host);
|
||||
|
||||
+struct device_node *mmc_of_find_child_device(struct mmc_host *host,
|
||||
+ unsigned func_num);
|
||||
+
|
||||
void mmc_init_erase(struct mmc_card *card);
|
||||
|
||||
void mmc_set_chip_select(struct mmc_host *host, int mode);
|
||||
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
|
||||
index 6da97b1..f63223a 100644
|
||||
--- a/drivers/mmc/core/sdio_bus.c
|
||||
+++ b/drivers/mmc/core/sdio_bus.c
|
||||
@@ -22,7 +22,9 @@
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
+#include <linux/of.h>
|
||||
|
||||
+#include "core.h"
|
||||
#include "sdio_cis.h"
|
||||
#include "sdio_bus.h"
|
||||
|
||||
@@ -303,6 +305,13 @@ static void sdio_acpi_set_handle(struct sdio_func *func)
|
||||
static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
|
||||
#endif
|
||||
|
||||
+static void sdio_set_of_node(struct sdio_func *func)
|
||||
+{
|
||||
+ struct mmc_host *host = func->card->host;
|
||||
+
|
||||
+ func->dev.of_node = mmc_of_find_child_device(host, func->num);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Register a new SDIO function with the driver model.
|
||||
*/
|
||||
@@ -312,6 +321,7 @@ int sdio_add_func(struct sdio_func *func)
|
||||
|
||||
dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
|
||||
|
||||
+ sdio_set_of_node(func);
|
||||
sdio_acpi_set_handle(func);
|
||||
ret = device_add(&func->dev);
|
||||
if (ret == 0) {
|
||||
@@ -335,6 +345,7 @@ void sdio_remove_func(struct sdio_func *func)
|
||||
|
||||
dev_pm_domain_detach(&func->dev, false);
|
||||
device_del(&func->dev);
|
||||
+ of_node_put(func->dev.of_node);
|
||||
put_device(&func->dev);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
From e4127db9b980a5684c537d9010ed2aaa05a1e79a Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sat, 24 May 2014 20:53:49 +0200
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add OOB irq support to boards with broadcom
|
||||
sdio wifi
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 11 +++++++++++
|
||||
arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts | 11 +++++++++++
|
||||
2 files changed, 22 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
index a6c1a3c..f9ab5d4 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
@@ -31,12 +31,23 @@
|
||||
};
|
||||
|
||||
mmc3: mmc@01c12000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc3_pins_a>;
|
||||
vmmc-supply = <®_vmmc3>;
|
||||
bus-width = <4>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
+
|
||||
+ brcmf: bcrmf@1 {
|
||||
+ reg = <1>;
|
||||
+ compatible = "brcm,bcm4329-fmac";
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <10 8>; /* PH10 / EINT10 */
|
||||
+ interrupt-names = "host-wake";
|
||||
+ };
|
||||
};
|
||||
|
||||
usbphy: phy@01c13400 {
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
|
||||
index 6a67712d..f620aea 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
|
||||
@@ -29,12 +29,23 @@
|
||||
};
|
||||
|
||||
mmc3: mmc@01c12000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc3_pins_a>;
|
||||
vmmc-supply = <®_vmmc3>;
|
||||
bus-width = <4>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
+
|
||||
+ brcmf: bcrmf@1 {
|
||||
+ reg = <1>;
|
||||
+ compatible = "brcm,bcm4329-fmac";
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <10 8>; /* PH10 / EINT10 */
|
||||
+ interrupt-names = "host-wake";
|
||||
+ };
|
||||
};
|
||||
|
||||
usbphy: phy@01c13400 {
|
|
@ -0,0 +1,75 @@
|
|||
From c6e2b7dad39a7887f935458d1c8de84db06243e1 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wens@csie.org>
|
||||
Date: Thu, 26 Dec 2013 17:15:47 +0800
|
||||
Subject: [PATCH] ARM: dts: sun7i: add bluetooth module to CubieTruck DTS
|
||||
|
||||
The CubieTruck has an AMPAK AP6210 WiFi+Bluetooth module. The
|
||||
Bluetooth part is a BCM20710 IC connected to UART2 in the A20
|
||||
SoC. The IC also takes a 32.768 KHz low power clock input, a power
|
||||
enable signal and a wake signal via GPIO.
|
||||
|
||||
The Bluetooth module supports out-of-band interrupt signaling via
|
||||
GPIO, but this is not supported in this patch.
|
||||
---
|
||||
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 36 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
index f9ab5d4..69d8c4c 100644
|
||||
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
|
||||
@@ -103,6 +103,20 @@
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
+
|
||||
+ bt_pwr_pin: bt_pwr_pin@0 {
|
||||
+ allwinner,pins = "PH18";
|
||||
+ allwinner,function = "gpio_out";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
+
|
||||
+ bt_wake_pin: bt_wake_pin@0 {
|
||||
+ allwinner,pins = "PH24";
|
||||
+ allwinner,function = "gpio_out";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
};
|
||||
|
||||
pwm: pwm@01c20e00 {
|
||||
@@ -123,6 +137,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+ uart2: serial@01c28800 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart2_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
i2c0: i2c@01c2ac00 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_pins_a>;
|
||||
@@ -214,4 +234,20 @@
|
||||
enable-active-high;
|
||||
gpio = <&pio 7 9 0>;
|
||||
};
|
||||
+
|
||||
+ rfkill-switches {
|
||||
+ compatible = "simple-bus";
|
||||
+ pinctrl-names = "default";
|
||||
+
|
||||
+ rfkill_bt {
|
||||
+ compatible = "rfkill-gpio";
|
||||
+ pinctrl-0 = <&bt_pwr_pin>, <&clk_out_a_pins_a>;
|
||||
+ rfkill-name = "bt";
|
||||
+ rfkill-type = <2>;
|
||||
+ bt_shutdown-gpios = <0>, <&pio 7 18 0>; /* PH18 */
|
||||
+ bt_reset-gpios = <&pio 7 24 0>; /* PH24 */
|
||||
+ clocks = <&clk_out_a>;
|
||||
+ clock-frequency = <32768>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
|
||||
@@ -529,6 +529,14 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ crypto: crypto-engine@01c15000 {
|
||||
+ compatible = "allwinner,sun7i-a20-crypto";
|
||||
+ reg = <0x01c15000 0x1000>;
|
||||
+ interrupts = <0 86 4>;
|
||||
+ clocks = <&ahb_gates 5>, <&ss_clk>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ };
|
||||
+
|
||||
spi2: spi@01c17000 {
|
||||
compatible = "allwinner,sun4i-a10-spi";
|
||||
reg = <0x01c17000 0x1000>;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,250 @@
|
|||
From 29b4146ec174f0f598d6b454caa335e8f57e392b Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 28 Jul 2014 23:05:14 +0200
|
||||
Subject: [PATCH] ARM: dts: sun7i: Add Banana Pi board
|
||||
|
||||
The Banana Pi is an A20 based development board using Raspberry Pi compatible
|
||||
IO headers. It comes with 1 GB RAM, 1 Gb ethernet, 2x USB host, sata, hdmi
|
||||
and stereo audio out + various expenansion headers:
|
||||
|
||||
http://www.lemaker.org/
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
arch/arm/boot/dts/Makefile | 1 +
|
||||
arch/arm/boot/dts/sun7i-a20-bananapi.dts | 214 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 215 insertions(+)
|
||||
create mode 100644 arch/arm/boot/dts/sun7i-a20-bananapi.dts
|
||||
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index 38c89ca..63422bd 100644
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -435,6 +435,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \
|
||||
sun6i-a31-hummingbird.dtb \
|
||||
sun6i-a31-m9.dtb
|
||||
dtb-$(CONFIG_MACH_SUN7I) += \
|
||||
+ sun7i-a20-bananapi.dtb \
|
||||
sun7i-a20-cubieboard2.dtb \
|
||||
sun7i-a20-cubietruck.dtb \
|
||||
sun7i-a20-hummingbird.dtb \
|
||||
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
|
||||
new file mode 100644
|
||||
index 0000000..0e7c9f5
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
|
||||
@@ -0,0 +1,214 @@
|
||||
+/*
|
||||
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * This file is dual-licensed: you can use it either under the terms
|
||||
+ * of the GPL or the X11 license, at your option. Note that this dual
|
||||
+ * licensing only applies to this file, and not this project as a
|
||||
+ * whole.
|
||||
+ *
|
||||
+ * a) This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this library; if not, write to the Free
|
||||
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
+ * MA 02110-1301 USA
|
||||
+ *
|
||||
+ * Or, alternatively,
|
||||
+ *
|
||||
+ * b) Permission is hereby granted, free of charge, to any person
|
||||
+ * obtaining a copy of this software and associated documentation
|
||||
+ * files (the "Software"), to deal in the Software without
|
||||
+ * restriction, including without limitation the rights to use,
|
||||
+ * copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
+ * sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following
|
||||
+ * conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
+ * OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+/include/ "sun7i-a20.dtsi"
|
||||
+/include/ "sunxi-common-regulators.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "LeMaker Banana Pi";
|
||||
+ compatible = "lemaker,bananapi", "allwinner,sun7i-a20";
|
||||
+
|
||||
+ soc@01c00000 {
|
||||
+ spi0: spi@01c05000 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi0_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ mmc0: mmc@01c0f000 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapi>;
|
||||
+ vmmc-supply = <®_vcc3v3>;
|
||||
+ bus-width = <4>;
|
||||
+ cd-gpios = <&pio 7 10 0>; /* PH10 */
|
||||
+ cd-inverted;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ usbphy: phy@01c13400 {
|
||||
+ usb1_vbus-supply = <®_usb1_vbus>;
|
||||
+ usb2_vbus-supply = <®_usb2_vbus>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ ehci0: usb@01c14000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ ohci0: usb@01c14400 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ ahci: sata@01c18000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ ehci1: usb@01c1c000 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ ohci1: usb@01c1c400 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ pinctrl@01c20800 {
|
||||
+ mmc0_cd_pin_bananapi: mmc0_cd_pin@0 {
|
||||
+ allwinner,pins = "PH10";
|
||||
+ allwinner,function = "gpio_in";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <1>;
|
||||
+ };
|
||||
+
|
||||
+ gmac_power_pin_bananapi: gmac_power_pin@0 {
|
||||
+ allwinner,pins = "PH23";
|
||||
+ allwinner,function = "gpio_out";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
+
|
||||
+ led_pins_bananapi: led_pins@0 {
|
||||
+ allwinner,pins = "PH24";
|
||||
+ allwinner,function = "gpio_out";
|
||||
+ allwinner,drive = <0>;
|
||||
+ allwinner,pull = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ir0: ir@01c21800 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ir0_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ uart0: serial@01c28000 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart0_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ uart3: serial@01c28c00 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart3_pins_b>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ uart7: serial@01c29c00 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart7_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ i2c0: i2c@01c2ac00 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c0_pins_a>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ axp209: pmic@34 {
|
||||
+ compatible = "x-powers,axp209";
|
||||
+ reg = <0x34>;
|
||||
+ interrupt-parent = <&nmi_intc>;
|
||||
+ interrupts = <0 8>;
|
||||
+
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c2: i2c@01c2b400 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c2_pins_a>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ gmac: ethernet@01c50000 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
|
||||
+ phy = <&phy1>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-supply = <®_gmac_3v3>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ phy1: ethernet-phy@1 {
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&led_pins_bananapi>;
|
||||
+
|
||||
+ green {
|
||||
+ label = "bananapi:green:usr";
|
||||
+ gpios = <&pio 7 24 0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ reg_usb1_vbus: usb1-vbus {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ reg_usb2_vbus: usb2-vbus {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ reg_gmac_3v3: gmac-3v3 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&gmac_power_pin_bananapi>;
|
||||
+ regulator-name = "gmac-3v3";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ startup-delay-us = <50000>;
|
||||
+ enable-active-high;
|
||||
+ gpio = <&pio 7 23 0>;
|
||||
+ };
|
||||
+};
|
Loading…
Reference in New Issue