summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/omap3-minnow.dtsi14
-rwxr-xr-xarch/arm/configs/minnow_defconfig1
-rw-r--r--drivers/misc/Kconfig6
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/c55_ctrl.c191
5 files changed, 213 insertions, 0 deletions
diff --git a/arch/arm/boot/dts/omap3-minnow.dtsi b/arch/arm/boot/dts/omap3-minnow.dtsi
index 512bf18eabd..172224bc50a 100644
--- a/arch/arm/boot/dts/omap3-minnow.dtsi
+++ b/arch/arm/boot/dts/omap3-minnow.dtsi
@@ -11,6 +11,13 @@
model = "Motorola OMAP3 Platform";
compatible = "mot,omap3-minnow", "ti,omap3";
+ c55-ctrl@0 {
+ compatible = "ti,c55-ctrl";
+ reg = <0 0>;
+ gpios = <&gpio3 12 1>, /* IRQ gpio_ap_int gpio-076 */
+ <&gpio3 16 0>, /* gpio_reset gpio-80*/
+ <&gpio3 17 2>; /* gpio_c55_int gpio-81*/
+ };
Display@0 {
compatible = "mot,minnow-panel-dsi-cm";
/* 0: MINNOW_PANEL_CM_220X176
@@ -154,6 +161,9 @@
0x08e 0x104 /* GPMC_CLK, MODE4 | INPUT */
0x0a0 0x002 /* GPMC_WAIT2, MODE2 | OUTPUT */
0x0a2 0x102 /* GPMC_WAIT3, MODE2 | INPUT */
+ 0x0b8 0x104 /* DSS_DATA6, MODE4 | INPUT */
+ 0x0c0 0x004 /* DSS_DATA10, MODE4 | OUTPUT */
+ 0x0c2 0x004 /* DSS_DATA11, MODE4 | OUTPUT */
0x0c6 0x004 /* DSS_DATA13, MODE4 | OUTPUT */
0x0ea 0x004 /* MUXCAM_D2, MODE4 | OUTPUT */
0x0e4 0x004 /* CAM_FLD, MODE4 | OUTPUT */
@@ -168,6 +178,10 @@
0x14e 0x000 /* UART1_RTS, MODE0 | OUTPUT */
0x150 0x100 /* UART1_CTS, MODE0 | INPUT */
0x152 0x100 /* UART1_RX, MODE0 | INPUT */
+ 0x154 0x100 /* MCBSP4_CLKX, MODE0| INPUT*/
+ 0x156 0x100 /* MCBSP4_DR, MODE0 | INPUT */
+ 0x158 0x000 /* MCBSP4_DX, MODE0 | OUTPUT */
+ 0x15a 0x118 /* MCBSP4_FSX,MODE0 | INPUT_PULLUP*/
0x168 0x104 /* MCBSP1_CLKX, MODE4 | INPUT */
0x16c 0x004 /* UART3_RTS_SD, MODE4 | OUTPUT */
0x18e 0x118 /* I2C2_SCL, MODE0 | INPUT_PULLUP */
diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig
index 39954c2e542..a32a9107d8e 100755
--- a/arch/arm/configs/minnow_defconfig
+++ b/arch/arm/configs/minnow_defconfig
@@ -953,6 +953,7 @@ CONFIG_VIB_GPIO=y
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
+CONFIG_C55_CTRL=y
# CONFIG_C2PORT is not set
#
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 18c65fcca01..8f2eb08c9a2 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -535,6 +535,12 @@ config SRAM
the genalloc API. It is supposed to be used for small on-chip SRAM
areas found on many SoCs.
+config C55_CTRL
+ tristate "TI C55 Control driver"
+ help
+ This option enables device driver to control the TI C55 IC. This
+ is intended to be a simple driver which only exports the GPIOs
+ for user space use.
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 33404218a5e..656d96be5ba 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_MFD_M4SENSORHUB) += m4sensorhub_display.o
obj-$(CONFIG_MFD_M4SENSORHUB) += m4sensorhub_audio.o
obj-$(CONFIG_MFD_M4SENSORHUB) += m4sensorhub_passive.o
obj-$(CONFIG_VIB_GPIO) += vib-gpio.o
+obj-$(CONFIG_C55_CTRL) += c55_ctrl.o
diff --git a/drivers/misc/c55_ctrl.c b/drivers/misc/c55_ctrl.c
new file mode 100644
index 00000000000..04f29d3ff9a
--- /dev/null
+++ b/drivers/misc/c55_ctrl.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2013 Motorola Mobility LLC
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/err.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/wakelock.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+
+struct c55_ctrl_data {
+ int int_gpio;
+ struct wake_lock wake_lock;
+};
+
+#define NUM_GPIOS 3
+
+const char *gpio_labels[NUM_GPIOS] = {
+ "gpio_ap_int",
+ "gpio_reset",
+ "gpio_c55_int"
+};
+
+static irqreturn_t c55_ctrl_isr(int irq, void *data)
+{
+ struct c55_ctrl_data *cdata = data;
+
+ pr_debug("%s: value=%d\n", __func__, gpio_get_value(cdata->int_gpio));
+
+ /* Interrupt is active low */
+ if (gpio_get_value(cdata->int_gpio) == 0)
+ wake_lock(&cdata->wake_lock);
+ else
+ wake_unlock(&cdata->wake_lock);
+
+ return IRQ_HANDLED;
+}
+
+static void c55_ctrl_int_setup(struct c55_ctrl_data *cdata, int gpio)
+{
+ int ret;
+ int irq = __gpio_to_irq(gpio);
+ unsigned int flags = 0;
+
+ if (cdata->int_gpio >= 0) {
+ /* Interrupt already registered */
+ return;
+ }
+
+ /* Interrupt is shared with user space */
+ flags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+ flags |= IRQF_SHARED|IRQF_ONESHOT;
+
+ ret = request_threaded_irq(irq, NULL, c55_ctrl_isr,
+ flags, "c55_ctrl", cdata);
+ if (ret) {
+ pr_err("%s: IRQ request failed: %d\n", __func__, ret);
+ return;
+ }
+
+ enable_irq_wake(irq);
+ cdata->int_gpio = gpio;
+}
+
+static int c55_ctrl_gpio_setup(struct c55_ctrl_data *cdata, struct device *dev)
+{
+ int i;
+
+ if (of_gpio_count(dev->of_node) != NUM_GPIOS) {
+ dev_err(dev, "%s: gpio count is not %d.\n", __func__, NUM_GPIOS);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < NUM_GPIOS; i++) {
+ enum of_gpio_flags flags;
+ int gpio;
+
+ gpio = of_get_gpio_flags(dev->of_node, i, &flags);
+ if (gpio < 0) {
+ pr_err("%s: of_get_gpio failed: %d\n", __func__, gpio);
+ return gpio;
+ }
+
+ gpio_request(gpio, gpio_labels[i]);
+
+ gpio_export(gpio, false);
+ gpio_export_link(dev, gpio_labels[i], gpio);
+
+ if ((flags & GPIOF_IN) == GPIOF_IN) {
+ gpio_direction_input(gpio);
+ c55_ctrl_int_setup(cdata, gpio);
+ } else {
+ if ((flags & GPIOF_OUT_INIT_HIGH) == GPIOF_OUT_INIT_HIGH)
+ gpio_direction_output(gpio, 1);
+ else
+ gpio_direction_output(gpio, 0);
+ }
+ }
+
+ return 0;
+}
+
+static int c55_ctrl_probe(struct platform_device *pdev)
+{
+ struct c55_ctrl_data *cdata;
+ int ret;
+ if (!pdev->dev.of_node) {
+ /* Platform data not currently supported */
+ dev_err(&pdev->dev, "%s: of devtree data not found\n", __func__);
+ return -EINVAL;
+ }
+
+ cdata = devm_kzalloc(&pdev->dev, sizeof(*cdata), GFP_KERNEL);
+ if (cdata == NULL) {
+ dev_err(&pdev->dev, "%s: devm_kzalloc failed.\n", __func__);
+ return -ENOMEM;
+ }
+ cdata->int_gpio = -1;
+ ret = c55_ctrl_gpio_setup(cdata, &pdev->dev);
+
+ if (ret) {
+ dev_err(&pdev->dev, "%s: c55_ctrl_gpio_setup failed.\n", __func__);
+ return ret;
+ }
+
+ wake_lock_init(&cdata->wake_lock, WAKE_LOCK_SUSPEND, "c55_ctrl");
+
+ platform_set_drvdata(pdev, cdata);
+ return 0;
+}
+
+static int c55_ctrl_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct of_device_id c55_ctrl_match[] = {
+ {.compatible = "ti,c55-ctrl",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, c55_ctrl_match);
+
+static const struct platform_device_id c55_ctrl_id_table[] = {
+ {"c55_ctrl", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(of, c55_ctrl_id_table);
+
+static struct platform_driver c55_ctrl_driver = {
+ .driver = {
+ .name = "c55_ctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = c55_ctrl_match,
+ },
+ .probe = c55_ctrl_probe,
+ .remove = c55_ctrl_remove,
+ .id_table = c55_ctrl_id_table,
+};
+
+static int __init c55_ctrl_init(void)
+{
+ return platform_driver_register(&c55_ctrl_driver);
+}
+
+static void __exit c55_ctrl_exit(void)
+{
+ platform_driver_unregister(&c55_ctrl_driver);
+}
+
+module_init(c55_ctrl_init);
+module_exit(c55_ctrl_exit);
+
+MODULE_ALIAS("platform:c55_ctrl");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Motorola");
+MODULE_DESCRIPTION("TI C55 control driver");