From c07ab3ce1c18437c480c3cec96da210434629c74 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Fri, 20 Jul 2007 18:59:39 -0400 Subject: [PATCH] cm-x270-ide --- drivers/ide/Kconfig | 8 +++ drivers/ide/arm/Makefile | 1 + drivers/ide/arm/cm-x270-ide.c | 135 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 0 deletions(-) create mode 100644 drivers/ide/arm/cm-x270-ide.c diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 4200251..ab3a29e 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -866,6 +866,14 @@ config BLK_DEV_IDE_BAST Say Y here if you want to support the onboard IDE channels on the Simtec BAST or the Thorcom VR1000 +config BLK_DEV_IDE_CM_X270 + tristate "CompuLab CM-X270 IDE support" + depends on ARM && (MACH_ARMCORE) + help + Say Y here if you want to support the onboard IDE channels on the + CompuLab CM-X270 module + + config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile index 6a78f07..e5cadb7 100644 --- a/drivers/ide/arm/Makefile +++ b/drivers/ide/arm/Makefile @@ -2,5 +2,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o +obj-$(CONFIG_BLK_DEV_IDE_CM_X270) += cm-x270-ide.o EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/arm/cm-x270-ide.c b/drivers/ide/arm/cm-x270-ide.c new file mode 100644 index 0000000..a8b15aa --- /dev/null +++ b/drivers/ide/arm/cm-x270-ide.c @@ -0,0 +1,135 @@ +/* linux/drivers/ide/arm/cm-x270-ide.c + * + * Copyright (c) 2006 CompuLab, Ltd + * Mike Rapoport + * + * Based on linux/drivers/ide/arm/bast-ide.c + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define CMX270_SB270_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<24) + (1<<25)) +#define CMX270_SB270_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25)) +#define CMX270_ATX_IDECS0_VIRT (CMX270_IDE104_VIRT + (1<<25)) +#define CMX270_ATX_IDECS1_VIRT (CMX270_IDE104_VIRT + (1<<25) + (1<<22)) + +/* list of registered interfaces */ +static ide_hwif_t *ifs[1]; + +static int __init +cmx270_ide_register(unsigned int base, unsigned int aux, int irq, + ide_hwif_t **hwif) +{ + hw_regs_t hw; + + memset(&hw, 0, sizeof(hw)); + + if(!base || !aux) return -EINVAL; + + printk(KERN_DEBUG "%s: base = %08x, aux = %08x\n", __FUNCTION__, + base, aux); + + /* Different mappings for local bus IDE and PCMCIA IDE */ + if(base == CMX270_SB270_IDECS0_VIRT) { + hw.io_ports[IDE_DATA_OFFSET] = base + 0; + hw.io_ports[IDE_ERROR_OFFSET] = base + (0x1<<3); + hw.io_ports[IDE_NSECTOR_OFFSET]= base + (0x2<<3); + hw.io_ports[IDE_SECTOR_OFFSET]= base + (0x3<<3); + hw.io_ports[IDE_LCYL_OFFSET]= base + (0x4<<3); + hw.io_ports[IDE_HCYL_OFFSET]= base + (0x5<<3); + hw.io_ports[IDE_SELECT_OFFSET]= base + (0x6<<3); + hw.io_ports[IDE_STATUS_OFFSET]= base + (0x7<<3); + hw.io_ports[IDE_CONTROL_OFFSET] = aux+(0x6<<3); + } + else if (base == CMX270_ATX_IDECS0_VIRT) { /* atx base */ + hw.io_ports[IDE_DATA_OFFSET] = base + 0; + hw.io_ports[IDE_ERROR_OFFSET] = base + 8; + hw.io_ports[IDE_NSECTOR_OFFSET]= base + 2; + hw.io_ports[IDE_SECTOR_OFFSET]= base + 10; + hw.io_ports[IDE_LCYL_OFFSET]= base + 4; + hw.io_ports[IDE_HCYL_OFFSET]= base + 12; + hw.io_ports[IDE_SELECT_OFFSET]= base + 6; //6; + hw.io_ports[IDE_STATUS_OFFSET]= base + 14; + hw.io_ports[IDE_CONTROL_OFFSET] = (aux+0x6); + } else { + printk(KERN_DEBUG "%s: registering wrong IDE i/f\n", __FUNCTION__); + hw.io_ports[IDE_DATA_OFFSET] = base + 8; + hw.io_ports[IDE_ERROR_OFFSET] = base + 13; + hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; + hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; + hw.io_ports[IDE_LCYL_OFFSET] = base + 4; + hw.io_ports[IDE_HCYL_OFFSET] = base + 5; + hw.io_ports[IDE_SELECT_OFFSET] = base + 6; + hw.io_ports[IDE_STATUS_OFFSET] = base + 7; + hw.io_ports[IDE_CONTROL_OFFSET] = aux; + } + + hw.irq = irq; + + return ide_register_hw(&hw, hwif); +} + +static int __init cmx270_ide_init(void) +{ + int retval = 0; + + if (!(machine_is_armcore())) + goto out; + + printk("CM-X270: initializing IDE interface\n"); + + MSC1 = 0x7ffc7ff4; + + /* Interrupts on rising edge: lines are inverted before they get to + the PXA */ + pxa_gpio_mode(IRQ_TO_GPIO(CMX270_IDE_IRQ)); + + /* try SB-X270 */ + set_irq_type(CMX270_IDE_IRQ, IRQ_TYPE_EDGE_RISING); + retval = cmx270_ide_register(CMX270_SB270_IDECS0_VIRT, + CMX270_SB270_IDECS1_VIRT, + CMX270_IDE_IRQ, &ifs[0]); + if (retval >= 0) { + printk(KERN_DEBUG "%s: found IDE interface on SB-X270\n", + __FUNCTION__); + goto out; + } + + /* SB-X270 detection failed, try ATX */ + set_irq_type(CMX270_IDE_IRQ, IRQ_TYPE_EDGE_FALLING); + retval = cmx270_ide_register(CMX270_ATX_IDECS0_VIRT, + CMX270_ATX_IDECS1_VIRT, + CMX270_IDE_IRQ, &ifs[0]); + + if ( retval >= 0 ) { + printk(KERN_DEBUG "%s: found IDE interface on ATX\n", + __FUNCTION__); + goto out; + } + + out: + return retval; +} + +module_init(cmx270_ide_init); + +MODULE_AUTHOR("CompuLab"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CompuLab CM-X270 IDE driver"); -- 1.5.2.5