Mass patch of the differences between the parrot code dump and 3.4.11 which it is based upon.
diff --git a/arch/arm/mach-parrot7/gpu-m400.c b/arch/arm/mach-parrot7/gpu-m400.c
new file mode 100644
index 0000000..7e81f29
--- /dev/null
+++ b/arch/arm/mach-parrot7/gpu-m400.c
@@ -0,0 +1,152 @@
+/**
+ * linux/arch/arm/mach-parrot7/gpu-m400.c - Parrot7 MALI400 GPU platform interface
+ *
+ * Copyright (C) 2013 Parrot S.A.
+ *
+ * author: Alvaro Moran <alvaro.moran@parrot.com>
+ * date: 28-05-2013
+ *
+ * This file is released under the GPL
+ */
+
+#if defined(CONFIG_MALI400) || \
+ defined(CONFIG_MALI400_MODULE)
+
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include "gpu/mali400/include/linux/mali/mali_utgard_uk_types.h"
+#include "gpu/mali400/include/linux/mali/mali_utgard.h"
+#include "gpu.h"
+#include "common.h"
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif
+
+static struct mali_gpu_device_data mali_gpu_data = {
+ /* Mali OS memory limit */
+ .shared_mem_size = 512 * 1024 * 1024, /* 512MB */
+
+ /* Framebuffer memory */
+ /* This will be set after the AVI FB has been set
+ .fb_start = <base address of contigous frame buffer memory>,
+ .fb_size = <size of frame buffer memory>
+ */
+
+ /* DVFS */
+ //.utilization_interval = 1000, /* ms */
+ //.utilization_handler = <utilization function>,
+
+};
+
+static struct resource mali_gpu_resources[] = {
+MALI_GPU_RESOURCES_MALI400_MP4(P7_GPU,
+ P7_GPU_GP_IRQ,
+ P7_GPU_GPMMU_IRQ,
+ P7_GPU_PP0_IRQ,
+ P7_GPU_PPMMU0_IRQ,
+ P7_GPU_PP1_IRQ,
+ P7_GPU_PPMMU1_IRQ,
+ P7_GPU_PP2_IRQ,
+ P7_GPU_PPMMU2_IRQ,
+ P7_GPU_PP3_IRQ,
+ P7_GPU_PPMMU3_IRQ)
+};
+
+static struct resource mali_gpu_resources_3pix[] = {
+MALI_GPU_RESOURCES_MALI400_MP3(P7_GPU,
+ P7_GPU_GP_IRQ,
+ P7_GPU_GPMMU_IRQ,
+ P7_GPU_PP0_IRQ,
+ P7_GPU_PPMMU0_IRQ,
+ P7_GPU_PP1_IRQ,
+ P7_GPU_PPMMU1_IRQ,
+ P7_GPU_PP2_IRQ,
+ P7_GPU_PPMMU2_IRQ)
+};
+
+static struct resource mali_gpu_resources_2pix[] = {
+MALI_GPU_RESOURCES_MALI400_MP2(P7_GPU,
+ P7_GPU_GP_IRQ,
+ P7_GPU_GPMMU_IRQ,
+ P7_GPU_PP0_IRQ,
+ P7_GPU_PPMMU0_IRQ,
+ P7_GPU_PP1_IRQ,
+ P7_GPU_PPMMU1_IRQ)
+};
+
+static struct resource mali_gpu_resources_1pix[] = {
+MALI_GPU_RESOURCES_MALI400_MP1(P7_GPU,
+ P7_GPU_GP_IRQ,
+ P7_GPU_GPMMU_IRQ,
+ P7_GPU_PP0_IRQ,
+ P7_GPU_PPMMU0_IRQ)
+};
+
+struct platform_device mali_gpu_device = {
+ .name = MALI_GPU_NAME_UTGARD,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mali_gpu_resources),
+ .resource = mali_gpu_resources,
+ .dev.platform_data = &mali_gpu_data,
+ .dev.coherent_dma_mask = DMA_BIT_MASK(32),
+};
+
+static int __init p7_init_gpu_m400(void)
+{
+ int ret = 0;
+
+ /* We have Mali400 only on Revision 3. */
+ if (P7_CHIPREV_R3 != p7_chiprev())
+ return 0;
+
+ ret = platform_device_register(&mali_gpu_device);
+ if (ret) {
+ printk(KERN_ERR "Error registering Mali400 GPU device: %d.\n", ret);
+ goto out;
+#ifdef CONFIG_PM_RUNTIME
+ } else {
+ pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
+ pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
+ pm_runtime_enable(&(mali_gpu_device.dev));
+#endif
+ }
+ printk(KERN_INFO"Mali400 GPU registered.\n");
+
+out:
+ return ret;
+}
+
+int __init p7_init_gpu_fb_m400(unsigned long fb_start, unsigned long fb_size, int nb_pixcore)
+{
+ if (nb_pixcore == 1) {
+ mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_1pix);
+ mali_gpu_device.resource = mali_gpu_resources_1pix;
+ }
+ else if (nb_pixcore == 2) {
+ mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_2pix);
+ mali_gpu_device.resource = mali_gpu_resources_2pix;
+ }
+ else if (nb_pixcore == 3) {
+ mali_gpu_device.num_resources = ARRAY_SIZE(mali_gpu_resources_3pix);
+ mali_gpu_device.resource = mali_gpu_resources_3pix;
+ }
+
+ /* Setup FB start and size according to given resource */
+ if (fb_start && fb_size) {
+ mali_gpu_data.fb_start = fb_start;
+ mali_gpu_data.fb_size = fb_size;
+
+ printk(KERN_INFO"Mali400 GPU Framebuffer: 0x%08lx size 0x%lx\n",
+ mali_gpu_data.fb_start,
+ mali_gpu_data.fb_size);
+ }
+
+ return p7_init_gpu_m400();
+}
+
+#endif /* defined(CONFIG_MALI400) || \
+ defined(CONFIG_MALI400_MODULE) */
+
diff --git a/arch/arm/mach-parrot7/gpu.c b/arch/arm/mach-parrot7/gpu.c
new file mode 100644
index 0000000..ee6f297
--- /dev/null
+++ b/arch/arm/mach-parrot7/gpu.c
@@ -0,0 +1,96 @@
+/**
+ * linux/arch/arm/mach-parrot7/gpu.c - Parrot7 GPU platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Alvaro Moran <alvaro.moran@parrot.com>
+ * date: 31-10-2012
+ *
+ * This file is released under the GPL
+ */
+
+#if defined(CONFIG_GPU_PARROT7) || \
+ defined(CONFIG_GPU_PARROT7_MODULE)
+
+#if !( defined(CONFIG_MALI200) || \
+ defined(CONFIG_MALI200_MODULE) ) && \
+ !( defined(CONFIG_MALI400) || \
+ defined(CONFIG_MALI400_MODULE))
+#error You need to select either Mali200 or Mali400 to enable the GPU.
+#endif
+
+#include "common.h"
+#include "gpu.h"
+
+static struct p7gpu_pm_plat_data p7gpu_pdata;
+
+static struct platform_device p7gpu_pm_dev = {
+ .name = "p7gpu",
+ .id = 0
+};
+
+static char* mali200_clocks_names[] = { M200_BUS_CLK, M200_CORE_CLK };
+static char *mali400_clocks_names[] = { M400_CLK,
+ M400_CLK"_pp0", M400_CLK"_pp1", M400_CLK"_pp2", M400_CLK"_pp3" };
+
+
+static int p7_init_gpu_pm(char** clocks_names, int num)
+{
+ int ret = 0;
+
+ /* Setup correct clock names */
+ if (NULL == clocks_names)
+ panic("P7 GPU Clock names not provided.");
+ p7gpu_pdata.clocks_names = clocks_names;
+ p7gpu_pdata.clocks_number = num;
+
+ p7gpu_pm_dev.dev.platform_data = &p7gpu_pdata;
+
+ /* Add power management device */
+ ret = platform_device_register(&p7gpu_pm_dev);
+ if (ret) {
+ printk(KERN_ERR "Error registering P7 GPU device: %d.\n", ret);
+ platform_device_unregister(&p7gpu_pm_dev);
+ goto out;
+ }
+ printk(KERN_INFO"P7 GPU device PM registered.\n");
+
+out:
+ return ret;
+}
+
+/*
+ * Setup GPU's framebuffer, passsing framebuffer buffer information.
+ */
+int __init p7_init_gpu_fb(unsigned long fb_start, unsigned long fb_size, int nb_pixcore)
+{
+ int ret = 0;
+ int chiprev = p7_chiprev();
+
+ /* Initialize Mali200/400 (and register platform device if needed) */
+ switch(chiprev) {
+ case P7_CHIPREV_R1:
+ case P7_CHIPREV_R2:
+ ret = p7_init_gpu_pm(mali200_clocks_names, ARRAY_SIZE(mali200_clocks_names));
+ if (ret == 0)
+ ret = p7_init_gpu_fb_m200(fb_start, fb_size);
+ break;
+ case P7_CHIPREV_R3:
+ if (nb_pixcore < 0 || nb_pixcore > 4)
+ ret = -1;
+ /* clock should be registered before gpu driver */
+ if (ret == 0)
+ ret = p7_init_gpu_pm(mali400_clocks_names, ARRAY_SIZE(mali400_clocks_names) - 4 + nb_pixcore);
+ if (ret == 0)
+ ret = p7_init_gpu_fb_m400(fb_start, fb_size, nb_pixcore);
+ break;
+ default:
+ ret = -1;
+ printk(KERN_ERR "GPU not initialized: Unknown P7 revision.\n");
+ }
+ return ret;
+}
+
+#endif /* defined(CONFIG_GPU_PARROT7) || \
+ defined(CONFIG_GPU_PARROT7_MODULE) */
+
diff --git a/arch/arm/mach-parrot7/gpu.h b/arch/arm/mach-parrot7/gpu.h
new file mode 100644
index 0000000..67b419a
--- /dev/null
+++ b/arch/arm/mach-parrot7/gpu.h
@@ -0,0 +1,40 @@
+/**
+ * linux/arch/arm/mach-parrot7/gpu.h - Parrot7 MALI200 GPU platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Alvaro Moran <alvaro.moran@parrot.com>
+ * date: 01-11-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include "gpu/p7gpu-pm.h"
+
+#if defined(CONFIG_GPU_PARROT7) || \
+ defined(CONFIG_GPU_PARROT7_MODULE)
+int p7_init_gpu_fb(unsigned long fb_start, unsigned long fb_size, int nb_pixcore) __init;
+
+#else
+#define p7_init_gpu_fb(_fb_start, _fb_size, nb_pixcore) \
+ ({ -ENOSYS; })
+#endif
+
+
+#if defined(CONFIG_MALI200) || \
+ defined(CONFIG_MALI200_MODULE)
+int p7_init_gpu_fb_m200(unsigned long fb_start, unsigned long fb_size) __init;
+#else
+#define p7_init_gpu_fb_m200(_fb_start, _fb_size) \
+ ({ -ENOSYS; })
+#endif
+
+
+#if defined(CONFIG_MALI400) || \
+ defined(CONFIG_MALI400_MODULE)
+int p7_init_gpu_fb_m400(unsigned long fb_start, unsigned long fb_size, int nb_pixcore) __init;
+#else
+#define p7_init_gpu_fb_m400(_fb_start, _fb_size, nb_pixcore) \
+ ({ -ENOSYS; })
+#endif
+
diff --git a/arch/arm/mach-parrot7/i2cm.c b/arch/arm/mach-parrot7/i2cm.c
new file mode 100644
index 0000000..c2ebb47
--- /dev/null
+++ b/arch/arm/mach-parrot7/i2cm.c
@@ -0,0 +1,329 @@
+/**
+ * linux/arch/arm/mach-parrot7/i2cm.c - Parrot7 i2c master controller platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 12-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/clkdev.h>
+#include <i2c/p7-i2cm.h>
+#include <i2c/muxes/p7-i2cmux.h>
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include "pinctrl.h"
+#include "common.h"
+#include "clock.h"
+#include "i2cm.h"
+
+/* Master / bus 0 resources */
+static struct resource p7_i2cm0_res[] = {
+ [0] = {
+ .start = P7_I2CM0,
+ .end = P7_I2CM0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CM0_IRQ,
+ .end = P7_I2CM0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Master / bus 1 resources */
+static struct resource p7_i2cm1_res[] = {
+ [0] = {
+ .start = P7_I2CM1,
+ .end = P7_I2CM1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CM1_IRQ,
+ .end = P7_I2CM1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Master / bus 2 resources */
+static struct resource p7_i2cm2_res[] = {
+ [0] = {
+ .start = P7_I2CM2,
+ .end = P7_I2CM2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CM2_IRQ,
+ .end = P7_I2CM2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Master / bus 3 resources */
+static struct resource p7_i2cm3_res[] = {
+ [0] = {
+ .start = P7_I2CMS,
+ .end = P7_I2CMS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CMS_IRQ,
+ .end = P7_I2CMS_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device p7_i2cm_devs[] = {
+ {
+ .name = P7I2CM_DRV_NAME,
+ .id = 0,
+ .resource = p7_i2cm0_res,
+ .num_resources = ARRAY_SIZE(p7_i2cm0_res)
+ },
+ {
+ .name = P7I2CM_DRV_NAME,
+ .id = 1,
+ .resource = p7_i2cm1_res,
+ .num_resources = ARRAY_SIZE(p7_i2cm1_res)
+ },
+ {
+ .name = P7I2CM_DRV_NAME,
+ .id = 2,
+ .resource = p7_i2cm2_res,
+ .num_resources = ARRAY_SIZE(p7_i2cm2_res)
+ },
+ {
+ .name = P7I2CM_DRV_NAME,
+ .id = 3,
+ .resource = p7_i2cm3_res,
+ .num_resources = ARRAY_SIZE(p7_i2cm3_res)
+ },
+};
+
+/**
+ * p7_init_i2cm() - Instantiate I2C master controller identified by @bus
+ * for further driver usage.
+ *
+ * @bus: master controller / bus identifier
+ * @pdata: controller platform specific data
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_i2cm(int bus,
+ struct p7i2cm_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(bus >= ARRAY_SIZE(p7_i2cm_devs));
+ BUG_ON(! pdata);
+ BUG_ON(pin_cnt && !pins);
+#endif
+ if (bus >= ARRAY_SIZE(p7_i2cm_devs)) {
+ return;
+ }
+ switch(p7_chiprev())
+ {
+ case P7_CHIPREV_R1:
+ pdata->revision = I2CM_REVISION_1;
+ break;
+ case P7_CHIPREV_R2:
+ pdata->revision = I2CM_REVISION_2;
+ break;
+ case P7_CHIPREV_R3:
+ pdata->revision = I2CM_REVISION_3;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ /* Assign pins before registering device in cases driver is already loaded. */
+ if (pin_cnt) {
+ char buf[10];
+ snprintf(buf, 10, "p7-i2cm.%d", bus);
+ err = p7_assign_pins(buf, pins, pin_cnt);
+ if (err)
+ goto err;
+ }
+
+ err = p7_init_dev(&p7_i2cm_devs[bus], pdata, NULL, 0);
+ if (! err)
+ return;
+
+ /*
+ * Pinctrl does not provide us with a way to remove registered pin
+ * mappings...
+ */
+
+err:
+ panic("p7: failed to init I2C master controller %d (%d)\n", bus, err);
+}
+
+#if defined(CONFIG_I2C_MUX_PARROT7) || defined(CONFIG_I2C_MUX_PARROT7_MODULE)
+
+/* Only I2CM_2 can be muxed on the P7 */
+static struct platform_device p7_i2cmux_dev = {
+ .name = P7I2CMUX_DRV_NAME,
+ .id = 0,
+};
+
+#include <i2c/muxes/p7-i2cmux.h>
+
+/**
+ * p7_init_i2cm2_muxed() - Instantiate I2C master controller 2 handling several
+ * physical buses. Only I2CM2 can be used that way on
+ * the P7.
+ *
+ * @pdata: platform data for...
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ */
+void __init p7_init_i2cm_muxed(int bus,
+ struct p7i2cm_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt,
+ struct p7i2cmux_plat_data* mux_pdata,
+ struct p7i2cmux_pins const* mux_pins)
+{
+ char dname[] = "p7-i2cmux.xx";
+ size_t i;
+ int ret;
+
+#ifdef DEBUG
+ BUG_ON(! pdata);
+ BUG_ON(! mux_pdata);
+ BUG_ON(! mux_pdata->channel_names);
+ BUG_ON(! mux_pdata->nr_channels);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+ BUG_ON(! mux_pins);
+#endif
+
+ /* Register the I2CM without any associated pins */
+ pdata->muxed = 1;
+ p7_init_i2cm(bus, pdata, NULL, 0);
+
+ /* We register the pin configurations first in case the driver is
+ * already loaded */
+
+ /* Register default pin configuration */
+ snprintf(dname, sizeof(dname), "p7-i2cmux.%d", bus);
+ ret = p7_assign_named_pins(dname, NULL, pins, pin_cnt);
+
+ /* Register alternate buses pin configurations */
+ for (i = 0; ! ret && i < mux_pdata->nr_channels; i++)
+ ret = p7_assign_named_pins(dname,
+ mux_pdata->channel_names[i],
+ mux_pins[i].pinmap,
+ mux_pins[i].sz);
+ if (ret)
+ goto err;
+
+ /* Register the mux device */
+ mux_pdata->parent = bus;
+ p7_i2cmux_dev.id = bus;
+
+ ret = p7_init_dev(&p7_i2cmux_dev, mux_pdata, NULL, 0);
+ if (!ret)
+ return;
+
+err:
+ panic("p7: failed to init muxed I2C master controller %d (%d)\n",
+ bus,
+ ret);
+}
+
+#endif /* #if defined(CONFIG_I2C_MUX_PARROT7) || \
+ defined(CONFIG_I2C_MUX_PARROT7_MODULE) */
+
+/**
+ * p7_init_i2cm_slave() - Register I2C slave device to master controller
+ * identified by @bus for further driver usage.
+ *
+ * @bus: master controller / bus identifier
+ * @info: slave device descriptor
+ * @pins: array of pin functions and optional settings
+ * @pin_cnt: number of element of @pins array
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ */
+int __init p7_init_i2cm_slave(int bus,
+ struct i2c_board_info const* info,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ struct i2c_adapter* adapt;
+ struct i2c_client* client;
+ char* name = NULL;
+ int err = 0;
+
+#ifdef DEBUG
+ BUG_ON(! info);
+
+ pr_debug("p7: registering %s %d-%04hx...\n", info->type, bus, info->addr);
+#endif
+
+ /*
+ * We need to use dynamic slave registration here since master driver
+ * might already be loaded. All static board info would therefore be
+ * ignored.
+ * Get master assigned to bus...
+ */
+ adapt = i2c_get_adapter(bus);
+ if (! adapt) {
+ printk("failed to get adapter\n");
+ err = -ENODEV;
+ goto err;
+ }
+
+ if (pin_cnt) {
+ name = kasprintf(GFP_KERNEL,
+ "%d-%04x",
+ i2c_adapter_id(adapt),
+ info->addr | ((info->flags & I2C_CLIENT_TEN)
+ ? 0xa000 : 0));
+ if (! name)
+ goto put;
+
+ err = p7_assign_named_pins(name, NULL, pins, pin_cnt);
+ if (err) {
+ kfree(name);
+ goto put;
+ }
+ }
+
+ /* Register new slave to master retrieved above... */
+ client = i2c_new_device(adapt, info);
+ if (! client) {
+ err = -ENXIO;
+ /*
+ * Don't free name since we cannot unregister pin mapping (which would
+ * still holds reference to name).
+ */
+ goto put;
+ }
+
+ if (err)
+ i2c_unregister_device(client);
+
+put:
+ i2c_put_adapter(adapt);
+err:
+ WARN(err,
+ "p7: failed to register %s %d-%04hx (%d)\n",
+ info->type,
+ bus,
+ info->addr,
+ err);
+ return err;
+}
diff --git a/arch/arm/mach-parrot7/i2cm.h b/arch/arm/mach-parrot7/i2cm.h
new file mode 100644
index 0000000..1338fd1
--- /dev/null
+++ b/arch/arm/mach-parrot7/i2cm.h
@@ -0,0 +1,75 @@
+/**
+ * linux/arch/arm/mach-parrot7/i2cm.h - Parrot7 I2C master controller platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 12-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_I2CM_H
+#define _ARCH_PARROT7_I2CM_H
+
+struct p7i2cm_plat_data;
+struct i2c_board_info;
+struct pinctrl_map;
+
+#if defined(CONFIG_I2CM_PARROT7) || \
+ defined(CONFIG_I2CM_PARROT7_MODULE)
+
+#include <linux/init.h>
+
+extern void p7_init_i2cm(int,
+ struct p7i2cm_plat_data*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+
+extern int p7_init_i2cm_slave(int,
+ struct i2c_board_info const*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+#else /* defined(CONFIG_I2CM_PARROT7) || \
+ defined(CONFIG_I2CM_PARROT7_MODULE) */
+
+#define p7_init_i2cm(_bus, _pdata, _pins, _pins_nr)
+#define p7_init_i2cm_slave(_bus, _info, _pins, _pins_nr) \
+ ({ -ENOSYS; })
+
+#endif /* defined(CONFIG_I2CM_PARROT7) || \
+ defined(CONFIG_I2CM_PARROT7_MODULE) */
+
+#if defined(CONFIG_I2C_MUX_PARROT7) || \
+ defined(CONFIG_I2C_MUX_PARROT7_MODULE)
+
+struct p7i2cmux_plat_data;
+
+struct p7i2cmux_pins {
+ struct pinctrl_map* pinmap;
+ size_t sz;
+};
+
+extern void p7_init_i2cm_muxed(int,
+ struct p7i2cm_plat_data*,
+ struct pinctrl_map*,
+ size_t,
+ struct p7i2cmux_plat_data*,
+ struct p7i2cmux_pins const*) __init;
+
+#else
+
+struct p7i2cmux_plat_data;
+
+struct p7i2cmux_pins {
+ struct pinctrl_map* pinmap;
+ size_t sz;
+};
+
+#endif /* #if defined(CONFIG_I2C_MUX_PARROT7) || \
+ defined(CONFIG_I2C_MUX_PARROT7_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/i2cs.c b/arch/arm/mach-parrot7/i2cs.c
new file mode 100644
index 0000000..f449021
--- /dev/null
+++ b/arch/arm/mach-parrot7/i2cs.c
@@ -0,0 +1,122 @@
+/**
+ * linux/arch/arm/mach-parrot7/i2cs.c - Parrot7 i2c slave controller platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 13-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/clkdev.h>
+#include <i2c/plds_i2cs.h>
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include "common.h"
+#include "clock.h"
+
+/* Slave 0 resources */
+static struct resource plds_i2cs0_res[] = {
+ [0] = {
+ .start = P7_I2CS0,
+ .end = P7_I2CS0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CS0_IRQ,
+ .end = P7_I2CS0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Slave 1 resources */
+static struct resource plds_i2cs1_res[] = {
+ [0] = {
+ .start = P7_I2CS1,
+ .end = P7_I2CS1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CS1_IRQ,
+ .end = P7_I2CS1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Slave 2 resources */
+static struct resource plds_i2cs2_res[] = {
+ [0] = {
+ .start = P7_I2CS2,
+ .end = P7_I2CS2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_I2CS2_IRQ,
+ .end = P7_I2CS2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource *plds_i2cs_res[] = {
+ plds_i2cs0_res,
+ plds_i2cs1_res,
+ plds_i2cs2_res,
+};
+
+static struct platform_device plds_i2cs_dev = {
+ .name = PLDS_I2CS_NAME,
+ .id = 0,
+ .resource = plds_i2cs0_res,
+ .num_resources = ARRAY_SIZE(plds_i2cs0_res)
+};
+
+/**
+ * p7_init_i2cs() - Instantiate I2C slave controller identified by @slave
+ * for further driver usage.
+ *
+ * @slave: slave controller identifier
+ * @pdata: controller platform specific data
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_i2cs( struct plds_i2cs_pdata *pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(! pdata);
+ BUG_ON(pdata->i2c_bus > 2);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+
+ switch(p7_chiprev()) {
+ case P7_CHIPREV_R1:
+ pdata->revision = I2CS_REVISION_1;
+ break;
+ case P7_CHIPREV_R2:
+ pdata->revision = I2CS_REVISION_2;
+ break;
+ case P7_CHIPREV_R3:
+ pdata->revision = I2CS_REVISION_3;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ plds_i2cs_dev.id = pdata->i2c_bus;
+ plds_i2cs_dev.resource = plds_i2cs_res[pdata->i2c_bus];
+ plds_i2cs_dev.num_resources = 2;
+
+ err = p7_init_dev(&plds_i2cs_dev, pdata, pins, pin_cnt);
+ if (err)
+ panic("p7: failed to init I2C slave controller %d (%d)\n",
+ pdata->i2c_bus, err);
+}
diff --git a/arch/arm/mach-parrot7/i2cs.h b/arch/arm/mach-parrot7/i2cs.h
new file mode 100644
index 0000000..ac2a526
--- /dev/null
+++ b/arch/arm/mach-parrot7/i2cs.h
@@ -0,0 +1,36 @@
+/**
+ * linux/arch/arm/mach-parrot7/i2cs.h - Parrot7 i2c slave controller platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 13-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_I2CS_H
+#define _ARCH_PARROT7_I2CS_H
+
+struct plds_i2cs_pdata;
+struct pinctrl_map;
+
+#if defined(CONFIG_PLDS_I2CS) || \
+ defined(CONFIG_PLDS_I2CS_MODULE)
+
+#include <linux/init.h>
+
+extern void p7_init_i2cs(struct plds_i2cs_pdata*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+#else /* defined(CONFIG_PLDS_I2CS) || \
+ defined(CONFIG_PLDS_I2CS_MODULE) */
+
+#define p7_init_i2cs(_pdata, _pins, _pins_nr)
+
+#endif /* defined(CONFIG_PLDS_I2CS) || \
+ defined(CONFIG_PLDS_I2CS_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/clkdev.h b/arch/arm/mach-parrot7/include/mach/clkdev.h
new file mode 100644
index 0000000..abe1e8b
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/clkdev.h
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/clkdev.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_CLKDEV_H
+#define _ARCH_PARROT7_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/debug-macro.S b/arch/arm/mach-parrot7/include/mach/debug-macro.S
new file mode 100644
index 0000000..c754e36
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/debug-macro.S
@@ -0,0 +1,162 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @author Lionel Flandrin <lionel.flandrin@parrot.com>
+ * @date 15-Nov-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <mach/p7.h>
+#include <mach/regs-uart.h>
+#include <asm/memory.h>
+
+#if defined(CONFIG_PARROT7_DEBUG_LL_ZPRINT)
+ .macro addruart,rp,rv,tmp
+ ldr \rp, =P7_ZPRINT @ physical
+ ldr \rv, =__MMIO_P2V(P7_ZPRINT) @ virtual
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0]
+ dsb
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+ .endm
+
+#else /* ZPRINT */
+
+ .macro addruart,rp,rv,tmp
+ /* The virtual and physical addresses are stored contiguously in
+ p7_early_uart declared in march-parrot7/devices.c */
+ ldr \tmp, =p7_early_uart
+
+ /* There's a trick here, we can't access =p7_early_uart directly because
+ it might not be valid if we're not yet remapped into virtual
+ addresses. To make sure this code works in both real and virtual modes I
+ use a trick from mach-omap2 where we use the relative offset between the
+ current PC and a known location (1999f in the code below) to get a
+ correct address each time. */
+ adr \rp, 1999f @ current address of word at label 1999
+ ldr \rv, [\rp] @ absolute (virtual) address of word at label 1999
+ sub \rv, \rv, \rp @ offset between the two. That should be 0 in
+ @ virtual mode
+ sub \tmp, \tmp, \rv @ "patch" the address of p7_early_uart with the
+ @ computed offset
+
+ /* At this point \tmp contains the proper current address of p7_early_uart */
+
+ ldr \rp, [\tmp] @ p7_early_uart[0] (physical addr)
+ ldr \rv, [\tmp, #4] @ p7_early_uart[1] (virtual addr)
+
+ /* If it's non-0 we can use these values directly */
+ cmp \rp, #0
+ cmpne \rv, #0
+ bne 1002f
+
+ /* Otherwise we have to initialize the value of p7_early_uart with the
+ address of the UART specified in the P7 BOOT_MODE */
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ is MMU active?
+
+ /* If the MMU is active we can't be sure the SYS block has been properly
+ remapped yet, so we bail out rather than risking a DATA_ABORT */
+ bne 1002f
+
+ ldr \rv, =P7_BOOT_MODE
+ ldr \rp, [\rv] @ Read the BOOT_MODE register value
+ and \rp, \rp, #P7_BOOT_MODE_DIAG_MASK
+
+ cmp \rp, #P7_BOOT_MODE_DIAG_UART0
+ ldreq \rp, =P7_UART0
+ ldreq \rv, =__MMIO_P2V(P7_UART0)
+ beq 1001f
+
+ cmp \rp, #P7_BOOT_MODE_DIAG_UART1
+ ldreq \rp, =P7_UART1
+ ldreq \rv, =__MMIO_P2V(P7_UART1)
+ beq 1001f
+
+ cmp \rp, #P7_BOOT_MODE_DIAG_UART2
+ ldreq \rp, =P7_UART2
+ ldreq \rv, =__MMIO_P2V(P7_UART2)
+ beq 1001f
+
+ cmp \rp, #P7_BOOT_MODE_DIAG_UART3
+ ldreq \rp, =P7_UART3
+ ldreq \rv, =__MMIO_P2V(P7_UART3)
+ beq 1001f
+
+ /* Fallthrough: the BOOT_MODE has an unknown or unsupported value */
+ mov \rp, #0
+ mov \rv, #0
+1001:
+ /* Now we want to store the \rp and \rv values back in p7_early_uart so
+ that they are found the next time this function is called. */
+ str \rp, [\tmp] @ p7_early_uart[0] (physical addr)
+ str \rv, [\tmp, #4] @ p7_early_uart[1] (virtual addr)
+
+ b 1002f
+
+1999:
+ /* This is just for calculating the offset of p7_early_uart above */
+ .word .
+ .ltorg
+1002:
+ /* At this point \rp and \rv contain either correct physical and virtual
+ addresses or 0 if there was a problem and the early printk is unusable. */
+ .endm
+
+
+ .macro senduart,rd,rx
+ /* NOP when rx is 0 (see addruart) */
+ cmp \rx, #0
+ beq 1003f
+ strb \rd, [\rx, #_UART_TRX]
+1003:
+ .endm
+
+
+ .macro waituart,rd,rx
+ /* NOP when rx is 0 (see addruart) */
+ cmp \rx, #0
+ beq 1005f
+1004:
+ ldr \rd, [\rx, #_UART_STATUS]
+ tst \rd, #UART_STATUS_TXFILLED
+ bne 1004b
+1005:
+ .endm
+
+
+ .macro busyuart,rd,rx
+ /* NOP when rx is 0 (see addruart) */
+ cmp \rx, #0
+ beq 1007f
+1006:
+ ldr \rd, [\rx, #_UART_STATUS]
+ tst \rd, #UART_STATUS_TXEMPTY
+ beq 1006b
+1007:
+ .endm
+
+#endif /* ZPRINT */
diff --git a/arch/arm/mach-parrot7/include/mach/entry-macro.S b/arch/arm/mach-parrot7/include/mach/entry-macro.S
new file mode 100644
index 0000000..1dd4be0
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/entry-macro.S
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <asm/ptrace.h>
+#include <asm/hardware/gic.h>
+#include <mach/p7.h>
+#include <mach/io.h>
+#include <mach/irqs.h>
+
+/* Uncomment this if running on old P7 releases where FIQs are always on... */
+#if 0
+#define P7_FIQ_WORKAROUND
+#endif
+
+ .macro disable_fiq
+#ifdef P7_FIQ_WORKAROUND
+ mrs r8, spsr
+ orr r8, r8, #PSR_F_BIT
+ msr spsr, r8
+#endif
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =__MMIO_P2V(P7_CPU_ICC)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #P7_LOCALTIMER_IRQ
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #P7_LOCALTIMER_IRQ
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+
+/* vim:set ts=4:sw=4:noet:ft=asm: */
diff --git a/arch/arm/mach-parrot7/include/mach/ether.h b/arch/arm/mach-parrot7/include/mach/ether.h
new file mode 100644
index 0000000..aef4a72
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/ether.h
@@ -0,0 +1,37 @@
+/**
+ * linux/arch/arm/mach-parrot7/ether.c - Parrot7 Ethernet platform interface
+ *
+ * Copyright (C) 2013 Parrot S.A.
+ *
+ * author: Jimmy Perchet <jimmy.perchet@parrot.com>
+ * date: 27-08-2013
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_ETH_H
+#define _ARCH_PARROT7_ETH_H
+
+#if defined(CONFIG_STMMAC_ETH) || \
+ defined(CONFIG_STMMAC_ETH_MODULE)
+
+#include <linux/init.h>
+
+enum phy_iface {
+ PHY_IFACE_MII,
+ PHY_IFACE_RGMII,
+ PHY_IFACE_MIILITE,
+ PHY_IFACE_SSMII,
+};
+
+void __init p7_init_ether(enum phy_iface iface,
+ int phy_reset_gpio,
+ unsigned long drive_strength);
+
+#else /*def CONFIG_STMMAC_ETH*/
+
+#define p7_init_ether(_iface,_phy_reset_gpio,_drive_strength) do {} while (0)
+
+#endif /*def CONFIG_STMMAC_ETH*/
+
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/gpio.h b/arch/arm/mach-parrot7/include/mach/gpio.h
new file mode 100644
index 0000000..d8da9a7
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/gpio.h
@@ -0,0 +1,146 @@
+/**
+ * linux/arch/arm/mach-parrot7/include/mach/gpio.h - Parrot7 gpiolib platform
+ * specific interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Lionel Flandrin <lionel.flandrin@parrot.com>
+ * date: 06-Apr-2012
+ *
+ * This file is released under the GPL
+ *
+ * The whole purpose of this file is to provide gpiolib and Parrot7's common
+ * platform code with GPIO space definitions, i.e., number of GPIO lines to
+ * manage, and, for each GPIO controller present in the system, their respective
+ * first GPIO within the global space (so-called "gpio base").
+ * We want to achieve this in a flexible enough manner to prevent from changing
+ * platform and / or driver code each time a new GPIO controller (or expander)
+ * is added.
+ */
+
+#ifndef _ARCH_PARROT7_GPIO_H_
+#define _ARCH_PARROT7_GPIO_H_
+
+/*
+ * Holds current number of GPIOs declared for the global space.
+ * Don't use this outside of this file, this is for internal purpose only !
+ */
+#define __P7_FIRST_GPIO__ 0
+
+/*
+ * Define gpio base for each controller.
+ * Use enum definition to force preprocessor expansion each time
+ * __P7_FIRST_GPIO__ is re-defined.
+ */
+enum {
+/**********************************
+ * Declare Parrot7 chip GPIO lines
+ **********************************/
+#if defined(CONFIG_GPIO_PARROT7) || defined(CONFIG_GPIO_PARROT7_MODULE)
+ P7_FIRST_GPIO = __P7_FIRST_GPIO__,
+#define P7_GPIOS_MAX 220
+#undef __P7_FIRST_GPIO__
+#define __P7_FIRST_GPIO__ P7_GPIOS_MAX
+
+#define P7_GPIO_NR(_n) (P7_FIRST_GPIO + (_n))
+
+#endif
+
+/******************************************************************
+ * Declare Parrot7 Power Management Unit companion chip GPIO lines
+ ******************************************************************/
+#if defined(CONFIG_GPIO_P7MU) || defined(CONFIG_GPIO_P7MU_MODULE)
+ P7MU_FIRST_GPIO = __P7_FIRST_GPIO__,
+#define P7MU_GPIOS_MAX 5
+#undef __P7_FIRST_GPIO__
+#define __P7_FIRST_GPIO__ (P7MU_FIRST_GPIO + P7MU_GPIOS_MAX)
+
+/* P7MU IOs are starting with IO1, so we substract 1 to be 0 indexed */
+#define P7MU_IO_NR(_n) (P7MU_FIRST_GPIO + (_n) - 1)
+
+#endif
+
+/***********************************************
+ * Declare first FC7100 I/O expander GPIO lines
+ ***********************************************/
+#if (defined(CONFIG_GPIO_PCA953X) || \
+ defined(CONFIG_GPIO_PCA953X_MODULE)) && \
+ defined(CONFIG_MACH_PARROT_FC7100_FAMILY)
+ FC7100_IOEXPAND0_FIRST_GPIO = __P7_FIRST_GPIO__,
+#define FC7100_IOEXPAND0_GPIOS_MAX 16
+#undef __P7_FIRST_GPIO__
+#define __P7_FIRST_GPIO__ \
+ (FC7100_IOEXPAND0_FIRST_GPIO + FC7100_IOEXPAND0_GPIOS_MAX)
+
+#define FC7100_IOEXPAND0_GPIO_NR(_n) (FC7100_IOEXPAND0_FIRST_GPIO + (_n))
+#endif
+
+/************************************************
+ * Declare second FC7100 I/O expander GPIO lines
+ ************************************************/
+#if (defined(CONFIG_GPIO_PCA953X) || \
+ defined(CONFIG_GPIO_PCA953X_MODULE)) && \
+ defined(CONFIG_MACH_PARROT_FC7100_FAMILY)
+ FC7100_IOEXPAND1_FIRST_GPIO = __P7_FIRST_GPIO__,
+#define FC7100_IOEXPAND1_GPIOS_MAX 16
+#undef __P7_FIRST_GPIO__
+#define __P7_FIRST_GPIO__ \
+ (FC7100_IOEXPAND1_FIRST_GPIO + FC7100_IOEXPAND1_GPIOS_MAX)
+
+#define FC7100_IOEXPAND1_GPIO_NR(_n) (FC7100_IOEXPAND1_FIRST_GPIO + (_n))
+#endif
+
+/****************************************************
+ * Declare 24 bits FC7100DEV I/O expander GPIO lines
+ ****************************************************/
+#define FC7100DEV_IOEXPAND_GPIO_NR FC7100_IOEXPAND0_GPIO_NR
+};
+
+/* At last, set the total number of available GPIO lines in the global space.
+ We add some headroom for potential "hotplug" GPIO chips (used on Sicilia to
+ add the external GPIOs of the irradiance module on the Hook).
+ */
+#define ARCH_NR_GPIOS (__P7_FIRST_GPIO__ + 50)
+
+#include <asm-generic/gpio.h>
+
+/*
+ * We use the gpiolib framework. Those functions will call the corresponding
+ * callbacks defined in the GPIO driver's struct gpio_chip. (see for instance
+ * drivers/parrot/gpio/p7gpio.c).
+ *
+ * If it turns out that the gpiolib framework is too slow for a given product,
+ * we could inline the code accessing the GPIO here and save a couple cycles
+ * (for instance for heavy bitbangig).
+ */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* When use filtering and/or phase measure, use the following struct
+ * @start and @stop are gpios
+ * @filter if the counter ratio is set. This ratio devides irqs.
+ *
+ */
+
+#define GPIO_NO_MEASURE (-1)
+#define GPIO_MEASURE_START 0
+#define GPIO_MEASURE_STOP 1
+#define GPIO_MEASURE_START_AFTER_STOP 2
+#define GPIO_MEASURE_STOP_AFTER_START 3
+
+struct p7gpio_filter_phase{
+ u32 start;
+ u32 stop;
+ u8 filter;
+ s8 mode;
+ u8 export_reset;
+};
+
+/* custom fonction for mapping a gpio to an irq :
+ should be called after the p7 gpio is registered, but before gpio_to_irq
+ */
+int p7_gpio_interrupt_register(unsigned gpio);
+int p7_gpio_filter_interrupt_register(struct p7gpio_filter_phase);
+#endif /* _ARCH_PARROT7_GPIO_H_ */
diff --git a/arch/arm/mach-parrot7/include/mach/gpu-p7.h b/arch/arm/mach-parrot7/include/mach/gpu-p7.h
new file mode 100644
index 0000000..47f6f91
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/gpu-p7.h
@@ -0,0 +1,28 @@
+/**
+ * linux/arch/arm/mach-parrot7/include/mach/gpu-p7.h - Parrot7 MALI200 GPU
+ * platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Alvaro Moran <alvaro.moran@parrot.com>
+ * date: 20-10-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef __ARCH_PARROT7_GPU_H__
+#define __ARCH_PARROT7_GPU_H__
+
+#if defined(CONFIG_MALI200) || \
+ defined(CONFIG_MALI200_MODULE)
+
+#include "mali_osk_specific.h"
+#include "mali_osk.h"
+
+extern _mali_osk_resource_t p7mali200_arch_configuration [];
+#define arch_configuration p7mali200_arch_configuration
+
+#endif /* defined(CONFIG_MALI200) || \
+ defined(CONFIG_MALI200_MODULE) */
+
+#endif /* __ARCH_PARROT7_GPU_H__ */
diff --git a/arch/arm/mach-parrot7/include/mach/hardware.h b/arch/arm/mach-parrot7/include/mach/hardware.h
new file mode 100644
index 0000000..9e3571b
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/hardware.h
@@ -0,0 +1 @@
+/* Useless. */
diff --git a/arch/arm/mach-parrot7/include/mach/irqs.h b/arch/arm/mach-parrot7/include/mach/irqs.h
new file mode 100644
index 0000000..551b6de
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/irqs.h
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/irqs.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_IRQS_H
+#define _ARCH_PARROT7_IRQS_H
+
+/* Private Peripherals Interrupts. */
+#define P7_LOCALTIMER_IRQ 29
+#define P7_LOCALWDOG_IRQ 30
+
+
+/* Shared Peripherals Interrupts. */
+#define P7_SPIRQ(_irq) (32 + (_irq))
+
+/* GPU IRQ for MALI200: only on P7 R1 & R2 */
+#define P7_GPU_IRQ0 P7_SPIRQ(0)
+#define P7_GPU_IRQ1 P7_SPIRQ(1)
+#define P7_GPU_IRQ2 P7_SPIRQ(2)
+/* GPU IRQ for MALI400: only on P7 R3 */
+#define P7_GPU_PP0_IRQ P7_SPIRQ(85)
+#define P7_GPU_PPMMU0_IRQ P7_SPIRQ(86)
+#define P7_GPU_PP1_IRQ P7_SPIRQ(87)
+#define P7_GPU_PPMMU1_IRQ P7_SPIRQ(88)
+#define P7_GPU_PP2_IRQ P7_SPIRQ(89)
+#define P7_GPU_PPMMU2_IRQ P7_SPIRQ(90)
+#define P7_GPU_PP3_IRQ P7_SPIRQ(91)
+#define P7_GPU_PPMMU3_IRQ P7_SPIRQ(92)
+#define P7_GPU_GP_IRQ P7_SPIRQ(93)
+#define P7_GPU_GPMMU_IRQ P7_SPIRQ(94)
+
+#define P7_NAND_IRQ P7_SPIRQ(3)
+#define P7_SDIO0_IRQ P7_SPIRQ(11)
+#define P7_SDIO1_IRQ P7_SPIRQ(12)
+#define P7_SDIO2_IRQ P7_SPIRQ(13)
+
+/* SPI IRQ: 4 to 7 */
+#define P7_SPI0_IRQ P7_SPIRQ(4)
+#define P7_SPI1_IRQ P7_SPIRQ(5)
+#define P7_SPI2_IRQ P7_SPIRQ(6)
+#define P7_SPI3_IRQ P7_SPIRQ(7)
+
+/* USB IRQ: 8 to 10 */
+#define P7_USB0_IRQ P7_SPIRQ(8)
+#define P7_USB1_IRQ P7_SPIRQ(9)
+
+/* DMAC IRQs on P7 R1: 15 to 21 */
+#define P7_R1_DMA_ABORT_IRQ P7_SPIRQ(15)
+#define P7_R1_DMA0_IRQ P7_SPIRQ(16)
+#define P7_R1_DMA1_IRQ P7_SPIRQ(17)
+#define P7_R1_DMA2_IRQ P7_SPIRQ(18)
+#define P7_R1_DMA3_IRQ P7_SPIRQ(19)
+#define P7_R1_DMA4_IRQ P7_SPIRQ(20)
+#define P7_R1_DMA5_IRQ P7_SPIRQ(21)
+
+/*Ethernet IRQs: 15 to 17 */
+#define P7_ETH0_IRQ P7_SPIRQ(15)
+#define P7_ETH1_IRQ P7_SPIRQ(16)
+#define P7_ETH2_IRQ P7_SPIRQ(17)
+
+/*MPEG_TS IRQs*/
+#define P7_MPEGTS0_IRQ P7_SPIRQ(18)
+#define P7_MPEGTS1_IRQ P7_SPIRQ(19)
+
+/* CRYPTO */
+#define P7_CRYPTO_IRQ P7_SPIRQ(20)
+
+/* DMAC IRQs on P7 R2/3 */
+#define P7_DMA_IRQ P7_SPIRQ(21)
+
+/* AVI IRQs: 22 to 56 */
+#define P7_CFG_IRQ P7_SPIRQ(22)
+#define P7_INTER_IRQ P7_SPIRQ(23)
+#define P7_FIFO00_IRQ P7_SPIRQ(24)
+#define P7_FIFO01_IRQ P7_SPIRQ(25)
+#define P7_FIFO02_IRQ P7_SPIRQ(26)
+#define P7_FIFO03_IRQ P7_SPIRQ(27)
+#define P7_FIFO04_IRQ P7_SPIRQ(28)
+#define P7_FIFO05_IRQ P7_SPIRQ(29)
+#define P7_FIFO06_IRQ P7_SPIRQ(30)
+#define P7_FIFO07_IRQ P7_SPIRQ(31)
+#define P7_FIFO08_IRQ P7_SPIRQ(32)
+#define P7_FIFO09_IRQ P7_SPIRQ(33)
+#define P7_FIFO10_IRQ P7_SPIRQ(34)
+#define P7_FIFO11_IRQ P7_SPIRQ(35)
+#define P7_CONV0_IRQ P7_SPIRQ(36)
+#define P7_CONV1_IRQ P7_SPIRQ(37)
+#define P7_CONV2_IRQ P7_SPIRQ(38)
+#define P7_CONV3_IRQ P7_SPIRQ(39)
+#define P7_BLEND0_IRQ P7_SPIRQ(40)
+#define P7_BLEND1_IRQ P7_SPIRQ(41)
+#define P7_LCD0_IRQ P7_SPIRQ(42)
+#define P7_LCD1_IRQ P7_SPIRQ(43)
+#define P7_CAM0_IRQ P7_SPIRQ(44)
+#define P7_CAM1_IRQ P7_SPIRQ(45)
+#define P7_CAM2_IRQ P7_SPIRQ(46)
+#define P7_CAM3_IRQ P7_SPIRQ(47)
+#define P7_CAM4_IRQ P7_SPIRQ(48)
+#define P7_CAM5_IRQ P7_SPIRQ(49)
+#define P7_SCALROT0_IRQ P7_SPIRQ(50)
+#define P7_SCALROT1_IRQ P7_SPIRQ(51)
+#define P7_GAM0_IRQ P7_SPIRQ(52)
+#define P7_GAM1_IRQ P7_SPIRQ(53)
+
+#define P7_VDEC_IRQ P7_SPIRQ(57)
+#define P7_VENC_IRQ P7_SPIRQ(58)
+
+#define P7_UART0_IRQ P7_SPIRQ(59)
+#define P7_UART1_IRQ P7_SPIRQ(60)
+#define P7_UART2_IRQ P7_SPIRQ(61)
+#define P7_UART3_IRQ P7_SPIRQ(62)
+#define P7_UART4_IRQ P7_SPIRQ(63)
+#define P7_UART5_IRQ P7_SPIRQ(64)
+#define P7_UART6_IRQ P7_SPIRQ(65)
+#define P7_UART7_IRQ P7_SPIRQ(66)
+#define P7_I2CM0_IRQ P7_SPIRQ(67)
+#define P7_I2CM1_IRQ P7_SPIRQ(68)
+#define P7_I2CM2_IRQ P7_SPIRQ(69)
+#define P7_I2CMS_IRQ P7_SPIRQ(95)
+#define P7_I2CS0_IRQ P7_SPIRQ(70)
+#define P7_I2CS1_IRQ P7_SPIRQ(71)
+#define P7_I2CS2_IRQ P7_SPIRQ(72)
+#define P7_GPIO_IRQ P7_SPIRQ(73)
+
+#define P7_AXIMON_IRQ P7_SPIRQ(74)
+
+#define P7_TIM0_IRQ P7_SPIRQ(75)
+#define P7_TIM1_IRQ P7_SPIRQ(76)
+#define P7_TIM2_IRQ P7_SPIRQ(77)
+#define P7_TIM3_IRQ P7_SPIRQ(78)
+
+#define P7_AAI_IRQ P7_SPIRQ(79)
+
+#define P7_CCAN0_IRQ P7_SPIRQ(83)
+#define P7_CCAN1_IRQ P7_SPIRQ(84)
+
+
+#define P7_PMU_IRQ0 P7_SPIRQ(115)
+#define P7_PMU_IRQ1 P7_SPIRQ(116)
+
+#define P7_IRQS (160)
+
+/* Parrot GPIO controller may handle up to 20 GPIO lines as interrupts. */
+#if defined(CONFIG_GPIO_PARROT7) || defined(CONFIG_GPIO_PARROT7_MODULE)
+#define P7_GPIO_IRQS (20)
+#else
+#define P7_GPIO_IRQS (0)
+#endif
+
+#define P7MU_GPIO_IRQS (22)
+
+#if defined(CONFIG_MACH_PARROT_FC7100)
+/* IRQs for the two IO expanders */
+#define P7_EXTERNAL_IRQS (2 * 16)
+#else
+#define P7_EXTERNAL_IRQS (0)
+#endif
+
+#define NR_IRQS (P7_IRQS + P7_GPIO_IRQS + P7MU_GPIO_IRQS + P7_EXTERNAL_IRQS)
+
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/memory.h b/arch/arm/mach-parrot7/include/mach/memory.h
new file mode 100644
index 0000000..5906fe6
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/memory.h
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/memory.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_MEMORY_H
+#define _ARCH_PARROT7_MEMORY_H
+
+/* RAM physical address. */
+#define PLAT_PHYS_OFFSET UL(0x80000000)
+
+/* Required for ION */
+#define ARCH_HAS_SG_CHAIN
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/p7-adc.h b/arch/arm/mach-parrot7/include/mach/p7-adc.h
new file mode 100644
index 0000000..69988b9
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/p7-adc.h
@@ -0,0 +1,56 @@
+/**
+********************************************************************************
+* @file p7-adc.h
+* @brief P7 Analogic to Digital Converter driver
+*
+* Copyright (C) 2013 Parrot S.A.
+*
+* @author Karl Leplat <karl.leplat@parrot.com>
+* @date 2013-09-19
+********************************************************************************
+*/
+#ifndef ADC_P7_ADC_H_
+#define ADC_P7_ADC_H_
+
+#include <linux/kernel.h>
+
+/* Max sampling frequency based on clk_adc 8Mhz - do not change */
+#define P7MUADC_MARKER_FREQ 1200000
+
+typedef enum {
+ P7MUADC_IIO_TEMP = 0,
+ P7MUADC_IIO_RING_BUFFER,
+ P7MUADC_IIO_MARKER,
+ P7_ADC_IIO_MAX_CHIP_INFO,
+} p7_adc_type;
+
+struct p7_adc_chan {
+ int type;
+ int channel;
+ u32 freq;
+ u32 samples;
+};
+
+struct p7_adc_chan_data {
+ struct p7_adc_chan *channels;
+ size_t num_channels;
+};
+
+struct p7_temp_chan {
+ int channel;
+ u32 freq;
+ const char *name;
+};
+
+enum {
+ P7_TEMP_FC7100_HW08,
+ P7_TEMP_FC7100_HW04,
+ P7_TEMP_SICILIA,
+};
+struct p7_temp_chan_data {
+ struct p7_temp_chan *channels;
+ size_t num_channels;
+ int temp_mode;
+};
+
+#endif /* ADC_P7_ADC_H_ */
diff --git a/arch/arm/mach-parrot7/include/mach/p7.h b/arch/arm/mach-parrot7/include/mach/p7.h
new file mode 100644
index 0000000..73d4300
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/p7.h
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/p7.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_P7_H
+#define _ARCH_PARROT7_P7_H
+
+#include <asm/memory.h>
+#ifndef __ASSEMBLY__
+#include <asm/io.h>
+#endif
+
+
+/*
+ * I/O devices static mappings: inside vmalloc region,
+ * 48MB below VMALLOC_END.
+ */
+#define __MMIO_P2V(_phys) (0xff000000 - (3 * SZ_16M) + ((_phys) & 0x03ffffff))
+#define MMIO_P2V(_phys) __typesafe_io(__MMIO_P2V(_phys))
+
+/* Primary input clock frequency (Hertz). */
+#define P7_CLKIN_HZ UL(26000000)
+
+#define P7_INTRAM UL(0x00100000)
+#define P7_GPU UL(0x00200000)
+#define P7_AAI UL(0x00300000)
+#define P7_AVI UL(0x00400000)
+#define P7_VDEC UL(0x00500000)
+#define P7_VENC UL(0x00600000)
+#define P7_DMA UL(0x00700000)
+#define P7_CPU UL(0x00800000)
+#define P7_MPMC UL(0x00900000)
+#define P7_SYS UL(0x00a00000)
+#define P7_NIC UL(0x00e00000)
+
+/*
+ * Core Private Memory Region.
+ */
+#define P7_CPU_PMR UL(0x00f00000)
+/* Snoop Control Unit registers. */
+#define P7_CPU_SCU (P7_CPU_PMR)
+/* Local interrupts controller interface. */
+#define P7_CPU_ICC (P7_CPU_PMR + UL(0x0100))
+/* Core private / local timer. */
+#define P7_CPU_LOCALTIMER (P7_CPU_PMR + UL(0x0600))
+/* Interrupts distributor. */
+#define P7_CPU_ICD (P7_CPU_PMR + UL(0x1000))
+
+/*
+ * Level 2 cache controller (PL310).
+ */
+#define P7_L2C (P7_CPU_PMR + SZ_512K)
+
+/*
+ * MPMC
+ */
+/* gate training */
+#define P7_MPMC_TRAIN_EN (UL(0x4f75 << 2))
+
+/*
+ * High Speed Peripherals.
+ */
+#define P7_HSP UL(0x01000000)
+#define P7_NAND P7_HSP
+#define P7_SPI0 (P7_HSP + UL(0x100000))
+#define P7_SPI1 (P7_HSP + UL(0x101000))
+#define P7_SPI2 (P7_HSP + UL(0x102000))
+#define P7_SPI3 (P7_HSP + UL(0x103000))
+#define P7_MPEGTS0 (P7_HSP + UL(0x104000))
+#define P7_MPEGTS1 (P7_HSP + UL(0x10c000))
+#define P7_SPI (P7_HSP + UL(0x10f000))
+#define P7_SDIO0 (P7_HSP + UL(0x200000))
+#define P7_SDIO1 (P7_HSP + UL(0x300000))
+#define P7_SDIO2 (P7_HSP + UL(0x400000))
+#define P7_USB0 (P7_HSP + UL(0x500000))
+#define P7_USB1 (P7_HSP + UL(0x600000))
+#define P7_USB2 (P7_HSP + UL(0x700000))
+#define P7_ETHER (P7_HSP + UL(0x800000))
+#define P7_CRYPTO (P7_HSP + UL(0x900000))
+
+/*
+ * Low Speed Peripherals.
+ */
+#define P7_LSP UL(0x02000000)
+#define P7_PWM (P7_LSP + UL(0x000000))
+#define P7_UART0 (P7_LSP + UL(0x100000))
+#define P7_UART1 (P7_LSP + UL(0x110000))
+#define P7_UART2 (P7_LSP + UL(0x120000))
+#define P7_UART3 (P7_LSP + UL(0x130000))
+#define P7_UART4 (P7_LSP + UL(0x140000))
+#define P7_UART5 (P7_LSP + UL(0x150000))
+#define P7_UART6 (P7_LSP + UL(0x160000))
+#define P7_UART7 (P7_LSP + UL(0x170000))
+#define P7_I2CM0 (P7_LSP + UL(0x200000))
+#define P7_I2CM1 (P7_LSP + UL(0x210000))
+#define P7_I2CM2 (P7_LSP + UL(0x220000))
+#define P7_I2CMS (P7_LSP + UL(0x800000))
+#define P7_I2CS0 (P7_LSP + UL(0x300000))
+#define P7_I2CS1 (P7_LSP + UL(0x310000))
+#define P7_I2CS2 (P7_LSP + UL(0x320000))
+#define P7_GPIO (P7_LSP + UL(0x400000))
+#define P7_CCAN0 (P7_LSP + UL(0x500000))
+#define P7_CCAN1 (P7_LSP + UL(0x510000))
+
+/*
+ * AXI Monitor
+ */
+#define P7_AXIMON (P7_MPMC + UL(0x80000))
+#define P7_MPMC_GBC (P7_MPMC + UL(0xffc00))
+#define P7_MPMC_GBC_PRI (P7_MPMC_GBC + UL(0x1f4))
+
+
+/*
+ * P7 Boot mode register containing the diagnostic channel to use amongst other
+ * things
+ */
+#define P7_BOOT_MODE (P7_SYS + UL(0x408))
+
+#define P7_BOOT_MODE_DIAG_MASK (0x7 << 5)
+#define P7_BOOT_MODE_DIAG_NONE (0 << 5)
+#define P7_BOOT_MODE_DIAG_USB0 (1 << 5)
+#define P7_BOOT_MODE_DIAG_UART0 (2 << 5)
+#define P7_BOOT_MODE_DIAG_DCC (3 << 5)
+#define P7_BOOT_MODE_DIAG_UART2 (4 << 5)
+#define P7_BOOT_MODE_DIAG_UART1 (5 << 5)
+#define P7_BOOT_MODE_DIAG_UART3 (6 << 5)
+
+/*
+ * System Debug (only present when running emulated design)
+ */
+
+#ifdef CONFIG_MACH_PARROT_ZEBU
+
+#ifdef CONFIG_ARCH_PARROT7_ZEBU_MPW1
+#define P7_SYS_DBG (P7_SYS + UL(0x2000))
+/* MPW2 */
+//#define P7_SYS_DBG (P7_SYS + UL(0x3000))
+
+#define P7_ZPRINT P7_SYS_DBG
+#define P7_SYS_DBG_HALT (P7_SYS_DBG + UL(0x1008))
+#endif
+
+#ifdef CONFIG_ARCH_PARROT7_ZEBU_MPW2
+#define P7_SYS_DBG (P7_SYS + UL(0x3000))
+#define P7_ZPRINT (P7_SYS + UL(0x70000))
+#define P7_SYS_DBG_HALT (P7_SYS + UL(0x71008))
+#endif
+
+#endif /* CONFIG_MACH_PARROT_ZEBU */
+
+#endif
diff --git a/arch/arm/mach-parrot7/include/mach/pwm.h b/arch/arm/mach-parrot7/include/mach/pwm.h
new file mode 100644
index 0000000..1f0d84f
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/pwm.h
@@ -0,0 +1,64 @@
+/**
+ * linux/arch/arm/mach-parrot7/include/mach/pwm.h - Parrot7 pwm platform
+ * specific interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 22-Nov-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_PWM_H_
+#define _ARCH_PARROT7_PWM_H_
+
+/*
+ * Holds current number of PWMs declared for the global space.
+ * Don't use this outside of this file, this is for internal purpose only !
+ */
+#define __P7_FIRST_PWM__ 0
+
+#define P7_PWMS_MAX 16
+#define P7MU_PWMS_MAX 2
+
+/*
+ * Define pwm base for each controller.
+ * Use enum definition to force preprocessor expansion each time
+ * __P7_FIRST_PWM__ is re-defined.
+ */
+enum {
+/**********************************
+ * Declare Parrot7 chip PWM lines
+ **********************************/
+#if defined(CONFIG_PWM_PARROT7) || defined(CONFIG_PWM_PARROT7_MODULE)
+ P7_FIRST_PWM = __P7_FIRST_PWM__,
+#undef __P7_FIRST_PWM__
+#define __P7_FIRST_PWM__ P7_PWMS_MAX
+
+#define P7_PWM_NR(_n) (P7_FIRST_PWM + (_n))
+#else
+#define P7_PWM_NR(_n) (-1)
+#endif
+
+/******************************************************************
+ * Declare Parrot7 Power Management Unit companion chip PWM lines
+ ******************************************************************/
+
+#if defined(CONFIG_PWM_P7MU) || defined(CONFIG_PWM_P7MU_MODULE)
+ P7MU_FIRST_PWM = __P7_FIRST_PWM__,
+#undef __P7_FIRST_PWM__
+#define __P7_FIRST_PWM__ (P7MU_FIRST_PWM + P7MU_PWMS_MAX)
+
+#define P7MU_PWM_NR(_n) (P7MU_FIRST_PWM + (_n))
+
+#else
+#define P7MU_PWM_NR(_n) (-1)
+#endif
+ P7_FIRST_NR = __P7_FIRST_PWM__,
+};
+
+/* At last, set the total number of available PWM lines in the global space. */
+#define ARCH_NR_PWMS __P7_FIRST_PWM__
+
+#endif /* _ARCH_PARROT7_PWM_H_ */
diff --git a/arch/arm/mach-parrot7/include/mach/regs-uart.h b/arch/arm/mach-parrot7/include/mach/regs-uart.h
new file mode 100644
index 0000000..e6f08e3
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/regs-uart.h
@@ -0,0 +1,135 @@
+/**
+ * @file linux/include/asm-arm/arch-parrot/regs-uart.h
+ * @brief Device I/O - Description of Parrot5/5+/6 serial hardware
+ *
+ * Copyright (C) 2005,2006,2007 Parrot S.A.
+ *
+ * @author yves.lemoine@parrot.com
+ * @author ivan.djelic@parrot.com
+ * @date 2005-09-28
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __ARCH_ARM_PARROT5_UART_REGS_H
+#define __ARCH_ARM_PARROT5_UART_REGS_H
+
+#define PXUART_NR 8
+
+#define _UART_TRX 0x00 /* UART RX/TX Buffers */
+#define _UART_IRX 0x04 /* Rx IRQ Enable Register */
+#define _UART_ITX 0x08 /* Tx IRQ Enable Register */
+#define _UART_RSTBRK 0x0C /* Reset Break Register */
+#define _UART_SETBRK 0x10 /* Set Break Register */
+#define _UART_LCR 0x14 /* Line Command Register */
+#define _UART_SPD 0x18 /* Speed Register */
+#define _UART_STATUS 0x1C /* Status Register */
+
+/* Registers bitwise definitions */
+
+/* Receive register */
+#define UART_TRX_INVALID (1 << 8) /* Byte invalidity flag */
+#define UART_TRX_OVERRUN (1 << 9) /* Over-run bit */
+#define UART_TRX_PARITY_ERROR (1 << 10) /* Parity error bit */
+#define UART_TRX_FRAME_ERROR (1 << 11) /* Frame error bit */
+#define UART_TRX_RXBREAK (1 << 12) /* Break detection bit */
+#define UART_TRX_TXCOLLISION (1 << 13) /* TX flag collision */
+
+/* Error mask - ignore invalid and collision flags */
+#define UART_TRX_ANY_ERROR \
+ (UART_TRX_OVERRUN | \
+ UART_TRX_PARITY_ERROR| \
+ UART_TRX_FRAME_ERROR | \
+ UART_TRX_RXBREAK)
+
+/* Receive Interrupt Enable Register */
+#define UART_IRX_RIM 1 /* RX Interrupt mask bit */
+
+/* Transmit Interrupt Enable Register */
+#define UART_ITX_TIM 1 /* TX Interrupt mask bit */
+
+/* Line Command Register */
+
+#define UART_LCR_LONG_BREAK_2 (0 << 12)
+#define UART_LCR_LONG_BREAK_4 (1 << 12)
+#define UART_LCR_LONG_BREAK_8 (2 << 12)
+#define UART_LCR_LONG_BREAK_16 (3 << 12)
+#define UART_LCR_LONG_BREAK_32 (4 << 12)
+#define UART_LCR_LONG_BREAK_64 (5 << 12)
+#define UART_LCR_LONG_BREAK_128 (6 << 12)
+#define UART_LCR_LONG_BREAK_256 (7 << 12)
+#define UART_LCR_TSTZERO (1 << 11) /* Collision test on level 0*/
+#define UART_LCR_SINGLEWIRE (1 << 10) /* Single Wire mode. */
+#define UART_LCR_TXFIFO (1 << 9) /* TX FIFO utilization */
+#define UART_LCR_RXFIFO (1 << 8) /* RX FIFO utilization */
+#define UART_LCR_FIFO_THRESHOLD_1 (0 << 6) /* RX FIFO threshold */
+#define UART_LCR_FIFO_THRESHOLD_8 (1 << 6)
+#define UART_LCR_FIFO_THRESHOLD_16 (2 << 6)
+#define UART_LCR_FIFO_THRESHOLD_24 (3 << 6)
+#define UART_LCR_CTSMODE (1 << 5) /* CTS validation bit */
+#define UART_LCR_STICKY (1 << 4) /* Fixed Parity bit */
+#define UART_LCR_EVEN (1 << 3) /* Even Parity bit */
+#define UART_LCR_PARITY (1 << 2) /* Parity enable bit */
+#define UART_LCR_TWOSTOP (1 << 1) /* 2 stop bits enable bit */
+#define UART_LCR_EIGHTBITS 1 /* 8 bits mode enable bit */
+
+/* Parrot5+ LCR extensions */
+#define UART_LCR_RTS_CTRL (1 << 15) /* auto(0)/manual(1) nRTS */
+#define UART_LCR_FIFO_RX_THRESHOLD_1 (0 << 6) /* Receive FIFO threshold */
+#define UART_LCR_FIFO_RX_THRESHOLD_16 (1 << 6)
+#define UART_LCR_FIFO_RX_THRESHOLD_32 (2 << 6)
+#define UART_LCR_FIFO_RX_THRESHOLD_48 (3 << 6)
+#define UART_LCR_FIFO_TX_THRESHOLD_0 (0 << 16) /* Transmit FIFO threshold */
+#define UART_LCR_FIFO_TX_THRESHOLD_4 (1 << 16)
+#define UART_LCR_FIFO_TX_THRESHOLD_8 (2 << 16)
+#define UART_LCR_FIFO_TX_THRESHOLD_16 (3 << 16)
+
+/* Status Register */
+#define UART_STATUS_COLLISION (1 << 10) /* Collision flag bit */
+#define UART_STATUS_STOP_BREAK (1 << 9) /* Stop break flag bit */
+#define UART_STATUS_TX_BREAK (1 << 8) /* Transmit Break flag bit */
+#define UART_STATUS_TXFILLED (1 << 7) /* FIFO TX Filled flag bit */
+#define UART_STATUS_TXEMPTY (1 << 6) /* TX empty flag bit */
+#define UART_STATUS_ITTX (1 << 5) /* TX Interrupt flag bit */
+#define UART_STATUS_CTSN (1 << 4) /* CTSN input read-back value */
+#define UART_STATUS_LONG_BREAK (1 << 3) /* Long brk detection flag bit*/
+#define UART_STATUS_RTSN (1 << 2) /* RSTN output read-back value*/
+#define UART_STATUS_RXFILLED (1 << 1) /* FIFO RX Filled flag bit */
+#define UART_STATUS_ITRX 1 /* Receive Interrupt flag bit */
+
+#define BAUD_921600 (UART_CLOCK/921600)
+#define BAUD_460800 (UART_CLOCK/460800)
+#define BAUD_115200 (UART_CLOCK/115200)
+#define BAUD_38400 (UART_CLOCK/ 38400)
+#define BAUD_19200 (UART_CLOCK/ 19200)
+#define BAUD_9600 (UART_CLOCK/ 9600)
+
+/* define alternative values for CPUCLK = 156 MHz mode */
+#define BAUD_921600_156MHZ ((3*UART_CLOCK/4)/921600)
+#define BAUD_460800_156MHZ ((3*UART_CLOCK/4)/460800)
+#define BAUD_115200_156MHZ ((3*UART_CLOCK/4)/115200)
+#define BAUD_38400_156MHZ ((3*UART_CLOCK/4)/ 38400)
+#define BAUD_19200_156MHZ ((3*UART_CLOCK/4)/ 19200)
+#define BAUD_9600_156MHZ ((3*UART_CLOCK/4)/ 9600)
+
+/* FIFO sizes */
+#define UART_TX_FIFO_SIZE_P5 (16)
+#define UART_RX_FIFO_SIZE_P5 (32)
+
+/* Parrot5+ fifos are twice deeper */
+#define UART_TX_FIFO_SIZE_P5P (32)
+#define UART_RX_FIFO_SIZE_P5P (64)
+
+#endif /* __ARCH_ARM_PARROT5_UART_REGS_H */
diff --git a/arch/arm/mach-parrot7/include/mach/smp.h b/arch/arm/mach-parrot7/include/mach/smp.h
new file mode 100644
index 0000000..a0e9813
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/smp.h
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/smp.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_SMP_H
+#define _ARCH_PARROT7_SMP_H
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id() \
+ ({ \
+ unsigned int cpunum; \
+ __asm__("mrc p15, 0, %0, c0, c0, 5" \
+ : "=r" (cpunum)); \
+ cpunum &= 0x0f; \
+ })
+
+/*
+ * We use IRQ1 as the IPI (Inter-Processor Interrupts).
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+ gic_raise_softirq(mask, 1);
+}
+
+#endif
+
+/* vim:set ts=4:sw=4:noet:ft=c: */
diff --git a/arch/arm/mach-parrot7/include/mach/system.h b/arch/arm/mach-parrot7/include/mach/system.h
new file mode 100644
index 0000000..ece1644
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/system.h
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/system.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_SYSTEM_H
+#define _ARCH_PARROT7_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+#endif
+
+/* vim:set ts=4:sw=4:noet:ft=c: */
diff --git a/arch/arm/mach-parrot7/include/mach/timex.h b/arch/arm/mach-parrot7/include/mach/timex.h
new file mode 100644
index 0000000..0ec044b
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/timex.h
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/timex.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_TIMEX_H
+#define _ARCH_PARROT7_TIMEX_H
+
+/*
+ * CLOCK_TICK_RATE is actually a don't-care value. Make it default to
+ * (100 * HZ).
+ */
+#define CLOCK_TICK_RATE (100 * HZ)
+
+#define ARCH_HAS_READ_CURRENT_TIMER
+
+#endif
+
+/* vim:set ts=4:sw=4:noet:ft=c: */
diff --git a/arch/arm/mach-parrot7/include/mach/uncompress.h b/arch/arm/mach-parrot7/include/mach/uncompress.h
new file mode 100644
index 0000000..7ab19a4
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/uncompress.h
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-parrot7/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 28-Oct-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <mach/p7.h>
+#include <mach/regs-uart.h>
+
+#if defined(CONFIG_PARROT7_DEBUG_LL_UART0)
+#define UART_TX (*(volatile unsigned char *)(P7_UART0 + _UART_TRX))
+#define UART_STAT (*(volatile unsigned char *)(P7_UART0 + _UART_STATUS))
+#elif defined(CONFIG_PARROT7_DEBUG_LL_UART1)
+#define UART_TX (*(volatile unsigned char *)(P7_UART1 + _UART_TRX))
+#define UART_STAT (*(volatile unsigned char *)(P7_UART1 + _UART_STATUS))
+#elif defined(CONFIG_PARROT7_DEBUG_LL_UART2)
+#define UART_TX (*(volatile unsigned char *)(P7_UART2 + _UART_TRX))
+#define UART_STAT (*(volatile unsigned char *)(P7_UART2 + _UART_STATUS))
+#elif defined(CONFIG_PARROT7_DEBUG_LL_UART3)
+#define UART_TX (*(volatile unsigned char *)(P7_UART3 + _UART_TRX))
+#define UART_STAT (*(volatile unsigned char *)(P7_UART3 + _UART_STATUS))
+#endif
+
+
+#if defined(CONFIG_PARROT7_DEBUG_LL_UART0) \
+ || defined(CONFIG_PARROT7_DEBUG_LL_UART1) \
+ || defined(CONFIG_PARROT7_DEBUG_LL_UART2) \
+ || defined(CONFIG_PARROT7_DEBUG_LL_UART3)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ while (UART_STAT & UART_STATUS_TXFILLED)
+ barrier();
+
+ UART_TX = c;
+}
+
+static inline void flush(void)
+{
+ while ((UART_STAT & UART_STATUS_TXEMPTY) == 0)
+ barrier();
+}
+#else
+static inline void putc(int c)
+{
+}
+
+static inline void flush(void)
+{
+}
+
+#endif
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+/* vim:set ts=4:sw=4:noet:ft=c: */
diff --git a/arch/arm/mach-parrot7/include/mach/usb-p7.h b/arch/arm/mach-parrot7/include/mach/usb-p7.h
new file mode 100644
index 0000000..5b29a2a
--- /dev/null
+++ b/arch/arm/mach-parrot7/include/mach/usb-p7.h
@@ -0,0 +1,49 @@
+/**
+ * @file arch/arm/mach-parrot7/include/mach/usb-p7.h
+ * @brief Parrot7 usb controller definitions
+ *
+ * Copyright (C) 2009 Parrot S.A.
+ *
+ * @author olivier.bienvenu@parrot.com
+ * @date 2009-04-17
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __ARCH_ARM_PARROT_USB_P7_H
+#define __ARCH_ARM_PARROT_USB_P7_H
+
+#include <linux/pinctrl/consumer.h>
+#include <linux/usb/chipidea.h>
+
+#define USB_DRV_NAME "ci_hdrc"
+
+enum p7_usb2_phy_modes {
+ P7_USB2_PHY_NONE,
+ P7_USB2_PHY_ULPI,
+ P7_USB2_PHY_UTMI,
+ P7_USB2_PHY_UTMI_WIDE,
+ P7_USB2_PHY_SERIAL,
+};
+
+struct p7_usb2_platform_data {
+ struct ci13xxx_udc_driver ci_udc;
+ unsigned int phy_enable; // adress of the PHY enable register on the p7mu
+ unsigned int gpio_vbus;
+ struct pinctrl *pctl;
+ unsigned int chip_rev;
+};
+
+#endif /* __ARCH_ARM_PARROT_REGS_P7_H */
diff --git a/arch/arm/mach-parrot7/ion.c b/arch/arm/mach-parrot7/ion.c
new file mode 100644
index 0000000..dd08c78
--- /dev/null
+++ b/arch/arm/mach-parrot7/ion.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/mach-parrot7/ion.c - Parrot7 ION allocator platform
+ * implementation
+ *
+ * Copyright (C) 2014 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 14-Jan-2014
+ *
+ * This file is released under the GPL
+ *
+ * See linux/drivers/parrot/gpu/ion/p7-ion.c
+ */
+
+#include <linux/platform_device.h>
+#include <linux/ion.h>
+#include "ion.h"
+
+#define P7ION_DRV_NAME "p7-ion"
+#define P7_ION_HEAPS_MAX 16
+
+static struct ion_platform_heap p7_ion_pheaps[P7_ION_HEAPS_MAX] = {
+ { /* vmalloc based */
+ .type = ION_HEAP_TYPE_SYSTEM,
+ .id = ION_HEAP_TYPE_SYSTEM,
+ .name = "vmalloc"
+ },
+ { /* kmalloc based */
+ .type = ION_HEAP_TYPE_SYSTEM_CONTIG,
+ .id = ION_HEAP_TYPE_SYSTEM_CONTIG,
+ .name = "kmalloc"
+ },
+ { /* global DMA coherent / CMA based */
+ .type = ION_HEAP_TYPE_DMA,
+ .id = ION_HEAP_TYPE_DMA,
+ .name = "cma",
+ .priv = NULL
+ }
+};
+
+static struct ion_platform_data p7_ion_pdata = {
+ .nr = 3,
+ .heaps = p7_ion_pheaps
+};
+
+static struct platform_device p7_ion_dev = {
+ .name = P7ION_DRV_NAME,
+ .id = 0,
+ .num_resources = 0,
+ .dev.platform_data = &p7_ion_pdata
+};
+
+void __init p7_ionize_dev(struct platform_device* pdev, unsigned int id)
+{
+ struct ion_platform_heap* const heap = &p7_ion_pheaps[p7_ion_pdata.nr];
+
+#ifdef DEBUG
+ BUG_ON(pdev);
+ /* dma_declare_coherent_memory MUST have been called before !! */
+ BUG_ON(! pdev->dev.dma_mem);
+ BUG_ON(id < ION_HEAP_TYPE_CUSTOM);
+ {
+ unsigned int h;
+ for (h = 0; h < p7_ion_pdata.nr; h++)
+ BUG_ON(id == p7_ion_pheaps[h].id);
+ }
+#endif
+
+ heap->type = ION_HEAP_TYPE_DMA;
+ heap->id = id;
+ heap->name = dev_name(&pdev->dev);
+ heap->priv = &pdev->dev;
+
+ p7_ion_pdata.nr++;
+}
+
+void __init p7_init_ion(void)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(! p7_ion_pdata.nr);
+#endif
+
+ pr_debug("p7: registering " P7ION_DRV_NAME ".0...\n");
+
+ err = platform_device_register(&p7_ion_dev);
+ if (err)
+ panic("p7: failed to register " P7ION_DRV_NAME ".0 (%d)\n", err);
+}
diff --git a/arch/arm/mach-parrot7/ion.h b/arch/arm/mach-parrot7/ion.h
new file mode 100644
index 0000000..29aff52
--- /dev/null
+++ b/arch/arm/mach-parrot7/ion.h
@@ -0,0 +1,37 @@
+/**
+ * linux/arch/arm/mach-parrot7/ion.h - Parrot7 ION allocator platform
+ * interface
+ *
+ * Copyright (C) 2014 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 14-Jan-2014
+ *
+ * This file is released under the GPL
+ *
+ * See linux/drivers/parrot/gpu/ion/p7-ion.c
+ */
+
+#ifndef _ARCH_PARROT7_ION_H
+#define _ARCH_PARROT7_ION_H
+
+#if defined(CONFIG_ION) || \
+ defined(CONFIG_ION_MODULE)
+
+#include <linux/init.h>
+
+struct platform_device;
+
+extern void p7_init_ion(void) __init;
+extern void p7_ionize_dev(struct platform_device*, unsigned int) __init;
+
+#else /* defined(CONFIG_ION) || \
+ defined(CONFIG_ION_MODULE) */
+
+#define p7_init_ion()
+#define p7_ionize_dev(_pdev)
+
+#endif /* defined(CONFIG_ION) || \
+ defined(CONFIG_ION_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/iopin.c b/arch/arm/mach-parrot7/iopin.c
new file mode 100644
index 0000000..f87eadc
--- /dev/null
+++ b/arch/arm/mach-parrot7/iopin.c
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-parrot7/iopin.c
+ *
+ * Copyright (C) 2011 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 10-Feb-2011
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <mach/p7.h>
+#include "system.h"
+#include "iopin.h"
+
+/* Uncomment this if running on old P7 releases where the input enable bit is buggy... */
+#if 0
+#define P7_r1865_IOPIN_WORKAROUND
+#endif
+
+static void __init p7_setup_iopin(union p7_iopin const config)
+{
+ unsigned long const addr = __MMIO_P2V(P7_SYS_PADCTRL_IO) +
+ (config.fields.id * sizeof(u32));
+ union p7_iopin pin = { .word = readl(addr) };
+
+#ifndef P7_r1865_IOPIN_WORKAROUND
+ /* Disable pin at first. */
+ pin.fields.input_en = 0;
+ __raw_writel(pin.word, addr);
+
+ if (config.fields.set_usage)
+ pin.fields.usage = config.fields.usage;
+
+ if (config.fields.set_trigger)
+ pin.fields.trigger = config.fields.trigger;
+
+ if (config.fields.set_pull)
+ pin.fields.pull = config.fields.pull;
+
+ if (config.fields.set_slewrate)
+ pin.fields.slewrate = config.fields.slewrate;
+
+ if (config.fields.set_driver)
+ pin.fields.driver = config.fields.driver;
+
+ /* Write config. */
+ writel(pin.word, addr);
+ /* Re-enable pin. */
+ pin.fields.input_en = 1;
+ writel(pin.word, addr);
+#else /* P7_r1865_IOPIN_WORKAROUND */
+ if (config.fields.set_usage)
+ pin.fields.usage = config.fields.usage;
+
+ __raw_writel(pin.word, addr);
+#endif /* P7_r1865_IOPIN_WORKAROUND */
+}
+
+void __init p7_init_iopin_table(union p7_iopin const* iopins)
+{
+ union p7_iopin const* pin;
+
+ for (pin = iopins; pin->word; pin++)
+ p7_setup_iopin(*pin);
+}
+
+/* vim:set ts=4:sw=4:et:ft=c: */
diff --git a/arch/arm/mach-parrot7/iopin.h b/arch/arm/mach-parrot7/iopin.h
new file mode 100644
index 0000000..c58820c
--- /dev/null
+++ b/arch/arm/mach-parrot7/iopin.h
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/arm/mach-parrot7/iopin.h
+ *
+ * Copyright (C) 2011 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 10-Feb-2011
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_IOPIN_H
+#define _ARCH_PARROT7_IOPIN_H
+
+#include <linux/init.h>
+#include <asm/types.h>
+
+union p7_iopin {
+ u32 word;
+ struct {
+ unsigned usage:2;
+ unsigned unused0:1;
+ unsigned set_usage:1;
+ unsigned set_trigger:1;
+ unsigned set_pull:1;
+ unsigned set_slewrate:1;
+ unsigned set_driver:1;
+ unsigned trigger:1;
+ unsigned pull:3;
+ unsigned input_en:1;
+ unsigned unused1:3;
+ unsigned slewrate:2;
+ unsigned driver:6;
+ unsigned id:8;
+ } fields;
+};
+
+#define P7_IOPIN_USAGE (1 << 3)
+#define P7_IOPIN_TRIGGER (1 << 4)
+#define P7_IOPIN_PULL (1 << 5)
+#define P7_IOPIN_SLEWRATE (1 << 6)
+#define P7_IOPIN_DRIVER (1 << 7)
+
+#define P7_IOPIN_SMT_NONE 0 /* No trigger */
+#define P7_IOPIN_SMT_EN 1 /* Schmidt trigger enabled */
+
+#define P7_IOPIN_PULL_HIGHZ 0 /* High impendence */
+#define P7_IOPIN_PULL_UP 1 /* Pull up */
+#define P7_IOPIN_PULL_DOWN 2 /* Pull down */
+#define P7_IOPIN_PULL_KEEP 4 /* Bus keeper */
+
+#define P7_IOPIN_SLEWRATE_0 0 /* Slowest */
+#define P7_IOPIN_SLEWRATE_1 1
+#define P7_IOPIN_SLEWRATE_2 2
+#define P7_IOPIN_SLEWRATE_3 3 /* Fastest */
+
+#define P7_IOPIN_DRIVER_0 1 /* Weakest */
+#define P7_IOPIN_DRIVER_1 3
+#define P7_IOPIN_DRIVER_2 7
+#define P7_IOPIN_DRIVER_3 0xf
+#define P7_IOPIN_DRIVER_4 0x1f
+#define P7_IOPIN_DRIVER_5 0x3f/* Strongest */
+
+#define P7_INIT_FULL_IOPIN(_id, \
+ _set, \
+ _trigger, \
+ _pull, \
+ _slewrate, \
+ _driver) \
+ { .fields = { \
+ .usage = (_id) & 0xf, \
+ .set_usage = !! ((_set) & P7_IOPIN_USAGE), \
+ .set_trigger = !! ((_set) & P7_IOPIN_TRIGGER), \
+ .set_pull = !! ((_set) & P7_IOPIN_PULL), \
+ .set_slewrate = !! ((_set) & P7_IOPIN_SLEWRATE), \
+ .set_driver = !! ((_set) & P7_IOPIN_DRIVER), \
+ .trigger = _trigger, \
+ .pull = _pull, \
+ .slewrate = _slewrate, \
+ .driver = _driver, \
+ .id = ((_id) >> 4) \
+ } \
+ }
+
+#define P7_INIT_IOPIN(_id) \
+ P7_INIT_FULL_IOPIN(_id, P7_IOPIN_USAGE, 0, 0, 0, 0)
+
+extern void p7_init_iopin_table(union p7_iopin const*) __init;
+
+#endif
+
+/* vim:set ts=4:sw=4:et:ft=c: */
diff --git a/arch/arm/mach-parrot7/lcd-monspecs.c b/arch/arm/mach-parrot7/lcd-monspecs.c
new file mode 100644
index 0000000..6342935
--- /dev/null
+++ b/arch/arm/mach-parrot7/lcd-monspecs.c
@@ -0,0 +1,728 @@
+#include "lcd-monspecs.h"
+
+/* The 7" OEM screen */
+/* The screen used in the RNB5. 6.2" with capacitive touchscreen */
+struct avi_videomode fg0700k_video_mode = {
+ .name = "fg0700k4dsswbgt1",
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 33260,
+ .left_margin = 104,/* Hback */
+ .right_margin = 24, /* Hfront */
+ .upper_margin = 12, /* Vback */
+ .lower_margin = 3, /* Vfront */
+ .hsync_len = 80,
+ .vsync_len = 7,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+};
+
+/* The 10" screen */
+struct avi_videomode lt104ac_video_mode = {
+ .name = "lt104ac",
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = 65000,
+ .left_margin = 160,
+ .right_margin = 24,
+ .upper_margin = 29,
+ .lower_margin = 3,
+ .hsync_len = 136,
+ .vsync_len = 6,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+};
+
+struct avi_videomode lt104ac_no_den_video_mode = {
+ .name = "lt104ac_no_den",
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = 65000,
+ .left_margin = 296,
+ .right_margin = 24,
+ .upper_margin = 34,
+ .lower_margin = 3,
+ .hsync_len = 136,
+ .vsync_len = 6,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+};
+
+
+/* The Antec 9" Screen */
+struct avi_videomode chimei_antec_video_mode = {
+ .name = "chimei-antec",
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 33300,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .left_margin = 46, /* Hback */
+ .right_margin = 210, /* Hfront */
+ .upper_margin = 23, /* Vback */
+ .lower_margin = 22, /* Vfront */
+ .hsync_len = 80,
+ .vsync_len = 7,
+};
+
+/* The FC6100 workbench 7' Screen */
+struct avi_videomode tpo_laj07t001a_video_mode = {
+ .name = "tpo_laj07t001a",
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 33230,
+ .flags = 0,
+ .left_margin = 128, /* Hback */
+ .right_margin = 49, /* Hfront */
+ .upper_margin = 34, /* Vback */
+ .lower_margin = 10, /* Vfront */
+ .hsync_len = 19,
+ .vsync_len = 2,
+};
+
+/* OEM FC7100 kyocera screen */
+struct avi_videomode kyocera_video_mode = {
+ .name = "kyocera",
+ .xres = 1280,
+ .yres = 800,
+ .pixclock = 71100,
+ /* The rest of the timings will be calculated using the VESA
+ * generalized timing formula. */
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 100,
+ .left_margin = 30,
+ .right_margin = 30,
+ .vsync_len = 5,
+ .upper_margin = 16,
+ .lower_margin = 2,
+ /* Don't attempt to validate monitor timings */
+};
+
+struct avi_videomode porsche_rse_video_mode = {
+ .name = "porsche_rse",
+ .xres = 1280,
+ .yres = 800,
+ .pixclock = 80500,
+ /* The rest of the timings will be calculated using the VESA
+ * generalized timing formula. */
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 200,
+ .left_margin = 10,
+ .right_margin = 10,
+ .vsync_len = 67,
+ .upper_margin = 5,
+ .lower_margin = 5,
+};
+
+struct avi_videomode drse_video_mode = {
+ .name = "drse",
+ .xres = 1280,
+ .yres = 800,
+ .pixclock = 71100,
+ /* The rest of the timings will be calculated using the VESA
+ * generalized timing formula. */
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 100,
+ .left_margin = 30,
+ .right_margin = 30,
+ .vsync_len = 5,
+ .upper_margin = 16,
+ .lower_margin = 2,
+};
+
+struct avi_videomode rnb6_truly_video_mode = {
+ .name = "rnb6_truly_video_mode",
+ .xres = 720,
+ .yres = 1280,
+ .flags = 0,
+ .hsync_len = 8,
+ .left_margin = 45,
+ .right_margin = 70,
+ .vsync_len = 2,
+ .upper_margin = 15,
+ .lower_margin = 16,
+ .pixclock = 66412,
+};
+
+struct avi_videomode ntsc_720_video_mode = {
+ .name = "ntsc_720",
+ .xres = 720,
+ .yres = 480,
+ .flags = AVI_VIDEOMODE_INTERLACED,
+
+ .hsync_len = 62,
+ .left_margin = 57,
+ .right_margin = 19,
+
+ .vsync_len = 5,
+ .upper_margin = 15,
+ .lower_margin = 2,
+
+ .pixclock = 13500,
+};
+
+struct avi_videomode ntsc_640_video_mode = {
+ .name = "ntsc_640",
+ .xres = 640,
+ .yres = 480,
+ .flags = AVI_VIDEOMODE_INTERLACED,
+
+ .hsync_len = 69,
+ .left_margin = 57,
+ .right_margin = 14,
+
+ .vsync_len = 5,
+ .upper_margin = 15,
+ .lower_margin = 2,
+
+ /* The AVI PLL can not actually generate anything under 12.5MHz, let's
+ * hope this is within tolerance. */
+ .pixclock = 12273,
+};
+
+/* OEM FC7100 Vovo truck screen: TRULY SEMICONDUCTORS 2K31715 */
+struct avi_videomode tft800480_video_mode = {
+ .name = "2K31715",
+ .xres = 800,
+ .yres = 480,
+
+ .pixclock = 30000,
+
+ .flags = 0,
+
+ .hsync_len = 48,
+ .left_margin = 41,
+ .right_margin = 40,
+
+ .vsync_len = 3,
+ .upper_margin = 29,
+ .lower_margin = 13,
+
+};
+
+/*************************************************/
+/********** HDMI OUT section *********************/
+/*************************************************/
+
+/* CEA 861D/TV Formats */
+
+struct avi_videomode hdmi_720x576p50_video_mode = {
+ .name = "hdmi_720x576p50",
+ .xres = 720,
+ .yres = 576,
+ .flags = 0,
+ /* As per CEA-861-D.pdf page 25 720x576p @50 Hz (Formats 17 & 18) */
+ .hsync_len = 64,
+ .left_margin = 68,
+ .right_margin = 12,
+ .vsync_len = 5,
+ .upper_margin = 39,
+ .lower_margin = 5,
+ .pixclock = 27000,
+};
+
+struct avi_videomode hdmi_720x576i50_video_mode = {
+ .name = "hdmi_720x576i50",
+ .xres = 720,
+ .yres = 576,
+ .flags = AVI_VIDEOMODE_INTERLACED,
+ /* As per CEA-861-D.pdf page 26 720(1440)x576i @50 Hz (Formats 21 & 22)
+ * Horizontal timings, horizontal resolution and pixel clock
+ * are divided by two from original values of CEA-861
+ */
+ .hsync_len = 63,
+ .left_margin = 69,
+ .right_margin = 12,
+ .vsync_len = 3,
+ .upper_margin = 19,
+ .lower_margin = 2,
+ .pixclock = 13500,
+};
+
+struct avi_videomode hdmi_720x480p60_video_mode = {
+ .name = "hdmi_720x480p60",
+ .xres = 720,
+ .yres = 480,
+ .flags = 0,
+ /* As per CEA-861-D.pdf page 21 720x480p @59.94/60 Hz (Formats 2 & 3) */
+ .hsync_len = 62,
+ .left_margin = 60,
+ .right_margin = 16,
+ .vsync_len = 6,
+ .upper_margin = 30,
+ .lower_margin = 9,
+ .pixclock = 27027,
+};
+
+struct avi_videomode hdmi_720x480p5994_video_mode = {
+ .name = "hdmi_720x480p59.94",
+ .xres = 720,
+ .yres = 480,
+ .flags = 0,
+ /* As per CEA-861-D.pdf page 21 720x480p @59.94/60 Hz (Formats 2 & 3) */
+ .hsync_len = 62,
+ .left_margin = 60,
+ .right_margin = 16,
+ .vsync_len = 6,
+ .upper_margin = 30,
+ .lower_margin = 9,
+ .pixclock = 27000,
+};
+
+struct avi_videomode hdmi_720x480i60_video_mode = {
+ .name = "hdmi_720x480i60",
+ .xres = 720,
+ .yres = 480,
+ .flags = AVI_VIDEOMODE_INTERLACED,
+ /* As per CEA-861-D.pdf page 22 720(1440)x480i @59.94/60 Hz (Formats 6 & 7)
+ * Horizontal timings, horizontal resolution and pixel clock
+ * are divided by two from original values of CEA-861
+ */
+ .hsync_len = 62,
+ .left_margin = 57,
+ .right_margin = 19,
+ .vsync_len = 3,
+ .upper_margin = 15,
+ .lower_margin = 4,
+ .pixclock = 13513,
+};
+
+struct avi_videomode hdmi_1440x480p60_video_mode = {
+ .name = "hdmi_1440x480p60",
+ .xres = 1440,
+ .yres = 480,
+ .flags = 0,
+ /* As per CEA-861-D.pdf page 32 1440x480p @59.94/60 Hz (Formats 14 & 15) */
+ .hsync_len = 124,
+ .left_margin = 120,
+ .right_margin = 32,
+ .vsync_len = 6,
+ .upper_margin = 30,
+ .lower_margin = 9,
+ .pixclock = 54054,
+};
+
+struct avi_videomode hdmi_1440x576p50_video_mode = {
+ .name = "hdmi_1440x576p50",
+ .xres = 1440,
+ .yres = 576,
+ .flags = 0,
+ /* As per CEA-861-D.pdf 1440x576p @50 Hz (Formats 29 & 30) */
+ .hsync_len = 128,
+ .left_margin = 136,
+ .right_margin = 24,
+ .vsync_len = 5,
+ .upper_margin = 39,
+ .lower_margin = 5,
+ .pixclock = 54000,
+};
+
+struct avi_videomode hdmi_1280x720p24_video_mode = {
+ .name = "hdmi_1280x720p24", /* vic#60 */
+ .xres = 1280,
+ .yres = 720,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-E.pdf page 16/17 1280x720p @24 Hz (Format 60) */
+ .hsync_len = 40,
+ .left_margin = 220,
+ .right_margin = 1760,
+ .vsync_len = 5,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .pixclock = 59400,
+};
+
+struct avi_videomode hdmi_1280x720p25_video_mode = {
+ .name = "hdmi_1280x720p25", /* vic#61 */
+ .xres = 1280,
+ .yres = 720,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-E.pdf page 16/17 1280x720p @25 Hz (Format 61) */
+ .hsync_len = 40,
+ .left_margin = 220,
+ .right_margin = 2420,
+ .vsync_len = 5,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1280x720p30_video_mode = {
+ .name = "hdmi_1280x720p30", /* vic#62 */
+ .xres = 1280,
+ .yres = 720,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-E.pdf page 16/17 1280x720p @30 Hz (Format 62) */
+ .hsync_len = 40,
+ .left_margin = 220,
+ .right_margin = 1760,
+ .vsync_len = 5,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1280x720p50_video_mode = {
+ .name = "hdmi_1280x720p50", /* vic#19 */
+ .xres = 1280,
+ .yres = 720,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf page 23 1280x720p @50 Hz (Format 19) */
+ .hsync_len = 40,
+ .left_margin = 220,
+ .right_margin = 440,
+ .vsync_len = 5,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1280x720p60_video_mode = {
+ .name = "hdmi_1280x720p60", /* vic#4 */
+ .xres = 1280,
+ .yres = 720,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf page 19 1280x720p @59.94/60 Hz (Format 4) */
+ .hsync_len = 40,
+ .left_margin = 220,
+ .right_margin = 110,
+ .vsync_len = 5,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080p30_video_mode = {
+ .name = "hdmi_1920x1080p30", /* vic#34 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf 1920x1080p @ 30Hz (Format 34) */
+ .hsync_len = 44,
+ .left_margin = 148,
+ .right_margin = 88,
+ .vsync_len = 5,
+ .upper_margin = 36,
+ .lower_margin = 4,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080p24_video_mode = {
+ .name = "hdmi_1920x1080p24", /* vic#32 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf 1920x1080p @ 24Hz (Format 32) */
+ .hsync_len = 44,
+ .left_margin = 148,/* Hback */
+ .right_margin = 638,/* Hfront */
+ .vsync_len = 5,
+ .upper_margin = 36,/* Vback */
+ .lower_margin = 4,/* Vfront */
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080p25_video_mode = {
+ .name = "hdmi_1920x1080p25", /* vic#33 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf 1920x1080p @ 25Hz (Format 33) */
+ .hsync_len = 44,
+ .left_margin = 148,/* Hback */
+ .right_margin = 528,/* Hfront */
+ .vsync_len = 5,
+ .upper_margin = 36,/* Vback */
+ .lower_margin = 4,/* Vfront */
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080i50_video_mode = {
+ .name = "hdmi_1920x1080i50", /* vic#20 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH
+ | AVI_VIDEOMODE_INTERLACED,
+ /* As per CEA-861-D.pdf page 24 1920x1080i @50 Hz (Format 20) */
+ .hsync_len = 44,
+ .left_margin = 148,
+ .right_margin = 528,
+ .vsync_len = 5,
+ .upper_margin = 15,
+ .lower_margin = 2,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080p50_video_mode = {
+ .name = "hdmi_1920x1080p50", /* vic#31 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf 1920x1080p @ 50Hz (Format 31) */
+ .hsync_len = 44,
+ .left_margin = 148,/* Hback */
+ .right_margin = 528,/* Hfront */
+ .vsync_len = 5,
+ .upper_margin = 36,/* Vback */
+ .lower_margin = 4,/* Vfront */
+ .pixclock = 148500,
+};
+
+struct avi_videomode hdmi_1920x1080i60_video_mode = {
+ .name = "hdmi_1920x1080i60", /* vic#5 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH
+ | AVI_VIDEOMODE_INTERLACED,
+ /* As per CEA-861-D.pdf page 20 1920x1080i @59.94/60 Hz (Format 5) */
+ .hsync_len = 44,
+ .left_margin = 148,
+ .right_margin = 88,
+ .vsync_len = 5,
+ .upper_margin = 15,
+ .lower_margin = 2,
+ .pixclock = 74250,
+};
+
+struct avi_videomode hdmi_1920x1080i5994_video_mode = {
+ .name = "hdmi_1920x1080i59.94", /* vic#5 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH
+ | AVI_VIDEOMODE_INTERLACED,
+ /* As per CEA-861-D.pdf page 20 1920x1080i @59.94/60 Hz (Format 5) */
+ .hsync_len = 44,
+ .left_margin = 148,
+ .right_margin = 88,
+ .vsync_len = 5,
+ .upper_margin = 15,
+ .lower_margin = 2,
+ .pixclock = 74176,
+};
+
+struct avi_videomode hdmi_1920x1080p60_video_mode = {
+ .name = "hdmi_1920x1080p60", /* vic#16 */
+ .xres = 1920,
+ .yres = 1080,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ /* As per CEA-861-D.pdf page 33 1920x1080p @ 59.94/60Hz (Format 16) */
+ .hsync_len = 44,
+ .left_margin = 148,/* Hback */
+ .right_margin = 88,/* Hfront */
+ .vsync_len = 5,
+ .upper_margin = 36,/* Vback */
+ .lower_margin = 4,/* Vfront */
+ .pixclock = 148500,
+};
+
+/* VESA Formats */
+
+struct avi_videomode hdmi_1024x768p60_video_mode = {
+ .name = "hdmi_1024x768p60", /* vesa */
+ .xres = 1024,
+ .yres = 768,
+ .flags = 0,
+ .hsync_len = 136,
+ .left_margin = 160,
+ .right_margin = 24,
+ .vsync_len = 6,
+ .upper_margin = 29,
+ .lower_margin = 3,
+ .pixclock = 65003,
+};
+
+struct avi_videomode hdmi_1024x768p75_video_mode = {
+ .name = "hdmi_1024x768p75", /* vesa */
+ .xres = 1024,
+ .yres = 768,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 96,
+ .left_margin = 176,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 28,
+ .lower_margin = 1,
+ .pixclock = 78802,
+};
+
+struct avi_videomode hdmi_1024x768p85_video_mode = {
+ .name = "hdmi_1024x768p85", /* vesa */
+ .xres = 1024,
+ .yres = 768,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 96,
+ .left_margin = 208,
+ .right_margin = 48,
+ .vsync_len = 3,
+ .upper_margin = 36,
+ .lower_margin = 1,
+ .pixclock = 94500,
+};
+
+struct avi_videomode hdmi_800x600p75_video_mode = {
+ .name = "hdmi_800x600p75", /* vesa */
+ .xres = 800,
+ .yres = 600,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 80,
+ .left_margin = 160,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 21,
+ .lower_margin = 1,
+ .pixclock = 49500,
+};
+
+struct avi_videomode hdmi_800x600p85_video_mode = {
+ .name = "hdmi_800x600p85", /* vesa */
+ .xres = 800,
+ .yres = 600,
+ .flags = AVI_VIDEOMODE_SYNC_ACTIVE_HIGH,
+ .hsync_len = 64,
+ .left_margin = 152,
+ .right_margin = 32,
+ .vsync_len = 3,
+ .upper_margin = 27,
+ .lower_margin = 1,
+ .pixclock = 56250,
+};
+
+struct avi_videomode hdmi_640x480p75_video_mode = {
+ .name = "hdmi_640x480p75", /* vesa */
+ .xres = 640,
+ .yres = 480,
+ .flags = 0,
+ .hsync_len = 64,
+ .left_margin = 120,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 16,
+ .lower_margin = 1,
+ .pixclock = 31500,
+};
+
+struct avi_videomode sfx1_tegra_640x3360p32_video_mode = {
+ .name = "sfx1_tegra_640x3360p32", /* sfx1 */
+ .xres = 640,
+ .yres = 3361, // One additionnal line for metadata
+ .flags = 0,
+ .hsync_len = 32,
+ .left_margin = 16,
+ .right_margin = 16,
+ .vsync_len = 54,
+ .upper_margin = 16,
+ .lower_margin = 1,
+ .pixclock = 77300,
+};
+
+struct avi_videomode sfx1_tegra_640x2401p32_video_mode = {
+ .name = "sfx1_tegra_640x2401p32", /* sfx1 */
+ .xres = 640,
+ .yres = 2401, // One additionnal line for metadata
+ .flags = 0,
+ .hsync_len = 32,
+ .left_margin = 16,
+ .right_margin = 16,
+ .vsync_len = 54,
+ .upper_margin = 16,
+ .lower_margin = 1,
+ .pixclock = 56700,
+};
+
+struct avi_videomode hdmi_640x480p85_video_mode = {
+ .name = "hdmi_640x480p85", /* vesa */
+ .xres = 640,
+ .yres = 480,
+ .flags = 0,
+ .hsync_len = 48,
+ .left_margin = 112,
+ .right_margin = 32,
+ .vsync_len = 3,
+ .upper_margin = 25,
+ .lower_margin = 1,
+ .pixclock = 36000,
+};
+
+struct avi_videomode hdmi_1280x1024p60_video_mode = {
+ .name = "hdmi_1280x1024p60", /* vesa */
+ .xres = 1280,
+ .yres = 1024,
+ .flags = 0,
+ .hsync_len = 112,
+ .left_margin = 248,
+ .right_margin = 48,
+ .vsync_len = 3,
+ .upper_margin = 38,
+ .lower_margin = 1,
+ .pixclock = 108000,
+};
+
+struct avi_videomode hdmi_1280x1024p75_video_mode = {
+ .name = "hdmi_1280x1024p75", /* vesa */
+ .xres = 1280,
+ .yres = 1024,
+ .flags = 0,
+ .hsync_len = 144,
+ .left_margin = 248,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 38,
+ .lower_margin = 1,
+ .pixclock = 135000,
+};
+
+struct avi_videomode hdmi_1280x1024p85_video_mode = {
+ .name = "hdmi_1280x1024p85", /* vesa */
+ .xres = 1280,
+ .yres = 1024,
+ .flags = 0,
+ .hsync_len = 160,
+ .left_margin = 240,
+ .right_margin = 48,
+ .vsync_len = 3,
+ .upper_margin = 44,
+ .lower_margin = 1,
+ .pixclock = 157500,
+};
+
+const struct avi_videomode *p7_all_video_modes[] = {
+ &fg0700k_video_mode,
+ <104ac_video_mode,
+ <104ac_no_den_video_mode,
+ &kyocera_video_mode,
+ &porsche_rse_video_mode,
+ &drse_video_mode,
+ &chimei_antec_video_mode,
+ &tpo_laj07t001a_video_mode,
+ &ntsc_720_video_mode,
+ &ntsc_640_video_mode,
+ &tft800480_video_mode,
+ &rnb6_truly_video_mode,
+ &hdmi_720x480p60_video_mode,
+ &hdmi_720x480p5994_video_mode,
+ &hdmi_720x480i60_video_mode,
+ &hdmi_1440x480p60_video_mode,
+ &hdmi_720x576p50_video_mode,
+ &hdmi_720x576i50_video_mode,
+ &hdmi_1440x576p50_video_mode,
+ &hdmi_1280x720p24_video_mode,
+ &hdmi_1280x720p25_video_mode,
+ &hdmi_1280x720p50_video_mode,
+ &hdmi_1280x720p30_video_mode,
+ &hdmi_1280x720p60_video_mode,
+ &hdmi_1920x1080p24_video_mode,
+ &hdmi_1920x1080p25_video_mode,
+ &hdmi_1920x1080i50_video_mode,
+ &hdmi_1920x1080p50_video_mode,
+ &hdmi_1920x1080p30_video_mode,
+ &hdmi_1920x1080i60_video_mode,
+ &hdmi_1920x1080i5994_video_mode,
+ &hdmi_1920x1080p60_video_mode,
+ &hdmi_1280x1024p60_video_mode,
+ &hdmi_1280x1024p75_video_mode,
+ &hdmi_1280x1024p85_video_mode,
+ &hdmi_1024x768p60_video_mode,
+ &hdmi_1024x768p75_video_mode,
+ &hdmi_1024x768p85_video_mode,
+ &hdmi_800x600p75_video_mode,
+ &hdmi_800x600p85_video_mode,
+ &hdmi_640x480p75_video_mode,
+ &hdmi_640x480p85_video_mode,
+ NULL /* end of table */
+};
diff --git a/arch/arm/mach-parrot7/lcd-monspecs.h b/arch/arm/mach-parrot7/lcd-monspecs.h
new file mode 100644
index 0000000..dd6ade8
--- /dev/null
+++ b/arch/arm/mach-parrot7/lcd-monspecs.h
@@ -0,0 +1,108 @@
+/**
+ * linux/arch/arm/mach-parrot7/lcd-monspecs.h
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Lionel Flandrin <lionel.flandrin@parrot.com>
+ * date: 08-Oct-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _LCD_MONSPECS_H_
+#define _LCD_MONSPECS_H_
+
+
+#include <video/avi.h>
+
+/* The 7" OEM screen */
+/* The screen used in the RNB5. 6.2" with capacitive touchscreen */
+extern struct avi_videomode fg0700k_video_mode;
+/* The 10" screen */
+extern struct avi_videomode lt104ac_video_mode;
+/* When DEN is not wired */
+extern struct avi_videomode lt104ac_no_den_video_mode;
+/* OEM kyocera */
+extern struct avi_videomode kyocera_video_mode;
+/* The Antec 9" Screen */
+extern struct avi_videomode chimei_antec_video_mode;
+/* PRSE */
+extern struct avi_videomode porsche_rse_video_mode;
+/* DRSE */
+extern struct avi_videomode drse_video_mode;
+
+extern struct avi_videomode ntsc_720_video_mode;
+extern struct avi_videomode ntsc_640_video_mode;
+
+/* OEM FC7100 Vovo truck screen: TRULY SEMICONDUCTORS 2K31715 */
+extern struct avi_videomode tft800480_video_mode;
+
+/* RNB6 screen 720x1280 */
+extern struct avi_videomode rnb6_truly_video_mode;
+
+/**** HDMI Output ****/
+/* CEA 861D/TV Formats */
+/* SD TV */
+/* NTSC */
+extern struct avi_videomode hdmi_720x480p60_video_mode;
+extern struct avi_videomode hdmi_720x480p5994_video_mode;
+extern struct avi_videomode hdmi_720x480i60_video_mode;
+extern struct avi_videomode hdmi_1440x480p60_video_mode;
+
+/* PAL */
+extern struct avi_videomode hdmi_720x576p50_video_mode;
+extern struct avi_videomode hdmi_720x576i50_video_mode;
+extern struct avi_videomode hdmi_1440x576p50_video_mode;
+
+/* HD TV HD Ready */
+/* Cinema */
+extern struct avi_videomode hdmi_1280x720p24_video_mode;
+/* Europe TV */
+extern struct avi_videomode hdmi_1280x720p25_video_mode;
+extern struct avi_videomode hdmi_1280x720p50_video_mode;
+/* America/Japan TV */
+extern struct avi_videomode hdmi_1280x720p30_video_mode;
+extern struct avi_videomode hdmi_1280x720p60_video_mode;
+
+/* HD TV Full HD */
+/* Cinema */
+extern struct avi_videomode hdmi_1920x1080p24_video_mode;
+
+/* Europe TV */
+extern struct avi_videomode hdmi_1920x1080p25_video_mode;
+extern struct avi_videomode hdmi_1920x1080i50_video_mode;
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1920x1080p50_video_mode;
+
+/* America/Japan TV */
+extern struct avi_videomode hdmi_1920x1080p30_video_mode;
+extern struct avi_videomode hdmi_1920x1080i60_video_mode;
+extern struct avi_videomode hdmi_1920x1080i5994_video_mode;
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1920x1080p60_video_mode;
+
+/* VESA Formats */
+/* formats p85 are not supported by HDTV monitor Samsung T22B300EW */
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1280x1024p60_video_mode;
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1280x1024p75_video_mode;
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1280x1024p85_video_mode;
+extern struct avi_videomode hdmi_1024x768p60_video_mode;
+extern struct avi_videomode hdmi_1024x768p75_video_mode;
+/* requires 24 bit data bus separate syncs only */
+extern struct avi_videomode hdmi_1024x768p85_video_mode;
+/* not supported by HDTV monitor Samsung T22B300EW */
+extern struct avi_videomode hdmi_800x600p75_video_mode;
+extern struct avi_videomode hdmi_800x600p85_video_mode;
+extern struct avi_videomode hdmi_640x480p75_video_mode;
+extern struct avi_videomode sfx1_tegra_640x3360p32_video_mode;
+extern struct avi_videomode sfx1_tegra_640x2401p32_video_mode;
+extern struct avi_videomode hdmi_640x480p85_video_mode;
+
+// Null terminated list of all the above modes
+extern const struct avi_videomode *p7_all_video_modes[];
+
+
+#endif /* _LCD_MONSPECS_H_ */
diff --git a/arch/arm/mach-parrot7/mpegts.c b/arch/arm/mach-parrot7/mpegts.c
new file mode 100644
index 0000000..909bbad
--- /dev/null
+++ b/arch/arm/mach-parrot7/mpegts.c
@@ -0,0 +1,119 @@
+/*
+ * Parrot7 MPEG-TS controller platform implementation
+ *
+ * Copyright (C) 2013 Parrot S.A.
+ *
+ * @author: Damien Riegel <damien.riegel.ext@parrot.com>
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <media/p7-mpegts.h>
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include "common.h"
+#include "dma.h"
+#include "spi.h"
+
+static struct resource p7_mpegts0_res[] = {
+ [0] = {
+ .start = P7_MPEGTS0,
+ .end = P7_MPEGTS0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_MPEGTS0_IRQ,
+ .end = P7_MPEGTS0_IRQ,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = P7_MPEGTS0_DMA,
+ .end = P7_MPEGTS0_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct resource p7_mpegts1_res[] = {
+ [0] = {
+ .start = P7_MPEGTS1,
+ .end = P7_MPEGTS1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_MPEGTS1_IRQ,
+ .end = P7_MPEGTS1_IRQ,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = P7_MPEGTS1_DMA,
+ .end = P7_MPEGTS1_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static u64 p7_mpegts0_dma_mask = DMA_BIT_MASK(32);
+static u64 p7_mpegts1_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device p7_mpegts_dev[] = {
+ {
+ .name = P7MPG_DRV_NAME,
+ .id = 0,
+ .resource = p7_mpegts0_res,
+ .num_resources = ARRAY_SIZE(p7_mpegts0_res),
+ .dev = {
+ .dma_mask = &p7_mpegts0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ },
+ {
+ .name = P7MPG_DRV_NAME,
+ .id = 1,
+ .resource = p7_mpegts1_res,
+ .num_resources = ARRAY_SIZE(p7_mpegts1_res),
+ .dev = {
+ .dma_mask = &p7_mpegts1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ }
+};
+
+static size_t p7_mpegts_dmasz[ARRAY_SIZE(p7_mpegts_dev)] __initdata;
+
+void __init p7_reserve_mpegtsmem(unsigned int core, size_t size)
+{
+#ifdef DEBUG
+ BUG_ON(! size);
+ BUG_ON(core >= ARRAY_SIZE(p7_mpegts_dev));
+#endif
+ p7_mpegts_dmasz[core] = size;
+ p7_reserve_devmem(&p7_mpegts_dev[core], NULL, &p7_mpegts_dmasz[core]);
+}
+
+void __init p7_init_mpegts(int core,
+ struct p7mpg_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ int err;
+ if (p7_chiprev() == P7_CHIPREV_R1) {
+ printk(KERN_ERR "MPEG-TS not available on P7R1\n");
+ return;
+ }
+
+#ifdef DEBUG
+ BUG_ON(core < 0 || core >= ARRAY_SIZE(p7_mpegts_dev));
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+ p7_init_spi();
+
+ pdata->dma_sz = p7_mpegts_dmasz[core];
+
+ err = p7_init_dev(&p7_mpegts_dev[core], pdata, pins, pin_cnt);
+ if (! err)
+ return;
+
+ panic("p7: failed to init MPEG-TS (%d)\n", err);
+}
diff --git a/arch/arm/mach-parrot7/mpegts.h b/arch/arm/mach-parrot7/mpegts.h
new file mode 100644
index 0000000..173f630
--- /dev/null
+++ b/arch/arm/mach-parrot7/mpegts.h
@@ -0,0 +1,42 @@
+/*
+ * Parrot 7 MPEG-TS controller platform interface
+ *
+ * Copyright (C) 2013 Parrot S.A.
+ *
+ * @author: Damien Riegel <damien.riegel.ext@parrot.com>
+ *
+ * This file is released under the GPL
+ */
+
+
+#ifndef _ARCH_PARROT7_MPEGTS_H
+#define _ARCH_PARROT7_MPEGTS_H
+
+#include <linux/init.h>
+#include <media/p7-mpegts.h>
+
+#if defined(CONFIG_MPEGTS_PARROT7) || \
+ defined(CONFIG_MPEGTS_PARROT7_MODULE)
+
+extern void p7_init_mpegts(int core, struct p7mpg_plat_data* pdata,
+ struct pinctrl_map* pins, size_t pin_cnt);
+extern void p7_reserve_mpegtsmem(unsigned int core, size_t size);
+
+#else
+
+static inline void p7_init_mpegts(int core,
+ struct p7mpg_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ return;
+}
+
+static inline void p7_reserve_mpegtsmem(unsigned int core, size_t size)
+{
+ return;
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-parrot7/mpmc.c b/arch/arm/mach-parrot7/mpmc.c
new file mode 100644
index 0000000..21631db
--- /dev/null
+++ b/arch/arm/mach-parrot7/mpmc.c
@@ -0,0 +1,87 @@
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/p7.h>
+
+#include "mpmc.h"
+
+int p7_mpmc_set_prio(enum p7_mpmc_port port, unsigned prio)
+{
+ int off = port * 4;
+ u32 r;
+
+ if (prio > 7)
+ return -ERANGE;
+
+ r = __raw_readl(__MMIO_P2V(P7_MPMC_GBC_PRI));
+ r &= ~(7UL << off);
+ r |= prio << off;
+
+ __raw_writel(r, __MMIO_P2V(P7_MPMC_GBC_PRI));
+
+ return 0;
+}
+
+unsigned p7_mpmc_get_prio(enum p7_mpmc_port port)
+{
+ int off = port * 4;
+ u32 r;
+
+ r = __raw_readl(__MMIO_P2V(P7_MPMC_GBC_PRI));
+ r >>= off;
+ r &= 7UL;
+
+ return r;
+}
+
+
+#ifdef CONFIG_PM
+
+static unsigned p7_mpmc_config[P7_MPMC_NR_PORT];
+
+/* Save PRIO values on suspend */
+static int p7_mpmc_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(p7_mpmc_config); i++)
+ p7_mpmc_config[i] = p7_mpmc_get_prio(i);
+
+ return 0;
+}
+
+/* Restore PRIO values on resume */
+static void p7_mpmc_resume(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(p7_mpmc_config); i++)
+ p7_mpmc_set_prio(i, p7_mpmc_config[i]);
+}
+
+struct syscore_ops p7_mpmc_syscore_ops = {
+ .suspend = p7_mpmc_suspend,
+ .resume = p7_mpmc_resume,
+};
+
+
+#endif /* CONFIG_PM */
+
+void __init p7_init_mpmc(void)
+{
+ /* Default MPMC configuration. We set all ports to priority 1 to disable
+ * QoS. */
+ p7_mpmc_set_prio(P7_MPMC_CPU_DMA_PORT, 1);
+ p7_mpmc_set_prio(P7_MPMC_AVI_PORT, 1);
+ p7_mpmc_set_prio(P7_MPMC_VDEC_VENC_PORT, 1);
+ p7_mpmc_set_prio(P7_MPMC_HSP_AAI_PORT, 1);
+ p7_mpmc_set_prio(P7_MPMC_GPU_VENC_PORT, 1);
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&p7_mpmc_syscore_ops);
+#endif
+}
diff --git a/arch/arm/mach-parrot7/mpmc.h b/arch/arm/mach-parrot7/mpmc.h
new file mode 100644
index 0000000..644e5a2
--- /dev/null
+++ b/arch/arm/mach-parrot7/mpmc.h
@@ -0,0 +1,21 @@
+#ifndef _MPMC_H_
+#define _MPMC_H_
+
+enum p7_mpmc_port
+{
+ /* The value of the enum are in register order (from LSB to MSB) */
+ P7_MPMC_CPU_DMA_PORT = 0,
+ P7_MPMC_AVI_PORT = 1,
+ P7_MPMC_VDEC_VENC_PORT = 2,
+ P7_MPMC_HSP_AAI_PORT = 3,
+ P7_MPMC_GPU_VENC_PORT = 4,
+ P7_MPMC_NR_PORT,
+};
+
+/* Prio is in the range [0, 7] */
+extern int p7_mpmc_set_prio(enum p7_mpmc_port port, unsigned prio);
+extern unsigned p7_mpmc_get_prio(enum p7_mpmc_port port);
+
+void __init p7_init_mpmc(void);
+
+#endif /* _MPMC_H_ */
diff --git a/arch/arm/mach-parrot7/nand.c b/arch/arm/mach-parrot7/nand.c
new file mode 100644
index 0000000..e47519d
--- /dev/null
+++ b/arch/arm/mach-parrot7/nand.c
@@ -0,0 +1,94 @@
+/**
+ * linux/arch/arm/mach-parrot7/nand.c - Nand controller platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 15-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clkdev.h>
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include <nand/cast-nand.h>
+#include <linux/mtd/nand.h>
+
+#include "common.h"
+#include "clock.h"
+
+/* The NAND controller allocate dma_memory only once in its probe,
+ * so the size is known at compilation time
+ */
+static size_t dma_size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE;
+static dma_addr_t dma_addr;
+
+static struct resource p7_nand_res[] = {
+ [0] = {
+ .start = P7_NAND,
+ .end = P7_NAND + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_NAND_IRQ,
+ .end = P7_NAND_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 p7_nand_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device p7_nand_dev = {
+ .name = CAST_DRV_NAME,
+ .id = 0,
+ .resource = p7_nand_res,
+ .num_resources = ARRAY_SIZE(p7_nand_res),
+ .dev = {
+ .dma_mask = &p7_nand_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32)
+ }
+};
+
+/**
+ * p7_init_nand() - Instantiate NAND controller for further driver usage.
+ *
+ * @pdata: controller platform specific data
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_nand(struct cast_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+#ifdef DEBUG
+ BUG_ON(! pdata);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+
+ p7_init_dev(&p7_nand_dev, pdata, pins, pin_cnt);
+ if (! dma_declare_coherent_memory(&p7_nand_dev.dev,
+ dma_addr,
+ dma_addr,
+ dma_size,
+ DMA_MEMORY_MAP))
+ panic("p7: failed to remap DMA area [%08x:%08x] for device %s\n",
+ dma_addr,
+ dma_addr + dma_size -1,
+ dev_name(&p7_nand_dev.dev));
+}
+
+/**
+ * p7_reserve_nand_mem() - Reserve DMA memory for the NAND controller
+ */
+void __init p7_reserve_nand_mem(void)
+{
+ /* The memory is not allocated in the global pool.
+ * The driver only does a small allocation that cause fragmentation in the global pool
+ */
+ p7_reserve_devmem(&p7_nand_dev,&dma_addr,&dma_size);
+}
diff --git a/arch/arm/mach-parrot7/nand.h b/arch/arm/mach-parrot7/nand.h
new file mode 100644
index 0000000..fcb1977
--- /dev/null
+++ b/arch/arm/mach-parrot7/nand.h
@@ -0,0 +1,37 @@
+/**
+ * linux/arch/arm/mach-parrot7/nand.h - Nand controller platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 15-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_NAND_H
+#define _ARCH_PARROT7_NAND_H
+
+struct cast_plat_data;
+struct pinctrl_map;
+
+#if defined(CONFIG_MTD_NAND_CAST) || \
+ defined(CONFIG_MTD_NAND_CAST_MODULE)
+
+#include <linux/init.h>
+
+extern void p7_init_nand(struct cast_plat_data*,
+ struct pinctrl_map*,
+ size_t) __init;
+extern void p7_reserve_nand_mem(void);
+#else /* defined(CONFIG_MTD_NAND_CAST) || \
+ defined(CONFIG_MTD_NAND_CAST_MODULE) */
+
+#define p7_init_nand(_pdata, _pins, _pins_nr)
+#define p7_reserve_nand_mem()
+
+#endif /* defined(CONFIG_MTD_NAND_CAST) || \
+ defined(CONFIG_MTD_NAND_CAST_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/p7-smc.S b/arch/arm/mach-parrot7/p7-smc.S
new file mode 100644
index 0000000..777bc1b
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7-smc.S
@@ -0,0 +1,311 @@
+/*
+ * Parrot7 secure API file
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * CPU0 only, enable or disable L2 cache
+ * r0 (smc_id) : SMC_L2CACHE (2)
+ * r1 (arg0): PL310 Auxiliary Control Reg value
+ * r2 (arg1): (enable << 31) | (data_ram_ctrl << 16) | tag_ram_ctrl
+ *
+ */
+ENTRY(smc_l2x0_enable)
+ stmfd sp!, {r2-r12, lr}
+ mov r2, r1
+ mov r1, r0
+ mov r0, #0x2
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r2-r12, pc}
+ENDPROC(smc_l2x0_enable)
+
+ENTRY(smc_l2x0_disable)
+ stmfd sp!, {r1-r12, lr}
+ mov r2, #0x0
+ mov r1, #0x0
+ mov r0, #0x2
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_disable)
+
+/*
+ * Write Auxiliary control register
+ * r0 (smc_id): SMC_ACTLR (3)
+ * r1 (arg0): value to be written
+ */
+ENTRY(smc_actlr)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ mov r0, #0x3
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_actlr)
+
+/*
+ * CPU0 only, Write PL301 remap register
+ * r0 (smc_id): SMC_PL301_REMAP (4)
+ * r1 (arg0): value to be written
+ */
+ENTRY(smc_pl301_remap)
+ /*stmfd sp!, {r2-r12, lr}*/
+ mov r1, r0
+ mov r0, #0x4
+ dsb
+ .arch_extension sec
+ smc #0
+ /*ldmfd sp!, {r2-r12, pc}*/
+ mov pc, lr
+ENDPROC(smc_pl301_remap)
+
+/*
+ * ARM_ERRATA_751472: An interrupted ICIALLUIS operation may
+ * prevent the completion of a following broadcasted operation
+ * Present in all r0, r1 and r2 revisions, fixed in r3r0
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_DISABLE_IR_MNT (6)
+ */
+ENTRY(smc_disable_ir_mnt)
+ stmfd sp!, {r1-r12, lr}
+ mov r0, #0x6
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_disable_ir_mnt)
+
+/*
+ * ARM_ERRATA_743622: Faulty logic in the store buffer may lead
+ * to data corruption
+ * Present in all r2 revisions, fixed in r3p0
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_DISABLE_FLU_OPT (7)
+ */
+ENTRY(smc_disable_flu_opt)
+ stmfd sp!, {r1-r12, lr}
+ ldr r0, =0x7
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_disable_flu_opt)
+
+
+/*
+ * Enable debug in non-secure modei
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_ENABLE_DEBUG (8)
+ */
+ENTRY(smc_enable_debug)
+ stmfd sp!, {r1-r12, lr}
+ ldr r0, =0x8
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_enable_debug)
+
+/*
+ * Write access to L2X0 ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_CTRL (9)
+ */
+ENTRY(smc_l2x0_ctrl)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0x9
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_ctrl)
+
+/*
+ * Write access to L2X0 auxiliary ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_AUX (10)
+ */
+ENTRY(smc_l2x0_aux)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xa
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_aux)
+
+/*
+ * Write access to L2X0 tag RAM latency ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_TAG_LAT (11)
+ */
+ENTRY(smc_l2x0_tag_lat)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xb
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_tag_lat)
+
+/*
+ * Write access to L2X0 data RAM latency ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_DAT_LAT (12)
+ */
+ENTRY(smc_l2x0_dat_lat)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xc
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_dat_lat)
+
+/*
+ * Write access to L2X0 debug ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_DBG_CTRL (13)
+ */
+ENTRY(smc_l2x0_dbg_ctrl)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xd
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_dbg_ctrl)
+
+/*
+ * Write access to L2X0 prefetch ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_PFT_CTRL (14)
+ */
+ENTRY(smc_l2x0_pft_ctrl)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xe
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_pft_ctrl)
+
+/*
+ * Write access to L2X0 power ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_PWR_CTRL (15)
+ */
+ENTRY(smc_l2x0_pwr_ctrl)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0xf
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_pwr_ctrl)
+
+/*
+ * Write access to L2X0 addr filtering start reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_ADR_FIL_START (16)
+ */
+ENTRY(smc_l2x0_adr_fil_start)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0x10
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_adr_fil_start)
+
+/*
+ * Write access to L2X0 addr filtering end reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_ADR_FIL_END (17)
+ */
+ENTRY(smc_l2x0_adr_fil_end)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0x11
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_adr_fil_end)
+
+/*
+ * Write access to SCU non-secure access ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_NSACR (18)
+ */
+ENTRY(smc_scu_nsacr)
+ stmfd sp!, {r1-r12, lr}
+ ldr r0, =0x12
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_scu_nsacr)
+
+/*
+ * Write access to L2X0 invalidate way reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_L2_INV_WAY (19)
+ */
+ENTRY(smc_l2x0_inv_way)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0x13
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_l2x0_inv_way)
+
+/*
+ * Write access to CPACR CP10/CP11 access ctrl reg
+ * This service is implemented in the library extension
+ * r0 (smc_id): EXT_WR_CPACR (20)
+ */
+ENTRY(smc_scu_cpacr)
+ stmfd sp!, {r1-r12, lr}
+ mov r1, r0
+ ldr r0, =0x14
+ dsb
+ .arch_extension sec
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(smc_scu_cpacr)
+/*
+ * Test if CPU is in non-secure state
+ */
+ENTRY(p7_is_nonsecure_)
+ stmfd sp!, {r1-r12, lr}
+ mrs r1, cpsr /*save local irq flags */
+ mrc p15, 0, r2, c1, c0, 1 /* read ACTLR */
+ mov r3, #0x80 /* ACTLR.EXCL mask*/
+ eor r4, r3, r2 /* attempt to toggle ACTLR.EXCL*/
+ mcr p15, 0, r4, c1, c0, 1
+ mrc p15, 0, r5, c1, c0, 1 /* read back ACTLR */
+ mcr p15, 0, r2, c1, c0, 1 /* write back ACTLR */
+ msr cpsr_c, r1 /*resotre local irq flags */
+ eors r2, r5
+ beq 1f
+ mov r0, #0
+ b 2f
+1: mov r0, #1
+2: ldmfd sp!, {r1-r12, pc}
+ENDPROC(p7_is_nonsecure_)
diff --git a/arch/arm/mach-parrot7/p7_pwm.c b/arch/arm/mach-parrot7/p7_pwm.c
new file mode 100644
index 0000000..68d4ce3
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7_pwm.c
@@ -0,0 +1,128 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7pwm.c - Parrot7 PWM platform implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Victor Lambret <victor.lambret.ext@parrot.com>
+ * date: 29-Nov-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clkdev.h>
+#include <pwm/p7_pwm.h>
+#include <mach/pwm.h>
+#include "p7_pwm.h"
+#include <mach/p7.h>
+#include "common.h"
+#include "clock.h"
+#include "pinctrl.h"
+
+static struct resource p7pwm_res[] = {
+ [0] = {
+ .start = P7_PWM,
+ .end = P7_PWM + SZ_64K - 1,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device p7_p7pwm_dev = {
+ .name = P7PWM_DRV_NAME,
+ .id = 0,
+ .resource = p7pwm_res,
+ .num_resources = ARRAY_SIZE(p7pwm_res)
+};
+
+/*This part deduce the used_pwms from pinmaps*/
+
+struct p7pwm_pinpwm {
+ uint16_t pin;
+ uint16_t mask_pwm;
+};
+
+
+const static struct p7pwm_pinpwm p7pwm_numpins[] __initconst = {
+ {.pin=P7_PWM_00, .mask_pwm=(1 << 0)},
+ {.pin=P7_PWM_01, .mask_pwm=(1 << 1)},
+ {.pin=P7_PWM_02, .mask_pwm=(1 << 2)},
+ {.pin=P7_PWM_03, .mask_pwm=(1 << 3)},
+ {.pin=P7_PWM_04, .mask_pwm=(1 << 4)},
+ {.pin=P7_PWM_05, .mask_pwm=(1 << 5)},
+ {.pin=P7_PWM_06, .mask_pwm=(1 << 6)},
+ {.pin=P7_PWM_07, .mask_pwm=(1 << 7)},
+ {.pin=P7_PWM_08, .mask_pwm=(1 << 8)},
+ {.pin=P7_PWM_09, .mask_pwm=(1 << 9)},
+ {.pin=P7_PWM_10, .mask_pwm=(1 << 10)},
+ {.pin=P7_PWM_11, .mask_pwm=(1 << 11)},
+ {.pin=P7_PWM_12, .mask_pwm=(1 << 12)},
+ {.pin=P7_PWM_13, .mask_pwm=(1 << 13)},
+ {.pin=P7_PWM_14, .mask_pwm=(1 << 14)},
+ {.pin=P7_PWM_15, .mask_pwm=(1 << 15)},
+ {.pin=P7_PWM_15a,.mask_pwm=(1 << 15)},
+};
+
+/*PWM default Configuration : No precision control, normal mode*/
+static struct p7pwm_conf p7pwm_default_conf = {
+ .period_precision = 100,
+ .duty_precision = 100,
+ .mode = P7PWM_MODE_NORMAL
+};
+
+/**
+ * p7_init_p7pwm() - Instantiate P7 PWM dev for further driver usage.
+ *
+ * @pdata: platform data
+ * @pins: array of pinmaps, each pinmap contain function & props for one PWM
+ * @cnt: number of PWM described in pins
+ */
+void __init p7_init_p7pwm(struct p7pwm_pdata *pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ int err;
+ unsigned int used = 0;
+ int i,j;
+
+#ifdef DEBUG
+ BUG_ON(! pins);
+ BUG_ON(! pdata);
+#endif
+
+ /*Compute dynamically the used pwms*/
+ for (i=0; i< pin_cnt; i++)
+ for (j=0; j < ARRAY_SIZE(p7pwm_numpins); j++)
+ if ((unsigned int)(pins[i].data.mux.function) == p7pwm_numpins[j].pin)
+ used |= p7pwm_numpins[j].mask_pwm;
+ pdata->used = used;
+
+ /*Replace NULL conf pointers by default conf*/
+ for (i=0 ; i<P7PWM_NUMBER; i++)
+ if (NULL == pdata->conf[i])
+ pdata->conf[i] = &p7pwm_default_conf;
+
+ /* Assign pins before registering device in cases driver is already
+ * loaded. */
+ if (pin_cnt) {
+ char buf[10];
+ snprintf(buf, 10, "p7_pwm.%d", p7_p7pwm_dev.id);
+ err = p7_assign_pins(buf, pins, pin_cnt);
+ if (err)
+ goto err;
+ }
+
+ /* Create platform device */
+ err = p7_init_dev(&p7_p7pwm_dev, pdata, NULL, 0);
+ if (err)
+ panic("p7: failed to init P7 PWM %d (%d)\n", 0, err);
+
+ return;
+
+ /*
+ * Pinctrl does not provide us with a way to remove registered pin
+ * mappings...
+ */
+err:
+ panic("p7: failed to init PWM master controller %d (%d)\n",
+ p7_p7pwm_dev.id, err);
+}
diff --git a/arch/arm/mach-parrot7/p7_pwm.h b/arch/arm/mach-parrot7/p7_pwm.h
new file mode 100644
index 0000000..d4b0949
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7_pwm.h
@@ -0,0 +1,34 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7pwm.h - Parrot7 PWM platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Victor Lambret <victor.lambret.ext@parrot.com>
+ * date: 29-Nov-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_P7PWM_H
+#define _ARCH_PARROT7_P7PWM_H
+
+#include <linux/init.h>
+#include <linux/pinctrl/machine.h>
+#include <pwm/p7_pwm.h>
+
+#if defined(CONFIG_PWM_PARROT7) || \
+ defined(CONFIG_PWM_PARROT7_MODULE)
+
+void __init p7_init_p7pwm(struct p7pwm_pdata *pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt) ;
+
+#else /* defined(CONFIG_PWM_PARROT7) || \
+ defined(CONFIG_PWM_PARROT7_MODULE) */
+
+#define p7_init_p7pwm(...)
+
+#endif /* defined(CONFIG_PWM_PARROT7) || \
+ defined(CONFIG_PWM_PARROT7_MODULE) */
+
+#endif /*_ARCH_PARROT7_P7PWM_H*/
diff --git a/arch/arm/mach-parrot7/p7_temperature.c b/arch/arm/mach-parrot7/p7_temperature.c
new file mode 100644
index 0000000..a03f09e
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7_temperature.c
@@ -0,0 +1,51 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7_temperature.c - Parrot7 TEMPERATURE platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Karl Leplat <karl.leplat@parrot.com>
+ * date: 20-Sept-2013
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <mach/p7-adc.h>
+#include "pinctrl.h"
+#include "p7_temperature.h"
+
+static struct p7_temp_chan p7mu_adc_channels[] = {
+ {
+ .channel = 0,
+ .freq = 160000,
+ .name = "p7",
+ },
+ {
+ .channel = 7,
+ .freq = 160000,
+ .name = "p7mu",
+ }
+};
+
+static struct p7_temp_chan_data p7mu_adc_chan_data = {
+ .channels = p7mu_adc_channels,
+ .num_channels = ARRAY_SIZE(p7mu_adc_channels),
+};
+
+static struct platform_device p7_temp_device = {
+ .name = "p7-temperature",
+ .id = -1,
+ .dev.platform_data = &p7mu_adc_chan_data,
+};
+
+void __init p7_init_temperature(void)
+{
+ int err;
+
+ p7_config_pin(49, P7CTL_DRV_CFG(5));
+ p7_config_pin(50, P7CTL_DRV_CFG(5));
+
+ err = platform_device_register(&p7_temp_device);
+ if (err)
+ pr_err(KERN_ERR "Error registering P7 temperature device: %d.\n", err);
+}
diff --git a/arch/arm/mach-parrot7/p7_temperature.h b/arch/arm/mach-parrot7/p7_temperature.h
new file mode 100644
index 0000000..d65c608
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7_temperature.h
@@ -0,0 +1,29 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7_temperature.h - Parrot7 TEMPERATURE platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Karl Leplat <karl.leplat@parrot.com>
+ * date: 20-Sept-2013
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_P7TEMPERATURE_H
+#define _ARCH_PARROT7_P7TEMPERATURE_H
+
+#if defined(CONFIG_P7_TEMPERATURE) || \
+ defined(CONFIG_P7_TEMPERATURE_MODULE)
+
+extern void p7_init_temperature(void) __init;
+
+#else /* defined(CONFIG_P7_TEMPERATURE) || \
+ defined(CONFIG_P7_TEMPERATURE) */
+
+#define p7_init_temperature() \
+ ({ -ENOSYS; })
+
+#endif /* defined(CONFIG_P7_TEMPERATURE) || \
+ defined(CONFIG_P7_TEMPERATURE_MODULE) */
+
+#endif /*_ARCH_PARROT7_P7TEMPERATURE_H*/
diff --git a/arch/arm/mach-parrot7/p7mu.c b/arch/arm/mach-parrot7/p7mu.c
new file mode 100644
index 0000000..1564675
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7mu.c
@@ -0,0 +1,47 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7mu.c - Parrot7 power management unit platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 22-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <mfd/p7mu.h>
+#include "common.h"
+#include "pinctrl.h"
+#include "i2cm.h"
+
+static struct i2c_board_info p7mu_dev __initdata = {
+ I2C_BOARD_INFO(P7MU_DRV_NAME, 0x31),
+};
+
+/**
+ * p7_init_p7mu() - Instantiate P7MU device on I2C bus identified by @bus
+ * for further driver usage.
+ *
+ * @bus: master controller / bus identifier
+ * @pdata: controller platform specific data
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_p7mu(int bus,
+ struct p7mu_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+#ifdef DEBUG
+ BUG_ON(! pdata);
+ BUG_ON(! gpio_is_valid(pdata->gpio));
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+
+ p7mu_dev.platform_data = pdata;
+ p7_init_i2cm_slave(bus, &p7mu_dev, pins, pin_cnt);
+}
diff --git a/arch/arm/mach-parrot7/p7mu.h b/arch/arm/mach-parrot7/p7mu.h
new file mode 100644
index 0000000..4ee960b
--- /dev/null
+++ b/arch/arm/mach-parrot7/p7mu.h
@@ -0,0 +1,37 @@
+/**
+ * linux/arch/arm/mach-parrot7/p7mu.h - Parrot7 power management unit platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 26-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_P7MU_H
+#define _ARCH_PARROT7_P7MU_H
+
+struct p7mu_plat_data;
+struct pinctrl_map;
+
+#if defined(CONFIG_MFD_P7MU) || \
+ defined(CONFIG_MFD_P7MU_MODULE)
+
+#include <linux/init.h>
+
+extern void p7_init_p7mu(int,
+ struct p7mu_plat_data*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+#else /* defined(CONFIG_MFD_P7MU) || \
+ defined(CONFIG_MFD_P7MU_MODULE) */
+
+#define p7_init_p7mu(_bus, _pdata, _pins, _pins_nr)
+
+#endif /* defined(CONFIG_MFD_P7MU) || \
+ defined(CONFIG_MFD_P7MU_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/pinctrl.c b/arch/arm/mach-parrot7/pinctrl.c
new file mode 100644
index 0000000..7488f65
--- /dev/null
+++ b/arch/arm/mach-parrot7/pinctrl.c
@@ -0,0 +1,202 @@
+/**
+ * linux/arch/arm/mach-parrot7/pinctrl.c - Parrot7 pin controller platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 06-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <gpio/p7-gpio.h>
+#include "system.h"
+#include "common.h"
+#include "pinctrl.h"
+
+static const struct p7_pinctrl_config *p7_pctl_chip_configs[] = {
+ [P7_CHIPREV_R1] = &p7_pinctrl_config_r1,
+ [P7_CHIPREV_R2] = &p7_pinctrl_config_r2,
+ [P7_CHIPREV_R3] = &p7_pinctrl_config_r3,
+};
+
+static inline const struct p7_pinctrl_config *p7_pctl_get_chip_config(void)
+{
+ int rev = p7_chiprev();
+
+ /* Check if we have a valid pin config for this chip rev */
+ BUG_ON(rev >= ARRAY_SIZE(p7_pctl_chip_configs) ||
+ p7_pctl_chip_configs[rev] == NULL);
+
+ return p7_pctl_chip_configs[rev];
+}
+
+
+/**
+ * p7_config_pin() - Configure a pin.
+ *
+ * @pin: pin index (ie gpio)
+ * @config: configuration to apply
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ */
+int p7_config_pin(int pin, int config)
+{
+ const struct p7_pinctrl_config *cfg;
+ const char *pin_name;
+
+ cfg = p7_pctl_get_chip_config();
+ if (pin < 0 || pin >= cfg->pin_descs_sz) {
+ pr_err("p7: invalid pin number (%d)\n", pin);
+ return -EINVAL;
+ }
+
+ pin_name = cfg->pin_descs[pin].name;
+ pr_debug("p7: config pin %d (%s)\n", pin, pin_name);
+ return pin_config_set(P7CTL_DRV_NAME ".0", pin_name, config);
+}
+
+
+/**
+ * p7_assign_named_pins() - Assign a set of pins to device for further usage.
+ *
+ * @dev_name: device name
+ * @name: optional pins set name
+ * @pins: array of pin functions and optional settings
+ * @pin_cnt: number of element of @pins array
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ *
+ * Register a set of multiplexed functions / pins to pinctrl core for device
+ * usage. @pins array element is either:
+ * - one multiplexed function / physical pin mapping initialized using
+ * P7_INIT_PINMAP(), or
+ * - one physical pin set of properties (pull up / down, drive strength...)
+ * initialized using P7_INIT_PINCFG().
+ *
+ * Device drivers will further use registered pins by requesting them from the
+ * pinctrl core.
+ * Keep in mind that PIN_MAP_CONFIGS_GROUPS mappings are not handled
+ * since Parrot7 has no notion of pin groups at hardware level.
+ *
+ * Note:
+ * @pins may be located into initdata section (or on stack) as pinctrl core
+ * (shallow) copies structures content at registering time. However, embedded
+ * pointers are not copied, meaning all pin settings cannot live in kernel's
+ * init sections.
+ */
+int __init p7_assign_named_pins(char const* dev_name,
+ char const* name,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ const struct p7_pinctrl_config *cfg;
+ unsigned int m;
+ int err;
+
+ cfg = p7_pctl_get_chip_config();
+
+#ifdef DEBUG
+ pr_debug("p7: registering %s I/O pins...\n", dev_name);
+ BUG_ON(! dev_name);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+
+ for (m = 0; m < pin_cnt; m++) {
+ enum p7_pin_func func_id;
+
+ switch (pins[m].type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ func_id = (enum p7_pin_func) pins[m].data.mux.function;
+
+ BUG_ON((unsigned int) func_id >= P7_N_FUNCTIONS);
+ /* Make sure the function is available on this chip rev */
+ BUG_ON(cfg->pin_funcs[func_id].name == NULL);
+
+ pins[m].data.mux.function = cfg->pin_funcs[func_id].name;
+
+ pr_debug("p7:\tinstall %s I/O pin function\n",
+ pins[m].data.mux.function);
+ break;
+
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ func_id = (enum p7_pin_func) pins[m].data.configs.group_or_pin;
+
+ BUG_ON((unsigned int) func_id >= P7_N_FUNCTIONS);
+ /* Make sure the function is available on this chip rev */
+ BUG_ON(cfg->pin_funcs[func_id].name == NULL);
+ BUG_ON((unsigned int) cfg->pin_funcs[func_id].pin_id >=
+ cfg->pin_descs_sz);
+
+ pins[m].data.configs.group_or_pin =
+ cfg->pin_descs[cfg->pin_funcs[func_id].pin_id].name;
+
+ pr_debug("p7:\tinstall %s I/O pin settings\n",
+ pins[m].data.configs.group_or_pin);
+ break;
+
+ default:
+ BUG();
+ }
+
+ /* Assign pins to device. */
+ pins[m].dev_name = dev_name;
+
+ /* Do not override default name if none given in argument. */
+ if (name)
+ pins[m].name = name;
+ }
+
+ /* Register pins to pinctrl core. */
+ err = pinctrl_register_mappings(pins, pin_cnt);
+ if (err)
+ pr_err("p7: failed to register %s I/O pins (%d)\n", dev_name, err);
+
+ return err;
+}
+
+/*
+ * Pin controller hardware registers space
+ */
+static struct resource p7_pctl_res = {
+ .start = P7_SYS_PADCTRL_IO,
+ .end = P7_SYS_PADCTRL_IO + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * Pin controller platform specific data, allowing to manage Parrot7 variants
+ * with different set of pins and functions. This one is meant for MPW1.
+ */
+static struct p7ctl_plat_data p7_pctl_pdata = {
+ .gpio_drv = P7GPIO_DRV_NAME
+};
+
+/*
+ * Pin controller device
+ */
+static struct platform_device p7_pctl_dev = {
+ .name = P7CTL_DRV_NAME,
+ .id = 0,
+ .dev.platform_data = &p7_pctl_pdata,
+ .num_resources = 1,
+ .resource = &p7_pctl_res
+};
+
+int __init p7_init_pctl(void)
+{
+ const struct p7_pinctrl_config *cfg = p7_pctl_get_chip_config();
+
+ p7_pctl_pdata.funcs = cfg->pin_funcs;
+ p7_pctl_pdata.funcs_nr = P7_N_FUNCTIONS;
+ p7_pctl_pdata.pins = cfg->pin_descs;
+ p7_pctl_pdata.pins_nr = cfg->pin_descs_sz;
+ p7_pctl_pdata.gpios = cfg->gpio_pins;
+ p7_pctl_pdata.gpios_nr = cfg->gpio_pins_sz;
+
+ return p7_init_dev(&p7_pctl_dev, NULL, NULL, 0);
+}
diff --git a/arch/arm/mach-parrot7/pinctrl.h b/arch/arm/mach-parrot7/pinctrl.h
new file mode 100644
index 0000000..0156c55
--- /dev/null
+++ b/arch/arm/mach-parrot7/pinctrl.h
@@ -0,0 +1,806 @@
+/**
+ * linux/arch/arm/mach-parrot7/pinctrl.h - Parrot7 pin controller platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 07-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+/**************************************************
+ * Pinctrl interface usage sample code for BSP...
+ **************************************************/
+
+#ifdef DONT_REMOVE_ME
+
+/*
+ * Properties tables must be declared as static. The cannot lay onto any
+ * kernel's init sections and must not be constant.
+ */
+static unsigned long myboard_sdhci_cmdcfg[] = {
+ P7CTL_SMT_CFG(OFF),
+ P7CTL_PUD_CFG(KEEP),
+ P7CTL_SLR_CFG(1),
+};
+
+static unsigned long myboard_sdhci_datcfg[] = {
+ P7CTL_SMT_CFG(ON),
+ P7CTL_PUD_CFG(UP),
+ P7CTL_SLR_CFG(0),
+ P7CTL_DRV_CFG(TRI)
+};
+
+static unsigned long myboard_sdhci1_clkcfg[] = {
+ P7CTL_PUD_CFG(DOWN),
+ P7CTL_DRV_CFG(5)
+};
+
+/*
+ * Pinmaps tables SHOULD be hold by an __initdata section.
+ */
+static struct pinctrl_map myboard_sdhci0_pins[] __initdata = {
+ /* Just select the right clock function. */
+ P7_INIT_PINMAP(P7_SD_0_CLK),
+
+ /* Command pin is assigned a set of properties shared with sdhci1 command. */
+ P7_INIT_PINMAP(P7_SD_0_CMD),
+ P7_INIT_PINCFG(P7_SD_0_CMD, myboard_sdhci_cmdcfg),
+
+ /* Just select the right functions here. */
+ P7_INIT_PINMAP(P7_SD_0_DAT00),
+ P7_INIT_PINMAP(P7_SD_0_DAT01),
+ P7_INIT_PINMAP(P7_SD_0_DAT02),
+
+ /* Properties also shared with sdhci0 dat00 & dat01. */
+ P7_INIT_PINCFG(P7_SD_0_DAT03, myboard_sdhci_datcfg),
+};
+
+static struct pinctrl_map myboard_sdhci1_pins[] __initdata = {
+ /* Clock pin is assigned its own set of properties. */
+ P7_INIT_PINMAP(P7_SD_1_CLK),
+ P7_INIT_PINCFG(P7_SD_1_CLK, myboard_sdhci1_clkcfg),
+
+ /* Same for command pin. */
+ P7_INIT_PINMAP(P7_SD_1_CMD),
+ P7_INIT_PINCFG(P7_SD_1_CMD, myboard_sdhci_cmdcfg),
+
+ /* A single set of properties is applied to dat00 & dat01 only */
+ P7_INIT_PINMAP(P7_SD_1_DAT00),
+ P7_INIT_PINCFG(P7_SD_1_DAT00, myboard_sdhci_datcfg),
+
+ P7_INIT_PINMAP(P7_SD_1_DAT01),
+ P7_INIT_PINCFG(P7_SD_1_DAT01, myboard_sdhci_datcfg),
+
+ /* Just select the right functions here. */
+ P7_INIT_PINMAP(P7_SD_1_DAT02),
+ P7_INIT_PINMAP(P7_SD_1_DAT03),
+};
+
+/*
+ * Register pinmaps later on using p7_init_dev or controller specific
+ * implementation.
+ */
+p7_init_sdhci(0,
+ &myboard_sdhci0_pdata,
+ myboard_sdhci0_pins,
+ ARRAY_SIZE(myboard_sdhci0_pins));
+p7_init_sdhci(1,
+ &myboard_sdhci1_pdata,
+ myboard_sdhci1_pins,
+ ARRAY_SIZE(myboard_sdhci1_pins));
+
+#endif /* DONT_REMOVE_ME */
+
+#ifndef _ARCH_PARROT7_PINCTRL_H
+#define _ARCH_PARROT7_PINCTRL_H
+
+#ifdef CONFIG_PINCTRL_PARROT7
+
+#include <linux/pinctrl/machine.h>
+#include <pinctrl/p7-pinctrl.h>
+
+extern int p7_config_pin(int pin,
+ int config);
+
+extern int p7_assign_named_pins(char const*,
+ char const*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+/**
+ * p7_assign_pins() - Assign a default set of pins to device for further usage.
+ *
+ * @dev_name: device name
+ * @pins: array of pin functions and optional settings
+ * @pin_cnt: number of element of @pins array
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ *
+ * Note: see p7_assign_pins() for more infos.
+ */
+ static inline int p7_assign_pins(char const* dev_name,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ return p7_assign_named_pins(dev_name, NULL, pins, pin_cnt);
+}
+
+/**
+ * P7_INIT_PINMAP() - Define a pin to be used according to multiplexing
+ * function passed in argument.
+ * @_func_id: multiplexing function identifier
+ */
+#define P7_INIT_PINMAP(_func_id) \
+ PIN_MAP_MUX_GROUP_DEFAULT(NULL, \
+ P7CTL_DRV_NAME ".0", \
+ NULL, \
+ (char*) _func_id)
+
+/**
+ * P7_INIT_PINCFG() - Define multiplexed pin settings
+ *
+ * @_func_id: multiplexing function identifier
+ * @_cfg: settings
+ *
+ * @_cfg must be initialized using Parrot7 pin controller driver macros
+ * (see linux/drivers/pinctrl/p7-pinctrl.h);
+ */
+#define P7_INIT_PINCFG(_func_id, _cfg) \
+ PIN_MAP_CONFIGS_PIN_DEFAULT(NULL, \
+ P7CTL_DRV_NAME ".0", \
+ (char*) _func_id, \
+ _cfg)
+
+struct p7_pinctrl_config {
+ const struct pinctrl_pin_desc *pin_descs;
+ unsigned pin_descs_sz;
+ const struct p7ctl_function *pin_funcs;
+ unsigned long *gpio_pins;
+ unsigned gpio_pins_sz;
+};
+
+extern const struct p7_pinctrl_config p7_pinctrl_config_r1;
+extern const struct p7_pinctrl_config p7_pinctrl_config_r2;
+extern const struct p7_pinctrl_config p7_pinctrl_config_r3;
+
+extern int p7_init_pctl(void) __init;
+
+/**
+ * enum p7_pin_func - Multiplexing function identifier.
+ *
+ * This enum list all functions that exist in *any* version of the chip, not all
+ * chips revisions will have the same set of functions.
+ *
+ * Note: identifiers were generated using the genpin.sh script located
+ * into this directory.
+ */
+enum p7_pin_func {
+ P7_CAM_1_DATA02,
+ P7_GPIO_000,
+ P7_SPI_03b,
+ P7_CAM_3_VSa,
+ P7_CAM_1_DATA03,
+ P7_GPIO_001,
+ P7_SPI_04b,
+ P7_CAM_3_HSa,
+ P7_CAM_1_DATA04,
+ P7_GPIO_002,
+ P7_SPI_05b,
+ P7_CAM_4_VSa,
+ P7_CAM_1_DATA05,
+ P7_GPIO_003,
+ P7_SPI_06b,
+ P7_CAM_4_HSa,
+ P7_CAM_1_DATA06,
+ P7_GPIO_004,
+ P7_SPI_07b,
+ P7_CAM_5_VSa,
+ P7_CAM_1_DATA07,
+ P7_GPIO_005,
+ P7_SPI_08b,
+ P7_CAM_5_HSa,
+ P7_CAM_5_CLK,
+ P7_GPIO_006,
+ P7_SD_2_CLK,
+ P7_CAM_5_DATA00,
+ P7_GPIO_007,
+ P7_SD_2_CMD,
+ P7_CAM_5_DATA01,
+ P7_GPIO_008,
+ P7_SD_2_DAT00,
+ P7_CAM_5_DATA02,
+ P7_GPIO_009,
+ P7_SD_2_DAT01,
+ P7_CAM_5_DATA03,
+ P7_GPIO_010,
+ P7_SD_2_DAT02,
+ P7_CAM_5_DATA04,
+ P7_GPIO_011,
+ P7_SD_2_DAT03,
+ P7_CAM_5_DATA05,
+ P7_GPIO_012,
+ P7_CAM_5_DATA06,
+ P7_GPIO_013,
+ P7_CAM_5_DATA07,
+ P7_GPIO_014,
+ P7_SD_1_CLK,
+ P7_UART_5_TX,
+ P7_SD_1_CMD,
+ P7_UART_5_RX,
+ P7_SD_1_DAT00,
+ P7_UART_6_TX,
+ P7_SD_1_DAT02,
+ P7_UART_7_TX,
+ P7_SD_1_DAT01,
+ P7_UART_6_RX,
+ P7_SD_1_DAT03,
+ P7_UART_7_RX,
+ P7_SD_0_CLK,
+ P7_SD_0_CMD,
+ P7_SD_0_DAT00,
+ P7_SD_0_DAT01,
+ P7_SD_0_DAT02,
+ P7_SD_0_DAT03,
+ P7_NAND_NCE,
+ P7_SPI_00a,
+ P7_NAND_NR,
+ P7_SPI_01a,
+ P7_NAND_NW,
+ P7_SPI_02a,
+ P7_NAND_AL,
+ P7_SPI_03a,
+ P7_NAND_CL,
+ P7_SPI_04a,
+ P7_NAND_RNB,
+ P7_SPI_05a,
+ P7_NAND_DQS,
+ P7_GPIO_033,
+ P7_CAN1_RXa,
+ P7_NAND_DATA_00,
+ P7_SPI_06a,
+ P7_NAND_DATA_01,
+ P7_SPI_07a,
+ P7_NAND_DATA_02,
+ P7_SPI_08a,
+ P7_NAND_DATA_03,
+ P7_SPI_09a,
+ P7_NAND_DATA_04,
+ P7_GPIO_038,
+ P7_NAND_DATA_05,
+ P7_GPIO_039,
+ P7_NAND_DATA_06,
+ P7_GPIO_040,
+ P7_NAND_DATA_07,
+ P7_GPIO_041,
+ P7_NAND_WP,
+ P7_GPIO_042,
+ P7_GPIO_049,
+ P7_GPIO_050,
+ P7_CAN1_TXa,
+ P7_FORCE_POWER_ON,
+ P7_TRST_N,
+ P7_TDI,
+ P7_TDO,
+ P7_TCK,
+ P7_TMS,
+ P7_UART_1_RX,
+ P7_UART_1_TX,
+ P7_UART_1_RTS,
+ P7_CAN0_RXb,
+ P7_UART_1_CTS,
+ P7_CAN0_TXb,
+ P7_UART_0_RX,
+ P7_GPIO_055,
+ P7_UART_0_TX,
+ P7_GPIO_056,
+ P7_UART_0_RTS,
+ P7_GPIO_057,
+ P7_UART_0_CTS,
+ P7_GPIO_058,
+ P7_I2C_2_DAT,
+ P7_GPIO_059,
+ P7_I2C_2_SL_DAT,
+ P7_I2C_2_CLK,
+ P7_GPIO_060,
+ P7_I2C_2_SL_CLK,
+ P7_I2C_1_DAT,
+ P7_GPIO_061,
+ P7_I2C_1_SL_DAT,
+ P7_I2C_1_CLK,
+ P7_GPIO_062,
+ P7_I2C_1_SL_CLK,
+ P7_I2C_0_DAT,
+ P7_GPIO_063,
+ P7_I2C_0_SL_DAT,
+ P7_I2C_0_CLK,
+ P7_GPIO_064,
+ P7_I2C_0_SL_CLK,
+ P7_UART_4_RX,
+ P7_GPIO_065,
+ P7_UART_4_TX,
+ P7_GPIO_066,
+ P7_UART_3_RX,
+ P7_GPIO_067,
+ P7_UART_3_TX,
+ P7_GPIO_068,
+ P7_UART_2_RX,
+ P7_CAN1_TXb,
+ P7_UART_2_TX,
+ P7_CAN1_RXb,
+ P7_I2C_SECURE_CLK,
+ P7_SPI_09b,
+ P7_GPIO_071,
+ P7_PWM_15,
+ P7_SPI_10b,
+ P7_GPIO_072,
+ P7_SPI_11b,
+ P7_GPIO_073,
+ P7_I2C_SECURE_CLKa,
+ P7_SPI_12b,
+ P7_GPIO_074,
+ P7_SPI_13b,
+ P7_GPIO_075,
+ P7_SPI_14b,
+ P7_GPIO_076,
+ P7_SPI_00,
+ P7_GPIO_077,
+ P7_AAI_15,
+ P7_CAN1_TX,
+ P7_SPI_01,
+ P7_GPIO_078,
+ P7_AAI_16,
+ P7_CAN1_RX,
+ P7_SPI_02,
+ P7_GPIO_079,
+ P7_AAI_17,
+ P7_CAN0_TX,
+ P7_SPI_03,
+ P7_GPIO_080,
+ P7_AAI_18,
+ P7_CAN0_RX,
+ P7_SPI_04,
+ P7_GPIO_081,
+ P7_AAI_19,
+ P7_SPI_05,
+ P7_GPIO_082,
+ P7_AAI_20,
+ P7_SPI_06,
+ P7_GPIO_083,
+ P7_AAI_21,
+ P7_SPI_07,
+ P7_GPIO_084,
+ P7_AAI_22,
+ P7_SPI_08,
+ P7_GPIO_085,
+ P7_AAI_23,
+ P7_SPI_09,
+ P7_GPIO_086,
+ P7_AAI_24,
+ P7_SPI_10,
+ P7_GPIO_087,
+ P7_AAI_25,
+ P7_SPI_11,
+ P7_GPIO_088,
+ P7_AAI_26,
+ P7_SPI_12,
+ P7_GPIO_089,
+ P7_AAI_27,
+ P7_SPI_13,
+ P7_GPIO_090,
+ P7_AAI_28,
+ P7_SPI_14,
+ P7_GPIO_091,
+ P7_AAI_29,
+ P7_SPI_15,
+ P7_GPIO_092,
+ P7_AAI_30,
+ P7_P7MU_CLK_OUT,
+ P7_PWM_15a,
+ P7_I2C_SECURE_DAT,
+ P7_REBOOT_P7MU,
+ P7_GPIO_094,
+ P7_ULPI_0_DATA00,
+ P7_ULPI_0_DATA01,
+ P7_ULPI_0_DATA02,
+ P7_ULPI_0_DATA03,
+ P7_ULPI_0_DATA04,
+ P7_ULPI_0_DATA05,
+ P7_ULPI_0_DATA06,
+ P7_ULPI_0_DATA07,
+ P7_ULPI_0_NXT,
+ P7_ULPI_0_DIR,
+ P7_ULPI_0_CLK,
+ P7_ULPI_1_DATA00,
+ P7_GPIO_106,
+ P7_I2C_2_CLKa,
+ P7_ULPI_1_DATA01,
+ P7_GPIO_107,
+ P7_I2C_2_DATa,
+ P7_ULPI_1_DATA02,
+ P7_GPIO_108,
+ P7_I2C_2_CLKb,
+ P7_ULPI_1_DATA03,
+ P7_GPIO_109,
+ P7_I2C_2_DATb,
+ P7_ULPI_1_DATA04,
+ P7_GPIO_110,
+ P7_I2C_2_CLKc,
+ P7_ULPI_1_DATA05,
+ P7_GPIO_111,
+ P7_I2C_2_DATc,
+ P7_ULPI_1_DATA06,
+ P7_GPIO_112,
+ P7_I2C_2_CLKd,
+ P7_ULPI_1_DATA07,
+ P7_GPIO_113,
+ P7_I2C_2_DATd,
+ P7_ULPI_1_NXT,
+ P7_GPIO_114,
+ P7_I2C_2_CLKe,
+ P7_ULPI_1_DIR,
+ P7_GPIO_115,
+ P7_ULPI_1_STP,
+ P7_GPIO_116,
+ P7_GPIO_117,
+ P7_I2C_2_DATe,
+ P7_ULPI_0_STP,
+ P7_ULPI_1_CLK,
+ P7_GPIO_118,
+ P7_AAI_00,
+ P7_GPIO_119,
+ P7_PWM_00,
+ P7_AAI_01,
+ P7_GPIO_120,
+ P7_PWM_01,
+ P7_AAI_02,
+ P7_GPIO_121,
+ P7_PWM_02,
+ P7_AAI_03,
+ P7_GPIO_122,
+ P7_PWM_03,
+ P7_AAI_04,
+ P7_GPIO_123,
+ P7_PWM_04,
+ P7_AAI_05,
+ P7_GPIO_124,
+ P7_PWM_05,
+ P7_AAI_06,
+ P7_GPIO_125,
+ P7_PWM_06,
+ P7_AAI_07,
+ P7_GPIO_126,
+ P7_PWM_07,
+ P7_AAI_08,
+ P7_GPIO_127,
+ P7_PWM_08,
+ P7_AAI_09,
+ P7_GPIO_128,
+ P7_PWM_09,
+ P7_AAI_10,
+ P7_GPIO_129,
+ P7_PWM_10,
+ P7_AAI_11,
+ P7_GPIO_130,
+ P7_PWM_11,
+ P7_AAI_12,
+ P7_GPIO_131,
+ P7_PWM_12,
+ P7_AAI_13,
+ P7_GPIO_132,
+ P7_PWM_13,
+ P7_AAI_14,
+ P7_GPIO_133,
+ P7_PWM_14,
+ P7_SPI_16,
+ P7_GPIO_134,
+ P7_ETH_MII_TXER,
+ P7_SPI_17,
+ P7_GPIO_135,
+ P7_ETH_MII_RXER,
+ P7_SPI_18,
+ P7_GPIO_136,
+ P7_ETH_MII_CRS,
+ P7_SPI_19,
+ P7_GPIO_137,
+ P7_ETH_MII_COL,
+ P7_ETH_RGMII_TXC,
+ P7_GPIO_138,
+ P7_ETH_RGMII_TXD_00,
+ P7_GPIO_139,
+ P7_ETH_RGMII_TXD_01,
+ P7_GPIO_140,
+ P7_ETH_RGMII_TXD_02,
+ P7_GPIO_141,
+ P7_ETH_RGMII_TXD_03,
+ P7_GPIO_142,
+ P7_ETH_RGMII_TX_CTL,
+ P7_GPIO_143,
+ P7_ETH_RGMII_RXC,
+ P7_GPIO_144,
+ P7_ETH_RGMII_RXD_00,
+ P7_GPIO_145,
+ P7_ETH_RGMII_RXD_01,
+ P7_GPIO_146,
+ P7_ETH_RGMII_RXD_02,
+ P7_GPIO_147,
+ P7_ETH_RGMII_RXD_03,
+ P7_GPIO_148,
+ P7_ETH_RGMII_RX_CTL,
+ P7_GPIO_149,
+ P7_ETH_MDC,
+ P7_GPIO_150,
+ P7_ETH_MDIO,
+ P7_GPIO_151,
+ P7_LCD_0_DEN,
+ P7_GPIO_152,
+ P7_CAM_1_VS,
+ P7_LCD_0_HS,
+ P7_GPIO_153,
+ P7_CAM_1_HS,
+ P7_LCD_0_DENa,
+ P7_LCD_0_VS,
+ P7_GPIO_154,
+ P7_CAM_0_VS,
+ P7_LCD_0_DATA00,
+ P7_GPIO_155,
+ P7_CAM_0_HS,
+ P7_LCD_0_DATA01,
+ P7_GPIO_156,
+ P7_CAM_2_VS,
+ P7_LCD_0_DATA02,
+ P7_GPIO_157,
+ P7_CAM_2_HS,
+ P7_LCD_0_DATA03,
+ P7_GPIO_158,
+ P7_CAM_3_VS,
+ P7_LCD_0_DATA04,
+ P7_GPIO_159,
+ P7_CAM_3_HS,
+ P7_LCD_0_DATA05,
+ P7_GPIO_160,
+ P7_CAM_5_VS,
+ P7_LCD_0_DATA06,
+ P7_GPIO_161,
+ P7_CAM_5_HS,
+ P7_LCD_0_DATA07,
+ P7_GPIO_162,
+ P7_CAM_0_DATA08,
+ P7_LCD_0_DATA08,
+ P7_GPIO_163,
+ P7_CAM_0_DATA09,
+ P7_CAM_0_DATA08a,
+ P7_LCD_0_DATA09,
+ P7_GPIO_164,
+ P7_CAM_0_DATA10,
+ P7_CAM_0_DATA09a,
+ P7_LCD_0_DATA10,
+ P7_GPIO_165,
+ P7_CAM_0_DATA11,
+ P7_CAM_0_DATA10a,
+ P7_LCD_0_DATA11,
+ P7_GPIO_166,
+ P7_CAM_0_DATA12,
+ P7_CAM_0_DATA11a,
+ P7_LCD_0_DATA12,
+ P7_GPIO_167,
+ P7_CAM_0_DATA13,
+ P7_CAM_0_DATA12a,
+ P7_LCD_0_DATA13,
+ P7_GPIO_168,
+ P7_CAM_0_DATA14,
+ P7_CAM_0_DATA13a,
+ P7_LCD_0_DATA14,
+ P7_GPIO_169,
+ P7_CAM_0_DATA15,
+ P7_CAM_0_DATA14a,
+ P7_LCD_0_DATA15,
+ P7_GPIO_170,
+ P7_CAM_0_DATA16,
+ P7_CAM_0_DATA15a,
+ P7_LCD_0_DATA16,
+ P7_GPIO_171,
+ P7_CAM_0_DATA17,
+ P7_LCD_0_DATA17,
+ P7_GPIO_172,
+ P7_CAM_0_DATA18,
+ P7_LCD_0_DATA18,
+ P7_GPIO_173,
+ P7_CAM_0_DATA19,
+ P7_LCD_0_DATA19,
+ P7_GPIO_174,
+ P7_CAM_0_DATA20,
+ P7_LCD_0_DATA20,
+ P7_GPIO_175,
+ P7_CAM_0_DATA21,
+ P7_CAM_3_DATA09a,
+ P7_LCD_0_DATA21,
+ P7_GPIO_176,
+ P7_CAM_0_DATA22,
+ P7_CAM_3_DATA08a,
+ P7_LCD_0_DATA22,
+ P7_GPIO_177,
+ P7_CAM_0_DATA23,
+ P7_LCD_0_DATA23,
+ P7_GPIO_178,
+ P7_CAM_4_VS,
+ P7_LCD_0_CLK,
+ P7_GPIO_179,
+ P7_CAM_4_HS,
+ P7_CAM_0_CLKa,
+ P7_LCD_1_HS,
+ P7_GPIO_180,
+ P7_CAM_2_CLK,
+ P7_LCD_1_DENa,
+ P7_LCD_1_VS,
+ P7_GPIO_181,
+ P7_CAM_2_DATA00,
+ P7_CPU_TRACECLKOUT,
+ P7_LCD_1_CLK,
+ P7_GPIO_182,
+ P7_CAM_2_DATA01,
+ P7_CPU_TRACECTL,
+ P7_LCD_1_DATA00,
+ P7_GPIO_183,
+ P7_CAM_2_DATA02,
+ P7_CPU_TRACEDATA_00,
+ P7_LCD_1_DATA01,
+ P7_GPIO_184,
+ P7_CAM_2_DATA03,
+ P7_CPU_TRACEDATA_01,
+ P7_LCD_1_DATA02,
+ P7_GPIO_185,
+ P7_CAM_2_DATA04,
+ P7_CPU_TRACEDATA_02,
+ P7_LCD_1_DATA03,
+ P7_GPIO_186,
+ P7_CAM_2_DATA05,
+ P7_CPU_TRACEDATA_03,
+ P7_LCD_1_DATA04,
+ P7_GPIO_187,
+ P7_CAM_2_DATA06,
+ P7_CPU_TRACEDATA_04,
+ P7_LCD_1_DATA05,
+ P7_GPIO_188,
+ P7_CAM_2_DATA07,
+ P7_CPU_TRACEDATA_05,
+ P7_LCD_1_DATA06,
+ P7_GPIO_189,
+ P7_CAM_3_CLK,
+ P7_CPU_TRACEDATA_06,
+ P7_LCD_1_DATA07,
+ P7_GPIO_190,
+ P7_CAM_3_DATA00,
+ P7_CPU_TRACEDATA_07,
+ P7_LCD_1_DATA08,
+ P7_GPIO_191,
+ P7_CAM_3_DATA01,
+ P7_CPU_TRACEDATA_08,
+ P7_LCD_1_DATA09,
+ P7_GPIO_192,
+ P7_CAM_3_DATA02,
+ P7_CPU_TRACEDATA_09,
+ P7_LCD_1_DATA10,
+ P7_GPIO_193,
+ P7_CAM_3_DATA03,
+ P7_CPU_TRACEDATA_10,
+ P7_LCD_1_DATA11,
+ P7_GPIO_194,
+ P7_CAM_3_DATA04,
+ P7_CPU_TRACEDATA_11,
+ P7_LCD_1_DATA12,
+ P7_GPIO_195,
+ P7_CAM_3_DATA05,
+ P7_CPU_TRACEDATA_12,
+ P7_LCD_1_DATA13,
+ P7_GPIO_196,
+ P7_CAM_3_DATA06,
+ P7_CPU_TRACEDATA_13,
+ P7_LCD_1_DATA14,
+ P7_GPIO_197,
+ P7_CAM_3_DATA07,
+ P7_CPU_TRACEDATA_14,
+ P7_LCD_1_DATA15,
+ P7_GPIO_198,
+ P7_CAM_4_CLK,
+ P7_CPU_TRACEDATA_15,
+ P7_LCD_1_DATA16,
+ P7_GPIO_199,
+ P7_CAM_4_DATA00,
+ P7_LCD_1_DATA17,
+ P7_GPIO_200,
+ P7_CAM_4_DATA01,
+ P7_LCD_1_DATA18,
+ P7_GPIO_201,
+ P7_CAM_4_DATA02,
+ P7_LCD_1_DATA19,
+ P7_GPIO_202,
+ P7_CAM_4_DATA03,
+ P7_LCD_1_DATA20,
+ P7_GPIO_203,
+ P7_CAM_4_DATA04,
+ P7_LCD_1_DATA21,
+ P7_GPIO_204,
+ P7_CAM_4_DATA05,
+ P7_LCD_1_DATA22,
+ P7_GPIO_205,
+ P7_CAM_4_DATA06,
+ P7_LCD_1_DATA23,
+ P7_GPIO_206,
+ P7_CAM_4_DATA07,
+ P7_LCD_1_DEN,
+ P7_GPIO_207,
+ P7_CAM_1_HSa,
+ P7_LCD_1_CLKa,
+ P7_CAM_0_CLK,
+ P7_GPIO_208,
+ P7_CAM_1_CLKa,
+ P7_CAM_0_DATA00,
+ P7_GPIO_209,
+ P7_CAM_1_DATA08,
+ P7_CAM_0_DATA01,
+ P7_GPIO_210,
+ P7_CAM_1_DATA09,
+ P7_CAM_0_DATA02,
+ P7_GPIO_211,
+ P7_CAM_1_DATA10,
+ P7_CAM_4_DATA08,
+ P7_CAM_0_DATA03,
+ P7_GPIO_212,
+ P7_CAM_1_DATA11,
+ P7_CAM_4_DATA09,
+ P7_CAM_0_DATA04,
+ P7_GPIO_213,
+ P7_CAM_1_DATA12,
+ P7_CAM_5_DATA08,
+ P7_CAM_0_DATA05,
+ P7_GPIO_214,
+ P7_CAM_1_DATA13,
+ P7_CAM_5_DATA09,
+ P7_CAM_0_DATA06,
+ P7_GPIO_215,
+ P7_CAM_1_DATA14,
+ P7_CAM_2_DATA08,
+ P7_CAM_0_DATA07,
+ P7_GPIO_216,
+ P7_CAM_1_DATA15,
+ P7_CAM_2_DATA09,
+ P7_CAM_1_CLK,
+ P7_GPIO_217,
+ P7_SPI_00b,
+ P7_CAM_1_DATA00,
+ P7_GPIO_218,
+ P7_SPI_01b,
+ P7_CAM_0_VSa,
+ P7_CAM_1_DATA01,
+ P7_GPIO_219,
+ P7_SPI_02b,
+ P7_CAM_0_HSa,
+ P7_PAR_NCS,
+ P7_PAR_NRS,
+ P7_PAR_NRD,
+ P7_PAR_NWR,
+ P7_PAR_D00,
+ P7_PAR_D01,
+ P7_PAR_D02,
+ P7_PAR_D03,
+ P7_PAR_D04,
+ P7_PAR_D05,
+ P7_PAR_D06,
+ P7_PAR_D07,
+ P7_PAR_D08,
+ P7_PAR_D09,
+ P7_PAR_D10,
+ P7_PAR_D11,
+ P7_PAR_D12,
+ P7_PAR_D13,
+ P7_PAR_D14,
+ P7_PAR_D15,
+ P7_N_FUNCTIONS,
+};
+
+#endif /* CONFIG_PINCTRL_PARROT7 */
+
+#endif /*_ARCH_PARROT7_PINCTRL_H */
diff --git a/arch/arm/mach-parrot7/pindesc-r1.c b/arch/arm/mach-parrot7/pindesc-r1.c
new file mode 100644
index 0000000..34c8fc8
--- /dev/null
+++ b/arch/arm/mach-parrot7/pindesc-r1.c
@@ -0,0 +1,808 @@
+#include "common.h"
+#include "pinctrl.h"
+
+/*
+ * Physical pin descriptors
+ *
+ * Pins identifiers use the GPIO numbering scheme. Names are assigned by
+ * concatenating all possible multiplexing functions a pin may be used with.
+ *
+ * Content was generated with the help of the genpin.sh script located into
+ * this directory.
+ */
+static struct pinctrl_pin_desc const p7_pin_descs_r1[] = {
+ P7CTL_INIT_PIN(0, "CAM_1_DATA02__GPIO_000__SPI_03b__CAM_3_VSa"),
+ P7CTL_INIT_PIN(1, "CAM_1_DATA03__GPIO_001__SPI_04b__CAM_3_HSa"),
+ P7CTL_INIT_PIN(2, "CAM_1_DATA04__GPIO_002__SPI_05b__CAM_4_VSa"),
+ P7CTL_INIT_PIN(3, "CAM_1_DATA05__GPIO_003__SPI_06b__CAM_4_HSa"),
+ P7CTL_INIT_PIN(4, "CAM_1_DATA06__GPIO_004__SPI_07b__CAM_5_VSa"),
+ P7CTL_INIT_PIN(5, "CAM_1_DATA07__GPIO_005__SPI_08b__CAM_5_HSa"),
+ P7CTL_INIT_PIN(6, "CAM_5_CLK__GPIO_006__SD_2_CLK"),
+ P7CTL_INIT_PIN(7, "CAM_5_DATA00__GPIO_007__SD_2_CMD"),
+ P7CTL_INIT_PIN(8, "CAM_5_DATA01__GPIO_008__SD_2_DAT00"),
+ P7CTL_INIT_PIN(9, "CAM_5_DATA02__GPIO_009__SD_2_DAT01"),
+ P7CTL_INIT_PIN(10, "CAM_5_DATA03__GPIO_010__SD_2_DAT02"),
+ P7CTL_INIT_PIN(11, "CAM_5_DATA04__GPIO_011__SD_2_DAT03"),
+ P7CTL_INIT_PIN(12, "CAM_5_DATA05__GPIO_012"),
+ P7CTL_INIT_PIN(13, "CAM_5_DATA06__GPIO_013"),
+ P7CTL_INIT_PIN(14, "CAM_5_DATA07__GPIO_014"),
+ P7CTL_INIT_PIN(15, "SD_1_CLK__GPIO_015__UART_5_TX"),
+ P7CTL_INIT_PIN(16, "SD_1_CMD__GPIO_016__UART_5_RX"),
+ P7CTL_INIT_PIN(17, "SD_1_DAT00__GPIO_017__UART_6_TX"),
+ P7CTL_INIT_PIN(18, "SD_1_DAT02__GPIO_018__UART_7_TX"),
+ P7CTL_INIT_PIN(19, "SD_1_DAT01__GPIO_019__UART_6_RX"),
+ P7CTL_INIT_PIN(20, "SD_1_DAT03__GPIO_020__UART_7_RX"),
+ P7CTL_INIT_PIN(21, "SD_0_CLK__GPIO_021"),
+ P7CTL_INIT_PIN(22, "SD_0_CMD__GPIO_022"),
+ P7CTL_INIT_PIN(23, "SD_0_DAT00__GPIO_023"),
+ P7CTL_INIT_PIN(24, "SD_0_DAT01__GPIO_024"),
+ P7CTL_INIT_PIN(25, "SD_0_DAT02__GPIO_025"),
+ P7CTL_INIT_PIN(26, "SD_0_DAT03__GPIO_026"),
+ P7CTL_INIT_PIN(27, "NAND_NCE__GPIO_027__SPI_00a"),
+ P7CTL_INIT_PIN(28, "NAND_NR__GPIO_028__SPI_01a"),
+ P7CTL_INIT_PIN(29, "NAND_NW__GPIO_029__SPI_02a"),
+ P7CTL_INIT_PIN(30, "NAND_AL__GPIO_030__SPI_03a"),
+ P7CTL_INIT_PIN(31, "NAND_CL__GPIO_031__SPI_04a"),
+ P7CTL_INIT_PIN(32, "NAND_RNB__GPIO_032__SPI_05a"),
+ P7CTL_INIT_PIN(33, "NAND_DQS__GPIO_033__CAN1_RXa"),
+ P7CTL_INIT_PIN(34, "NAND_DATA_00__GPIO_034__SPI_06a"),
+ P7CTL_INIT_PIN(35, "NAND_DATA_01__GPIO_035__SPI_07a"),
+ P7CTL_INIT_PIN(36, "NAND_DATA_02__GPIO_036__SPI_08a"),
+ P7CTL_INIT_PIN(37, "NAND_DATA_03__GPIO_037__SPI_09a"),
+ P7CTL_INIT_PIN(38, "NAND_DATA_04__GPIO_038"),
+ P7CTL_INIT_PIN(39, "NAND_DATA_05__GPIO_039"),
+ P7CTL_INIT_PIN(40, "NAND_DATA_06__GPIO_040"),
+ P7CTL_INIT_PIN(41, "NAND_DATA_07__GPIO_041"),
+ P7CTL_INIT_PIN(42, "NAND_WP__GPIO_042__CAN1_TXa"),
+ P7CTL_INIT_PIN(43, "FORCE_POWER_ON__GPIO_043"),
+ P7CTL_INIT_PIN(44, "TRST_N__GPIO_044"),
+ P7CTL_INIT_PIN(45, "TDI__GPIO_045"),
+ P7CTL_INIT_PIN(46, "TDO__GPIO_046"),
+ P7CTL_INIT_PIN(47, "TCK__GPIO_047"),
+ P7CTL_INIT_PIN(48, "TMS__GPIO_048"),
+ P7CTL_INIT_PIN(49, "GPIO_049"),
+ P7CTL_INIT_PIN(50, "GPIO_050"),
+ P7CTL_INIT_PIN(51, "UART_1_RX__GPIO_051"),
+ P7CTL_INIT_PIN(52, "UART_1_TX__GPIO_052"),
+ P7CTL_INIT_PIN(53, "UART_1_RTS__GPIO_053__CAN0_RXb"),
+ P7CTL_INIT_PIN(54, "UART_1_CTS__GPIO_054__CAN0_TXb"),
+ P7CTL_INIT_PIN(55, "UART_0_RX__GPIO_055"),
+ P7CTL_INIT_PIN(56, "UART_0_TX__GPIO_056"),
+ P7CTL_INIT_PIN(57, "UART_0_RTS__GPIO_057"),
+ P7CTL_INIT_PIN(58, "UART_0_CTS__GPIO_058"),
+ P7CTL_INIT_PIN(59, "I2C_2_DAT__GPIO_059__I2C_2_SL_DAT"),
+ P7CTL_INIT_PIN(60, "I2C_2_CLK__GPIO_060__I2C_2_SL_CLK"),
+ P7CTL_INIT_PIN(61, "I2C_1_DAT__GPIO_061__I2C_1_SL_DAT"),
+ P7CTL_INIT_PIN(62, "I2C_1_CLK__GPIO_062__I2C_1_SL_CLK"),
+ P7CTL_INIT_PIN(63, "I2C_0_DAT__GPIO_063__I2C_0_SL_DAT"),
+ P7CTL_INIT_PIN(64, "I2C_0_CLK__GPIO_064__I2C_0_SL_CLK"),
+ P7CTL_INIT_PIN(65, "UART_4_RX__GPIO_065"),
+ P7CTL_INIT_PIN(66, "UART_4_TX__GPIO_066"),
+ P7CTL_INIT_PIN(67, "UART_3_RX__GPIO_067"),
+ P7CTL_INIT_PIN(68, "UART_3_TX__GPIO_068"),
+ P7CTL_INIT_PIN(69, "UART_2_RX__GPIO_069__CAN1_TXb"),
+ P7CTL_INIT_PIN(70, "UART_2_TX__GPIO_070__CAN1_RXb"),
+ P7CTL_INIT_PIN(71, "SPI_09b__GPIO_071__PWM_15"),
+ P7CTL_INIT_PIN(72, "SPI_10b__GPIO_072"),
+ P7CTL_INIT_PIN(73, "SPI_11b__GPIO_073"),
+ P7CTL_INIT_PIN(74, "SPI_12b__GPIO_074"),
+ P7CTL_INIT_PIN(75, "SPI_13b__GPIO_075"),
+ P7CTL_INIT_PIN(76, "SPI_14b__GPIO_076"),
+ P7CTL_INIT_PIN(77, "SPI_00__GPIO_077__AAI_15__CAN1_TX"),
+ P7CTL_INIT_PIN(78, "SPI_01__GPIO_078__AAI_16__CAN1_RX"),
+ P7CTL_INIT_PIN(79, "SPI_02__GPIO_079__AAI_17__CAN0_TX"),
+ P7CTL_INIT_PIN(80, "SPI_03__GPIO_080__AAI_18__CAN0_RX"),
+ P7CTL_INIT_PIN(81, "SPI_04__GPIO_081__AAI_19"),
+ P7CTL_INIT_PIN(82, "SPI_05__GPIO_082__AAI_20"),
+ P7CTL_INIT_PIN(83, "SPI_06__GPIO_083__AAI_21"),
+ P7CTL_INIT_PIN(84, "SPI_07__GPIO_084__AAI_22"),
+ P7CTL_INIT_PIN(85, "SPI_08__GPIO_085__AAI_23"),
+ P7CTL_INIT_PIN(86, "SPI_09__GPIO_086__AAI_24"),
+ P7CTL_INIT_PIN(87, "SPI_10__GPIO_087__AAI_25"),
+ P7CTL_INIT_PIN(88, "SPI_11__GPIO_088__AAI_26"),
+ P7CTL_INIT_PIN(89, "SPI_12__GPIO_089__AAI_27"),
+ P7CTL_INIT_PIN(90, "SPI_13__GPIO_090__AAI_28"),
+ P7CTL_INIT_PIN(91, "SPI_14__GPIO_091__AAI_29"),
+ P7CTL_INIT_PIN(92, "SPI_15__GPIO_092__AAI_30"),
+ P7CTL_INIT_PIN(93, "P7MU_CLK_OUT__GPIO_093__PWM_15a"),
+ P7CTL_INIT_PIN(94, "REBOOT_P7MU__GPIO_094"),
+ P7CTL_INIT_PIN(95, "ULPI_0_DATA00__GPIO_095"),
+ P7CTL_INIT_PIN(96, "ULPI_0_DATA01__GPIO_096"),
+ P7CTL_INIT_PIN(97, "ULPI_0_DATA02__GPIO_097"),
+ P7CTL_INIT_PIN(98, "ULPI_0_DATA03__GPIO_098"),
+ P7CTL_INIT_PIN(99, "ULPI_0_DATA04__GPIO_099"),
+ P7CTL_INIT_PIN(100, "ULPI_0_DATA05__GPIO_100"),
+ P7CTL_INIT_PIN(101, "ULPI_0_DATA06__GPIO_101"),
+ P7CTL_INIT_PIN(102, "ULPI_0_DATA07__GPIO_102"),
+ P7CTL_INIT_PIN(103, "ULPI_0_NXT__GPIO_103"),
+ P7CTL_INIT_PIN(104, "ULPI_0_STP__GPIO_104"),
+ P7CTL_INIT_PIN(105, "ULPI_0_DIR__GPIO_105"),
+ P7CTL_INIT_PIN(106, "ULPI_0_CLK__GPIO_106"),
+ P7CTL_INIT_PIN(107, "ULPI_1_DATA00__GPIO_107__I2C_2_CLKa"),
+ P7CTL_INIT_PIN(108, "ULPI_1_DATA01__GPIO_108__I2C_2_DATa"),
+ P7CTL_INIT_PIN(109, "ULPI_1_DATA02__GPIO_109__I2C_2_CLKb"),
+ P7CTL_INIT_PIN(110, "ULPI_1_DATA03__GPIO_110__I2C_2_DATb"),
+ P7CTL_INIT_PIN(111, "ULPI_1_DATA04__GPIO_111__I2C_2_CLKc"),
+ P7CTL_INIT_PIN(112, "ULPI_1_DATA05__GPIO_112__I2C_2_DATc"),
+ P7CTL_INIT_PIN(113, "ULPI_1_DATA06__GPIO_113__I2C_2_CLKd"),
+ P7CTL_INIT_PIN(114, "ULPI_1_DATA07__GPIO_114__I2C_2_DATd"),
+ P7CTL_INIT_PIN(115, "ULPI_1_NXT__GPIO_115__I2C_2_CLKe"),
+ P7CTL_INIT_PIN(116, "ULPI_1_STP__GPIO_116__I2C_2_DATe"),
+ P7CTL_INIT_PIN(117, "ULPI_1_DIR__GPIO_117"),
+ P7CTL_INIT_PIN(118, "ULPI_1_CLK__GPIO_118"),
+ P7CTL_INIT_PIN(119, "AAI_00__GPIO_119__PWM_00"),
+ P7CTL_INIT_PIN(120, "AAI_01__GPIO_120__PWM_01"),
+ P7CTL_INIT_PIN(121, "AAI_02__GPIO_121__PWM_02"),
+ P7CTL_INIT_PIN(122, "AAI_03__GPIO_122__PWM_03"),
+ P7CTL_INIT_PIN(123, "AAI_04__GPIO_123__PWM_04"),
+ P7CTL_INIT_PIN(124, "AAI_05__GPIO_124__PWM_05"),
+ P7CTL_INIT_PIN(125, "AAI_06__GPIO_125__PWM_06"),
+ P7CTL_INIT_PIN(126, "AAI_07__GPIO_126__PWM_07"),
+ P7CTL_INIT_PIN(127, "AAI_08__GPIO_127__PWM_08"),
+ P7CTL_INIT_PIN(128, "AAI_09__GPIO_128__PWM_09"),
+ P7CTL_INIT_PIN(129, "AAI_10__GPIO_129__PWM_10"),
+ P7CTL_INIT_PIN(130, "AAI_11__GPIO_130__PWM_11"),
+ P7CTL_INIT_PIN(131, "AAI_12__GPIO_131__PWM_12"),
+ P7CTL_INIT_PIN(132, "AAI_13__GPIO_132__PWM_13"),
+ P7CTL_INIT_PIN(133, "AAI_14__GPIO_133__PWM_14"),
+ P7CTL_INIT_PIN(134, "LCD_0_DEN__GPIO_134__CAM_1_VS"),
+ P7CTL_INIT_PIN(135, "LCD_0_HS__GPIO_135__CAM_1_HS__LCD_0_DENa"),
+ P7CTL_INIT_PIN(136, "LCD_0_VS__GPIO_136__CAM_0_VS__PAR_NCS"),
+ P7CTL_INIT_PIN(137, "LCD_0_DATA00__GPIO_137__CAM_0_HS__PAR_NRS"),
+ P7CTL_INIT_PIN(138, "LCD_0_DATA01__GPIO_138__CAM_2_VS__PAR_NRD"),
+ P7CTL_INIT_PIN(139, "LCD_0_DATA02__GPIO_139__CAM_2_HS__PAR_NWR"),
+ P7CTL_INIT_PIN(140, "LCD_0_DATA03__GPIO_140__CAM_3_VS__PAR_D00"),
+ P7CTL_INIT_PIN(141, "LCD_0_DATA04__GPIO_141__CAM_3_HS__PAR_D01"),
+ P7CTL_INIT_PIN(142, "LCD_0_DATA05__GPIO_142__CAM_5_VS__PAR_D02"),
+ P7CTL_INIT_PIN(143, "LCD_0_DATA06__GPIO_143__CAM_5_HS__PAR_D03"),
+ P7CTL_INIT_PIN(144, "LCD_0_DATA07__GPIO_144__CAM_0_DATA08__PAR_D04"),
+ P7CTL_INIT_PIN(145, "LCD_0_DATA08__GPIO_145__CAM_0_DATA09__PAR_D05"),
+ P7CTL_INIT_PIN(146, "LCD_0_DATA09__GPIO_146__CAM_0_DATA10__PAR_D06"),
+ P7CTL_INIT_PIN(147, "LCD_0_DATA10__GPIO_147__CAM_0_DATA11__PAR_D07"),
+ P7CTL_INIT_PIN(148, "LCD_0_DATA11__GPIO_148__CAM_0_DATA12__PAR_D08"),
+ P7CTL_INIT_PIN(149, "LCD_0_DATA12__GPIO_149__CAM_0_DATA13__PAR_D09"),
+ P7CTL_INIT_PIN(150, "LCD_0_DATA13__GPIO_150__CAM_0_DATA14__PAR_D10"),
+ P7CTL_INIT_PIN(151, "LCD_0_DATA14__GPIO_151__CAM_0_DATA15__PAR_D11"),
+ P7CTL_INIT_PIN(152, "LCD_0_DATA15__GPIO_152__CAM_0_DATA16__PAR_D12"),
+ P7CTL_INIT_PIN(153, "LCD_0_DATA16__GPIO_153__CAM_0_DATA17__PAR_D13"),
+ P7CTL_INIT_PIN(154, "LCD_0_DATA17__GPIO_154__CAM_0_DATA18__PAR_D14"),
+ P7CTL_INIT_PIN(155, "LCD_0_DATA18__GPIO_155__CAM_0_DATA19__PAR_D15"),
+ P7CTL_INIT_PIN(156, "LCD_0_DATA19__GPIO_156__CAM_0_DATA20"),
+ P7CTL_INIT_PIN(157, "LCD_0_DATA20__GPIO_157__CAM_0_DATA21"),
+ P7CTL_INIT_PIN(158, "LCD_0_DATA21__GPIO_158__CAM_0_DATA22"),
+ P7CTL_INIT_PIN(159, "LCD_0_DATA22__GPIO_159__CAM_0_DATA23"),
+ P7CTL_INIT_PIN(160, "LCD_0_DATA23__GPIO_160__CAM_4_VS"),
+ P7CTL_INIT_PIN(161, "LCD_0_CLK__GPIO_161__CAM_4_HS"),
+ P7CTL_INIT_PIN(162, "LCD_1_HS__GPIO_162__CAM_2_CLK__LCD_1_DENa"),
+ P7CTL_INIT_PIN(163, "LCD_1_VS__GPIO_163__CAM_2_DATA00__CPU_TRACECLKOUT"),
+ P7CTL_INIT_PIN(164, "LCD_1_CLK__GPIO_164__CAM_2_DATA01__CPU_TRACECTL"),
+ P7CTL_INIT_PIN(165, "LCD_1_DATA00__GPIO_165__CAM_2_DATA02__CPU_TRACEDATA_00"),
+ P7CTL_INIT_PIN(166, "LCD_1_DATA01__GPIO_166__CAM_2_DATA03__CPU_TRACEDATA_01"),
+ P7CTL_INIT_PIN(167, "LCD_1_DATA02__GPIO_167__CAM_2_DATA04__CPU_TRACEDATA_02"),
+ P7CTL_INIT_PIN(168, "LCD_1_DATA03__GPIO_168__CAM_2_DATA05__CPU_TRACEDATA_03"),
+ P7CTL_INIT_PIN(169, "LCD_1_DATA04__GPIO_169__CAM_2_DATA06__CPU_TRACEDATA_04"),
+ P7CTL_INIT_PIN(170, "LCD_1_DATA05__GPIO_170__CAM_2_DATA07__CPU_TRACEDATA_05"),
+ P7CTL_INIT_PIN(171, "LCD_1_DATA06__GPIO_171__CAM_3_CLK__CPU_TRACEDATA_06"),
+ P7CTL_INIT_PIN(172, "LCD_1_DATA07__GPIO_172__CAM_3_DATA00__CPU_TRACEDATA_07"),
+ P7CTL_INIT_PIN(173, "LCD_1_DATA08__GPIO_173__CAM_3_DATA01__CPU_TRACEDATA_08"),
+ P7CTL_INIT_PIN(174, "LCD_1_DATA09__GPIO_174__CAM_3_DATA02__CPU_TRACEDATA_09"),
+ P7CTL_INIT_PIN(175, "LCD_1_DATA10__GPIO_175__CAM_3_DATA03__CPU_TRACEDATA_10"),
+ P7CTL_INIT_PIN(176, "LCD_1_DATA11__GPIO_176__CAM_3_DATA04__CPU_TRACEDATA_11"),
+ P7CTL_INIT_PIN(177, "LCD_1_DATA12__GPIO_177__CAM_3_DATA05__CPU_TRACEDATA_12"),
+ P7CTL_INIT_PIN(178, "LCD_1_DATA13__GPIO_178__CAM_3_DATA06__CPU_TRACEDATA_13"),
+ P7CTL_INIT_PIN(179, "LCD_1_DATA14__GPIO_179__CAM_3_DATA07__CPU_TRACEDATA_14"),
+ P7CTL_INIT_PIN(180, "LCD_1_DATA15__GPIO_180__CAM_4_CLK__CPU_TRACEDATA_15"),
+ P7CTL_INIT_PIN(181, "LCD_1_DATA16__GPIO_181__CAM_4_DATA00"),
+ P7CTL_INIT_PIN(182, "LCD_1_DATA17__GPIO_182__CAM_4_DATA01"),
+ P7CTL_INIT_PIN(183, "LCD_1_DATA18__GPIO_183__CAM_4_DATA02"),
+ P7CTL_INIT_PIN(184, "LCD_1_DATA19__GPIO_184__CAM_4_DATA03"),
+ P7CTL_INIT_PIN(185, "LCD_1_DATA20__GPIO_185__CAM_4_DATA04"),
+ P7CTL_INIT_PIN(186, "LCD_1_DATA21__GPIO_186__CAM_4_DATA05"),
+ P7CTL_INIT_PIN(187, "LCD_1_DATA22__GPIO_187__CAM_4_DATA06"),
+ P7CTL_INIT_PIN(188, "LCD_1_DATA23__GPIO_188__CAM_4_DATA07"),
+ P7CTL_INIT_PIN(189, "LCD_1_DEN__GPIO_189__CAM_1_HSa__LCD_1_CLKa"),
+ P7CTL_INIT_PIN(190, "CAM_0_CLK__GPIO_190"),
+ P7CTL_INIT_PIN(191, "CAM_0_DATA00__GPIO_191__CAM_1_DATA08"),
+ P7CTL_INIT_PIN(192, "CAM_0_DATA01__GPIO_192__CAM_1_DATA09"),
+ P7CTL_INIT_PIN(193, "CAM_0_DATA02__GPIO_193__CAM_1_DATA10"),
+ P7CTL_INIT_PIN(194, "CAM_0_DATA03__GPIO_194__CAM_1_DATA11"),
+ P7CTL_INIT_PIN(195, "CAM_0_DATA04__GPIO_195__CAM_1_DATA12"),
+ P7CTL_INIT_PIN(196, "CAM_0_DATA05__GPIO_196__CAM_1_DATA13"),
+ P7CTL_INIT_PIN(197, "CAM_0_DATA06__GPIO_197__CAM_1_DATA14"),
+ P7CTL_INIT_PIN(198, "CAM_0_DATA07__GPIO_198__CAM_1_DATA15"),
+ P7CTL_INIT_PIN(199, "CAM_1_CLK__GPIO_199__SPI_00b"),
+ P7CTL_INIT_PIN(200, "CAM_1_DATA00__GPIO_200__SPI_01b__CAM_0_VSa"),
+ P7CTL_INIT_PIN(201, "CAM_1_DATA01__GPIO_201__SPI_02b__CAM_0_HSa")
+};
+
+/*
+ * Multiplexing funcions
+ *
+ * Each physical pin may be used with up to 4 multiplexing functions.
+ *
+ * Content was generated with the help of the genpin.sh script located uinto
+ * this directory.
+ */
+static struct p7ctl_function const p7_pin_funcs_r1[P7_N_FUNCTIONS] = {
+ [P7_CAM_1_DATA02] = P7CTL_INIT_FUNC(CAM_1_DATA02, 0, 0),
+ [P7_GPIO_000] = P7CTL_INIT_FUNC(GPIO_000, 0, 1),
+ [P7_SPI_03b] = P7CTL_INIT_FUNC(SPI_03b, 0, 2),
+ [P7_CAM_3_VSa] = P7CTL_INIT_FUNC(CAM_3_VSa, 0, 3),
+ [P7_CAM_1_DATA03] = P7CTL_INIT_FUNC(CAM_1_DATA03, 1, 0),
+ [P7_GPIO_001] = P7CTL_INIT_FUNC(GPIO_001, 1, 1),
+ [P7_SPI_04b] = P7CTL_INIT_FUNC(SPI_04b, 1, 2),
+ [P7_CAM_3_HSa] = P7CTL_INIT_FUNC(CAM_3_HSa, 1, 3),
+ [P7_CAM_1_DATA04] = P7CTL_INIT_FUNC(CAM_1_DATA04, 2, 0),
+ [P7_GPIO_002] = P7CTL_INIT_FUNC(GPIO_002, 2, 1),
+ [P7_SPI_05b] = P7CTL_INIT_FUNC(SPI_05b, 2, 2),
+ [P7_CAM_4_VSa] = P7CTL_INIT_FUNC(CAM_4_VSa, 2, 3),
+ [P7_CAM_1_DATA05] = P7CTL_INIT_FUNC(CAM_1_DATA05, 3, 0),
+ [P7_GPIO_003] = P7CTL_INIT_FUNC(GPIO_003, 3, 1),
+ [P7_SPI_06b] = P7CTL_INIT_FUNC(SPI_06b, 3, 2),
+ [P7_CAM_4_HSa] = P7CTL_INIT_FUNC(CAM_4_HSa, 3, 3),
+ [P7_CAM_1_DATA06] = P7CTL_INIT_FUNC(CAM_1_DATA06, 4, 0),
+ [P7_GPIO_004] = P7CTL_INIT_FUNC(GPIO_004, 4, 1),
+ [P7_SPI_07b] = P7CTL_INIT_FUNC(SPI_07b, 4, 2),
+ [P7_CAM_5_VSa] = P7CTL_INIT_FUNC(CAM_5_VSa, 4, 3),
+ [P7_CAM_1_DATA07] = P7CTL_INIT_FUNC(CAM_1_DATA07, 5, 0),
+ [P7_GPIO_005] = P7CTL_INIT_FUNC(GPIO_005, 5, 1),
+ [P7_SPI_08b] = P7CTL_INIT_FUNC(SPI_08b, 5, 2),
+ [P7_CAM_5_HSa] = P7CTL_INIT_FUNC(CAM_5_HSa, 5, 3),
+ [P7_CAM_5_CLK] = P7CTL_INIT_FUNC(CAM_5_CLK, 6, 0),
+ [P7_GPIO_006] = P7CTL_INIT_FUNC(GPIO_006, 6, 1),
+ [P7_SD_2_CLK] = P7CTL_INIT_FUNC(SD_2_CLK, 6, 2),
+ [P7_CAM_5_DATA00] = P7CTL_INIT_FUNC(CAM_5_DATA00, 7, 0),
+ [P7_GPIO_007] = P7CTL_INIT_FUNC(GPIO_007, 7, 1),
+ [P7_SD_2_CMD] = P7CTL_INIT_FUNC(SD_2_CMD, 7, 2),
+ [P7_CAM_5_DATA01] = P7CTL_INIT_FUNC(CAM_5_DATA01, 8, 0),
+ [P7_GPIO_008] = P7CTL_INIT_FUNC(GPIO_008, 8, 1),
+ [P7_SD_2_DAT00] = P7CTL_INIT_FUNC(SD_2_DAT00, 8, 2),
+ [P7_CAM_5_DATA02] = P7CTL_INIT_FUNC(CAM_5_DATA02, 9, 0),
+ [P7_GPIO_009] = P7CTL_INIT_FUNC(GPIO_009, 9, 1),
+ [P7_SD_2_DAT01] = P7CTL_INIT_FUNC(SD_2_DAT01, 9, 2),
+ [P7_CAM_5_DATA03] = P7CTL_INIT_FUNC(CAM_5_DATA03, 10, 0),
+ [P7_GPIO_010] = P7CTL_INIT_FUNC(GPIO_010, 10, 1),
+ [P7_SD_2_DAT02] = P7CTL_INIT_FUNC(SD_2_DAT02, 10, 2),
+ [P7_CAM_5_DATA04] = P7CTL_INIT_FUNC(CAM_5_DATA04, 11, 0),
+ [P7_GPIO_011] = P7CTL_INIT_FUNC(GPIO_011, 11, 1),
+ [P7_SD_2_DAT03] = P7CTL_INIT_FUNC(SD_2_DAT03, 11, 2),
+ [P7_CAM_5_DATA05] = P7CTL_INIT_FUNC(CAM_5_DATA05, 12, 0),
+ [P7_GPIO_012] = P7CTL_INIT_FUNC(GPIO_012, 12, 1),
+ [P7_CAM_5_DATA06] = P7CTL_INIT_FUNC(CAM_5_DATA06, 13, 0),
+ [P7_GPIO_013] = P7CTL_INIT_FUNC(GPIO_013, 13, 1),
+ [P7_CAM_5_DATA07] = P7CTL_INIT_FUNC(CAM_5_DATA07, 14, 0),
+ [P7_GPIO_014] = P7CTL_INIT_FUNC(GPIO_014, 14, 1),
+ [P7_SD_1_CLK] = P7CTL_INIT_FUNC(SD_1_CLK, 15, 0),
+ [P7_UART_5_TX] = P7CTL_INIT_FUNC(UART_5_TX, 15, 2),
+ [P7_SD_1_CMD] = P7CTL_INIT_FUNC(SD_1_CMD, 16, 0),
+ [P7_UART_5_RX] = P7CTL_INIT_FUNC(UART_5_RX, 16, 2),
+ [P7_SD_1_DAT00] = P7CTL_INIT_FUNC(SD_1_DAT00, 17, 0),
+ [P7_UART_6_TX] = P7CTL_INIT_FUNC(UART_6_TX, 17, 2),
+ [P7_SD_1_DAT02] = P7CTL_INIT_FUNC(SD_1_DAT02, 18, 0),
+ [P7_UART_7_TX] = P7CTL_INIT_FUNC(UART_7_TX, 18, 2),
+ [P7_SD_1_DAT01] = P7CTL_INIT_FUNC(SD_1_DAT01, 19, 0),
+ [P7_UART_6_RX] = P7CTL_INIT_FUNC(UART_6_RX, 19, 2),
+ [P7_SD_1_DAT03] = P7CTL_INIT_FUNC(SD_1_DAT03, 20, 0),
+ [P7_UART_7_RX] = P7CTL_INIT_FUNC(UART_7_RX, 20, 2),
+ [P7_SD_0_CLK] = P7CTL_INIT_FUNC(SD_0_CLK, 21, 0),
+ [P7_SD_0_CMD] = P7CTL_INIT_FUNC(SD_0_CMD, 22, 0),
+ [P7_SD_0_DAT00] = P7CTL_INIT_FUNC(SD_0_DAT00, 23, 0),
+ [P7_SD_0_DAT01] = P7CTL_INIT_FUNC(SD_0_DAT01, 24, 0),
+ [P7_SD_0_DAT02] = P7CTL_INIT_FUNC(SD_0_DAT02, 25, 0),
+ [P7_SD_0_DAT03] = P7CTL_INIT_FUNC(SD_0_DAT03, 26, 0),
+ [P7_NAND_NCE] = P7CTL_INIT_FUNC(NAND_NCE, 27, 0),
+ [P7_SPI_00a] = P7CTL_INIT_FUNC(SPI_00a, 27, 2),
+ [P7_NAND_NR] = P7CTL_INIT_FUNC(NAND_NR, 28, 0),
+ [P7_SPI_01a] = P7CTL_INIT_FUNC(SPI_01a, 28, 2),
+ [P7_NAND_NW] = P7CTL_INIT_FUNC(NAND_NW, 29, 0),
+ [P7_SPI_02a] = P7CTL_INIT_FUNC(SPI_02a, 29, 2),
+ [P7_NAND_AL] = P7CTL_INIT_FUNC(NAND_AL, 30, 0),
+ [P7_SPI_03a] = P7CTL_INIT_FUNC(SPI_03a, 30, 2),
+ [P7_NAND_CL] = P7CTL_INIT_FUNC(NAND_CL, 31, 0),
+ [P7_SPI_04a] = P7CTL_INIT_FUNC(SPI_04a, 31, 2),
+ [P7_NAND_RNB] = P7CTL_INIT_FUNC(NAND_RNB, 32, 0),
+ [P7_SPI_05a] = P7CTL_INIT_FUNC(SPI_05a, 32, 2),
+ [P7_NAND_DQS] = P7CTL_INIT_FUNC(NAND_DQS, 33, 0),
+ [P7_GPIO_033] = P7CTL_INIT_FUNC(GPIO_033, 33, 1),
+ [P7_CAN1_RXa] = P7CTL_INIT_FUNC(CAN1_RXa, 33, 2),
+ [P7_NAND_DATA_00] = P7CTL_INIT_FUNC(NAND_DATA_00, 34, 0),
+ [P7_SPI_06a] = P7CTL_INIT_FUNC(SPI_06a, 34, 2),
+ [P7_NAND_DATA_01] = P7CTL_INIT_FUNC(NAND_DATA_01, 35, 0),
+ [P7_SPI_07a] = P7CTL_INIT_FUNC(SPI_07a, 35, 2),
+ [P7_NAND_DATA_02] = P7CTL_INIT_FUNC(NAND_DATA_02, 36, 0),
+ [P7_SPI_08a] = P7CTL_INIT_FUNC(SPI_08a, 36, 2),
+ [P7_NAND_DATA_03] = P7CTL_INIT_FUNC(NAND_DATA_03, 37, 0),
+ [P7_SPI_09a] = P7CTL_INIT_FUNC(SPI_09a, 37, 2),
+ [P7_NAND_DATA_04] = P7CTL_INIT_FUNC(NAND_DATA_04, 38, 0),
+ [P7_GPIO_038] = P7CTL_INIT_FUNC(GPIO_038, 38, 1),
+ [P7_NAND_DATA_05] = P7CTL_INIT_FUNC(NAND_DATA_05, 39, 0),
+ [P7_GPIO_039] = P7CTL_INIT_FUNC(GPIO_039, 39, 1),
+ [P7_NAND_DATA_06] = P7CTL_INIT_FUNC(NAND_DATA_06, 40, 0),
+ [P7_GPIO_040] = P7CTL_INIT_FUNC(GPIO_040, 40, 1),
+ [P7_NAND_DATA_07] = P7CTL_INIT_FUNC(NAND_DATA_07, 41, 0),
+ [P7_GPIO_041] = P7CTL_INIT_FUNC(GPIO_041, 41, 1),
+ [P7_NAND_WP] = P7CTL_INIT_FUNC(NAND_WP, 42, 0),
+ [P7_GPIO_042] = P7CTL_INIT_FUNC(GPIO_042, 42, 1),
+ [P7_CAN1_TXa] = P7CTL_INIT_FUNC(CAN1_TXa, 42, 2),
+ [P7_FORCE_POWER_ON] = P7CTL_INIT_FUNC(FORCE_POWER_ON, 43, 0),
+ [P7_TRST_N] = P7CTL_INIT_FUNC(TRST_N, 44, 0),
+ [P7_TDI] = P7CTL_INIT_FUNC(TDI, 45, 0),
+ [P7_TDO] = P7CTL_INIT_FUNC(TDO, 46, 0),
+ [P7_TCK] = P7CTL_INIT_FUNC(TCK, 47, 0),
+ [P7_TMS] = P7CTL_INIT_FUNC(TMS, 48, 0),
+ [P7_GPIO_049] = P7CTL_INIT_FUNC(GPIO_049, 49, 1),
+ [P7_GPIO_050] = P7CTL_INIT_FUNC(GPIO_050, 50, 1),
+ [P7_UART_1_RX] = P7CTL_INIT_FUNC(UART_1_RX, 51, 0),
+ [P7_UART_1_TX] = P7CTL_INIT_FUNC(UART_1_TX, 52, 0),
+ [P7_UART_1_RTS] = P7CTL_INIT_FUNC(UART_1_RTS, 53, 0),
+ [P7_CAN0_RXb] = P7CTL_INIT_FUNC(CAN0_RXb, 53, 2),
+ [P7_UART_1_CTS] = P7CTL_INIT_FUNC(UART_1_CTS, 54, 0),
+ [P7_CAN0_TXb] = P7CTL_INIT_FUNC(CAN0_TXb, 54, 2),
+ [P7_UART_0_RX] = P7CTL_INIT_FUNC(UART_0_RX, 55, 0),
+ [P7_UART_0_TX] = P7CTL_INIT_FUNC(UART_0_TX, 56, 0),
+ [P7_UART_0_RTS] = P7CTL_INIT_FUNC(UART_0_RTS, 57, 0),
+ [P7_UART_0_CTS] = P7CTL_INIT_FUNC(UART_0_CTS, 58, 0),
+ [P7_I2C_2_DAT] = P7CTL_INIT_FUNC(I2C_2_DAT, 59, 0),
+ [P7_GPIO_059] = P7CTL_INIT_FUNC(GPIO_059, 59, 1),
+ [P7_I2C_2_SL_DAT] = P7CTL_INIT_FUNC(I2C_2_SL_DAT, 59, 2),
+ [P7_I2C_2_CLK] = P7CTL_INIT_FUNC(I2C_2_CLK, 60, 0),
+ [P7_GPIO_060] = P7CTL_INIT_FUNC(GPIO_060, 60, 1),
+ [P7_I2C_2_SL_CLK] = P7CTL_INIT_FUNC(I2C_2_SL_CLK, 60, 2),
+ [P7_I2C_1_DAT] = P7CTL_INIT_FUNC(I2C_1_DAT, 61, 0),
+ [P7_GPIO_061] = P7CTL_INIT_FUNC(GPIO_061, 61, 1),
+ [P7_I2C_1_SL_DAT] = P7CTL_INIT_FUNC(I2C_1_SL_DAT, 61, 2),
+ [P7_I2C_1_CLK] = P7CTL_INIT_FUNC(I2C_1_CLK, 62, 0),
+ [P7_GPIO_062] = P7CTL_INIT_FUNC(GPIO_062, 62, 1),
+ [P7_I2C_1_SL_CLK] = P7CTL_INIT_FUNC(I2C_1_SL_CLK, 62, 2),
+ [P7_I2C_0_DAT] = P7CTL_INIT_FUNC(I2C_0_DAT, 63, 0),
+ [P7_GPIO_063] = P7CTL_INIT_FUNC(GPIO_063, 63, 1),
+ [P7_I2C_0_SL_DAT] = P7CTL_INIT_FUNC(I2C_0_SL_DAT, 63, 2),
+ [P7_I2C_0_CLK] = P7CTL_INIT_FUNC(I2C_0_CLK, 64, 0),
+ [P7_GPIO_064] = P7CTL_INIT_FUNC(GPIO_064, 64, 1),
+ [P7_I2C_0_SL_CLK] = P7CTL_INIT_FUNC(I2C_0_SL_CLK, 64, 2),
+ [P7_UART_4_RX] = P7CTL_INIT_FUNC(UART_4_RX, 65, 0),
+ [P7_GPIO_065] = P7CTL_INIT_FUNC(GPIO_065, 65, 1),
+ [P7_UART_4_TX] = P7CTL_INIT_FUNC(UART_4_TX, 66, 0),
+ [P7_GPIO_066] = P7CTL_INIT_FUNC(GPIO_066, 66, 1),
+ [P7_UART_3_RX] = P7CTL_INIT_FUNC(UART_3_RX, 67, 0),
+ [P7_GPIO_067] = P7CTL_INIT_FUNC(GPIO_067, 67, 1),
+ [P7_UART_3_TX] = P7CTL_INIT_FUNC(UART_3_TX, 68, 0),
+ [P7_GPIO_068] = P7CTL_INIT_FUNC(GPIO_068, 68, 1),
+ [P7_UART_2_RX] = P7CTL_INIT_FUNC(UART_2_RX, 69, 0),
+ [P7_CAN1_TXb] = P7CTL_INIT_FUNC(CAN1_TXb, 69, 2),
+ [P7_UART_2_TX] = P7CTL_INIT_FUNC(UART_2_TX, 70, 0),
+ [P7_CAN1_RXb] = P7CTL_INIT_FUNC(CAN1_RXb, 70, 2),
+ [P7_SPI_09b] = P7CTL_INIT_FUNC(SPI_09b, 71, 0),
+ [P7_GPIO_071] = P7CTL_INIT_FUNC(GPIO_071, 71, 1),
+ [P7_PWM_15] = P7CTL_INIT_FUNC(PWM_15, 71, 2),
+ [P7_SPI_10b] = P7CTL_INIT_FUNC(SPI_10b, 72, 0),
+ [P7_GPIO_072] = P7CTL_INIT_FUNC(GPIO_072, 72, 1),
+ [P7_SPI_11b] = P7CTL_INIT_FUNC(SPI_11b, 73, 0),
+ [P7_GPIO_073] = P7CTL_INIT_FUNC(GPIO_073, 73, 1),
+ [P7_SPI_12b] = P7CTL_INIT_FUNC(SPI_12b, 74, 0),
+ [P7_GPIO_074] = P7CTL_INIT_FUNC(GPIO_074, 74, 1),
+ [P7_SPI_13b] = P7CTL_INIT_FUNC(SPI_13b, 75, 0),
+ [P7_GPIO_075] = P7CTL_INIT_FUNC(GPIO_075, 75, 1),
+ [P7_SPI_14b] = P7CTL_INIT_FUNC(SPI_14b, 76, 0),
+ [P7_GPIO_076] = P7CTL_INIT_FUNC(GPIO_076, 76, 1),
+ [P7_SPI_00] = P7CTL_INIT_FUNC(SPI_00, 77, 0),
+ [P7_GPIO_077] = P7CTL_INIT_FUNC(GPIO_077, 77, 1),
+ [P7_AAI_15] = P7CTL_INIT_FUNC(AAI_15, 77, 2),
+ [P7_CAN1_TX] = P7CTL_INIT_FUNC(CAN1_TX, 77, 3),
+ [P7_SPI_01] = P7CTL_INIT_FUNC(SPI_01, 78, 0),
+ [P7_GPIO_078] = P7CTL_INIT_FUNC(GPIO_078, 78, 1),
+ [P7_AAI_16] = P7CTL_INIT_FUNC(AAI_16, 78, 2),
+ [P7_CAN1_RX] = P7CTL_INIT_FUNC(CAN1_RX, 78, 3),
+ [P7_SPI_02] = P7CTL_INIT_FUNC(SPI_02, 79, 0),
+ [P7_GPIO_079] = P7CTL_INIT_FUNC(GPIO_079, 79, 1),
+ [P7_AAI_17] = P7CTL_INIT_FUNC(AAI_17, 79, 2),
+ [P7_CAN0_TX] = P7CTL_INIT_FUNC(CAN0_TX, 79, 3),
+ [P7_SPI_03] = P7CTL_INIT_FUNC(SPI_03, 80, 0),
+ [P7_GPIO_080] = P7CTL_INIT_FUNC(GPIO_080, 80, 1),
+ [P7_AAI_18] = P7CTL_INIT_FUNC(AAI_18, 80, 2),
+ [P7_CAN0_RX] = P7CTL_INIT_FUNC(CAN0_RX, 80, 3),
+ [P7_SPI_04] = P7CTL_INIT_FUNC(SPI_04, 81, 0),
+ [P7_GPIO_081] = P7CTL_INIT_FUNC(GPIO_081, 81, 1),
+ [P7_AAI_19] = P7CTL_INIT_FUNC(AAI_19, 81, 2),
+ [P7_SPI_05] = P7CTL_INIT_FUNC(SPI_05, 82, 0),
+ [P7_GPIO_082] = P7CTL_INIT_FUNC(GPIO_082, 82, 1),
+ [P7_AAI_20] = P7CTL_INIT_FUNC(AAI_20, 82, 2),
+ [P7_SPI_06] = P7CTL_INIT_FUNC(SPI_06, 83, 0),
+ [P7_GPIO_083] = P7CTL_INIT_FUNC(GPIO_083, 83, 1),
+ [P7_AAI_21] = P7CTL_INIT_FUNC(AAI_21, 83, 2),
+ [P7_SPI_07] = P7CTL_INIT_FUNC(SPI_07, 84, 0),
+ [P7_GPIO_084] = P7CTL_INIT_FUNC(GPIO_084, 84, 1),
+ [P7_AAI_22] = P7CTL_INIT_FUNC(AAI_22, 84, 2),
+ [P7_SPI_08] = P7CTL_INIT_FUNC(SPI_08, 85, 0),
+ [P7_GPIO_085] = P7CTL_INIT_FUNC(GPIO_085, 85, 1),
+ [P7_AAI_23] = P7CTL_INIT_FUNC(AAI_23, 85, 2),
+ [P7_SPI_09] = P7CTL_INIT_FUNC(SPI_09, 86, 0),
+ [P7_GPIO_086] = P7CTL_INIT_FUNC(GPIO_086, 86, 1),
+ [P7_AAI_24] = P7CTL_INIT_FUNC(AAI_24, 86, 2),
+ [P7_SPI_10] = P7CTL_INIT_FUNC(SPI_10, 87, 0),
+ [P7_GPIO_087] = P7CTL_INIT_FUNC(GPIO_087, 87, 1),
+ [P7_AAI_25] = P7CTL_INIT_FUNC(AAI_25, 87, 2),
+ [P7_SPI_11] = P7CTL_INIT_FUNC(SPI_11, 88, 0),
+ [P7_GPIO_088] = P7CTL_INIT_FUNC(GPIO_088, 88, 1),
+ [P7_AAI_26] = P7CTL_INIT_FUNC(AAI_26, 88, 2),
+ [P7_SPI_12] = P7CTL_INIT_FUNC(SPI_12, 89, 0),
+ [P7_GPIO_089] = P7CTL_INIT_FUNC(GPIO_089, 89, 1),
+ [P7_AAI_27] = P7CTL_INIT_FUNC(AAI_27, 89, 2),
+ [P7_SPI_13] = P7CTL_INIT_FUNC(SPI_13, 90, 0),
+ [P7_GPIO_090] = P7CTL_INIT_FUNC(GPIO_090, 90, 1),
+ [P7_AAI_28] = P7CTL_INIT_FUNC(AAI_28, 90, 2),
+ [P7_SPI_14] = P7CTL_INIT_FUNC(SPI_14, 91, 0),
+ [P7_GPIO_091] = P7CTL_INIT_FUNC(GPIO_091, 91, 1),
+ [P7_AAI_29] = P7CTL_INIT_FUNC(AAI_29, 91, 2),
+ [P7_SPI_15] = P7CTL_INIT_FUNC(SPI_15, 92, 0),
+ [P7_GPIO_092] = P7CTL_INIT_FUNC(GPIO_092, 92, 1),
+ [P7_AAI_30] = P7CTL_INIT_FUNC(AAI_30, 92, 2),
+ [P7_P7MU_CLK_OUT] = P7CTL_INIT_FUNC(P7MU_CLK_OUT, 93, 0),
+ [P7_PWM_15a] = P7CTL_INIT_FUNC(PWM_15a, 93, 2),
+ [P7_REBOOT_P7MU] = P7CTL_INIT_FUNC(REBOOT_P7MU, 94, 0),
+ [P7_GPIO_094] = P7CTL_INIT_FUNC(GPIO_094, 94, 1),
+ [P7_ULPI_0_DATA00] = P7CTL_INIT_FUNC(ULPI_0_DATA00, 95, 0),
+ [P7_ULPI_0_DATA01] = P7CTL_INIT_FUNC(ULPI_0_DATA01, 96, 0),
+ [P7_ULPI_0_DATA02] = P7CTL_INIT_FUNC(ULPI_0_DATA02, 97, 0),
+ [P7_ULPI_0_DATA03] = P7CTL_INIT_FUNC(ULPI_0_DATA03, 98, 0),
+ [P7_ULPI_0_DATA04] = P7CTL_INIT_FUNC(ULPI_0_DATA04, 99, 0),
+ [P7_ULPI_0_DATA05] = P7CTL_INIT_FUNC(ULPI_0_DATA05, 100, 0),
+ [P7_ULPI_0_DATA06] = P7CTL_INIT_FUNC(ULPI_0_DATA06, 101, 0),
+ [P7_ULPI_0_DATA07] = P7CTL_INIT_FUNC(ULPI_0_DATA07, 102, 0),
+ [P7_ULPI_0_NXT] = P7CTL_INIT_FUNC(ULPI_0_NXT, 103, 0),
+ [P7_ULPI_0_STP] = P7CTL_INIT_FUNC(ULPI_0_STP, 104, 0),
+ [P7_ULPI_0_DIR] = P7CTL_INIT_FUNC(ULPI_0_DIR, 105, 0),
+ [P7_ULPI_0_CLK] = P7CTL_INIT_FUNC(ULPI_0_CLK, 106, 0),
+ [P7_ULPI_1_DATA00] = P7CTL_INIT_FUNC(ULPI_1_DATA00, 107, 0),
+ [P7_GPIO_107] = P7CTL_INIT_FUNC(GPIO_107, 107, 1),
+ [P7_I2C_2_CLKa] = P7CTL_INIT_FUNC(I2C_2_CLKa, 107, 2),
+ [P7_ULPI_1_DATA01] = P7CTL_INIT_FUNC(ULPI_1_DATA01, 108, 0),
+ [P7_GPIO_108] = P7CTL_INIT_FUNC(GPIO_108, 108, 1),
+ [P7_I2C_2_DATa] = P7CTL_INIT_FUNC(I2C_2_DATa, 108, 2),
+ [P7_ULPI_1_DATA02] = P7CTL_INIT_FUNC(ULPI_1_DATA02, 109, 0),
+ [P7_GPIO_109] = P7CTL_INIT_FUNC(GPIO_109, 109, 1),
+ [P7_I2C_2_CLKb] = P7CTL_INIT_FUNC(I2C_2_CLKb, 109, 2),
+ [P7_ULPI_1_DATA03] = P7CTL_INIT_FUNC(ULPI_1_DATA03, 110, 0),
+ [P7_GPIO_110] = P7CTL_INIT_FUNC(GPIO_110, 110, 1),
+ [P7_I2C_2_DATb] = P7CTL_INIT_FUNC(I2C_2_DATb, 110, 2),
+ [P7_ULPI_1_DATA04] = P7CTL_INIT_FUNC(ULPI_1_DATA04, 111, 0),
+ [P7_GPIO_111] = P7CTL_INIT_FUNC(GPIO_111, 111, 1),
+ [P7_I2C_2_CLKc] = P7CTL_INIT_FUNC(I2C_2_CLKc, 111, 2),
+ [P7_ULPI_1_DATA05] = P7CTL_INIT_FUNC(ULPI_1_DATA05, 112, 0),
+ [P7_GPIO_112] = P7CTL_INIT_FUNC(GPIO_112, 112, 1),
+ [P7_I2C_2_DATc] = P7CTL_INIT_FUNC(I2C_2_DATc, 112, 2),
+ [P7_ULPI_1_DATA06] = P7CTL_INIT_FUNC(ULPI_1_DATA06, 113, 0),
+ [P7_GPIO_113] = P7CTL_INIT_FUNC(GPIO_113, 113, 1),
+ [P7_I2C_2_CLKd] = P7CTL_INIT_FUNC(I2C_2_CLKd, 113, 2),
+ [P7_ULPI_1_DATA07] = P7CTL_INIT_FUNC(ULPI_1_DATA07, 114, 0),
+ [P7_GPIO_114] = P7CTL_INIT_FUNC(GPIO_114, 114, 1),
+ [P7_I2C_2_DATd] = P7CTL_INIT_FUNC(I2C_2_DATd, 114, 2),
+ [P7_ULPI_1_NXT] = P7CTL_INIT_FUNC(ULPI_1_NXT, 115, 0),
+ [P7_GPIO_115] = P7CTL_INIT_FUNC(GPIO_115, 115, 1),
+ [P7_I2C_2_CLKe] = P7CTL_INIT_FUNC(I2C_2_CLKe, 115, 2),
+ [P7_ULPI_1_STP] = P7CTL_INIT_FUNC(ULPI_1_STP, 116, 0),
+ [P7_GPIO_116] = P7CTL_INIT_FUNC(GPIO_116, 116, 1),
+ [P7_I2C_2_DATe] = P7CTL_INIT_FUNC(I2C_2_DATe, 116, 2),
+ [P7_ULPI_1_DIR] = P7CTL_INIT_FUNC(ULPI_1_DIR, 117, 0),
+ [P7_GPIO_117] = P7CTL_INIT_FUNC(GPIO_117, 117, 1),
+ [P7_ULPI_1_CLK] = P7CTL_INIT_FUNC(ULPI_1_CLK, 118, 0),
+ [P7_GPIO_118] = P7CTL_INIT_FUNC(GPIO_118, 118, 1),
+ [P7_AAI_00] = P7CTL_INIT_FUNC(AAI_00, 119, 0),
+ [P7_GPIO_119] = P7CTL_INIT_FUNC(GPIO_119, 119, 1),
+ [P7_PWM_00] = P7CTL_INIT_FUNC(PWM_00, 119, 2),
+ [P7_AAI_01] = P7CTL_INIT_FUNC(AAI_01, 120, 0),
+ [P7_GPIO_120] = P7CTL_INIT_FUNC(GPIO_120, 120, 1),
+ [P7_PWM_01] = P7CTL_INIT_FUNC(PWM_01, 120, 2),
+ [P7_AAI_02] = P7CTL_INIT_FUNC(AAI_02, 121, 0),
+ [P7_GPIO_121] = P7CTL_INIT_FUNC(GPIO_121, 121, 1),
+ [P7_PWM_02] = P7CTL_INIT_FUNC(PWM_02, 121, 2),
+ [P7_AAI_03] = P7CTL_INIT_FUNC(AAI_03, 122, 0),
+ [P7_GPIO_122] = P7CTL_INIT_FUNC(GPIO_122, 122, 1),
+ [P7_PWM_03] = P7CTL_INIT_FUNC(PWM_03, 122, 2),
+ [P7_AAI_04] = P7CTL_INIT_FUNC(AAI_04, 123, 0),
+ [P7_GPIO_123] = P7CTL_INIT_FUNC(GPIO_123, 123, 1),
+ [P7_PWM_04] = P7CTL_INIT_FUNC(PWM_04, 123, 2),
+ [P7_AAI_05] = P7CTL_INIT_FUNC(AAI_05, 124, 0),
+ [P7_GPIO_124] = P7CTL_INIT_FUNC(GPIO_124, 124, 1),
+ [P7_PWM_05] = P7CTL_INIT_FUNC(PWM_05, 124, 2),
+ [P7_AAI_06] = P7CTL_INIT_FUNC(AAI_06, 125, 0),
+ [P7_GPIO_125] = P7CTL_INIT_FUNC(GPIO_125, 125, 1),
+ [P7_PWM_06] = P7CTL_INIT_FUNC(PWM_06, 125, 2),
+ [P7_AAI_07] = P7CTL_INIT_FUNC(AAI_07, 126, 0),
+ [P7_GPIO_126] = P7CTL_INIT_FUNC(GPIO_126, 126, 1),
+ [P7_PWM_07] = P7CTL_INIT_FUNC(PWM_07, 126, 2),
+ [P7_AAI_08] = P7CTL_INIT_FUNC(AAI_08, 127, 0),
+ [P7_GPIO_127] = P7CTL_INIT_FUNC(GPIO_127, 127, 1),
+ [P7_PWM_08] = P7CTL_INIT_FUNC(PWM_08, 127, 2),
+ [P7_AAI_09] = P7CTL_INIT_FUNC(AAI_09, 128, 0),
+ [P7_GPIO_128] = P7CTL_INIT_FUNC(GPIO_128, 128, 1),
+ [P7_PWM_09] = P7CTL_INIT_FUNC(PWM_09, 128, 2),
+ [P7_AAI_10] = P7CTL_INIT_FUNC(AAI_10, 129, 0),
+ [P7_GPIO_129] = P7CTL_INIT_FUNC(GPIO_129, 129, 1),
+ [P7_PWM_10] = P7CTL_INIT_FUNC(PWM_10, 129, 2),
+ [P7_AAI_11] = P7CTL_INIT_FUNC(AAI_11, 130, 0),
+ [P7_GPIO_130] = P7CTL_INIT_FUNC(GPIO_130, 130, 1),
+ [P7_PWM_11] = P7CTL_INIT_FUNC(PWM_11, 130, 2),
+ [P7_AAI_12] = P7CTL_INIT_FUNC(AAI_12, 131, 0),
+ [P7_GPIO_131] = P7CTL_INIT_FUNC(GPIO_131, 131, 1),
+ [P7_PWM_12] = P7CTL_INIT_FUNC(PWM_12, 131, 2),
+ [P7_AAI_13] = P7CTL_INIT_FUNC(AAI_13, 132, 0),
+ [P7_GPIO_132] = P7CTL_INIT_FUNC(GPIO_132, 132, 1),
+ [P7_PWM_13] = P7CTL_INIT_FUNC(PWM_13, 132, 2),
+ [P7_AAI_14] = P7CTL_INIT_FUNC(AAI_14, 133, 0),
+ [P7_GPIO_133] = P7CTL_INIT_FUNC(GPIO_133, 133, 1),
+ [P7_PWM_14] = P7CTL_INIT_FUNC(PWM_14, 133, 2),
+ [P7_LCD_0_DEN] = P7CTL_INIT_FUNC(LCD_0_DEN, 134, 0),
+ [P7_GPIO_134] = P7CTL_INIT_FUNC(GPIO_134, 134, 1),
+ [P7_CAM_1_VS] = P7CTL_INIT_FUNC(CAM_1_VS, 134, 2),
+ [P7_LCD_0_HS] = P7CTL_INIT_FUNC(LCD_0_HS, 135, 0),
+ [P7_GPIO_135] = P7CTL_INIT_FUNC(GPIO_135, 135, 1),
+ [P7_CAM_1_HS] = P7CTL_INIT_FUNC(CAM_1_HS, 135, 2),
+ [P7_LCD_0_DENa] = P7CTL_INIT_FUNC(LCD_0_DENa, 135, 3),
+ [P7_LCD_0_VS] = P7CTL_INIT_FUNC(LCD_0_VS, 136, 0),
+ [P7_GPIO_136] = P7CTL_INIT_FUNC(GPIO_136, 136, 1),
+ [P7_CAM_0_VS] = P7CTL_INIT_FUNC(CAM_0_VS, 136, 2),
+ [P7_PAR_NCS] = P7CTL_INIT_FUNC(PAR_NCS, 136, 3),
+ [P7_LCD_0_DATA00] = P7CTL_INIT_FUNC(LCD_0_DATA00, 137, 0),
+ [P7_GPIO_137] = P7CTL_INIT_FUNC(GPIO_137, 137, 1),
+ [P7_CAM_0_HS] = P7CTL_INIT_FUNC(CAM_0_HS, 137, 2),
+ [P7_PAR_NRS] = P7CTL_INIT_FUNC(PAR_NRS, 137, 3),
+ [P7_LCD_0_DATA01] = P7CTL_INIT_FUNC(LCD_0_DATA01, 138, 0),
+ [P7_GPIO_138] = P7CTL_INIT_FUNC(GPIO_138, 138, 1),
+ [P7_CAM_2_VS] = P7CTL_INIT_FUNC(CAM_2_VS, 138, 2),
+ [P7_PAR_NRD] = P7CTL_INIT_FUNC(PAR_NRD, 138, 3),
+ [P7_LCD_0_DATA02] = P7CTL_INIT_FUNC(LCD_0_DATA02, 139, 0),
+ [P7_GPIO_139] = P7CTL_INIT_FUNC(GPIO_139, 139, 1),
+ [P7_CAM_2_HS] = P7CTL_INIT_FUNC(CAM_2_HS, 139, 2),
+ [P7_PAR_NWR] = P7CTL_INIT_FUNC(PAR_NWR, 139, 3),
+ [P7_LCD_0_DATA03] = P7CTL_INIT_FUNC(LCD_0_DATA03, 140, 0),
+ [P7_GPIO_140] = P7CTL_INIT_FUNC(GPIO_140, 140, 1),
+ [P7_CAM_3_VS] = P7CTL_INIT_FUNC(CAM_3_VS, 140, 2),
+ [P7_PAR_D00] = P7CTL_INIT_FUNC(PAR_D00, 140, 3),
+ [P7_LCD_0_DATA04] = P7CTL_INIT_FUNC(LCD_0_DATA04, 141, 0),
+ [P7_GPIO_141] = P7CTL_INIT_FUNC(GPIO_141, 141, 1),
+ [P7_CAM_3_HS] = P7CTL_INIT_FUNC(CAM_3_HS, 141, 2),
+ [P7_PAR_D01] = P7CTL_INIT_FUNC(PAR_D01, 141, 3),
+ [P7_LCD_0_DATA05] = P7CTL_INIT_FUNC(LCD_0_DATA05, 142, 0),
+ [P7_GPIO_142] = P7CTL_INIT_FUNC(GPIO_142, 142, 1),
+ [P7_CAM_5_VS] = P7CTL_INIT_FUNC(CAM_5_VS, 142, 2),
+ [P7_PAR_D02] = P7CTL_INIT_FUNC(PAR_D02, 142, 3),
+ [P7_LCD_0_DATA06] = P7CTL_INIT_FUNC(LCD_0_DATA06, 143, 0),
+ [P7_GPIO_143] = P7CTL_INIT_FUNC(GPIO_143, 143, 1),
+ [P7_CAM_5_HS] = P7CTL_INIT_FUNC(CAM_5_HS, 143, 2),
+ [P7_PAR_D03] = P7CTL_INIT_FUNC(PAR_D03, 143, 3),
+ [P7_LCD_0_DATA07] = P7CTL_INIT_FUNC(LCD_0_DATA07, 144, 0),
+ [P7_GPIO_144] = P7CTL_INIT_FUNC(GPIO_144, 144, 1),
+ [P7_CAM_0_DATA08] = P7CTL_INIT_FUNC(CAM_0_DATA08, 144, 2),
+ [P7_PAR_D04] = P7CTL_INIT_FUNC(PAR_D04, 144, 3),
+ [P7_LCD_0_DATA08] = P7CTL_INIT_FUNC(LCD_0_DATA08, 145, 0),
+ [P7_GPIO_145] = P7CTL_INIT_FUNC(GPIO_145, 145, 1),
+ [P7_CAM_0_DATA09] = P7CTL_INIT_FUNC(CAM_0_DATA09, 145, 2),
+ [P7_PAR_D05] = P7CTL_INIT_FUNC(PAR_D05, 145, 3),
+ [P7_LCD_0_DATA09] = P7CTL_INIT_FUNC(LCD_0_DATA09, 146, 0),
+ [P7_GPIO_146] = P7CTL_INIT_FUNC(GPIO_146, 146, 1),
+ [P7_CAM_0_DATA10] = P7CTL_INIT_FUNC(CAM_0_DATA10, 146, 2),
+ [P7_PAR_D06] = P7CTL_INIT_FUNC(PAR_D06, 146, 3),
+ [P7_LCD_0_DATA10] = P7CTL_INIT_FUNC(LCD_0_DATA10, 147, 0),
+ [P7_GPIO_147] = P7CTL_INIT_FUNC(GPIO_147, 147, 1),
+ [P7_CAM_0_DATA11] = P7CTL_INIT_FUNC(CAM_0_DATA11, 147, 2),
+ [P7_PAR_D07] = P7CTL_INIT_FUNC(PAR_D07, 147, 3),
+ [P7_LCD_0_DATA11] = P7CTL_INIT_FUNC(LCD_0_DATA11, 148, 0),
+ [P7_GPIO_148] = P7CTL_INIT_FUNC(GPIO_148, 148, 1),
+ [P7_CAM_0_DATA12] = P7CTL_INIT_FUNC(CAM_0_DATA12, 148, 2),
+ [P7_PAR_D08] = P7CTL_INIT_FUNC(PAR_D08, 148, 3),
+ [P7_LCD_0_DATA12] = P7CTL_INIT_FUNC(LCD_0_DATA12, 149, 0),
+ [P7_GPIO_149] = P7CTL_INIT_FUNC(GPIO_149, 149, 1),
+ [P7_CAM_0_DATA13] = P7CTL_INIT_FUNC(CAM_0_DATA13, 149, 2),
+ [P7_PAR_D09] = P7CTL_INIT_FUNC(PAR_D09, 149, 3),
+ [P7_LCD_0_DATA13] = P7CTL_INIT_FUNC(LCD_0_DATA13, 150, 0),
+ [P7_GPIO_150] = P7CTL_INIT_FUNC(GPIO_150, 150, 1),
+ [P7_CAM_0_DATA14] = P7CTL_INIT_FUNC(CAM_0_DATA14, 150, 2),
+ [P7_PAR_D10] = P7CTL_INIT_FUNC(PAR_D10, 150, 3),
+ [P7_LCD_0_DATA14] = P7CTL_INIT_FUNC(LCD_0_DATA14, 151, 0),
+ [P7_GPIO_151] = P7CTL_INIT_FUNC(GPIO_151, 151, 1),
+ [P7_CAM_0_DATA15] = P7CTL_INIT_FUNC(CAM_0_DATA15, 151, 2),
+ [P7_PAR_D11] = P7CTL_INIT_FUNC(PAR_D11, 151, 3),
+ [P7_LCD_0_DATA15] = P7CTL_INIT_FUNC(LCD_0_DATA15, 152, 0),
+ [P7_GPIO_152] = P7CTL_INIT_FUNC(GPIO_152, 152, 1),
+ [P7_CAM_0_DATA16] = P7CTL_INIT_FUNC(CAM_0_DATA16, 152, 2),
+ [P7_PAR_D12] = P7CTL_INIT_FUNC(PAR_D12, 152, 3),
+ [P7_LCD_0_DATA16] = P7CTL_INIT_FUNC(LCD_0_DATA16, 153, 0),
+ [P7_GPIO_153] = P7CTL_INIT_FUNC(GPIO_153, 153, 1),
+ [P7_CAM_0_DATA17] = P7CTL_INIT_FUNC(CAM_0_DATA17, 153, 2),
+ [P7_PAR_D13] = P7CTL_INIT_FUNC(PAR_D13, 153, 3),
+ [P7_LCD_0_DATA17] = P7CTL_INIT_FUNC(LCD_0_DATA17, 154, 0),
+ [P7_GPIO_154] = P7CTL_INIT_FUNC(GPIO_154, 154, 1),
+ [P7_CAM_0_DATA18] = P7CTL_INIT_FUNC(CAM_0_DATA18, 154, 2),
+ [P7_PAR_D14] = P7CTL_INIT_FUNC(PAR_D14, 154, 3),
+ [P7_LCD_0_DATA18] = P7CTL_INIT_FUNC(LCD_0_DATA18, 155, 0),
+ [P7_GPIO_155] = P7CTL_INIT_FUNC(GPIO_155, 155, 1),
+ [P7_CAM_0_DATA19] = P7CTL_INIT_FUNC(CAM_0_DATA19, 155, 2),
+ [P7_PAR_D15] = P7CTL_INIT_FUNC(PAR_D15, 155, 3),
+ [P7_LCD_0_DATA19] = P7CTL_INIT_FUNC(LCD_0_DATA19, 156, 0),
+ [P7_GPIO_156] = P7CTL_INIT_FUNC(GPIO_156, 156, 1),
+ [P7_CAM_0_DATA20] = P7CTL_INIT_FUNC(CAM_0_DATA20, 156, 2),
+ [P7_LCD_0_DATA20] = P7CTL_INIT_FUNC(LCD_0_DATA20, 157, 0),
+ [P7_GPIO_157] = P7CTL_INIT_FUNC(GPIO_157, 157, 1),
+ [P7_CAM_0_DATA21] = P7CTL_INIT_FUNC(CAM_0_DATA21, 157, 2),
+ [P7_LCD_0_DATA21] = P7CTL_INIT_FUNC(LCD_0_DATA21, 158, 0),
+ [P7_GPIO_158] = P7CTL_INIT_FUNC(GPIO_158, 158, 1),
+ [P7_CAM_0_DATA22] = P7CTL_INIT_FUNC(CAM_0_DATA22, 158, 2),
+ [P7_LCD_0_DATA22] = P7CTL_INIT_FUNC(LCD_0_DATA22, 159, 0),
+ [P7_GPIO_159] = P7CTL_INIT_FUNC(GPIO_159, 159, 1),
+ [P7_CAM_0_DATA23] = P7CTL_INIT_FUNC(CAM_0_DATA23, 159, 2),
+ [P7_LCD_0_DATA23] = P7CTL_INIT_FUNC(LCD_0_DATA23, 160, 0),
+ [P7_GPIO_160] = P7CTL_INIT_FUNC(GPIO_160, 160, 1),
+ [P7_CAM_4_VS] = P7CTL_INIT_FUNC(CAM_4_VS, 160, 2),
+ [P7_LCD_0_CLK] = P7CTL_INIT_FUNC(LCD_0_CLK, 161, 0),
+ [P7_GPIO_161] = P7CTL_INIT_FUNC(GPIO_161, 161, 1),
+ [P7_CAM_4_HS] = P7CTL_INIT_FUNC(CAM_4_HS, 161, 2),
+ [P7_LCD_1_HS] = P7CTL_INIT_FUNC(LCD_1_HS, 162, 0),
+ [P7_GPIO_162] = P7CTL_INIT_FUNC(GPIO_162, 162, 1),
+ [P7_CAM_2_CLK] = P7CTL_INIT_FUNC(CAM_2_CLK, 162, 2),
+ [P7_LCD_1_DENa] = P7CTL_INIT_FUNC(LCD_1_DENa, 162, 3),
+ [P7_LCD_1_VS] = P7CTL_INIT_FUNC(LCD_1_VS, 163, 0),
+ [P7_GPIO_163] = P7CTL_INIT_FUNC(GPIO_163, 163, 1),
+ [P7_CAM_2_DATA00] = P7CTL_INIT_FUNC(CAM_2_DATA00, 163, 2),
+ [P7_CPU_TRACECLKOUT] = P7CTL_INIT_FUNC(CPU_TRACECLKOUT, 163, 3),
+ [P7_LCD_1_CLK] = P7CTL_INIT_FUNC(LCD_1_CLK, 164, 0),
+ [P7_GPIO_164] = P7CTL_INIT_FUNC(GPIO_164, 164, 1),
+ [P7_CAM_2_DATA01] = P7CTL_INIT_FUNC(CAM_2_DATA01, 164, 2),
+ [P7_CPU_TRACECTL] = P7CTL_INIT_FUNC(CPU_TRACECTL, 164, 3),
+ [P7_LCD_1_DATA00] = P7CTL_INIT_FUNC(LCD_1_DATA00, 165, 0),
+ [P7_GPIO_165] = P7CTL_INIT_FUNC(GPIO_165, 165, 1),
+ [P7_CAM_2_DATA02] = P7CTL_INIT_FUNC(CAM_2_DATA02, 165, 2),
+ [P7_CPU_TRACEDATA_00] = P7CTL_INIT_FUNC(CPU_TRACEDATA_00, 165, 3),
+ [P7_LCD_1_DATA01] = P7CTL_INIT_FUNC(LCD_1_DATA01, 166, 0),
+ [P7_GPIO_166] = P7CTL_INIT_FUNC(GPIO_166, 166, 1),
+ [P7_CAM_2_DATA03] = P7CTL_INIT_FUNC(CAM_2_DATA03, 166, 2),
+ [P7_CPU_TRACEDATA_01] = P7CTL_INIT_FUNC(CPU_TRACEDATA_01, 166, 3),
+ [P7_LCD_1_DATA02] = P7CTL_INIT_FUNC(LCD_1_DATA02, 167, 0),
+ [P7_GPIO_167] = P7CTL_INIT_FUNC(GPIO_167, 167, 1),
+ [P7_CAM_2_DATA04] = P7CTL_INIT_FUNC(CAM_2_DATA04, 167, 2),
+ [P7_CPU_TRACEDATA_02] = P7CTL_INIT_FUNC(CPU_TRACEDATA_02, 167, 3),
+ [P7_LCD_1_DATA03] = P7CTL_INIT_FUNC(LCD_1_DATA03, 168, 0),
+ [P7_GPIO_168] = P7CTL_INIT_FUNC(GPIO_168, 168, 1),
+ [P7_CAM_2_DATA05] = P7CTL_INIT_FUNC(CAM_2_DATA05, 168, 2),
+ [P7_CPU_TRACEDATA_03] = P7CTL_INIT_FUNC(CPU_TRACEDATA_03, 168, 3),
+ [P7_LCD_1_DATA04] = P7CTL_INIT_FUNC(LCD_1_DATA04, 169, 0),
+ [P7_GPIO_169] = P7CTL_INIT_FUNC(GPIO_169, 169, 1),
+ [P7_CAM_2_DATA06] = P7CTL_INIT_FUNC(CAM_2_DATA06, 169, 2),
+ [P7_CPU_TRACEDATA_04] = P7CTL_INIT_FUNC(CPU_TRACEDATA_04, 169, 3),
+ [P7_LCD_1_DATA05] = P7CTL_INIT_FUNC(LCD_1_DATA05, 170, 0),
+ [P7_GPIO_170] = P7CTL_INIT_FUNC(GPIO_170, 170, 1),
+ [P7_CAM_2_DATA07] = P7CTL_INIT_FUNC(CAM_2_DATA07, 170, 2),
+ [P7_CPU_TRACEDATA_05] = P7CTL_INIT_FUNC(CPU_TRACEDATA_05, 170, 3),
+ [P7_LCD_1_DATA06] = P7CTL_INIT_FUNC(LCD_1_DATA06, 171, 0),
+ [P7_GPIO_171] = P7CTL_INIT_FUNC(GPIO_171, 171, 1),
+ [P7_CAM_3_CLK] = P7CTL_INIT_FUNC(CAM_3_CLK, 171, 2),
+ [P7_CPU_TRACEDATA_06] = P7CTL_INIT_FUNC(CPU_TRACEDATA_06, 171, 3),
+ [P7_LCD_1_DATA07] = P7CTL_INIT_FUNC(LCD_1_DATA07, 172, 0),
+ [P7_GPIO_172] = P7CTL_INIT_FUNC(GPIO_172, 172, 1),
+ [P7_CAM_3_DATA00] = P7CTL_INIT_FUNC(CAM_3_DATA00, 172, 2),
+ [P7_CPU_TRACEDATA_07] = P7CTL_INIT_FUNC(CPU_TRACEDATA_07, 172, 3),
+ [P7_LCD_1_DATA08] = P7CTL_INIT_FUNC(LCD_1_DATA08, 173, 0),
+ [P7_GPIO_173] = P7CTL_INIT_FUNC(GPIO_173, 173, 1),
+ [P7_CAM_3_DATA01] = P7CTL_INIT_FUNC(CAM_3_DATA01, 173, 2),
+ [P7_CPU_TRACEDATA_08] = P7CTL_INIT_FUNC(CPU_TRACEDATA_08, 173, 3),
+ [P7_LCD_1_DATA09] = P7CTL_INIT_FUNC(LCD_1_DATA09, 174, 0),
+ [P7_GPIO_174] = P7CTL_INIT_FUNC(GPIO_174, 174, 1),
+ [P7_CAM_3_DATA02] = P7CTL_INIT_FUNC(CAM_3_DATA02, 174, 2),
+ [P7_CPU_TRACEDATA_09] = P7CTL_INIT_FUNC(CPU_TRACEDATA_09, 174, 3),
+ [P7_LCD_1_DATA10] = P7CTL_INIT_FUNC(LCD_1_DATA10, 175, 0),
+ [P7_GPIO_175] = P7CTL_INIT_FUNC(GPIO_175, 175, 1),
+ [P7_CAM_3_DATA03] = P7CTL_INIT_FUNC(CAM_3_DATA03, 175, 2),
+ [P7_CPU_TRACEDATA_10] = P7CTL_INIT_FUNC(CPU_TRACEDATA_10, 175, 3),
+ [P7_LCD_1_DATA11] = P7CTL_INIT_FUNC(LCD_1_DATA11, 176, 0),
+ [P7_GPIO_176] = P7CTL_INIT_FUNC(GPIO_176, 176, 1),
+ [P7_CAM_3_DATA04] = P7CTL_INIT_FUNC(CAM_3_DATA04, 176, 2),
+ [P7_CPU_TRACEDATA_11] = P7CTL_INIT_FUNC(CPU_TRACEDATA_11, 176, 3),
+ [P7_LCD_1_DATA12] = P7CTL_INIT_FUNC(LCD_1_DATA12, 177, 0),
+ [P7_GPIO_177] = P7CTL_INIT_FUNC(GPIO_177, 177, 1),
+ [P7_CAM_3_DATA05] = P7CTL_INIT_FUNC(CAM_3_DATA05, 177, 2),
+ [P7_CPU_TRACEDATA_12] = P7CTL_INIT_FUNC(CPU_TRACEDATA_12, 177, 3),
+ [P7_LCD_1_DATA13] = P7CTL_INIT_FUNC(LCD_1_DATA13, 178, 0),
+ [P7_GPIO_178] = P7CTL_INIT_FUNC(GPIO_178, 178, 1),
+ [P7_CAM_3_DATA06] = P7CTL_INIT_FUNC(CAM_3_DATA06, 178, 2),
+ [P7_CPU_TRACEDATA_13] = P7CTL_INIT_FUNC(CPU_TRACEDATA_13, 178, 3),
+ [P7_LCD_1_DATA14] = P7CTL_INIT_FUNC(LCD_1_DATA14, 179, 0),
+ [P7_GPIO_179] = P7CTL_INIT_FUNC(GPIO_179, 179, 1),
+ [P7_CAM_3_DATA07] = P7CTL_INIT_FUNC(CAM_3_DATA07, 179, 2),
+ [P7_CPU_TRACEDATA_14] = P7CTL_INIT_FUNC(CPU_TRACEDATA_14, 179, 3),
+ [P7_LCD_1_DATA15] = P7CTL_INIT_FUNC(LCD_1_DATA15, 180, 0),
+ [P7_GPIO_180] = P7CTL_INIT_FUNC(GPIO_180, 180, 1),
+ [P7_CAM_4_CLK] = P7CTL_INIT_FUNC(CAM_4_CLK, 180, 2),
+ [P7_CPU_TRACEDATA_15] = P7CTL_INIT_FUNC(CPU_TRACEDATA_15, 180, 3),
+ [P7_LCD_1_DATA16] = P7CTL_INIT_FUNC(LCD_1_DATA16, 181, 0),
+ [P7_GPIO_181] = P7CTL_INIT_FUNC(GPIO_181, 181, 1),
+ [P7_CAM_4_DATA00] = P7CTL_INIT_FUNC(CAM_4_DATA00, 181, 2),
+ [P7_LCD_1_DATA17] = P7CTL_INIT_FUNC(LCD_1_DATA17, 182, 0),
+ [P7_GPIO_182] = P7CTL_INIT_FUNC(GPIO_182, 182, 1),
+ [P7_CAM_4_DATA01] = P7CTL_INIT_FUNC(CAM_4_DATA01, 182, 2),
+ [P7_LCD_1_DATA18] = P7CTL_INIT_FUNC(LCD_1_DATA18, 183, 0),
+ [P7_GPIO_183] = P7CTL_INIT_FUNC(GPIO_183, 183, 1),
+ [P7_CAM_4_DATA02] = P7CTL_INIT_FUNC(CAM_4_DATA02, 183, 2),
+ [P7_LCD_1_DATA19] = P7CTL_INIT_FUNC(LCD_1_DATA19, 184, 0),
+ [P7_GPIO_184] = P7CTL_INIT_FUNC(GPIO_184, 184, 1),
+ [P7_CAM_4_DATA03] = P7CTL_INIT_FUNC(CAM_4_DATA03, 184, 2),
+ [P7_LCD_1_DATA20] = P7CTL_INIT_FUNC(LCD_1_DATA20, 185, 0),
+ [P7_GPIO_185] = P7CTL_INIT_FUNC(GPIO_185, 185, 1),
+ [P7_CAM_4_DATA04] = P7CTL_INIT_FUNC(CAM_4_DATA04, 185, 2),
+ [P7_LCD_1_DATA21] = P7CTL_INIT_FUNC(LCD_1_DATA21, 186, 0),
+ [P7_GPIO_186] = P7CTL_INIT_FUNC(GPIO_186, 186, 1),
+ [P7_CAM_4_DATA05] = P7CTL_INIT_FUNC(CAM_4_DATA05, 186, 2),
+ [P7_LCD_1_DATA22] = P7CTL_INIT_FUNC(LCD_1_DATA22, 187, 0),
+ [P7_GPIO_187] = P7CTL_INIT_FUNC(GPIO_187, 187, 1),
+ [P7_CAM_4_DATA06] = P7CTL_INIT_FUNC(CAM_4_DATA06, 187, 2),
+ [P7_LCD_1_DATA23] = P7CTL_INIT_FUNC(LCD_1_DATA23, 188, 0),
+ [P7_GPIO_188] = P7CTL_INIT_FUNC(GPIO_188, 188, 1),
+ [P7_CAM_4_DATA07] = P7CTL_INIT_FUNC(CAM_4_DATA07, 188, 2),
+ [P7_LCD_1_DEN] = P7CTL_INIT_FUNC(LCD_1_DEN, 189, 0),
+ [P7_GPIO_189] = P7CTL_INIT_FUNC(GPIO_189, 189, 1),
+ [P7_CAM_1_HSa] = P7CTL_INIT_FUNC(CAM_1_HSa, 189, 2),
+ [P7_LCD_1_CLKa] = P7CTL_INIT_FUNC(LCD_1_CLKa, 189, 3),
+ [P7_CAM_0_CLK] = P7CTL_INIT_FUNC(CAM_0_CLK, 190, 0),
+ [P7_GPIO_190] = P7CTL_INIT_FUNC(GPIO_190, 190, 1),
+ [P7_CAM_0_DATA00] = P7CTL_INIT_FUNC(CAM_0_DATA00, 191, 0),
+ [P7_GPIO_191] = P7CTL_INIT_FUNC(GPIO_191, 191, 1),
+ [P7_CAM_1_DATA08] = P7CTL_INIT_FUNC(CAM_1_DATA08, 191, 2),
+ [P7_CAM_0_DATA01] = P7CTL_INIT_FUNC(CAM_0_DATA01, 192, 0),
+ [P7_GPIO_192] = P7CTL_INIT_FUNC(GPIO_192, 192, 1),
+ [P7_CAM_1_DATA09] = P7CTL_INIT_FUNC(CAM_1_DATA09, 192, 2),
+ [P7_CAM_0_DATA02] = P7CTL_INIT_FUNC(CAM_0_DATA02, 193, 0),
+ [P7_GPIO_193] = P7CTL_INIT_FUNC(GPIO_193, 193, 1),
+ [P7_CAM_1_DATA10] = P7CTL_INIT_FUNC(CAM_1_DATA10, 193, 2),
+ [P7_CAM_0_DATA03] = P7CTL_INIT_FUNC(CAM_0_DATA03, 194, 0),
+ [P7_GPIO_194] = P7CTL_INIT_FUNC(GPIO_194, 194, 1),
+ [P7_CAM_1_DATA11] = P7CTL_INIT_FUNC(CAM_1_DATA11, 194, 2),
+ [P7_CAM_0_DATA04] = P7CTL_INIT_FUNC(CAM_0_DATA04, 195, 0),
+ [P7_GPIO_195] = P7CTL_INIT_FUNC(GPIO_195, 195, 1),
+ [P7_CAM_1_DATA12] = P7CTL_INIT_FUNC(CAM_1_DATA12, 195, 2),
+ [P7_CAM_0_DATA05] = P7CTL_INIT_FUNC(CAM_0_DATA05, 196, 0),
+ [P7_GPIO_196] = P7CTL_INIT_FUNC(GPIO_196, 196, 1),
+ [P7_CAM_1_DATA13] = P7CTL_INIT_FUNC(CAM_1_DATA13, 196, 2),
+ [P7_CAM_0_DATA06] = P7CTL_INIT_FUNC(CAM_0_DATA06, 197, 0),
+ [P7_GPIO_197] = P7CTL_INIT_FUNC(GPIO_197, 197, 1),
+ [P7_CAM_1_DATA14] = P7CTL_INIT_FUNC(CAM_1_DATA14, 197, 2),
+ [P7_CAM_0_DATA07] = P7CTL_INIT_FUNC(CAM_0_DATA07, 198, 0),
+ [P7_GPIO_198] = P7CTL_INIT_FUNC(GPIO_198, 198, 1),
+ [P7_CAM_1_DATA15] = P7CTL_INIT_FUNC(CAM_1_DATA15, 198, 2),
+ [P7_CAM_1_CLK] = P7CTL_INIT_FUNC(CAM_1_CLK, 199, 0),
+ [P7_GPIO_199] = P7CTL_INIT_FUNC(GPIO_199, 199, 1),
+ [P7_SPI_00b] = P7CTL_INIT_FUNC(SPI_00b, 199, 2),
+ [P7_CAM_1_DATA00] = P7CTL_INIT_FUNC(CAM_1_DATA00, 200, 0),
+ [P7_GPIO_200] = P7CTL_INIT_FUNC(GPIO_200, 200, 1),
+ [P7_SPI_01b] = P7CTL_INIT_FUNC(SPI_01b, 200, 2),
+ [P7_CAM_0_VSa] = P7CTL_INIT_FUNC(CAM_0_VSa, 200, 3),
+ [P7_CAM_1_DATA01] = P7CTL_INIT_FUNC(CAM_1_DATA01, 201, 0),
+ [P7_GPIO_201] = P7CTL_INIT_FUNC(GPIO_201, 201, 1),
+ [P7_SPI_02b] = P7CTL_INIT_FUNC(SPI_02b, 201, 2),
+ [P7_CAM_0_HSa] = P7CTL_INIT_FUNC(CAM_0_HSa, 201, 3)
+};
+
+/*
+ * Bitmap of GPIO enabled pins
+ *
+ * Each physical pin usable as GPIO is indicated with a bit set to 1 in this
+ * bitmap. The bitmap is indexed by pin identifier.
+ *
+ * Content was generated with the help of the genpin.sh script located uinto
+ * this directory.
+ */
+static unsigned long p7_gpio_pins_r1[] = {
+ 0x00007fff,
+ 0xf80607c2,
+ 0x5fffff9f,
+ 0xfffff800,
+ 0xffffffff,
+ 0xffffffff,
+ 0x000003ff
+};
+
+const struct p7_pinctrl_config p7_pinctrl_config_r1 = {
+ .pin_descs = p7_pin_descs_r1,
+ .pin_descs_sz = ARRAY_SIZE(p7_pin_descs_r1),
+ .pin_funcs = p7_pin_funcs_r1,
+ .gpio_pins = p7_gpio_pins_r1,
+ .gpio_pins_sz = ARRAY_SIZE(p7_gpio_pins_r1),
+};
diff --git a/arch/arm/mach-parrot7/pindesc-r2.c b/arch/arm/mach-parrot7/pindesc-r2.c
new file mode 100644
index 0000000..6295a6f
--- /dev/null
+++ b/arch/arm/mach-parrot7/pindesc-r2.c
@@ -0,0 +1,855 @@
+#include "common.h"
+#include "pinctrl.h"
+
+/*
+ * Physical pin descriptors
+ *
+ * Pins identifiers use the GPIO numbering scheme. Names are assigned by
+ * concatenating all possible multiplexing functions a pin may be used with.
+ *
+ * Content was generated with the help of the genpin.sh script located into
+ * this directory.
+ */
+/* Physical pin descriptors */
+static struct pinctrl_pin_desc const p7_pin_descs_r2[] = {
+ P7CTL_INIT_PIN(0, "CAM_1_DATA02__GPIO_000__SPI_03b__CAM_3_VSa"),
+ P7CTL_INIT_PIN(1, "CAM_1_DATA03__GPIO_001__SPI_04b__CAM_3_HSa"),
+ P7CTL_INIT_PIN(2, "CAM_1_DATA04__GPIO_002__SPI_05b__CAM_4_VSa"),
+ P7CTL_INIT_PIN(3, "CAM_1_DATA05__GPIO_003__SPI_06b__CAM_4_HSa"),
+ P7CTL_INIT_PIN(4, "CAM_1_DATA06__GPIO_004__SPI_07b__CAM_5_VSa"),
+ P7CTL_INIT_PIN(5, "CAM_1_DATA07__GPIO_005__SPI_08b__CAM_5_HSa"),
+ P7CTL_INIT_PIN(6, "CAM_5_CLK__GPIO_006__SD_2_CLK"),
+ P7CTL_INIT_PIN(7, "CAM_5_DATA00__GPIO_007__SD_2_CMD"),
+ P7CTL_INIT_PIN(8, "CAM_5_DATA01__GPIO_008__SD_2_DAT00"),
+ P7CTL_INIT_PIN(9, "CAM_5_DATA02__GPIO_009__SD_2_DAT01"),
+ P7CTL_INIT_PIN(10, "CAM_5_DATA03__GPIO_010__SD_2_DAT02"),
+ P7CTL_INIT_PIN(11, "CAM_5_DATA04__GPIO_011__SD_2_DAT03"),
+ P7CTL_INIT_PIN(12, "CAM_5_DATA05__GPIO_012"),
+ P7CTL_INIT_PIN(13, "CAM_5_DATA06__GPIO_013"),
+ P7CTL_INIT_PIN(14, "CAM_5_DATA07__GPIO_014"),
+ P7CTL_INIT_PIN(15, "SD_1_CLK__GPIO_015__UART_5_TX"),
+ P7CTL_INIT_PIN(16, "SD_1_CMD__GPIO_016__UART_5_RX"),
+ P7CTL_INIT_PIN(17, "SD_1_DAT00__GPIO_017__UART_6_TX"),
+ P7CTL_INIT_PIN(18, "SD_1_DAT02__GPIO_018__UART_7_TX"),
+ P7CTL_INIT_PIN(19, "SD_1_DAT01__GPIO_019__UART_6_RX"),
+ P7CTL_INIT_PIN(20, "SD_1_DAT03__GPIO_020__UART_7_RX"),
+ P7CTL_INIT_PIN(21, "SD_0_CLK__GPIO_021"),
+ P7CTL_INIT_PIN(22, "SD_0_CMD__GPIO_022"),
+ P7CTL_INIT_PIN(23, "SD_0_DAT00__GPIO_023"),
+ P7CTL_INIT_PIN(24, "SD_0_DAT01__GPIO_024"),
+ P7CTL_INIT_PIN(25, "SD_0_DAT02__GPIO_025"),
+ P7CTL_INIT_PIN(26, "SD_0_DAT03__GPIO_026"),
+ P7CTL_INIT_PIN(27, "NAND_NCE__GPIO_027__SPI_00a"),
+ P7CTL_INIT_PIN(28, "NAND_NR__GPIO_028__SPI_01a"),
+ P7CTL_INIT_PIN(29, "NAND_NW__GPIO_029__SPI_02a"),
+ P7CTL_INIT_PIN(30, "NAND_AL__GPIO_030__SPI_03a"),
+ P7CTL_INIT_PIN(31, "NAND_CL__GPIO_031__SPI_04a"),
+ P7CTL_INIT_PIN(32, "NAND_RNB__GPIO_032__SPI_05a"),
+ P7CTL_INIT_PIN(33, "NAND_DQS__GPIO_033__CAN1_RXa"),
+ P7CTL_INIT_PIN(34, "NAND_DATA_00__GPIO_034__SPI_06a"),
+ P7CTL_INIT_PIN(35, "NAND_DATA_01__GPIO_035__SPI_07a"),
+ P7CTL_INIT_PIN(36, "NAND_DATA_02__GPIO_036__SPI_08a"),
+ P7CTL_INIT_PIN(37, "NAND_DATA_03__GPIO_037__SPI_09a"),
+ P7CTL_INIT_PIN(38, "NAND_DATA_04__GPIO_038"),
+ P7CTL_INIT_PIN(39, "NAND_DATA_05__GPIO_039"),
+ P7CTL_INIT_PIN(40, "NAND_DATA_06__GPIO_040"),
+ P7CTL_INIT_PIN(41, "NAND_DATA_07__GPIO_041"),
+ P7CTL_INIT_PIN(42, "NAND_WP__GPIO_042__CAN1_TXa"),
+ P7CTL_INIT_PIN(43, "FORCE_POWER_ON__GPIO_043"),
+ P7CTL_INIT_PIN(44, "TRST_N__GPIO_044"),
+ P7CTL_INIT_PIN(45, "TDI__GPIO_045"),
+ P7CTL_INIT_PIN(46, "TDO__GPIO_046"),
+ P7CTL_INIT_PIN(47, "TCK__GPIO_047"),
+ P7CTL_INIT_PIN(48, "TMS__GPIO_048"),
+ P7CTL_INIT_PIN(49, "GPIO_049"),
+ P7CTL_INIT_PIN(50, "GPIO_050"),
+ P7CTL_INIT_PIN(51, "UART_1_RX__GPIO_051"),
+ P7CTL_INIT_PIN(52, "UART_1_TX__GPIO_052"),
+ P7CTL_INIT_PIN(53, "UART_1_RTS__GPIO_053__CAN0_RXb"),
+ P7CTL_INIT_PIN(54, "UART_1_CTS__GPIO_054__CAN0_TXb"),
+ P7CTL_INIT_PIN(55, "UART_0_RX__GPIO_055"),
+ P7CTL_INIT_PIN(56, "UART_0_TX__GPIO_056"),
+ P7CTL_INIT_PIN(57, "UART_0_RTS__GPIO_057"),
+ P7CTL_INIT_PIN(58, "UART_0_CTS__GPIO_058"),
+ P7CTL_INIT_PIN(59, "I2C_2_DAT__GPIO_059__I2C_2_SL_DAT"),
+ P7CTL_INIT_PIN(60, "I2C_2_CLK__GPIO_060__I2C_2_SL_CLK"),
+ P7CTL_INIT_PIN(61, "I2C_1_DAT__GPIO_061__I2C_1_SL_DAT"),
+ P7CTL_INIT_PIN(62, "I2C_1_CLK__GPIO_062__I2C_1_SL_CLK"),
+ P7CTL_INIT_PIN(63, "I2C_0_DAT__GPIO_063__I2C_0_SL_DAT"),
+ P7CTL_INIT_PIN(64, "I2C_0_CLK__GPIO_064__I2C_0_SL_CLK"),
+ P7CTL_INIT_PIN(65, "UART_4_RX__GPIO_065"),
+ P7CTL_INIT_PIN(66, "UART_4_TX__GPIO_066"),
+ P7CTL_INIT_PIN(67, "UART_3_RX__GPIO_067"),
+ P7CTL_INIT_PIN(68, "UART_3_TX__GPIO_068"),
+ P7CTL_INIT_PIN(69, "UART_2_RX__GPIO_069__CAN1_TXb"),
+ P7CTL_INIT_PIN(70, "UART_2_TX__GPIO_070__CAN1_RXb"),
+ P7CTL_INIT_PIN(71, "SPI_09b__GPIO_071__PWM_15"),
+ P7CTL_INIT_PIN(72, "SPI_10b__GPIO_072"),
+ P7CTL_INIT_PIN(73, "SPI_11b__GPIO_073"),
+ P7CTL_INIT_PIN(74, "SPI_12b__GPIO_074"),
+ P7CTL_INIT_PIN(75, "SPI_13b__GPIO_075"),
+ P7CTL_INIT_PIN(76, "SPI_14b__GPIO_076"),
+ P7CTL_INIT_PIN(77, "SPI_00__GPIO_077__AAI_15__CAN1_TX"),
+ P7CTL_INIT_PIN(78, "SPI_01__GPIO_078__AAI_16__CAN1_RX"),
+ P7CTL_INIT_PIN(79, "SPI_02__GPIO_079__AAI_17__CAN0_TX"),
+ P7CTL_INIT_PIN(80, "SPI_03__GPIO_080__AAI_18__CAN0_RX"),
+ P7CTL_INIT_PIN(81, "SPI_04__GPIO_081__AAI_19"),
+ P7CTL_INIT_PIN(82, "SPI_05__GPIO_082__AAI_20"),
+ P7CTL_INIT_PIN(83, "SPI_06__GPIO_083__AAI_21"),
+ P7CTL_INIT_PIN(84, "SPI_07__GPIO_084__AAI_22"),
+ P7CTL_INIT_PIN(85, "SPI_08__GPIO_085__AAI_23"),
+ P7CTL_INIT_PIN(86, "SPI_09__GPIO_086__AAI_24"),
+ P7CTL_INIT_PIN(87, "SPI_10__GPIO_087__AAI_25"),
+ P7CTL_INIT_PIN(88, "SPI_11__GPIO_088__AAI_26"),
+ P7CTL_INIT_PIN(89, "SPI_12__GPIO_089__AAI_27"),
+ P7CTL_INIT_PIN(90, "SPI_13__GPIO_090__AAI_28"),
+ P7CTL_INIT_PIN(91, "SPI_14__GPIO_091__AAI_29"),
+ P7CTL_INIT_PIN(92, "SPI_15__GPIO_092__AAI_30"),
+ P7CTL_INIT_PIN(93, "P7MU_CLK_OUT__GPIO_093__PWM_15a"),
+ P7CTL_INIT_PIN(94, "REBOOT_P7MU__GPIO_094"),
+ P7CTL_INIT_PIN(95, "ULPI_0_DATA00__GPIO_095"),
+ P7CTL_INIT_PIN(96, "ULPI_0_DATA01__GPIO_096"),
+ P7CTL_INIT_PIN(97, "ULPI_0_DATA02__GPIO_097"),
+ P7CTL_INIT_PIN(98, "ULPI_0_DATA03__GPIO_098"),
+ P7CTL_INIT_PIN(99, "ULPI_0_DATA04__GPIO_099"),
+ P7CTL_INIT_PIN(100, "ULPI_0_DATA05__GPIO_100"),
+ P7CTL_INIT_PIN(101, "ULPI_0_DATA06__GPIO_101"),
+ P7CTL_INIT_PIN(102, "ULPI_0_DATA07__GPIO_102"),
+ P7CTL_INIT_PIN(103, "ULPI_0_NXT__GPIO_103"),
+ P7CTL_INIT_PIN(104, "ULPI_0_DIR__GPIO_104"),
+ P7CTL_INIT_PIN(105, "ULPI_0_CLK__GPIO_105"),
+ P7CTL_INIT_PIN(106, "ULPI_1_DATA00__GPIO_106__I2C_2_CLKa"),
+ P7CTL_INIT_PIN(107, "ULPI_1_DATA01__GPIO_107__I2C_2_DATa"),
+ P7CTL_INIT_PIN(108, "ULPI_1_DATA02__GPIO_108__I2C_2_CLKb"),
+ P7CTL_INIT_PIN(109, "ULPI_1_DATA03__GPIO_109__I2C_2_DATb"),
+ P7CTL_INIT_PIN(110, "ULPI_1_DATA04__GPIO_110__I2C_2_CLKc"),
+ P7CTL_INIT_PIN(111, "ULPI_1_DATA05__GPIO_111__I2C_2_DATc"),
+ P7CTL_INIT_PIN(112, "ULPI_1_DATA06__GPIO_112__I2C_2_CLKd"),
+ P7CTL_INIT_PIN(113, "ULPI_1_DATA07__GPIO_113__I2C_2_DATd"),
+ P7CTL_INIT_PIN(114, "ULPI_1_NXT__GPIO_114__I2C_2_CLKe"),
+ P7CTL_INIT_PIN(115, "ULPI_1_DIR__GPIO_115"),
+ P7CTL_INIT_PIN(116, "ULPI_1_STP__GPIO_116__I2C_2_DATe"),
+ P7CTL_INIT_PIN(117, "ULPI_0_STP__GPIO_117"),
+ P7CTL_INIT_PIN(118, "ULPI_1_CLK__GPIO_118"),
+ P7CTL_INIT_PIN(119, "AAI_00__GPIO_119__PWM_00"),
+ P7CTL_INIT_PIN(120, "AAI_01__GPIO_120__PWM_01"),
+ P7CTL_INIT_PIN(121, "AAI_02__GPIO_121__PWM_02"),
+ P7CTL_INIT_PIN(122, "AAI_03__GPIO_122__PWM_03"),
+ P7CTL_INIT_PIN(123, "AAI_04__GPIO_123__PWM_04"),
+ P7CTL_INIT_PIN(124, "AAI_05__GPIO_124__PWM_05"),
+ P7CTL_INIT_PIN(125, "AAI_06__GPIO_125__PWM_06"),
+ P7CTL_INIT_PIN(126, "AAI_07__GPIO_126__PWM_07"),
+ P7CTL_INIT_PIN(127, "AAI_08__GPIO_127__PWM_08"),
+ P7CTL_INIT_PIN(128, "AAI_09__GPIO_128__PWM_09"),
+ P7CTL_INIT_PIN(129, "AAI_10__GPIO_129__PWM_10"),
+ P7CTL_INIT_PIN(130, "AAI_11__GPIO_130__PWM_11"),
+ P7CTL_INIT_PIN(131, "AAI_12__GPIO_131__PWM_12"),
+ P7CTL_INIT_PIN(132, "AAI_13__GPIO_132__PWM_13"),
+ P7CTL_INIT_PIN(133, "AAI_14__GPIO_133__PWM_14"),
+ P7CTL_INIT_PIN(134, "SPI_16__GPIO_134__ETH_MII_TXER"),
+ P7CTL_INIT_PIN(135, "SPI_17__GPIO_135__ETH_MII_RXER"),
+ P7CTL_INIT_PIN(136, "SPI_18__GPIO_136__ETH_MII_CRS"),
+ P7CTL_INIT_PIN(137, "SPI_19__GPIO_137__ETH_MII_COL"),
+ P7CTL_INIT_PIN(138, "ETH_RGMII_TXC__GPIO_138"),
+ P7CTL_INIT_PIN(139, "ETH_RGMII_TXD_00__GPIO_139"),
+ P7CTL_INIT_PIN(140, "ETH_RGMII_TXD_01__GPIO_140"),
+ P7CTL_INIT_PIN(141, "ETH_RGMII_TXD_02__GPIO_141"),
+ P7CTL_INIT_PIN(142, "ETH_RGMII_TXD_03__GPIO_142"),
+ P7CTL_INIT_PIN(143, "ETH_RGMII_TX_CTL__GPIO_143"),
+ P7CTL_INIT_PIN(144, "ETH_RGMII_RXC__GPIO_144"),
+ P7CTL_INIT_PIN(145, "ETH_RGMII_RXD_00__GPIO_145"),
+ P7CTL_INIT_PIN(146, "ETH_RGMII_RXD_01__GPIO_146"),
+ P7CTL_INIT_PIN(147, "ETH_RGMII_RXD_02__GPIO_147"),
+ P7CTL_INIT_PIN(148, "ETH_RGMII_RXD_03__GPIO_148"),
+ P7CTL_INIT_PIN(149, "ETH_RGMII_RX_CTL__GPIO_149"),
+ P7CTL_INIT_PIN(150, "ETH_MDC__GPIO_150"),
+ P7CTL_INIT_PIN(151, "ETH_MDIO__GPIO_151"),
+ P7CTL_INIT_PIN(152, "LCD_0_DEN__GPIO_152__CAM_1_VS"),
+ P7CTL_INIT_PIN(153, "LCD_0_HS__GPIO_153__CAM_1_HS__LCD_0_DENa"),
+ P7CTL_INIT_PIN(154, "LCD_0_VS__GPIO_154__CAM_0_VS__PAR_NCS"),
+ P7CTL_INIT_PIN(155, "LCD_0_DATA00__GPIO_155__CAM_0_HS__PAR_NRS"),
+ P7CTL_INIT_PIN(156, "LCD_0_DATA01__GPIO_156__CAM_2_VS__PAR_NRD"),
+ P7CTL_INIT_PIN(157, "LCD_0_DATA02__GPIO_157__CAM_2_HS__PAR_NWR"),
+ P7CTL_INIT_PIN(158, "LCD_0_DATA03__GPIO_158__CAM_3_VS__PAR_D00"),
+ P7CTL_INIT_PIN(159, "LCD_0_DATA04__GPIO_159__CAM_3_HS__PAR_D01"),
+ P7CTL_INIT_PIN(160, "LCD_0_DATA05__GPIO_160__CAM_5_VS__PAR_D02"),
+ P7CTL_INIT_PIN(161, "LCD_0_DATA06__GPIO_161__CAM_5_HS__PAR_D03"),
+ P7CTL_INIT_PIN(162, "LCD_0_DATA07__GPIO_162__CAM_0_DATA08__PAR_D04"),
+ P7CTL_INIT_PIN(163, "LCD_0_DATA08__GPIO_163__CAM_0_DATA09__PAR_D05"),
+ P7CTL_INIT_PIN(164, "LCD_0_DATA09__GPIO_164__CAM_0_DATA10__PAR_D06"),
+ P7CTL_INIT_PIN(165, "LCD_0_DATA10__GPIO_165__CAM_0_DATA11__PAR_D07"),
+ P7CTL_INIT_PIN(166, "LCD_0_DATA11__GPIO_166__CAM_0_DATA12__PAR_D08"),
+ P7CTL_INIT_PIN(167, "LCD_0_DATA12__GPIO_167__CAM_0_DATA13__PAR_D09"),
+ P7CTL_INIT_PIN(168, "LCD_0_DATA13__GPIO_168__CAM_0_DATA14__PAR_D10"),
+ P7CTL_INIT_PIN(169, "LCD_0_DATA14__GPIO_169__CAM_0_DATA15__PAR_D11"),
+ P7CTL_INIT_PIN(170, "LCD_0_DATA15__GPIO_170__CAM_0_DATA16__PAR_D12"),
+ P7CTL_INIT_PIN(171, "LCD_0_DATA16__GPIO_171__CAM_0_DATA17__PAR_D13"),
+ P7CTL_INIT_PIN(172, "LCD_0_DATA17__GPIO_172__CAM_0_DATA18__PAR_D14"),
+ P7CTL_INIT_PIN(173, "LCD_0_DATA18__GPIO_173__CAM_0_DATA19__PAR_D15"),
+ P7CTL_INIT_PIN(174, "LCD_0_DATA19__GPIO_174__CAM_0_DATA20"),
+ P7CTL_INIT_PIN(175, "LCD_0_DATA20__GPIO_175__CAM_0_DATA21"),
+ P7CTL_INIT_PIN(176, "LCD_0_DATA21__GPIO_176__CAM_0_DATA22"),
+ P7CTL_INIT_PIN(177, "LCD_0_DATA22__GPIO_177__CAM_0_DATA23"),
+ P7CTL_INIT_PIN(178, "LCD_0_DATA23__GPIO_178__CAM_4_VS"),
+ P7CTL_INIT_PIN(179, "LCD_0_CLK__GPIO_179__CAM_4_HS"),
+ P7CTL_INIT_PIN(180, "LCD_1_HS__GPIO_180__CAM_2_CLK__LCD_1_DENa"),
+ P7CTL_INIT_PIN(181, "LCD_1_VS__GPIO_181__CAM_2_DATA00__CPU_TRACECLKOUT"),
+ P7CTL_INIT_PIN(182, "LCD_1_CLK__GPIO_182__CAM_2_DATA01__CPU_TRACECTL"),
+ P7CTL_INIT_PIN(183, "LCD_1_DATA00__GPIO_183__CAM_2_DATA02__CPU_TRACEDATA_00"),
+ P7CTL_INIT_PIN(184, "LCD_1_DATA01__GPIO_184__CAM_2_DATA03__CPU_TRACEDATA_01"),
+ P7CTL_INIT_PIN(185, "LCD_1_DATA02__GPIO_185__CAM_2_DATA04__CPU_TRACEDATA_02"),
+ P7CTL_INIT_PIN(186, "LCD_1_DATA03__GPIO_186__CAM_2_DATA05__CPU_TRACEDATA_03"),
+ P7CTL_INIT_PIN(187, "LCD_1_DATA04__GPIO_187__CAM_2_DATA06__CPU_TRACEDATA_04"),
+ P7CTL_INIT_PIN(188, "LCD_1_DATA05__GPIO_188__CAM_2_DATA07__CPU_TRACEDATA_05"),
+ P7CTL_INIT_PIN(189, "LCD_1_DATA06__GPIO_189__CAM_3_CLK__CPU_TRACEDATA_06"),
+ P7CTL_INIT_PIN(190, "LCD_1_DATA07__GPIO_190__CAM_3_DATA00__CPU_TRACEDATA_07"),
+ P7CTL_INIT_PIN(191, "LCD_1_DATA08__GPIO_191__CAM_3_DATA01__CPU_TRACEDATA_08"),
+ P7CTL_INIT_PIN(192, "LCD_1_DATA09__GPIO_192__CAM_3_DATA02__CPU_TRACEDATA_09"),
+ P7CTL_INIT_PIN(193, "LCD_1_DATA10__GPIO_193__CAM_3_DATA03__CPU_TRACEDATA_10"),
+ P7CTL_INIT_PIN(194, "LCD_1_DATA11__GPIO_194__CAM_3_DATA04__CPU_TRACEDATA_11"),
+ P7CTL_INIT_PIN(195, "LCD_1_DATA12__GPIO_195__CAM_3_DATA05__CPU_TRACEDATA_12"),
+ P7CTL_INIT_PIN(196, "LCD_1_DATA13__GPIO_196__CAM_3_DATA06__CPU_TRACEDATA_13"),
+ P7CTL_INIT_PIN(197, "LCD_1_DATA14__GPIO_197__CAM_3_DATA07__CPU_TRACEDATA_14"),
+ P7CTL_INIT_PIN(198, "LCD_1_DATA15__GPIO_198__CAM_4_CLK__CPU_TRACEDATA_15"),
+ P7CTL_INIT_PIN(199, "LCD_1_DATA16__GPIO_199__CAM_4_DATA00"),
+ P7CTL_INIT_PIN(200, "LCD_1_DATA17__GPIO_200__CAM_4_DATA01"),
+ P7CTL_INIT_PIN(201, "LCD_1_DATA18__GPIO_201__CAM_4_DATA02"),
+ P7CTL_INIT_PIN(202, "LCD_1_DATA19__GPIO_202__CAM_4_DATA03"),
+ P7CTL_INIT_PIN(203, "LCD_1_DATA20__GPIO_203__CAM_4_DATA04"),
+ P7CTL_INIT_PIN(204, "LCD_1_DATA21__GPIO_204__CAM_4_DATA05"),
+ P7CTL_INIT_PIN(205, "LCD_1_DATA22__GPIO_205__CAM_4_DATA06"),
+ P7CTL_INIT_PIN(206, "LCD_1_DATA23__GPIO_206__CAM_4_DATA07"),
+ P7CTL_INIT_PIN(207, "LCD_1_DEN__GPIO_207__CAM_1_HSa__LCD_1_CLKa"),
+ P7CTL_INIT_PIN(208, "CAM_0_CLK__GPIO_208"),
+ P7CTL_INIT_PIN(209, "CAM_0_DATA00__GPIO_209__CAM_1_DATA08"),
+ P7CTL_INIT_PIN(210, "CAM_0_DATA01__GPIO_210__CAM_1_DATA09"),
+ P7CTL_INIT_PIN(211, "CAM_0_DATA02__GPIO_211__CAM_1_DATA10"),
+ P7CTL_INIT_PIN(212, "CAM_0_DATA03__GPIO_212__CAM_1_DATA11"),
+ P7CTL_INIT_PIN(213, "CAM_0_DATA04__GPIO_213__CAM_1_DATA12"),
+ P7CTL_INIT_PIN(214, "CAM_0_DATA05__GPIO_214__CAM_1_DATA13"),
+ P7CTL_INIT_PIN(215, "CAM_0_DATA06__GPIO_215__CAM_1_DATA14"),
+ P7CTL_INIT_PIN(216, "CAM_0_DATA07__GPIO_216__CAM_1_DATA15"),
+ P7CTL_INIT_PIN(217, "CAM_1_CLK__GPIO_217__SPI_00b"),
+ P7CTL_INIT_PIN(218, "CAM_1_DATA00__GPIO_218__SPI_01b__CAM_0_VSa"),
+ P7CTL_INIT_PIN(219, "CAM_1_DATA01__GPIO_219__SPI_02b__CAM_0_HSa")
+};
+
+/* Pinmux functions */
+static struct p7ctl_function const p7_pin_funcs_r2[P7_N_FUNCTIONS] = {
+ [P7_CAM_1_DATA02] = P7CTL_INIT_FUNC(CAM_1_DATA02, 0, 0),
+ [P7_GPIO_000] = P7CTL_INIT_FUNC(GPIO_000, 0, 1),
+ [P7_SPI_03b] = P7CTL_INIT_FUNC(SPI_03b, 0, 2),
+ [P7_CAM_3_VSa] = P7CTL_INIT_FUNC(CAM_3_VSa, 0, 3),
+ [P7_CAM_1_DATA03] = P7CTL_INIT_FUNC(CAM_1_DATA03, 1, 0),
+ [P7_GPIO_001] = P7CTL_INIT_FUNC(GPIO_001, 1, 1),
+ [P7_SPI_04b] = P7CTL_INIT_FUNC(SPI_04b, 1, 2),
+ [P7_CAM_3_HSa] = P7CTL_INIT_FUNC(CAM_3_HSa, 1, 3),
+ [P7_CAM_1_DATA04] = P7CTL_INIT_FUNC(CAM_1_DATA04, 2, 0),
+ [P7_GPIO_002] = P7CTL_INIT_FUNC(GPIO_002, 2, 1),
+ [P7_SPI_05b] = P7CTL_INIT_FUNC(SPI_05b, 2, 2),
+ [P7_CAM_4_VSa] = P7CTL_INIT_FUNC(CAM_4_VSa, 2, 3),
+ [P7_CAM_1_DATA05] = P7CTL_INIT_FUNC(CAM_1_DATA05, 3, 0),
+ [P7_GPIO_003] = P7CTL_INIT_FUNC(GPIO_003, 3, 1),
+ [P7_SPI_06b] = P7CTL_INIT_FUNC(SPI_06b, 3, 2),
+ [P7_CAM_4_HSa] = P7CTL_INIT_FUNC(CAM_4_HSa, 3, 3),
+ [P7_CAM_1_DATA06] = P7CTL_INIT_FUNC(CAM_1_DATA06, 4, 0),
+ [P7_GPIO_004] = P7CTL_INIT_FUNC(GPIO_004, 4, 1),
+ [P7_SPI_07b] = P7CTL_INIT_FUNC(SPI_07b, 4, 2),
+ [P7_CAM_5_VSa] = P7CTL_INIT_FUNC(CAM_5_VSa, 4, 3),
+ [P7_CAM_1_DATA07] = P7CTL_INIT_FUNC(CAM_1_DATA07, 5, 0),
+ [P7_GPIO_005] = P7CTL_INIT_FUNC(GPIO_005, 5, 1),
+ [P7_SPI_08b] = P7CTL_INIT_FUNC(SPI_08b, 5, 2),
+ [P7_CAM_5_HSa] = P7CTL_INIT_FUNC(CAM_5_HSa, 5, 3),
+ [P7_CAM_5_CLK] = P7CTL_INIT_FUNC(CAM_5_CLK, 6, 0),
+ [P7_GPIO_006] = P7CTL_INIT_FUNC(GPIO_006, 6, 1),
+ [P7_SD_2_CLK] = P7CTL_INIT_FUNC(SD_2_CLK, 6, 2),
+ [P7_CAM_5_DATA00] = P7CTL_INIT_FUNC(CAM_5_DATA00, 7, 0),
+ [P7_GPIO_007] = P7CTL_INIT_FUNC(GPIO_007, 7, 1),
+ [P7_SD_2_CMD] = P7CTL_INIT_FUNC(SD_2_CMD, 7, 2),
+ [P7_CAM_5_DATA01] = P7CTL_INIT_FUNC(CAM_5_DATA01, 8, 0),
+ [P7_GPIO_008] = P7CTL_INIT_FUNC(GPIO_008, 8, 1),
+ [P7_SD_2_DAT00] = P7CTL_INIT_FUNC(SD_2_DAT00, 8, 2),
+ [P7_CAM_5_DATA02] = P7CTL_INIT_FUNC(CAM_5_DATA02, 9, 0),
+ [P7_GPIO_009] = P7CTL_INIT_FUNC(GPIO_009, 9, 1),
+ [P7_SD_2_DAT01] = P7CTL_INIT_FUNC(SD_2_DAT01, 9, 2),
+ [P7_CAM_5_DATA03] = P7CTL_INIT_FUNC(CAM_5_DATA03, 10, 0),
+ [P7_GPIO_010] = P7CTL_INIT_FUNC(GPIO_010, 10, 1),
+ [P7_SD_2_DAT02] = P7CTL_INIT_FUNC(SD_2_DAT02, 10, 2),
+ [P7_CAM_5_DATA04] = P7CTL_INIT_FUNC(CAM_5_DATA04, 11, 0),
+ [P7_GPIO_011] = P7CTL_INIT_FUNC(GPIO_011, 11, 1),
+ [P7_SD_2_DAT03] = P7CTL_INIT_FUNC(SD_2_DAT03, 11, 2),
+ [P7_CAM_5_DATA05] = P7CTL_INIT_FUNC(CAM_5_DATA05, 12, 0),
+ [P7_GPIO_012] = P7CTL_INIT_FUNC(GPIO_012, 12, 1),
+ [P7_CAM_5_DATA06] = P7CTL_INIT_FUNC(CAM_5_DATA06, 13, 0),
+ [P7_GPIO_013] = P7CTL_INIT_FUNC(GPIO_013, 13, 1),
+ [P7_CAM_5_DATA07] = P7CTL_INIT_FUNC(CAM_5_DATA07, 14, 0),
+ [P7_GPIO_014] = P7CTL_INIT_FUNC(GPIO_014, 14, 1),
+ [P7_SD_1_CLK] = P7CTL_INIT_FUNC(SD_1_CLK, 15, 0),
+ [P7_UART_5_TX] = P7CTL_INIT_FUNC(UART_5_TX, 15, 2),
+ [P7_SD_1_CMD] = P7CTL_INIT_FUNC(SD_1_CMD, 16, 0),
+ [P7_UART_5_RX] = P7CTL_INIT_FUNC(UART_5_RX, 16, 2),
+ [P7_SD_1_DAT00] = P7CTL_INIT_FUNC(SD_1_DAT00, 17, 0),
+ [P7_UART_6_TX] = P7CTL_INIT_FUNC(UART_6_TX, 17, 2),
+ [P7_SD_1_DAT02] = P7CTL_INIT_FUNC(SD_1_DAT02, 18, 0),
+ [P7_UART_7_TX] = P7CTL_INIT_FUNC(UART_7_TX, 18, 2),
+ [P7_SD_1_DAT01] = P7CTL_INIT_FUNC(SD_1_DAT01, 19, 0),
+ [P7_UART_6_RX] = P7CTL_INIT_FUNC(UART_6_RX, 19, 2),
+ [P7_SD_1_DAT03] = P7CTL_INIT_FUNC(SD_1_DAT03, 20, 0),
+ [P7_UART_7_RX] = P7CTL_INIT_FUNC(UART_7_RX, 20, 2),
+ [P7_SD_0_CLK] = P7CTL_INIT_FUNC(SD_0_CLK, 21, 0),
+ [P7_SD_0_CMD] = P7CTL_INIT_FUNC(SD_0_CMD, 22, 0),
+ [P7_SD_0_DAT00] = P7CTL_INIT_FUNC(SD_0_DAT00, 23, 0),
+ [P7_SD_0_DAT01] = P7CTL_INIT_FUNC(SD_0_DAT01, 24, 0),
+ [P7_SD_0_DAT02] = P7CTL_INIT_FUNC(SD_0_DAT02, 25, 0),
+ [P7_SD_0_DAT03] = P7CTL_INIT_FUNC(SD_0_DAT03, 26, 0),
+ [P7_NAND_NCE] = P7CTL_INIT_FUNC(NAND_NCE, 27, 0),
+ [P7_SPI_00a] = P7CTL_INIT_FUNC(SPI_00a, 27, 2),
+ [P7_NAND_NR] = P7CTL_INIT_FUNC(NAND_NR, 28, 0),
+ [P7_SPI_01a] = P7CTL_INIT_FUNC(SPI_01a, 28, 2),
+ [P7_NAND_NW] = P7CTL_INIT_FUNC(NAND_NW, 29, 0),
+ [P7_SPI_02a] = P7CTL_INIT_FUNC(SPI_02a, 29, 2),
+ [P7_NAND_AL] = P7CTL_INIT_FUNC(NAND_AL, 30, 0),
+ [P7_SPI_03a] = P7CTL_INIT_FUNC(SPI_03a, 30, 2),
+ [P7_NAND_CL] = P7CTL_INIT_FUNC(NAND_CL, 31, 0),
+ [P7_SPI_04a] = P7CTL_INIT_FUNC(SPI_04a, 31, 2),
+ [P7_NAND_RNB] = P7CTL_INIT_FUNC(NAND_RNB, 32, 0),
+ [P7_SPI_05a] = P7CTL_INIT_FUNC(SPI_05a, 32, 2),
+ [P7_NAND_DQS] = P7CTL_INIT_FUNC(NAND_DQS, 33, 0),
+ [P7_GPIO_033] = P7CTL_INIT_FUNC(GPIO_033, 33, 1),
+ [P7_CAN1_RXa] = P7CTL_INIT_FUNC(CAN1_RXa, 33, 2),
+ [P7_NAND_DATA_00] = P7CTL_INIT_FUNC(NAND_DATA_00, 34, 0),
+ [P7_SPI_06a] = P7CTL_INIT_FUNC(SPI_06a, 34, 2),
+ [P7_NAND_DATA_01] = P7CTL_INIT_FUNC(NAND_DATA_01, 35, 0),
+ [P7_SPI_07a] = P7CTL_INIT_FUNC(SPI_07a, 35, 2),
+ [P7_NAND_DATA_02] = P7CTL_INIT_FUNC(NAND_DATA_02, 36, 0),
+ [P7_SPI_08a] = P7CTL_INIT_FUNC(SPI_08a, 36, 2),
+ [P7_NAND_DATA_03] = P7CTL_INIT_FUNC(NAND_DATA_03, 37, 0),
+ [P7_SPI_09a] = P7CTL_INIT_FUNC(SPI_09a, 37, 2),
+ [P7_NAND_DATA_04] = P7CTL_INIT_FUNC(NAND_DATA_04, 38, 0),
+ [P7_GPIO_038] = P7CTL_INIT_FUNC(GPIO_038, 38, 1),
+ [P7_NAND_DATA_05] = P7CTL_INIT_FUNC(NAND_DATA_05, 39, 0),
+ [P7_GPIO_039] = P7CTL_INIT_FUNC(GPIO_039, 39, 1),
+ [P7_NAND_DATA_06] = P7CTL_INIT_FUNC(NAND_DATA_06, 40, 0),
+ [P7_GPIO_040] = P7CTL_INIT_FUNC(GPIO_040, 40, 1),
+ [P7_NAND_DATA_07] = P7CTL_INIT_FUNC(NAND_DATA_07, 41, 0),
+ [P7_GPIO_041] = P7CTL_INIT_FUNC(GPIO_041, 41, 1),
+ [P7_NAND_WP] = P7CTL_INIT_FUNC(NAND_WP, 42, 0),
+ [P7_GPIO_042] = P7CTL_INIT_FUNC(GPIO_042, 42, 1),
+ [P7_CAN1_TXa] = P7CTL_INIT_FUNC(CAN1_TXa, 42, 2),
+ [P7_FORCE_POWER_ON] = P7CTL_INIT_FUNC(FORCE_POWER_ON, 43, 0),
+ [P7_TRST_N] = P7CTL_INIT_FUNC(TRST_N, 44, 0),
+ [P7_TDI] = P7CTL_INIT_FUNC(TDI, 45, 0),
+ [P7_TDO] = P7CTL_INIT_FUNC(TDO, 46, 0),
+ [P7_TCK] = P7CTL_INIT_FUNC(TCK, 47, 0),
+ [P7_TMS] = P7CTL_INIT_FUNC(TMS, 48, 0),
+ [P7_GPIO_049] = P7CTL_INIT_FUNC(GPIO_049, 49, 1),
+ [P7_GPIO_050] = P7CTL_INIT_FUNC(GPIO_050, 50, 1),
+ [P7_UART_1_RX] = P7CTL_INIT_FUNC(UART_1_RX, 51, 0),
+ [P7_UART_1_TX] = P7CTL_INIT_FUNC(UART_1_TX, 52, 0),
+ [P7_UART_1_RTS] = P7CTL_INIT_FUNC(UART_1_RTS, 53, 0),
+ [P7_CAN0_RXb] = P7CTL_INIT_FUNC(CAN0_RXb, 53, 2),
+ [P7_UART_1_CTS] = P7CTL_INIT_FUNC(UART_1_CTS, 54, 0),
+ [P7_CAN0_TXb] = P7CTL_INIT_FUNC(CAN0_TXb, 54, 2),
+ [P7_UART_0_RX] = P7CTL_INIT_FUNC(UART_0_RX, 55, 0),
+ [P7_GPIO_055] = P7CTL_INIT_FUNC(GPIO_055, 55, 1),
+ [P7_UART_0_TX] = P7CTL_INIT_FUNC(UART_0_TX, 56, 0),
+ [P7_GPIO_056] = P7CTL_INIT_FUNC(GPIO_056, 56, 1),
+ [P7_UART_0_RTS] = P7CTL_INIT_FUNC(UART_0_RTS, 57, 0),
+ [P7_GPIO_057] = P7CTL_INIT_FUNC(GPIO_057, 57, 1),
+ [P7_UART_0_CTS] = P7CTL_INIT_FUNC(UART_0_CTS, 58, 0),
+ [P7_GPIO_058] = P7CTL_INIT_FUNC(GPIO_058, 58, 1),
+ [P7_I2C_2_DAT] = P7CTL_INIT_FUNC(I2C_2_DAT, 59, 0),
+ [P7_GPIO_059] = P7CTL_INIT_FUNC(GPIO_059, 59, 1),
+ [P7_I2C_2_SL_DAT] = P7CTL_INIT_FUNC(I2C_2_SL_DAT, 59, 2),
+ [P7_I2C_2_CLK] = P7CTL_INIT_FUNC(I2C_2_CLK, 60, 0),
+ [P7_GPIO_060] = P7CTL_INIT_FUNC(GPIO_060, 60, 1),
+ [P7_I2C_2_SL_CLK] = P7CTL_INIT_FUNC(I2C_2_SL_CLK, 60, 2),
+ [P7_I2C_1_DAT] = P7CTL_INIT_FUNC(I2C_1_DAT, 61, 0),
+ [P7_GPIO_061] = P7CTL_INIT_FUNC(GPIO_061, 61, 1),
+ [P7_I2C_1_SL_DAT] = P7CTL_INIT_FUNC(I2C_1_SL_DAT, 61, 2),
+ [P7_I2C_1_CLK] = P7CTL_INIT_FUNC(I2C_1_CLK, 62, 0),
+ [P7_GPIO_062] = P7CTL_INIT_FUNC(GPIO_062, 62, 1),
+ [P7_I2C_1_SL_CLK] = P7CTL_INIT_FUNC(I2C_1_SL_CLK, 62, 2),
+ [P7_I2C_0_DAT] = P7CTL_INIT_FUNC(I2C_0_DAT, 63, 0),
+ [P7_GPIO_063] = P7CTL_INIT_FUNC(GPIO_063, 63, 1),
+ [P7_I2C_0_SL_DAT] = P7CTL_INIT_FUNC(I2C_0_SL_DAT, 63, 2),
+ [P7_I2C_0_CLK] = P7CTL_INIT_FUNC(I2C_0_CLK, 64, 0),
+ [P7_GPIO_064] = P7CTL_INIT_FUNC(GPIO_064, 64, 1),
+ [P7_I2C_0_SL_CLK] = P7CTL_INIT_FUNC(I2C_0_SL_CLK, 64, 2),
+ [P7_UART_4_RX] = P7CTL_INIT_FUNC(UART_4_RX, 65, 0),
+ [P7_GPIO_065] = P7CTL_INIT_FUNC(GPIO_065, 65, 1),
+ [P7_UART_4_TX] = P7CTL_INIT_FUNC(UART_4_TX, 66, 0),
+ [P7_GPIO_066] = P7CTL_INIT_FUNC(GPIO_066, 66, 1),
+ [P7_UART_3_RX] = P7CTL_INIT_FUNC(UART_3_RX, 67, 0),
+ [P7_GPIO_067] = P7CTL_INIT_FUNC(GPIO_067, 67, 1),
+ [P7_UART_3_TX] = P7CTL_INIT_FUNC(UART_3_TX, 68, 0),
+ [P7_GPIO_068] = P7CTL_INIT_FUNC(GPIO_068, 68, 1),
+ [P7_UART_2_RX] = P7CTL_INIT_FUNC(UART_2_RX, 69, 0),
+ [P7_CAN1_TXb] = P7CTL_INIT_FUNC(CAN1_TXb, 69, 2),
+ [P7_UART_2_TX] = P7CTL_INIT_FUNC(UART_2_TX, 70, 0),
+ [P7_CAN1_RXb] = P7CTL_INIT_FUNC(CAN1_RXb, 70, 2),
+ [P7_SPI_09b] = P7CTL_INIT_FUNC(SPI_09b, 71, 0),
+ [P7_GPIO_071] = P7CTL_INIT_FUNC(GPIO_071, 71, 1),
+ [P7_PWM_15] = P7CTL_INIT_FUNC(PWM_15, 71, 2),
+ [P7_SPI_10b] = P7CTL_INIT_FUNC(SPI_10b, 72, 0),
+ [P7_GPIO_072] = P7CTL_INIT_FUNC(GPIO_072, 72, 1),
+ [P7_SPI_11b] = P7CTL_INIT_FUNC(SPI_11b, 73, 0),
+ [P7_GPIO_073] = P7CTL_INIT_FUNC(GPIO_073, 73, 1),
+ [P7_SPI_12b] = P7CTL_INIT_FUNC(SPI_12b, 74, 0),
+ [P7_GPIO_074] = P7CTL_INIT_FUNC(GPIO_074, 74, 1),
+ [P7_SPI_13b] = P7CTL_INIT_FUNC(SPI_13b, 75, 0),
+ [P7_GPIO_075] = P7CTL_INIT_FUNC(GPIO_075, 75, 1),
+ [P7_SPI_14b] = P7CTL_INIT_FUNC(SPI_14b, 76, 0),
+ [P7_GPIO_076] = P7CTL_INIT_FUNC(GPIO_076, 76, 1),
+ [P7_SPI_00] = P7CTL_INIT_FUNC(SPI_00, 77, 0),
+ [P7_GPIO_077] = P7CTL_INIT_FUNC(GPIO_077, 77, 1),
+ [P7_AAI_15] = P7CTL_INIT_FUNC(AAI_15, 77, 2),
+ [P7_CAN1_TX] = P7CTL_INIT_FUNC(CAN1_TX, 77, 3),
+ [P7_SPI_01] = P7CTL_INIT_FUNC(SPI_01, 78, 0),
+ [P7_GPIO_078] = P7CTL_INIT_FUNC(GPIO_078, 78, 1),
+ [P7_AAI_16] = P7CTL_INIT_FUNC(AAI_16, 78, 2),
+ [P7_CAN1_RX] = P7CTL_INIT_FUNC(CAN1_RX, 78, 3),
+ [P7_SPI_02] = P7CTL_INIT_FUNC(SPI_02, 79, 0),
+ [P7_GPIO_079] = P7CTL_INIT_FUNC(GPIO_079, 79, 1),
+ [P7_AAI_17] = P7CTL_INIT_FUNC(AAI_17, 79, 2),
+ [P7_CAN0_TX] = P7CTL_INIT_FUNC(CAN0_TX, 79, 3),
+ [P7_SPI_03] = P7CTL_INIT_FUNC(SPI_03, 80, 0),
+ [P7_GPIO_080] = P7CTL_INIT_FUNC(GPIO_080, 80, 1),
+ [P7_AAI_18] = P7CTL_INIT_FUNC(AAI_18, 80, 2),
+ [P7_CAN0_RX] = P7CTL_INIT_FUNC(CAN0_RX, 80, 3),
+ [P7_SPI_04] = P7CTL_INIT_FUNC(SPI_04, 81, 0),
+ [P7_GPIO_081] = P7CTL_INIT_FUNC(GPIO_081, 81, 1),
+ [P7_AAI_19] = P7CTL_INIT_FUNC(AAI_19, 81, 2),
+ [P7_SPI_05] = P7CTL_INIT_FUNC(SPI_05, 82, 0),
+ [P7_GPIO_082] = P7CTL_INIT_FUNC(GPIO_082, 82, 1),
+ [P7_AAI_20] = P7CTL_INIT_FUNC(AAI_20, 82, 2),
+ [P7_SPI_06] = P7CTL_INIT_FUNC(SPI_06, 83, 0),
+ [P7_GPIO_083] = P7CTL_INIT_FUNC(GPIO_083, 83, 1),
+ [P7_AAI_21] = P7CTL_INIT_FUNC(AAI_21, 83, 2),
+ [P7_SPI_07] = P7CTL_INIT_FUNC(SPI_07, 84, 0),
+ [P7_GPIO_084] = P7CTL_INIT_FUNC(GPIO_084, 84, 1),
+ [P7_AAI_22] = P7CTL_INIT_FUNC(AAI_22, 84, 2),
+ [P7_SPI_08] = P7CTL_INIT_FUNC(SPI_08, 85, 0),
+ [P7_GPIO_085] = P7CTL_INIT_FUNC(GPIO_085, 85, 1),
+ [P7_AAI_23] = P7CTL_INIT_FUNC(AAI_23, 85, 2),
+ [P7_SPI_09] = P7CTL_INIT_FUNC(SPI_09, 86, 0),
+ [P7_GPIO_086] = P7CTL_INIT_FUNC(GPIO_086, 86, 1),
+ [P7_AAI_24] = P7CTL_INIT_FUNC(AAI_24, 86, 2),
+ [P7_SPI_10] = P7CTL_INIT_FUNC(SPI_10, 87, 0),
+ [P7_GPIO_087] = P7CTL_INIT_FUNC(GPIO_087, 87, 1),
+ [P7_AAI_25] = P7CTL_INIT_FUNC(AAI_25, 87, 2),
+ [P7_SPI_11] = P7CTL_INIT_FUNC(SPI_11, 88, 0),
+ [P7_GPIO_088] = P7CTL_INIT_FUNC(GPIO_088, 88, 1),
+ [P7_AAI_26] = P7CTL_INIT_FUNC(AAI_26, 88, 2),
+ [P7_SPI_12] = P7CTL_INIT_FUNC(SPI_12, 89, 0),
+ [P7_GPIO_089] = P7CTL_INIT_FUNC(GPIO_089, 89, 1),
+ [P7_AAI_27] = P7CTL_INIT_FUNC(AAI_27, 89, 2),
+ [P7_SPI_13] = P7CTL_INIT_FUNC(SPI_13, 90, 0),
+ [P7_GPIO_090] = P7CTL_INIT_FUNC(GPIO_090, 90, 1),
+ [P7_AAI_28] = P7CTL_INIT_FUNC(AAI_28, 90, 2),
+ [P7_SPI_14] = P7CTL_INIT_FUNC(SPI_14, 91, 0),
+ [P7_GPIO_091] = P7CTL_INIT_FUNC(GPIO_091, 91, 1),
+ [P7_AAI_29] = P7CTL_INIT_FUNC(AAI_29, 91, 2),
+ [P7_SPI_15] = P7CTL_INIT_FUNC(SPI_15, 92, 0),
+ [P7_GPIO_092] = P7CTL_INIT_FUNC(GPIO_092, 92, 1),
+ [P7_AAI_30] = P7CTL_INIT_FUNC(AAI_30, 92, 2),
+ [P7_P7MU_CLK_OUT] = P7CTL_INIT_FUNC(P7MU_CLK_OUT, 93, 0),
+ [P7_PWM_15a] = P7CTL_INIT_FUNC(PWM_15a, 93, 2),
+ [P7_REBOOT_P7MU] = P7CTL_INIT_FUNC(REBOOT_P7MU, 94, 0),
+ [P7_GPIO_094] = P7CTL_INIT_FUNC(GPIO_094, 94, 1),
+ [P7_ULPI_0_DATA00] = P7CTL_INIT_FUNC(ULPI_0_DATA00, 95, 0),
+ [P7_ULPI_0_DATA01] = P7CTL_INIT_FUNC(ULPI_0_DATA01, 96, 0),
+ [P7_ULPI_0_DATA02] = P7CTL_INIT_FUNC(ULPI_0_DATA02, 97, 0),
+ [P7_ULPI_0_DATA03] = P7CTL_INIT_FUNC(ULPI_0_DATA03, 98, 0),
+ [P7_ULPI_0_DATA04] = P7CTL_INIT_FUNC(ULPI_0_DATA04, 99, 0),
+ [P7_ULPI_0_DATA05] = P7CTL_INIT_FUNC(ULPI_0_DATA05, 100, 0),
+ [P7_ULPI_0_DATA06] = P7CTL_INIT_FUNC(ULPI_0_DATA06, 101, 0),
+ [P7_ULPI_0_DATA07] = P7CTL_INIT_FUNC(ULPI_0_DATA07, 102, 0),
+ [P7_ULPI_0_NXT] = P7CTL_INIT_FUNC(ULPI_0_NXT, 103, 0),
+ [P7_ULPI_0_DIR] = P7CTL_INIT_FUNC(ULPI_0_DIR, 104, 0),
+ [P7_ULPI_0_CLK] = P7CTL_INIT_FUNC(ULPI_0_CLK, 105, 0),
+ [P7_ULPI_1_DATA00] = P7CTL_INIT_FUNC(ULPI_1_DATA00, 106, 0),
+ [P7_GPIO_106] = P7CTL_INIT_FUNC(GPIO_106, 106, 1),
+ [P7_I2C_2_CLKa] = P7CTL_INIT_FUNC(I2C_2_CLKa, 106, 2),
+ [P7_ULPI_1_DATA01] = P7CTL_INIT_FUNC(ULPI_1_DATA01, 107, 0),
+ [P7_GPIO_107] = P7CTL_INIT_FUNC(GPIO_107, 107, 1),
+ [P7_I2C_2_DATa] = P7CTL_INIT_FUNC(I2C_2_DATa, 107, 2),
+ [P7_ULPI_1_DATA02] = P7CTL_INIT_FUNC(ULPI_1_DATA02, 108, 0),
+ [P7_GPIO_108] = P7CTL_INIT_FUNC(GPIO_108, 108, 1),
+ [P7_I2C_2_CLKb] = P7CTL_INIT_FUNC(I2C_2_CLKb, 108, 2),
+ [P7_ULPI_1_DATA03] = P7CTL_INIT_FUNC(ULPI_1_DATA03, 109, 0),
+ [P7_GPIO_109] = P7CTL_INIT_FUNC(GPIO_109, 109, 1),
+ [P7_I2C_2_DATb] = P7CTL_INIT_FUNC(I2C_2_DATb, 109, 2),
+ [P7_ULPI_1_DATA04] = P7CTL_INIT_FUNC(ULPI_1_DATA04, 110, 0),
+ [P7_GPIO_110] = P7CTL_INIT_FUNC(GPIO_110, 110, 1),
+ [P7_I2C_2_CLKc] = P7CTL_INIT_FUNC(I2C_2_CLKc, 110, 2),
+ [P7_ULPI_1_DATA05] = P7CTL_INIT_FUNC(ULPI_1_DATA05, 111, 0),
+ [P7_GPIO_111] = P7CTL_INIT_FUNC(GPIO_111, 111, 1),
+ [P7_I2C_2_DATc] = P7CTL_INIT_FUNC(I2C_2_DATc, 111, 2),
+ [P7_ULPI_1_DATA06] = P7CTL_INIT_FUNC(ULPI_1_DATA06, 112, 0),
+ [P7_GPIO_112] = P7CTL_INIT_FUNC(GPIO_112, 112, 1),
+ [P7_I2C_2_CLKd] = P7CTL_INIT_FUNC(I2C_2_CLKd, 112, 2),
+ [P7_ULPI_1_DATA07] = P7CTL_INIT_FUNC(ULPI_1_DATA07, 113, 0),
+ [P7_GPIO_113] = P7CTL_INIT_FUNC(GPIO_113, 113, 1),
+ [P7_I2C_2_DATd] = P7CTL_INIT_FUNC(I2C_2_DATd, 113, 2),
+ [P7_ULPI_1_NXT] = P7CTL_INIT_FUNC(ULPI_1_NXT, 114, 0),
+ [P7_GPIO_114] = P7CTL_INIT_FUNC(GPIO_114, 114, 1),
+ [P7_I2C_2_CLKe] = P7CTL_INIT_FUNC(I2C_2_CLKe, 114, 2),
+ [P7_ULPI_1_DIR] = P7CTL_INIT_FUNC(ULPI_1_DIR, 115, 0),
+ [P7_GPIO_115] = P7CTL_INIT_FUNC(GPIO_115, 115, 1),
+ [P7_ULPI_1_STP] = P7CTL_INIT_FUNC(ULPI_1_STP, 116, 0),
+ [P7_GPIO_116] = P7CTL_INIT_FUNC(GPIO_116, 116, 1),
+ [P7_I2C_2_DATe] = P7CTL_INIT_FUNC(I2C_2_DATe, 116, 2),
+ [P7_ULPI_0_STP] = P7CTL_INIT_FUNC(ULPI_0_STP, 117, 0),
+ [P7_ULPI_1_CLK] = P7CTL_INIT_FUNC(ULPI_1_CLK, 118, 0),
+ [P7_GPIO_118] = P7CTL_INIT_FUNC(GPIO_118, 118, 1),
+ [P7_AAI_00] = P7CTL_INIT_FUNC(AAI_00, 119, 0),
+ [P7_GPIO_119] = P7CTL_INIT_FUNC(GPIO_119, 119, 1),
+ [P7_PWM_00] = P7CTL_INIT_FUNC(PWM_00, 119, 2),
+ [P7_AAI_01] = P7CTL_INIT_FUNC(AAI_01, 120, 0),
+ [P7_GPIO_120] = P7CTL_INIT_FUNC(GPIO_120, 120, 1),
+ [P7_PWM_01] = P7CTL_INIT_FUNC(PWM_01, 120, 2),
+ [P7_AAI_02] = P7CTL_INIT_FUNC(AAI_02, 121, 0),
+ [P7_GPIO_121] = P7CTL_INIT_FUNC(GPIO_121, 121, 1),
+ [P7_PWM_02] = P7CTL_INIT_FUNC(PWM_02, 121, 2),
+ [P7_AAI_03] = P7CTL_INIT_FUNC(AAI_03, 122, 0),
+ [P7_GPIO_122] = P7CTL_INIT_FUNC(GPIO_122, 122, 1),
+ [P7_PWM_03] = P7CTL_INIT_FUNC(PWM_03, 122, 2),
+ [P7_AAI_04] = P7CTL_INIT_FUNC(AAI_04, 123, 0),
+ [P7_GPIO_123] = P7CTL_INIT_FUNC(GPIO_123, 123, 1),
+ [P7_PWM_04] = P7CTL_INIT_FUNC(PWM_04, 123, 2),
+ [P7_AAI_05] = P7CTL_INIT_FUNC(AAI_05, 124, 0),
+ [P7_GPIO_124] = P7CTL_INIT_FUNC(GPIO_124, 124, 1),
+ [P7_PWM_05] = P7CTL_INIT_FUNC(PWM_05, 124, 2),
+ [P7_AAI_06] = P7CTL_INIT_FUNC(AAI_06, 125, 0),
+ [P7_GPIO_125] = P7CTL_INIT_FUNC(GPIO_125, 125, 1),
+ [P7_PWM_06] = P7CTL_INIT_FUNC(PWM_06, 125, 2),
+ [P7_AAI_07] = P7CTL_INIT_FUNC(AAI_07, 126, 0),
+ [P7_GPIO_126] = P7CTL_INIT_FUNC(GPIO_126, 126, 1),
+ [P7_PWM_07] = P7CTL_INIT_FUNC(PWM_07, 126, 2),
+ [P7_AAI_08] = P7CTL_INIT_FUNC(AAI_08, 127, 0),
+ [P7_GPIO_127] = P7CTL_INIT_FUNC(GPIO_127, 127, 1),
+ [P7_PWM_08] = P7CTL_INIT_FUNC(PWM_08, 127, 2),
+ [P7_AAI_09] = P7CTL_INIT_FUNC(AAI_09, 128, 0),
+ [P7_GPIO_128] = P7CTL_INIT_FUNC(GPIO_128, 128, 1),
+ [P7_PWM_09] = P7CTL_INIT_FUNC(PWM_09, 128, 2),
+ [P7_AAI_10] = P7CTL_INIT_FUNC(AAI_10, 129, 0),
+ [P7_GPIO_129] = P7CTL_INIT_FUNC(GPIO_129, 129, 1),
+ [P7_PWM_10] = P7CTL_INIT_FUNC(PWM_10, 129, 2),
+ [P7_AAI_11] = P7CTL_INIT_FUNC(AAI_11, 130, 0),
+ [P7_GPIO_130] = P7CTL_INIT_FUNC(GPIO_130, 130, 1),
+ [P7_PWM_11] = P7CTL_INIT_FUNC(PWM_11, 130, 2),
+ [P7_AAI_12] = P7CTL_INIT_FUNC(AAI_12, 131, 0),
+ [P7_GPIO_131] = P7CTL_INIT_FUNC(GPIO_131, 131, 1),
+ [P7_PWM_12] = P7CTL_INIT_FUNC(PWM_12, 131, 2),
+ [P7_AAI_13] = P7CTL_INIT_FUNC(AAI_13, 132, 0),
+ [P7_GPIO_132] = P7CTL_INIT_FUNC(GPIO_132, 132, 1),
+ [P7_PWM_13] = P7CTL_INIT_FUNC(PWM_13, 132, 2),
+ [P7_AAI_14] = P7CTL_INIT_FUNC(AAI_14, 133, 0),
+ [P7_GPIO_133] = P7CTL_INIT_FUNC(GPIO_133, 133, 1),
+ [P7_PWM_14] = P7CTL_INIT_FUNC(PWM_14, 133, 2),
+ [P7_SPI_16] = P7CTL_INIT_FUNC(SPI_16, 134, 0),
+ [P7_GPIO_134] = P7CTL_INIT_FUNC(GPIO_134, 134, 1),
+ [P7_ETH_MII_TXER] = P7CTL_INIT_FUNC(ETH_MII_TXER, 134, 2),
+ [P7_SPI_17] = P7CTL_INIT_FUNC(SPI_17, 135, 0),
+ [P7_GPIO_135] = P7CTL_INIT_FUNC(GPIO_135, 135, 1),
+ [P7_ETH_MII_RXER] = P7CTL_INIT_FUNC(ETH_MII_RXER, 135, 2),
+ [P7_SPI_18] = P7CTL_INIT_FUNC(SPI_18, 136, 0),
+ [P7_GPIO_136] = P7CTL_INIT_FUNC(GPIO_136, 136, 1),
+ [P7_ETH_MII_CRS] = P7CTL_INIT_FUNC(ETH_MII_CRS, 136, 2),
+ [P7_SPI_19] = P7CTL_INIT_FUNC(SPI_19, 137, 0),
+ [P7_GPIO_137] = P7CTL_INIT_FUNC(GPIO_137, 137, 1),
+ [P7_ETH_MII_COL] = P7CTL_INIT_FUNC(ETH_MII_COL, 137, 2),
+ [P7_ETH_RGMII_TXC] = P7CTL_INIT_FUNC(ETH_RGMII_TXC, 138, 0),
+ [P7_GPIO_138] = P7CTL_INIT_FUNC(GPIO_138, 138, 1),
+ [P7_ETH_RGMII_TXD_00] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_00, 139, 0),
+ [P7_GPIO_139] = P7CTL_INIT_FUNC(GPIO_139, 139, 1),
+ [P7_ETH_RGMII_TXD_01] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_01, 140, 0),
+ [P7_GPIO_140] = P7CTL_INIT_FUNC(GPIO_140, 140, 1),
+ [P7_ETH_RGMII_TXD_02] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_02, 141, 0),
+ [P7_GPIO_141] = P7CTL_INIT_FUNC(GPIO_141, 141, 1),
+ [P7_ETH_RGMII_TXD_03] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_03, 142, 0),
+ [P7_GPIO_142] = P7CTL_INIT_FUNC(GPIO_142, 142, 1),
+ [P7_ETH_RGMII_TX_CTL] = P7CTL_INIT_FUNC(ETH_RGMII_TX_CTL, 143, 0),
+ [P7_GPIO_143] = P7CTL_INIT_FUNC(GPIO_143, 143, 1),
+ [P7_ETH_RGMII_RXC] = P7CTL_INIT_FUNC(ETH_RGMII_RXC, 144, 0),
+ [P7_GPIO_144] = P7CTL_INIT_FUNC(GPIO_144, 144, 1),
+ [P7_ETH_RGMII_RXD_00] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_00, 145, 0),
+ [P7_GPIO_145] = P7CTL_INIT_FUNC(GPIO_145, 145, 1),
+ [P7_ETH_RGMII_RXD_01] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_01, 146, 0),
+ [P7_GPIO_146] = P7CTL_INIT_FUNC(GPIO_146, 146, 1),
+ [P7_ETH_RGMII_RXD_02] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_02, 147, 0),
+ [P7_GPIO_147] = P7CTL_INIT_FUNC(GPIO_147, 147, 1),
+ [P7_ETH_RGMII_RXD_03] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_03, 148, 0),
+ [P7_GPIO_148] = P7CTL_INIT_FUNC(GPIO_148, 148, 1),
+ [P7_ETH_RGMII_RX_CTL] = P7CTL_INIT_FUNC(ETH_RGMII_RX_CTL, 149, 0),
+ [P7_GPIO_149] = P7CTL_INIT_FUNC(GPIO_149, 149, 1),
+ [P7_ETH_MDC] = P7CTL_INIT_FUNC(ETH_MDC, 150, 0),
+ [P7_GPIO_150] = P7CTL_INIT_FUNC(GPIO_150, 150, 1),
+ [P7_ETH_MDIO] = P7CTL_INIT_FUNC(ETH_MDIO, 151, 0),
+ [P7_GPIO_151] = P7CTL_INIT_FUNC(GPIO_151, 151, 1),
+ [P7_LCD_0_DEN] = P7CTL_INIT_FUNC(LCD_0_DEN, 152, 0),
+ [P7_GPIO_152] = P7CTL_INIT_FUNC(GPIO_152, 152, 1),
+ [P7_CAM_1_VS] = P7CTL_INIT_FUNC(CAM_1_VS, 152, 2),
+ [P7_LCD_0_HS] = P7CTL_INIT_FUNC(LCD_0_HS, 153, 0),
+ [P7_GPIO_153] = P7CTL_INIT_FUNC(GPIO_153, 153, 1),
+ [P7_CAM_1_HS] = P7CTL_INIT_FUNC(CAM_1_HS, 153, 2),
+ [P7_LCD_0_DENa] = P7CTL_INIT_FUNC(LCD_0_DENa, 153, 3),
+ [P7_LCD_0_VS] = P7CTL_INIT_FUNC(LCD_0_VS, 154, 0),
+ [P7_GPIO_154] = P7CTL_INIT_FUNC(GPIO_154, 154, 1),
+ [P7_CAM_0_VS] = P7CTL_INIT_FUNC(CAM_0_VS, 154, 2),
+ [P7_PAR_NCS] = P7CTL_INIT_FUNC(PAR_NCS, 154, 3),
+ [P7_LCD_0_DATA00] = P7CTL_INIT_FUNC(LCD_0_DATA00, 155, 0),
+ [P7_GPIO_155] = P7CTL_INIT_FUNC(GPIO_155, 155, 1),
+ [P7_CAM_0_HS] = P7CTL_INIT_FUNC(CAM_0_HS, 155, 2),
+ [P7_PAR_NRS] = P7CTL_INIT_FUNC(PAR_NRS, 155, 3),
+ [P7_LCD_0_DATA01] = P7CTL_INIT_FUNC(LCD_0_DATA01, 156, 0),
+ [P7_GPIO_156] = P7CTL_INIT_FUNC(GPIO_156, 156, 1),
+ [P7_CAM_2_VS] = P7CTL_INIT_FUNC(CAM_2_VS, 156, 2),
+ [P7_PAR_NRD] = P7CTL_INIT_FUNC(PAR_NRD, 156, 3),
+ [P7_LCD_0_DATA02] = P7CTL_INIT_FUNC(LCD_0_DATA02, 157, 0),
+ [P7_GPIO_157] = P7CTL_INIT_FUNC(GPIO_157, 157, 1),
+ [P7_CAM_2_HS] = P7CTL_INIT_FUNC(CAM_2_HS, 157, 2),
+ [P7_PAR_NWR] = P7CTL_INIT_FUNC(PAR_NWR, 157, 3),
+ [P7_LCD_0_DATA03] = P7CTL_INIT_FUNC(LCD_0_DATA03, 158, 0),
+ [P7_GPIO_158] = P7CTL_INIT_FUNC(GPIO_158, 158, 1),
+ [P7_CAM_3_VS] = P7CTL_INIT_FUNC(CAM_3_VS, 158, 2),
+ [P7_PAR_D00] = P7CTL_INIT_FUNC(PAR_D00, 158, 3),
+ [P7_LCD_0_DATA04] = P7CTL_INIT_FUNC(LCD_0_DATA04, 159, 0),
+ [P7_GPIO_159] = P7CTL_INIT_FUNC(GPIO_159, 159, 1),
+ [P7_CAM_3_HS] = P7CTL_INIT_FUNC(CAM_3_HS, 159, 2),
+ [P7_PAR_D01] = P7CTL_INIT_FUNC(PAR_D01, 159, 3),
+ [P7_LCD_0_DATA05] = P7CTL_INIT_FUNC(LCD_0_DATA05, 160, 0),
+ [P7_GPIO_160] = P7CTL_INIT_FUNC(GPIO_160, 160, 1),
+ [P7_CAM_5_VS] = P7CTL_INIT_FUNC(CAM_5_VS, 160, 2),
+ [P7_PAR_D02] = P7CTL_INIT_FUNC(PAR_D02, 160, 3),
+ [P7_LCD_0_DATA06] = P7CTL_INIT_FUNC(LCD_0_DATA06, 161, 0),
+ [P7_GPIO_161] = P7CTL_INIT_FUNC(GPIO_161, 161, 1),
+ [P7_CAM_5_HS] = P7CTL_INIT_FUNC(CAM_5_HS, 161, 2),
+ [P7_PAR_D03] = P7CTL_INIT_FUNC(PAR_D03, 161, 3),
+ [P7_LCD_0_DATA07] = P7CTL_INIT_FUNC(LCD_0_DATA07, 162, 0),
+ [P7_GPIO_162] = P7CTL_INIT_FUNC(GPIO_162, 162, 1),
+ [P7_CAM_0_DATA08] = P7CTL_INIT_FUNC(CAM_0_DATA08, 162, 2),
+ [P7_PAR_D04] = P7CTL_INIT_FUNC(PAR_D04, 162, 3),
+ [P7_LCD_0_DATA08] = P7CTL_INIT_FUNC(LCD_0_DATA08, 163, 0),
+ [P7_GPIO_163] = P7CTL_INIT_FUNC(GPIO_163, 163, 1),
+ [P7_CAM_0_DATA09] = P7CTL_INIT_FUNC(CAM_0_DATA09, 163, 2),
+ [P7_PAR_D05] = P7CTL_INIT_FUNC(PAR_D05, 163, 3),
+ [P7_LCD_0_DATA09] = P7CTL_INIT_FUNC(LCD_0_DATA09, 164, 0),
+ [P7_GPIO_164] = P7CTL_INIT_FUNC(GPIO_164, 164, 1),
+ [P7_CAM_0_DATA10] = P7CTL_INIT_FUNC(CAM_0_DATA10, 164, 2),
+ [P7_PAR_D06] = P7CTL_INIT_FUNC(PAR_D06, 164, 3),
+ [P7_LCD_0_DATA10] = P7CTL_INIT_FUNC(LCD_0_DATA10, 165, 0),
+ [P7_GPIO_165] = P7CTL_INIT_FUNC(GPIO_165, 165, 1),
+ [P7_CAM_0_DATA11] = P7CTL_INIT_FUNC(CAM_0_DATA11, 165, 2),
+ [P7_PAR_D07] = P7CTL_INIT_FUNC(PAR_D07, 165, 3),
+ [P7_LCD_0_DATA11] = P7CTL_INIT_FUNC(LCD_0_DATA11, 166, 0),
+ [P7_GPIO_166] = P7CTL_INIT_FUNC(GPIO_166, 166, 1),
+ [P7_CAM_0_DATA12] = P7CTL_INIT_FUNC(CAM_0_DATA12, 166, 2),
+ [P7_PAR_D08] = P7CTL_INIT_FUNC(PAR_D08, 166, 3),
+ [P7_LCD_0_DATA12] = P7CTL_INIT_FUNC(LCD_0_DATA12, 167, 0),
+ [P7_GPIO_167] = P7CTL_INIT_FUNC(GPIO_167, 167, 1),
+ [P7_CAM_0_DATA13] = P7CTL_INIT_FUNC(CAM_0_DATA13, 167, 2),
+ [P7_PAR_D09] = P7CTL_INIT_FUNC(PAR_D09, 167, 3),
+ [P7_LCD_0_DATA13] = P7CTL_INIT_FUNC(LCD_0_DATA13, 168, 0),
+ [P7_GPIO_168] = P7CTL_INIT_FUNC(GPIO_168, 168, 1),
+ [P7_CAM_0_DATA14] = P7CTL_INIT_FUNC(CAM_0_DATA14, 168, 2),
+ [P7_PAR_D10] = P7CTL_INIT_FUNC(PAR_D10, 168, 3),
+ [P7_LCD_0_DATA14] = P7CTL_INIT_FUNC(LCD_0_DATA14, 169, 0),
+ [P7_GPIO_169] = P7CTL_INIT_FUNC(GPIO_169, 169, 1),
+ [P7_CAM_0_DATA15] = P7CTL_INIT_FUNC(CAM_0_DATA15, 169, 2),
+ [P7_PAR_D11] = P7CTL_INIT_FUNC(PAR_D11, 169, 3),
+ [P7_LCD_0_DATA15] = P7CTL_INIT_FUNC(LCD_0_DATA15, 170, 0),
+ [P7_GPIO_170] = P7CTL_INIT_FUNC(GPIO_170, 170, 1),
+ [P7_CAM_0_DATA16] = P7CTL_INIT_FUNC(CAM_0_DATA16, 170, 2),
+ [P7_PAR_D12] = P7CTL_INIT_FUNC(PAR_D12, 170, 3),
+ [P7_LCD_0_DATA16] = P7CTL_INIT_FUNC(LCD_0_DATA16, 171, 0),
+ [P7_GPIO_171] = P7CTL_INIT_FUNC(GPIO_171, 171, 1),
+ [P7_CAM_0_DATA17] = P7CTL_INIT_FUNC(CAM_0_DATA17, 171, 2),
+ [P7_PAR_D13] = P7CTL_INIT_FUNC(PAR_D13, 171, 3),
+ [P7_LCD_0_DATA17] = P7CTL_INIT_FUNC(LCD_0_DATA17, 172, 0),
+ [P7_GPIO_172] = P7CTL_INIT_FUNC(GPIO_172, 172, 1),
+ [P7_CAM_0_DATA18] = P7CTL_INIT_FUNC(CAM_0_DATA18, 172, 2),
+ [P7_PAR_D14] = P7CTL_INIT_FUNC(PAR_D14, 172, 3),
+ [P7_LCD_0_DATA18] = P7CTL_INIT_FUNC(LCD_0_DATA18, 173, 0),
+ [P7_GPIO_173] = P7CTL_INIT_FUNC(GPIO_173, 173, 1),
+ [P7_CAM_0_DATA19] = P7CTL_INIT_FUNC(CAM_0_DATA19, 173, 2),
+ [P7_PAR_D15] = P7CTL_INIT_FUNC(PAR_D15, 173, 3),
+ [P7_LCD_0_DATA19] = P7CTL_INIT_FUNC(LCD_0_DATA19, 174, 0),
+ [P7_GPIO_174] = P7CTL_INIT_FUNC(GPIO_174, 174, 1),
+ [P7_CAM_0_DATA20] = P7CTL_INIT_FUNC(CAM_0_DATA20, 174, 2),
+ [P7_LCD_0_DATA20] = P7CTL_INIT_FUNC(LCD_0_DATA20, 175, 0),
+ [P7_GPIO_175] = P7CTL_INIT_FUNC(GPIO_175, 175, 1),
+ [P7_CAM_0_DATA21] = P7CTL_INIT_FUNC(CAM_0_DATA21, 175, 2),
+ [P7_LCD_0_DATA21] = P7CTL_INIT_FUNC(LCD_0_DATA21, 176, 0),
+ [P7_GPIO_176] = P7CTL_INIT_FUNC(GPIO_176, 176, 1),
+ [P7_CAM_0_DATA22] = P7CTL_INIT_FUNC(CAM_0_DATA22, 176, 2),
+ [P7_LCD_0_DATA22] = P7CTL_INIT_FUNC(LCD_0_DATA22, 177, 0),
+ [P7_GPIO_177] = P7CTL_INIT_FUNC(GPIO_177, 177, 1),
+ [P7_CAM_0_DATA23] = P7CTL_INIT_FUNC(CAM_0_DATA23, 177, 2),
+ [P7_LCD_0_DATA23] = P7CTL_INIT_FUNC(LCD_0_DATA23, 178, 0),
+ [P7_GPIO_178] = P7CTL_INIT_FUNC(GPIO_178, 178, 1),
+ [P7_CAM_4_VS] = P7CTL_INIT_FUNC(CAM_4_VS, 178, 2),
+ [P7_LCD_0_CLK] = P7CTL_INIT_FUNC(LCD_0_CLK, 179, 0),
+ [P7_GPIO_179] = P7CTL_INIT_FUNC(GPIO_179, 179, 1),
+ [P7_CAM_4_HS] = P7CTL_INIT_FUNC(CAM_4_HS, 179, 2),
+ [P7_LCD_1_HS] = P7CTL_INIT_FUNC(LCD_1_HS, 180, 0),
+ [P7_GPIO_180] = P7CTL_INIT_FUNC(GPIO_180, 180, 1),
+ [P7_CAM_2_CLK] = P7CTL_INIT_FUNC(CAM_2_CLK, 180, 2),
+ [P7_LCD_1_DENa] = P7CTL_INIT_FUNC(LCD_1_DENa, 180, 3),
+ [P7_LCD_1_VS] = P7CTL_INIT_FUNC(LCD_1_VS, 181, 0),
+ [P7_GPIO_181] = P7CTL_INIT_FUNC(GPIO_181, 181, 1),
+ [P7_CAM_2_DATA00] = P7CTL_INIT_FUNC(CAM_2_DATA00, 181, 2),
+ [P7_CPU_TRACECLKOUT] = P7CTL_INIT_FUNC(CPU_TRACECLKOUT, 181, 3),
+ [P7_LCD_1_CLK] = P7CTL_INIT_FUNC(LCD_1_CLK, 182, 0),
+ [P7_GPIO_182] = P7CTL_INIT_FUNC(GPIO_182, 182, 1),
+ [P7_CAM_2_DATA01] = P7CTL_INIT_FUNC(CAM_2_DATA01, 182, 2),
+ [P7_CPU_TRACECTL] = P7CTL_INIT_FUNC(CPU_TRACECTL, 182, 3),
+ [P7_LCD_1_DATA00] = P7CTL_INIT_FUNC(LCD_1_DATA00, 183, 0),
+ [P7_GPIO_183] = P7CTL_INIT_FUNC(GPIO_183, 183, 1),
+ [P7_CAM_2_DATA02] = P7CTL_INIT_FUNC(CAM_2_DATA02, 183, 2),
+ [P7_CPU_TRACEDATA_00] = P7CTL_INIT_FUNC(CPU_TRACEDATA_00, 183, 3),
+ [P7_LCD_1_DATA01] = P7CTL_INIT_FUNC(LCD_1_DATA01, 184, 0),
+ [P7_GPIO_184] = P7CTL_INIT_FUNC(GPIO_184, 184, 1),
+ [P7_CAM_2_DATA03] = P7CTL_INIT_FUNC(CAM_2_DATA03, 184, 2),
+ [P7_CPU_TRACEDATA_01] = P7CTL_INIT_FUNC(CPU_TRACEDATA_01, 184, 3),
+ [P7_LCD_1_DATA02] = P7CTL_INIT_FUNC(LCD_1_DATA02, 185, 0),
+ [P7_GPIO_185] = P7CTL_INIT_FUNC(GPIO_185, 185, 1),
+ [P7_CAM_2_DATA04] = P7CTL_INIT_FUNC(CAM_2_DATA04, 185, 2),
+ [P7_CPU_TRACEDATA_02] = P7CTL_INIT_FUNC(CPU_TRACEDATA_02, 185, 3),
+ [P7_LCD_1_DATA03] = P7CTL_INIT_FUNC(LCD_1_DATA03, 186, 0),
+ [P7_GPIO_186] = P7CTL_INIT_FUNC(GPIO_186, 186, 1),
+ [P7_CAM_2_DATA05] = P7CTL_INIT_FUNC(CAM_2_DATA05, 186, 2),
+ [P7_CPU_TRACEDATA_03] = P7CTL_INIT_FUNC(CPU_TRACEDATA_03, 186, 3),
+ [P7_LCD_1_DATA04] = P7CTL_INIT_FUNC(LCD_1_DATA04, 187, 0),
+ [P7_GPIO_187] = P7CTL_INIT_FUNC(GPIO_187, 187, 1),
+ [P7_CAM_2_DATA06] = P7CTL_INIT_FUNC(CAM_2_DATA06, 187, 2),
+ [P7_CPU_TRACEDATA_04] = P7CTL_INIT_FUNC(CPU_TRACEDATA_04, 187, 3),
+ [P7_LCD_1_DATA05] = P7CTL_INIT_FUNC(LCD_1_DATA05, 188, 0),
+ [P7_GPIO_188] = P7CTL_INIT_FUNC(GPIO_188, 188, 1),
+ [P7_CAM_2_DATA07] = P7CTL_INIT_FUNC(CAM_2_DATA07, 188, 2),
+ [P7_CPU_TRACEDATA_05] = P7CTL_INIT_FUNC(CPU_TRACEDATA_05, 188, 3),
+ [P7_LCD_1_DATA06] = P7CTL_INIT_FUNC(LCD_1_DATA06, 189, 0),
+ [P7_GPIO_189] = P7CTL_INIT_FUNC(GPIO_189, 189, 1),
+ [P7_CAM_3_CLK] = P7CTL_INIT_FUNC(CAM_3_CLK, 189, 2),
+ [P7_CPU_TRACEDATA_06] = P7CTL_INIT_FUNC(CPU_TRACEDATA_06, 189, 3),
+ [P7_LCD_1_DATA07] = P7CTL_INIT_FUNC(LCD_1_DATA07, 190, 0),
+ [P7_GPIO_190] = P7CTL_INIT_FUNC(GPIO_190, 190, 1),
+ [P7_CAM_3_DATA00] = P7CTL_INIT_FUNC(CAM_3_DATA00, 190, 2),
+ [P7_CPU_TRACEDATA_07] = P7CTL_INIT_FUNC(CPU_TRACEDATA_07, 190, 3),
+ [P7_LCD_1_DATA08] = P7CTL_INIT_FUNC(LCD_1_DATA08, 191, 0),
+ [P7_GPIO_191] = P7CTL_INIT_FUNC(GPIO_191, 191, 1),
+ [P7_CAM_3_DATA01] = P7CTL_INIT_FUNC(CAM_3_DATA01, 191, 2),
+ [P7_CPU_TRACEDATA_08] = P7CTL_INIT_FUNC(CPU_TRACEDATA_08, 191, 3),
+ [P7_LCD_1_DATA09] = P7CTL_INIT_FUNC(LCD_1_DATA09, 192, 0),
+ [P7_GPIO_192] = P7CTL_INIT_FUNC(GPIO_192, 192, 1),
+ [P7_CAM_3_DATA02] = P7CTL_INIT_FUNC(CAM_3_DATA02, 192, 2),
+ [P7_CPU_TRACEDATA_09] = P7CTL_INIT_FUNC(CPU_TRACEDATA_09, 192, 3),
+ [P7_LCD_1_DATA10] = P7CTL_INIT_FUNC(LCD_1_DATA10, 193, 0),
+ [P7_GPIO_193] = P7CTL_INIT_FUNC(GPIO_193, 193, 1),
+ [P7_CAM_3_DATA03] = P7CTL_INIT_FUNC(CAM_3_DATA03, 193, 2),
+ [P7_CPU_TRACEDATA_10] = P7CTL_INIT_FUNC(CPU_TRACEDATA_10, 193, 3),
+ [P7_LCD_1_DATA11] = P7CTL_INIT_FUNC(LCD_1_DATA11, 194, 0),
+ [P7_GPIO_194] = P7CTL_INIT_FUNC(GPIO_194, 194, 1),
+ [P7_CAM_3_DATA04] = P7CTL_INIT_FUNC(CAM_3_DATA04, 194, 2),
+ [P7_CPU_TRACEDATA_11] = P7CTL_INIT_FUNC(CPU_TRACEDATA_11, 194, 3),
+ [P7_LCD_1_DATA12] = P7CTL_INIT_FUNC(LCD_1_DATA12, 195, 0),
+ [P7_GPIO_195] = P7CTL_INIT_FUNC(GPIO_195, 195, 1),
+ [P7_CAM_3_DATA05] = P7CTL_INIT_FUNC(CAM_3_DATA05, 195, 2),
+ [P7_CPU_TRACEDATA_12] = P7CTL_INIT_FUNC(CPU_TRACEDATA_12, 195, 3),
+ [P7_LCD_1_DATA13] = P7CTL_INIT_FUNC(LCD_1_DATA13, 196, 0),
+ [P7_GPIO_196] = P7CTL_INIT_FUNC(GPIO_196, 196, 1),
+ [P7_CAM_3_DATA06] = P7CTL_INIT_FUNC(CAM_3_DATA06, 196, 2),
+ [P7_CPU_TRACEDATA_13] = P7CTL_INIT_FUNC(CPU_TRACEDATA_13, 196, 3),
+ [P7_LCD_1_DATA14] = P7CTL_INIT_FUNC(LCD_1_DATA14, 197, 0),
+ [P7_GPIO_197] = P7CTL_INIT_FUNC(GPIO_197, 197, 1),
+ [P7_CAM_3_DATA07] = P7CTL_INIT_FUNC(CAM_3_DATA07, 197, 2),
+ [P7_CPU_TRACEDATA_14] = P7CTL_INIT_FUNC(CPU_TRACEDATA_14, 197, 3),
+ [P7_LCD_1_DATA15] = P7CTL_INIT_FUNC(LCD_1_DATA15, 198, 0),
+ [P7_GPIO_198] = P7CTL_INIT_FUNC(GPIO_198, 198, 1),
+ [P7_CAM_4_CLK] = P7CTL_INIT_FUNC(CAM_4_CLK, 198, 2),
+ [P7_CPU_TRACEDATA_15] = P7CTL_INIT_FUNC(CPU_TRACEDATA_15, 198, 3),
+ [P7_LCD_1_DATA16] = P7CTL_INIT_FUNC(LCD_1_DATA16, 199, 0),
+ [P7_GPIO_199] = P7CTL_INIT_FUNC(GPIO_199, 199, 1),
+ [P7_CAM_4_DATA00] = P7CTL_INIT_FUNC(CAM_4_DATA00, 199, 2),
+ [P7_LCD_1_DATA17] = P7CTL_INIT_FUNC(LCD_1_DATA17, 200, 0),
+ [P7_GPIO_200] = P7CTL_INIT_FUNC(GPIO_200, 200, 1),
+ [P7_CAM_4_DATA01] = P7CTL_INIT_FUNC(CAM_4_DATA01, 200, 2),
+ [P7_LCD_1_DATA18] = P7CTL_INIT_FUNC(LCD_1_DATA18, 201, 0),
+ [P7_GPIO_201] = P7CTL_INIT_FUNC(GPIO_201, 201, 1),
+ [P7_CAM_4_DATA02] = P7CTL_INIT_FUNC(CAM_4_DATA02, 201, 2),
+ [P7_LCD_1_DATA19] = P7CTL_INIT_FUNC(LCD_1_DATA19, 202, 0),
+ [P7_GPIO_202] = P7CTL_INIT_FUNC(GPIO_202, 202, 1),
+ [P7_CAM_4_DATA03] = P7CTL_INIT_FUNC(CAM_4_DATA03, 202, 2),
+ [P7_LCD_1_DATA20] = P7CTL_INIT_FUNC(LCD_1_DATA20, 203, 0),
+ [P7_GPIO_203] = P7CTL_INIT_FUNC(GPIO_203, 203, 1),
+ [P7_CAM_4_DATA04] = P7CTL_INIT_FUNC(CAM_4_DATA04, 203, 2),
+ [P7_LCD_1_DATA21] = P7CTL_INIT_FUNC(LCD_1_DATA21, 204, 0),
+ [P7_GPIO_204] = P7CTL_INIT_FUNC(GPIO_204, 204, 1),
+ [P7_CAM_4_DATA05] = P7CTL_INIT_FUNC(CAM_4_DATA05, 204, 2),
+ [P7_LCD_1_DATA22] = P7CTL_INIT_FUNC(LCD_1_DATA22, 205, 0),
+ [P7_GPIO_205] = P7CTL_INIT_FUNC(GPIO_205, 205, 1),
+ [P7_CAM_4_DATA06] = P7CTL_INIT_FUNC(CAM_4_DATA06, 205, 2),
+ [P7_LCD_1_DATA23] = P7CTL_INIT_FUNC(LCD_1_DATA23, 206, 0),
+ [P7_GPIO_206] = P7CTL_INIT_FUNC(GPIO_206, 206, 1),
+ [P7_CAM_4_DATA07] = P7CTL_INIT_FUNC(CAM_4_DATA07, 206, 2),
+ [P7_LCD_1_DEN] = P7CTL_INIT_FUNC(LCD_1_DEN, 207, 0),
+ [P7_GPIO_207] = P7CTL_INIT_FUNC(GPIO_207, 207, 1),
+ [P7_CAM_1_HSa] = P7CTL_INIT_FUNC(CAM_1_HSa, 207, 2),
+ [P7_LCD_1_CLKa] = P7CTL_INIT_FUNC(LCD_1_CLKa, 207, 3),
+ [P7_CAM_0_CLK] = P7CTL_INIT_FUNC(CAM_0_CLK, 208, 0),
+ [P7_GPIO_208] = P7CTL_INIT_FUNC(GPIO_208, 208, 1),
+ [P7_CAM_0_DATA00] = P7CTL_INIT_FUNC(CAM_0_DATA00, 209, 0),
+ [P7_GPIO_209] = P7CTL_INIT_FUNC(GPIO_209, 209, 1),
+ [P7_CAM_1_DATA08] = P7CTL_INIT_FUNC(CAM_1_DATA08, 209, 2),
+ [P7_CAM_0_DATA01] = P7CTL_INIT_FUNC(CAM_0_DATA01, 210, 0),
+ [P7_GPIO_210] = P7CTL_INIT_FUNC(GPIO_210, 210, 1),
+ [P7_CAM_1_DATA09] = P7CTL_INIT_FUNC(CAM_1_DATA09, 210, 2),
+ [P7_CAM_0_DATA02] = P7CTL_INIT_FUNC(CAM_0_DATA02, 211, 0),
+ [P7_GPIO_211] = P7CTL_INIT_FUNC(GPIO_211, 211, 1),
+ [P7_CAM_1_DATA10] = P7CTL_INIT_FUNC(CAM_1_DATA10, 211, 2),
+ [P7_CAM_0_DATA03] = P7CTL_INIT_FUNC(CAM_0_DATA03, 212, 0),
+ [P7_GPIO_212] = P7CTL_INIT_FUNC(GPIO_212, 212, 1),
+ [P7_CAM_1_DATA11] = P7CTL_INIT_FUNC(CAM_1_DATA11, 212, 2),
+ [P7_CAM_0_DATA04] = P7CTL_INIT_FUNC(CAM_0_DATA04, 213, 0),
+ [P7_GPIO_213] = P7CTL_INIT_FUNC(GPIO_213, 213, 1),
+ [P7_CAM_1_DATA12] = P7CTL_INIT_FUNC(CAM_1_DATA12, 213, 2),
+ [P7_CAM_0_DATA05] = P7CTL_INIT_FUNC(CAM_0_DATA05, 214, 0),
+ [P7_GPIO_214] = P7CTL_INIT_FUNC(GPIO_214, 214, 1),
+ [P7_CAM_1_DATA13] = P7CTL_INIT_FUNC(CAM_1_DATA13, 214, 2),
+ [P7_CAM_0_DATA06] = P7CTL_INIT_FUNC(CAM_0_DATA06, 215, 0),
+ [P7_GPIO_215] = P7CTL_INIT_FUNC(GPIO_215, 215, 1),
+ [P7_CAM_1_DATA14] = P7CTL_INIT_FUNC(CAM_1_DATA14, 215, 2),
+ [P7_CAM_0_DATA07] = P7CTL_INIT_FUNC(CAM_0_DATA07, 216, 0),
+ [P7_GPIO_216] = P7CTL_INIT_FUNC(GPIO_216, 216, 1),
+ [P7_CAM_1_DATA15] = P7CTL_INIT_FUNC(CAM_1_DATA15, 216, 2),
+ [P7_CAM_1_CLK] = P7CTL_INIT_FUNC(CAM_1_CLK, 217, 0),
+ [P7_GPIO_217] = P7CTL_INIT_FUNC(GPIO_217, 217, 1),
+ [P7_SPI_00b] = P7CTL_INIT_FUNC(SPI_00b, 217, 2),
+ [P7_CAM_1_DATA00] = P7CTL_INIT_FUNC(CAM_1_DATA00, 218, 0),
+ [P7_GPIO_218] = P7CTL_INIT_FUNC(GPIO_218, 218, 1),
+ [P7_SPI_01b] = P7CTL_INIT_FUNC(SPI_01b, 218, 2),
+ [P7_CAM_0_VSa] = P7CTL_INIT_FUNC(CAM_0_VSa, 218, 3),
+ [P7_CAM_1_DATA01] = P7CTL_INIT_FUNC(CAM_1_DATA01, 219, 0),
+ [P7_GPIO_219] = P7CTL_INIT_FUNC(GPIO_219, 219, 1),
+ [P7_SPI_02b] = P7CTL_INIT_FUNC(SPI_02b, 219, 2),
+ [P7_CAM_0_HSa] = P7CTL_INIT_FUNC(CAM_0_HSa, 219, 3)
+};
+
+static unsigned long p7_gpio_pins_r2[] = {
+ 0x00007fff,
+ 0xff8007c2,
+ 0x5fffff9f,
+ 0xffdffc00,
+ 0xffffffff,
+ 0xffffffff,
+ 0x0fffffff
+};
+
+const struct p7_pinctrl_config p7_pinctrl_config_r2 = {
+ .pin_descs = p7_pin_descs_r2,
+ .pin_descs_sz = ARRAY_SIZE(p7_pin_descs_r2),
+ .pin_funcs = p7_pin_funcs_r2,
+ .gpio_pins = p7_gpio_pins_r2,
+ .gpio_pins_sz = ARRAY_SIZE(p7_gpio_pins_r2),
+};
diff --git a/arch/arm/mach-parrot7/pindesc-r3.c b/arch/arm/mach-parrot7/pindesc-r3.c
new file mode 100644
index 0000000..1c70bfd
--- /dev/null
+++ b/arch/arm/mach-parrot7/pindesc-r3.c
@@ -0,0 +1,855 @@
+#include "common.h"
+#include "pinctrl.h"
+
+/*
+ * Physical pin descriptors
+ *
+ * Pins identifiers use the GPIO numbering scheme. Names are assigned by
+ * concatenating all possible multiplexing functions a pin may be used with.
+ *
+ * Content was generated with the help of the genpin.sh script located into
+ * this directory.
+ */
+static struct pinctrl_pin_desc const p7_pin_descs_r3[] = {
+ P7CTL_INIT_PIN(0, "CAM_1_DATA02__GPIO_000__SPI_03b__CAM_3_VSa"),
+ P7CTL_INIT_PIN(1, "CAM_1_DATA03__GPIO_001__SPI_04b__CAM_3_HSa"),
+ P7CTL_INIT_PIN(2, "CAM_1_DATA04__GPIO_002__SPI_05b__CAM_4_VSa"),
+ P7CTL_INIT_PIN(3, "CAM_1_DATA05__GPIO_003__SPI_06b__CAM_4_HSa"),
+ P7CTL_INIT_PIN(4, "CAM_1_DATA06__GPIO_004__SPI_07b__CAM_5_VSa"),
+ P7CTL_INIT_PIN(5, "CAM_1_DATA07__GPIO_005__SPI_08b__CAM_5_HSa"),
+ P7CTL_INIT_PIN(6, "CAM_5_CLK__GPIO_006__SD_2_CLK"),
+ P7CTL_INIT_PIN(7, "CAM_5_DATA00__GPIO_007__SD_2_CMD"),
+ P7CTL_INIT_PIN(8, "CAM_5_DATA01__GPIO_008__SD_2_DAT00"),
+ P7CTL_INIT_PIN(9, "CAM_5_DATA02__GPIO_009__SD_2_DAT01"),
+ P7CTL_INIT_PIN(10, "CAM_5_DATA03__GPIO_010__SD_2_DAT02"),
+ P7CTL_INIT_PIN(11, "CAM_5_DATA04__GPIO_011__SD_2_DAT03"),
+ P7CTL_INIT_PIN(12, "CAM_5_DATA05__GPIO_012"),
+ P7CTL_INIT_PIN(13, "CAM_5_DATA06__GPIO_013"),
+ P7CTL_INIT_PIN(14, "CAM_5_DATA07__GPIO_014"),
+ P7CTL_INIT_PIN(15, "SD_1_CLK__GPIO_015__UART_5_TX"),
+ P7CTL_INIT_PIN(16, "SD_1_CMD__GPIO_016__UART_5_RX"),
+ P7CTL_INIT_PIN(17, "SD_1_DAT00__GPIO_017__UART_6_TX"),
+ P7CTL_INIT_PIN(18, "SD_1_DAT02__GPIO_018__UART_7_TX"),
+ P7CTL_INIT_PIN(19, "SD_1_DAT01__GPIO_019__UART_6_RX"),
+ P7CTL_INIT_PIN(20, "SD_1_DAT03__GPIO_020__UART_7_RX"),
+ P7CTL_INIT_PIN(21, "SD_0_CLK__GPIO_021"),
+ P7CTL_INIT_PIN(22, "SD_0_CMD__GPIO_022"),
+ P7CTL_INIT_PIN(23, "SD_0_DAT00__GPIO_023"),
+ P7CTL_INIT_PIN(24, "SD_0_DAT01__GPIO_024"),
+ P7CTL_INIT_PIN(25, "SD_0_DAT02__GPIO_025"),
+ P7CTL_INIT_PIN(26, "SD_0_DAT03__GPIO_026"),
+ P7CTL_INIT_PIN(27, "NAND_NCE__GPIO_027__SPI_00a"),
+ P7CTL_INIT_PIN(28, "NAND_NR__GPIO_028__SPI_01a"),
+ P7CTL_INIT_PIN(29, "NAND_NW__GPIO_029__SPI_02a"),
+ P7CTL_INIT_PIN(30, "NAND_AL__GPIO_030__SPI_03a"),
+ P7CTL_INIT_PIN(31, "NAND_CL__GPIO_031__SPI_04a"),
+ P7CTL_INIT_PIN(32, "NAND_RNB__GPIO_032__SPI_05a"),
+ P7CTL_INIT_PIN(33, "NAND_DQS__GPIO_033__CAN1_RXa"),
+ P7CTL_INIT_PIN(34, "NAND_DATA_00__GPIO_034__SPI_06a"),
+ P7CTL_INIT_PIN(35, "NAND_DATA_01__GPIO_035__SPI_07a"),
+ P7CTL_INIT_PIN(36, "NAND_DATA_02__GPIO_036__SPI_08a"),
+ P7CTL_INIT_PIN(37, "NAND_DATA_03__GPIO_037__SPI_09a"),
+ P7CTL_INIT_PIN(38, "NAND_DATA_04__GPIO_038"),
+ P7CTL_INIT_PIN(39, "NAND_DATA_05__GPIO_039"),
+ P7CTL_INIT_PIN(40, "NAND_DATA_06__GPIO_040"),
+ P7CTL_INIT_PIN(41, "NAND_DATA_07__GPIO_041"),
+ P7CTL_INIT_PIN(42, "NAND_WP__GPIO_042__CAN1_TXa"),
+ P7CTL_INIT_PIN(43, "FORCE_POWER_ON__GPIO_043"),
+ P7CTL_INIT_PIN(44, "TRST_N__GPIO_044"),
+ P7CTL_INIT_PIN(45, "TDI__GPIO_045"),
+ P7CTL_INIT_PIN(46, "TDO__GPIO_046"),
+ P7CTL_INIT_PIN(47, "TCK__GPIO_047"),
+ P7CTL_INIT_PIN(48, "TMS__GPIO_048"),
+ P7CTL_INIT_PIN(49, "GPIO_049"),
+ P7CTL_INIT_PIN(50, "GPIO_050"),
+ P7CTL_INIT_PIN(51, "UART_1_RX__GPIO_051"),
+ P7CTL_INIT_PIN(52, "UART_1_TX__GPIO_052"),
+ P7CTL_INIT_PIN(53, "UART_1_RTS__GPIO_053__CAN0_RXb"),
+ P7CTL_INIT_PIN(54, "UART_1_CTS__GPIO_054__CAN0_TXb"),
+ P7CTL_INIT_PIN(55, "UART_0_RX__GPIO_055"),
+ P7CTL_INIT_PIN(56, "UART_0_TX__GPIO_056"),
+ P7CTL_INIT_PIN(57, "UART_0_RTS__GPIO_057"),
+ P7CTL_INIT_PIN(58, "UART_0_CTS__GPIO_058"),
+ P7CTL_INIT_PIN(59, "I2C_2_DAT__GPIO_059__I2C_2_SL_DAT"),
+ P7CTL_INIT_PIN(60, "I2C_2_CLK__GPIO_060__I2C_2_SL_CLK"),
+ P7CTL_INIT_PIN(61, "I2C_1_DAT__GPIO_061__I2C_1_SL_DAT"),
+ P7CTL_INIT_PIN(62, "I2C_1_CLK__GPIO_062__I2C_1_SL_CLK"),
+ P7CTL_INIT_PIN(63, "I2C_0_DAT__GPIO_063__I2C_0_SL_DAT"),
+ P7CTL_INIT_PIN(64, "I2C_0_CLK__GPIO_064__I2C_0_SL_CLK"),
+ P7CTL_INIT_PIN(65, "UART_4_RX__GPIO_065"),
+ P7CTL_INIT_PIN(66, "UART_4_TX__GPIO_066"),
+ P7CTL_INIT_PIN(67, "UART_3_RX__GPIO_067"),
+ P7CTL_INIT_PIN(68, "UART_3_TX__GPIO_068"),
+ P7CTL_INIT_PIN(69, "UART_2_RX__GPIO_069__CAN1_TXb"),
+ P7CTL_INIT_PIN(70, "UART_2_TX__GPIO_070__CAN1_RXb__I2C_SECURE_CLK"),
+ P7CTL_INIT_PIN(71, "SPI_09b__GPIO_071__PWM_15"),
+ P7CTL_INIT_PIN(72, "SPI_10b__GPIO_072"),
+ P7CTL_INIT_PIN(73, "SPI_11b__GPIO_073__I2C_SECURE_CLKa"),
+ P7CTL_INIT_PIN(74, "SPI_12b__GPIO_074"),
+ P7CTL_INIT_PIN(75, "SPI_13b__GPIO_075"),
+ P7CTL_INIT_PIN(76, "SPI_14b__GPIO_076"),
+ P7CTL_INIT_PIN(77, "SPI_00__GPIO_077__AAI_15__CAN1_TX"),
+ P7CTL_INIT_PIN(78, "SPI_01__GPIO_078__AAI_16__CAN1_RX"),
+ P7CTL_INIT_PIN(79, "SPI_02__GPIO_079__AAI_17__CAN0_TX"),
+ P7CTL_INIT_PIN(80, "SPI_03__GPIO_080__AAI_18__CAN0_RX"),
+ P7CTL_INIT_PIN(81, "SPI_04__GPIO_081__AAI_19"),
+ P7CTL_INIT_PIN(82, "SPI_05__GPIO_082__AAI_20"),
+ P7CTL_INIT_PIN(83, "SPI_06__GPIO_083__AAI_21"),
+ P7CTL_INIT_PIN(84, "SPI_07__GPIO_084__AAI_22"),
+ P7CTL_INIT_PIN(85, "SPI_08__GPIO_085__AAI_23"),
+ P7CTL_INIT_PIN(86, "SPI_09__GPIO_086__AAI_24"),
+ P7CTL_INIT_PIN(87, "SPI_10__GPIO_087__AAI_25"),
+ P7CTL_INIT_PIN(88, "SPI_11__GPIO_088__AAI_26"),
+ P7CTL_INIT_PIN(89, "SPI_12__GPIO_089__AAI_27"),
+ P7CTL_INIT_PIN(90, "SPI_13__GPIO_090__AAI_28"),
+ P7CTL_INIT_PIN(91, "SPI_14__GPIO_091__AAI_29"),
+ P7CTL_INIT_PIN(92, "SPI_15__GPIO_092__AAI_30"),
+ P7CTL_INIT_PIN(93, "P7MU_CLK_OUT__GPIO_093__PWM_15a__I2C_SECURE_DAT"),
+ P7CTL_INIT_PIN(94, "REBOOT_P7MU__GPIO_094"),
+ P7CTL_INIT_PIN(95, "ULPI_0_DATA00__GPIO_095"),
+ P7CTL_INIT_PIN(96, "ULPI_0_DATA01__GPIO_096"),
+ P7CTL_INIT_PIN(97, "ULPI_0_DATA02__GPIO_097"),
+ P7CTL_INIT_PIN(98, "ULPI_0_DATA03__GPIO_098"),
+ P7CTL_INIT_PIN(99, "ULPI_0_DATA04__GPIO_099"),
+ P7CTL_INIT_PIN(100, "ULPI_0_DATA05__GPIO_100"),
+ P7CTL_INIT_PIN(101, "ULPI_0_DATA06__GPIO_101"),
+ P7CTL_INIT_PIN(102, "ULPI_0_DATA07__GPIO_102"),
+ P7CTL_INIT_PIN(103, "ULPI_0_NXT__GPIO_103"),
+ P7CTL_INIT_PIN(104, "ULPI_0_DIR__GPIO_104"),
+ P7CTL_INIT_PIN(105, "ULPI_0_CLK__GPIO_105"),
+ P7CTL_INIT_PIN(106, "ULPI_1_DATA00__GPIO_106__I2C_2_CLKa"),
+ P7CTL_INIT_PIN(107, "ULPI_1_DATA01__GPIO_107__I2C_2_DATa"),
+ P7CTL_INIT_PIN(108, "ULPI_1_DATA02__GPIO_108__I2C_2_CLKb"),
+ P7CTL_INIT_PIN(109, "ULPI_1_DATA03__GPIO_109__I2C_2_DATb"),
+ P7CTL_INIT_PIN(110, "ULPI_1_DATA04__GPIO_110__I2C_2_CLKc"),
+ P7CTL_INIT_PIN(111, "ULPI_1_DATA05__GPIO_111__I2C_2_DATc"),
+ P7CTL_INIT_PIN(112, "ULPI_1_DATA06__GPIO_112__I2C_2_CLKd"),
+ P7CTL_INIT_PIN(113, "ULPI_1_DATA07__GPIO_113__I2C_2_DATd"),
+ P7CTL_INIT_PIN(114, "ULPI_1_NXT__GPIO_114__I2C_2_CLKe"),
+ P7CTL_INIT_PIN(115, "ULPI_1_DIR__GPIO_115"),
+ P7CTL_INIT_PIN(116, "ULPI_1_STP__GPIO_116__I2C_2_DATe"),
+ P7CTL_INIT_PIN(117, "ULPI_0_STP__GPIO_117"),
+ P7CTL_INIT_PIN(118, "ULPI_1_CLK__GPIO_118"),
+ P7CTL_INIT_PIN(119, "AAI_00__GPIO_119__PWM_00"),
+ P7CTL_INIT_PIN(120, "AAI_01__GPIO_120__PWM_01"),
+ P7CTL_INIT_PIN(121, "AAI_02__GPIO_121__PWM_02"),
+ P7CTL_INIT_PIN(122, "AAI_03__GPIO_122__PWM_03"),
+ P7CTL_INIT_PIN(123, "AAI_04__GPIO_123__PWM_04"),
+ P7CTL_INIT_PIN(124, "AAI_05__GPIO_124__PWM_05"),
+ P7CTL_INIT_PIN(125, "AAI_06__GPIO_125__PWM_06"),
+ P7CTL_INIT_PIN(126, "AAI_07__GPIO_126__PWM_07"),
+ P7CTL_INIT_PIN(127, "AAI_08__GPIO_127__PWM_08"),
+ P7CTL_INIT_PIN(128, "AAI_09__GPIO_128__PWM_09"),
+ P7CTL_INIT_PIN(129, "AAI_10__GPIO_129__PWM_10"),
+ P7CTL_INIT_PIN(130, "AAI_11__GPIO_130__PWM_11"),
+ P7CTL_INIT_PIN(131, "AAI_12__GPIO_131__PWM_12"),
+ P7CTL_INIT_PIN(132, "AAI_13__GPIO_132__PWM_13"),
+ P7CTL_INIT_PIN(133, "AAI_14__GPIO_133__PWM_14"),
+ P7CTL_INIT_PIN(134, "SPI_16__GPIO_134__ETH_MII_TXER"),
+ P7CTL_INIT_PIN(135, "SPI_17__GPIO_135__ETH_MII_RXER"),
+ P7CTL_INIT_PIN(136, "SPI_18__GPIO_136__ETH_MII_CRS"),
+ P7CTL_INIT_PIN(137, "SPI_19__GPIO_137__ETH_MII_COL"),
+ P7CTL_INIT_PIN(138, "ETH_RGMII_TXC__GPIO_138"),
+ P7CTL_INIT_PIN(139, "ETH_RGMII_TXD_00__GPIO_139"),
+ P7CTL_INIT_PIN(140, "ETH_RGMII_TXD_01__GPIO_140"),
+ P7CTL_INIT_PIN(141, "ETH_RGMII_TXD_02__GPIO_141"),
+ P7CTL_INIT_PIN(142, "ETH_RGMII_TXD_03__GPIO_142"),
+ P7CTL_INIT_PIN(143, "ETH_RGMII_TX_CTL__GPIO_143"),
+ P7CTL_INIT_PIN(144, "ETH_RGMII_RXC__GPIO_144"),
+ P7CTL_INIT_PIN(145, "ETH_RGMII_RXD_00__GPIO_145"),
+ P7CTL_INIT_PIN(146, "ETH_RGMII_RXD_01__GPIO_146"),
+ P7CTL_INIT_PIN(147, "ETH_RGMII_RXD_02__GPIO_147"),
+ P7CTL_INIT_PIN(148, "ETH_RGMII_RXD_03__GPIO_148"),
+ P7CTL_INIT_PIN(149, "ETH_RGMII_RX_CTL__GPIO_149"),
+ P7CTL_INIT_PIN(150, "ETH_MDC__GPIO_150"),
+ P7CTL_INIT_PIN(151, "ETH_MDIO__GPIO_151"),
+ P7CTL_INIT_PIN(152, "LCD_0_DEN__GPIO_152__CAM_1_VS"),
+ P7CTL_INIT_PIN(153, "LCD_0_HS__GPIO_153__CAM_1_HS__LCD_0_DENa"),
+ P7CTL_INIT_PIN(154, "LCD_0_VS__GPIO_154__CAM_0_VS"),
+ P7CTL_INIT_PIN(155, "LCD_0_DATA00__GPIO_155__CAM_0_HS"),
+ P7CTL_INIT_PIN(156, "LCD_0_DATA01__GPIO_156__CAM_2_VS"),
+ P7CTL_INIT_PIN(157, "LCD_0_DATA02__GPIO_157__CAM_2_HS"),
+ P7CTL_INIT_PIN(158, "LCD_0_DATA03__GPIO_158__CAM_3_VS"),
+ P7CTL_INIT_PIN(159, "LCD_0_DATA04__GPIO_159__CAM_3_HS"),
+ P7CTL_INIT_PIN(160, "LCD_0_DATA05__GPIO_160__CAM_5_VS"),
+ P7CTL_INIT_PIN(161, "LCD_0_DATA06__GPIO_161__CAM_5_HS"),
+ P7CTL_INIT_PIN(162, "LCD_0_DATA07__GPIO_162__CAM_0_DATA08"),
+ P7CTL_INIT_PIN(163, "LCD_0_DATA08__GPIO_163__CAM_0_DATA09__CAM_0_DATA08a"),
+ P7CTL_INIT_PIN(164, "LCD_0_DATA09__GPIO_164__CAM_0_DATA10__CAM_0_DATA09a"),
+ P7CTL_INIT_PIN(165, "LCD_0_DATA10__GPIO_165__CAM_0_DATA11__CAM_0_DATA10a"),
+ P7CTL_INIT_PIN(166, "LCD_0_DATA11__GPIO_166__CAM_0_DATA12__CAM_0_DATA11a"),
+ P7CTL_INIT_PIN(167, "LCD_0_DATA12__GPIO_167__CAM_0_DATA13__CAM_0_DATA12a"),
+ P7CTL_INIT_PIN(168, "LCD_0_DATA13__GPIO_168__CAM_0_DATA14__CAM_0_DATA13a"),
+ P7CTL_INIT_PIN(169, "LCD_0_DATA14__GPIO_169__CAM_0_DATA15__CAM_0_DATA14a"),
+ P7CTL_INIT_PIN(170, "LCD_0_DATA15__GPIO_170__CAM_0_DATA16__CAM_0_DATA15a"),
+ P7CTL_INIT_PIN(171, "LCD_0_DATA16__GPIO_171__CAM_0_DATA17"),
+ P7CTL_INIT_PIN(172, "LCD_0_DATA17__GPIO_172__CAM_0_DATA18"),
+ P7CTL_INIT_PIN(173, "LCD_0_DATA18__GPIO_173__CAM_0_DATA19"),
+ P7CTL_INIT_PIN(174, "LCD_0_DATA19__GPIO_174__CAM_0_DATA20"),
+ P7CTL_INIT_PIN(175, "LCD_0_DATA20__GPIO_175__CAM_0_DATA21__CAM_3_DATA09a"),
+ P7CTL_INIT_PIN(176, "LCD_0_DATA21__GPIO_176__CAM_0_DATA22__CAM_3_DATA08a"),
+ P7CTL_INIT_PIN(177, "LCD_0_DATA22__GPIO_177__CAM_0_DATA23"),
+ P7CTL_INIT_PIN(178, "LCD_0_DATA23__GPIO_178__CAM_4_VS"),
+ P7CTL_INIT_PIN(179, "LCD_0_CLK__GPIO_179__CAM_4_HS__CAM_0_CLKa"),
+ P7CTL_INIT_PIN(180, "LCD_1_HS__GPIO_180__CAM_2_CLK__LCD_1_DENa"),
+ P7CTL_INIT_PIN(181, "LCD_1_VS__GPIO_181__CAM_2_DATA00__CPU_TRACECLKOUT"),
+ P7CTL_INIT_PIN(182, "LCD_1_CLK__GPIO_182__CAM_2_DATA01__CPU_TRACECTL"),
+ P7CTL_INIT_PIN(183, "LCD_1_DATA00__GPIO_183__CAM_2_DATA02__CPU_TRACEDATA_00"),
+ P7CTL_INIT_PIN(184, "LCD_1_DATA01__GPIO_184__CAM_2_DATA03__CPU_TRACEDATA_01"),
+ P7CTL_INIT_PIN(185, "LCD_1_DATA02__GPIO_185__CAM_2_DATA04__CPU_TRACEDATA_02"),
+ P7CTL_INIT_PIN(186, "LCD_1_DATA03__GPIO_186__CAM_2_DATA05__CPU_TRACEDATA_03"),
+ P7CTL_INIT_PIN(187, "LCD_1_DATA04__GPIO_187__CAM_2_DATA06__CPU_TRACEDATA_04"),
+ P7CTL_INIT_PIN(188, "LCD_1_DATA05__GPIO_188__CAM_2_DATA07__CPU_TRACEDATA_05"),
+ P7CTL_INIT_PIN(189, "LCD_1_DATA06__GPIO_189__CAM_3_CLK__CPU_TRACEDATA_06"),
+ P7CTL_INIT_PIN(190, "LCD_1_DATA07__GPIO_190__CAM_3_DATA00__CPU_TRACEDATA_07"),
+ P7CTL_INIT_PIN(191, "LCD_1_DATA08__GPIO_191__CAM_3_DATA01__CPU_TRACEDATA_08"),
+ P7CTL_INIT_PIN(192, "LCD_1_DATA09__GPIO_192__CAM_3_DATA02__CPU_TRACEDATA_09"),
+ P7CTL_INIT_PIN(193, "LCD_1_DATA10__GPIO_193__CAM_3_DATA03__CPU_TRACEDATA_10"),
+ P7CTL_INIT_PIN(194, "LCD_1_DATA11__GPIO_194__CAM_3_DATA04__CPU_TRACEDATA_11"),
+ P7CTL_INIT_PIN(195, "LCD_1_DATA12__GPIO_195__CAM_3_DATA05__CPU_TRACEDATA_12"),
+ P7CTL_INIT_PIN(196, "LCD_1_DATA13__GPIO_196__CAM_3_DATA06__CPU_TRACEDATA_13"),
+ P7CTL_INIT_PIN(197, "LCD_1_DATA14__GPIO_197__CAM_3_DATA07__CPU_TRACEDATA_14"),
+ P7CTL_INIT_PIN(198, "LCD_1_DATA15__GPIO_198__CAM_4_CLK__CPU_TRACEDATA_15"),
+ P7CTL_INIT_PIN(199, "LCD_1_DATA16__GPIO_199__CAM_4_DATA00"),
+ P7CTL_INIT_PIN(200, "LCD_1_DATA17__GPIO_200__CAM_4_DATA01"),
+ P7CTL_INIT_PIN(201, "LCD_1_DATA18__GPIO_201__CAM_4_DATA02"),
+ P7CTL_INIT_PIN(202, "LCD_1_DATA19__GPIO_202__CAM_4_DATA03"),
+ P7CTL_INIT_PIN(203, "LCD_1_DATA20__GPIO_203__CAM_4_DATA04"),
+ P7CTL_INIT_PIN(204, "LCD_1_DATA21__GPIO_204__CAM_4_DATA05"),
+ P7CTL_INIT_PIN(205, "LCD_1_DATA22__GPIO_205__CAM_4_DATA06"),
+ P7CTL_INIT_PIN(206, "LCD_1_DATA23__GPIO_206__CAM_4_DATA07"),
+ P7CTL_INIT_PIN(207, "LCD_1_DEN__GPIO_207__CAM_1_HSa__LCD_1_CLKa"),
+ P7CTL_INIT_PIN(208, "CAM_0_CLK__GPIO_208__CAM_1_CLKa"),
+ P7CTL_INIT_PIN(209, "CAM_0_DATA00__GPIO_209__CAM_1_DATA08"),
+ P7CTL_INIT_PIN(210, "CAM_0_DATA01__GPIO_210__CAM_1_DATA09"),
+ P7CTL_INIT_PIN(211, "CAM_0_DATA02__GPIO_211__CAM_1_DATA10__CAM_4_DATA08"),
+ P7CTL_INIT_PIN(212, "CAM_0_DATA03__GPIO_212__CAM_1_DATA11__CAM_4_DATA09"),
+ P7CTL_INIT_PIN(213, "CAM_0_DATA04__GPIO_213__CAM_1_DATA12__CAM_5_DATA08"),
+ P7CTL_INIT_PIN(214, "CAM_0_DATA05__GPIO_214__CAM_1_DATA13__CAM_5_DATA09"),
+ P7CTL_INIT_PIN(215, "CAM_0_DATA06__GPIO_215__CAM_1_DATA14__CAM_2_DATA08"),
+ P7CTL_INIT_PIN(216, "CAM_0_DATA07__GPIO_216__CAM_1_DATA15__CAM_2_DATA09"),
+ P7CTL_INIT_PIN(217, "CAM_1_CLK__GPIO_217__SPI_00b"),
+ P7CTL_INIT_PIN(218, "CAM_1_DATA00__GPIO_218__SPI_01b__CAM_0_VSa"),
+ P7CTL_INIT_PIN(219, "CAM_1_DATA01__GPIO_219__SPI_02b__CAM_0_HSa")
+};
+
+/* Pinmux functions */
+static struct p7ctl_function const p7_pin_funcs_r3[P7_N_FUNCTIONS] = {
+ [P7_CAM_1_DATA02] = P7CTL_INIT_FUNC(CAM_1_DATA02, 0, 0),
+ [P7_GPIO_000] = P7CTL_INIT_FUNC(GPIO_000, 0, 1),
+ [P7_SPI_03b] = P7CTL_INIT_FUNC(SPI_03b, 0, 2),
+ [P7_CAM_3_VSa] = P7CTL_INIT_FUNC(CAM_3_VSa, 0, 3),
+ [P7_CAM_1_DATA03] = P7CTL_INIT_FUNC(CAM_1_DATA03, 1, 0),
+ [P7_GPIO_001] = P7CTL_INIT_FUNC(GPIO_001, 1, 1),
+ [P7_SPI_04b] = P7CTL_INIT_FUNC(SPI_04b, 1, 2),
+ [P7_CAM_3_HSa] = P7CTL_INIT_FUNC(CAM_3_HSa, 1, 3),
+ [P7_CAM_1_DATA04] = P7CTL_INIT_FUNC(CAM_1_DATA04, 2, 0),
+ [P7_GPIO_002] = P7CTL_INIT_FUNC(GPIO_002, 2, 1),
+ [P7_SPI_05b] = P7CTL_INIT_FUNC(SPI_05b, 2, 2),
+ [P7_CAM_4_VSa] = P7CTL_INIT_FUNC(CAM_4_VSa, 2, 3),
+ [P7_CAM_1_DATA05] = P7CTL_INIT_FUNC(CAM_1_DATA05, 3, 0),
+ [P7_GPIO_003] = P7CTL_INIT_FUNC(GPIO_003, 3, 1),
+ [P7_SPI_06b] = P7CTL_INIT_FUNC(SPI_06b, 3, 2),
+ [P7_CAM_4_HSa] = P7CTL_INIT_FUNC(CAM_4_HSa, 3, 3),
+ [P7_CAM_1_DATA06] = P7CTL_INIT_FUNC(CAM_1_DATA06, 4, 0),
+ [P7_GPIO_004] = P7CTL_INIT_FUNC(GPIO_004, 4, 1),
+ [P7_SPI_07b] = P7CTL_INIT_FUNC(SPI_07b, 4, 2),
+ [P7_CAM_5_VSa] = P7CTL_INIT_FUNC(CAM_5_VSa, 4, 3),
+ [P7_CAM_1_DATA07] = P7CTL_INIT_FUNC(CAM_1_DATA07, 5, 0),
+ [P7_GPIO_005] = P7CTL_INIT_FUNC(GPIO_005, 5, 1),
+ [P7_SPI_08b] = P7CTL_INIT_FUNC(SPI_08b, 5, 2),
+ [P7_CAM_5_HSa] = P7CTL_INIT_FUNC(CAM_5_HSa, 5, 3),
+ [P7_CAM_5_CLK] = P7CTL_INIT_FUNC(CAM_5_CLK, 6, 0),
+ [P7_GPIO_006] = P7CTL_INIT_FUNC(GPIO_006, 6, 1),
+ [P7_SD_2_CLK] = P7CTL_INIT_FUNC(SD_2_CLK, 6, 2),
+ [P7_CAM_5_DATA00] = P7CTL_INIT_FUNC(CAM_5_DATA00, 7, 0),
+ [P7_GPIO_007] = P7CTL_INIT_FUNC(GPIO_007, 7, 1),
+ [P7_SD_2_CMD] = P7CTL_INIT_FUNC(SD_2_CMD, 7, 2),
+ [P7_CAM_5_DATA01] = P7CTL_INIT_FUNC(CAM_5_DATA01, 8, 0),
+ [P7_GPIO_008] = P7CTL_INIT_FUNC(GPIO_008, 8, 1),
+ [P7_SD_2_DAT00] = P7CTL_INIT_FUNC(SD_2_DAT00, 8, 2),
+ [P7_CAM_5_DATA02] = P7CTL_INIT_FUNC(CAM_5_DATA02, 9, 0),
+ [P7_GPIO_009] = P7CTL_INIT_FUNC(GPIO_009, 9, 1),
+ [P7_SD_2_DAT01] = P7CTL_INIT_FUNC(SD_2_DAT01, 9, 2),
+ [P7_CAM_5_DATA03] = P7CTL_INIT_FUNC(CAM_5_DATA03, 10, 0),
+ [P7_GPIO_010] = P7CTL_INIT_FUNC(GPIO_010, 10, 1),
+ [P7_SD_2_DAT02] = P7CTL_INIT_FUNC(SD_2_DAT02, 10, 2),
+ [P7_CAM_5_DATA04] = P7CTL_INIT_FUNC(CAM_5_DATA04, 11, 0),
+ [P7_GPIO_011] = P7CTL_INIT_FUNC(GPIO_011, 11, 1),
+ [P7_SD_2_DAT03] = P7CTL_INIT_FUNC(SD_2_DAT03, 11, 2),
+ [P7_CAM_5_DATA05] = P7CTL_INIT_FUNC(CAM_5_DATA05, 12, 0),
+ [P7_GPIO_012] = P7CTL_INIT_FUNC(GPIO_012, 12, 1),
+ [P7_CAM_5_DATA06] = P7CTL_INIT_FUNC(CAM_5_DATA06, 13, 0),
+ [P7_GPIO_013] = P7CTL_INIT_FUNC(GPIO_013, 13, 1),
+ [P7_CAM_5_DATA07] = P7CTL_INIT_FUNC(CAM_5_DATA07, 14, 0),
+ [P7_GPIO_014] = P7CTL_INIT_FUNC(GPIO_014, 14, 1),
+ [P7_SD_1_CLK] = P7CTL_INIT_FUNC(SD_1_CLK, 15, 0),
+ [P7_UART_5_TX] = P7CTL_INIT_FUNC(UART_5_TX, 15, 2),
+ [P7_SD_1_CMD] = P7CTL_INIT_FUNC(SD_1_CMD, 16, 0),
+ [P7_UART_5_RX] = P7CTL_INIT_FUNC(UART_5_RX, 16, 2),
+ [P7_SD_1_DAT00] = P7CTL_INIT_FUNC(SD_1_DAT00, 17, 0),
+ [P7_UART_6_TX] = P7CTL_INIT_FUNC(UART_6_TX, 17, 2),
+ [P7_SD_1_DAT02] = P7CTL_INIT_FUNC(SD_1_DAT02, 18, 0),
+ [P7_UART_7_TX] = P7CTL_INIT_FUNC(UART_7_TX, 18, 2),
+ [P7_SD_1_DAT01] = P7CTL_INIT_FUNC(SD_1_DAT01, 19, 0),
+ [P7_UART_6_RX] = P7CTL_INIT_FUNC(UART_6_RX, 19, 2),
+ [P7_SD_1_DAT03] = P7CTL_INIT_FUNC(SD_1_DAT03, 20, 0),
+ [P7_UART_7_RX] = P7CTL_INIT_FUNC(UART_7_RX, 20, 2),
+ [P7_SD_0_CLK] = P7CTL_INIT_FUNC(SD_0_CLK, 21, 0),
+ [P7_SD_0_CMD] = P7CTL_INIT_FUNC(SD_0_CMD, 22, 0),
+ [P7_SD_0_DAT00] = P7CTL_INIT_FUNC(SD_0_DAT00, 23, 0),
+ [P7_SD_0_DAT01] = P7CTL_INIT_FUNC(SD_0_DAT01, 24, 0),
+ [P7_SD_0_DAT02] = P7CTL_INIT_FUNC(SD_0_DAT02, 25, 0),
+ [P7_SD_0_DAT03] = P7CTL_INIT_FUNC(SD_0_DAT03, 26, 0),
+ [P7_NAND_NCE] = P7CTL_INIT_FUNC(NAND_NCE, 27, 0),
+ [P7_SPI_00a] = P7CTL_INIT_FUNC(SPI_00a, 27, 2),
+ [P7_NAND_NR] = P7CTL_INIT_FUNC(NAND_NR, 28, 0),
+ [P7_SPI_01a] = P7CTL_INIT_FUNC(SPI_01a, 28, 2),
+ [P7_NAND_NW] = P7CTL_INIT_FUNC(NAND_NW, 29, 0),
+ [P7_SPI_02a] = P7CTL_INIT_FUNC(SPI_02a, 29, 2),
+ [P7_NAND_AL] = P7CTL_INIT_FUNC(NAND_AL, 30, 0),
+ [P7_SPI_03a] = P7CTL_INIT_FUNC(SPI_03a, 30, 2),
+ [P7_NAND_CL] = P7CTL_INIT_FUNC(NAND_CL, 31, 0),
+ [P7_SPI_04a] = P7CTL_INIT_FUNC(SPI_04a, 31, 2),
+ [P7_NAND_RNB] = P7CTL_INIT_FUNC(NAND_RNB, 32, 0),
+ [P7_SPI_05a] = P7CTL_INIT_FUNC(SPI_05a, 32, 2),
+ [P7_NAND_DQS] = P7CTL_INIT_FUNC(NAND_DQS, 33, 0),
+ [P7_GPIO_033] = P7CTL_INIT_FUNC(GPIO_033, 33, 1),
+ [P7_CAN1_RXa] = P7CTL_INIT_FUNC(CAN1_RXa, 33, 2),
+ [P7_NAND_DATA_00] = P7CTL_INIT_FUNC(NAND_DATA_00, 34, 0),
+ [P7_SPI_06a] = P7CTL_INIT_FUNC(SPI_06a, 34, 2),
+ [P7_NAND_DATA_01] = P7CTL_INIT_FUNC(NAND_DATA_01, 35, 0),
+ [P7_SPI_07a] = P7CTL_INIT_FUNC(SPI_07a, 35, 2),
+ [P7_NAND_DATA_02] = P7CTL_INIT_FUNC(NAND_DATA_02, 36, 0),
+ [P7_SPI_08a] = P7CTL_INIT_FUNC(SPI_08a, 36, 2),
+ [P7_NAND_DATA_03] = P7CTL_INIT_FUNC(NAND_DATA_03, 37, 0),
+ [P7_SPI_09a] = P7CTL_INIT_FUNC(SPI_09a, 37, 2),
+ [P7_NAND_DATA_04] = P7CTL_INIT_FUNC(NAND_DATA_04, 38, 0),
+ [P7_GPIO_038] = P7CTL_INIT_FUNC(GPIO_038, 38, 1),
+ [P7_NAND_DATA_05] = P7CTL_INIT_FUNC(NAND_DATA_05, 39, 0),
+ [P7_GPIO_039] = P7CTL_INIT_FUNC(GPIO_039, 39, 1),
+ [P7_NAND_DATA_06] = P7CTL_INIT_FUNC(NAND_DATA_06, 40, 0),
+ [P7_GPIO_040] = P7CTL_INIT_FUNC(GPIO_040, 40, 1),
+ [P7_NAND_DATA_07] = P7CTL_INIT_FUNC(NAND_DATA_07, 41, 0),
+ [P7_GPIO_041] = P7CTL_INIT_FUNC(GPIO_041, 41, 1),
+ [P7_NAND_WP] = P7CTL_INIT_FUNC(NAND_WP, 42, 0),
+ [P7_GPIO_042] = P7CTL_INIT_FUNC(GPIO_042, 42, 1),
+ [P7_CAN1_TXa] = P7CTL_INIT_FUNC(CAN1_TXa, 42, 2),
+ [P7_FORCE_POWER_ON] = P7CTL_INIT_FUNC(FORCE_POWER_ON, 43, 0),
+ [P7_TRST_N] = P7CTL_INIT_FUNC(TRST_N, 44, 0),
+ [P7_TDI] = P7CTL_INIT_FUNC(TDI, 45, 0),
+ [P7_TDO] = P7CTL_INIT_FUNC(TDO, 46, 0),
+ [P7_TCK] = P7CTL_INIT_FUNC(TCK, 47, 0),
+ [P7_TMS] = P7CTL_INIT_FUNC(TMS, 48, 0),
+ [P7_GPIO_049] = P7CTL_INIT_FUNC(GPIO_049, 49, 1),
+ [P7_GPIO_050] = P7CTL_INIT_FUNC(GPIO_050, 50, 1),
+ [P7_UART_1_RX] = P7CTL_INIT_FUNC(UART_1_RX, 51, 0),
+ [P7_UART_1_TX] = P7CTL_INIT_FUNC(UART_1_TX, 52, 0),
+ [P7_UART_1_RTS] = P7CTL_INIT_FUNC(UART_1_RTS, 53, 0),
+ [P7_CAN0_RXb] = P7CTL_INIT_FUNC(CAN0_RXb, 53, 2),
+ [P7_UART_1_CTS] = P7CTL_INIT_FUNC(UART_1_CTS, 54, 0),
+ [P7_CAN0_TXb] = P7CTL_INIT_FUNC(CAN0_TXb, 54, 2),
+ [P7_UART_0_RX] = P7CTL_INIT_FUNC(UART_0_RX, 55, 0),
+ [P7_GPIO_055] = P7CTL_INIT_FUNC(GPIO_055, 55, 1),
+ [P7_UART_0_TX] = P7CTL_INIT_FUNC(UART_0_TX, 56, 0),
+ [P7_GPIO_056] = P7CTL_INIT_FUNC(GPIO_056, 56, 1),
+ [P7_UART_0_RTS] = P7CTL_INIT_FUNC(UART_0_RTS, 57, 0),
+ [P7_GPIO_057] = P7CTL_INIT_FUNC(GPIO_057, 57, 1),
+ [P7_UART_0_CTS] = P7CTL_INIT_FUNC(UART_0_CTS, 58, 0),
+ [P7_GPIO_058] = P7CTL_INIT_FUNC(GPIO_058, 58, 1),
+ [P7_I2C_2_DAT] = P7CTL_INIT_FUNC(I2C_2_DAT, 59, 0),
+ [P7_GPIO_059] = P7CTL_INIT_FUNC(GPIO_059, 59, 1),
+ [P7_I2C_2_SL_DAT] = P7CTL_INIT_FUNC(I2C_2_SL_DAT, 59, 2),
+ [P7_I2C_2_CLK] = P7CTL_INIT_FUNC(I2C_2_CLK, 60, 0),
+ [P7_GPIO_060] = P7CTL_INIT_FUNC(GPIO_060, 60, 1),
+ [P7_I2C_2_SL_CLK] = P7CTL_INIT_FUNC(I2C_2_SL_CLK, 60, 2),
+ [P7_I2C_1_DAT] = P7CTL_INIT_FUNC(I2C_1_DAT, 61, 0),
+ [P7_GPIO_061] = P7CTL_INIT_FUNC(GPIO_061, 61, 1),
+ [P7_I2C_1_SL_DAT] = P7CTL_INIT_FUNC(I2C_1_SL_DAT, 61, 2),
+ [P7_I2C_1_CLK] = P7CTL_INIT_FUNC(I2C_1_CLK, 62, 0),
+ [P7_GPIO_062] = P7CTL_INIT_FUNC(GPIO_062, 62, 1),
+ [P7_I2C_1_SL_CLK] = P7CTL_INIT_FUNC(I2C_1_SL_CLK, 62, 2),
+ [P7_I2C_0_DAT] = P7CTL_INIT_FUNC(I2C_0_DAT, 63, 0),
+ [P7_GPIO_063] = P7CTL_INIT_FUNC(GPIO_063, 63, 1),
+ [P7_I2C_0_SL_DAT] = P7CTL_INIT_FUNC(I2C_0_SL_DAT, 63, 2),
+ [P7_I2C_0_CLK] = P7CTL_INIT_FUNC(I2C_0_CLK, 64, 0),
+ [P7_GPIO_064] = P7CTL_INIT_FUNC(GPIO_064, 64, 1),
+ [P7_I2C_0_SL_CLK] = P7CTL_INIT_FUNC(I2C_0_SL_CLK, 64, 2),
+ [P7_UART_4_RX] = P7CTL_INIT_FUNC(UART_4_RX, 65, 0),
+ [P7_GPIO_065] = P7CTL_INIT_FUNC(GPIO_065, 65, 1),
+ [P7_UART_4_TX] = P7CTL_INIT_FUNC(UART_4_TX, 66, 0),
+ [P7_GPIO_066] = P7CTL_INIT_FUNC(GPIO_066, 66, 1),
+ [P7_UART_3_RX] = P7CTL_INIT_FUNC(UART_3_RX, 67, 0),
+ [P7_GPIO_067] = P7CTL_INIT_FUNC(GPIO_067, 67, 1),
+ [P7_UART_3_TX] = P7CTL_INIT_FUNC(UART_3_TX, 68, 0),
+ [P7_GPIO_068] = P7CTL_INIT_FUNC(GPIO_068, 68, 1),
+ [P7_UART_2_RX] = P7CTL_INIT_FUNC(UART_2_RX, 69, 0),
+ [P7_CAN1_TXb] = P7CTL_INIT_FUNC(CAN1_TXb, 69, 2),
+ [P7_UART_2_TX] = P7CTL_INIT_FUNC(UART_2_TX, 70, 0),
+ [P7_CAN1_RXb] = P7CTL_INIT_FUNC(CAN1_RXb, 70, 2),
+ [P7_I2C_SECURE_CLK] = P7CTL_INIT_FUNC(I2C_SECURE_CLK, 70, 3),
+ [P7_SPI_09b] = P7CTL_INIT_FUNC(SPI_09b, 71, 0),
+ [P7_GPIO_071] = P7CTL_INIT_FUNC(GPIO_071, 71, 1),
+ [P7_PWM_15] = P7CTL_INIT_FUNC(PWM_15, 71, 2),
+ [P7_SPI_10b] = P7CTL_INIT_FUNC(SPI_10b, 72, 0),
+ [P7_GPIO_072] = P7CTL_INIT_FUNC(GPIO_072, 72, 1),
+ [P7_SPI_11b] = P7CTL_INIT_FUNC(SPI_11b, 73, 0),
+ [P7_GPIO_073] = P7CTL_INIT_FUNC(GPIO_073, 73, 1),
+ [P7_I2C_SECURE_CLKa] = P7CTL_INIT_FUNC(I2C_SECURE_CLKa, 73, 2),
+ [P7_SPI_12b] = P7CTL_INIT_FUNC(SPI_12b, 74, 0),
+ [P7_GPIO_074] = P7CTL_INIT_FUNC(GPIO_074, 74, 1),
+ [P7_SPI_13b] = P7CTL_INIT_FUNC(SPI_13b, 75, 0),
+ [P7_GPIO_075] = P7CTL_INIT_FUNC(GPIO_075, 75, 1),
+ [P7_SPI_14b] = P7CTL_INIT_FUNC(SPI_14b, 76, 0),
+ [P7_GPIO_076] = P7CTL_INIT_FUNC(GPIO_076, 76, 1),
+ [P7_SPI_00] = P7CTL_INIT_FUNC(SPI_00, 77, 0),
+ [P7_GPIO_077] = P7CTL_INIT_FUNC(GPIO_077, 77, 1),
+ [P7_AAI_15] = P7CTL_INIT_FUNC(AAI_15, 77, 2),
+ [P7_CAN1_TX] = P7CTL_INIT_FUNC(CAN1_TX, 77, 3),
+ [P7_SPI_01] = P7CTL_INIT_FUNC(SPI_01, 78, 0),
+ [P7_GPIO_078] = P7CTL_INIT_FUNC(GPIO_078, 78, 1),
+ [P7_AAI_16] = P7CTL_INIT_FUNC(AAI_16, 78, 2),
+ [P7_CAN1_RX] = P7CTL_INIT_FUNC(CAN1_RX, 78, 3),
+ [P7_SPI_02] = P7CTL_INIT_FUNC(SPI_02, 79, 0),
+ [P7_GPIO_079] = P7CTL_INIT_FUNC(GPIO_079, 79, 1),
+ [P7_AAI_17] = P7CTL_INIT_FUNC(AAI_17, 79, 2),
+ [P7_CAN0_TX] = P7CTL_INIT_FUNC(CAN0_TX, 79, 3),
+ [P7_SPI_03] = P7CTL_INIT_FUNC(SPI_03, 80, 0),
+ [P7_GPIO_080] = P7CTL_INIT_FUNC(GPIO_080, 80, 1),
+ [P7_AAI_18] = P7CTL_INIT_FUNC(AAI_18, 80, 2),
+ [P7_CAN0_RX] = P7CTL_INIT_FUNC(CAN0_RX, 80, 3),
+ [P7_SPI_04] = P7CTL_INIT_FUNC(SPI_04, 81, 0),
+ [P7_GPIO_081] = P7CTL_INIT_FUNC(GPIO_081, 81, 1),
+ [P7_AAI_19] = P7CTL_INIT_FUNC(AAI_19, 81, 2),
+ [P7_SPI_05] = P7CTL_INIT_FUNC(SPI_05, 82, 0),
+ [P7_GPIO_082] = P7CTL_INIT_FUNC(GPIO_082, 82, 1),
+ [P7_AAI_20] = P7CTL_INIT_FUNC(AAI_20, 82, 2),
+ [P7_SPI_06] = P7CTL_INIT_FUNC(SPI_06, 83, 0),
+ [P7_GPIO_083] = P7CTL_INIT_FUNC(GPIO_083, 83, 1),
+ [P7_AAI_21] = P7CTL_INIT_FUNC(AAI_21, 83, 2),
+ [P7_SPI_07] = P7CTL_INIT_FUNC(SPI_07, 84, 0),
+ [P7_GPIO_084] = P7CTL_INIT_FUNC(GPIO_084, 84, 1),
+ [P7_AAI_22] = P7CTL_INIT_FUNC(AAI_22, 84, 2),
+ [P7_SPI_08] = P7CTL_INIT_FUNC(SPI_08, 85, 0),
+ [P7_GPIO_085] = P7CTL_INIT_FUNC(GPIO_085, 85, 1),
+ [P7_AAI_23] = P7CTL_INIT_FUNC(AAI_23, 85, 2),
+ [P7_SPI_09] = P7CTL_INIT_FUNC(SPI_09, 86, 0),
+ [P7_GPIO_086] = P7CTL_INIT_FUNC(GPIO_086, 86, 1),
+ [P7_AAI_24] = P7CTL_INIT_FUNC(AAI_24, 86, 2),
+ [P7_SPI_10] = P7CTL_INIT_FUNC(SPI_10, 87, 0),
+ [P7_GPIO_087] = P7CTL_INIT_FUNC(GPIO_087, 87, 1),
+ [P7_AAI_25] = P7CTL_INIT_FUNC(AAI_25, 87, 2),
+ [P7_SPI_11] = P7CTL_INIT_FUNC(SPI_11, 88, 0),
+ [P7_GPIO_088] = P7CTL_INIT_FUNC(GPIO_088, 88, 1),
+ [P7_AAI_26] = P7CTL_INIT_FUNC(AAI_26, 88, 2),
+ [P7_SPI_12] = P7CTL_INIT_FUNC(SPI_12, 89, 0),
+ [P7_GPIO_089] = P7CTL_INIT_FUNC(GPIO_089, 89, 1),
+ [P7_AAI_27] = P7CTL_INIT_FUNC(AAI_27, 89, 2),
+ [P7_SPI_13] = P7CTL_INIT_FUNC(SPI_13, 90, 0),
+ [P7_GPIO_090] = P7CTL_INIT_FUNC(GPIO_090, 90, 1),
+ [P7_AAI_28] = P7CTL_INIT_FUNC(AAI_28, 90, 2),
+ [P7_SPI_14] = P7CTL_INIT_FUNC(SPI_14, 91, 0),
+ [P7_GPIO_091] = P7CTL_INIT_FUNC(GPIO_091, 91, 1),
+ [P7_AAI_29] = P7CTL_INIT_FUNC(AAI_29, 91, 2),
+ [P7_SPI_15] = P7CTL_INIT_FUNC(SPI_15, 92, 0),
+ [P7_GPIO_092] = P7CTL_INIT_FUNC(GPIO_092, 92, 1),
+ [P7_AAI_30] = P7CTL_INIT_FUNC(AAI_30, 92, 2),
+ [P7_P7MU_CLK_OUT] = P7CTL_INIT_FUNC(P7MU_CLK_OUT, 93, 0),
+ [P7_PWM_15a] = P7CTL_INIT_FUNC(PWM_15a, 93, 2),
+ [P7_I2C_SECURE_DAT] = P7CTL_INIT_FUNC(I2C_SECURE_DAT, 93, 3),
+ [P7_REBOOT_P7MU] = P7CTL_INIT_FUNC(REBOOT_P7MU, 94, 0),
+ [P7_GPIO_094] = P7CTL_INIT_FUNC(GPIO_094, 94, 1),
+ [P7_ULPI_0_DATA00] = P7CTL_INIT_FUNC(ULPI_0_DATA00, 95, 0),
+ [P7_ULPI_0_DATA01] = P7CTL_INIT_FUNC(ULPI_0_DATA01, 96, 0),
+ [P7_ULPI_0_DATA02] = P7CTL_INIT_FUNC(ULPI_0_DATA02, 97, 0),
+ [P7_ULPI_0_DATA03] = P7CTL_INIT_FUNC(ULPI_0_DATA03, 98, 0),
+ [P7_ULPI_0_DATA04] = P7CTL_INIT_FUNC(ULPI_0_DATA04, 99, 0),
+ [P7_ULPI_0_DATA05] = P7CTL_INIT_FUNC(ULPI_0_DATA05, 100, 0),
+ [P7_ULPI_0_DATA06] = P7CTL_INIT_FUNC(ULPI_0_DATA06, 101, 0),
+ [P7_ULPI_0_DATA07] = P7CTL_INIT_FUNC(ULPI_0_DATA07, 102, 0),
+ [P7_ULPI_0_NXT] = P7CTL_INIT_FUNC(ULPI_0_NXT, 103, 0),
+ [P7_ULPI_0_DIR] = P7CTL_INIT_FUNC(ULPI_0_DIR, 104, 0),
+ [P7_ULPI_0_CLK] = P7CTL_INIT_FUNC(ULPI_0_CLK, 105, 0),
+ [P7_ULPI_1_DATA00] = P7CTL_INIT_FUNC(ULPI_1_DATA00, 106, 0),
+ [P7_GPIO_106] = P7CTL_INIT_FUNC(GPIO_106, 106, 1),
+ [P7_I2C_2_CLKa] = P7CTL_INIT_FUNC(I2C_2_CLKa, 106, 2),
+ [P7_ULPI_1_DATA01] = P7CTL_INIT_FUNC(ULPI_1_DATA01, 107, 0),
+ [P7_GPIO_107] = P7CTL_INIT_FUNC(GPIO_107, 107, 1),
+ [P7_I2C_2_DATa] = P7CTL_INIT_FUNC(I2C_2_DATa, 107, 2),
+ [P7_ULPI_1_DATA02] = P7CTL_INIT_FUNC(ULPI_1_DATA02, 108, 0),
+ [P7_GPIO_108] = P7CTL_INIT_FUNC(GPIO_108, 108, 1),
+ [P7_I2C_2_CLKb] = P7CTL_INIT_FUNC(I2C_2_CLKb, 108, 2),
+ [P7_ULPI_1_DATA03] = P7CTL_INIT_FUNC(ULPI_1_DATA03, 109, 0),
+ [P7_GPIO_109] = P7CTL_INIT_FUNC(GPIO_109, 109, 1),
+ [P7_I2C_2_DATb] = P7CTL_INIT_FUNC(I2C_2_DATb, 109, 2),
+ [P7_ULPI_1_DATA04] = P7CTL_INIT_FUNC(ULPI_1_DATA04, 110, 0),
+ [P7_GPIO_110] = P7CTL_INIT_FUNC(GPIO_110, 110, 1),
+ [P7_I2C_2_CLKc] = P7CTL_INIT_FUNC(I2C_2_CLKc, 110, 2),
+ [P7_ULPI_1_DATA05] = P7CTL_INIT_FUNC(ULPI_1_DATA05, 111, 0),
+ [P7_GPIO_111] = P7CTL_INIT_FUNC(GPIO_111, 111, 1),
+ [P7_I2C_2_DATc] = P7CTL_INIT_FUNC(I2C_2_DATc, 111, 2),
+ [P7_ULPI_1_DATA06] = P7CTL_INIT_FUNC(ULPI_1_DATA06, 112, 0),
+ [P7_GPIO_112] = P7CTL_INIT_FUNC(GPIO_112, 112, 1),
+ [P7_I2C_2_CLKd] = P7CTL_INIT_FUNC(I2C_2_CLKd, 112, 2),
+ [P7_ULPI_1_DATA07] = P7CTL_INIT_FUNC(ULPI_1_DATA07, 113, 0),
+ [P7_GPIO_113] = P7CTL_INIT_FUNC(GPIO_113, 113, 1),
+ [P7_I2C_2_DATd] = P7CTL_INIT_FUNC(I2C_2_DATd, 113, 2),
+ [P7_ULPI_1_NXT] = P7CTL_INIT_FUNC(ULPI_1_NXT, 114, 0),
+ [P7_GPIO_114] = P7CTL_INIT_FUNC(GPIO_114, 114, 1),
+ [P7_I2C_2_CLKe] = P7CTL_INIT_FUNC(I2C_2_CLKe, 114, 2),
+ [P7_ULPI_1_DIR] = P7CTL_INIT_FUNC(ULPI_1_DIR, 115, 0),
+ [P7_GPIO_115] = P7CTL_INIT_FUNC(GPIO_115, 115, 1),
+ [P7_ULPI_1_STP] = P7CTL_INIT_FUNC(ULPI_1_STP, 116, 0),
+ [P7_GPIO_116] = P7CTL_INIT_FUNC(GPIO_116, 116, 1),
+ [P7_I2C_2_DATe] = P7CTL_INIT_FUNC(I2C_2_DATe, 116, 2),
+ [P7_ULPI_0_STP] = P7CTL_INIT_FUNC(ULPI_0_STP, 117, 0),
+ [P7_ULPI_1_CLK] = P7CTL_INIT_FUNC(ULPI_1_CLK, 118, 0),
+ [P7_GPIO_118] = P7CTL_INIT_FUNC(GPIO_118, 118, 1),
+ [P7_AAI_00] = P7CTL_INIT_FUNC(AAI_00, 119, 0),
+ [P7_GPIO_119] = P7CTL_INIT_FUNC(GPIO_119, 119, 1),
+ [P7_PWM_00] = P7CTL_INIT_FUNC(PWM_00, 119, 2),
+ [P7_AAI_01] = P7CTL_INIT_FUNC(AAI_01, 120, 0),
+ [P7_GPIO_120] = P7CTL_INIT_FUNC(GPIO_120, 120, 1),
+ [P7_PWM_01] = P7CTL_INIT_FUNC(PWM_01, 120, 2),
+ [P7_AAI_02] = P7CTL_INIT_FUNC(AAI_02, 121, 0),
+ [P7_GPIO_121] = P7CTL_INIT_FUNC(GPIO_121, 121, 1),
+ [P7_PWM_02] = P7CTL_INIT_FUNC(PWM_02, 121, 2),
+ [P7_AAI_03] = P7CTL_INIT_FUNC(AAI_03, 122, 0),
+ [P7_GPIO_122] = P7CTL_INIT_FUNC(GPIO_122, 122, 1),
+ [P7_PWM_03] = P7CTL_INIT_FUNC(PWM_03, 122, 2),
+ [P7_AAI_04] = P7CTL_INIT_FUNC(AAI_04, 123, 0),
+ [P7_GPIO_123] = P7CTL_INIT_FUNC(GPIO_123, 123, 1),
+ [P7_PWM_04] = P7CTL_INIT_FUNC(PWM_04, 123, 2),
+ [P7_AAI_05] = P7CTL_INIT_FUNC(AAI_05, 124, 0),
+ [P7_GPIO_124] = P7CTL_INIT_FUNC(GPIO_124, 124, 1),
+ [P7_PWM_05] = P7CTL_INIT_FUNC(PWM_05, 124, 2),
+ [P7_AAI_06] = P7CTL_INIT_FUNC(AAI_06, 125, 0),
+ [P7_GPIO_125] = P7CTL_INIT_FUNC(GPIO_125, 125, 1),
+ [P7_PWM_06] = P7CTL_INIT_FUNC(PWM_06, 125, 2),
+ [P7_AAI_07] = P7CTL_INIT_FUNC(AAI_07, 126, 0),
+ [P7_GPIO_126] = P7CTL_INIT_FUNC(GPIO_126, 126, 1),
+ [P7_PWM_07] = P7CTL_INIT_FUNC(PWM_07, 126, 2),
+ [P7_AAI_08] = P7CTL_INIT_FUNC(AAI_08, 127, 0),
+ [P7_GPIO_127] = P7CTL_INIT_FUNC(GPIO_127, 127, 1),
+ [P7_PWM_08] = P7CTL_INIT_FUNC(PWM_08, 127, 2),
+ [P7_AAI_09] = P7CTL_INIT_FUNC(AAI_09, 128, 0),
+ [P7_GPIO_128] = P7CTL_INIT_FUNC(GPIO_128, 128, 1),
+ [P7_PWM_09] = P7CTL_INIT_FUNC(PWM_09, 128, 2),
+ [P7_AAI_10] = P7CTL_INIT_FUNC(AAI_10, 129, 0),
+ [P7_GPIO_129] = P7CTL_INIT_FUNC(GPIO_129, 129, 1),
+ [P7_PWM_10] = P7CTL_INIT_FUNC(PWM_10, 129, 2),
+ [P7_AAI_11] = P7CTL_INIT_FUNC(AAI_11, 130, 0),
+ [P7_GPIO_130] = P7CTL_INIT_FUNC(GPIO_130, 130, 1),
+ [P7_PWM_11] = P7CTL_INIT_FUNC(PWM_11, 130, 2),
+ [P7_AAI_12] = P7CTL_INIT_FUNC(AAI_12, 131, 0),
+ [P7_GPIO_131] = P7CTL_INIT_FUNC(GPIO_131, 131, 1),
+ [P7_PWM_12] = P7CTL_INIT_FUNC(PWM_12, 131, 2),
+ [P7_AAI_13] = P7CTL_INIT_FUNC(AAI_13, 132, 0),
+ [P7_GPIO_132] = P7CTL_INIT_FUNC(GPIO_132, 132, 1),
+ [P7_PWM_13] = P7CTL_INIT_FUNC(PWM_13, 132, 2),
+ [P7_AAI_14] = P7CTL_INIT_FUNC(AAI_14, 133, 0),
+ [P7_GPIO_133] = P7CTL_INIT_FUNC(GPIO_133, 133, 1),
+ [P7_PWM_14] = P7CTL_INIT_FUNC(PWM_14, 133, 2),
+ [P7_SPI_16] = P7CTL_INIT_FUNC(SPI_16, 134, 0),
+ [P7_GPIO_134] = P7CTL_INIT_FUNC(GPIO_134, 134, 1),
+ [P7_ETH_MII_TXER] = P7CTL_INIT_FUNC(ETH_MII_TXER, 134, 2),
+ [P7_SPI_17] = P7CTL_INIT_FUNC(SPI_17, 135, 0),
+ [P7_GPIO_135] = P7CTL_INIT_FUNC(GPIO_135, 135, 1),
+ [P7_ETH_MII_RXER] = P7CTL_INIT_FUNC(ETH_MII_RXER, 135, 2),
+ [P7_SPI_18] = P7CTL_INIT_FUNC(SPI_18, 136, 0),
+ [P7_GPIO_136] = P7CTL_INIT_FUNC(GPIO_136, 136, 1),
+ [P7_ETH_MII_CRS] = P7CTL_INIT_FUNC(ETH_MII_CRS, 136, 2),
+ [P7_SPI_19] = P7CTL_INIT_FUNC(SPI_19, 137, 0),
+ [P7_GPIO_137] = P7CTL_INIT_FUNC(GPIO_137, 137, 1),
+ [P7_ETH_MII_COL] = P7CTL_INIT_FUNC(ETH_MII_COL, 137, 2),
+ [P7_ETH_RGMII_TXC] = P7CTL_INIT_FUNC(ETH_RGMII_TXC, 138, 0),
+ [P7_GPIO_138] = P7CTL_INIT_FUNC(GPIO_138, 138, 1),
+ [P7_ETH_RGMII_TXD_00] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_00, 139, 0),
+ [P7_GPIO_139] = P7CTL_INIT_FUNC(GPIO_139, 139, 1),
+ [P7_ETH_RGMII_TXD_01] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_01, 140, 0),
+ [P7_GPIO_140] = P7CTL_INIT_FUNC(GPIO_140, 140, 1),
+ [P7_ETH_RGMII_TXD_02] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_02, 141, 0),
+ [P7_GPIO_141] = P7CTL_INIT_FUNC(GPIO_141, 141, 1),
+ [P7_ETH_RGMII_TXD_03] = P7CTL_INIT_FUNC(ETH_RGMII_TXD_03, 142, 0),
+ [P7_GPIO_142] = P7CTL_INIT_FUNC(GPIO_142, 142, 1),
+ [P7_ETH_RGMII_TX_CTL] = P7CTL_INIT_FUNC(ETH_RGMII_TX_CTL, 143, 0),
+ [P7_GPIO_143] = P7CTL_INIT_FUNC(GPIO_143, 143, 1),
+ [P7_ETH_RGMII_RXC] = P7CTL_INIT_FUNC(ETH_RGMII_RXC, 144, 0),
+ [P7_GPIO_144] = P7CTL_INIT_FUNC(GPIO_144, 144, 1),
+ [P7_ETH_RGMII_RXD_00] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_00, 145, 0),
+ [P7_GPIO_145] = P7CTL_INIT_FUNC(GPIO_145, 145, 1),
+ [P7_ETH_RGMII_RXD_01] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_01, 146, 0),
+ [P7_GPIO_146] = P7CTL_INIT_FUNC(GPIO_146, 146, 1),
+ [P7_ETH_RGMII_RXD_02] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_02, 147, 0),
+ [P7_GPIO_147] = P7CTL_INIT_FUNC(GPIO_147, 147, 1),
+ [P7_ETH_RGMII_RXD_03] = P7CTL_INIT_FUNC(ETH_RGMII_RXD_03, 148, 0),
+ [P7_GPIO_148] = P7CTL_INIT_FUNC(GPIO_148, 148, 1),
+ [P7_ETH_RGMII_RX_CTL] = P7CTL_INIT_FUNC(ETH_RGMII_RX_CTL, 149, 0),
+ [P7_GPIO_149] = P7CTL_INIT_FUNC(GPIO_149, 149, 1),
+ [P7_ETH_MDC] = P7CTL_INIT_FUNC(ETH_MDC, 150, 0),
+ [P7_GPIO_150] = P7CTL_INIT_FUNC(GPIO_150, 150, 1),
+ [P7_ETH_MDIO] = P7CTL_INIT_FUNC(ETH_MDIO, 151, 0),
+ [P7_GPIO_151] = P7CTL_INIT_FUNC(GPIO_151, 151, 1),
+ [P7_LCD_0_DEN] = P7CTL_INIT_FUNC(LCD_0_DEN, 152, 0),
+ [P7_GPIO_152] = P7CTL_INIT_FUNC(GPIO_152, 152, 1),
+ [P7_CAM_1_VS] = P7CTL_INIT_FUNC(CAM_1_VS, 152, 2),
+ [P7_LCD_0_HS] = P7CTL_INIT_FUNC(LCD_0_HS, 153, 0),
+ [P7_GPIO_153] = P7CTL_INIT_FUNC(GPIO_153, 153, 1),
+ [P7_CAM_1_HS] = P7CTL_INIT_FUNC(CAM_1_HS, 153, 2),
+ [P7_LCD_0_DENa] = P7CTL_INIT_FUNC(LCD_0_DENa, 153, 3),
+ [P7_LCD_0_VS] = P7CTL_INIT_FUNC(LCD_0_VS, 154, 0),
+ [P7_GPIO_154] = P7CTL_INIT_FUNC(GPIO_154, 154, 1),
+ [P7_CAM_0_VS] = P7CTL_INIT_FUNC(CAM_0_VS, 154, 2),
+ [P7_LCD_0_DATA00] = P7CTL_INIT_FUNC(LCD_0_DATA00, 155, 0),
+ [P7_GPIO_155] = P7CTL_INIT_FUNC(GPIO_155, 155, 1),
+ [P7_CAM_0_HS] = P7CTL_INIT_FUNC(CAM_0_HS, 155, 2),
+ [P7_LCD_0_DATA01] = P7CTL_INIT_FUNC(LCD_0_DATA01, 156, 0),
+ [P7_GPIO_156] = P7CTL_INIT_FUNC(GPIO_156, 156, 1),
+ [P7_CAM_2_VS] = P7CTL_INIT_FUNC(CAM_2_VS, 156, 2),
+ [P7_LCD_0_DATA02] = P7CTL_INIT_FUNC(LCD_0_DATA02, 157, 0),
+ [P7_GPIO_157] = P7CTL_INIT_FUNC(GPIO_157, 157, 1),
+ [P7_CAM_2_HS] = P7CTL_INIT_FUNC(CAM_2_HS, 157, 2),
+ [P7_LCD_0_DATA03] = P7CTL_INIT_FUNC(LCD_0_DATA03, 158, 0),
+ [P7_GPIO_158] = P7CTL_INIT_FUNC(GPIO_158, 158, 1),
+ [P7_CAM_3_VS] = P7CTL_INIT_FUNC(CAM_3_VS, 158, 2),
+ [P7_LCD_0_DATA04] = P7CTL_INIT_FUNC(LCD_0_DATA04, 159, 0),
+ [P7_GPIO_159] = P7CTL_INIT_FUNC(GPIO_159, 159, 1),
+ [P7_CAM_3_HS] = P7CTL_INIT_FUNC(CAM_3_HS, 159, 2),
+ [P7_LCD_0_DATA05] = P7CTL_INIT_FUNC(LCD_0_DATA05, 160, 0),
+ [P7_GPIO_160] = P7CTL_INIT_FUNC(GPIO_160, 160, 1),
+ [P7_CAM_5_VS] = P7CTL_INIT_FUNC(CAM_5_VS, 160, 2),
+ [P7_LCD_0_DATA06] = P7CTL_INIT_FUNC(LCD_0_DATA06, 161, 0),
+ [P7_GPIO_161] = P7CTL_INIT_FUNC(GPIO_161, 161, 1),
+ [P7_CAM_5_HS] = P7CTL_INIT_FUNC(CAM_5_HS, 161, 2),
+ [P7_LCD_0_DATA07] = P7CTL_INIT_FUNC(LCD_0_DATA07, 162, 0),
+ [P7_GPIO_162] = P7CTL_INIT_FUNC(GPIO_162, 162, 1),
+ [P7_CAM_0_DATA08] = P7CTL_INIT_FUNC(CAM_0_DATA08, 162, 2),
+ [P7_LCD_0_DATA08] = P7CTL_INIT_FUNC(LCD_0_DATA08, 163, 0),
+ [P7_GPIO_163] = P7CTL_INIT_FUNC(GPIO_163, 163, 1),
+ [P7_CAM_0_DATA09] = P7CTL_INIT_FUNC(CAM_0_DATA09, 163, 2),
+ [P7_CAM_0_DATA08a] = P7CTL_INIT_FUNC(CAM_0_DATA08a, 163, 3),
+ [P7_LCD_0_DATA09] = P7CTL_INIT_FUNC(LCD_0_DATA09, 164, 0),
+ [P7_GPIO_164] = P7CTL_INIT_FUNC(GPIO_164, 164, 1),
+ [P7_CAM_0_DATA10] = P7CTL_INIT_FUNC(CAM_0_DATA10, 164, 2),
+ [P7_CAM_0_DATA09a] = P7CTL_INIT_FUNC(CAM_0_DATA09a, 164, 3),
+ [P7_LCD_0_DATA10] = P7CTL_INIT_FUNC(LCD_0_DATA10, 165, 0),
+ [P7_GPIO_165] = P7CTL_INIT_FUNC(GPIO_165, 165, 1),
+ [P7_CAM_0_DATA11] = P7CTL_INIT_FUNC(CAM_0_DATA11, 165, 2),
+ [P7_CAM_0_DATA10a] = P7CTL_INIT_FUNC(CAM_0_DATA10a, 165, 3),
+ [P7_LCD_0_DATA11] = P7CTL_INIT_FUNC(LCD_0_DATA11, 166, 0),
+ [P7_GPIO_166] = P7CTL_INIT_FUNC(GPIO_166, 166, 1),
+ [P7_CAM_0_DATA12] = P7CTL_INIT_FUNC(CAM_0_DATA12, 166, 2),
+ [P7_CAM_0_DATA11a] = P7CTL_INIT_FUNC(CAM_0_DATA11a, 166, 3),
+ [P7_LCD_0_DATA12] = P7CTL_INIT_FUNC(LCD_0_DATA12, 167, 0),
+ [P7_GPIO_167] = P7CTL_INIT_FUNC(GPIO_167, 167, 1),
+ [P7_CAM_0_DATA13] = P7CTL_INIT_FUNC(CAM_0_DATA13, 167, 2),
+ [P7_CAM_0_DATA12a] = P7CTL_INIT_FUNC(CAM_0_DATA12a, 167, 3),
+ [P7_LCD_0_DATA13] = P7CTL_INIT_FUNC(LCD_0_DATA13, 168, 0),
+ [P7_GPIO_168] = P7CTL_INIT_FUNC(GPIO_168, 168, 1),
+ [P7_CAM_0_DATA14] = P7CTL_INIT_FUNC(CAM_0_DATA14, 168, 2),
+ [P7_CAM_0_DATA13a] = P7CTL_INIT_FUNC(CAM_0_DATA13a, 168, 3),
+ [P7_LCD_0_DATA14] = P7CTL_INIT_FUNC(LCD_0_DATA14, 169, 0),
+ [P7_GPIO_169] = P7CTL_INIT_FUNC(GPIO_169, 169, 1),
+ [P7_CAM_0_DATA15] = P7CTL_INIT_FUNC(CAM_0_DATA15, 169, 2),
+ [P7_CAM_0_DATA14a] = P7CTL_INIT_FUNC(CAM_0_DATA14a, 169, 3),
+ [P7_LCD_0_DATA15] = P7CTL_INIT_FUNC(LCD_0_DATA15, 170, 0),
+ [P7_GPIO_170] = P7CTL_INIT_FUNC(GPIO_170, 170, 1),
+ [P7_CAM_0_DATA16] = P7CTL_INIT_FUNC(CAM_0_DATA16, 170, 2),
+ [P7_CAM_0_DATA15a] = P7CTL_INIT_FUNC(CAM_0_DATA15a, 170, 3),
+ [P7_LCD_0_DATA16] = P7CTL_INIT_FUNC(LCD_0_DATA16, 171, 0),
+ [P7_GPIO_171] = P7CTL_INIT_FUNC(GPIO_171, 171, 1),
+ [P7_CAM_0_DATA17] = P7CTL_INIT_FUNC(CAM_0_DATA17, 171, 2),
+ [P7_LCD_0_DATA17] = P7CTL_INIT_FUNC(LCD_0_DATA17, 172, 0),
+ [P7_GPIO_172] = P7CTL_INIT_FUNC(GPIO_172, 172, 1),
+ [P7_CAM_0_DATA18] = P7CTL_INIT_FUNC(CAM_0_DATA18, 172, 2),
+ [P7_LCD_0_DATA18] = P7CTL_INIT_FUNC(LCD_0_DATA18, 173, 0),
+ [P7_GPIO_173] = P7CTL_INIT_FUNC(GPIO_173, 173, 1),
+ [P7_CAM_0_DATA19] = P7CTL_INIT_FUNC(CAM_0_DATA19, 173, 2),
+ [P7_LCD_0_DATA19] = P7CTL_INIT_FUNC(LCD_0_DATA19, 174, 0),
+ [P7_GPIO_174] = P7CTL_INIT_FUNC(GPIO_174, 174, 1),
+ [P7_CAM_0_DATA20] = P7CTL_INIT_FUNC(CAM_0_DATA20, 174, 2),
+ [P7_LCD_0_DATA20] = P7CTL_INIT_FUNC(LCD_0_DATA20, 175, 0),
+ [P7_GPIO_175] = P7CTL_INIT_FUNC(GPIO_175, 175, 1),
+ [P7_CAM_0_DATA21] = P7CTL_INIT_FUNC(CAM_0_DATA21, 175, 2),
+ [P7_CAM_3_DATA09a] = P7CTL_INIT_FUNC(CAM_3_DATA09a, 175, 3),
+ [P7_LCD_0_DATA21] = P7CTL_INIT_FUNC(LCD_0_DATA21, 176, 0),
+ [P7_GPIO_176] = P7CTL_INIT_FUNC(GPIO_176, 176, 1),
+ [P7_CAM_0_DATA22] = P7CTL_INIT_FUNC(CAM_0_DATA22, 176, 2),
+ [P7_CAM_3_DATA08a] = P7CTL_INIT_FUNC(CAM_3_DATA08a, 176, 3),
+ [P7_LCD_0_DATA22] = P7CTL_INIT_FUNC(LCD_0_DATA22, 177, 0),
+ [P7_GPIO_177] = P7CTL_INIT_FUNC(GPIO_177, 177, 1),
+ [P7_CAM_0_DATA23] = P7CTL_INIT_FUNC(CAM_0_DATA23, 177, 2),
+ [P7_LCD_0_DATA23] = P7CTL_INIT_FUNC(LCD_0_DATA23, 178, 0),
+ [P7_GPIO_178] = P7CTL_INIT_FUNC(GPIO_178, 178, 1),
+ [P7_CAM_4_VS] = P7CTL_INIT_FUNC(CAM_4_VS, 178, 2),
+ [P7_LCD_0_CLK] = P7CTL_INIT_FUNC(LCD_0_CLK, 179, 0),
+ [P7_GPIO_179] = P7CTL_INIT_FUNC(GPIO_179, 179, 1),
+ [P7_CAM_4_HS] = P7CTL_INIT_FUNC(CAM_4_HS, 179, 2),
+ [P7_CAM_0_CLKa] = P7CTL_INIT_FUNC(CAM_0_CLKa, 179, 3),
+ [P7_LCD_1_HS] = P7CTL_INIT_FUNC(LCD_1_HS, 180, 0),
+ [P7_GPIO_180] = P7CTL_INIT_FUNC(GPIO_180, 180, 1),
+ [P7_CAM_2_CLK] = P7CTL_INIT_FUNC(CAM_2_CLK, 180, 2),
+ [P7_LCD_1_DENa] = P7CTL_INIT_FUNC(LCD_1_DENa, 180, 3),
+ [P7_LCD_1_VS] = P7CTL_INIT_FUNC(LCD_1_VS, 181, 0),
+ [P7_GPIO_181] = P7CTL_INIT_FUNC(GPIO_181, 181, 1),
+ [P7_CAM_2_DATA00] = P7CTL_INIT_FUNC(CAM_2_DATA00, 181, 2),
+ [P7_CPU_TRACECLKOUT] = P7CTL_INIT_FUNC(CPU_TRACECLKOUT, 181, 3),
+ [P7_LCD_1_CLK] = P7CTL_INIT_FUNC(LCD_1_CLK, 182, 0),
+ [P7_GPIO_182] = P7CTL_INIT_FUNC(GPIO_182, 182, 1),
+ [P7_CAM_2_DATA01] = P7CTL_INIT_FUNC(CAM_2_DATA01, 182, 2),
+ [P7_CPU_TRACECTL] = P7CTL_INIT_FUNC(CPU_TRACECTL, 182, 3),
+ [P7_LCD_1_DATA00] = P7CTL_INIT_FUNC(LCD_1_DATA00, 183, 0),
+ [P7_GPIO_183] = P7CTL_INIT_FUNC(GPIO_183, 183, 1),
+ [P7_CAM_2_DATA02] = P7CTL_INIT_FUNC(CAM_2_DATA02, 183, 2),
+ [P7_CPU_TRACEDATA_00] = P7CTL_INIT_FUNC(CPU_TRACEDATA_00, 183, 3),
+ [P7_LCD_1_DATA01] = P7CTL_INIT_FUNC(LCD_1_DATA01, 184, 0),
+ [P7_GPIO_184] = P7CTL_INIT_FUNC(GPIO_184, 184, 1),
+ [P7_CAM_2_DATA03] = P7CTL_INIT_FUNC(CAM_2_DATA03, 184, 2),
+ [P7_CPU_TRACEDATA_01] = P7CTL_INIT_FUNC(CPU_TRACEDATA_01, 184, 3),
+ [P7_LCD_1_DATA02] = P7CTL_INIT_FUNC(LCD_1_DATA02, 185, 0),
+ [P7_GPIO_185] = P7CTL_INIT_FUNC(GPIO_185, 185, 1),
+ [P7_CAM_2_DATA04] = P7CTL_INIT_FUNC(CAM_2_DATA04, 185, 2),
+ [P7_CPU_TRACEDATA_02] = P7CTL_INIT_FUNC(CPU_TRACEDATA_02, 185, 3),
+ [P7_LCD_1_DATA03] = P7CTL_INIT_FUNC(LCD_1_DATA03, 186, 0),
+ [P7_GPIO_186] = P7CTL_INIT_FUNC(GPIO_186, 186, 1),
+ [P7_CAM_2_DATA05] = P7CTL_INIT_FUNC(CAM_2_DATA05, 186, 2),
+ [P7_CPU_TRACEDATA_03] = P7CTL_INIT_FUNC(CPU_TRACEDATA_03, 186, 3),
+ [P7_LCD_1_DATA04] = P7CTL_INIT_FUNC(LCD_1_DATA04, 187, 0),
+ [P7_GPIO_187] = P7CTL_INIT_FUNC(GPIO_187, 187, 1),
+ [P7_CAM_2_DATA06] = P7CTL_INIT_FUNC(CAM_2_DATA06, 187, 2),
+ [P7_CPU_TRACEDATA_04] = P7CTL_INIT_FUNC(CPU_TRACEDATA_04, 187, 3),
+ [P7_LCD_1_DATA05] = P7CTL_INIT_FUNC(LCD_1_DATA05, 188, 0),
+ [P7_GPIO_188] = P7CTL_INIT_FUNC(GPIO_188, 188, 1),
+ [P7_CAM_2_DATA07] = P7CTL_INIT_FUNC(CAM_2_DATA07, 188, 2),
+ [P7_CPU_TRACEDATA_05] = P7CTL_INIT_FUNC(CPU_TRACEDATA_05, 188, 3),
+ [P7_LCD_1_DATA06] = P7CTL_INIT_FUNC(LCD_1_DATA06, 189, 0),
+ [P7_GPIO_189] = P7CTL_INIT_FUNC(GPIO_189, 189, 1),
+ [P7_CAM_3_CLK] = P7CTL_INIT_FUNC(CAM_3_CLK, 189, 2),
+ [P7_CPU_TRACEDATA_06] = P7CTL_INIT_FUNC(CPU_TRACEDATA_06, 189, 3),
+ [P7_LCD_1_DATA07] = P7CTL_INIT_FUNC(LCD_1_DATA07, 190, 0),
+ [P7_GPIO_190] = P7CTL_INIT_FUNC(GPIO_190, 190, 1),
+ [P7_CAM_3_DATA00] = P7CTL_INIT_FUNC(CAM_3_DATA00, 190, 2),
+ [P7_CPU_TRACEDATA_07] = P7CTL_INIT_FUNC(CPU_TRACEDATA_07, 190, 3),
+ [P7_LCD_1_DATA08] = P7CTL_INIT_FUNC(LCD_1_DATA08, 191, 0),
+ [P7_GPIO_191] = P7CTL_INIT_FUNC(GPIO_191, 191, 1),
+ [P7_CAM_3_DATA01] = P7CTL_INIT_FUNC(CAM_3_DATA01, 191, 2),
+ [P7_CPU_TRACEDATA_08] = P7CTL_INIT_FUNC(CPU_TRACEDATA_08, 191, 3),
+ [P7_LCD_1_DATA09] = P7CTL_INIT_FUNC(LCD_1_DATA09, 192, 0),
+ [P7_GPIO_192] = P7CTL_INIT_FUNC(GPIO_192, 192, 1),
+ [P7_CAM_3_DATA02] = P7CTL_INIT_FUNC(CAM_3_DATA02, 192, 2),
+ [P7_CPU_TRACEDATA_09] = P7CTL_INIT_FUNC(CPU_TRACEDATA_09, 192, 3),
+ [P7_LCD_1_DATA10] = P7CTL_INIT_FUNC(LCD_1_DATA10, 193, 0),
+ [P7_GPIO_193] = P7CTL_INIT_FUNC(GPIO_193, 193, 1),
+ [P7_CAM_3_DATA03] = P7CTL_INIT_FUNC(CAM_3_DATA03, 193, 2),
+ [P7_CPU_TRACEDATA_10] = P7CTL_INIT_FUNC(CPU_TRACEDATA_10, 193, 3),
+ [P7_LCD_1_DATA11] = P7CTL_INIT_FUNC(LCD_1_DATA11, 194, 0),
+ [P7_GPIO_194] = P7CTL_INIT_FUNC(GPIO_194, 194, 1),
+ [P7_CAM_3_DATA04] = P7CTL_INIT_FUNC(CAM_3_DATA04, 194, 2),
+ [P7_CPU_TRACEDATA_11] = P7CTL_INIT_FUNC(CPU_TRACEDATA_11, 194, 3),
+ [P7_LCD_1_DATA12] = P7CTL_INIT_FUNC(LCD_1_DATA12, 195, 0),
+ [P7_GPIO_195] = P7CTL_INIT_FUNC(GPIO_195, 195, 1),
+ [P7_CAM_3_DATA05] = P7CTL_INIT_FUNC(CAM_3_DATA05, 195, 2),
+ [P7_CPU_TRACEDATA_12] = P7CTL_INIT_FUNC(CPU_TRACEDATA_12, 195, 3),
+ [P7_LCD_1_DATA13] = P7CTL_INIT_FUNC(LCD_1_DATA13, 196, 0),
+ [P7_GPIO_196] = P7CTL_INIT_FUNC(GPIO_196, 196, 1),
+ [P7_CAM_3_DATA06] = P7CTL_INIT_FUNC(CAM_3_DATA06, 196, 2),
+ [P7_CPU_TRACEDATA_13] = P7CTL_INIT_FUNC(CPU_TRACEDATA_13, 196, 3),
+ [P7_LCD_1_DATA14] = P7CTL_INIT_FUNC(LCD_1_DATA14, 197, 0),
+ [P7_GPIO_197] = P7CTL_INIT_FUNC(GPIO_197, 197, 1),
+ [P7_CAM_3_DATA07] = P7CTL_INIT_FUNC(CAM_3_DATA07, 197, 2),
+ [P7_CPU_TRACEDATA_14] = P7CTL_INIT_FUNC(CPU_TRACEDATA_14, 197, 3),
+ [P7_LCD_1_DATA15] = P7CTL_INIT_FUNC(LCD_1_DATA15, 198, 0),
+ [P7_GPIO_198] = P7CTL_INIT_FUNC(GPIO_198, 198, 1),
+ [P7_CAM_4_CLK] = P7CTL_INIT_FUNC(CAM_4_CLK, 198, 2),
+ [P7_CPU_TRACEDATA_15] = P7CTL_INIT_FUNC(CPU_TRACEDATA_15, 198, 3),
+ [P7_LCD_1_DATA16] = P7CTL_INIT_FUNC(LCD_1_DATA16, 199, 0),
+ [P7_GPIO_199] = P7CTL_INIT_FUNC(GPIO_199, 199, 1),
+ [P7_CAM_4_DATA00] = P7CTL_INIT_FUNC(CAM_4_DATA00, 199, 2),
+ [P7_LCD_1_DATA17] = P7CTL_INIT_FUNC(LCD_1_DATA17, 200, 0),
+ [P7_GPIO_200] = P7CTL_INIT_FUNC(GPIO_200, 200, 1),
+ [P7_CAM_4_DATA01] = P7CTL_INIT_FUNC(CAM_4_DATA01, 200, 2),
+ [P7_LCD_1_DATA18] = P7CTL_INIT_FUNC(LCD_1_DATA18, 201, 0),
+ [P7_GPIO_201] = P7CTL_INIT_FUNC(GPIO_201, 201, 1),
+ [P7_CAM_4_DATA02] = P7CTL_INIT_FUNC(CAM_4_DATA02, 201, 2),
+ [P7_LCD_1_DATA19] = P7CTL_INIT_FUNC(LCD_1_DATA19, 202, 0),
+ [P7_GPIO_202] = P7CTL_INIT_FUNC(GPIO_202, 202, 1),
+ [P7_CAM_4_DATA03] = P7CTL_INIT_FUNC(CAM_4_DATA03, 202, 2),
+ [P7_LCD_1_DATA20] = P7CTL_INIT_FUNC(LCD_1_DATA20, 203, 0),
+ [P7_GPIO_203] = P7CTL_INIT_FUNC(GPIO_203, 203, 1),
+ [P7_CAM_4_DATA04] = P7CTL_INIT_FUNC(CAM_4_DATA04, 203, 2),
+ [P7_LCD_1_DATA21] = P7CTL_INIT_FUNC(LCD_1_DATA21, 204, 0),
+ [P7_GPIO_204] = P7CTL_INIT_FUNC(GPIO_204, 204, 1),
+ [P7_CAM_4_DATA05] = P7CTL_INIT_FUNC(CAM_4_DATA05, 204, 2),
+ [P7_LCD_1_DATA22] = P7CTL_INIT_FUNC(LCD_1_DATA22, 205, 0),
+ [P7_GPIO_205] = P7CTL_INIT_FUNC(GPIO_205, 205, 1),
+ [P7_CAM_4_DATA06] = P7CTL_INIT_FUNC(CAM_4_DATA06, 205, 2),
+ [P7_LCD_1_DATA23] = P7CTL_INIT_FUNC(LCD_1_DATA23, 206, 0),
+ [P7_GPIO_206] = P7CTL_INIT_FUNC(GPIO_206, 206, 1),
+ [P7_CAM_4_DATA07] = P7CTL_INIT_FUNC(CAM_4_DATA07, 206, 2),
+ [P7_LCD_1_DEN] = P7CTL_INIT_FUNC(LCD_1_DEN, 207, 0),
+ [P7_GPIO_207] = P7CTL_INIT_FUNC(GPIO_207, 207, 1),
+ [P7_CAM_1_HSa] = P7CTL_INIT_FUNC(CAM_1_HSa, 207, 2),
+ [P7_LCD_1_CLKa] = P7CTL_INIT_FUNC(LCD_1_CLKa, 207, 3),
+ [P7_CAM_0_CLK] = P7CTL_INIT_FUNC(CAM_0_CLK, 208, 0),
+ [P7_GPIO_208] = P7CTL_INIT_FUNC(GPIO_208, 208, 1),
+ [P7_CAM_1_CLKa] = P7CTL_INIT_FUNC(CAM_1_CLKa, 208, 2),
+ [P7_CAM_0_DATA00] = P7CTL_INIT_FUNC(CAM_0_DATA00, 209, 0),
+ [P7_GPIO_209] = P7CTL_INIT_FUNC(GPIO_209, 209, 1),
+ [P7_CAM_1_DATA08] = P7CTL_INIT_FUNC(CAM_1_DATA08, 209, 2),
+ [P7_CAM_0_DATA01] = P7CTL_INIT_FUNC(CAM_0_DATA01, 210, 0),
+ [P7_GPIO_210] = P7CTL_INIT_FUNC(GPIO_210, 210, 1),
+ [P7_CAM_1_DATA09] = P7CTL_INIT_FUNC(CAM_1_DATA09, 210, 2),
+ [P7_CAM_0_DATA02] = P7CTL_INIT_FUNC(CAM_0_DATA02, 211, 0),
+ [P7_GPIO_211] = P7CTL_INIT_FUNC(GPIO_211, 211, 1),
+ [P7_CAM_1_DATA10] = P7CTL_INIT_FUNC(CAM_1_DATA10, 211, 2),
+ [P7_CAM_4_DATA08] = P7CTL_INIT_FUNC(CAM_4_DATA08, 211, 3),
+ [P7_CAM_0_DATA03] = P7CTL_INIT_FUNC(CAM_0_DATA03, 212, 0),
+ [P7_GPIO_212] = P7CTL_INIT_FUNC(GPIO_212, 212, 1),
+ [P7_CAM_1_DATA11] = P7CTL_INIT_FUNC(CAM_1_DATA11, 212, 2),
+ [P7_CAM_4_DATA09] = P7CTL_INIT_FUNC(CAM_4_DATA09, 212, 3),
+ [P7_CAM_0_DATA04] = P7CTL_INIT_FUNC(CAM_0_DATA04, 213, 0),
+ [P7_GPIO_213] = P7CTL_INIT_FUNC(GPIO_213, 213, 1),
+ [P7_CAM_1_DATA12] = P7CTL_INIT_FUNC(CAM_1_DATA12, 213, 2),
+ [P7_CAM_5_DATA08] = P7CTL_INIT_FUNC(CAM_5_DATA08, 213, 3),
+ [P7_CAM_0_DATA05] = P7CTL_INIT_FUNC(CAM_0_DATA05, 214, 0),
+ [P7_GPIO_214] = P7CTL_INIT_FUNC(GPIO_214, 214, 1),
+ [P7_CAM_1_DATA13] = P7CTL_INIT_FUNC(CAM_1_DATA13, 214, 2),
+ [P7_CAM_5_DATA09] = P7CTL_INIT_FUNC(CAM_5_DATA09, 214, 3),
+ [P7_CAM_0_DATA06] = P7CTL_INIT_FUNC(CAM_0_DATA06, 215, 0),
+ [P7_GPIO_215] = P7CTL_INIT_FUNC(GPIO_215, 215, 1),
+ [P7_CAM_1_DATA14] = P7CTL_INIT_FUNC(CAM_1_DATA14, 215, 2),
+ [P7_CAM_2_DATA08] = P7CTL_INIT_FUNC(CAM_2_DATA08, 215, 3),
+ [P7_CAM_0_DATA07] = P7CTL_INIT_FUNC(CAM_0_DATA07, 216, 0),
+ [P7_GPIO_216] = P7CTL_INIT_FUNC(GPIO_216, 216, 1),
+ [P7_CAM_1_DATA15] = P7CTL_INIT_FUNC(CAM_1_DATA15, 216, 2),
+ [P7_CAM_2_DATA09] = P7CTL_INIT_FUNC(CAM_2_DATA09, 216, 3),
+ [P7_CAM_1_CLK] = P7CTL_INIT_FUNC(CAM_1_CLK, 217, 0),
+ [P7_GPIO_217] = P7CTL_INIT_FUNC(GPIO_217, 217, 1),
+ [P7_SPI_00b] = P7CTL_INIT_FUNC(SPI_00b, 217, 2),
+ [P7_CAM_1_DATA00] = P7CTL_INIT_FUNC(CAM_1_DATA00, 218, 0),
+ [P7_GPIO_218] = P7CTL_INIT_FUNC(GPIO_218, 218, 1),
+ [P7_SPI_01b] = P7CTL_INIT_FUNC(SPI_01b, 218, 2),
+ [P7_CAM_0_VSa] = P7CTL_INIT_FUNC(CAM_0_VSa, 218, 3),
+ [P7_CAM_1_DATA01] = P7CTL_INIT_FUNC(CAM_1_DATA01, 219, 0),
+ [P7_GPIO_219] = P7CTL_INIT_FUNC(GPIO_219, 219, 1),
+ [P7_SPI_02b] = P7CTL_INIT_FUNC(SPI_02b, 219, 2),
+ [P7_CAM_0_HSa] = P7CTL_INIT_FUNC(CAM_0_HSa, 219, 3)
+};
+
+static unsigned long p7_gpio_pins_r3[] = {
+ 0x00007fff,
+ 0xff8607c2,
+ 0x5fffff9f,
+ 0xffdffc00,
+ 0xffffffff,
+ 0xffffffff,
+ 0x0fffffff
+};
+
+const struct p7_pinctrl_config p7_pinctrl_config_r3 = {
+ .pin_descs = p7_pin_descs_r3,
+ .pin_descs_sz = ARRAY_SIZE(p7_pin_descs_r3),
+ .pin_funcs = p7_pin_funcs_r3,
+ .gpio_pins = p7_gpio_pins_r3,
+ .gpio_pins_sz = ARRAY_SIZE(p7_gpio_pins_r3),
+};
diff --git a/arch/arm/mach-parrot7/pm.c b/arch/arm/mach-parrot7/pm.c
new file mode 100644
index 0000000..dd53d2a
--- /dev/null
+++ b/arch/arm/mach-parrot7/pm.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2013 Parrot S.A.
+ * Author: Alvaro Moran <alvaro.moran@parrot.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/system_misc.h>
+#include <mfd/p7mu.h>
+#include <linux/delay.h>
+#include <asm/smp_scu.h>
+#include <linux/mman.h>
+#include <mach/p7.h>
+#include "common.h"
+#include "system.h"
+#include "clock.h"
+#include "dma.h"
+#include "core.h"
+
+#include <mfd/p7mu.h>
+#include <asm/setup.h>
+#include <asm/smp_twd.h>
+
+/*
+ * TODO: Consider that the beginning of INTRAM might be used by the DMA, so we
+ * just want to be sure nobody else is using it.
+ */
+
+int p7_resume_cnt;
+static u32 suspend_vaddr;
+extern void p7_finish_suspend(void);
+extern int p7_finish_suspend_sz;
+struct {
+ int p7_ram_size;
+} p7_s2r_param;
+
+static int __maybe_unused p7_last_jump(unsigned long arg)
+{
+ /* assume only one memory bank : we have one CS */
+ struct membank *bank = &meminfo.bank[0];
+ p7_s2r_param.p7_ram_size = bank->size;
+
+ outer_flush_all();
+
+ soft_restart(P7_INTRAM);
+
+ /* Should never get here. */
+ BUG();
+}
+
+/*
+ * Will copy the last suspend instructions to intram.
+ */
+static int p7_prepare_suspend(void)
+{
+
+ if (p7_finish_suspend_sz > 8 * 1024) {
+ printk("Error sleep code is too big %d\n", p7_finish_suspend_sz);
+ return -1;
+ }
+ /*
+ * map physical addresses of INTRAM controller to copy the sleep code
+ * and jump there later.
+ */
+ suspend_vaddr = (u32)__arm_ioremap_exec(P7_INTRAM,
+ p7_finish_suspend_sz, false);
+ if (!suspend_vaddr) {
+ printk("Error trying to map 0x%lx\n", P7_INTRAM);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void p7_unprepare_suspend(void)
+{
+ __iounmap((void*)suspend_vaddr);
+}
+
+static int p7_enter_pm(suspend_state_t state)
+{
+ int err;
+ u32 scu_ctrl __maybe_unused;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ cpu_do_idle();
+ return 0;
+
+#ifdef CONFIG_PM_SLEEP
+ case PM_SUSPEND_MEM:
+#ifdef CONFIG_ARCH_PARROT7_DEBUG_S2RAM
+ /* debug use rom code and we use p7r3 symbols */
+ if (p7_chiprev() != P7_CHIPREV_R3) {
+ return -EINVAL;
+ }
+ /* keep 1K for stack */
+ if (p7_is_nonsecure()) {
+ return -EINVAL;
+ }
+#endif
+
+ /* warning intram is also used by PL330 ucode */
+ memcpy_toio((void*)suspend_vaddr,
+ p7_finish_suspend, p7_finish_suspend_sz);
+ err = cpu_suspend(0, p7_last_jump);
+
+ if (err == 0) {
+ p7_resume_cnt++;
+ }
+ printk("Starting resume #%d... (%d)\n", p7_resume_cnt, err);
+
+ /* stop watchdog set by bootloader on cpu0 */
+ writel(0x12345678, __MMIO_P2V(P7_CPU_LOCALTIMER) + TWD_WDOG_DISABLE);
+ writel(0x87654321, __MMIO_P2V(P7_CPU_LOCALTIMER) + TWD_WDOG_DISABLE);
+ writel(0x0, __MMIO_P2V(P7_CPU_LOCALTIMER) + TWD_WDOG_CONTROL);
+
+ /* De-reset NEON unit. */
+ p7_enable_neonclk(0);
+#ifdef CONFIG_SMP
+ platform_smp_prepare_cpus(num_possible_cpus());
+#endif
+#ifdef CONFIG_CACHE_L2X0
+ outer_resume();
+#endif
+#ifdef CONFIG_DMA_PARROT7
+ /*
+ * PL330 knows that a channel is free when the first
+ * instruction in channel's microcode is DMAEND (0x0).
+ * To simplify, make all memory used for DMA ucode to 0.
+ */
+ memset((void*)__MMIO_P2V(p7_dma_ucode_addr()),
+ 0, p7_dma_ucode_sz());
+#endif
+ break;
+#endif
+ default:
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int p7_begin_pm(suspend_state_t state)
+{
+ u16 reg;
+ int ret;
+
+ disable_hlt();
+
+ p7mu_read16(0xe18, ®); /* OTP reset value */
+ reg = (reg >> 8) ^ 'P'; /* xor with 'P' */
+ p7mu_write16(0xe83, reg);
+
+ ret = p7mu_save_cpu_jump(cpu_resume);
+ if (ret)
+ return ret;
+ return p7_prepare_suspend();
+}
+
+static void p7_end_pm(void)
+{
+ p7_unprepare_suspend();
+ enable_hlt();
+ return;
+}
+
+static struct platform_suspend_ops p7_pm_ops = {
+ .begin = p7_begin_pm,
+ .end = p7_end_pm,
+ .enter = p7_enter_pm,
+ .valid = suspend_valid_only_mem,
+};
+
+void __init p7_pm_init(void)
+{
+ suspend_set_ops(&p7_pm_ops);
+}
+
diff --git a/arch/arm/mach-parrot7/readme.txt b/arch/arm/mach-parrot7/readme.txt
new file mode 100644
index 0000000..32ab3a0
--- /dev/null
+++ b/arch/arm/mach-parrot7/readme.txt
@@ -0,0 +1,38 @@
+Using clocks with the Parrot 7 Linux BSP :
+==========================================
+
+From within drivers you should use :
+
+struct clk* clk_get(struct device*, char const*);
+void clk_put(struct clk*);
+int clk_enable(struct clk*);
+void clk_disable(struct clk*);
+unsigned long clk_get_rate(struct clk*);
+
+Usage sample code:
+------------------
+
+static struct clk* myclk;
+
+int myfunc(void)
+{
+ printk("%lu Hertz\n", clk_get_rate(myclk));
+}
+
+int init(struct platform_device* mydev)
+{
+ /* Get a reference to my clock. */
+ myclk = clk_get(&mydev->dev, "core");
+
+ /* activate clock. */
+ clk_enable(myclk);
+}
+
+void fini(void)
+{
+ /* Turn clock off. */
+ clk_disable(myclk);
+
+ /* Do not forget this! Release clock reference. */
+ clk_put(myclk);
+}
diff --git a/arch/arm/mach-parrot7/sdhci.c b/arch/arm/mach-parrot7/sdhci.c
new file mode 100644
index 0000000..45005e8
--- /dev/null
+++ b/arch/arm/mach-parrot7/sdhci.c
@@ -0,0 +1,145 @@
+/**
+ * linux/arch/arm/mach-parrot7/sdhci.c - Parrot7 eMMC / SD / SDIO controller
+ * platform implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 14-Jun-2012
+ *
+ * This file is released under the GPL
+ *
+ * See linux/drivers/parrot/mmc/acs3-sdhci.c file header
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <mach/irqs.h>
+#include <mach/p7.h>
+#include <mmc/acs3-sdhci.h>
+#include "common.h"
+#include "clock.h"
+
+/*****************************
+ * Host controller instances
+ *****************************/
+
+static struct resource p7_sdhci0_res[] = {
+ [0] = {
+ .start = P7_SDIO0,
+ .end = P7_SDIO0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_SDIO0_IRQ,
+ .end = P7_SDIO0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_sdhci1_res[] = {
+ [0] = {
+ .start = P7_SDIO1,
+ .end = P7_SDIO1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_SDIO1_IRQ,
+ .end = P7_SDIO1_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_sdhci2_res[] = {
+ [0] = {
+ .start = P7_SDIO2,
+ .end = P7_SDIO2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_SDIO2_IRQ,
+ .end = P7_SDIO2_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device p7_sdhci_devs[] = {
+ {
+ .name = ACS3_DRV_NAME,
+ .id = 0,
+ .resource = p7_sdhci0_res,
+ .num_resources = ARRAY_SIZE(p7_sdhci0_res)
+ },
+ {
+ .name = ACS3_DRV_NAME,
+ .id = 1,
+ .resource = p7_sdhci1_res,
+ .num_resources = ARRAY_SIZE(p7_sdhci1_res)
+ },
+ {
+ .name = ACS3_DRV_NAME,
+ .id = 2,
+ .resource = p7_sdhci2_res,
+ .num_resources = ARRAY_SIZE(p7_sdhci2_res)
+ }
+};
+
+static struct acs3_regs const p7_sdhci_regs[] = {
+ { /* SDIO controller 0. */
+ .tdl1 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO0_TDL1_CFG),
+ .tdl2 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO0_TDL2_CFG),
+ .ctrl = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO0_CTRL),
+ .retune = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO0_RETUNE)
+ },
+ { /* SDIO controller 1. */
+ .tdl1 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO1_TDL1_CFG),
+ .tdl2 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO1_TDL2_CFG),
+ .ctrl = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO1_CTRL),
+ .retune = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO1_RETUNE)
+ },
+ { /* SDIO controller 2. */
+ .tdl1 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO2_TDL1_CFG),
+ .tdl2 = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO2_TDL2_CFG),
+ .ctrl = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO2_CTRL),
+ .retune = __MMIO_P2V(P7_HSP_GBC + HSP_GBC_SDIO2_RETUNE)
+ }
+};
+
+/**
+ * p7_init_sdhci() - Instantiate SDHCI host controller identified by @host
+ * for further driver usage.
+ *
+ * @host: SDHCI host controller identifier
+ * @pdata: controller platform specific data
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_sdhci(int host,
+ struct acs3_plat_data* pdata,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+#ifdef DEBUG
+ BUG_ON(host < 0);
+ BUG_ON(host >= ARRAY_SIZE(p7_sdhci_devs));
+ BUG_ON(! pdata);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+
+ /*
+ * Set GBC registers addresses so that driver can easily locate them in a
+ * portable way.
+ */
+ pdata->regs = &p7_sdhci_regs[host];
+
+ /*
+ * Disable the command confict error, i.e. disable multi-master mode.
+ * This allows us to keep working at high frequencies.
+ */
+ __raw_writel(__raw_readl(pdata->regs->ctrl) | ACS3_CTRL_CMD_CONFLICT_DIS_MASK,
+ pdata->regs->ctrl);
+
+ p7_init_dev(&p7_sdhci_devs[host], pdata, pins, pin_cnt);
+}
diff --git a/arch/arm/mach-parrot7/sdhci.h b/arch/arm/mach-parrot7/sdhci.h
new file mode 100644
index 0000000..b6e7c44
--- /dev/null
+++ b/arch/arm/mach-parrot7/sdhci.h
@@ -0,0 +1,39 @@
+/**
+ * linux/arch/arm/mach-parrot7/sdhci.h - Parrot7 eMMC / SD / SDIO controller
+ * platform interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 14-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_SDHCI_H
+#define _ARCH_PARROT7_SDHCI_H
+
+struct acs3_plat_data;
+struct pinctrl_map;
+
+#include <linux/init.h>
+#include <mmc/acs3-sdhci.h>
+
+
+#if defined(CONFIG_MMC_SDHCI_ACS3) || \
+ defined(CONFIG_MMC_SDHCI_ACS3_MODULE)
+
+extern void p7_init_sdhci(int,
+ struct acs3_plat_data*,
+ struct pinctrl_map*,
+ size_t) __init;
+
+#else /* defined(CONFIG_MMC_PARROT7) || \
+ defined(CONFIG_MMC_PARROT7_MODULE) */
+
+#define p7_init_sdhci(_host, _pdata, _pins, _pins_nr)
+
+#endif /* defined(CONFIG_MMC_SDHCI_ACS3) || \
+ defined(CONFIG_MMC_SDHCI_ACS3_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/sii_platform_data.h b/arch/arm/mach-parrot7/sii_platform_data.h
new file mode 100644
index 0000000..ebc3152
--- /dev/null
+++ b/arch/arm/mach-parrot7/sii_platform_data.h
@@ -0,0 +1,37 @@
+/*
+ * Platform data for the sii5293
+ *
+ * Copyright (C) 2014 Parrot S.A.
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ */
+
+
+#ifndef __SII_PLATFORM_DATA_H__
+#define __SII_PLATFORM_DATA_H__
+
+#define SII5293_PDATA_STRUCT_VERSION 1
+
+struct sii5293_platform_data {
+ /* keep version field in first position */
+ int version;
+
+ int gpio_rst;
+ int gpio_irq;
+ int i2c_bus;
+
+ int output_format;
+
+ int input_dev_rap;
+ int input_dev_rcp;
+ int input_dev_ucp;
+};
+
+#endif
diff --git a/arch/arm/mach-parrot7/sleep.S b/arch/arm/mach-parrot7/sleep.S
new file mode 100644
index 0000000..a280617
--- /dev/null
+++ b/arch/arm/mach-parrot7/sleep.S
@@ -0,0 +1,183 @@
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/p7.h>
+#include "gbc.h"
+
+#ifdef CONFIG_ARCH_PARROT7_DEBUG_S2RAM
+#define P7_DDR_CRC_ALL 1
+#else
+#define P7_DDR_CRC_ALL 0
+#endif
+
+#define I2CM_TIP (1 << 1)
+#define I2CM_COMMAND_WR (1 << 1)
+#define I2CM_COMMAND_STOP (1 << 3)
+#define I2CM_COMMAND_START (1 << 4)
+#define I2CM_TX_REG (0x00)
+#define I2CM_STATUS_REG (0x10)
+#define I2CM_COMMAND_REG (0x14)
+#define I2CM_PRESCALE (0x18)
+
+#define P7MU_ADDR (0x31)
+#define P7MU_COMMAND_REG (0x107)
+#define P7MU_SUSPEND_CMD (1 << 1)
+#define P7MU_APP0 (0x900)
+#define P7MU_APP1 (0x901)
+#define P7MU_APP3 (0x903)
+#define P7MU_APP4 (0x904)
+#define P7MU_APP5 (0x905)
+#define P7MU_APP6 (0x906)
+
+.macro p7mu_write, reg16
+ @ input r0 (data)
+ @ local use r0: cmd byte, r1: byte to transmit, r2
+ mov r2, r0
+ mov r0, #I2CM_COMMAND_START
+ mov r1, #(P7MU_ADDR << 1)
+ bl send_byte
+ mov r0, #0
+ mov r1, #((\reg16 >> 8))
+ bl send_byte
+ mov r1, #(\reg16 & 0xff)
+ bl send_byte
+ mov r1, r2, lsr #8
+ bl send_byte
+ mov r0, #I2CM_COMMAND_STOP
+ and r1, r2, #255
+ bl send_byte
+.endm
+
+ .text
+
+ENTRY(p7_finish_suspend)
+ @set vector at 0. It helps debug in case of abort
+ mrc p15, 0, r0, c1, c0, 0 @ read control register
+ bic r0, r0, #(1 << 13)
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+
+#if P7_DDR_CRC_ALL
+ ldr r0, p7_s2r_param_ptr
+ ldr r10, [r0]
+ adr r0, rom_bases
+ ldmia r0, {r4 - r9}
+ @we store the mmu table after the stack. We need 32K align
+ mov sp, #(P7_INTRAM+32*1024)
+ stmdb sp!, {r0,r1,r2,r4,r5,r7,r9,r11}
+ blx r4 @cache invalidate
+ ldmia sp!, {r0,r1,r2,r4,r5,r7,r9,r11}
+ blx r5 @mmu_off
+ mov r0, sp
+ mov r1, r10, lsr #20
+ blx r6 @mmu_on
+ blx r7 @dcache
+ blx r8 @icache
+
+
+ @crc of all ddr
+ mov r0, #(0x80000000)
+ mov r1, r10
+ blx r9 @posix_crc
+ mov r10, r0
+#else
+ mov r10, #0
+#endif
+
+#if 0
+ @crc of resume code
+ ldr r0, p7_s2r_param_ptr
+ ldr r0, [r0, #4]
+ mov r1, #4096
+ blx r9 @posix_crc
+ mov r9, r0
+#else
+ mov r9, #0
+#endif
+
+ @ r4: mpmc self refresh register
+ @ r5: mpmc gate training register
+ @ r6: i2cm base address
+ @ r7: i2cm clock register
+ @ r8: watchdog base address
+ adr r0, reg_bases
+ ldmia r0, {r4 - r8}
+
+ @ enable watchdog
+ mov r0, #0xff000 @load register. the timeout is ((load + 1) * (prescaler + 1)) / (cpu_clk/2)
+ @for 780Mhz cpu it should give us 680ms.
+ str r0, [r8, #0x20]
+ movw r0, #0x0000FF09 @ctrl reg : prescaler = 0xff, WD mode, enable
+ str r0, [r8, #0x28]
+
+ @ disable gate training
+ mov r0, #0
+ str r0, [r5]
+
+ @ enable self-refresh
+ mov r0, #1
+ str r0, [r4]
+ @ MPMC is now in self-refresh
+
+ @ enable i2c clock and dereset IP
+ mov r0, #1
+ str r0, [r7]
+ mov r0, #0
+ str r0, [r7, #(LSP_GBC_I2CM0_RESET - LSP_GBC_I2CM0_CLOCK)]
+
+ @ init i2c IP
+ mov r0, #0
+ str r0, [r6, #I2CM_PRESCALE]
+
+ mov r0, #0xd8 @100KHZ
+ str r0, [r6, #I2CM_PRESCALE]
+
+ @crc of ddr
+ mov r0, r10, lsr #16
+ p7mu_write P7MU_APP3
+ mov r0, r10
+ p7mu_write P7MU_APP4
+
+ @ Send the suspend command to the P7MU via I2C
+ mov r0, #P7MU_SUSPEND_CMD
+ p7mu_write P7MU_COMMAND_REG
+
+ @ Wait here for P7MU to shutdown the power domain that
+ @ powers the CPU
+ b .
+
+ @ very simple send byte function for I2CM
+ @ write command and byte to xfer, wait for xfer to be done, return
+ @ there is no error handling
+ @ r6: i2cm base address
+ @ r0: cmd
+ @ r1: byte to write
+ @ ip: tmp
+send_byte:
+ orr r0, r0, #I2CM_COMMAND_WR
+ str r1, [r6, #I2CM_TX_REG]
+ str r0, [r6, #I2CM_COMMAND_REG]
+1: ldr ip, [r6, #I2CM_STATUS_REG]
+ ands ip, ip, #I2CM_TIP
+ bne 1b
+ bx lr
+
+reg_bases:
+ .long P7_MPMC_GBC + MPMC_GBC_SELF_REFRESH
+ .long P7_MPMC + P7_MPMC_TRAIN_EN
+ .long P7_I2CM0
+ .long P7_LSP_GBC + LSP_GBC_I2CM0_CLOCK
+ .long P7_CPU_LOCALTIMER
+
+rom_bases:
+ .long 0x00000244 @invalidate_caches_and_tlbs
+ .long 0x000144ac @mmu_off
+ .long 0x0001430c @mmu_on
+ .long 0x000016a0 @dcache_on
+ .long 0x00001670 @icache_on
+ .long 0x00001250 @posix_crc
+
+p7_s2r_param_ptr:
+ .word p7_s2r_param
+
+ENTRY(p7_finish_suspend_sz)
+ .word . - p7_finish_suspend
diff --git a/arch/arm/mach-parrot7/spi.c b/arch/arm/mach-parrot7/spi.c
new file mode 100644
index 0000000..3e39b34
--- /dev/null
+++ b/arch/arm/mach-parrot7/spi.c
@@ -0,0 +1,399 @@
+/**
+ * linux/arch/arm/mach-parrot7/spi.c - Parrot7 SPI controller platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 27-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clkdev.h>
+#include <linux/spi/spi.h>
+#include <spi/p7-spi.h>
+#include <mach/p7.h>
+#include <mach/irqs.h>
+#include "pinctrl.h"
+#include "dma.h"
+#include "common.h"
+#include "clock.h"
+
+/* SPI Kernel resource */
+static struct resource p7_spi_res = {
+ .start = P7_SPI,
+ .end = P7_SPI + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct p7spi_plat_data p7_spi_pdata = {
+ .max_slave_hz = 10000000,
+ .wcnt = 128,
+};
+
+/* SPI Kernel device */
+static struct platform_device p7_spi_dev = {
+ .name = P7SPI_DRV_NAME,
+ .id = 0,
+ .dev.platform_data = &p7_spi_pdata,
+ .resource = &p7_spi_res,
+ .num_resources = 1,
+};
+
+static enum p7spi_core_type p7spi_core_r1[] = {
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+};
+
+static enum p7spi_core_type p7spi_core_r23[] = {
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_SPI,
+ P7SPI_CORE_MPEG,
+ P7SPI_CORE_MPEG,
+};
+
+static bool already_init = false;
+
+/**
+ * p7_init_spi() - Instantiate SPI shared resources "controller"
+ * for further driver usage.
+ *
+ * @pdata: controller platform specific data
+ */
+void __init p7_init_spi(void)
+{
+ int err = p7_chiprev();
+
+ if (already_init)
+ return;
+
+ switch (err) {
+ case P7_CHIPREV_R1:
+ p7_spi_pdata.rev = SPI_REVISION_1;
+ break;
+ case P7_CHIPREV_R2:
+ p7_spi_pdata.rev = SPI_REVISION_2;
+ break;
+ case P7_CHIPREV_R3:
+ p7_spi_pdata.rev = SPI_REVISION_3;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ if (p7_spi_pdata.rev == SPI_REVISION_1) {
+ /* MPW1 is limited to 127kHz - 65MHz. */
+ p7_spi_pdata.min_hz = 127000;
+ p7_spi_pdata.max_master_hz = 65000000;
+ p7_spi_pdata.num_pads = 16;
+ p7_spi_pdata.cores = p7spi_core_r1;
+ p7_spi_pdata.num_cores = ARRAY_SIZE(p7spi_core_r1);
+ }
+ else {
+ /* R2 and R3 to 2kHz - 130 MHz */
+ p7_spi_pdata.min_hz = 2000;
+ p7_spi_pdata.max_master_hz = 130000000;
+ p7_spi_pdata.num_pads = 20;
+ p7_spi_pdata.cores = p7spi_core_r23;
+ p7_spi_pdata.num_cores = ARRAY_SIZE(p7spi_core_r23);
+ }
+
+ err = p7_init_dev(&p7_spi_dev, NULL, NULL, 0);
+ if (! err) {
+ already_init = true;
+ return;
+ }
+
+ panic("p7: failed to init SPI kernel (%d)\n", err);
+}
+
+#if defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE)
+
+/* Bus 0 resources */
+static struct resource p7_spi0_res[] = {
+ [0] = {
+ .start = P7_SPI0,
+ .end = P7_SPI0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_SPI0_IRQ,
+ .end = P7_SPI0_IRQ,
+#ifdef CONFIG_ARCH_VEXPRESS_P7FPGA
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+#else
+ .flags = IORESOURCE_IRQ,
+#endif
+ },
+ [2] = {
+ .start = P7_SPI0_DMA,
+ .end = P7_SPI0_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+/* Bus 1 resources */
+static struct resource p7_spi1_res[] = {
+ [0] = {
+ .start = P7_SPI1,
+ .end = P7_SPI1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_SPI1_IRQ,
+ .end = P7_SPI1_IRQ,
+#ifdef CONFIG_ARCH_VEXPRESS_P7FPGA
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+#else
+ .flags = IORESOURCE_IRQ,
+#endif
+ },
+ [2] = {
+ .start = P7_SPI1_DMA,
+ .end = P7_SPI1_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+/* Bus 2 resources */
+static struct resource p7_spi2_res[] = {
+ [0] = {
+ .start = P7_SPI2,
+ .end = P7_SPI2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_SPI2_IRQ,
+ .end = P7_SPI2_IRQ,
+#ifdef CONFIG_ARCH_VEXPRESS_P7FPGA
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+#else
+ .flags = IORESOURCE_IRQ,
+#endif
+ },
+ [2] = {
+ .start = P7_SPI2_DMA,
+ .end = P7_SPI2_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+/* Bus 3 resources */
+static struct resource p7_spi3_res[] = {
+ [0] = {
+ .start = P7_SPI3,
+ .end = P7_SPI3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = P7_SPI3_IRQ,
+ .end = P7_SPI3_IRQ,
+#ifdef CONFIG_ARCH_VEXPRESS_P7FPGA
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+#else
+ .flags = IORESOURCE_IRQ,
+#endif
+ },
+ [2] = {
+ .start = P7_SPI3_DMA,
+ .end = P7_SPI3_DMA,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct platform_device p7_spi_devs[] = {
+ {
+ .id = 0,
+ .resource = p7_spi0_res,
+ .num_resources = ARRAY_SIZE(p7_spi0_res),
+ },
+ {
+ .id = 1,
+ .resource = p7_spi1_res,
+ .num_resources = ARRAY_SIZE(p7_spi1_res),
+ },
+ {
+ .id = 2,
+ .resource = p7_spi2_res,
+ .num_resources = ARRAY_SIZE(p7_spi2_res),
+ },
+ {
+ .id = 3,
+ .resource = p7_spi3_res,
+ .num_resources = ARRAY_SIZE(p7_spi3_res),
+ }
+};
+
+#endif /* defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE) */
+
+#if defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE)
+#include <spi/p7-spim.h>
+
+/**
+ * p7_init_spim() - Instantiate SPI master controller identified by @bus
+ * for further driver usage.
+ *
+ * @bus: master controller / bus identifier
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_spim(int bus, struct pinctrl_map* pins, size_t pin_cnt,
+ struct p7spi_swb const * const pdata)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(bus >= ARRAY_SIZE(p7_spi_devs));
+ BUG_ON(p7_spi_devs[bus].name);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+ BUG_ON(! pdata);
+#endif
+ p7_init_spi();
+
+ p7_spi_devs[bus].name = P7SPIM_DRV_NAME;
+ err = p7_init_dev(&p7_spi_devs[bus], (void*)pdata, pins, pin_cnt);
+ if (! err)
+ return;
+
+ panic("p7: failed to init SPI master controller %d (%d)\n",
+ bus,
+ err);
+}
+
+/**
+ * p7_init_spim_slave() - Register SPI slave device to master controller
+ * further driver usage.
+ *
+ * @bus: master controller / bus identifier
+ * @info: slave device descriptor
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ */
+int __init p7_init_spim_slave(int bus, struct spi_board_info* info)
+{
+ int err;
+
+#ifdef DEBUG
+ struct p7spi_ctrl_data* const cdata = info->controller_data;
+ BUG_ON(bus >= ARRAY_SIZE(p7_spi_devs));
+ BUG_ON(! info);
+ BUG_ON(! info->modalias);
+ BUG_ON(! cdata);
+ BUG_ON(info->chip_select);
+ BUG_ON(p7_spi_devs[bus].name && strcmp(p7_spi_devs[bus].name, P7SPIM_DRV_NAME));
+
+ pr_debug("p7: registering %s%sspi%u.0...\n",
+ info->modalias ? info->modalias : "",
+ info->modalias ? " slave as " : "",
+ bus);
+#endif
+
+ info->bus_num = bus;
+ err = spi_register_board_info(info, 1);
+ WARN(err,
+ "p7: failed to register %s%sspi%u.0 (%d)\n",
+ info->modalias ? info->modalias : "",
+ info->modalias ? " slave as " : "",
+ bus,
+ err);
+
+ return err;
+}
+
+#endif /* defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE) */
+
+#if defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE)
+#include <spi/p7-spis.h>
+
+/**
+ * p7_init_spis() - Instantiate SPI slave controller identified by @bus
+ * for further driver usage.
+ *
+ * @bus: slave controller / bus identifier
+ * @pins: array of pin functions and optional settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_spis(int bus, struct pinctrl_map* pins, size_t pin_cnt,
+ struct p7spi_swb const * const pdata)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(bus >= ARRAY_SIZE(p7_spi_devs));
+ BUG_ON(p7_spi_devs[bus].name);
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+ BUG_ON(! pdata);
+#endif
+ p7_init_spi();
+
+ p7_spi_devs[bus].name = P7SPIS_DRV_NAME;
+ err = p7_init_dev(&p7_spi_devs[bus], (void*)pdata, pins, pin_cnt);
+ if (! err)
+ return;
+
+ panic("p7: failed to init SPI slave controller %d (%d)\n",
+ bus,
+ err);
+}
+
+/**
+ * p7_init_spis_master() - Register SPI master device to slave controller
+ * for further driver usage.
+ *
+ * @bus: slave controller / bus identifier
+ * @info: master device descriptor
+ *
+ * Returns: 0 - success, a negative errno like value if failure
+ */
+int __init p7_init_spis_master(int bus, struct spi_board_info* info)
+{
+ int err;
+
+#ifdef DEBUG
+ struct p7spi_ctrl_data* const cdata = info->controller_data;
+ BUG_ON(bus >= ARRAY_SIZE(p7_spi_devs));
+ BUG_ON(! info);
+ BUG_ON(! info->modalias);
+ BUG_ON(! cdata);
+ BUG_ON(info->chip_select);
+ BUG_ON(strcmp(p7_spi_devs[bus].name, P7SPIS_DRV_NAME));
+
+ pr_debug("p7: registering %s%sspi%u.0...\n",
+ info->modalias ? info->modalias : "",
+ info->modalias ? " master as " : "",
+ bus);
+#endif
+
+ info->bus_num = bus;
+ err = spi_register_board_info(info, 1);
+ WARN(err,
+ "p7: failed to register %s%sspi%u.0 (%d)\n",
+ info->modalias ? info->modalias : "",
+ info->modalias ? " slave as " : "",
+ bus,
+ err);
+
+ return err;
+}
+
+#endif /* defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE) */
diff --git a/arch/arm/mach-parrot7/spi.h b/arch/arm/mach-parrot7/spi.h
new file mode 100644
index 0000000..3e1dba5
--- /dev/null
+++ b/arch/arm/mach-parrot7/spi.h
@@ -0,0 +1,187 @@
+/**
+ * linux/arch/arm/mach-parrot7/spi.h - Parrot7 SPI controller platform
+ * interface
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 28-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#ifndef _ARCH_PARROT7_SPI_H
+#define _ARCH_PARROT7_SPI_H
+
+struct p7spi_plat_data;
+struct p7spi_swb;
+struct spi_board_info;
+struct pinctrl_map;
+
+#if defined(CONFIG_SPI_PARROT7) || \
+ defined(CONFIG_SPI_PARROT7_MODULE)
+
+#include <linux/init.h>
+
+extern void p7_init_spi(void) __init;
+
+#else /* defined(CONFIG_SPI_PARROT7) || \
+ defined(CONFIG_SPI_PARROT7_MODULE) */
+
+#define p7_init_spi()
+
+#endif /* defined(CONFIG_SPI_PARROT7) || \
+ defined(CONFIG_SPI_PARROT7_MODULE) */
+
+#if defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE)
+
+extern void p7_init_spim(int, struct pinctrl_map*, size_t,
+ struct p7spi_swb const * const) __init;
+
+/**
+ * P7_INIT_SPIM_SLAVE() - Init a SPI slave device (connected to master
+ * controller).
+ *
+ * @_mod: name of module drive this slave
+ * @_pdata: platform data assigned to this slave
+ * @_cdata: master controller platform data to use with this slave
+ * @_hz: maximum frequency this slave may work at
+ * @_mode: clock phase / polarity this slave may work with (one of
+ * %SPI_MODE_0, %SPI_MODE_1, %SPI_MODE_2, %SPI_MODE_3, or a
+ * combination of %SPI_CPHA and / or %SPI_CPOL flags)
+ */
+#define P7_INIT_SPIM_SLAVE(_mod, _pdata, _cdata, _hz, _mode)\
+ { \
+ .modalias = _mod, \
+ .platform_data = _pdata, \
+ .controller_data = _cdata, \
+ .irq = -1, \
+ .max_speed_hz = _hz, \
+ .chip_select = 0, \
+ .mode = _mode \
+ }
+
+/**
+ * P7_DECLARE_SPIM_SLAVE() - Declare a SPI slave device (connected to master
+ * controller).
+ *
+ * @_name: slave variable name
+ * @_mod: name of module drive this slave
+ * @_pdata: platform data assigned to this slave
+ * @_cdata: master controller platform data to use with this slave
+ * @_hz: maximum frequency this slave may work at
+ * @_mode: clock phase / polarity this slave may work with (one of
+ * %SPI_MODE_0, %SPI_MODE_1, %SPI_MODE_2, %SPI_MODE_3, or a
+ * combination of %SPI_CPHA and / or %SPI_CPOL flags)
+ */
+#define P7_DECLARE_SPIM_SLAVE(_name, _mod, _pdata, _cdata, _hz, _mode) \
+ struct spi_board_info _name __initdata = P7_INIT_SPIM_SLAVE(_mod, \
+ _pdata, \
+ _cdata, \
+ _hz, \
+ _mode)
+
+extern int p7_init_spim_slave(int, struct spi_board_info*) __init;
+
+#else /* defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE) */
+
+static inline void p7_init_spim(int i,
+ struct pinctrl_map *m,
+ size_t s,
+ struct p7spi_swb const * const p)
+{
+ return;
+}
+
+static inline int p7_init_spim_slave(int i, struct spi_board_info *s)
+{
+ return -ENOSYS;
+}
+
+#define P7_DECLARE_SPIM_SLAVE(_name, _mod, _pdata, _cdata, _hz, _mode) \
+ struct spi_board_info _name __initdata = P7_INIT_SPIM_SLAVE(_mod, \
+ _pdata, \
+ _cdata, \
+ _hz, \
+ _mode)
+/**
+ * P7_INIT_SPIM_SLAVE() - Init a SPI slave device (connected to master
+ * controller).
+ *
+ * @_mod: name of module drive this slave
+ * @_pdata: platform data assigned to this slave
+ * @_cdata: master controller platform data to use with this slave
+ * @_hz: maximum frequency this slave may work at
+ * @_mode: clock phase / polarity this slave may work with (one of
+ * %SPI_MODE_0, %SPI_MODE_1, %SPI_MODE_2, %SPI_MODE_3, or a
+ * combination of %SPI_CPHA and / or %SPI_CPOL flags)
+ */
+#define P7_INIT_SPIM_SLAVE(_mod, _pdata, _cdata, _hz, _mode)\
+ { \
+ .modalias = _mod, \
+ .platform_data = _pdata, \
+ .controller_data = _cdata, \
+ .irq = -1, \
+ .max_speed_hz = _hz, \
+ .chip_select = 0, \
+ .mode = _mode \
+ }
+
+#endif /* defined(CONFIG_SPI_MASTER_PARROT7) || \
+ defined(CONFIG_SPI_MASTER_PARROT7_MODULE) */
+
+#define P7_DECLARE_SPIS_MASTER(_name, _mod, _pdata, _cdata, _hz, _mode) \
+ struct spi_board_info _name __initdata = { \
+ .modalias = _mod, \
+ .platform_data = _pdata, \
+ .controller_data = _cdata, \
+ .irq = -1, \
+ .max_speed_hz = _hz, \
+ .chip_select = 0, \
+ .mode = _mode \
+ }
+
+#if defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE)
+
+extern void p7_init_spis(int, struct pinctrl_map*, size_t,
+ struct p7spi_swb const * const) __init;
+
+/**
+ * P7_DECLARE_SPIS_MASTER() - Declare a SPI master device (connected to slave
+ * controller).
+ *
+ * @_name: master variable name
+ * @_mod: name of module drive this master
+ * @_pdata: platform data assigned to this master
+ * @_cdata: slave controller platform data to use with this master
+ * @_hz: maximum frequency this master may work at
+ * @_mode: clock phase / polarity this master may work with (one of
+ * %SPI_MODE_0, %SPI_MODE_1, %SPI_MODE_2, %SPI_MODE_3, or a
+ * combination of %SPI_CPHA and / or %SPI_CPOL flags)
+ */
+
+extern int p7_init_spis_master(int, struct spi_board_info*) __init;
+
+#else /* defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE) */
+
+static inline void p7_init_spis(int i,
+ struct pinctrl_map *m,
+ size_t s,
+ struct p7spi_swb const * const p)
+{
+ return;
+}
+
+static inline int p7_init_spis_master(int i, struct spi_board_info *s)
+{
+ return -ENOSYS;
+}
+
+#endif /* defined(CONFIG_SPI_SLAVE_PARROT7) || \
+ defined(CONFIG_SPI_SLAVE_PARROT7_MODULE) */
+
+#endif
diff --git a/arch/arm/mach-parrot7/system.h b/arch/arm/mach-parrot7/system.h
new file mode 100644
index 0000000..d1bb7a8
--- /dev/null
+++ b/arch/arm/mach-parrot7/system.h
@@ -0,0 +1,154 @@
+/*
+ * linux/arch/arm/mach-parrot7/system.h
+ *
+ * Copyright (C) 2010 Parrot S.A.
+ *
+ * @author Gregor Boirie <gregor.boirie@parrot.com>
+ * @date 08-Nov-2010
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ARCH_PARROT7_SYSTEM_H
+#define _ARCH_PARROT7_SYSTEM_H
+
+#include <mach/p7.h>
+
+/* Clocks generation. */
+#define P7_SYS_CLKGEN P7_SYS
+#define P7_SYS_CLKGEN_STATUS P7_SYS_CLKGEN
+#define P7_SYS_CLKGEN_CFG_CPU_DIV (P7_SYS_CLKGEN + UL(0x04))
+#define P7_SYS_CLKGEN_CFG_SYS_DIV (P7_SYS_CLKGEN + UL(0x08))
+#define P7_SYS_CLKGEN_CFG_USB_DIV (P7_SYS_CLKGEN + UL(0x0c))
+#define P7_SYS_CLKGEN_CFG_CAN_DIV (P7_SYS_CLKGEN + UL(0x10))
+#define P7_SYS_CLKGEN_CFG_FAST (P7_SYS_CLKGEN + UL(0x14))
+#define P7_SYS_CLKGEN_CFG_DDR (P7_SYS_CLKGEN + UL(0x18))
+#define P7_SYS_CLKGEN_CFG_AVI00 (P7_SYS_CLKGEN + UL(0x1c))
+#define P7_SYS_CLKGEN_CFG_AVI01 (P7_SYS_CLKGEN + UL(0x20))
+#define P7_SYS_CLKGEN_CFG_AVI10 (P7_SYS_CLKGEN + UL(0x24))
+#define P7_SYS_CLKGEN_CFG_AVI11 (P7_SYS_CLKGEN + UL(0x28))
+#define P7_SYS_CLKGEN_CFG_AAI (P7_SYS_CLKGEN + UL(0x2c))
+#define P7_SYS_CLKGEN_CFG_NAND (P7_SYS_CLKGEN + UL(0x30))
+#define P7_SYS_CLKGEN_CFG_USB (P7_SYS_CLKGEN + UL(0x34))
+#define P7_SYS_CLKGEN_CFG_TRACE (P7_SYS_CLKGEN + UL(0x38))
+#define P7_SYS_CLKGEN_CFG_ETHERNET (P7_SYS_CLKGEN + UL(0x3c))
+
+/* Multiplexed I/O setup. */
+#define P7_SYS_PADCTRL_IO (P7_SYS + UL(0x1000))
+#define P7_SYS_PADCTRL_IO_00 (P7_SYS_PADCTRL_IO + UL(4 * 0))
+#define P7_SYS_PADCTRL_IO_01 (P7_SYS_PADCTRL_IO + UL(4 * 1))
+#define P7_SYS_PADCTRL_IO_02 (P7_SYS_PADCTRL_IO + UL(4 * 2))
+#define P7_SYS_PADCTRL_IO_03 (P7_SYS_PADCTRL_IO + UL(4 * 3))
+#define P7_SYS_PADCTRL_IO_04 (P7_SYS_PADCTRL_IO + UL(4 * 4))
+#define P7_SYS_PADCTRL_IO_05 (P7_SYS_PADCTRL_IO + UL(4 * 5))
+#define P7_SYS_PADCTRL_IO_06 (P7_SYS_PADCTRL_IO + UL(4 * 6))
+#define P7_SYS_PADCTRL_IO_07 (P7_SYS_PADCTRL_IO + UL(4 * 7))
+#define P7_SYS_PADCTRL_IO_08 (P7_SYS_PADCTRL_IO + UL(4 * 8))
+#define P7_SYS_PADCTRL_IO_09 (P7_SYS_PADCTRL_IO + UL(4 * 9))
+#define P7_SYS_PADCTRL_IO_10 (P7_SYS_PADCTRL_IO + UL(4 * 10))
+#define P7_SYS_PADCTRL_IO_11 (P7_SYS_PADCTRL_IO + UL(4 * 11))
+#define P7_SYS_PADCTRL_IO_12 (P7_SYS_PADCTRL_IO + UL(4 * 12))
+#define P7_SYS_PADCTRL_IO_13 (P7_SYS_PADCTRL_IO + UL(4 * 13))
+#define P7_SYS_PADCTRL_IO_14 (P7_SYS_PADCTRL_IO + UL(4 * 14))
+#define P7_SYS_PADCTRL_IO_15 (P7_SYS_PADCTRL_IO + UL(4 * 15))
+#define P7_SYS_PADCTRL_IO_16 (P7_SYS_PADCTRL_IO + UL(4 * 16))
+#define P7_SYS_PADCTRL_IO_17 (P7_SYS_PADCTRL_IO + UL(4 * 17))
+#define P7_SYS_PADCTRL_IO_18 (P7_SYS_PADCTRL_IO + UL(4 * 18))
+#define P7_SYS_PADCTRL_IO_19 (P7_SYS_PADCTRL_IO + UL(4 * 19))
+#define P7_SYS_PADCTRL_IO_20 (P7_SYS_PADCTRL_IO + UL(4 * 20))
+#define P7_SYS_PADCTRL_IO_21 (P7_SYS_PADCTRL_IO + UL(4 * 21))
+#define P7_SYS_PADCTRL_IO_22 (P7_SYS_PADCTRL_IO + UL(4 * 22))
+#define P7_SYS_PADCTRL_IO_23 (P7_SYS_PADCTRL_IO + UL(4 * 23))
+#define P7_SYS_PADCTRL_IO_24 (P7_SYS_PADCTRL_IO + UL(4 * 24))
+#define P7_SYS_PADCTRL_IO_25 (P7_SYS_PADCTRL_IO + UL(4 * 25))
+#define P7_SYS_PADCTRL_IO_26 (P7_SYS_PADCTRL_IO + UL(4 * 26))
+#define P7_SYS_PADCTRL_IO_27 (P7_SYS_PADCTRL_IO + UL(4 * 27))
+#define P7_SYS_PADCTRL_IO_28 (P7_SYS_PADCTRL_IO + UL(4 * 28))
+#define P7_SYS_PADCTRL_IO_29 (P7_SYS_PADCTRL_IO + UL(4 * 29))
+#define P7_SYS_PADCTRL_IO_30 (P7_SYS_PADCTRL_IO + UL(4 * 30))
+#define P7_SYS_PADCTRL_IO_31 (P7_SYS_PADCTRL_IO + UL(4 * 31))
+#define P7_SYS_PADCTRL_IO_32 (P7_SYS_PADCTRL_IO + UL(4 * 32))
+#define P7_SYS_PADCTRL_IO_33 (P7_SYS_PADCTRL_IO + UL(4 * 33))
+#define P7_SYS_PADCTRL_IO_34 (P7_SYS_PADCTRL_IO + UL(4 * 34))
+#define P7_SYS_PADCTRL_IO_35 (P7_SYS_PADCTRL_IO + UL(4 * 35))
+#define P7_SYS_PADCTRL_IO_36 (P7_SYS_PADCTRL_IO + UL(4 * 36))
+#define P7_SYS_PADCTRL_IO_37 (P7_SYS_PADCTRL_IO + UL(4 * 37))
+#define P7_SYS_PADCTRL_IO_38 (P7_SYS_PADCTRL_IO + UL(4 * 38))
+#define P7_SYS_PADCTRL_IO_39 (P7_SYS_PADCTRL_IO + UL(4 * 39))
+#define P7_SYS_PADCTRL_IO_40 (P7_SYS_PADCTRL_IO + UL(4 * 40))
+#define P7_SYS_PADCTRL_IO_41 (P7_SYS_PADCTRL_IO + UL(4 * 41))
+#define P7_SYS_PADCTRL_IO_42 (P7_SYS_PADCTRL_IO + UL(4 * 42))
+#define P7_SYS_PADCTRL_IO_43 (P7_SYS_PADCTRL_IO + UL(4 * 43))
+#define P7_SYS_PADCTRL_IO_44 (P7_SYS_PADCTRL_IO + UL(4 * 44))
+#define P7_SYS_PADCTRL_IO_45 (P7_SYS_PADCTRL_IO + UL(4 * 45))
+#define P7_SYS_PADCTRL_IO_46 (P7_SYS_PADCTRL_IO + UL(4 * 46))
+#define P7_SYS_PADCTRL_IO_47 (P7_SYS_PADCTRL_IO + UL(4 * 47))
+#define P7_SYS_PADCTRL_IO_48 (P7_SYS_PADCTRL_IO + UL(4 * 48))
+#define P7_SYS_PADCTRL_IO_49 (P7_SYS_PADCTRL_IO + UL(4 * 49))
+#define P7_SYS_PADCTRL_IO_50 (P7_SYS_PADCTRL_IO + UL(4 * 50))
+#define P7_SYS_PADCTRL_IO_51 (P7_SYS_PADCTRL_IO + UL(4 * 51))
+#define P7_SYS_PADCTRL_IO_52 (P7_SYS_PADCTRL_IO + UL(4 * 52))
+#define P7_SYS_PADCTRL_IO_53 (P7_SYS_PADCTRL_IO + UL(4 * 53))
+#define P7_SYS_PADCTRL_IO_54 (P7_SYS_PADCTRL_IO + UL(4 * 54))
+#define P7_SYS_PADCTRL_IO_55 (P7_SYS_PADCTRL_IO + UL(4 * 55))
+#define P7_SYS_PADCTRL_IO_56 (P7_SYS_PADCTRL_IO + UL(4 * 56))
+#define P7_SYS_PADCTRL_IO_57 (P7_SYS_PADCTRL_IO + UL(4 * 57))
+
+/* Configuration registers. */
+#define P7_SYS_CHIP_ID (P7_SYS + UL(0x400))
+#define P7_SYS_BOOT_MODE (P7_SYS + UL(0x408))
+#define P7_SYS_SCRATCH_REG0 (P7_SYS + UL(0x40c))
+#define P7_SYS_SCRATCH_REG1 (P7_SYS + UL(0x410))
+#define P7_SYS_WATCHDOG (P7_SYS + UL(0x418))
+
+/* Timers. */
+#define P7_SYS_TIMX_CTL UL(0x0)
+#define P7_SYS_TIMXCTL_ENABLE (1U << 0)
+#define P7_SYS_TIMX_LD UL(0x4)
+#define P7_SYS_TIMX_CNT UL(0x8)
+#define P7_SYS_TIM0_IT (1U << 0)
+#define P7_SYS_TIM1_IT (1U << 1)
+#define P7_SYS_TIM2_IT (1U << 2)
+#define P7_SYS_TIM3_IT (1U << 3)
+
+#define P7_SYS_TIM (P7_SYS + UL(0x800))
+
+#define P7_SYS_TIM0 (P7_SYS + UL(0x0))
+#define P7_SYS_TIM0_CTL (P7_SYS_TIM0 + P7_SYS_TIMX_CTL)
+#define P7_SYS_TIM0_LD (P7_SYS_TIM0 + P7_SYS_TIMX_LD)
+#define P7_SYS_TIM0_CNT (P7_SYS_TIM0 + P7_SYS_TIMX_CNT)
+
+#define P7_SYS_TIM1 (P7_SYS_TIM + UL(0x10))
+#define P7_SYS_TIM1_CTL (P7_SYS_TIM1 + P7_SYS_TIMX_CTL)
+#define P7_SYS_TIM1_LD (P7_SYS_TIM1 + P7_SYS_TIMX_LD)
+#define P7_SYS_TIM1_CNT (P7_SYS_TIM1 + P7_SYS_TIMX_CNT)
+
+#define P7_SYS_TIM2 (P7_SYS_TIM + UL(0x20))
+#define P7_SYS_TIM2_CTL (P7_SYS_TIM2 + P7_SYS_TIMX_CTL)
+#define P7_SYS_TIM2_LD (P7_SYS_TIM2 + P7_SYS_TIMX_LD)
+#define P7_SYS_TIM2_CNT (P7_SYS_TIM2 + P7_SYS_TIMX_CNT)
+
+#define P7_SYS_TIM3 (P7_SYS_TIM + UL(0x30))
+#define P7_SYS_TIM3_CTL (P7_SYS_TIM3 + P7_SYS_TIMX_CTL)
+#define P7_SYS_TIM3_LD (P7_SYS_TIM3 + P7_SYS_TIMX_LD)
+#define P7_SYS_TIM3_CNT (P7_SYS_TIM3 + P7_SYS_TIMX_CNT)
+
+#define P7_SYS_TIM_STATUS (P7_SYS_TIM + UL(0x100))
+#define P7_SYS_TIM_ITEN (P7_SYS_TIM + UL(0x104))
+#define P7_SYS_TIM_ITACK (P7_SYS_TIM + UL(0x108))
+
+#endif
+
+/* vim:set ts=4:sw=4:noet:ft=c: */
diff --git a/arch/arm/mach-parrot7/uart.c b/arch/arm/mach-parrot7/uart.c
new file mode 100644
index 0000000..e145833
--- /dev/null
+++ b/arch/arm/mach-parrot7/uart.c
@@ -0,0 +1,203 @@
+/**
+ * linux/arch/arm/mach-parrot7/uart.c - Parrot7 serial port platform
+ * implementation
+ *
+ * Copyright (C) 2012 Parrot S.A.
+ *
+ * author: Gregor Boirie <gregor.boirie@parrot.com>
+ * date: 13-Jun-2012
+ *
+ * This file is released under the GPL
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clkdev.h>
+#include <serial/px-uart.h>
+#include <mach/irqs.h>
+#include <mach/p7.h>
+#include "common.h"
+#include "clock.h"
+
+static struct resource p7_uart0_res[] = {
+ [0] = {
+ .start = P7_UART0,
+ .end = P7_UART0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART0_IRQ,
+ .end = P7_UART0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart1_res[] = {
+ [0] = {
+ .start = P7_UART1,
+ .end = P7_UART1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART1_IRQ,
+ .end = P7_UART1_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart2_res[] = {
+ [0] = {
+ .start = P7_UART2,
+ .end = P7_UART2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART2_IRQ,
+ .end = P7_UART2_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart3_res[] = {
+ [0] = {
+ .start = P7_UART3,
+ .end = P7_UART3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART3_IRQ,
+ .end = P7_UART3_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart4_res[] = {
+ [0] = {
+ .start = P7_UART4,
+ .end = P7_UART4 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART4_IRQ,
+ .end = P7_UART4_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart5_res[] = {
+ [0] = {
+ .start = P7_UART5,
+ .end = P7_UART5 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART5_IRQ,
+ .end = P7_UART5_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart6_res[] = {
+ [0] = {
+ .start = P7_UART6,
+ .end = P7_UART6 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART6_IRQ,
+ .end = P7_UART6_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource p7_uart7_res[] = {
+ [0] = {
+ .start = P7_UART7,
+ .end = P7_UART7 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = P7_UART7_IRQ,
+ .end = P7_UART7_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device p7_uart_devs[] = {
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 0,
+ .resource = p7_uart0_res,
+ .num_resources = ARRAY_SIZE(p7_uart0_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 1,
+ .resource = p7_uart1_res,
+ .num_resources = ARRAY_SIZE(p7_uart1_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 2,
+ .resource = p7_uart2_res,
+ .num_resources = ARRAY_SIZE(p7_uart2_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 3,
+ .resource = p7_uart3_res,
+ .num_resources = ARRAY_SIZE(p7_uart3_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 4,
+ .resource = p7_uart4_res,
+ .num_resources = ARRAY_SIZE(p7_uart4_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 5,
+ .resource = p7_uart5_res,
+ .num_resources = ARRAY_SIZE(p7_uart5_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 6,
+ .resource = p7_uart6_res,
+ .num_resources = ARRAY_SIZE(p7_uart6_res)
+ },
+ {
+ .name = PXUART_DRV_NAME,
+ .id = 7,
+ .resource = p7_uart7_res,
+ .num_resources = ARRAY_SIZE(p7_uart7_res)
+ },
+};
+
+/**
+ * p7_init_uart() - Instantiate I2C master controller identified by @bus
+ * for further driver usage.
+ *
+ * @port: UART port identifier
+ * @pins: array of pin functions and settings
+ * @pin_cnt: number of element of @pins array
+ */
+void __init p7_init_uart(int port,
+ struct pinctrl_map* pins,
+ size_t pin_cnt)
+{
+ int err;
+
+#ifdef DEBUG
+ BUG_ON(port >= ARRAY_SIZE(p7_uart_devs));
+ BUG_ON(! pins);
+ BUG_ON(! pin_cnt);
+#endif
+ if (port >= ARRAY_SIZE(p7_uart_devs)) {
+ printk(KERN_ERR "p7 Uart%d do not exist\n", port);
+ return;
+ }
+
+ err = p7_init_dev(&p7_uart_devs[port], NULL, pins, pin_cnt);
+ if (err)
+ panic("p7: failed to init UART %d (%d)\n", port, err);
+}
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
new file mode 100644
index 0000000..345395e
--- /dev/null
+++ b/drivers/iio/Kconfig
@@ -0,0 +1,81 @@
+#
+# Industrial I/O subsystem configuration
+#
+
+menuconfig IIO
+ tristate "Industrial I/O support"
+ select ANON_INODES
+ help
+ The industrial I/O subsystem provides a unified framework for
+ drivers for many different types of embedded sensors using a
+ number of different physical interfaces (i2c, spi, etc).
+
+if IIO
+
+config IIO_BUFFER
+ bool "Enable buffer support within IIO"
+ help
+ Provide core support for various buffer based data
+ acquisition methods.
+
+if IIO_BUFFER
+
+config IIO_BUFFER_CB
+boolean "IIO callback buffer used for push in-kernel interfaces"
+ help
+ Should be selected by any drivers that do in-kernel push
+ usage. That is, those where the data is pushed to the consumer.
+
+config IIO_KFIFO_BUF
+ select IIO_TRIGGER
+ tristate "Industrial I/O buffering based on kfifo"
+ help
+ A simple fifo based on kfifo. Note that this currently provides
+ no buffer events so it is up to userspace to work out how
+ often to read from the buffer.
+
+config IIO_TRIGGERED_BUFFER
+ tristate
+ select IIO_TRIGGER
+ select IIO_KFIFO_BUF
+ help
+ Provides helper functions for setting up triggered buffers.
+
+endif # IIO_BUFFER
+
+config IIO_TRIGGER
+ boolean "Enable triggered sampling support"
+ help
+ Provides IIO core support for triggers. Currently these
+ are used to initialize capture of samples to push into
+ buffers. The triggers are effectively a 'capture
+ data now' interrupt.
+
+config IIO_CONSUMERS_PER_TRIGGER
+ int "Maximum number of consumers per trigger"
+ depends on IIO_TRIGGER
+ default "2"
+ help
+ This value controls the maximum number of consumers that a
+ given trigger may handle. Default is 2.
+
+source "drivers/iio/accel/Kconfig"
+source "drivers/iio/adc/Kconfig"
+source "drivers/iio/amplifiers/Kconfig"
+source "drivers/iio/common/Kconfig"
+source "drivers/iio/dac/Kconfig"
+source "drivers/iio/frequency/Kconfig"
+source "drivers/iio/gyro/Kconfig"
+source "drivers/iio/humidity/Kconfig"
+source "drivers/iio/imu/Kconfig"
+source "drivers/iio/light/Kconfig"
+source "drivers/iio/magnetometer/Kconfig"
+source "drivers/iio/orientation/Kconfig"
+if IIO_TRIGGER
+ source "drivers/iio/trigger/Kconfig"
+endif #IIO_TRIGGER
+source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/proximity/Kconfig"
+source "drivers/iio/temperature/Kconfig"
+
+endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
new file mode 100644
index 0000000..698afc2
--- /dev/null
+++ b/drivers/iio/Makefile
@@ -0,0 +1,29 @@
+#
+# Makefile for the industrial I/O core.
+#
+
+obj-$(CONFIG_IIO) += industrialio.o
+industrialio-y := industrialio-core.o industrialio-event.o inkern.o
+industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
+industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
+industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o
+
+obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
+obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
+
+obj-y += accel/
+obj-y += adc/
+obj-y += amplifiers/
+obj-y += common/
+obj-y += dac/
+obj-y += gyro/
+obj-y += frequency/
+obj-y += humidity/
+obj-y += imu/
+obj-y += light/
+obj-y += magnetometer/
+obj-y += orientation/
+obj-y += pressure/
+obj-y += proximity/
+obj-y += temperature/
+obj-y += trigger/
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
new file mode 100644
index 0000000..9b9be87
--- /dev/null
+++ b/drivers/iio/accel/Kconfig
@@ -0,0 +1,108 @@
+#
+# Accelerometer drivers
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Accelerometers"
+
+config BMA180
+ tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build a driver for the Bosch BMA180 or
+ BMA250 triaxial acceleration sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bma180.
+
+config BMC150_ACCEL
+ tristate "Bosch BMC150 Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for the following Bosch accelerometers:
+ BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
+
+ Currently this only supports the device via an i2c interface.
+
+ This is a combo module with both accelerometer and magnetometer.
+ This driver is only implementing accelerometer part, which has
+ its own address and register map.
+
+config HID_SENSOR_ACCEL_3D
+ depends on HID_SENSOR_HUB
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select HID_SENSOR_IIO_COMMON
+ select HID_SENSOR_IIO_TRIGGER
+ tristate "HID Accelerometers 3D"
+ help
+ Say yes here to build support for the HID SENSOR
+ accelerometers 3D.
+
+config IIO_ST_ACCEL_3AXIS
+ tristate "STMicroelectronics accelerometers 3-Axis Driver"
+ depends on (I2C || SPI_MASTER) && SYSFS
+ select IIO_ST_SENSORS_CORE
+ select IIO_ST_ACCEL_I2C_3AXIS if (I2C)
+ select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER)
+ select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
+ help
+ Say yes here to build support for STMicroelectronics accelerometers:
+ LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
+ LIS331DLH, LSM303DL, LSM303DLM, LSM330.
+
+ This driver can also be built as a module. If so, these modules
+ will be created:
+ - st_accel (core functions for the driver [it is mandatory]);
+ - st_accel_i2c (necessary for the I2C devices [optional*]);
+ - st_accel_spi (necessary for the SPI devices [optional*]);
+
+ (*) one of these is necessary to do something.
+
+config IIO_ST_ACCEL_I2C_3AXIS
+ tristate
+ depends on IIO_ST_ACCEL_3AXIS
+ depends on IIO_ST_SENSORS_I2C
+
+config IIO_ST_ACCEL_SPI_3AXIS
+ tristate
+ depends on IIO_ST_ACCEL_3AXIS
+ depends on IIO_ST_SENSORS_SPI
+
+config KXSD9
+ tristate "Kionix KXSD9 Accelerometer Driver"
+ depends on SPI
+ help
+ Say yes here to build support for the Kionix KXSD9 accelerometer.
+ Currently this only supports the device via an SPI interface.
+
+config MMA8452
+ tristate "Freescale MMA8452Q Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for the Freescale MMA8452Q 3-axis
+ accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mma8452.
+
+config KXCJK1013
+ tristate "Kionix 3-Axis Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build a driver for the Kionix KXCJK-1013
+ triaxial acceleration sensor. This driver also supports KXCJ9-1008
+ and KXTJ2-1009.
+
+ To compile this driver as a module, choose M here: the module will
+ be called kxcjk-1013.
+
+endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
new file mode 100644
index 0000000..a593996
--- /dev/null
+++ b/drivers/iio/accel/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for industrial I/O accelerometer drivers
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_BMA180) += bma180.o
+obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
+obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
+obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
+obj-$(CONFIG_KXSD9) += kxsd9.o
+obj-$(CONFIG_MMA8452) += mma8452.o
+
+obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
+st_accel-y := st_accel_core.o
+st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
+
+obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
+obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
new file mode 100644
index 0000000..01003d0
--- /dev/null
+++ b/drivers/iio/accel/bma180.c
@@ -0,0 +1,862 @@
+/*
+ * bma180.c - IIO driver for Bosch BMA180 triaxial acceleration sensor
+ *
+ * Copyright 2013 Oleksandr Kravchenko <x0199363@ti.com>
+ *
+ * Support for BMA250 (c) Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SPI is not supported by driver
+ * BMA180: 7-bit I2C slave address 0x40 or 0x41
+ * BMA250: 7-bit I2C slave address 0x18 or 0x19
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define BMA180_DRV_NAME "bma180"
+#define BMA180_IRQ_NAME "bma180_event"
+
+enum {
+ BMA180,
+ BMA250,
+};
+
+struct bma180_data;
+
+struct bma180_part_info {
+ const struct iio_chan_spec *channels;
+ unsigned num_channels;
+ const int *scale_table;
+ unsigned num_scales;
+ const int *bw_table;
+ unsigned num_bw;
+
+ u8 int_reset_reg, int_reset_mask;
+ u8 sleep_reg, sleep_mask;
+ u8 bw_reg, bw_mask;
+ u8 scale_reg, scale_mask;
+ u8 power_reg, power_mask, lowpower_val;
+ u8 int_enable_reg, int_enable_mask;
+ u8 softreset_reg;
+
+ int (*chip_config)(struct bma180_data *data);
+ void (*chip_disable)(struct bma180_data *data);
+};
+
+/* Register set */
+#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */
+#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */
+#define BMA180_TEMP 0x08
+#define BMA180_CTRL_REG0 0x0d
+#define BMA180_RESET 0x10
+#define BMA180_BW_TCS 0x20
+#define BMA180_CTRL_REG3 0x21
+#define BMA180_TCO_Z 0x30
+#define BMA180_OFFSET_LSB1 0x35
+
+/* BMA180_CTRL_REG0 bits */
+#define BMA180_DIS_WAKE_UP BIT(0) /* Disable wake up mode */
+#define BMA180_SLEEP BIT(1) /* 1 - chip will sleep */
+#define BMA180_EE_W BIT(4) /* Unlock writing to addr from 0x20 */
+#define BMA180_RESET_INT BIT(6) /* Reset pending interrupts */
+
+/* BMA180_CTRL_REG3 bits */
+#define BMA180_NEW_DATA_INT BIT(1) /* Intr every new accel data is ready */
+
+/* BMA180_OFFSET_LSB1 skipping mode bit */
+#define BMA180_SMP_SKIP BIT(0)
+
+/* Bit masks for registers bit fields */
+#define BMA180_RANGE 0x0e /* Range of measured accel values */
+#define BMA180_BW 0xf0 /* Accel bandwidth */
+#define BMA180_MODE_CONFIG 0x03 /* Config operation modes */
+
+/* We have to write this value in reset register to do soft reset */
+#define BMA180_RESET_VAL 0xb6
+
+#define BMA180_ID_REG_VAL 0x03
+
+/* Chip power modes */
+#define BMA180_LOW_POWER 0x03
+
+#define BMA250_RANGE_REG 0x0f
+#define BMA250_BW_REG 0x10
+#define BMA250_POWER_REG 0x11
+#define BMA250_RESET_REG 0x14
+#define BMA250_INT_ENABLE_REG 0x17
+#define BMA250_INT_MAP_REG 0x1a
+#define BMA250_INT_RESET_REG 0x21
+
+#define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */
+#define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */
+#define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */
+#define BMA250_LOWPOWER_MASK BIT(6)
+#define BMA250_DATA_INTEN_MASK BIT(4)
+#define BMA250_INT1_DATA_MASK BIT(0)
+#define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */
+
+struct bma180_data {
+ struct i2c_client *client;
+ struct iio_trigger *trig;
+ const struct bma180_part_info *part_info;
+ struct mutex mutex;
+ bool sleep_state;
+ int scale;
+ int bw;
+ bool pmode;
+ u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */
+};
+
+enum bma180_chan {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_Z,
+ TEMP
+};
+
+static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
+static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
+
+static int bma250_bw_table[] = { 8, 16, 31, 63, 125, 250 }; /* Hz */
+static int bma250_scale_table[] = { 0, 0, 0, 38344, 0, 76590, 0, 0, 153180, 0,
+ 0, 0, 306458 };
+
+static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
+{
+ int ret;
+
+ if (data->sleep_state)
+ return -EBUSY;
+
+ switch (chan) {
+ case TEMP:
+ ret = i2c_smbus_read_byte_data(data->client, BMA180_TEMP);
+ if (ret < 0)
+ dev_err(&data->client->dev, "failed to read temp register\n");
+ break;
+ default:
+ ret = i2c_smbus_read_word_data(data->client,
+ BMA180_ACC_X_LSB + chan * 2);
+ if (ret < 0)
+ dev_err(&data->client->dev,
+ "failed to read accel_%c register\n",
+ 'x' + chan);
+ }
+
+ return ret;
+}
+
+static int bma180_set_bits(struct bma180_data *data, u8 reg, u8 mask, u8 val)
+{
+ int ret = i2c_smbus_read_byte_data(data->client, reg);
+ u8 reg_val = (ret & ~mask) | (val << (ffs(mask) - 1));
+
+ if (ret < 0)
+ return ret;
+
+ return i2c_smbus_write_byte_data(data->client, reg, reg_val);
+}
+
+static int bma180_reset_intr(struct bma180_data *data)
+{
+ int ret = bma180_set_bits(data, data->part_info->int_reset_reg,
+ data->part_info->int_reset_mask, 1);
+
+ if (ret)
+ dev_err(&data->client->dev, "failed to reset interrupt\n");
+
+ return ret;
+}
+
+static int bma180_set_new_data_intr_state(struct bma180_data *data, bool state)
+{
+ int ret = bma180_set_bits(data, data->part_info->int_enable_reg,
+ data->part_info->int_enable_mask, state);
+ if (ret)
+ goto err;
+ ret = bma180_reset_intr(data);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ dev_err(&data->client->dev,
+ "failed to set new data interrupt state %d\n", state);
+ return ret;
+}
+
+static int bma180_set_sleep_state(struct bma180_data *data, bool state)
+{
+ int ret = bma180_set_bits(data, data->part_info->sleep_reg,
+ data->part_info->sleep_mask, state);
+
+ if (ret) {
+ dev_err(&data->client->dev,
+ "failed to set sleep state %d\n", state);
+ return ret;
+ }
+ data->sleep_state = state;
+
+ return 0;
+}
+
+static int bma180_set_ee_writing_state(struct bma180_data *data, bool state)
+{
+ int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_EE_W, state);
+
+ if (ret)
+ dev_err(&data->client->dev,
+ "failed to set ee writing state %d\n", state);
+
+ return ret;
+}
+
+static int bma180_set_bw(struct bma180_data *data, int val)
+{
+ int ret, i;
+
+ if (data->sleep_state)
+ return -EBUSY;
+
+ for (i = 0; i < data->part_info->num_bw; ++i) {
+ if (data->part_info->bw_table[i] == val) {
+ ret = bma180_set_bits(data, data->part_info->bw_reg,
+ data->part_info->bw_mask, i);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "failed to set bandwidth\n");
+ return ret;
+ }
+ data->bw = val;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int bma180_set_scale(struct bma180_data *data, int val)
+{
+ int ret, i;
+
+ if (data->sleep_state)
+ return -EBUSY;
+
+ for (i = 0; i < data->part_info->num_scales; ++i)
+ if (data->part_info->scale_table[i] == val) {
+ ret = bma180_set_bits(data, data->part_info->scale_reg,
+ data->part_info->scale_mask, i);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "failed to set scale\n");
+ return ret;
+ }
+ data->scale = val;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int bma180_set_pmode(struct bma180_data *data, bool mode)
+{
+ u8 reg_val = mode ? data->part_info->lowpower_val : 0;
+ int ret = bma180_set_bits(data, data->part_info->power_reg,
+ data->part_info->power_mask, reg_val);
+
+ if (ret) {
+ dev_err(&data->client->dev, "failed to set power mode\n");
+ return ret;
+ }
+ data->pmode = mode;
+
+ return 0;
+}
+
+static int bma180_soft_reset(struct bma180_data *data)
+{
+ int ret = i2c_smbus_write_byte_data(data->client,
+ data->part_info->softreset_reg, BMA180_RESET_VAL);
+
+ if (ret)
+ dev_err(&data->client->dev, "failed to reset the chip\n");
+
+ return ret;
+}
+
+static int bma180_chip_init(struct bma180_data *data)
+{
+ /* Try to read chip_id register. It must return 0x03. */
+ int ret = i2c_smbus_read_byte_data(data->client, BMA180_CHIP_ID);
+
+ if (ret < 0)
+ return ret;
+ if (ret != BMA180_ID_REG_VAL)
+ return -ENODEV;
+
+ ret = bma180_soft_reset(data);
+ if (ret)
+ return ret;
+ /*
+ * No serial transaction should occur within minimum 10 us
+ * after soft_reset command
+ */
+ msleep(20);
+
+ ret = bma180_set_new_data_intr_state(data, false);
+ if (ret)
+ return ret;
+
+ return bma180_set_pmode(data, false);
+}
+
+static int bma180_chip_config(struct bma180_data *data)
+{
+ int ret = bma180_chip_init(data);
+
+ if (ret)
+ goto err;
+ ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_DIS_WAKE_UP, 1);
+ if (ret)
+ goto err;
+ ret = bma180_set_ee_writing_state(data, true);
+ if (ret)
+ goto err;
+ ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
+ if (ret)
+ goto err;
+ ret = bma180_set_bw(data, 20); /* 20 Hz */
+ if (ret)
+ goto err;
+ ret = bma180_set_scale(data, 2452); /* 2 G */
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ dev_err(&data->client->dev, "failed to config the chip\n");
+ return ret;
+}
+
+static int bma250_chip_config(struct bma180_data *data)
+{
+ int ret = bma180_chip_init(data);
+
+ if (ret)
+ goto err;
+ ret = bma180_set_bw(data, 16); /* 16 Hz */
+ if (ret)
+ goto err;
+ ret = bma180_set_scale(data, 38344); /* 2 G */
+ if (ret)
+ goto err;
+ ret = bma180_set_bits(data, BMA250_INT_MAP_REG,
+ BMA250_INT1_DATA_MASK, 1);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ dev_err(&data->client->dev, "failed to config the chip\n");
+ return ret;
+}
+
+static void bma180_chip_disable(struct bma180_data *data)
+{
+ if (bma180_set_new_data_intr_state(data, false))
+ goto err;
+ if (bma180_set_ee_writing_state(data, false))
+ goto err;
+ if (bma180_set_sleep_state(data, true))
+ goto err;
+
+ return;
+
+err:
+ dev_err(&data->client->dev, "failed to disable the chip\n");
+}
+
+static void bma250_chip_disable(struct bma180_data *data)
+{
+ if (bma180_set_new_data_intr_state(data, false))
+ goto err;
+ if (bma180_set_sleep_state(data, true))
+ goto err;
+
+ return;
+
+err:
+ dev_err(&data->client->dev, "failed to disable the chip\n");
+}
+
+static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned n,
+ bool micros)
+{
+ size_t len = 0;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (!vals[i])
+ continue;
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ micros ? "0.%06d " : "%d ", vals[i]);
+ }
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t bma180_show_filter_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ return bma180_show_avail(buf, data->part_info->bw_table,
+ data->part_info->num_bw, false);
+}
+
+static ssize_t bma180_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ return bma180_show_avail(buf, data->part_info->scale_table,
+ data->part_info->num_scales, true);
+}
+
+static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
+ S_IRUGO, bma180_show_filter_freq_avail, NULL, 0);
+
+static IIO_DEVICE_ATTR(in_accel_scale_available,
+ S_IRUGO, bma180_show_scale_avail, NULL, 0);
+
+static struct attribute *bma180_attributes[] = {
+ &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.
+ dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group bma180_attrs_group = {
+ .attrs = bma180_attributes,
+};
+
+static int bma180_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2,
+ long mask)
+{
+ struct bma180_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&data->mutex);
+ if (iio_buffer_enabled(indio_dev)) {
+ mutex_unlock(&data->mutex);
+ return -EBUSY;
+ }
+ ret = bma180_get_data_reg(data, chan->scan_index);
+ mutex_unlock(&data->mutex);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret >> chan->scan_type.shift,
+ chan->scan_type.realbits - 1);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ *val = data->bw;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ACCEL:
+ *val = 0;
+ *val2 = data->scale;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_TEMP:
+ *val = 500;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 48; /* 0 LSB @ 24 degree C */
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int bma180_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+ struct bma180_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ if (val)
+ return -EINVAL;
+ mutex_lock(&data->mutex);
+ ret = bma180_set_scale(data, val2);
+ mutex_unlock(&data->mutex);
+ return ret;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&data->mutex);
+ ret = bma180_set_bw(data, val);
+ mutex_unlock(&data->mutex);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info bma180_info = {
+ .attrs = &bma180_attrs_group,
+ .read_raw = bma180_read_raw,
+ .write_raw = bma180_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static const char * const bma180_power_modes[] = { "low_noise", "low_power" };
+
+static int bma180_get_power_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct bma180_data *data = iio_priv(indio_dev);
+
+ return data->pmode;
+}
+
+static int bma180_set_power_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, unsigned int mode)
+{
+ struct bma180_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma180_set_pmode(data, mode);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static const struct iio_enum bma180_power_mode_enum = {
+ .items = bma180_power_modes,
+ .num_items = ARRAY_SIZE(bma180_power_modes),
+ .get = bma180_get_power_mode,
+ .set = bma180_set_power_mode,
+};
+
+static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
+ IIO_ENUM("power_mode", true, &bma180_power_mode_enum),
+ IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum),
+ { },
+};
+
+#define BMA180_ACC_CHANNEL(_axis, _bits) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .scan_index = AXIS_##_axis, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = _bits, \
+ .storagebits = 16, \
+ .shift = 16 - _bits, \
+ }, \
+ .ext_info = bma180_ext_info, \
+}
+
+#define BMA180_TEMP_CHANNEL { \
+ .type = IIO_TEMP, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_index = TEMP, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 8, \
+ .storagebits = 16, \
+ }, \
+}
+
+static const struct iio_chan_spec bma180_channels[] = {
+ BMA180_ACC_CHANNEL(X, 14),
+ BMA180_ACC_CHANNEL(Y, 14),
+ BMA180_ACC_CHANNEL(Z, 14),
+ BMA180_TEMP_CHANNEL,
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static const struct iio_chan_spec bma250_channels[] = {
+ BMA180_ACC_CHANNEL(X, 10),
+ BMA180_ACC_CHANNEL(Y, 10),
+ BMA180_ACC_CHANNEL(Z, 10),
+ BMA180_TEMP_CHANNEL,
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static const struct bma180_part_info bma180_part_info[] = {
+ [BMA180] = {
+ bma180_channels, ARRAY_SIZE(bma180_channels),
+ bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
+ bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
+ BMA180_CTRL_REG0, BMA180_RESET_INT,
+ BMA180_CTRL_REG0, BMA180_SLEEP,
+ BMA180_BW_TCS, BMA180_BW,
+ BMA180_OFFSET_LSB1, BMA180_RANGE,
+ BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
+ BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
+ BMA180_RESET,
+ bma180_chip_config,
+ bma180_chip_disable,
+ },
+ [BMA250] = {
+ bma250_channels, ARRAY_SIZE(bma250_channels),
+ bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
+ bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
+ BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
+ BMA250_POWER_REG, BMA250_SUSPEND_MASK,
+ BMA250_BW_REG, BMA250_BW_MASK,
+ BMA250_RANGE_REG, BMA250_RANGE_MASK,
+ BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
+ BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
+ BMA250_RESET_REG,
+ bma250_chip_config,
+ bma250_chip_disable,
+ },
+};
+
+static irqreturn_t bma180_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct bma180_data *data = iio_priv(indio_dev);
+ int64_t time_ns = iio_get_time_ns();
+ int bit, ret, i = 0;
+
+ mutex_lock(&data->mutex);
+
+ for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ indio_dev->masklength) {
+ ret = bma180_get_data_reg(data, bit);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ goto err;
+ }
+ ((s16 *)data->buff)[i++] = ret;
+ }
+
+ mutex_unlock(&data->mutex);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
+err:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int bma180_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct bma180_data *data = iio_priv(indio_dev);
+
+ return bma180_set_new_data_intr_state(data, state);
+}
+
+static int bma180_trig_try_reen(struct iio_trigger *trig)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct bma180_data *data = iio_priv(indio_dev);
+
+ return bma180_reset_intr(data);
+}
+
+static const struct iio_trigger_ops bma180_trigger_ops = {
+ .set_trigger_state = bma180_data_rdy_trigger_set_state,
+ .try_reenable = bma180_trig_try_reen,
+ .owner = THIS_MODULE,
+};
+
+static int bma180_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bma180_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+ data->part_info = &bma180_part_info[id->driver_data];
+
+ ret = data->part_info->chip_config(data);
+ if (ret < 0)
+ goto err_chip_disable;
+
+ mutex_init(&data->mutex);
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = data->part_info->channels;
+ indio_dev->num_channels = data->part_info->num_channels;
+ indio_dev->name = id->name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &bma180_info;
+
+ if (client->irq > 0) {
+ data->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+ indio_dev->id);
+ if (!data->trig) {
+ ret = -ENOMEM;
+ goto err_chip_disable;
+ }
+
+ ret = devm_request_irq(&client->dev, client->irq,
+ iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING,
+ "bma180_event", data->trig);
+ if (ret) {
+ dev_err(&client->dev, "unable to request IRQ\n");
+ goto err_trigger_free;
+ }
+
+ data->trig->dev.parent = &client->dev;
+ data->trig->ops = &bma180_trigger_ops;
+ iio_trigger_set_drvdata(data->trig, indio_dev);
+ indio_dev->trig = iio_trigger_get(data->trig);
+
+ ret = iio_trigger_register(data->trig);
+ if (ret)
+ goto err_trigger_free;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ bma180_trigger_handler, NULL);
+ if (ret < 0) {
+ dev_err(&client->dev, "unable to setup iio triggered buffer\n");
+ goto err_trigger_unregister;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "unable to register iio device\n");
+ goto err_buffer_cleanup;
+ }
+
+ return 0;
+
+err_buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+ if (data->trig)
+ iio_trigger_unregister(data->trig);
+err_trigger_free:
+ iio_trigger_free(data->trig);
+err_chip_disable:
+ data->part_info->chip_disable(data);
+
+ return ret;
+}
+
+static int bma180_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct bma180_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ if (data->trig) {
+ iio_trigger_unregister(data->trig);
+ iio_trigger_free(data->trig);
+ }
+
+ mutex_lock(&data->mutex);
+ data->part_info->chip_disable(data);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int bma180_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bma180_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma180_set_sleep_state(data, true);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int bma180_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bma180_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = bma180_set_sleep_state(data, false);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
+#define BMA180_PM_OPS (&bma180_pm_ops)
+#else
+#define BMA180_PM_OPS NULL
+#endif
+
+static struct i2c_device_id bma180_ids[] = {
+ { "bma180", BMA180 },
+ { "bma250", BMA250 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, bma180_ids);
+
+static struct i2c_driver bma180_driver = {
+ .driver = {
+ .name = "bma180",
+ .owner = THIS_MODULE,
+ .pm = BMA180_PM_OPS,
+ },
+ .probe = bma180_probe,
+ .remove = bma180_remove,
+ .id_table = bma180_ids,
+};
+
+module_i2c_driver(bma180_driver);
+
+MODULE_AUTHOR("Kravchenko Oleksandr <x0199363@ti.com>");
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("Bosch BMA180/BMA250 triaxial acceleration sensor");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
new file mode 100644
index 0000000..066d0c0
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -0,0 +1,1456 @@
+/*
+ * 3-axis accelerometer driver supporting following Bosch-Sensortec chips:
+ * - BMC150
+ * - BMI055
+ * - BMA255
+ * - BMA250E
+ * - BMA222E
+ * - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define BMC150_ACCEL_DRV_NAME "bmc150_accel"
+#define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
+#define BMC150_ACCEL_GPIO_NAME "bmc150_accel_int"
+
+#define BMC150_ACCEL_REG_CHIP_ID 0x00
+
+#define BMC150_ACCEL_REG_INT_STATUS_2 0x0B
+#define BMC150_ACCEL_ANY_MOTION_MASK 0x07
+#define BMC150_ACCEL_ANY_MOTION_BIT_X BIT(0)
+#define BMC150_ACCEL_ANY_MOTION_BIT_Y BIT(1)
+#define BMC150_ACCEL_ANY_MOTION_BIT_Z BIT(2)
+#define BMC150_ACCEL_ANY_MOTION_BIT_SIGN BIT(3)
+
+#define BMC150_ACCEL_REG_PMU_LPW 0x11
+#define BMC150_ACCEL_PMU_MODE_MASK 0xE0
+#define BMC150_ACCEL_PMU_MODE_SHIFT 5
+#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_MASK 0x17
+#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT 1
+
+#define BMC150_ACCEL_REG_PMU_RANGE 0x0F
+
+#define BMC150_ACCEL_DEF_RANGE_2G 0x03
+#define BMC150_ACCEL_DEF_RANGE_4G 0x05
+#define BMC150_ACCEL_DEF_RANGE_8G 0x08
+#define BMC150_ACCEL_DEF_RANGE_16G 0x0C
+
+/* Default BW: 125Hz */
+#define BMC150_ACCEL_REG_PMU_BW 0x10
+#define BMC150_ACCEL_DEF_BW 125
+
+#define BMC150_ACCEL_REG_INT_MAP_0 0x19
+#define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE BIT(2)
+
+#define BMC150_ACCEL_REG_INT_MAP_1 0x1A
+#define BMC150_ACCEL_INT_MAP_1_BIT_DATA BIT(0)
+
+#define BMC150_ACCEL_REG_INT_RST_LATCH 0x21
+#define BMC150_ACCEL_INT_MODE_LATCH_RESET 0x80
+#define BMC150_ACCEL_INT_MODE_LATCH_INT 0x0F
+#define BMC150_ACCEL_INT_MODE_NON_LATCH_INT 0x00
+
+#define BMC150_ACCEL_REG_INT_EN_0 0x16
+#define BMC150_ACCEL_INT_EN_BIT_SLP_X BIT(0)
+#define BMC150_ACCEL_INT_EN_BIT_SLP_Y BIT(1)
+#define BMC150_ACCEL_INT_EN_BIT_SLP_Z BIT(2)
+
+#define BMC150_ACCEL_REG_INT_EN_1 0x17
+#define BMC150_ACCEL_INT_EN_BIT_DATA_EN BIT(4)
+
+#define BMC150_ACCEL_REG_INT_OUT_CTRL 0x20
+#define BMC150_ACCEL_INT_OUT_CTRL_INT1_LVL BIT(0)
+
+#define BMC150_ACCEL_REG_INT_5 0x27
+#define BMC150_ACCEL_SLOPE_DUR_MASK 0x03
+
+#define BMC150_ACCEL_REG_INT_6 0x28
+#define BMC150_ACCEL_SLOPE_THRES_MASK 0xFF
+
+/* Slope duration in terms of number of samples */
+#define BMC150_ACCEL_DEF_SLOPE_DURATION 1
+/* in terms of multiples of g's/LSB, based on range */
+#define BMC150_ACCEL_DEF_SLOPE_THRESHOLD 1
+
+#define BMC150_ACCEL_REG_XOUT_L 0x02
+
+#define BMC150_ACCEL_MAX_STARTUP_TIME_MS 100
+
+/* Sleep Duration values */
+#define BMC150_ACCEL_SLEEP_500_MICRO 0x05
+#define BMC150_ACCEL_SLEEP_1_MS 0x06
+#define BMC150_ACCEL_SLEEP_2_MS 0x07
+#define BMC150_ACCEL_SLEEP_4_MS 0x08
+#define BMC150_ACCEL_SLEEP_6_MS 0x09
+#define BMC150_ACCEL_SLEEP_10_MS 0x0A
+#define BMC150_ACCEL_SLEEP_25_MS 0x0B
+#define BMC150_ACCEL_SLEEP_50_MS 0x0C
+#define BMC150_ACCEL_SLEEP_100_MS 0x0D
+#define BMC150_ACCEL_SLEEP_500_MS 0x0E
+#define BMC150_ACCEL_SLEEP_1_SEC 0x0F
+
+#define BMC150_ACCEL_REG_TEMP 0x08
+#define BMC150_ACCEL_TEMP_CENTER_VAL 24
+
+#define BMC150_ACCEL_AXIS_TO_REG(axis) (BMC150_ACCEL_REG_XOUT_L + (axis * 2))
+#define BMC150_AUTO_SUSPEND_DELAY_MS 2000
+
+enum bmc150_accel_axis {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_Z,
+};
+
+enum bmc150_power_modes {
+ BMC150_ACCEL_SLEEP_MODE_NORMAL,
+ BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND,
+ BMC150_ACCEL_SLEEP_MODE_LPM,
+ BMC150_ACCEL_SLEEP_MODE_SUSPEND = 0x04,
+};
+
+struct bmc150_scale_info {
+ int scale;
+ u8 reg_range;
+};
+
+struct bmc150_accel_chip_info {
+ u8 chip_id;
+ const struct iio_chan_spec *channels;
+ int num_channels;
+ const struct bmc150_scale_info scale_table[4];
+};
+
+struct bmc150_accel_data {
+ struct i2c_client *client;
+ struct iio_trigger *dready_trig;
+ struct iio_trigger *motion_trig;
+ struct mutex mutex;
+ s16 buffer[8];
+ u8 bw_bits;
+ u32 slope_dur;
+ u32 slope_thres;
+ u32 range;
+ int ev_enable_state;
+ bool dready_trigger_on;
+ bool motion_trigger_on;
+ int64_t timestamp;
+ const struct bmc150_accel_chip_info *chip_info;
+};
+
+static const struct {
+ int val;
+ int val2;
+ u8 bw_bits;
+} bmc150_accel_samp_freq_table[] = { {7, 810000, 0x08},
+ {15, 630000, 0x09},
+ {31, 250000, 0x0A},
+ {62, 500000, 0x0B},
+ {125, 0, 0x0C},
+ {250, 0, 0x0D},
+ {500, 0, 0x0E},
+ {1000, 0, 0x0F} };
+
+static const struct {
+ int bw_bits;
+ int msec;
+} bmc150_accel_sample_upd_time[] = { {0x08, 64},
+ {0x09, 32},
+ {0x0A, 16},
+ {0x0B, 8},
+ {0x0C, 4},
+ {0x0D, 2},
+ {0x0E, 1},
+ {0x0F, 1} };
+
+static const struct {
+ int sleep_dur;
+ u8 reg_value;
+} bmc150_accel_sleep_value_table[] = { {0, 0},
+ {500, BMC150_ACCEL_SLEEP_500_MICRO},
+ {1000, BMC150_ACCEL_SLEEP_1_MS},
+ {2000, BMC150_ACCEL_SLEEP_2_MS},
+ {4000, BMC150_ACCEL_SLEEP_4_MS},
+ {6000, BMC150_ACCEL_SLEEP_6_MS},
+ {10000, BMC150_ACCEL_SLEEP_10_MS},
+ {25000, BMC150_ACCEL_SLEEP_25_MS},
+ {50000, BMC150_ACCEL_SLEEP_50_MS},
+ {100000, BMC150_ACCEL_SLEEP_100_MS},
+ {500000, BMC150_ACCEL_SLEEP_500_MS},
+ {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
+
+
+static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
+ enum bmc150_power_modes mode,
+ int dur_us)
+{
+ int i;
+ int ret;
+ u8 lpw_bits;
+ int dur_val = -1;
+
+ if (dur_us > 0) {
+ for (i = 0; i < ARRAY_SIZE(bmc150_accel_sleep_value_table);
+ ++i) {
+ if (bmc150_accel_sleep_value_table[i].sleep_dur ==
+ dur_us)
+ dur_val =
+ bmc150_accel_sleep_value_table[i].reg_value;
+ }
+ } else
+ dur_val = 0;
+
+ if (dur_val < 0)
+ return -EINVAL;
+
+ lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
+ lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
+
+ dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
+ int val2)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
+ if (bmc150_accel_samp_freq_table[i].val == val &&
+ bmc150_accel_samp_freq_table[i].val2 == val2) {
+ ret = i2c_smbus_write_byte_data(
+ data->client,
+ BMC150_ACCEL_REG_PMU_BW,
+ bmc150_accel_samp_freq_table[i].bw_bits);
+ if (ret < 0)
+ return ret;
+
+ data->bw_bits =
+ bmc150_accel_samp_freq_table[i].bw_bits;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error: Reading chip id\n");
+ return ret;
+ }
+
+ dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
+ if (ret != data->chip_info->chip_id) {
+ dev_err(&data->client->dev, "Invalid chip %x\n", ret);
+ return -ENODEV;
+ }
+
+ ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Set Bandwidth */
+ ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Set Default Range */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_PMU_RANGE,
+ BMC150_ACCEL_DEF_RANGE_4G);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_pmu_range\n");
+ return ret;
+ }
+
+ data->range = BMC150_ACCEL_DEF_RANGE_4G;
+
+ /* Set default slope duration */
+ ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_5\n");
+ return ret;
+ }
+ data->slope_dur |= BMC150_ACCEL_DEF_SLOPE_DURATION;
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_5,
+ data->slope_dur);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_5\n");
+ return ret;
+ }
+ dev_dbg(&data->client->dev, "slope_dur %x\n", data->slope_dur);
+
+ /* Set default slope thresholds */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_6,
+ BMC150_ACCEL_DEF_SLOPE_THRESHOLD);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_6\n");
+ return ret;
+ }
+ data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD;
+ dev_dbg(&data->client->dev, "slope_thres %x\n", data->slope_thres);
+
+ /* Set default as latched interrupts */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_int_rst_latch\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_setup_any_motion_interrupt(
+ struct bmc150_accel_data *data,
+ bool status)
+{
+ int ret;
+
+ /* Enable/Disable INT1 mapping */
+ ret = i2c_smbus_read_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_MAP_0);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_map_0\n");
+ return ret;
+ }
+ if (status)
+ ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE;
+ else
+ ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_MAP_0,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_map_0\n");
+ return ret;
+ }
+
+ if (status) {
+ /* Set slope duration (no of samples) */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_5,
+ data->slope_dur);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error write reg_int_5\n");
+ return ret;
+ }
+
+ /* Set slope thresholds */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_6,
+ data->slope_thres);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error write reg_int_6\n");
+ return ret;
+ }
+
+ /*
+ * New data interrupt is always non-latched,
+ * which will have higher priority, so no need
+ * to set latched mode, we will be flooded anyway with INTR
+ */
+ if (!data->dready_trigger_on) {
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_int_rst_latch\n");
+ return ret;
+ }
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_EN_0,
+ BMC150_ACCEL_INT_EN_BIT_SLP_X |
+ BMC150_ACCEL_INT_EN_BIT_SLP_Y |
+ BMC150_ACCEL_INT_EN_BIT_SLP_Z);
+ } else
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_EN_0,
+ 0);
+
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_en_0\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data,
+ bool status)
+{
+ int ret;
+
+ /* Enable/Disable INT1 mapping */
+ ret = i2c_smbus_read_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_MAP_1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_map_1\n");
+ return ret;
+ }
+ if (status)
+ ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA;
+ else
+ ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_MAP_1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_map_1\n");
+ return ret;
+ }
+
+ if (status) {
+ /*
+ * Set non latched mode interrupt and clear any latched
+ * interrupt
+ */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_NON_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_int_rst_latch\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_EN_1,
+ BMC150_ACCEL_INT_EN_BIT_DATA_EN);
+
+ } else {
+ /* Restore default interrupt mode */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_int_rst_latch\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_EN_1,
+ 0);
+ }
+
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_en_1\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
+ int *val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
+ if (bmc150_accel_samp_freq_table[i].bw_bits == data->bw_bits) {
+ *val = bmc150_accel_samp_freq_table[i].val;
+ *val2 = bmc150_accel_samp_freq_table[i].val2;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ }
+
+ return -EINVAL;
+}
+
+#ifdef CONFIG_PM
+static int bmc150_accel_get_startup_times(struct bmc150_accel_data *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bmc150_accel_sample_upd_time); ++i) {
+ if (bmc150_accel_sample_upd_time[i].bw_bits == data->bw_bits)
+ return bmc150_accel_sample_upd_time[i].msec;
+ }
+
+ return BMC150_ACCEL_MAX_STARTUP_TIME_MS;
+}
+
+static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
+{
+ int ret;
+
+ if (on)
+ ret = pm_runtime_get_sync(&data->client->dev);
+ else {
+ pm_runtime_mark_last_busy(&data->client->dev);
+ ret = pm_runtime_put_autosuspend(&data->client->dev);
+ }
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Failed: bmc150_accel_set_power_state for %d\n", on);
+ if (on)
+ pm_runtime_put_noidle(&data->client->dev);
+
+ return ret;
+ }
+
+ return 0;
+}
+#else
+static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
+{
+ return 0;
+}
+#endif
+
+static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
+ if (data->chip_info->scale_table[i].scale == val) {
+ ret = i2c_smbus_write_byte_data(
+ data->client,
+ BMC150_ACCEL_REG_PMU_RANGE,
+ data->chip_info->scale_table[i].reg_range);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing pmu_range\n");
+ return ret;
+ }
+
+ data->range = data->chip_info->scale_table[i].reg_range;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
+{
+ int ret;
+
+ mutex_lock(&data->mutex);
+
+ ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_temp\n");
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ *val = sign_extend32(ret, 7);
+
+ mutex_unlock(&data->mutex);
+
+ return IIO_VAL_INT;
+}
+
+static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ int ret;
+ int axis = chan->scan_index;
+
+ mutex_lock(&data->mutex);
+ ret = bmc150_accel_set_power_state(data, true);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+
+ ret = i2c_smbus_read_word_data(data->client,
+ BMC150_ACCEL_AXIS_TO_REG(axis));
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading axis %d\n", axis);
+ bmc150_accel_set_power_state(data, false);
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ *val = sign_extend32(ret >> chan->scan_type.shift,
+ chan->scan_type.realbits - 1);
+ ret = bmc150_accel_set_power_state(data, false);
+ mutex_unlock(&data->mutex);
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+}
+
+static int bmc150_accel_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ switch (chan->type) {
+ case IIO_TEMP:
+ return bmc150_accel_get_temp(data, val);
+ case IIO_ACCEL:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+ else
+ return bmc150_accel_get_axis(data, chan, val);
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ if (chan->type == IIO_TEMP) {
+ *val = BMC150_ACCEL_TEMP_CENTER_VAL;
+ return IIO_VAL_INT;
+ } else
+ return -EINVAL;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val2 = 500000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_ACCEL:
+ {
+ int i;
+ const struct bmc150_scale_info *si;
+ int st_size = ARRAY_SIZE(data->chip_info->scale_table);
+
+ for (i = 0; i < st_size; ++i) {
+ si = &data->chip_info->scale_table[i];
+ if (si->reg_range == data->range) {
+ *val2 = si->scale;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ }
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = bmc150_accel_get_bw(data, val, val2);
+ mutex_unlock(&data->mutex);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int bmc150_accel_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = bmc150_accel_set_bw(data, val, val2);
+ mutex_unlock(&data->mutex);
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ if (val)
+ return -EINVAL;
+
+ mutex_lock(&data->mutex);
+ ret = bmc150_accel_set_scale(data, val2);
+ mutex_unlock(&data->mutex);
+ return ret;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int bmc150_accel_read_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int *val, int *val2)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ *val2 = 0;
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ *val = data->slope_thres;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ *val = data->slope_dur & BMC150_ACCEL_SLOPE_DUR_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return IIO_VAL_INT;
+}
+
+static int bmc150_accel_write_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int val, int val2)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ if (data->ev_enable_state)
+ return -EBUSY;
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ data->slope_thres = val;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ data->slope_dur &= ~BMC150_ACCEL_SLOPE_DUR_MASK;
+ data->slope_dur |= val & BMC150_ACCEL_SLOPE_DUR_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_read_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
+{
+
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ return data->ev_enable_state;
+}
+
+static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ int state)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (state && data->ev_enable_state)
+ return 0;
+
+ mutex_lock(&data->mutex);
+
+ if (!state && data->motion_trigger_on) {
+ data->ev_enable_state = 0;
+ mutex_unlock(&data->mutex);
+ return 0;
+ }
+
+ /*
+ * We will expect the enable and disable to do operation in
+ * in reverse order. This will happen here anyway as our
+ * resume operation uses sync mode runtime pm calls, the
+ * suspend operation will be delayed by autosuspend delay
+ * So the disable operation will still happen in reverse of
+ * enable operation. When runtime pm is disabled the mode
+ * is always on so sequence doesn't matter
+ */
+
+ ret = bmc150_accel_set_power_state(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+
+ ret = bmc150_accel_setup_any_motion_interrupt(data, state);
+ if (ret < 0) {
+ bmc150_accel_set_power_state(data, false);
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+
+ data->ev_enable_state = state;
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
+ struct iio_trigger *trig)
+{
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ if (data->dready_trig != trig && data->motion_trig != trig)
+ return -EINVAL;
+
+ return 0;
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
+ "7.810000 15.630000 31.250000 62.500000 125 250 500 1000");
+
+static struct attribute *bmc150_accel_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group bmc150_accel_attrs_group = {
+ .attrs = bmc150_accel_attributes,
+};
+
+static const struct iio_event_spec bmc150_accel_event = {
+ .type = IIO_EV_TYPE_ROC,
+ .dir = IIO_EV_DIR_EITHER,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_PERIOD)
+};
+
+#define BMC150_ACCEL_CHANNEL(_axis, bits) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = AXIS_##_axis, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .shift = 16 - (bits), \
+ }, \
+ .event_spec = &bmc150_accel_event, \
+ .num_event_specs = 1 \
+}
+
+#define BMC150_ACCEL_CHANNELS(bits) { \
+ { \
+ .type = IIO_TEMP, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_index = -1, \
+ }, \
+ BMC150_ACCEL_CHANNEL(X, bits), \
+ BMC150_ACCEL_CHANNEL(Y, bits), \
+ BMC150_ACCEL_CHANNEL(Z, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(3), \
+}
+
+static const struct iio_chan_spec bma222e_accel_channels[] =
+ BMC150_ACCEL_CHANNELS(8);
+static const struct iio_chan_spec bma250e_accel_channels[] =
+ BMC150_ACCEL_CHANNELS(10);
+static const struct iio_chan_spec bmc150_accel_channels[] =
+ BMC150_ACCEL_CHANNELS(12);
+static const struct iio_chan_spec bma280_accel_channels[] =
+ BMC150_ACCEL_CHANNELS(14);
+
+enum {
+ bmc150,
+ bmi055,
+ bma255,
+ bma250e,
+ bma222e,
+ bma280,
+};
+
+static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
+ [bmc150] = {
+ .chip_id = 0xFA,
+ .channels = bmc150_accel_channels,
+ .num_channels = ARRAY_SIZE(bmc150_accel_channels),
+ .scale_table = { {9610, BMC150_ACCEL_DEF_RANGE_2G},
+ {19122, BMC150_ACCEL_DEF_RANGE_4G},
+ {38344, BMC150_ACCEL_DEF_RANGE_8G},
+ {76590, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+ [bmi055] = {
+ .chip_id = 0xFA,
+ .channels = bmc150_accel_channels,
+ .num_channels = ARRAY_SIZE(bmc150_accel_channels),
+ .scale_table = { {9610, BMC150_ACCEL_DEF_RANGE_2G},
+ {19122, BMC150_ACCEL_DEF_RANGE_4G},
+ {38344, BMC150_ACCEL_DEF_RANGE_8G},
+ {76590, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+ [bma255] = {
+ .chip_id = 0xFA,
+ .channels = bmc150_accel_channels,
+ .num_channels = ARRAY_SIZE(bmc150_accel_channels),
+ .scale_table = { {9610, BMC150_ACCEL_DEF_RANGE_2G},
+ {19122, BMC150_ACCEL_DEF_RANGE_4G},
+ {38344, BMC150_ACCEL_DEF_RANGE_8G},
+ {76590, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+ [bma250e] = {
+ .chip_id = 0xF9,
+ .channels = bma250e_accel_channels,
+ .num_channels = ARRAY_SIZE(bma250e_accel_channels),
+ .scale_table = { {38344, BMC150_ACCEL_DEF_RANGE_2G},
+ {76590, BMC150_ACCEL_DEF_RANGE_4G},
+ {153277, BMC150_ACCEL_DEF_RANGE_8G},
+ {306457, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+ [bma222e] = {
+ .chip_id = 0xF8,
+ .channels = bma222e_accel_channels,
+ .num_channels = ARRAY_SIZE(bma222e_accel_channels),
+ .scale_table = { {153277, BMC150_ACCEL_DEF_RANGE_2G},
+ {306457, BMC150_ACCEL_DEF_RANGE_4G},
+ {612915, BMC150_ACCEL_DEF_RANGE_8G},
+ {1225831, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+ [bma280] = {
+ .chip_id = 0xFB,
+ .channels = bma280_accel_channels,
+ .num_channels = ARRAY_SIZE(bma280_accel_channels),
+ .scale_table = { {2392, BMC150_ACCEL_DEF_RANGE_2G},
+ {4785, BMC150_ACCEL_DEF_RANGE_4G},
+ {9581, BMC150_ACCEL_DEF_RANGE_8G},
+ {19152, BMC150_ACCEL_DEF_RANGE_16G} },
+ },
+};
+
+static const struct iio_info bmc150_accel_info = {
+ .attrs = &bmc150_accel_attrs_group,
+ .read_raw = bmc150_accel_read_raw,
+ .write_raw = bmc150_accel_write_raw,
+ .read_event_value = bmc150_accel_read_event,
+ .write_event_value = bmc150_accel_write_event,
+ .write_event_config = bmc150_accel_write_event_config,
+ .read_event_config = bmc150_accel_read_event_config,
+ .validate_trigger = bmc150_accel_validate_trigger,
+ .driver_module = THIS_MODULE,
+};
+
+static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int bit, ret, i = 0;
+
+ mutex_lock(&data->mutex);
+ for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ indio_dev->masklength) {
+ ret = i2c_smbus_read_word_data(data->client,
+ BMC150_ACCEL_AXIS_TO_REG(bit));
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ goto err_read;
+ }
+ data->buffer[i++] = ret;
+ }
+ mutex_unlock(&data->mutex);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ data->timestamp);
+err_read:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ /* new data interrupts don't need ack */
+ if (data->dready_trigger_on)
+ return 0;
+
+ mutex_lock(&data->mutex);
+ /* clear any latched interrupt */
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ mutex_unlock(&data->mutex);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_int_rst_latch\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+
+ if (!state && data->ev_enable_state && data->motion_trigger_on) {
+ data->motion_trigger_on = false;
+ mutex_unlock(&data->mutex);
+ return 0;
+ }
+
+ /*
+ * Refer to comment in bmc150_accel_write_event_config for
+ * enable/disable operation order
+ */
+ ret = bmc150_accel_set_power_state(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ if (data->motion_trig == trig)
+ ret = bmc150_accel_setup_any_motion_interrupt(data, state);
+ else
+ ret = bmc150_accel_setup_new_data_interrupt(data, state);
+ if (ret < 0) {
+ bmc150_accel_set_power_state(data, false);
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ if (data->motion_trig == trig)
+ data->motion_trigger_on = state;
+ else
+ data->dready_trigger_on = state;
+
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static const struct iio_trigger_ops bmc150_accel_trigger_ops = {
+ .set_trigger_state = bmc150_accel_data_rdy_trigger_set_state,
+ .try_reenable = bmc150_accel_trig_try_reen,
+ .owner = THIS_MODULE,
+};
+
+static irqreturn_t bmc150_accel_event_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+ int dir;
+
+ ret = i2c_smbus_read_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_STATUS_2);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
+ goto ack_intr_status;
+ }
+
+ if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
+ dir = IIO_EV_DIR_FALLING;
+ else
+ dir = IIO_EV_DIR_RISING;
+
+ if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
+ iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_X,
+ IIO_EV_TYPE_ROC,
+ dir),
+ data->timestamp);
+ if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
+ iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Y,
+ IIO_EV_TYPE_ROC,
+ dir),
+ data->timestamp);
+ if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
+ iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Z,
+ IIO_EV_TYPE_ROC,
+ dir),
+ data->timestamp);
+ack_intr_status:
+ if (!data->dready_trigger_on)
+ ret = i2c_smbus_write_byte_data(data->client,
+ BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t bmc150_accel_data_rdy_trig_poll(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ data->timestamp = iio_get_time_ns();
+
+ if (data->dready_trigger_on)
+ iio_trigger_poll(data->dready_trig);
+ else if (data->motion_trigger_on)
+ iio_trigger_poll(data->motion_trig);
+
+ if (data->ev_enable_state)
+ return IRQ_WAKE_THREAD;
+ else
+ return IRQ_HANDLED;
+}
+
+static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
+{
+ const struct acpi_device_id *id;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+
+ if (!id)
+ return NULL;
+
+ *data = (int) id->driver_data;
+
+ return dev_name(dev);
+}
+
+static int bmc150_accel_gpio_probe(struct i2c_client *client,
+ struct bmc150_accel_data *data)
+{
+ struct device *dev;
+ struct gpio_desc *gpio;
+ int ret;
+
+ if (!client)
+ return -EINVAL;
+
+ dev = &client->dev;
+
+ /* data ready gpio interrupt pin */
+ gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0);
+ if (IS_ERR(gpio)) {
+ dev_err(dev, "Failed: gpio get index\n");
+ return PTR_ERR(gpio);
+ }
+
+ ret = gpiod_direction_input(gpio);
+ if (ret)
+ return ret;
+
+ ret = gpiod_to_irq(gpio);
+
+ dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+ return ret;
+}
+
+static int bmc150_accel_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bmc150_accel_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+ const char *name = NULL;
+ int chip_id = 0;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ if (id) {
+ name = id->name;
+ chip_id = id->driver_data;
+ }
+
+ if (ACPI_HANDLE(&client->dev))
+ name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
+
+ data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
+
+ ret = bmc150_accel_chip_init(data);
+ if (ret < 0)
+ return ret;
+
+ mutex_init(&data->mutex);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = data->chip_info->channels;
+ indio_dev->num_channels = data->chip_info->num_channels;
+ indio_dev->name = name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &bmc150_accel_info;
+
+ if (client->irq < 0)
+ client->irq = bmc150_accel_gpio_probe(client, data);
+
+ if (client->irq >= 0) {
+ ret = devm_request_threaded_irq(
+ &client->dev, client->irq,
+ bmc150_accel_data_rdy_trig_poll,
+ bmc150_accel_event_handler,
+ IRQF_TRIGGER_RISING,
+ BMC150_ACCEL_IRQ_NAME,
+ indio_dev);
+ if (ret)
+ return ret;
+
+ data->dready_trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-dev%d",
+ indio_dev->name,
+ indio_dev->id);
+ if (!data->dready_trig)
+ return -ENOMEM;
+
+ data->motion_trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-any-motion-dev%d",
+ indio_dev->name,
+ indio_dev->id);
+ if (!data->motion_trig)
+ return -ENOMEM;
+
+ data->dready_trig->dev.parent = &client->dev;
+ data->dready_trig->ops = &bmc150_accel_trigger_ops;
+ iio_trigger_set_drvdata(data->dready_trig, indio_dev);
+ ret = iio_trigger_register(data->dready_trig);
+ if (ret)
+ return ret;
+
+ data->motion_trig->dev.parent = &client->dev;
+ data->motion_trig->ops = &bmc150_accel_trigger_ops;
+ iio_trigger_set_drvdata(data->motion_trig, indio_dev);
+ ret = iio_trigger_register(data->motion_trig);
+ if (ret) {
+ data->motion_trig = NULL;
+ goto err_trigger_unregister;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev,
+ &iio_pollfunc_store_time,
+ bmc150_accel_trigger_handler,
+ NULL);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "Failed: iio triggered buffer setup\n");
+ goto err_trigger_unregister;
+ }
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "Unable to register iio device\n");
+ goto err_buffer_cleanup;
+ }
+
+ ret = pm_runtime_set_active(&client->dev);
+ if (ret)
+ goto err_iio_unregister;
+
+ pm_runtime_enable(&client->dev);
+ pm_runtime_set_autosuspend_delay(&client->dev,
+ BMC150_AUTO_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&client->dev);
+
+ return 0;
+
+err_iio_unregister:
+ iio_device_unregister(indio_dev);
+err_buffer_cleanup:
+ if (data->dready_trig)
+ iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+ if (data->dready_trig)
+ iio_trigger_unregister(data->dready_trig);
+ if (data->motion_trig)
+ iio_trigger_unregister(data->motion_trig);
+
+ return ret;
+}
+
+static int bmc150_accel_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ iio_device_unregister(indio_dev);
+
+ if (data->dready_trig) {
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_trigger_unregister(data->dready_trig);
+ iio_trigger_unregister(data->motion_trig);
+ }
+
+ mutex_lock(&data->mutex);
+ bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int bmc150_accel_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+ bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static int bmc150_accel_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+ if (data->dready_trigger_on || data->motion_trigger_on ||
+ data->ev_enable_state)
+ bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int bmc150_accel_runtime_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+
+ dev_dbg(&data->client->dev, __func__);
+ ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
+ if (ret < 0)
+ return -EAGAIN;
+
+ return 0;
+}
+
+static int bmc150_accel_runtime_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct bmc150_accel_data *data = iio_priv(indio_dev);
+ int ret;
+ int sleep_val;
+
+ dev_dbg(&data->client->dev, __func__);
+
+ ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+ if (ret < 0)
+ return ret;
+
+ sleep_val = bmc150_accel_get_startup_times(data);
+ if (sleep_val < 20)
+ usleep_range(sleep_val * 1000, 20000);
+ else
+ msleep_interruptible(sleep_val);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops bmc150_accel_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
+ SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
+ bmc150_accel_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id bmc150_accel_acpi_match[] = {
+ {"BSBA0150", bmc150},
+ {"BMC150A", bmc150},
+ {"BMI055A", bmi055},
+ {"BMA0255", bma255},
+ {"BMA250E", bma250e},
+ {"BMA222E", bma222e},
+ {"BMA0280", bma280},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
+
+static const struct i2c_device_id bmc150_accel_id[] = {
+ {"bmc150_accel", bmc150},
+ {"bmi055_accel", bmi055},
+ {"bma255", bma255},
+ {"bma250e", bma250e},
+ {"bma222e", bma222e},
+ {"bma280", bma280},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
+
+static struct i2c_driver bmc150_accel_driver = {
+ .driver = {
+ .name = BMC150_ACCEL_DRV_NAME,
+ .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+ .pm = &bmc150_accel_pm_ops,
+ },
+ .probe = bmc150_accel_probe,
+ .remove = bmc150_accel_remove,
+ .id_table = bmc150_accel_id,
+};
+module_i2c_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 accelerometer driver");
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
new file mode 100644
index 0000000..d5d9531
--- /dev/null
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -0,0 +1,430 @@
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+enum accel_3d_channel {
+ CHANNEL_SCAN_INDEX_X,
+ CHANNEL_SCAN_INDEX_Y,
+ CHANNEL_SCAN_INDEX_Z,
+ ACCEL_3D_CHANNEL_MAX,
+};
+
+struct accel_3d_state {
+ struct hid_sensor_hub_callbacks callbacks;
+ struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX];
+ u32 accel_val[ACCEL_3D_CHANNEL_MAX];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
+};
+
+static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = {
+ HID_USAGE_SENSOR_ACCEL_X_AXIS,
+ HID_USAGE_SENSOR_ACCEL_Y_AXIS,
+ HID_USAGE_SENSOR_ACCEL_Z_AXIS
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec accel_3d_channels[] = {
+ {
+ .type = IIO_ACCEL,
+ .modified = 1,
+ .channel2 = IIO_MOD_X,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_X,
+ }, {
+ .type = IIO_ACCEL,
+ .modified = 1,
+ .channel2 = IIO_MOD_Y,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_Y,
+ }, {
+ .type = IIO_ACCEL,
+ .modified = 1,
+ .channel2 = IIO_MOD_Z,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_Z,
+ }
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void accel_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
+ int channel, int size)
+{
+ channels[channel].scan_type.sign = 's';
+ /* Real storage bits will change based on the report desc. */
+ channels[channel].scan_type.realbits = size * 8;
+ /* Maximum size of a sample to capture is u32 */
+ channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+}
+
+/* Channel read_raw handler */
+static int accel_3d_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2,
+ long mask)
+{
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
+ int report_id = -1;
+ u32 address;
+ int ret_type;
+ s32 poll_value;
+
+ *val = 0;
+ *val2 = 0;
+ switch (mask) {
+ case 0:
+ poll_value = hid_sensor_read_poll_value(
+ &accel_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&accel_state->common_attributes, true);
+ msleep_interruptible(poll_value * 2);
+ report_id = accel_state->accel[chan->scan_index].report_id;
+ address = accel_3d_addresses[chan->scan_index];
+ if (report_id >= 0)
+ *val = sensor_hub_input_attr_get_raw_value(
+ accel_state->common_attributes.hsdev,
+ HID_USAGE_SENSOR_ACCEL_3D, address,
+ report_id);
+ else {
+ *val = 0;
+ hid_sensor_power_state(&accel_state->common_attributes,
+ false);
+ return -EINVAL;
+ }
+ hid_sensor_power_state(&accel_state->common_attributes, false);
+ ret_type = IIO_VAL_INT;
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ *val = accel_state->scale_pre_decml;
+ *val2 = accel_state->scale_post_decml;
+ ret_type = accel_state->scale_precision;
+ break;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = accel_state->value_offset;
+ ret_type = IIO_VAL_INT;
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret_type = hid_sensor_read_samp_freq_value(
+ &accel_state->common_attributes, val, val2);
+ break;
+ case IIO_CHAN_INFO_HYSTERESIS:
+ ret_type = hid_sensor_read_raw_hyst_value(
+ &accel_state->common_attributes, val, val2);
+ break;
+ default:
+ ret_type = -EINVAL;
+ break;
+ }
+
+ return ret_type;
+}
+
+/* Channel write_raw handler */
+static int accel_3d_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
+ int ret = 0;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = hid_sensor_write_samp_freq_value(
+ &accel_state->common_attributes, val, val2);
+ break;
+ case IIO_CHAN_INFO_HYSTERESIS:
+ ret = hid_sensor_write_raw_hyst_value(
+ &accel_state->common_attributes, val, val2);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct iio_info accel_3d_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &accel_3d_read_raw,
+ .write_raw = &accel_3d_write_raw,
+};
+
+/* Function to push data to buffer */
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+ int len)
+{
+ dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
+ iio_push_to_buffers(indio_dev, data);
+}
+
+/* Callback handler to send event after all samples are received and captured */
+static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
+ unsigned usage_id,
+ void *priv)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(priv);
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
+
+ dev_dbg(&indio_dev->dev, "accel_3d_proc_event\n");
+ if (atomic_read(&accel_state->common_attributes.data_ready))
+ hid_sensor_push_data(indio_dev,
+ accel_state->accel_val,
+ sizeof(accel_state->accel_val));
+
+ return 0;
+}
+
+/* Capture samples in local storage */
+static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
+ unsigned usage_id,
+ size_t raw_len, char *raw_data,
+ void *priv)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(priv);
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
+ int offset;
+ int ret = -EINVAL;
+
+ switch (usage_id) {
+ case HID_USAGE_SENSOR_ACCEL_X_AXIS:
+ case HID_USAGE_SENSOR_ACCEL_Y_AXIS:
+ case HID_USAGE_SENSOR_ACCEL_Z_AXIS:
+ offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS;
+ accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] =
+ *(u32 *)raw_data;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/* Parse report which is specific to an usage id*/
+static int accel_3d_parse_report(struct platform_device *pdev,
+ struct hid_sensor_hub_device *hsdev,
+ struct iio_chan_spec *channels,
+ unsigned usage_id,
+ struct accel_3d_state *st)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
+ ret = sensor_hub_input_get_attribute_info(hsdev,
+ HID_INPUT_REPORT,
+ usage_id,
+ HID_USAGE_SENSOR_ACCEL_X_AXIS + i,
+ &st->accel[CHANNEL_SCAN_INDEX_X + i]);
+ if (ret < 0)
+ break;
+ accel_3d_adjust_channel_bit_mask(channels,
+ CHANNEL_SCAN_INDEX_X + i,
+ st->accel[CHANNEL_SCAN_INDEX_X + i].size);
+ }
+ dev_dbg(&pdev->dev, "accel_3d %x:%x, %x:%x, %x:%x\n",
+ st->accel[0].index,
+ st->accel[0].report_id,
+ st->accel[1].index, st->accel[1].report_id,
+ st->accel[2].index, st->accel[2].report_id);
+
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_ACCEL_3D,
+ &st->accel[CHANNEL_SCAN_INDEX_X],
+ &st->scale_pre_decml, &st->scale_post_decml);
+
+ /* Set Sensitivity field ids, when there is no individual modifier */
+ if (st->common_attributes.sensitivity.index < 0) {
+ sensor_hub_input_get_attribute_info(hsdev,
+ HID_FEATURE_REPORT, usage_id,
+ HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+ HID_USAGE_SENSOR_DATA_ACCELERATION,
+ &st->common_attributes.sensitivity);
+ dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+ st->common_attributes.sensitivity.index,
+ st->common_attributes.sensitivity.report_id);
+ }
+
+ return ret;
+}
+
+/* Function to initialize the processing for usage id */
+static int hid_accel_3d_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ static const char *name = "accel_3d";
+ struct iio_dev *indio_dev;
+ struct accel_3d_state *accel_state;
+ struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+ struct iio_chan_spec *channels;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev,
+ sizeof(struct accel_3d_state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ accel_state = iio_priv(indio_dev);
+ accel_state->common_attributes.hsdev = hsdev;
+ accel_state->common_attributes.pdev = pdev;
+
+ ret = hid_sensor_parse_common_attributes(hsdev,
+ HID_USAGE_SENSOR_ACCEL_3D,
+ &accel_state->common_attributes);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to setup common attributes\n");
+ return ret;
+ }
+
+ channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
+ GFP_KERNEL);
+ if (!channels) {
+ dev_err(&pdev->dev, "failed to duplicate channels\n");
+ return -ENOMEM;
+ }
+
+ ret = accel_3d_parse_report(pdev, hsdev, channels,
+ HID_USAGE_SENSOR_ACCEL_3D, accel_state);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to setup attributes\n");
+ goto error_free_dev_mem;
+ }
+
+ indio_dev->channels = channels;
+ indio_dev->num_channels = ARRAY_SIZE(accel_3d_channels);
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->info = &accel_3d_info;
+ indio_dev->name = name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ NULL, NULL);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
+ goto error_free_dev_mem;
+ }
+ atomic_set(&accel_state->common_attributes.data_ready, 0);
+ ret = hid_sensor_setup_trigger(indio_dev, name,
+ &accel_state->common_attributes);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "trigger setup failed\n");
+ goto error_unreg_buffer_funcs;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "device register failed\n");
+ goto error_remove_trigger;
+ }
+
+ accel_state->callbacks.send_event = accel_3d_proc_event;
+ accel_state->callbacks.capture_sample = accel_3d_capture_sample;
+ accel_state->callbacks.pdev = pdev;
+ ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D,
+ &accel_state->callbacks);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "callback reg failed\n");
+ goto error_iio_unreg;
+ }
+
+ return ret;
+
+error_iio_unreg:
+ iio_device_unregister(indio_dev);
+error_remove_trigger:
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
+error_unreg_buffer_funcs:
+ iio_triggered_buffer_cleanup(indio_dev);
+error_free_dev_mem:
+ kfree(indio_dev->channels);
+ return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_accel_3d_remove(struct platform_device *pdev)
+{
+ struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct accel_3d_state *accel_state = iio_priv(indio_dev);
+
+ sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D);
+ iio_device_unregister(indio_dev);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
+ iio_triggered_buffer_cleanup(indio_dev);
+ kfree(indio_dev->channels);
+
+ return 0;
+}
+
+static struct platform_device_id hid_accel_3d_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-200073",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
+
+static struct platform_driver hid_accel_3d_platform_driver = {
+ .id_table = hid_accel_3d_ids,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ },
+ .probe = hid_accel_3d_probe,
+ .remove = hid_accel_3d_remove,
+};
+module_platform_driver(hid_accel_3d_platform_driver);
+
+MODULE_DESCRIPTION("HID Sensor Accel 3D");
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
new file mode 100644
index 0000000..da2fe93
--- /dev/null
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -0,0 +1,1429 @@
+/*
+ * KXCJK-1013 3-axis accelerometer driver
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/events.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/accel/kxcjk_1013.h>
+
+#define KXCJK1013_DRV_NAME "kxcjk1013"
+#define KXCJK1013_IRQ_NAME "kxcjk1013_event"
+
+#define KXCJK1013_REG_XOUT_L 0x06
+/*
+ * From low byte X axis register, all the other addresses of Y and Z can be
+ * obtained by just applying axis offset. The following axis defines are just
+ * provide clarity, but not used.
+ */
+#define KXCJK1013_REG_XOUT_H 0x07
+#define KXCJK1013_REG_YOUT_L 0x08
+#define KXCJK1013_REG_YOUT_H 0x09
+#define KXCJK1013_REG_ZOUT_L 0x0A
+#define KXCJK1013_REG_ZOUT_H 0x0B
+
+#define KXCJK1013_REG_DCST_RESP 0x0C
+#define KXCJK1013_REG_WHO_AM_I 0x0F
+#define KXCJK1013_REG_INT_SRC1 0x16
+#define KXCJK1013_REG_INT_SRC2 0x17
+#define KXCJK1013_REG_STATUS_REG 0x18
+#define KXCJK1013_REG_INT_REL 0x1A
+#define KXCJK1013_REG_CTRL1 0x1B
+#define KXCJK1013_REG_CTRL2 0x1D
+#define KXCJK1013_REG_INT_CTRL1 0x1E
+#define KXCJK1013_REG_INT_CTRL2 0x1F
+#define KXCJK1013_REG_DATA_CTRL 0x21
+#define KXCJK1013_REG_WAKE_TIMER 0x29
+#define KXCJK1013_REG_SELF_TEST 0x3A
+#define KXCJK1013_REG_WAKE_THRES 0x6A
+
+#define KXCJK1013_REG_CTRL1_BIT_PC1 BIT(7)
+#define KXCJK1013_REG_CTRL1_BIT_RES BIT(6)
+#define KXCJK1013_REG_CTRL1_BIT_DRDY BIT(5)
+#define KXCJK1013_REG_CTRL1_BIT_GSEL1 BIT(4)
+#define KXCJK1013_REG_CTRL1_BIT_GSEL0 BIT(3)
+#define KXCJK1013_REG_CTRL1_BIT_WUFE BIT(1)
+#define KXCJK1013_REG_INT_REG1_BIT_IEA BIT(4)
+#define KXCJK1013_REG_INT_REG1_BIT_IEN BIT(5)
+
+#define KXCJK1013_DATA_MASK_12_BIT 0x0FFF
+#define KXCJK1013_MAX_STARTUP_TIME_US 100000
+
+#define KXCJK1013_SLEEP_DELAY_MS 2000
+
+#define KXCJK1013_REG_INT_SRC2_BIT_ZP BIT(0)
+#define KXCJK1013_REG_INT_SRC2_BIT_ZN BIT(1)
+#define KXCJK1013_REG_INT_SRC2_BIT_YP BIT(2)
+#define KXCJK1013_REG_INT_SRC2_BIT_YN BIT(3)
+#define KXCJK1013_REG_INT_SRC2_BIT_XP BIT(4)
+#define KXCJK1013_REG_INT_SRC2_BIT_XN BIT(5)
+
+#define KXCJK1013_DEFAULT_WAKE_THRES 1
+
+enum kx_chipset {
+ KXCJK1013,
+ KXCJ91008,
+ KXTJ21009,
+ KX_MAX_CHIPS /* this must be last */
+};
+
+struct kxcjk1013_data {
+ struct i2c_client *client;
+ struct iio_trigger *dready_trig;
+ struct iio_trigger *motion_trig;
+ struct mutex mutex;
+ s16 buffer[8];
+ u8 odr_bits;
+ u8 range;
+ int wake_thres;
+ int wake_dur;
+ bool active_high_intr;
+ bool dready_trigger_on;
+ int ev_enable_state;
+ bool motion_trigger_on;
+ int64_t timestamp;
+ enum kx_chipset chipset;
+};
+
+enum kxcjk1013_axis {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_Z,
+};
+
+enum kxcjk1013_mode {
+ STANDBY,
+ OPERATION,
+};
+
+enum kxcjk1013_range {
+ KXCJK1013_RANGE_2G,
+ KXCJK1013_RANGE_4G,
+ KXCJK1013_RANGE_8G,
+};
+
+static const struct {
+ int val;
+ int val2;
+ int odr_bits;
+} samp_freq_table[] = { {0, 781000, 0x08}, {1, 563000, 0x09},
+ {3, 125000, 0x0A}, {6, 250000, 0x0B}, {12, 500000, 0},
+ {25, 0, 0x01}, {50, 0, 0x02}, {100, 0, 0x03},
+ {200, 0, 0x04}, {400, 0, 0x05}, {800, 0, 0x06},
+ {1600, 0, 0x07} };
+
+/* Refer to section 4 of the specification */
+static const struct {
+ int odr_bits;
+ int usec;
+} odr_start_up_times[KX_MAX_CHIPS][12] = {
+ /* KXCJK-1013 */
+ {
+ {0x08, 100000},
+ {0x09, 100000},
+ {0x0A, 100000},
+ {0x0B, 100000},
+ {0, 80000},
+ {0x01, 41000},
+ {0x02, 21000},
+ {0x03, 11000},
+ {0x04, 6400},
+ {0x05, 3900},
+ {0x06, 2700},
+ {0x07, 2100},
+ },
+ /* KXCJ9-1008 */
+ {
+ {0x08, 100000},
+ {0x09, 100000},
+ {0x0A, 100000},
+ {0x0B, 100000},
+ {0, 80000},
+ {0x01, 41000},
+ {0x02, 21000},
+ {0x03, 11000},
+ {0x04, 6400},
+ {0x05, 3900},
+ {0x06, 2700},
+ {0x07, 2100},
+ },
+ /* KXCTJ2-1009 */
+ {
+ {0x08, 1240000},
+ {0x09, 621000},
+ {0x0A, 309000},
+ {0x0B, 151000},
+ {0, 80000},
+ {0x01, 41000},
+ {0x02, 21000},
+ {0x03, 11000},
+ {0x04, 6000},
+ {0x05, 4000},
+ {0x06, 3000},
+ {0x07, 2000},
+ },
+};
+
+static const struct {
+ u16 scale;
+ u8 gsel_0;
+ u8 gsel_1;
+} KXCJK1013_scale_table[] = { {9582, 0, 0},
+ {19163, 1, 0},
+ {38326, 0, 1} };
+
+static const struct {
+ int val;
+ int val2;
+ int odr_bits;
+} wake_odr_data_rate_table[] = { {0, 781000, 0x00},
+ {1, 563000, 0x01},
+ {3, 125000, 0x02},
+ {6, 250000, 0x03},
+ {12, 500000, 0x04},
+ {25, 0, 0x05},
+ {50, 0, 0x06},
+ {100, 0, 0x06},
+ {200, 0, 0x06},
+ {400, 0, 0x06},
+ {800, 0, 0x06},
+ {1600, 0, 0x06} };
+
+static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
+ enum kxcjk1013_mode mode)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (mode == STANDBY)
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_PC1;
+ else
+ ret |= KXCJK1013_REG_CTRL1_BIT_PC1;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1, ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_get_mode(struct kxcjk1013_data *data,
+ enum kxcjk1013_mode *mode)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (ret & KXCJK1013_REG_CTRL1_BIT_PC1)
+ *mode = OPERATION;
+ else
+ *mode = STANDBY;
+
+ return 0;
+}
+
+static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ ret &= ~(KXCJK1013_REG_CTRL1_BIT_GSEL0 |
+ KXCJK1013_REG_CTRL1_BIT_GSEL1);
+ ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3);
+ ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4);
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ data->range = range_index;
+
+ return 0;
+}
+
+static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading who_am_i\n");
+ return ret;
+ }
+
+ dev_dbg(&data->client->dev, "KXCJK1013 Chip Id %x\n", ret);
+
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ /* Set 12 bit mode */
+ ret |= KXCJK1013_REG_CTRL1_BIT_RES;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl\n");
+ return ret;
+ }
+
+ /* Setting range to 4G */
+ ret = kxcjk1013_set_range(data, KXCJK1013_RANGE_4G);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_data_ctrl\n");
+ return ret;
+ }
+
+ data->odr_bits = ret;
+
+ /* Set up INT polarity */
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+ return ret;
+ }
+
+ if (data->active_high_intr)
+ ret |= KXCJK1013_REG_INT_REG1_BIT_IEA;
+ else
+ ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEA;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+ return ret;
+ }
+
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+
+ data->wake_thres = KXCJK1013_DEFAULT_WAKE_THRES;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
+{
+ int i;
+ int idx = data->chipset;
+
+ for (i = 0; i < ARRAY_SIZE(odr_start_up_times[idx]); ++i) {
+ if (odr_start_up_times[idx][i].odr_bits == data->odr_bits)
+ return odr_start_up_times[idx][i].usec;
+ }
+
+ return KXCJK1013_MAX_STARTUP_TIME_US;
+}
+#endif
+
+static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
+{
+ int ret;
+
+ if (on)
+ ret = pm_runtime_get_sync(&data->client->dev);
+ else {
+ pm_runtime_mark_last_busy(&data->client->dev);
+ ret = pm_runtime_put_autosuspend(&data->client->dev);
+ }
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Failed: kxcjk1013_set_power_state for %d\n", on);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_WAKE_TIMER,
+ data->wake_dur);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error writing reg_wake_timer\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_WAKE_THRES,
+ data->wake_thres);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_wake_thres\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data,
+ bool status)
+{
+ int ret;
+ enum kxcjk1013_mode store_mode;
+
+ ret = kxcjk1013_get_mode(data, &store_mode);
+ if (ret < 0)
+ return ret;
+
+ /* This is requirement by spec to change state to STANDBY */
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = kxcjk1013_chip_update_thresholds(data);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
+ else
+ ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_CTRL1_BIT_WUFE;
+ else
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_WUFE;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1, ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ if (store_mode == OPERATION) {
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data,
+ bool status)
+{
+ int ret;
+ enum kxcjk1013_mode store_mode;
+
+ ret = kxcjk1013_get_mode(data, &store_mode);
+ if (ret < 0)
+ return ret;
+
+ /* This is requirement by spec to change state to STANDBY */
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
+ else
+ ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_CTRL1_BIT_DRDY;
+ else
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_DRDY;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1, ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ if (store_mode == OPERATION) {
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_convert_freq_to_bit(int val, int val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) {
+ if (samp_freq_table[i].val == val &&
+ samp_freq_table[i].val2 == val2) {
+ return samp_freq_table[i].odr_bits;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_convert_wake_odr_to_bit(int val, int val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wake_odr_data_rate_table); ++i) {
+ if (wake_odr_data_rate_table[i].val == val &&
+ wake_odr_data_rate_table[i].val2 == val2) {
+ return wake_odr_data_rate_table[i].odr_bits;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
+{
+ int ret;
+ int odr_bits;
+ enum kxcjk1013_mode store_mode;
+
+ ret = kxcjk1013_get_mode(data, &store_mode);
+ if (ret < 0)
+ return ret;
+
+ odr_bits = kxcjk1013_convert_freq_to_bit(val, val2);
+ if (odr_bits < 0)
+ return odr_bits;
+
+ /* To change ODR, the chip must be set to STANDBY as per spec */
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_DATA_CTRL,
+ odr_bits);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing data_ctrl\n");
+ return ret;
+ }
+
+ data->odr_bits = odr_bits;
+
+ odr_bits = kxcjk1013_convert_wake_odr_to_bit(val, val2);
+ if (odr_bits < 0)
+ return odr_bits;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL2,
+ odr_bits);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl2\n");
+ return ret;
+ }
+
+ if (store_mode == OPERATION) {
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_get_odr(struct kxcjk1013_data *data, int *val, int *val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) {
+ if (samp_freq_table[i].odr_bits == data->odr_bits) {
+ *val = samp_freq_table[i].val;
+ *val2 = samp_freq_table[i].val2;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis)
+{
+ u8 reg = KXCJK1013_REG_XOUT_L + axis * 2;
+ int ret;
+
+ ret = i2c_smbus_read_word_data(data->client, reg);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "failed to read accel_%c registers\n", 'x' + axis);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val)
+{
+ int ret, i;
+ enum kxcjk1013_mode store_mode;
+
+
+ for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
+ if (KXCJK1013_scale_table[i].scale == val) {
+
+ ret = kxcjk1013_get_mode(data, &store_mode);
+ if (ret < 0)
+ return ret;
+
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = kxcjk1013_set_range(data, i);
+ if (ret < 0)
+ return ret;
+
+ if (store_mode == OPERATION) {
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&data->mutex);
+ if (iio_buffer_enabled(indio_dev))
+ ret = -EBUSY;
+ else {
+ ret = kxcjk1013_set_power_state(data, true);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ ret = kxcjk1013_get_acc_reg(data, chan->scan_index);
+ if (ret < 0) {
+ kxcjk1013_set_power_state(data, false);
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ *val = sign_extend32(ret >> 4, 11);
+ ret = kxcjk1013_set_power_state(data, false);
+ }
+ mutex_unlock(&data->mutex);
+
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = KXCJK1013_scale_table[data->range].scale;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_get_odr(data, val, val2);
+ mutex_unlock(&data->mutex);
+ return ret;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int kxcjk1013_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val,
+ int val2, long mask)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_set_odr(data, val, val2);
+ mutex_unlock(&data->mutex);
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ if (val)
+ return -EINVAL;
+
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_set_scale(data, val2);
+ mutex_unlock(&data->mutex);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int kxcjk1013_read_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int *val, int *val2)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ *val2 = 0;
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ *val = data->wake_thres;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ *val = data->wake_dur;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return IIO_VAL_INT;
+}
+
+static int kxcjk1013_write_event(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int val, int val2)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ if (data->ev_enable_state)
+ return -EBUSY;
+
+ switch (info) {
+ case IIO_EV_INFO_VALUE:
+ data->wake_thres = val;
+ break;
+ case IIO_EV_INFO_PERIOD:
+ data->wake_dur = val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_read_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
+{
+
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ return data->ev_enable_state;
+}
+
+static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ int state)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (state && data->ev_enable_state)
+ return 0;
+
+ mutex_lock(&data->mutex);
+
+ if (!state && data->motion_trigger_on) {
+ data->ev_enable_state = 0;
+ mutex_unlock(&data->mutex);
+ return 0;
+ }
+
+ /*
+ * We will expect the enable and disable to do operation in
+ * in reverse order. This will happen here anyway as our
+ * resume operation uses sync mode runtime pm calls, the
+ * suspend operation will be delayed by autosuspend delay
+ * So the disable operation will still happen in reverse of
+ * enable operation. When runtime pm is disabled the mode
+ * is always on so sequence doesn't matter
+ */
+ ret = kxcjk1013_set_power_state(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+
+ ret = kxcjk1013_setup_any_motion_interrupt(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+
+ data->ev_enable_state = state;
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev,
+ struct iio_trigger *trig)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ if (data->dready_trig != trig && data->motion_trig != trig)
+ return -EINVAL;
+
+ return 0;
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
+ "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600");
+
+static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019163 0.038326");
+
+static struct attribute *kxcjk1013_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_const_attr_in_accel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group kxcjk1013_attrs_group = {
+ .attrs = kxcjk1013_attributes,
+};
+
+static const struct iio_event_spec kxcjk1013_event = {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_EITHER,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+ BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_PERIOD)
+};
+
+#define KXCJK1013_CHANNEL(_axis) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = AXIS_##_axis, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_CPU, \
+ }, \
+ .event_spec = &kxcjk1013_event, \
+ .num_event_specs = 1 \
+}
+
+static const struct iio_chan_spec kxcjk1013_channels[] = {
+ KXCJK1013_CHANNEL(X),
+ KXCJK1013_CHANNEL(Y),
+ KXCJK1013_CHANNEL(Z),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_info kxcjk1013_info = {
+ .attrs = &kxcjk1013_attrs_group,
+ .read_raw = kxcjk1013_read_raw,
+ .write_raw = kxcjk1013_write_raw,
+ .read_event_value = kxcjk1013_read_event,
+ .write_event_value = kxcjk1013_write_event,
+ .write_event_config = kxcjk1013_write_event_config,
+ .read_event_config = kxcjk1013_read_event_config,
+ .validate_trigger = kxcjk1013_validate_trigger,
+ .driver_module = THIS_MODULE,
+};
+
+static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int bit, ret, i = 0;
+
+ mutex_lock(&data->mutex);
+
+ for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ indio_dev->masklength) {
+ ret = kxcjk1013_get_acc_reg(data, bit);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ goto err;
+ }
+ data->buffer[i++] = ret;
+ }
+ mutex_unlock(&data->mutex);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ data->timestamp);
+err:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int kxcjk1013_trig_try_reen(struct iio_trigger *trig)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_rel\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+
+ if (!state && data->ev_enable_state && data->motion_trigger_on) {
+ data->motion_trigger_on = false;
+ mutex_unlock(&data->mutex);
+ return 0;
+ }
+
+ ret = kxcjk1013_set_power_state(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ if (data->motion_trig == trig)
+ ret = kxcjk1013_setup_any_motion_interrupt(data, state);
+ else
+ ret = kxcjk1013_setup_new_data_interrupt(data, state);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ if (data->motion_trig == trig)
+ data->motion_trigger_on = state;
+ else
+ data->dready_trigger_on = state;
+
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static const struct iio_trigger_ops kxcjk1013_trigger_ops = {
+ .set_trigger_state = kxcjk1013_data_rdy_trigger_set_state,
+ .try_reenable = kxcjk1013_trig_try_reen,
+ .owner = THIS_MODULE,
+};
+
+static irqreturn_t kxcjk1013_event_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_SRC1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_src1\n");
+ goto ack_intr;
+ }
+
+ if (ret & 0x02) {
+ ret = i2c_smbus_read_byte_data(data->client,
+ KXCJK1013_REG_INT_SRC2);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "Error reading reg_int_src2\n");
+ goto ack_intr;
+ }
+
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_XN)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_X,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_FALLING),
+ data->timestamp);
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_XP)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_X,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING),
+ data->timestamp);
+
+
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_YN)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Y,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_FALLING),
+ data->timestamp);
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_YP)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Y,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING),
+ data->timestamp);
+
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZN)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Z,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_FALLING),
+ data->timestamp);
+ if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZP)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
+ 0,
+ IIO_MOD_Z,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING),
+ data->timestamp);
+ }
+
+ack_intr:
+ if (data->dready_trigger_on)
+ return IRQ_HANDLED;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL);
+ if (ret < 0)
+ dev_err(&data->client->dev, "Error reading reg_int_rel\n");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ data->timestamp = iio_get_time_ns();
+
+ if (data->dready_trigger_on)
+ iio_trigger_poll(data->dready_trig);
+ else if (data->motion_trigger_on)
+ iio_trigger_poll(data->motion_trig);
+
+ if (data->ev_enable_state)
+ return IRQ_WAKE_THREAD;
+ else
+ return IRQ_HANDLED;
+}
+
+static const char *kxcjk1013_match_acpi_device(struct device *dev,
+ enum kx_chipset *chipset)
+{
+ const struct acpi_device_id *id;
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return NULL;
+ *chipset = (enum kx_chipset)id->driver_data;
+
+ return dev_name(dev);
+}
+
+static int kxcjk1013_gpio_probe(struct i2c_client *client,
+ struct kxcjk1013_data *data)
+{
+ struct device *dev;
+ struct gpio_desc *gpio;
+ int ret;
+
+ if (!client)
+ return -EINVAL;
+
+ dev = &client->dev;
+
+ /* data ready gpio interrupt pin */
+ gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0);
+ if (IS_ERR(gpio)) {
+ dev_err(dev, "acpi gpio get index failed\n");
+ return PTR_ERR(gpio);
+ }
+
+ ret = gpiod_direction_input(gpio);
+ if (ret)
+ return ret;
+
+ ret = gpiod_to_irq(gpio);
+
+ dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+ return ret;
+}
+
+static int kxcjk1013_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct kxcjk1013_data *data;
+ struct iio_dev *indio_dev;
+ struct kxcjk_1013_platform_data *pdata;
+ const char *name;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ pdata = dev_get_platdata(&client->dev);
+ if (pdata)
+ data->active_high_intr = pdata->active_high_intr;
+ else
+ data->active_high_intr = true; /* default polarity */
+
+ if (id) {
+ data->chipset = (enum kx_chipset)(id->driver_data);
+ name = id->name;
+ } else if (ACPI_HANDLE(&client->dev)) {
+ name = kxcjk1013_match_acpi_device(&client->dev,
+ &data->chipset);
+ } else
+ return -ENODEV;
+
+ ret = kxcjk1013_chip_init(data);
+ if (ret < 0)
+ return ret;
+
+ mutex_init(&data->mutex);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = kxcjk1013_channels;
+ indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels);
+ indio_dev->name = name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &kxcjk1013_info;
+
+ if (client->irq < 0)
+ client->irq = kxcjk1013_gpio_probe(client, data);
+
+ if (client->irq >= 0) {
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ kxcjk1013_data_rdy_trig_poll,
+ kxcjk1013_event_handler,
+ IRQF_TRIGGER_RISING,
+ KXCJK1013_IRQ_NAME,
+ indio_dev);
+ if (ret)
+ return ret;
+
+ data->dready_trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-dev%d",
+ indio_dev->name,
+ indio_dev->id);
+ if (!data->dready_trig)
+ return -ENOMEM;
+
+ data->motion_trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-any-motion-dev%d",
+ indio_dev->name,
+ indio_dev->id);
+ if (!data->motion_trig)
+ return -ENOMEM;
+
+ data->dready_trig->dev.parent = &client->dev;
+ data->dready_trig->ops = &kxcjk1013_trigger_ops;
+ iio_trigger_set_drvdata(data->dready_trig, indio_dev);
+ indio_dev->trig = data->dready_trig;
+ iio_trigger_get(indio_dev->trig);
+ ret = iio_trigger_register(data->dready_trig);
+ if (ret)
+ return ret;
+
+ data->motion_trig->dev.parent = &client->dev;
+ data->motion_trig->ops = &kxcjk1013_trigger_ops;
+ iio_trigger_set_drvdata(data->motion_trig, indio_dev);
+ ret = iio_trigger_register(data->motion_trig);
+ if (ret) {
+ data->motion_trig = NULL;
+ goto err_trigger_unregister;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev,
+ &iio_pollfunc_store_time,
+ kxcjk1013_trigger_handler,
+ NULL);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "iio triggered buffer setup failed\n");
+ goto err_trigger_unregister;
+ }
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "unable to register iio device\n");
+ goto err_buffer_cleanup;
+ }
+
+ ret = pm_runtime_set_active(&client->dev);
+ if (ret)
+ goto err_iio_unregister;
+
+ pm_runtime_enable(&client->dev);
+ pm_runtime_set_autosuspend_delay(&client->dev,
+ KXCJK1013_SLEEP_DELAY_MS);
+ pm_runtime_use_autosuspend(&client->dev);
+
+ return 0;
+
+err_iio_unregister:
+ iio_device_unregister(indio_dev);
+err_buffer_cleanup:
+ if (data->dready_trig)
+ iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+ if (data->dready_trig)
+ iio_trigger_unregister(data->dready_trig);
+ if (data->motion_trig)
+ iio_trigger_unregister(data->motion_trig);
+
+ return ret;
+}
+
+static int kxcjk1013_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ iio_device_unregister(indio_dev);
+
+ if (data->dready_trig) {
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_trigger_unregister(data->dready_trig);
+ iio_trigger_unregister(data->motion_trig);
+ }
+
+ mutex_lock(&data->mutex);
+ kxcjk1013_set_mode(data, STANDBY);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int kxcjk1013_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int kxcjk1013_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret = 0;
+
+ mutex_lock(&data->mutex);
+ /* Check, if the suspend occured while active */
+ if (data->dready_trigger_on || data->motion_trigger_on ||
+ data->ev_enable_state)
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int kxcjk1013_runtime_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ return kxcjk1013_set_mode(data, STANDBY);
+}
+
+static int kxcjk1013_runtime_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+ int sleep_val;
+
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+
+ sleep_val = kxcjk1013_get_startup_times(data);
+ if (sleep_val < 20000)
+ usleep_range(sleep_val, 20000);
+ else
+ msleep_interruptible(sleep_val/1000);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops kxcjk1013_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume)
+ SET_RUNTIME_PM_OPS(kxcjk1013_runtime_suspend,
+ kxcjk1013_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id kx_acpi_match[] = {
+ {"KXCJ1013", KXCJK1013},
+ {"KXCJ1008", KXCJ91008},
+ {"KXTJ1009", KXTJ21009},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
+
+static const struct i2c_device_id kxcjk1013_id[] = {
+ {"kxcjk1013", KXCJK1013},
+ {"kxcj91008", KXCJ91008},
+ {"kxtj21009", KXTJ21009},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, kxcjk1013_id);
+
+static struct i2c_driver kxcjk1013_driver = {
+ .driver = {
+ .name = KXCJK1013_DRV_NAME,
+ .acpi_match_table = ACPI_PTR(kx_acpi_match),
+ .pm = &kxcjk1013_pm_ops,
+ },
+ .probe = kxcjk1013_probe,
+ .remove = kxcjk1013_remove,
+ .id_table = kxcjk1013_id,
+};
+module_i2c_driver(kxcjk1013_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("KXCJK1013 accelerometer driver");
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
new file mode 100644
index 0000000..98ba761
--- /dev/null
+++ b/drivers/iio/accel/kxsd9.c
@@ -0,0 +1,276 @@
+/*
+ * kxsd9.c simple support for the Kionix KXSD9 3D
+ * accelerometer.
+ *
+ * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org>
+ *
+ * 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.
+ *
+ * The i2c interface is very similar, so shouldn't be a problem once
+ * I have a suitable wire made up.
+ *
+ * TODO: Support the motion detector
+ * Uses register address incrementing so could have a
+ * heavily optimized ring buffer access function.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define KXSD9_REG_X 0x00
+#define KXSD9_REG_Y 0x02
+#define KXSD9_REG_Z 0x04
+#define KXSD9_REG_AUX 0x06
+#define KXSD9_REG_RESET 0x0a
+#define KXSD9_REG_CTRL_C 0x0c
+
+#define KXSD9_FS_MASK 0x03
+
+#define KXSD9_REG_CTRL_B 0x0d
+#define KXSD9_REG_CTRL_A 0x0e
+
+#define KXSD9_READ(a) (0x80 | (a))
+#define KXSD9_WRITE(a) (a)
+
+#define KXSD9_STATE_RX_SIZE 2
+#define KXSD9_STATE_TX_SIZE 2
+/**
+ * struct kxsd9_state - device related storage
+ * @buf_lock: protect the rx and tx buffers.
+ * @us: spi device
+ * @rx: single rx buffer storage
+ * @tx: single tx buffer storage
+ **/
+struct kxsd9_state {
+ struct mutex buf_lock;
+ struct spi_device *us;
+ u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
+ u8 tx[KXSD9_STATE_TX_SIZE];
+};
+
+#define KXSD9_SCALE_2G "0.011978"
+#define KXSD9_SCALE_4G "0.023927"
+#define KXSD9_SCALE_6G "0.035934"
+#define KXSD9_SCALE_8G "0.047853"
+
+/* reverse order */
+static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
+
+static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
+{
+ int ret, i;
+ struct kxsd9_state *st = iio_priv(indio_dev);
+ bool foundit = false;
+
+ for (i = 0; i < 4; i++)
+ if (micro == kxsd9_micro_scales[i]) {
+ foundit = true;
+ break;
+ }
+ if (!foundit)
+ return -EINVAL;
+
+ mutex_lock(&st->buf_lock);
+ ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+ if (ret)
+ goto error_ret;
+ st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
+ st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
+
+ ret = spi_write(st->us, st->tx, 2);
+error_ret:
+ mutex_unlock(&st->buf_lock);
+ return ret;
+}
+
+static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
+{
+ int ret;
+ struct kxsd9_state *st = iio_priv(indio_dev);
+ struct spi_transfer xfers[] = {
+ {
+ .bits_per_word = 8,
+ .len = 1,
+ .delay_usecs = 200,
+ .tx_buf = st->tx,
+ }, {
+ .bits_per_word = 8,
+ .len = 2,
+ .rx_buf = st->rx,
+ },
+ };
+
+ mutex_lock(&st->buf_lock);
+ st->tx[0] = KXSD9_READ(address);
+ ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
+ if (!ret)
+ ret = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+ mutex_unlock(&st->buf_lock);
+ return ret;
+}
+
+static IIO_CONST_ATTR(accel_scale_available,
+ KXSD9_SCALE_2G " "
+ KXSD9_SCALE_4G " "
+ KXSD9_SCALE_6G " "
+ KXSD9_SCALE_8G);
+
+static struct attribute *kxsd9_attributes[] = {
+ &iio_const_attr_accel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static int kxsd9_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ int ret = -EINVAL;
+
+ if (mask == IIO_CHAN_INFO_SCALE) {
+ /* Check no integer component */
+ if (val)
+ return -EINVAL;
+ ret = kxsd9_write_scale(indio_dev, val2);
+ }
+
+ return ret;
+}
+
+static int kxsd9_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ int ret = -EINVAL;
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = kxsd9_read(indio_dev, chan->address);
+ if (ret < 0)
+ goto error_ret;
+ *val = ret;
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+ if (ret)
+ goto error_ret;
+ *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+ }
+
+error_ret:
+ return ret;
+};
+#define KXSD9_ACCEL_CHAN(axis) \
+ { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .address = KXSD9_REG_##axis, \
+ }
+
+static const struct iio_chan_spec kxsd9_channels[] = {
+ KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z),
+ {
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .indexed = 1,
+ .address = KXSD9_REG_AUX,
+ }
+};
+
+static const struct attribute_group kxsd9_attribute_group = {
+ .attrs = kxsd9_attributes,
+};
+
+static int kxsd9_power_up(struct kxsd9_state *st)
+{
+ int ret;
+
+ st->tx[0] = 0x0d;
+ st->tx[1] = 0x40;
+ ret = spi_write(st->us, st->tx, 2);
+ if (ret)
+ return ret;
+
+ st->tx[0] = 0x0c;
+ st->tx[1] = 0x9b;
+ return spi_write(st->us, st->tx, 2);
+};
+
+static const struct iio_info kxsd9_info = {
+ .read_raw = &kxsd9_read_raw,
+ .write_raw = &kxsd9_write_raw,
+ .attrs = &kxsd9_attribute_group,
+ .driver_module = THIS_MODULE,
+};
+
+static int kxsd9_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct kxsd9_state *st;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ spi_set_drvdata(spi, indio_dev);
+
+ st->us = spi;
+ mutex_init(&st->buf_lock);
+ indio_dev->channels = kxsd9_channels;
+ indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->info = &kxsd9_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ spi->mode = SPI_MODE_0;
+ spi_setup(spi);
+ kxsd9_power_up(st);
+
+ return iio_device_register(indio_dev);
+}
+
+static int kxsd9_remove(struct spi_device *spi)
+{
+ iio_device_unregister(spi_get_drvdata(spi));
+
+ return 0;
+}
+
+static const struct spi_device_id kxsd9_id[] = {
+ {"kxsd9", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(spi, kxsd9_id);
+
+static struct spi_driver kxsd9_driver = {
+ .driver = {
+ .name = "kxsd9",
+ .owner = THIS_MODULE,
+ },
+ .probe = kxsd9_probe,
+ .remove = kxsd9_remove,
+ .id_table = kxsd9_id,
+};
+module_spi_driver(kxsd9_driver);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
new file mode 100644
index 0000000..5b80657
--- /dev/null
+++ b/drivers/iio/accel/mma8452.c
@@ -0,0 +1,451 @@
+/*
+ * mma8452.c - Support for Freescale MMA8452Q 3-axis 12-bit accelerometer
+ *
+ * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * 7-bit I2C slave address 0x1c/0x1d (pin selectable)
+ *
+ * TODO: interrupt, thresholding, orientation / freefall events, autosleep
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/delay.h>
+
+#define MMA8452_STATUS 0x00
+#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */
+#define MMA8452_OUT_Y 0x03
+#define MMA8452_OUT_Z 0x05
+#define MMA8452_WHO_AM_I 0x0d
+#define MMA8452_DATA_CFG 0x0e
+#define MMA8452_OFF_X 0x2f
+#define MMA8452_OFF_Y 0x30
+#define MMA8452_OFF_Z 0x31
+#define MMA8452_CTRL_REG1 0x2a
+#define MMA8452_CTRL_REG2 0x2b
+
+#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
+
+#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3))
+#define MMA8452_CTRL_DR_SHIFT 3
+#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
+#define MMA8452_CTRL_ACTIVE BIT(0)
+
+#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0))
+#define MMA8452_DATA_CFG_FS_2G 0
+#define MMA8452_DATA_CFG_FS_4G 1
+#define MMA8452_DATA_CFG_FS_8G 2
+
+#define MMA8452_DEVICE_ID 0x2a
+
+struct mma8452_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 ctrl_reg1;
+ u8 data_cfg;
+};
+
+static int mma8452_drdy(struct mma8452_data *data)
+{
+ int tries = 150;
+
+ while (tries-- > 0) {
+ int ret = i2c_smbus_read_byte_data(data->client,
+ MMA8452_STATUS);
+ if (ret < 0)
+ return ret;
+ if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
+ return 0;
+ msleep(20);
+ }
+
+ dev_err(&data->client->dev, "data not ready\n");
+ return -EIO;
+}
+
+static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
+{
+ int ret = mma8452_drdy(data);
+ if (ret < 0)
+ return ret;
+ return i2c_smbus_read_i2c_block_data(data->client,
+ MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
+}
+
+static ssize_t mma8452_show_int_plus_micros(char *buf,
+ const int (*vals)[2], int n)
+{
+ size_t len = 0;
+
+ while (n-- > 0)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d.%06d ", vals[n][0], vals[n][1]);
+
+ /* replace trailing space by newline */
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
+ int val, int val2)
+{
+ while (n-- > 0)
+ if (val == vals[n][0] && val2 == vals[n][1])
+ return n;
+
+ return -EINVAL;
+}
+
+static const int mma8452_samp_freq[8][2] = {
+ {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
+ {6, 250000}, {1, 560000}
+};
+
+/*
+ * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
+ * The userspace interface uses m/s^2 and we declare micro units
+ * So scale factor is given by:
+ * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
+ */
+static const int mma8452_scales[3][2] = {
+ {0, 9577}, {0, 19154}, {0, 38307}
+};
+
+static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
+ ARRAY_SIZE(mma8452_samp_freq));
+}
+
+static ssize_t mma8452_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return mma8452_show_int_plus_micros(buf, mma8452_scales,
+ ARRAY_SIZE(mma8452_scales));
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
+static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
+ mma8452_show_scale_avail, NULL, 0);
+
+static int mma8452_get_samp_freq_index(struct mma8452_data *data,
+ int val, int val2)
+{
+ return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
+ ARRAY_SIZE(mma8452_samp_freq), val, val2);
+}
+
+static int mma8452_get_scale_index(struct mma8452_data *data,
+ int val, int val2)
+{
+ return mma8452_get_int_plus_micros_index(mma8452_scales,
+ ARRAY_SIZE(mma8452_scales), val, val2);
+}
+
+static int mma8452_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct mma8452_data *data = iio_priv(indio_dev);
+ __be16 buffer[3];
+ int i, ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ mutex_lock(&data->lock);
+ ret = mma8452_read(data, buffer);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(
+ be16_to_cpu(buffer[chan->scan_index]) >> 4, 11);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
+ *val = mma8452_scales[i][0];
+ *val2 = mma8452_scales[i][1];
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ i = (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
+ MMA8452_CTRL_DR_SHIFT;
+ *val = mma8452_samp_freq[i][0];
+ *val2 = mma8452_samp_freq[i][1];
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X +
+ chan->scan_index);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret, 7);
+ return IIO_VAL_INT;
+ }
+ return -EINVAL;
+}
+
+static int mma8452_standby(struct mma8452_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
+}
+
+static int mma8452_active(struct mma8452_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+}
+
+static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
+{
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ /* config can only be changed when in standby */
+ ret = mma8452_standby(data);
+ if (ret < 0)
+ goto fail;
+
+ ret = i2c_smbus_write_byte_data(data->client, reg, val);
+ if (ret < 0)
+ goto fail;
+
+ ret = mma8452_active(data);
+ if (ret < 0)
+ goto fail;
+
+ ret = 0;
+fail:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int mma8452_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct mma8452_data *data = iio_priv(indio_dev);
+ int i;
+
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ i = mma8452_get_samp_freq_index(data, val, val2);
+ if (i < 0)
+ return -EINVAL;
+
+ data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
+ data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
+ return mma8452_change_config(data, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+ case IIO_CHAN_INFO_SCALE:
+ i = mma8452_get_scale_index(data, val, val2);
+ if (i < 0)
+ return -EINVAL;
+ data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
+ data->data_cfg |= i;
+ return mma8452_change_config(data, MMA8452_DATA_CFG,
+ data->data_cfg);
+ case IIO_CHAN_INFO_CALIBBIAS:
+ if (val < -128 || val > 127)
+ return -EINVAL;
+ return mma8452_change_config(data, MMA8452_OFF_X +
+ chan->scan_index, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t mma8452_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct mma8452_data *data = iio_priv(indio_dev);
+ u8 buffer[16]; /* 3 16-bit channels + padding + ts */
+ int ret;
+
+ ret = mma8452_read(data, (__be16 *) buffer);
+ if (ret < 0)
+ goto done;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+ iio_get_time_ns());
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+#define MMA8452_CHANNEL(axis, idx) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = idx, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+static const struct iio_chan_spec mma8452_channels[] = {
+ MMA8452_CHANNEL(X, 0),
+ MMA8452_CHANNEL(Y, 1),
+ MMA8452_CHANNEL(Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static struct attribute *mma8452_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group mma8452_group = {
+ .attrs = mma8452_attributes,
+};
+
+static const struct iio_info mma8452_info = {
+ .attrs = &mma8452_group,
+ .read_raw = &mma8452_read_raw,
+ .write_raw = &mma8452_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static const unsigned long mma8452_scan_masks[] = {0x7, 0};
+
+static int mma8452_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mma8452_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
+ if (ret < 0)
+ return ret;
+ if (ret != MMA8452_DEVICE_ID)
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ mutex_init(&data->lock);
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->info = &mma8452_info;
+ indio_dev->name = id->name;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mma8452_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mma8452_channels);
+ indio_dev->available_scan_masks = mma8452_scan_masks;
+
+ data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
+ (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
+ ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+ if (ret < 0)
+ return ret;
+
+ data->data_cfg = MMA8452_DATA_CFG_FS_2G;
+ ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
+ data->data_cfg);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ mma8452_trigger_handler, NULL);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto buffer_cleanup;
+ return 0;
+
+buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+
+static int mma8452_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ mma8452_standby(iio_priv(indio_dev));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mma8452_suspend(struct device *dev)
+{
+ return mma8452_standby(iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev))));
+}
+
+static int mma8452_resume(struct device *dev)
+{
+ return mma8452_active(iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev))));
+}
+
+static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume);
+#define MMA8452_PM_OPS (&mma8452_pm_ops)
+#else
+#define MMA8452_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id mma8452_id[] = {
+ { "mma8452", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mma8452_id);
+
+static const struct of_device_id mma8452_dt_ids[] = {
+ { .compatible = "fsl,mma8452" },
+ { }
+};
+
+static struct i2c_driver mma8452_driver = {
+ .driver = {
+ .name = "mma8452",
+ .of_match_table = of_match_ptr(mma8452_dt_ids),
+ .pm = MMA8452_PM_OPS,
+ },
+ .probe = mma8452_probe,
+ .remove = mma8452_remove,
+ .id_table = mma8452_id,
+};
+module_i2c_driver(mma8452_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Freescale MMA8452 accelerometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
new file mode 100644
index 0000000..fa96460
--- /dev/null
+++ b/drivers/iio/accel/st_accel.h
@@ -0,0 +1,55 @@
+/*
+ * STMicroelectronics accelerometers driver
+ *
+ * Copyright 2012-2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ * v. 1.0.0
+ * Licensed under the GPL-2.
+ */
+
+#ifndef ST_ACCEL_H
+#define ST_ACCEL_H
+
+#include <linux/types.h>
+#include <linux/iio/common/st_sensors.h>
+
+#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
+#define LIS3DH_ACCEL_DEV_NAME "lis3dh"
+#define LSM330D_ACCEL_DEV_NAME "lsm330d_accel"
+#define LSM330DL_ACCEL_DEV_NAME "lsm330dl_accel"
+#define LSM330DLC_ACCEL_DEV_NAME "lsm330dlc_accel"
+#define LIS331DLH_ACCEL_DEV_NAME "lis331dlh"
+#define LSM303DL_ACCEL_DEV_NAME "lsm303dl_accel"
+#define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh_accel"
+#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
+#define LSM330_ACCEL_DEV_NAME "lsm330_accel"
+
+/**
+* struct st_sensors_platform_data - default accel platform data
+* @drdy_int_pin: default accel DRDY is available on INT1 pin.
+*/
+static const struct st_sensors_platform_data default_accel_pdata = {
+ .drdy_int_pin = 1,
+};
+
+int st_accel_common_probe(struct iio_dev *indio_dev);
+void st_accel_common_remove(struct iio_dev *indio_dev);
+
+#ifdef CONFIG_IIO_BUFFER
+int st_accel_allocate_ring(struct iio_dev *indio_dev);
+void st_accel_deallocate_ring(struct iio_dev *indio_dev);
+int st_accel_trig_set_state(struct iio_trigger *trig, bool state);
+#define ST_ACCEL_TRIGGER_SET_STATE (&st_accel_trig_set_state)
+#else /* CONFIG_IIO_BUFFER */
+static inline int st_accel_allocate_ring(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+static inline void st_accel_deallocate_ring(struct iio_dev *indio_dev)
+{
+}
+#define ST_ACCEL_TRIGGER_SET_STATE NULL
+#endif /* CONFIG_IIO_BUFFER */
+
+#endif /* ST_ACCEL_H */
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c
new file mode 100644
index 0000000..a1e642e
--- /dev/null
+++ b/drivers/iio/accel/st_accel_buffer.c
@@ -0,0 +1,105 @@
+/*
+ * STMicroelectronics accelerometers driver
+ *
+ * Copyright 2012-2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include "st_accel.h"
+
+int st_accel_trig_set_state(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+
+ return st_sensors_set_dataready_irq(indio_dev, state);
+}
+
+static int st_accel_buffer_preenable(struct iio_dev *indio_dev)
+{
+ return st_sensors_set_enable(indio_dev, true);
+}
+
+static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
+{
+ int err;
+ struct st_sensor_data *adata = iio_priv(indio_dev);
+
+ adata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+ if (adata->buffer_data == NULL) {
+ err = -ENOMEM;
+ goto allocate_memory_error;
+ }
+
+ err = st_sensors_set_axis_enable(indio_dev,
+ (u8)indio_dev->active_scan_mask[0]);
+ if (err < 0)
+ goto st_accel_buffer_postenable_error;
+
+ err = iio_triggered_buffer_postenable(indio_dev);
+ if (err < 0)
+ goto st_accel_buffer_postenable_error;
+
+ return err;
+
+st_accel_buffer_postenable_error:
+ kfree(adata->buffer_data);
+allocate_memory_error:
+ return err;
+}
+
+static int st_accel_buffer_predisable(struct iio_dev *indio_dev)
+{
+ int err;
+ struct st_sensor_data *adata = iio_priv(indio_dev);
+
+ err = iio_triggered_buffer_predisable(indio_dev);
+ if (err < 0)
+ goto st_accel_buffer_predisable_error;
+
+ err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
+ if (err < 0)
+ goto st_accel_buffer_predisable_error;
+
+ err = st_sensors_set_enable(indio_dev, false);
+
+st_accel_buffer_predisable_error:
+ kfree(adata->buffer_data);
+ return err;
+}
+
+static const struct iio_buffer_setup_ops st_accel_buffer_setup_ops = {
+ .preenable = &st_accel_buffer_preenable,
+ .postenable = &st_accel_buffer_postenable,
+ .predisable = &st_accel_buffer_predisable,
+};
+
+int st_accel_allocate_ring(struct iio_dev *indio_dev)
+{
+ return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ &st_sensors_trigger_handler, &st_accel_buffer_setup_ops);
+}
+
+void st_accel_deallocate_ring(struct iio_dev *indio_dev)
+{
+ iio_triggered_buffer_cleanup(indio_dev);
+}
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics accelerometers buffer");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
new file mode 100644
index 0000000..53f3262
--- /dev/null
+++ b/drivers/iio/accel/st_accel_core.c
@@ -0,0 +1,540 @@
+/*
+ * STMicroelectronics accelerometers driver
+ *
+ * Copyright 2012-2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include "st_accel.h"
+
+#define ST_ACCEL_NUMBER_DATA_CHANNELS 3
+
+/* DEFAULT VALUE FOR SENSORS */
+#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28
+#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a
+#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR 0x2c
+
+/* FULLSCALE */
+#define ST_ACCEL_FS_AVL_2G 2
+#define ST_ACCEL_FS_AVL_4G 4
+#define ST_ACCEL_FS_AVL_6G 6
+#define ST_ACCEL_FS_AVL_8G 8
+#define ST_ACCEL_FS_AVL_16G 16
+
+/* CUSTOM VALUES FOR SENSOR 1 */
+#define ST_ACCEL_1_WAI_EXP 0x33
+#define ST_ACCEL_1_ODR_ADDR 0x20
+#define ST_ACCEL_1_ODR_MASK 0xf0
+#define ST_ACCEL_1_ODR_AVL_1HZ_VAL 0x01
+#define ST_ACCEL_1_ODR_AVL_10HZ_VAL 0x02
+#define ST_ACCEL_1_ODR_AVL_25HZ_VAL 0x03
+#define ST_ACCEL_1_ODR_AVL_50HZ_VAL 0x04
+#define ST_ACCEL_1_ODR_AVL_100HZ_VAL 0x05
+#define ST_ACCEL_1_ODR_AVL_200HZ_VAL 0x06
+#define ST_ACCEL_1_ODR_AVL_400HZ_VAL 0x07
+#define ST_ACCEL_1_ODR_AVL_1600HZ_VAL 0x08
+#define ST_ACCEL_1_FS_ADDR 0x23
+#define ST_ACCEL_1_FS_MASK 0x30
+#define ST_ACCEL_1_FS_AVL_2_VAL 0x00
+#define ST_ACCEL_1_FS_AVL_4_VAL 0x01
+#define ST_ACCEL_1_FS_AVL_8_VAL 0x02
+#define ST_ACCEL_1_FS_AVL_16_VAL 0x03
+#define ST_ACCEL_1_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000)
+#define ST_ACCEL_1_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000)
+#define ST_ACCEL_1_FS_AVL_8_GAIN IIO_G_TO_M_S_2(4000)
+#define ST_ACCEL_1_FS_AVL_16_GAIN IIO_G_TO_M_S_2(12000)
+#define ST_ACCEL_1_BDU_ADDR 0x23
+#define ST_ACCEL_1_BDU_MASK 0x80
+#define ST_ACCEL_1_DRDY_IRQ_ADDR 0x22
+#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK 0x10
+#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK 0x08
+#define ST_ACCEL_1_MULTIREAD_BIT true
+
+/* CUSTOM VALUES FOR SENSOR 2 */
+#define ST_ACCEL_2_WAI_EXP 0x32
+#define ST_ACCEL_2_ODR_ADDR 0x20
+#define ST_ACCEL_2_ODR_MASK 0x18
+#define ST_ACCEL_2_ODR_AVL_50HZ_VAL 0x00
+#define ST_ACCEL_2_ODR_AVL_100HZ_VAL 0x01
+#define ST_ACCEL_2_ODR_AVL_400HZ_VAL 0x02
+#define ST_ACCEL_2_ODR_AVL_1000HZ_VAL 0x03
+#define ST_ACCEL_2_PW_ADDR 0x20
+#define ST_ACCEL_2_PW_MASK 0xe0
+#define ST_ACCEL_2_FS_ADDR 0x23
+#define ST_ACCEL_2_FS_MASK 0x30
+#define ST_ACCEL_2_FS_AVL_2_VAL 0X00
+#define ST_ACCEL_2_FS_AVL_4_VAL 0X01
+#define ST_ACCEL_2_FS_AVL_8_VAL 0x03
+#define ST_ACCEL_2_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000)
+#define ST_ACCEL_2_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000)
+#define ST_ACCEL_2_FS_AVL_8_GAIN IIO_G_TO_M_S_2(3900)
+#define ST_ACCEL_2_BDU_ADDR 0x23
+#define ST_ACCEL_2_BDU_MASK 0x80
+#define ST_ACCEL_2_DRDY_IRQ_ADDR 0x22
+#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK 0x02
+#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK 0x10
+#define ST_ACCEL_2_MULTIREAD_BIT true
+
+/* CUSTOM VALUES FOR SENSOR 3 */
+#define ST_ACCEL_3_WAI_EXP 0x40
+#define ST_ACCEL_3_ODR_ADDR 0x20
+#define ST_ACCEL_3_ODR_MASK 0xf0
+#define ST_ACCEL_3_ODR_AVL_3HZ_VAL 0x01
+#define ST_ACCEL_3_ODR_AVL_6HZ_VAL 0x02
+#define ST_ACCEL_3_ODR_AVL_12HZ_VAL 0x03
+#define ST_ACCEL_3_ODR_AVL_25HZ_VAL 0x04
+#define ST_ACCEL_3_ODR_AVL_50HZ_VAL 0x05
+#define ST_ACCEL_3_ODR_AVL_100HZ_VAL 0x06
+#define ST_ACCEL_3_ODR_AVL_200HZ_VAL 0x07
+#define ST_ACCEL_3_ODR_AVL_400HZ_VAL 0x08
+#define ST_ACCEL_3_ODR_AVL_800HZ_VAL 0x09
+#define ST_ACCEL_3_ODR_AVL_1600HZ_VAL 0x0a
+#define ST_ACCEL_3_FS_ADDR 0x24
+#define ST_ACCEL_3_FS_MASK 0x38
+#define ST_ACCEL_3_FS_AVL_2_VAL 0X00
+#define ST_ACCEL_3_FS_AVL_4_VAL 0X01
+#define ST_ACCEL_3_FS_AVL_6_VAL 0x02
+#define ST_ACCEL_3_FS_AVL_8_VAL 0x03
+#define ST_ACCEL_3_FS_AVL_16_VAL 0x04
+#define ST_ACCEL_3_FS_AVL_2_GAIN IIO_G_TO_M_S_2(61)
+#define ST_ACCEL_3_FS_AVL_4_GAIN IIO_G_TO_M_S_2(122)
+#define ST_ACCEL_3_FS_AVL_6_GAIN IIO_G_TO_M_S_2(183)
+#define ST_ACCEL_3_FS_AVL_8_GAIN IIO_G_TO_M_S_2(244)
+#define ST_ACCEL_3_FS_AVL_16_GAIN IIO_G_TO_M_S_2(732)
+#define ST_ACCEL_3_BDU_ADDR 0x20
+#define ST_ACCEL_3_BDU_MASK 0x08
+#define ST_ACCEL_3_DRDY_IRQ_ADDR 0x23
+#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK 0x80
+#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK 0x00
+#define ST_ACCEL_3_IG1_EN_ADDR 0x23
+#define ST_ACCEL_3_IG1_EN_MASK 0x08
+#define ST_ACCEL_3_MULTIREAD_BIT false
+
+static const struct iio_chan_spec st_accel_12bit_channels[] = {
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16,
+ ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16,
+ ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16,
+ ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
+ IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
+static const struct iio_chan_spec st_accel_16bit_channels[] = {
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+ ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+ ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
+ ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+ ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
+ IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
+static const struct st_sensor_settings st_accel_sensors_settings[] = {
+ {
+ .wai = ST_ACCEL_1_WAI_EXP,
+ .sensors_supported = {
+ [0] = LIS3DH_ACCEL_DEV_NAME,
+ [1] = LSM303DLHC_ACCEL_DEV_NAME,
+ [2] = LSM330D_ACCEL_DEV_NAME,
+ [3] = LSM330DL_ACCEL_DEV_NAME,
+ [4] = LSM330DLC_ACCEL_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
+ .odr = {
+ .addr = ST_ACCEL_1_ODR_ADDR,
+ .mask = ST_ACCEL_1_ODR_MASK,
+ .odr_avl = {
+ { 1, ST_ACCEL_1_ODR_AVL_1HZ_VAL, },
+ { 10, ST_ACCEL_1_ODR_AVL_10HZ_VAL, },
+ { 25, ST_ACCEL_1_ODR_AVL_25HZ_VAL, },
+ { 50, ST_ACCEL_1_ODR_AVL_50HZ_VAL, },
+ { 100, ST_ACCEL_1_ODR_AVL_100HZ_VAL, },
+ { 200, ST_ACCEL_1_ODR_AVL_200HZ_VAL, },
+ { 400, ST_ACCEL_1_ODR_AVL_400HZ_VAL, },
+ { 1600, ST_ACCEL_1_ODR_AVL_1600HZ_VAL, },
+ },
+ },
+ .pw = {
+ .addr = ST_ACCEL_1_ODR_ADDR,
+ .mask = ST_ACCEL_1_ODR_MASK,
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .enable_axis = {
+ .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+ .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+ },
+ .fs = {
+ .addr = ST_ACCEL_1_FS_ADDR,
+ .mask = ST_ACCEL_1_FS_MASK,
+ .fs_avl = {
+ [0] = {
+ .num = ST_ACCEL_FS_AVL_2G,
+ .value = ST_ACCEL_1_FS_AVL_2_VAL,
+ .gain = ST_ACCEL_1_FS_AVL_2_GAIN,
+ },
+ [1] = {
+ .num = ST_ACCEL_FS_AVL_4G,
+ .value = ST_ACCEL_1_FS_AVL_4_VAL,
+ .gain = ST_ACCEL_1_FS_AVL_4_GAIN,
+ },
+ [2] = {
+ .num = ST_ACCEL_FS_AVL_8G,
+ .value = ST_ACCEL_1_FS_AVL_8_VAL,
+ .gain = ST_ACCEL_1_FS_AVL_8_GAIN,
+ },
+ [3] = {
+ .num = ST_ACCEL_FS_AVL_16G,
+ .value = ST_ACCEL_1_FS_AVL_16_VAL,
+ .gain = ST_ACCEL_1_FS_AVL_16_GAIN,
+ },
+ },
+ },
+ .bdu = {
+ .addr = ST_ACCEL_1_BDU_ADDR,
+ .mask = ST_ACCEL_1_BDU_MASK,
+ },
+ .drdy_irq = {
+ .addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
+ .mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
+ },
+ .multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
+ .bootime = 2,
+ },
+ {
+ .wai = ST_ACCEL_2_WAI_EXP,
+ .sensors_supported = {
+ [0] = LIS331DLH_ACCEL_DEV_NAME,
+ [1] = LSM303DL_ACCEL_DEV_NAME,
+ [2] = LSM303DLH_ACCEL_DEV_NAME,
+ [3] = LSM303DLM_ACCEL_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
+ .odr = {
+ .addr = ST_ACCEL_2_ODR_ADDR,
+ .mask = ST_ACCEL_2_ODR_MASK,
+ .odr_avl = {
+ { 50, ST_ACCEL_2_ODR_AVL_50HZ_VAL, },
+ { 100, ST_ACCEL_2_ODR_AVL_100HZ_VAL, },
+ { 400, ST_ACCEL_2_ODR_AVL_400HZ_VAL, },
+ { 1000, ST_ACCEL_2_ODR_AVL_1000HZ_VAL, },
+ },
+ },
+ .pw = {
+ .addr = ST_ACCEL_2_PW_ADDR,
+ .mask = ST_ACCEL_2_PW_MASK,
+ .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .enable_axis = {
+ .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+ .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+ },
+ .fs = {
+ .addr = ST_ACCEL_2_FS_ADDR,
+ .mask = ST_ACCEL_2_FS_MASK,
+ .fs_avl = {
+ [0] = {
+ .num = ST_ACCEL_FS_AVL_2G,
+ .value = ST_ACCEL_2_FS_AVL_2_VAL,
+ .gain = ST_ACCEL_2_FS_AVL_2_GAIN,
+ },
+ [1] = {
+ .num = ST_ACCEL_FS_AVL_4G,
+ .value = ST_ACCEL_2_FS_AVL_4_VAL,
+ .gain = ST_ACCEL_2_FS_AVL_4_GAIN,
+ },
+ [2] = {
+ .num = ST_ACCEL_FS_AVL_8G,
+ .value = ST_ACCEL_2_FS_AVL_8_VAL,
+ .gain = ST_ACCEL_2_FS_AVL_8_GAIN,
+ },
+ },
+ },
+ .bdu = {
+ .addr = ST_ACCEL_2_BDU_ADDR,
+ .mask = ST_ACCEL_2_BDU_MASK,
+ },
+ .drdy_irq = {
+ .addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
+ .mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
+ },
+ .multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
+ .bootime = 2,
+ },
+ {
+ .wai = ST_ACCEL_3_WAI_EXP,
+ .sensors_supported = {
+ [0] = LSM330_ACCEL_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
+ .odr = {
+ .addr = ST_ACCEL_3_ODR_ADDR,
+ .mask = ST_ACCEL_3_ODR_MASK,
+ .odr_avl = {
+ { 3, ST_ACCEL_3_ODR_AVL_3HZ_VAL },
+ { 6, ST_ACCEL_3_ODR_AVL_6HZ_VAL, },
+ { 12, ST_ACCEL_3_ODR_AVL_12HZ_VAL, },
+ { 25, ST_ACCEL_3_ODR_AVL_25HZ_VAL, },
+ { 50, ST_ACCEL_3_ODR_AVL_50HZ_VAL, },
+ { 100, ST_ACCEL_3_ODR_AVL_100HZ_VAL, },
+ { 200, ST_ACCEL_3_ODR_AVL_200HZ_VAL, },
+ { 400, ST_ACCEL_3_ODR_AVL_400HZ_VAL, },
+ { 800, ST_ACCEL_3_ODR_AVL_800HZ_VAL, },
+ { 1600, ST_ACCEL_3_ODR_AVL_1600HZ_VAL, },
+ },
+ },
+ .pw = {
+ .addr = ST_ACCEL_3_ODR_ADDR,
+ .mask = ST_ACCEL_3_ODR_MASK,
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .enable_axis = {
+ .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+ .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+ },
+ .fs = {
+ .addr = ST_ACCEL_3_FS_ADDR,
+ .mask = ST_ACCEL_3_FS_MASK,
+ .fs_avl = {
+ [0] = {
+ .num = ST_ACCEL_FS_AVL_2G,
+ .value = ST_ACCEL_3_FS_AVL_2_VAL,
+ .gain = ST_ACCEL_3_FS_AVL_2_GAIN,
+ },
+ [1] = {
+ .num = ST_ACCEL_FS_AVL_4G,
+ .value = ST_ACCEL_3_FS_AVL_4_VAL,
+ .gain = ST_ACCEL_3_FS_AVL_4_GAIN,
+ },
+ [2] = {
+ .num = ST_ACCEL_FS_AVL_6G,
+ .value = ST_ACCEL_3_FS_AVL_6_VAL,
+ .gain = ST_ACCEL_3_FS_AVL_6_GAIN,
+ },
+ [3] = {
+ .num = ST_ACCEL_FS_AVL_8G,
+ .value = ST_ACCEL_3_FS_AVL_8_VAL,
+ .gain = ST_ACCEL_3_FS_AVL_8_GAIN,
+ },
+ [4] = {
+ .num = ST_ACCEL_FS_AVL_16G,
+ .value = ST_ACCEL_3_FS_AVL_16_VAL,
+ .gain = ST_ACCEL_3_FS_AVL_16_GAIN,
+ },
+ },
+ },
+ .bdu = {
+ .addr = ST_ACCEL_3_BDU_ADDR,
+ .mask = ST_ACCEL_3_BDU_MASK,
+ },
+ .drdy_irq = {
+ .addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
+ .mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
+ .mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
+ .ig1 = {
+ .en_addr = ST_ACCEL_3_IG1_EN_ADDR,
+ .en_mask = ST_ACCEL_3_IG1_EN_MASK,
+ },
+ },
+ .multi_read_bit = ST_ACCEL_3_MULTIREAD_BIT,
+ .bootime = 2,
+ },
+};
+
+static int st_accel_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *ch, int *val,
+ int *val2, long mask)
+{
+ int err;
+ struct st_sensor_data *adata = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ err = st_sensors_read_info_raw(indio_dev, ch, val);
+ if (err < 0)
+ goto read_error;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = adata->current_fullscale->gain;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = adata->odr;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+
+read_error:
+ return err;
+}
+
+static int st_accel_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+ int err;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ err = st_sensors_set_odr(indio_dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return err;
+ default:
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
+static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
+
+static struct attribute *st_accel_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_accel_attribute_group = {
+ .attrs = st_accel_attributes,
+};
+
+static const struct iio_info accel_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_accel_attribute_group,
+ .read_raw = &st_accel_read_raw,
+ .write_raw = &st_accel_write_raw,
+};
+
+#ifdef CONFIG_IIO_TRIGGER
+static const struct iio_trigger_ops st_accel_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE,
+};
+#define ST_ACCEL_TRIGGER_OPS (&st_accel_trigger_ops)
+#else
+#define ST_ACCEL_TRIGGER_OPS NULL
+#endif
+
+int st_accel_common_probe(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *adata = iio_priv(indio_dev);
+ int irq = adata->get_irq_data_ready(indio_dev);
+ int err;
+
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &accel_info;
+
+ st_sensors_power_enable(indio_dev);
+
+ err = st_sensors_check_device_support(indio_dev,
+ ARRAY_SIZE(st_accel_sensors_settings),
+ st_accel_sensors_settings);
+ if (err < 0)
+ return err;
+
+ adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
+ adata->multiread_bit = adata->sensor_settings->multi_read_bit;
+ indio_dev->channels = adata->sensor_settings->ch;
+ indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
+
+ adata->current_fullscale = (struct st_sensor_fullscale_avl *)
+ &adata->sensor_settings->fs.fs_avl[0];
+ adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
+
+ if (!adata->dev->platform_data)
+ adata->dev->platform_data =
+ (struct st_sensors_platform_data *)&default_accel_pdata;
+
+ err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
+ if (err < 0)
+ return err;
+
+ err = st_accel_allocate_ring(indio_dev);
+ if (err < 0)
+ return err;
+
+ if (irq > 0) {
+ err = st_sensors_allocate_trigger(indio_dev,
+ ST_ACCEL_TRIGGER_OPS);
+ if (err < 0)
+ goto st_accel_probe_trigger_error;
+ }
+
+ err = iio_device_register(indio_dev);
+ if (err)
+ goto st_accel_device_register_error;
+
+ dev_info(&indio_dev->dev, "registered accelerometer %s\n",
+ indio_dev->name);
+
+ return 0;
+
+st_accel_device_register_error:
+ if (irq > 0)
+ st_sensors_deallocate_trigger(indio_dev);
+st_accel_probe_trigger_error:
+ st_accel_deallocate_ring(indio_dev);
+
+ return err;
+}
+EXPORT_SYMBOL(st_accel_common_probe);
+
+void st_accel_common_remove(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *adata = iio_priv(indio_dev);
+
+ st_sensors_power_disable(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ if (adata->get_irq_data_ready(indio_dev) > 0)
+ st_sensors_deallocate_trigger(indio_dev);
+
+ st_accel_deallocate_ring(indio_dev);
+}
+EXPORT_SYMBOL(st_accel_common_remove);
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
new file mode 100644
index 0000000..c7246bd
--- /dev/null
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -0,0 +1,129 @@
+/*
+ * STMicroelectronics accelerometers driver
+ *
+ * Copyright 2012-2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.