[PATCH 1/2][RFC] ep93xx pcmcia support
Lennert Buytenhek
buytenh at wantstofly.org
Sun Feb 4 19:05:07 EST 2007
Signed-off-by: Lennert Buytenhek <buytenh at wantstofly.org>
Index: linux-2.6.20/drivers/pcmcia/Kconfig
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/Kconfig
+++ linux-2.6.20/drivers/pcmcia/Kconfig
@@ -197,6 +197,12 @@ config PCMCIA_AU1X00
tristate "Au1x00 pcmcia support"
depends on SOC_AU1X00 && PCMCIA
+config PCMCIA_EP93XX
+ tristate "EP93xx support"
+ depends on ARM && ARCH_EP93XX && PCMCIA
+ help
+ Say Y here to include support for the EP93xx PCMCIA controller
+
config PCMCIA_SA1100
tristate "SA1100 support"
depends on ARM && ARCH_SA1100 && PCMCIA
Index: linux-2.6.20/drivers/pcmcia/Makefile
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/Makefile
+++ linux-2.6.20/drivers/pcmcia/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
+obj-$(CONFIG_PCMCIA_EP93XX) += ep93xx_core.o ep93xx_cs.o
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
@@ -38,6 +39,7 @@ obj-$(CONFIG_PCMCIA_VRC4173) += vrc417
obj-$(CONFIG_OMAP_CF) += omap_cf.o
obj-$(CONFIG_AT91_CF) += at91_cf.o
+ep93xx_core-y += soc_common.o ep93xx_base.o
sa11xx_core-y += soc_common.o sa11xx_base.o
pxa2xx_core-y += soc_common.o pxa2xx_base.o
Index: linux-2.6.20/drivers/pcmcia/ep93xx_base.c
===================================================================
--- /dev/null
+++ linux-2.6.20/drivers/pcmcia/ep93xx_base.c
@@ -0,0 +1,194 @@
+/*======================================================================
+
+ Device driver for the PCMCIA control functionality of EP93xx
+ microprocessors. Derived from pxa2xx_base.c
+
+ The contents of this file may be used under the
+ terms of the GNU Public License version 2 (the "GPL")
+
+ (c) Ian Molton (spyro at f2s.com) 2003
+ (c) Stefan Eletzhofer (stefan.eletzhofer at inquant.de) 2003,4
+ (c) Robert Whaley (rwhaley at applieddata.net) 2005
+
+ derived from sa11xx_base.c
+
+ Portions created by John G. Dorsey are
+ Copyright (C) 1999 John G. Dorsey.
+
+ ======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+#include "soc_common.h"
+
+#define PC1ATTRIB (EP93XX_PCMCIA_CONTROLLER_BASE + 0x20)
+#define PC1COMMON (EP93XX_PCMCIA_CONTROLLER_BASE + 0x24)
+#define PC1IO (EP93XX_PCMCIA_CONTROLLER_BASE + 0x28)
+#define PC16BITSWIDE 0x80000000
+
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+
+#define MCXX_SETUP_MAX 0xff
+#define MCXX_ASST_MAX 0xff
+#define MCXX_HOLD_MAX 0x0f
+
+#define MCXX_SETUP_SHIFT 0
+#define MCXX_ASST_SHIFT 16
+#define MCXX_HOLD_SHIFT 8
+
+
+static inline u_int ep93xx_mcxx_hold(u_int pcmcia_cycle_ns,
+ u_int hclk_10khz)
+{
+ u_int code = pcmcia_cycle_ns * hclk_10khz;
+ return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static inline u_int ep93xx_mcxx_asst(u_int pcmcia_cycle_ns,
+ u_int hclk_10khz)
+{
+ u_int code = pcmcia_cycle_ns * hclk_10khz;
+ return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static inline u_int ep93xx_mcxx_setup(u_int pcmcia_cycle_ns,
+ u_int hclk_10khz)
+{
+ u_int code = pcmcia_cycle_ns * hclk_10khz;
+ return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static int ep93xx_pcmcia_set_mcmem( int sock, int speed, int clock )
+{
+ writel(PC16BITSWIDE
+ | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT)
+ | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT)
+ | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT),
+ PC1COMMON);
+
+ return 0;
+}
+
+static int ep93xx_pcmcia_set_mcio( int sock, int speed, int clock )
+{
+ writel(PC16BITSWIDE
+ | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT)
+ | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT)
+ | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT),
+ PC1IO);
+
+ return 0;
+}
+
+static int ep93xx_pcmcia_set_mcatt( int sock, int speed, int clock )
+{
+ writel(PC16BITSWIDE
+ | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << MCXX_SETUP_SHIFT)
+ | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << MCXX_ASST_SHIFT)
+ | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << MCXX_HOLD_SHIFT),
+ PC1ATTRIB);
+
+ return 0;
+}
+
+static int ep93xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk)
+{
+ struct soc_pcmcia_timing timing;
+ int sock = skt->nr;
+
+ soc_common_pcmcia_get_timing(skt, &timing);
+
+ ep93xx_pcmcia_set_mcmem(sock, timing.mem, clk);
+ ep93xx_pcmcia_set_mcatt(sock, timing.attr, clk);
+ ep93xx_pcmcia_set_mcio(sock, timing.io, clk);
+
+ return 0;
+}
+
+static int ep93xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
+{
+ unsigned int hclk;
+
+ /* for now just hard code hclk to 100Mhz (in 10khz units)*/
+ hclk = 10000;
+
+ return ep93xx_pcmcia_set_mcxx(skt, hclk);
+}
+
+
+static int ep93xx_drv_pcmcia_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct pcmcia_low_level *ops;
+ int first, nr;
+
+ if (pdev->dev.platform_data == NULL)
+ return -ENODEV;
+
+ ops = (struct pcmcia_low_level *)pdev->dev.platform_data;
+ first = ops->first;
+ nr = ops->nr;
+
+ /* Provide our EP93xx specific timing routines. */
+ ops->set_timing = ep93xx_pcmcia_set_timing;
+
+ ret = soc_common_drv_pcmcia_probe(&pdev->dev, ops, first, nr);
+
+ return ret;
+}
+
+static int ep93xx_drv_pcmcia_remove(struct platform_device *pdev)
+{
+ return soc_common_drv_pcmcia_remove(&pdev->dev);
+}
+
+static int ep93xx_drv_pcmcia_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&pdev->dev, state);
+}
+
+static int ep93xx_drv_pcmcia_resume(struct platform_device *pdev)
+{
+ return pcmcia_socket_dev_resume(&pdev->dev);
+}
+
+static struct platform_driver ep93xx_pcmcia_driver = {
+ .probe = ep93xx_drv_pcmcia_probe,
+ .remove = ep93xx_drv_pcmcia_remove,
+ .suspend = ep93xx_drv_pcmcia_suspend,
+ .resume = ep93xx_drv_pcmcia_resume,
+ .driver = {
+ .name = "ep93xx-pcmcia",
+ },
+};
+
+static int __init ep93xx_pcmcia_init(void)
+{
+ return platform_driver_register(&ep93xx_pcmcia_driver);
+}
+
+static void __exit ep93xx_pcmcia_exit(void)
+{
+ platform_driver_unregister(&ep93xx_pcmcia_driver);
+}
+
+fs_initcall(ep93xx_pcmcia_init);
+module_exit(ep93xx_pcmcia_exit);
+
+MODULE_AUTHOR("Robert Whaley <rwhaley at applieddata.net>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: EP93xx core socket driver");
+MODULE_LICENSE("GPL");
Index: linux-2.6.20/drivers/pcmcia/soc_common.c
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/soc_common.c
+++ linux-2.6.20/drivers/pcmcia/soc_common.c
@@ -49,6 +49,9 @@
#include "soc_common.h"
/* FIXME: platform dependent resource declaration has to move out of this file */
+#ifdef CONFIG_ARCH_EP93XX
+#include <asm/arch/pcmcia.h>
+#endif
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
#endif
Index: linux-2.6.20/include/asm-arm/arch-ep93xx/pcmcia.h
===================================================================
--- /dev/null
+++ linux-2.6.20/include/asm-arm/arch-ep93xx/pcmcia.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/pcmcia.h
+ */
+
+#ifndef __ASM_ARCH_PCMCIA_H
+#define __ASM_ARCH_PCMCIA_H
+
+#define _PCMCIA(slt) (0x40000000 + ((slt) ? 0x10000000 : 0))
+#define _PCMCIAIO(slt) _PCMCIA(slt)
+#define _PCMCIAAttr(slt) (_PCMCIA(slt) + 0x08000000)
+#define _PCMCIAMem(slt) (_PCMCIA(slt) + 0x0c000000)
+
+#define PCMCIASp 0x10000000
+#define PCMCIAIOSp 0x04000000
+#define PCMCIAAttrSp 0x04000000
+#define PCMCIAMemSp 0x04000000
+
+
+#endif
More information about the linux-pcmcia
mailing list