/* * linux/arch/sh/kernel/setup_ec3104.c * EC3104 companion chip support * * Copyright (C) 2000 Philipp Rumpf * */ /* EC3104 note: * This code was written without any documentation about the EC3104 chip. While * I hope I got most of the basic functionality right, the register names I use * are most likely completely different from those in the chip documentation. * * If you have any further information about the EC3104, please tell me * (prumpf@tux.org). */ #include #include #include #include #include #include #include #include #include #include /* This is for debugging mostly; here's the table that I intend to keep * in here: * * index function base addr power interrupt bit * 0 power b0ec0000 --- 00000001 (unused) * 1 irqs b0ec1000 --- 00000002 (unused) * 2 ?? b0ec2000 b0ec0008 00000004 * 3 PS2 (1) b0ec3000 b0ec000c 00000008 * 4 PS2 (2) b0ec4000 b0ec0010 00000010 * 5 ?? b0ec5000 b0ec0014 00000020 * 6 I2C b0ec6000 b0ec0018 00000040 * 7 serial (1) b0ec7000 b0ec001c 00000080 * 8 serial (2) b0ec8000 b0ec0020 00000100 * 9 serial (3) b0ec9000 b0ec0024 00000200 * 10 serial (4) b0eca000 b0ec0028 00000400 * 12 GPIO (1) b0ecc000 b0ec0030 * 13 GPIO (2) b0ecc000 b0ec0030 * 16 pcmcia (1) b0ed0000 b0ec0040 00010000 * 17 pcmcia (2) b0ed1000 b0ec0044 00020000 */ /* I used the register names from another interrupt controller I worked with, * since it seems to be identical to the ec3104 except that all bits are * inverted: * * IRR: Interrupt Request Register (pending and enabled interrupts) * IMR: Interrupt Mask Register (which interrupts are enabled) * IPR: Interrupt Pending Register (pending interrupts, even disabled ones) * * 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all * IRQs seem to be level-triggered. */ #define EC3104_IRR (EC3104_BASE + 0x1000) #define EC3104_IMR (EC3104_BASE + 0x1004) #define EC3104_IPR (EC3104_BASE + 0x1008) #define ctrl_readl(addr) (*(volatile u32 *)(addr)) #define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data)) #define ctrl_readb(addr) (*(volatile u8 *)(addr)) static char *ec3104_name(unsigned index) { switch(index) { case 0: return "power management"; case 1: return "interrupts"; case 3: return "PS2 (1)"; case 4: return "PS2 (2)"; case 5: return "I2C (1)"; case 6: return "I2C (2)"; case 7: return "serial (1)"; case 8: return "serial (2)"; case 9: return "serial (3)"; case 10: return "serial (4)"; case 16: return "pcmcia (1)"; case 17: return "pcmcia (2)"; default: { static char buf[32]; sprintf(buf, "unknown (%d)", index); return buf; } } } int get_pending_interrupts(char *buf) { u32 ipr; u32 bit; char *p = buf; p += sprintf(p, "pending: ("); ipr = ctrl_inl(EC3104_IPR); for (bit = 1; bit < 32; bit++) if (!(ipr & (1<