lkml.org 
[lkml]   [2012]   [Dec]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH] input: i8042: Add support for devicetree to i8042 serio driver
Date
This patch adds basic devicetree support for the i8042 controller
driver.

Simple properties to specify the register offsets.
Optional properties to specify the linux device descriptions.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
.../devicetree/bindings/input/intel-8042.txt | 29 +++++
drivers/input/serio/Kconfig | 10 +-
drivers/input/serio/i8042-dt.h | 127 ++++++++++++++++++++
drivers/input/serio/i8042.c | 15 ++-
drivers/input/serio/i8042.h | 4 +-
5 files changed, 181 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/intel-8042.txt
create mode 100644 drivers/input/serio/i8042-dt.h

diff --git a/Documentation/devicetree/bindings/input/intel-8042.txt b/Documentation/devicetree/bindings/input/intel-8042.txt
new file mode 100644
index 0000000..68f6fa2
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/intel-8042.txt
@@ -0,0 +1,29 @@
+* Intel 8042 Keyboard controller
+
+Required properties:
+- compatible: should be "intel,8042"
+- regs: memory for keyboard controller
+- interrupts: two interrupts should be specified (keyboard and aux).
+- command-reg: offset in memory for command register
+- status-reg: offset in memory for status register
+- data-reg: offset in memory for data register
+
+Optional properties:
+- init-reset: Controller should be reset on init and cleanup
+
+Optional linux specific properties:
+- linux,kbd_phys_desc: defaults to i8042/serio0
+- linux,aux_phys_desc: defaults to i8042/serio1
+- linux,mux_phys_desc: defaults to i8042/serio%d
+
+
+Example:
+ keyboard@d8008800 {
+ compatible = "intel,8042";
+ reg = <0xD8008800 0x100>;
+ interrupts = <23 4>;
+ command-reg = <0x04>;
+ status-reg = <0x04>;
+ data-reg = <0x00>;
+ mux-ports = <2>;
+ };
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 4a4e182..26e97a3 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -21,8 +21,9 @@ if SERIO
config SERIO_I8042
tristate "i8042 PC Keyboard controller" if EXPERT || !X86
default y
- depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \
- (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN
+ depends on (!PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \
+ (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN) || \
+ (SERIO_I8042_DT)
help
i8042 is the chip over which the standard AT keyboard and PS/2
mouse are connected to the computer. If you use these devices,
@@ -33,6 +34,11 @@ config SERIO_I8042
To compile this driver as a module, choose M here: the
module will be called i8042.

+config SERIO_I8042_DT
+ tristate "i8042 Keyboard controller DT support" if EXPERT || !X86
+ depends on USE_OF
+ select SERIO_I8042
+
config SERIO_SERPORT
tristate "Serial port line discipline"
default y
diff --git a/drivers/input/serio/i8042-dt.h b/drivers/input/serio/i8042-dt.h
new file mode 100644
index 0000000..3875c90
--- /dev/null
+++ b/drivers/input/serio/i8042-dt.h
@@ -0,0 +1,127 @@
+#ifndef _I8042_DT_H
+#define _I8042_DT_H
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+/*
+ * 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.
+ */
+
+static void __iomem *dt_base;
+static const char *dt_kbd_phys_desc;
+static const char *dt_aux_phys_desc;
+static const char *dt_mux_phys_desc;
+static int dt_kbd_irq;
+static int dt_aux_irq;
+static unsigned int dt_command_reg;
+static unsigned int dt_status_reg;
+static unsigned int dt_data_reg;
+
+#define I8042_KBD_PHYS_DESC dt_kbd_phys_desc
+#define I8042_AUX_PHYS_DESC dt_aux_phys_desc
+#define I8042_MUX_PHYS_DESC dt_mux_phys_desc
+
+#define I8042_KBD_IRQ (dt_kbd_irq)
+#define I8042_AUX_IRQ (dt_aux_irq)
+
+#define I8042_COMMAND_REG (dt_command_reg)
+#define I8042_STATUS_REG (dt_status_reg)
+#define I8042_DATA_REG (dt_data_reg)
+
+
+static inline int i8042_read_data(void)
+{
+ return readb(dt_base + dt_data_reg);
+}
+
+static inline int i8042_read_status(void)
+{
+ return readb(dt_base + dt_status_reg);
+}
+
+static inline void i8042_write_data(int val)
+{
+ writeb(val, dt_base + dt_data_reg);
+}
+
+static inline void i8042_write_command(int val)
+{
+ writeb(val, dt_base + dt_command_reg);
+}
+
+static inline int dt_parse_node(struct device_node *np)
+{
+ int ret;
+
+ dt_base = of_iomap(np, 0);
+ if (!dt_base)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(np, "command-reg", &dt_command_reg);
+ if (ret) {
+ pr_err("i8042-dt: command-reg missing or invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "status-reg", &dt_status_reg);
+ if (ret) {
+ pr_err("i8042-dt: status-reg missing or invalid\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "data-reg", &dt_data_reg);
+ if (ret) {
+ pr_err("i8042-dt: data-reg missing or invalid\n");
+ return ret;
+ }
+
+ dt_kbd_irq = irq_of_parse_and_map(np, 0);
+ dt_aux_irq = irq_of_parse_and_map(np, 1);
+
+ ret = of_property_read_string(np, "linux,kbd_phys_desc",
+ &dt_kbd_phys_desc);
+ if (ret)
+ dt_kbd_phys_desc = "i8042/serio0";
+
+ ret = of_property_read_string(np, "linux,aux_phys_desc",
+ &dt_aux_phys_desc);
+ if (ret)
+ dt_aux_phys_desc = "i8042/serio1";
+
+ ret = of_property_read_string(np, "linux,mux_phys_desc",
+ &dt_mux_phys_desc);
+ if (ret)
+ dt_mux_phys_desc = "i8042/serio%d";
+
+ if (of_get_property(np, "init-reset", NULL))
+ i8042_reset = true;
+
+ return 0;
+}
+
+static inline int i8042_platform_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "intel,8042");
+ if (!np) {
+ pr_err("%s: no devicetree node found\n", __func__);
+ return -ENODEV;
+ }
+
+ dt_parse_node(np);
+
+ return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+ if (dt_base)
+ iounmap(dt_base);
+}
+
+#endif
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 78e4de4..c4cb1c4 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1447,6 +1447,11 @@ static int i8042_remove(struct platform_device *dev)
return 0;
}

+static struct of_device_id i8042_dt_ids[] = {
+ { .compatible = "intel,8042" },
+ { /* Sentinel */ },
+};
+
static struct platform_driver i8042_driver = {
.driver = {
.name = "i8042",
@@ -1454,6 +1459,7 @@ static struct platform_driver i8042_driver = {
#ifdef CONFIG_PM
.pm = &i8042_pm_ops,
#endif
+ .of_match_table = i8042_dt_ids,
},
.remove = i8042_remove,
.shutdown = i8042_shutdown,
@@ -1461,7 +1467,9 @@ static struct platform_driver i8042_driver = {

static int __init i8042_init(void)
{
+#ifndef CONFIG_SERIO_I8042_DT
struct platform_device *pdev;
+#endif
int err;

dbg_init();
@@ -1474,12 +1482,17 @@ static int __init i8042_init(void)
if (err)
goto err_platform_exit;

+#ifdef CONFIG_SERIO_I8042_DT
+ err = platform_driver_probe(&i8042_driver, i8042_probe);
+ if (err)
+ goto err_platform_exit;
+#else
pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
if (IS_ERR(pdev)) {
err = PTR_ERR(pdev);
goto err_platform_exit;
}
-
+#endif
panic_blink = i8042_panic_blink;

return 0;
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index 3452708..c8d70d9 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -14,7 +14,9 @@
* Arch-dependent inline functions and defines.
*/

-#if defined(CONFIG_MACH_JAZZ)
+#if defined(CONFIG_SERIO_I8042_DT)
+#include "i8042-dt.h"
+#elif defined(CONFIG_MACH_JAZZ)
#include "i8042-jazzio.h"
#elif defined(CONFIG_SGI_HAS_I8042)
#include "i8042-ip22io.h"
--
1.7.9.5


\
 
 \ /
  Last update: 2012-12-31 00:01    [W:0.056 / U:0.372 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site