1f59c811fSManuel Lauss /* 2f59c811fSManuel Lauss * DBAu1000/1500/1100 board support 3f59c811fSManuel Lauss * 4f59c811fSManuel Lauss * Copyright 2000, 2008 MontaVista Software Inc. 5f59c811fSManuel Lauss * Author: MontaVista Software, Inc. <source@mvista.com> 6f59c811fSManuel Lauss * 7f59c811fSManuel Lauss * This program is free software; you can redistribute it and/or modify 8f59c811fSManuel Lauss * it under the terms of the GNU General Public License as published by 9f59c811fSManuel Lauss * the Free Software Foundation; either version 2 of the License, or 10f59c811fSManuel Lauss * (at your option) any later version. 11f59c811fSManuel Lauss * 12f59c811fSManuel Lauss * This program is distributed in the hope that it will be useful, 13f59c811fSManuel Lauss * but WITHOUT ANY WARRANTY; without even the implied warranty of 14f59c811fSManuel Lauss * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15f59c811fSManuel Lauss * GNU General Public License for more details. 16f59c811fSManuel Lauss * 17f59c811fSManuel Lauss * You should have received a copy of the GNU General Public License 18f59c811fSManuel Lauss * along with this program; if not, write to the Free Software 19f59c811fSManuel Lauss * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20f59c811fSManuel Lauss */ 21f59c811fSManuel Lauss 22f59c811fSManuel Lauss #include <linux/dma-mapping.h> 23f59c811fSManuel Lauss #include <linux/gpio.h> 24f59c811fSManuel Lauss #include <linux/init.h> 25f59c811fSManuel Lauss #include <linux/interrupt.h> 26c9af5144SManuel Lauss #include <linux/leds.h> 27c9af5144SManuel Lauss #include <linux/mmc/host.h> 28c9af5144SManuel Lauss #include <linux/module.h> 29f59c811fSManuel Lauss #include <linux/platform_device.h> 30f59c811fSManuel Lauss #include <linux/pm.h> 312a32daf1SManuel Lauss #include <linux/spi/spi.h> 322a32daf1SManuel Lauss #include <linux/spi/spi_gpio.h> 332a32daf1SManuel Lauss #include <linux/spi/ads7846.h> 34f59c811fSManuel Lauss #include <asm/mach-au1x00/au1000.h> 35f59c811fSManuel Lauss #include <asm/mach-au1x00/au1000_dma.h> 36c9af5144SManuel Lauss #include <asm/mach-au1x00/au1100_mmc.h> 37f59c811fSManuel Lauss #include <asm/mach-db1x00/bcsr.h> 38f59c811fSManuel Lauss #include <asm/reboot.h> 39f59c811fSManuel Lauss #include <prom.h> 40f59c811fSManuel Lauss #include "platform.h" 41f59c811fSManuel Lauss 42f59c811fSManuel Lauss #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT) 43f59c811fSManuel Lauss 44f59c811fSManuel Lauss struct pci_dev; 45f59c811fSManuel Lauss 46f59c811fSManuel Lauss static const char *board_type_str(void) 47f59c811fSManuel Lauss { 48f59c811fSManuel Lauss switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { 49f59c811fSManuel Lauss case BCSR_WHOAMI_DB1000: 50f59c811fSManuel Lauss return "DB1000"; 51f59c811fSManuel Lauss case BCSR_WHOAMI_DB1500: 52f59c811fSManuel Lauss return "DB1500"; 53f59c811fSManuel Lauss case BCSR_WHOAMI_DB1100: 54f59c811fSManuel Lauss return "DB1100"; 55f59c811fSManuel Lauss default: 56f59c811fSManuel Lauss return "(unknown)"; 57f59c811fSManuel Lauss } 58f59c811fSManuel Lauss } 59f59c811fSManuel Lauss 60f59c811fSManuel Lauss const char *get_system_type(void) 61f59c811fSManuel Lauss { 62f59c811fSManuel Lauss return board_type_str(); 63f59c811fSManuel Lauss } 64f59c811fSManuel Lauss 65f59c811fSManuel Lauss void __init board_setup(void) 66f59c811fSManuel Lauss { 67f59c811fSManuel Lauss /* initialize board register space */ 68f59c811fSManuel Lauss bcsr_init(DB1000_BCSR_PHYS_ADDR, 69f59c811fSManuel Lauss DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS); 70f59c811fSManuel Lauss 71f59c811fSManuel Lauss printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str()); 72f59c811fSManuel Lauss } 73f59c811fSManuel Lauss 74f59c811fSManuel Lauss 75f59c811fSManuel Lauss static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) 76f59c811fSManuel Lauss { 77f59c811fSManuel Lauss if ((slot < 12) || (slot > 13) || pin == 0) 78f59c811fSManuel Lauss return -1; 79f59c811fSManuel Lauss if (slot == 12) 80f59c811fSManuel Lauss return (pin == 1) ? AU1500_PCI_INTA : 0xff; 81f59c811fSManuel Lauss if (slot == 13) { 82f59c811fSManuel Lauss switch (pin) { 83f59c811fSManuel Lauss case 1: return AU1500_PCI_INTA; 84f59c811fSManuel Lauss case 2: return AU1500_PCI_INTB; 85f59c811fSManuel Lauss case 3: return AU1500_PCI_INTC; 86f59c811fSManuel Lauss case 4: return AU1500_PCI_INTD; 87f59c811fSManuel Lauss } 88f59c811fSManuel Lauss } 89f59c811fSManuel Lauss return -1; 90f59c811fSManuel Lauss } 91f59c811fSManuel Lauss 92f59c811fSManuel Lauss static struct resource alchemy_pci_host_res[] = { 93f59c811fSManuel Lauss [0] = { 94f59c811fSManuel Lauss .start = AU1500_PCI_PHYS_ADDR, 95f59c811fSManuel Lauss .end = AU1500_PCI_PHYS_ADDR + 0xfff, 96f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 97f59c811fSManuel Lauss }, 98f59c811fSManuel Lauss }; 99f59c811fSManuel Lauss 100f59c811fSManuel Lauss static struct alchemy_pci_platdata db1500_pci_pd = { 101f59c811fSManuel Lauss .board_map_irq = db1500_map_pci_irq, 102f59c811fSManuel Lauss }; 103f59c811fSManuel Lauss 104f59c811fSManuel Lauss static struct platform_device db1500_pci_host_dev = { 105f59c811fSManuel Lauss .dev.platform_data = &db1500_pci_pd, 106f59c811fSManuel Lauss .name = "alchemy-pci", 107f59c811fSManuel Lauss .id = 0, 108f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(alchemy_pci_host_res), 109f59c811fSManuel Lauss .resource = alchemy_pci_host_res, 110f59c811fSManuel Lauss }; 111f59c811fSManuel Lauss 112f59c811fSManuel Lauss static int __init db1500_pci_init(void) 113f59c811fSManuel Lauss { 114f59c811fSManuel Lauss if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500) 115f59c811fSManuel Lauss return platform_device_register(&db1500_pci_host_dev); 116f59c811fSManuel Lauss return 0; 117f59c811fSManuel Lauss } 118f59c811fSManuel Lauss /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ 119f59c811fSManuel Lauss arch_initcall(db1500_pci_init); 120f59c811fSManuel Lauss 121f59c811fSManuel Lauss 122f59c811fSManuel Lauss static struct resource au1100_lcd_resources[] = { 123f59c811fSManuel Lauss [0] = { 124f59c811fSManuel Lauss .start = AU1100_LCD_PHYS_ADDR, 125f59c811fSManuel Lauss .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, 126f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 127f59c811fSManuel Lauss }, 128f59c811fSManuel Lauss [1] = { 129f59c811fSManuel Lauss .start = AU1100_LCD_INT, 130f59c811fSManuel Lauss .end = AU1100_LCD_INT, 131f59c811fSManuel Lauss .flags = IORESOURCE_IRQ, 132f59c811fSManuel Lauss } 133f59c811fSManuel Lauss }; 134f59c811fSManuel Lauss 135f59c811fSManuel Lauss static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); 136f59c811fSManuel Lauss 137f59c811fSManuel Lauss static struct platform_device au1100_lcd_device = { 138f59c811fSManuel Lauss .name = "au1100-lcd", 139f59c811fSManuel Lauss .id = 0, 140f59c811fSManuel Lauss .dev = { 141f59c811fSManuel Lauss .dma_mask = &au1100_lcd_dmamask, 142f59c811fSManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 143f59c811fSManuel Lauss }, 144f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(au1100_lcd_resources), 145f59c811fSManuel Lauss .resource = au1100_lcd_resources, 146f59c811fSManuel Lauss }; 147f59c811fSManuel Lauss 148f59c811fSManuel Lauss static struct resource alchemy_ac97c_res[] = { 149f59c811fSManuel Lauss [0] = { 150f59c811fSManuel Lauss .start = AU1000_AC97_PHYS_ADDR, 151f59c811fSManuel Lauss .end = AU1000_AC97_PHYS_ADDR + 0xfff, 152f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 153f59c811fSManuel Lauss }, 154f59c811fSManuel Lauss [1] = { 155f59c811fSManuel Lauss .start = DMA_ID_AC97C_TX, 156f59c811fSManuel Lauss .end = DMA_ID_AC97C_TX, 157f59c811fSManuel Lauss .flags = IORESOURCE_DMA, 158f59c811fSManuel Lauss }, 159f59c811fSManuel Lauss [2] = { 160f59c811fSManuel Lauss .start = DMA_ID_AC97C_RX, 161f59c811fSManuel Lauss .end = DMA_ID_AC97C_RX, 162f59c811fSManuel Lauss .flags = IORESOURCE_DMA, 163f59c811fSManuel Lauss }, 164f59c811fSManuel Lauss }; 165f59c811fSManuel Lauss 166f59c811fSManuel Lauss static struct platform_device alchemy_ac97c_dev = { 167f59c811fSManuel Lauss .name = "alchemy-ac97c", 168f59c811fSManuel Lauss .id = -1, 169f59c811fSManuel Lauss .resource = alchemy_ac97c_res, 170f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(alchemy_ac97c_res), 171f59c811fSManuel Lauss }; 172f59c811fSManuel Lauss 173f59c811fSManuel Lauss static struct platform_device alchemy_ac97c_dma_dev = { 174f59c811fSManuel Lauss .name = "alchemy-pcm-dma", 175f59c811fSManuel Lauss .id = 0, 176f59c811fSManuel Lauss }; 177f59c811fSManuel Lauss 178f59c811fSManuel Lauss static struct platform_device db1x00_codec_dev = { 179f59c811fSManuel Lauss .name = "ac97-codec", 180f59c811fSManuel Lauss .id = -1, 181f59c811fSManuel Lauss }; 182f59c811fSManuel Lauss 183f59c811fSManuel Lauss static struct platform_device db1x00_audio_dev = { 184f59c811fSManuel Lauss .name = "db1000-audio", 185f59c811fSManuel Lauss }; 186f59c811fSManuel Lauss 187c9af5144SManuel Lauss /******************************************************************************/ 188c9af5144SManuel Lauss 189c9af5144SManuel Lauss static irqreturn_t db1100_mmc_cd(int irq, void *ptr) 190c9af5144SManuel Lauss { 191c9af5144SManuel Lauss void (*mmc_cd)(struct mmc_host *, unsigned long); 192c9af5144SManuel Lauss /* link against CONFIG_MMC=m */ 193c9af5144SManuel Lauss mmc_cd = symbol_get(mmc_detect_change); 194c9af5144SManuel Lauss mmc_cd(ptr, msecs_to_jiffies(500)); 195c9af5144SManuel Lauss symbol_put(mmc_detect_change); 196c9af5144SManuel Lauss 197c9af5144SManuel Lauss return IRQ_HANDLED; 198c9af5144SManuel Lauss } 199c9af5144SManuel Lauss 200c9af5144SManuel Lauss static int db1100_mmc_cd_setup(void *mmc_host, int en) 201c9af5144SManuel Lauss { 202c9af5144SManuel Lauss int ret = 0; 203c9af5144SManuel Lauss 204c9af5144SManuel Lauss if (en) { 205c9af5144SManuel Lauss irq_set_irq_type(AU1100_GPIO19_INT, IRQ_TYPE_EDGE_BOTH); 206c9af5144SManuel Lauss ret = request_irq(AU1100_GPIO19_INT, db1100_mmc_cd, 0, 207c9af5144SManuel Lauss "sd0_cd", mmc_host); 208c9af5144SManuel Lauss } else 209c9af5144SManuel Lauss free_irq(AU1100_GPIO19_INT, mmc_host); 210c9af5144SManuel Lauss return ret; 211c9af5144SManuel Lauss } 212c9af5144SManuel Lauss 213c9af5144SManuel Lauss static int db1100_mmc1_cd_setup(void *mmc_host, int en) 214c9af5144SManuel Lauss { 215c9af5144SManuel Lauss int ret = 0; 216c9af5144SManuel Lauss 217c9af5144SManuel Lauss if (en) { 218c9af5144SManuel Lauss irq_set_irq_type(AU1100_GPIO20_INT, IRQ_TYPE_EDGE_BOTH); 219c9af5144SManuel Lauss ret = request_irq(AU1100_GPIO20_INT, db1100_mmc_cd, 0, 220c9af5144SManuel Lauss "sd1_cd", mmc_host); 221c9af5144SManuel Lauss } else 222c9af5144SManuel Lauss free_irq(AU1100_GPIO20_INT, mmc_host); 223c9af5144SManuel Lauss return ret; 224c9af5144SManuel Lauss } 225c9af5144SManuel Lauss 226c9af5144SManuel Lauss static int db1100_mmc_card_readonly(void *mmc_host) 227c9af5144SManuel Lauss { 228c9af5144SManuel Lauss /* testing suggests that this bit is inverted */ 229c9af5144SManuel Lauss return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1; 230c9af5144SManuel Lauss } 231c9af5144SManuel Lauss 232c9af5144SManuel Lauss static int db1100_mmc_card_inserted(void *mmc_host) 233c9af5144SManuel Lauss { 234c9af5144SManuel Lauss return !alchemy_gpio_get_value(19); 235c9af5144SManuel Lauss } 236c9af5144SManuel Lauss 237c9af5144SManuel Lauss static void db1100_mmc_set_power(void *mmc_host, int state) 238c9af5144SManuel Lauss { 239c9af5144SManuel Lauss if (state) { 240c9af5144SManuel Lauss bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR); 241c9af5144SManuel Lauss msleep(400); /* stabilization time */ 242c9af5144SManuel Lauss } else 243c9af5144SManuel Lauss bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0); 244c9af5144SManuel Lauss } 245c9af5144SManuel Lauss 246c9af5144SManuel Lauss static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b) 247c9af5144SManuel Lauss { 248c9af5144SManuel Lauss if (b != LED_OFF) 249c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0); 250c9af5144SManuel Lauss else 251c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0); 252c9af5144SManuel Lauss } 253c9af5144SManuel Lauss 254c9af5144SManuel Lauss static struct led_classdev db1100_mmc_led = { 255c9af5144SManuel Lauss .brightness_set = db1100_mmcled_set, 256c9af5144SManuel Lauss }; 257c9af5144SManuel Lauss 258c9af5144SManuel Lauss static int db1100_mmc1_card_readonly(void *mmc_host) 259c9af5144SManuel Lauss { 260c9af5144SManuel Lauss return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0; 261c9af5144SManuel Lauss } 262c9af5144SManuel Lauss 263c9af5144SManuel Lauss static int db1100_mmc1_card_inserted(void *mmc_host) 264c9af5144SManuel Lauss { 265c9af5144SManuel Lauss return !alchemy_gpio_get_value(20); 266c9af5144SManuel Lauss } 267c9af5144SManuel Lauss 268c9af5144SManuel Lauss static void db1100_mmc1_set_power(void *mmc_host, int state) 269c9af5144SManuel Lauss { 270c9af5144SManuel Lauss if (state) { 271c9af5144SManuel Lauss bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR); 272c9af5144SManuel Lauss msleep(400); /* stabilization time */ 273c9af5144SManuel Lauss } else 274c9af5144SManuel Lauss bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0); 275c9af5144SManuel Lauss } 276c9af5144SManuel Lauss 277c9af5144SManuel Lauss static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b) 278c9af5144SManuel Lauss { 279c9af5144SManuel Lauss if (b != LED_OFF) 280c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0); 281c9af5144SManuel Lauss else 282c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1); 283c9af5144SManuel Lauss } 284c9af5144SManuel Lauss 285c9af5144SManuel Lauss static struct led_classdev db1100_mmc1_led = { 286c9af5144SManuel Lauss .brightness_set = db1100_mmc1led_set, 287c9af5144SManuel Lauss }; 288c9af5144SManuel Lauss 289c9af5144SManuel Lauss static struct au1xmmc_platform_data db1100_mmc_platdata[2] = { 290c9af5144SManuel Lauss [0] = { 291c9af5144SManuel Lauss .cd_setup = db1100_mmc_cd_setup, 292c9af5144SManuel Lauss .set_power = db1100_mmc_set_power, 293c9af5144SManuel Lauss .card_inserted = db1100_mmc_card_inserted, 294c9af5144SManuel Lauss .card_readonly = db1100_mmc_card_readonly, 295c9af5144SManuel Lauss .led = &db1100_mmc_led, 296c9af5144SManuel Lauss }, 297c9af5144SManuel Lauss [1] = { 298c9af5144SManuel Lauss .cd_setup = db1100_mmc1_cd_setup, 299c9af5144SManuel Lauss .set_power = db1100_mmc1_set_power, 300c9af5144SManuel Lauss .card_inserted = db1100_mmc1_card_inserted, 301c9af5144SManuel Lauss .card_readonly = db1100_mmc1_card_readonly, 302c9af5144SManuel Lauss .led = &db1100_mmc1_led, 303c9af5144SManuel Lauss }, 304c9af5144SManuel Lauss }; 305c9af5144SManuel Lauss 306c9af5144SManuel Lauss static struct resource au1100_mmc0_resources[] = { 307c9af5144SManuel Lauss [0] = { 308c9af5144SManuel Lauss .start = AU1100_SD0_PHYS_ADDR, 309c9af5144SManuel Lauss .end = AU1100_SD0_PHYS_ADDR + 0xfff, 310c9af5144SManuel Lauss .flags = IORESOURCE_MEM, 311c9af5144SManuel Lauss }, 312c9af5144SManuel Lauss [1] = { 313c9af5144SManuel Lauss .start = AU1100_SD_INT, 314c9af5144SManuel Lauss .end = AU1100_SD_INT, 315c9af5144SManuel Lauss .flags = IORESOURCE_IRQ, 316c9af5144SManuel Lauss }, 317c9af5144SManuel Lauss [2] = { 318c9af5144SManuel Lauss .start = DMA_ID_SD0_TX, 319c9af5144SManuel Lauss .end = DMA_ID_SD0_TX, 320c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 321c9af5144SManuel Lauss }, 322c9af5144SManuel Lauss [3] = { 323c9af5144SManuel Lauss .start = DMA_ID_SD0_RX, 324c9af5144SManuel Lauss .end = DMA_ID_SD0_RX, 325c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 326c9af5144SManuel Lauss } 327c9af5144SManuel Lauss }; 328c9af5144SManuel Lauss 329c9af5144SManuel Lauss static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); 330c9af5144SManuel Lauss 331c9af5144SManuel Lauss static struct platform_device db1100_mmc0_dev = { 332c9af5144SManuel Lauss .name = "au1xxx-mmc", 333c9af5144SManuel Lauss .id = 0, 334c9af5144SManuel Lauss .dev = { 335c9af5144SManuel Lauss .dma_mask = &au1xxx_mmc_dmamask, 336c9af5144SManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 337c9af5144SManuel Lauss .platform_data = &db1100_mmc_platdata[0], 338c9af5144SManuel Lauss }, 339c9af5144SManuel Lauss .num_resources = ARRAY_SIZE(au1100_mmc0_resources), 340c9af5144SManuel Lauss .resource = au1100_mmc0_resources, 341c9af5144SManuel Lauss }; 342c9af5144SManuel Lauss 343c9af5144SManuel Lauss static struct resource au1100_mmc1_res[] = { 344c9af5144SManuel Lauss [0] = { 345c9af5144SManuel Lauss .start = AU1100_SD1_PHYS_ADDR, 346c9af5144SManuel Lauss .end = AU1100_SD1_PHYS_ADDR + 0xfff, 347c9af5144SManuel Lauss .flags = IORESOURCE_MEM, 348c9af5144SManuel Lauss }, 349c9af5144SManuel Lauss [1] = { 350c9af5144SManuel Lauss .start = AU1100_SD_INT, 351c9af5144SManuel Lauss .end = AU1100_SD_INT, 352c9af5144SManuel Lauss .flags = IORESOURCE_IRQ, 353c9af5144SManuel Lauss }, 354c9af5144SManuel Lauss [2] = { 355c9af5144SManuel Lauss .start = DMA_ID_SD1_TX, 356c9af5144SManuel Lauss .end = DMA_ID_SD1_TX, 357c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 358c9af5144SManuel Lauss }, 359c9af5144SManuel Lauss [3] = { 360c9af5144SManuel Lauss .start = DMA_ID_SD1_RX, 361c9af5144SManuel Lauss .end = DMA_ID_SD1_RX, 362c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 363c9af5144SManuel Lauss } 364c9af5144SManuel Lauss }; 365c9af5144SManuel Lauss 366c9af5144SManuel Lauss static struct platform_device db1100_mmc1_dev = { 367c9af5144SManuel Lauss .name = "au1xxx-mmc", 368c9af5144SManuel Lauss .id = 1, 369c9af5144SManuel Lauss .dev = { 370c9af5144SManuel Lauss .dma_mask = &au1xxx_mmc_dmamask, 371c9af5144SManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 372c9af5144SManuel Lauss .platform_data = &db1100_mmc_platdata[1], 373c9af5144SManuel Lauss }, 374c9af5144SManuel Lauss .num_resources = ARRAY_SIZE(au1100_mmc1_res), 375c9af5144SManuel Lauss .resource = au1100_mmc1_res, 376c9af5144SManuel Lauss }; 377c9af5144SManuel Lauss 378e734ae13SManuel Lauss /******************************************************************************/ 379e734ae13SManuel Lauss 380e734ae13SManuel Lauss static void db1000_irda_set_phy_mode(int mode) 381e734ae13SManuel Lauss { 382e734ae13SManuel Lauss unsigned short mask = BCSR_RESETS_IRDA_MODE_MASK | BCSR_RESETS_FIR_SEL; 383e734ae13SManuel Lauss 384e734ae13SManuel Lauss switch (mode) { 385e734ae13SManuel Lauss case AU1000_IRDA_PHY_MODE_OFF: 386e734ae13SManuel Lauss bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_OFF); 387e734ae13SManuel Lauss break; 388e734ae13SManuel Lauss case AU1000_IRDA_PHY_MODE_SIR: 389e734ae13SManuel Lauss bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL); 390e734ae13SManuel Lauss break; 391e734ae13SManuel Lauss case AU1000_IRDA_PHY_MODE_FIR: 392e734ae13SManuel Lauss bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL | 393e734ae13SManuel Lauss BCSR_RESETS_FIR_SEL); 394e734ae13SManuel Lauss break; 395e734ae13SManuel Lauss } 396e734ae13SManuel Lauss } 397e734ae13SManuel Lauss 398e734ae13SManuel Lauss static struct au1k_irda_platform_data db1000_irda_platdata = { 399e734ae13SManuel Lauss .set_phy_mode = db1000_irda_set_phy_mode, 400e734ae13SManuel Lauss }; 401e734ae13SManuel Lauss 402e734ae13SManuel Lauss static struct resource au1000_irda_res[] = { 403e734ae13SManuel Lauss [0] = { 404e734ae13SManuel Lauss .start = AU1000_IRDA_PHYS_ADDR, 405e734ae13SManuel Lauss .end = AU1000_IRDA_PHYS_ADDR + 0x0fff, 406e734ae13SManuel Lauss .flags = IORESOURCE_MEM, 407e734ae13SManuel Lauss }, 408e734ae13SManuel Lauss [1] = { 409e734ae13SManuel Lauss .start = AU1000_IRDA_TX_INT, 410e734ae13SManuel Lauss .end = AU1000_IRDA_TX_INT, 411e734ae13SManuel Lauss .flags = IORESOURCE_IRQ, 412e734ae13SManuel Lauss }, 413e734ae13SManuel Lauss [2] = { 414e734ae13SManuel Lauss .start = AU1000_IRDA_RX_INT, 415e734ae13SManuel Lauss .end = AU1000_IRDA_RX_INT, 416e734ae13SManuel Lauss .flags = IORESOURCE_IRQ, 417e734ae13SManuel Lauss }, 418e734ae13SManuel Lauss }; 419e734ae13SManuel Lauss 420e734ae13SManuel Lauss static struct platform_device db1000_irda_dev = { 421e734ae13SManuel Lauss .name = "au1000-irda", 422e734ae13SManuel Lauss .id = -1, 423e734ae13SManuel Lauss .dev = { 424e734ae13SManuel Lauss .platform_data = &db1000_irda_platdata, 425e734ae13SManuel Lauss }, 426e734ae13SManuel Lauss .resource = au1000_irda_res, 427e734ae13SManuel Lauss .num_resources = ARRAY_SIZE(au1000_irda_res), 428e734ae13SManuel Lauss }; 429c9af5144SManuel Lauss 4302a32daf1SManuel Lauss /******************************************************************************/ 4312a32daf1SManuel Lauss 4322a32daf1SManuel Lauss static struct ads7846_platform_data db1100_touch_pd = { 4332a32daf1SManuel Lauss .model = 7846, 4342a32daf1SManuel Lauss .vref_mv = 3300, 4352a32daf1SManuel Lauss .gpio_pendown = 21, 4362a32daf1SManuel Lauss }; 4372a32daf1SManuel Lauss 4382a32daf1SManuel Lauss static struct spi_gpio_platform_data db1100_spictl_pd = { 4392a32daf1SManuel Lauss .sck = 209, 4402a32daf1SManuel Lauss .mosi = 208, 4412a32daf1SManuel Lauss .miso = 207, 4422a32daf1SManuel Lauss .num_chipselect = 1, 4432a32daf1SManuel Lauss }; 4442a32daf1SManuel Lauss 4452a32daf1SManuel Lauss static struct spi_board_info db1100_spi_info[] __initdata = { 4462a32daf1SManuel Lauss [0] = { 4472a32daf1SManuel Lauss .modalias = "ads7846", 4482a32daf1SManuel Lauss .max_speed_hz = 3250000, 4492a32daf1SManuel Lauss .bus_num = 0, 4502a32daf1SManuel Lauss .chip_select = 0, 4512a32daf1SManuel Lauss .mode = 0, 4522a32daf1SManuel Lauss .irq = AU1100_GPIO21_INT, 4532a32daf1SManuel Lauss .platform_data = &db1100_touch_pd, 4542a32daf1SManuel Lauss .controller_data = (void *)210, /* for spi_gpio: CS# GPIO210 */ 4552a32daf1SManuel Lauss }, 4562a32daf1SManuel Lauss }; 4572a32daf1SManuel Lauss 4582a32daf1SManuel Lauss static struct platform_device db1100_spi_dev = { 4592a32daf1SManuel Lauss .name = "spi_gpio", 4602a32daf1SManuel Lauss .id = 0, 4612a32daf1SManuel Lauss .dev = { 4622a32daf1SManuel Lauss .platform_data = &db1100_spictl_pd, 4632a32daf1SManuel Lauss }, 4642a32daf1SManuel Lauss }; 4652a32daf1SManuel Lauss 4662a32daf1SManuel Lauss 467f59c811fSManuel Lauss static struct platform_device *db1x00_devs[] = { 468f59c811fSManuel Lauss &db1x00_codec_dev, 469f59c811fSManuel Lauss &alchemy_ac97c_dma_dev, 470f59c811fSManuel Lauss &alchemy_ac97c_dev, 471f59c811fSManuel Lauss &db1x00_audio_dev, 472f59c811fSManuel Lauss }; 473f59c811fSManuel Lauss 474e734ae13SManuel Lauss static struct platform_device *db1000_devs[] = { 475e734ae13SManuel Lauss &db1000_irda_dev, 476e734ae13SManuel Lauss }; 477e734ae13SManuel Lauss 478f59c811fSManuel Lauss static struct platform_device *db1100_devs[] = { 479f59c811fSManuel Lauss &au1100_lcd_device, 480c9af5144SManuel Lauss &db1100_mmc0_dev, 481c9af5144SManuel Lauss &db1100_mmc1_dev, 482e734ae13SManuel Lauss &db1000_irda_dev, 4832a32daf1SManuel Lauss &db1100_spi_dev, 484f59c811fSManuel Lauss }; 485f59c811fSManuel Lauss 486f59c811fSManuel Lauss static int __init db1000_dev_init(void) 487f59c811fSManuel Lauss { 488f59c811fSManuel Lauss int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); 489f59c811fSManuel Lauss int c0, c1, d0, d1, s0, s1; 4902a32daf1SManuel Lauss unsigned long pfc; 491f59c811fSManuel Lauss 492f59c811fSManuel Lauss if (board == BCSR_WHOAMI_DB1500) { 493f59c811fSManuel Lauss c0 = AU1500_GPIO2_INT; 494f59c811fSManuel Lauss c1 = AU1500_GPIO5_INT; 495f59c811fSManuel Lauss d0 = AU1500_GPIO0_INT; 496f59c811fSManuel Lauss d1 = AU1500_GPIO3_INT; 497f59c811fSManuel Lauss s0 = AU1500_GPIO1_INT; 498f59c811fSManuel Lauss s1 = AU1500_GPIO4_INT; 499f59c811fSManuel Lauss } else if (board == BCSR_WHOAMI_DB1100) { 500f59c811fSManuel Lauss c0 = AU1100_GPIO2_INT; 501f59c811fSManuel Lauss c1 = AU1100_GPIO5_INT; 502f59c811fSManuel Lauss d0 = AU1100_GPIO0_INT; 503f59c811fSManuel Lauss d1 = AU1100_GPIO3_INT; 504f59c811fSManuel Lauss s0 = AU1100_GPIO1_INT; 505f59c811fSManuel Lauss s1 = AU1100_GPIO4_INT; 506c9af5144SManuel Lauss 507c9af5144SManuel Lauss gpio_direction_input(19); /* sd0 cd# */ 508c9af5144SManuel Lauss gpio_direction_input(20); /* sd1 cd# */ 5092a32daf1SManuel Lauss gpio_direction_input(21); /* touch pendown# */ 5102a32daf1SManuel Lauss gpio_direction_input(207); /* SPI MISO */ 5112a32daf1SManuel Lauss gpio_direction_output(208, 0); /* SPI MOSI */ 5122a32daf1SManuel Lauss gpio_direction_output(209, 1); /* SPI SCK */ 5132a32daf1SManuel Lauss gpio_direction_output(210, 1); /* SPI CS# */ 5142a32daf1SManuel Lauss 5152a32daf1SManuel Lauss /* spi_gpio on SSI0 pins */ 5162a32daf1SManuel Lauss pfc = __raw_readl((void __iomem *)SYS_PINFUNC); 5172a32daf1SManuel Lauss pfc |= (1 << 0); /* SSI0 pins as GPIOs */ 5182a32daf1SManuel Lauss __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); 5192a32daf1SManuel Lauss wmb(); 5202a32daf1SManuel Lauss 5212a32daf1SManuel Lauss spi_register_board_info(db1100_spi_info, 5222a32daf1SManuel Lauss ARRAY_SIZE(db1100_spi_info)); 523c9af5144SManuel Lauss 524f59c811fSManuel Lauss platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); 525f59c811fSManuel Lauss } else if (board == BCSR_WHOAMI_DB1000) { 526f59c811fSManuel Lauss c0 = AU1000_GPIO2_INT; 527f59c811fSManuel Lauss c1 = AU1000_GPIO5_INT; 528f59c811fSManuel Lauss d0 = AU1000_GPIO0_INT; 529f59c811fSManuel Lauss d1 = AU1000_GPIO3_INT; 530f59c811fSManuel Lauss s0 = AU1000_GPIO1_INT; 531f59c811fSManuel Lauss s1 = AU1000_GPIO4_INT; 532e734ae13SManuel Lauss platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs)); 533f59c811fSManuel Lauss } else 534f59c811fSManuel Lauss return 0; /* unknown board, no further dev setup to do */ 535f59c811fSManuel Lauss 536f59c811fSManuel Lauss irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH); 537f59c811fSManuel Lauss irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH); 538f59c811fSManuel Lauss irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW); 539f59c811fSManuel Lauss irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW); 540f59c811fSManuel Lauss irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW); 541f59c811fSManuel Lauss irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW); 542f59c811fSManuel Lauss 543f59c811fSManuel Lauss db1x_register_pcmcia_socket( 544f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR, 545f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, 546f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR, 547f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, 548f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR, 549f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, 550f59c811fSManuel Lauss c0, d0, /*s0*/0, 0, 0); 551f59c811fSManuel Lauss 552f59c811fSManuel Lauss db1x_register_pcmcia_socket( 553f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, 554f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, 555f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, 556f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, 557f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, 558f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, 559f59c811fSManuel Lauss c1, d1, /*s1*/0, 0, 1); 560f59c811fSManuel Lauss 561f59c811fSManuel Lauss platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs)); 562f59c811fSManuel Lauss db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED); 563f59c811fSManuel Lauss return 0; 564f59c811fSManuel Lauss } 565f59c811fSManuel Lauss device_initcall(db1000_dev_init); 566