The following patch adds support for PISMO modules found on ARM Ltd
development platforms. These are MTD modules, and can have a
selection of SRAM, flash or DOC devices as described by an on-board
I2C EEPROM.
We support SRAM and NOR flash devices only by registering appropriate
conventional MTD platform devices as children of the 'pismo' device.
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
--
drivers/mtd/maps/Kconfig | 15 ++
drivers/mtd/maps/Makefile |1
drivers/mtd/maps/pismo.c | 325 ++
include/linux/mtd/pismo.h | 17 ++
4 files changed, 358 insertions(+)
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 0b98654..631b060 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -553,4 +553,19 @@ config MTD_VMU
To build this as a module select M here, the module will be called
vmu-flash.
+config MTD_PISMO
+ tristate MTD discovery driver for PISMO modules
+ depends on I2C
+ depends on ARCH_VERSATILE
+ help
+ This driver allows for discovery of PISMO modules - see
+ http://www.pismoworld.org/. These are small modules containing
+ up to five memory devices (eg, SRAM, flash, DOC) described by an
+ I2C EEPROM.
+
+ This driver does not create any MTD maps itself; instead it
+ creates MTD physmap and MTD SRAM platform devices. If you
+ enable this option, you should consider enabling MTD_PHYSMAP
+ and/or MTD_PLATRAM according to the devices on your module.
+
endmenu
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 8bae7f9..cffaaf1 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTD_INTEL_VR_NOR)+= intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
+obj-$(CONFIG_MTD_PISMO)+= pismo.o
--- /dev/null 2009-08-03 10:19:25.737008066 +0100
+++ b/drivers/mtd/maps/pismo.c 2009-08-03 14:23:32.0 +0100
@@ -0,0 +1,325 @@
+/*
+ * PISMO memory driver - http://www.pismoworld.org/
+ *
+ * For ARM Realview and Versatile platforms
+ *
+ * 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.
+ */
+#include linux/init.h
+#include linux/module.h
+#include linux/i2c.h
+#include linux/platform_device.h
+#include linux/spinlock.h
+#include linux/mutex.h
+#include linux/mtd/physmap.h
+#include linux/mtd/plat-ram.h
+#include linux/mtd/pismo.h
+
+#define PISMO_NUM_CS 5
+
+struct pismo_cs_block {
+ u8 type;
+ u8 width;
+ __le16 access;
+ __le32 size;
+ u32 reserved[2];
+ chardevice[32];
+} __packed;
+
+struct pismo_eeprom {
+ struct pismo_cs_block cs[PISMO_NUM_CS];
+ charboard[15];
+ u8 sum;
+} __packed;
+
+struct pismo_mem {
+ phys_addr_t base;
+ u32 size;
+ u16 access;
+ u8 width;
+ u8 type;
+};
+
+struct pismo_data {
+ struct i2c_client *client;
+ void(*vpp)(void *, int);
+ void*vpp_data;
+ struct platform_device *dev[PISMO_NUM_CS];
+};
+
+/* FIXME: set_vpp could do with a better calling convention */
+static struct pismo_data *vpp_pismo;
+static DEFINE_MUTEX(pismo_mutex);
+
+static int pismo_setvpp_probe_fix(struct pismo_data *pismo)
+{
+ mutex_lock(pismo_mutex);
+ if (vpp_pismo) {
+ mutex_unlock(pismo_mutex);
+ kfree(pismo);
+ return -EBUSY;
+ }
+ vpp_pismo = pismo;
+ mutex_unlock(pismo_mutex);
+ return 0;
+}
+
+static void pismo_setvpp_remove_fix(struct pismo_data *pismo)
+{
+ mutex_lock(pismo_mutex);
+ if (vpp_pismo == pismo)
+ vpp_pismo = NULL;
+ mutex_unlock(pismo_mutex);
+}
+
+static void pismo_set_vpp(struct map_info *map, int on)
+{
+ struct pismo_data *pismo = vpp_pismo;
+
+ pismo-vpp(pismo-vpp_data, on);
+}
+/* end of hack */
+
+
+static unsigned int pismo_width_to_bytes(unsigned int width)
+{
+ width = 15;
+ if (width 2)
+ return 0;
+ return 1 width;
+}
+
+static int pismo_eeprom_read(struct i2c_client *client, void *buf, u8 addr,
+ size_t size)
+{
+ int ret;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client-addr,
+ .len = sizeof(addr),
+ .buf = addr,
+ }, {
+ .addr = client-addr,
+ .flags = I2C_M_RD,
+ .len = size,
+ .buf = buf,
+ },
+ };
+
+ ret =