1fd534e9bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2f59c811fSManuel Lauss /* 3851d4f5dSManuel Lauss * DBAu1000/1500/1100 PBAu1100/1500 board support 4f59c811fSManuel Lauss * 5f59c811fSManuel Lauss * Copyright 2000, 2008 MontaVista Software Inc. 6f59c811fSManuel Lauss * Author: MontaVista Software, Inc. <source@mvista.com> 7f59c811fSManuel Lauss */ 8f59c811fSManuel Lauss 96b1889c1SManuel Lauss #include <linux/clk.h> 10f59c811fSManuel Lauss #include <linux/dma-mapping.h> 11f59c811fSManuel Lauss #include <linux/gpio.h> 129b00bc7bSLinus Walleij #include <linux/gpio/machine.h> 13f59c811fSManuel Lauss #include <linux/init.h> 14f59c811fSManuel Lauss #include <linux/interrupt.h> 15c9af5144SManuel Lauss #include <linux/leds.h> 16c9af5144SManuel Lauss #include <linux/mmc/host.h> 17c9af5144SManuel Lauss #include <linux/module.h> 18f59c811fSManuel Lauss #include <linux/platform_device.h> 19f59c811fSManuel Lauss #include <linux/pm.h> 202a32daf1SManuel Lauss #include <linux/spi/spi.h> 212a32daf1SManuel Lauss #include <linux/spi/spi_gpio.h> 222a32daf1SManuel Lauss #include <linux/spi/ads7846.h> 23f59c811fSManuel Lauss #include <asm/mach-au1x00/au1000.h> 24832f5dacSAlban Bedel #include <asm/mach-au1x00/gpio-au1000.h> 25f59c811fSManuel Lauss #include <asm/mach-au1x00/au1000_dma.h> 26c9af5144SManuel Lauss #include <asm/mach-au1x00/au1100_mmc.h> 27f59c811fSManuel Lauss #include <asm/mach-db1x00/bcsr.h> 28f59c811fSManuel Lauss #include <asm/reboot.h> 29f59c811fSManuel Lauss #include <prom.h> 30f59c811fSManuel Lauss #include "platform.h" 31f59c811fSManuel Lauss 32f59c811fSManuel Lauss #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT) 33f59c811fSManuel Lauss 34970e268dSManuel Lauss const char *get_system_type(void); 35f59c811fSManuel Lauss 36970e268dSManuel Lauss int __init db1000_board_setup(void) 37f59c811fSManuel Lauss { 38f59c811fSManuel Lauss /* initialize board register space */ 39f59c811fSManuel Lauss bcsr_init(DB1000_BCSR_PHYS_ADDR, 40f59c811fSManuel Lauss DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS); 41f59c811fSManuel Lauss 42970e268dSManuel Lauss switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { 43970e268dSManuel Lauss case BCSR_WHOAMI_DB1000: 44970e268dSManuel Lauss case BCSR_WHOAMI_DB1500: 45970e268dSManuel Lauss case BCSR_WHOAMI_DB1100: 46970e268dSManuel Lauss case BCSR_WHOAMI_PB1500: 47970e268dSManuel Lauss case BCSR_WHOAMI_PB1500R2: 48970e268dSManuel Lauss case BCSR_WHOAMI_PB1100: 49970e268dSManuel Lauss pr_info("AMD Alchemy %s Board\n", get_system_type()); 50970e268dSManuel Lauss return 0; 51f59c811fSManuel Lauss } 52970e268dSManuel Lauss return -ENODEV; 53970e268dSManuel Lauss } 54f59c811fSManuel Lauss 55f59c811fSManuel Lauss static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) 56f59c811fSManuel Lauss { 57f59c811fSManuel Lauss if ((slot < 12) || (slot > 13) || pin == 0) 58f59c811fSManuel Lauss return -1; 59f59c811fSManuel Lauss if (slot == 12) 60f59c811fSManuel Lauss return (pin == 1) ? AU1500_PCI_INTA : 0xff; 61f59c811fSManuel Lauss if (slot == 13) { 62f59c811fSManuel Lauss switch (pin) { 63f59c811fSManuel Lauss case 1: return AU1500_PCI_INTA; 64f59c811fSManuel Lauss case 2: return AU1500_PCI_INTB; 65f59c811fSManuel Lauss case 3: return AU1500_PCI_INTC; 66f59c811fSManuel Lauss case 4: return AU1500_PCI_INTD; 67f59c811fSManuel Lauss } 68f59c811fSManuel Lauss } 69f59c811fSManuel Lauss return -1; 70f59c811fSManuel Lauss } 71f59c811fSManuel Lauss 72994bc7faSManuel Lauss static u64 au1xxx_all_dmamask = DMA_BIT_MASK(32); 73994bc7faSManuel Lauss 74f59c811fSManuel Lauss static struct resource alchemy_pci_host_res[] = { 75f59c811fSManuel Lauss [0] = { 76f59c811fSManuel Lauss .start = AU1500_PCI_PHYS_ADDR, 77f59c811fSManuel Lauss .end = AU1500_PCI_PHYS_ADDR + 0xfff, 78f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 79f59c811fSManuel Lauss }, 80f59c811fSManuel Lauss }; 81f59c811fSManuel Lauss 82f59c811fSManuel Lauss static struct alchemy_pci_platdata db1500_pci_pd = { 83f59c811fSManuel Lauss .board_map_irq = db1500_map_pci_irq, 84f59c811fSManuel Lauss }; 85f59c811fSManuel Lauss 86f59c811fSManuel Lauss static struct platform_device db1500_pci_host_dev = { 87f59c811fSManuel Lauss .dev.platform_data = &db1500_pci_pd, 88f59c811fSManuel Lauss .name = "alchemy-pci", 89f59c811fSManuel Lauss .id = 0, 90f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(alchemy_pci_host_res), 91f59c811fSManuel Lauss .resource = alchemy_pci_host_res, 92f59c811fSManuel Lauss }; 93f59c811fSManuel Lauss 94970e268dSManuel Lauss int __init db1500_pci_setup(void) 95f59c811fSManuel Lauss { 96f59c811fSManuel Lauss return platform_device_register(&db1500_pci_host_dev); 97f59c811fSManuel Lauss } 98f59c811fSManuel Lauss 99f59c811fSManuel Lauss static struct resource au1100_lcd_resources[] = { 100f59c811fSManuel Lauss [0] = { 101f59c811fSManuel Lauss .start = AU1100_LCD_PHYS_ADDR, 102f59c811fSManuel Lauss .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, 103f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 104f59c811fSManuel Lauss }, 105f59c811fSManuel Lauss [1] = { 106f59c811fSManuel Lauss .start = AU1100_LCD_INT, 107f59c811fSManuel Lauss .end = AU1100_LCD_INT, 108f59c811fSManuel Lauss .flags = IORESOURCE_IRQ, 109f59c811fSManuel Lauss } 110f59c811fSManuel Lauss }; 111f59c811fSManuel Lauss 112f59c811fSManuel Lauss static struct platform_device au1100_lcd_device = { 113f59c811fSManuel Lauss .name = "au1100-lcd", 114f59c811fSManuel Lauss .id = 0, 115f59c811fSManuel Lauss .dev = { 116994bc7faSManuel Lauss .dma_mask = &au1xxx_all_dmamask, 117f59c811fSManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 118f59c811fSManuel Lauss }, 119f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(au1100_lcd_resources), 120f59c811fSManuel Lauss .resource = au1100_lcd_resources, 121f59c811fSManuel Lauss }; 122f59c811fSManuel Lauss 123f59c811fSManuel Lauss static struct resource alchemy_ac97c_res[] = { 124f59c811fSManuel Lauss [0] = { 125f59c811fSManuel Lauss .start = AU1000_AC97_PHYS_ADDR, 126f59c811fSManuel Lauss .end = AU1000_AC97_PHYS_ADDR + 0xfff, 127f59c811fSManuel Lauss .flags = IORESOURCE_MEM, 128f59c811fSManuel Lauss }, 129f59c811fSManuel Lauss [1] = { 130f59c811fSManuel Lauss .start = DMA_ID_AC97C_TX, 131f59c811fSManuel Lauss .end = DMA_ID_AC97C_TX, 132f59c811fSManuel Lauss .flags = IORESOURCE_DMA, 133f59c811fSManuel Lauss }, 134f59c811fSManuel Lauss [2] = { 135f59c811fSManuel Lauss .start = DMA_ID_AC97C_RX, 136f59c811fSManuel Lauss .end = DMA_ID_AC97C_RX, 137f59c811fSManuel Lauss .flags = IORESOURCE_DMA, 138f59c811fSManuel Lauss }, 139f59c811fSManuel Lauss }; 140f59c811fSManuel Lauss 141f59c811fSManuel Lauss static struct platform_device alchemy_ac97c_dev = { 142f59c811fSManuel Lauss .name = "alchemy-ac97c", 143f59c811fSManuel Lauss .id = -1, 144f59c811fSManuel Lauss .resource = alchemy_ac97c_res, 145f59c811fSManuel Lauss .num_resources = ARRAY_SIZE(alchemy_ac97c_res), 146f59c811fSManuel Lauss }; 147f59c811fSManuel Lauss 148f59c811fSManuel Lauss static struct platform_device alchemy_ac97c_dma_dev = { 149f59c811fSManuel Lauss .name = "alchemy-pcm-dma", 150f59c811fSManuel Lauss .id = 0, 151f59c811fSManuel Lauss }; 152f59c811fSManuel Lauss 153f59c811fSManuel Lauss static struct platform_device db1x00_codec_dev = { 154f59c811fSManuel Lauss .name = "ac97-codec", 155f59c811fSManuel Lauss .id = -1, 156f59c811fSManuel Lauss }; 157f59c811fSManuel Lauss 158f59c811fSManuel Lauss static struct platform_device db1x00_audio_dev = { 159f59c811fSManuel Lauss .name = "db1000-audio", 160994bc7faSManuel Lauss .dev = { 161994bc7faSManuel Lauss .dma_mask = &au1xxx_all_dmamask, 162994bc7faSManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 163994bc7faSManuel Lauss }, 164f59c811fSManuel Lauss }; 165f59c811fSManuel Lauss 166c9af5144SManuel Lauss /******************************************************************************/ 167c9af5144SManuel Lauss 168c9af5144SManuel Lauss static irqreturn_t db1100_mmc_cd(int irq, void *ptr) 169c9af5144SManuel Lauss { 170c9af5144SManuel Lauss void (*mmc_cd)(struct mmc_host *, unsigned long); 171c9af5144SManuel Lauss /* link against CONFIG_MMC=m */ 172c9af5144SManuel Lauss mmc_cd = symbol_get(mmc_detect_change); 173c9af5144SManuel Lauss mmc_cd(ptr, msecs_to_jiffies(500)); 174c9af5144SManuel Lauss symbol_put(mmc_detect_change); 175c9af5144SManuel Lauss 176c9af5144SManuel Lauss return IRQ_HANDLED; 177c9af5144SManuel Lauss } 178c9af5144SManuel Lauss 179c9af5144SManuel Lauss static int db1100_mmc_cd_setup(void *mmc_host, int en) 180c9af5144SManuel Lauss { 181851d4f5dSManuel Lauss int ret = 0, irq; 182851d4f5dSManuel Lauss 183851d4f5dSManuel Lauss if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) 184851d4f5dSManuel Lauss irq = AU1100_GPIO19_INT; 185851d4f5dSManuel Lauss else 186851d4f5dSManuel Lauss irq = AU1100_GPIO14_INT; /* PB1100 SD0 CD# */ 187c9af5144SManuel Lauss 188c9af5144SManuel Lauss if (en) { 189851d4f5dSManuel Lauss irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); 190851d4f5dSManuel Lauss ret = request_irq(irq, db1100_mmc_cd, 0, 191c9af5144SManuel Lauss "sd0_cd", mmc_host); 192c9af5144SManuel Lauss } else 193851d4f5dSManuel Lauss free_irq(irq, mmc_host); 194c9af5144SManuel Lauss return ret; 195c9af5144SManuel Lauss } 196c9af5144SManuel Lauss 197c9af5144SManuel Lauss static int db1100_mmc1_cd_setup(void *mmc_host, int en) 198c9af5144SManuel Lauss { 199851d4f5dSManuel Lauss int ret = 0, irq; 200851d4f5dSManuel Lauss 201851d4f5dSManuel Lauss if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) 202851d4f5dSManuel Lauss irq = AU1100_GPIO20_INT; 203851d4f5dSManuel Lauss else 204851d4f5dSManuel Lauss irq = AU1100_GPIO15_INT; /* PB1100 SD1 CD# */ 205c9af5144SManuel Lauss 206c9af5144SManuel Lauss if (en) { 207851d4f5dSManuel Lauss irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); 208851d4f5dSManuel Lauss ret = request_irq(irq, db1100_mmc_cd, 0, 209c9af5144SManuel Lauss "sd1_cd", mmc_host); 210c9af5144SManuel Lauss } else 211851d4f5dSManuel Lauss free_irq(irq, mmc_host); 212c9af5144SManuel Lauss return ret; 213c9af5144SManuel Lauss } 214c9af5144SManuel Lauss 215c9af5144SManuel Lauss static int db1100_mmc_card_readonly(void *mmc_host) 216c9af5144SManuel Lauss { 217c9af5144SManuel Lauss /* testing suggests that this bit is inverted */ 218c9af5144SManuel Lauss return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1; 219c9af5144SManuel Lauss } 220c9af5144SManuel Lauss 221c9af5144SManuel Lauss static int db1100_mmc_card_inserted(void *mmc_host) 222c9af5144SManuel Lauss { 223c9af5144SManuel Lauss return !alchemy_gpio_get_value(19); 224c9af5144SManuel Lauss } 225c9af5144SManuel Lauss 226c9af5144SManuel Lauss static void db1100_mmc_set_power(void *mmc_host, int state) 227c9af5144SManuel Lauss { 228851d4f5dSManuel Lauss int bit; 229851d4f5dSManuel Lauss 230851d4f5dSManuel Lauss if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) 231851d4f5dSManuel Lauss bit = BCSR_BOARD_SD0PWR; 232851d4f5dSManuel Lauss else 233851d4f5dSManuel Lauss bit = BCSR_BOARD_PB1100_SD0PWR; 234851d4f5dSManuel Lauss 235c9af5144SManuel Lauss if (state) { 236851d4f5dSManuel Lauss bcsr_mod(BCSR_BOARD, 0, bit); 237c9af5144SManuel Lauss msleep(400); /* stabilization time */ 238c9af5144SManuel Lauss } else 239851d4f5dSManuel Lauss bcsr_mod(BCSR_BOARD, bit, 0); 240c9af5144SManuel Lauss } 241c9af5144SManuel Lauss 242c9af5144SManuel Lauss static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b) 243c9af5144SManuel Lauss { 244c9af5144SManuel Lauss if (b != LED_OFF) 245c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0); 246c9af5144SManuel Lauss else 247c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0); 248c9af5144SManuel Lauss } 249c9af5144SManuel Lauss 250c9af5144SManuel Lauss static struct led_classdev db1100_mmc_led = { 251c9af5144SManuel Lauss .brightness_set = db1100_mmcled_set, 252c9af5144SManuel Lauss }; 253c9af5144SManuel Lauss 254c9af5144SManuel Lauss static int db1100_mmc1_card_readonly(void *mmc_host) 255c9af5144SManuel Lauss { 256c9af5144SManuel Lauss return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0; 257c9af5144SManuel Lauss } 258c9af5144SManuel Lauss 259c9af5144SManuel Lauss static int db1100_mmc1_card_inserted(void *mmc_host) 260c9af5144SManuel Lauss { 261c9af5144SManuel Lauss return !alchemy_gpio_get_value(20); 262c9af5144SManuel Lauss } 263c9af5144SManuel Lauss 264c9af5144SManuel Lauss static void db1100_mmc1_set_power(void *mmc_host, int state) 265c9af5144SManuel Lauss { 266851d4f5dSManuel Lauss int bit; 267851d4f5dSManuel Lauss 268851d4f5dSManuel Lauss if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) 269851d4f5dSManuel Lauss bit = BCSR_BOARD_SD1PWR; 270851d4f5dSManuel Lauss else 271851d4f5dSManuel Lauss bit = BCSR_BOARD_PB1100_SD1PWR; 272851d4f5dSManuel Lauss 273c9af5144SManuel Lauss if (state) { 274851d4f5dSManuel Lauss bcsr_mod(BCSR_BOARD, 0, bit); 275c9af5144SManuel Lauss msleep(400); /* stabilization time */ 276c9af5144SManuel Lauss } else 277851d4f5dSManuel Lauss bcsr_mod(BCSR_BOARD, bit, 0); 278c9af5144SManuel Lauss } 279c9af5144SManuel Lauss 280c9af5144SManuel Lauss static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b) 281c9af5144SManuel Lauss { 282c9af5144SManuel Lauss if (b != LED_OFF) 283c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0); 284c9af5144SManuel Lauss else 285c9af5144SManuel Lauss bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1); 286c9af5144SManuel Lauss } 287c9af5144SManuel Lauss 288c9af5144SManuel Lauss static struct led_classdev db1100_mmc1_led = { 289c9af5144SManuel Lauss .brightness_set = db1100_mmc1led_set, 290c9af5144SManuel Lauss }; 291c9af5144SManuel Lauss 292c9af5144SManuel Lauss static struct au1xmmc_platform_data db1100_mmc_platdata[2] = { 293c9af5144SManuel Lauss [0] = { 294c9af5144SManuel Lauss .cd_setup = db1100_mmc_cd_setup, 295c9af5144SManuel Lauss .set_power = db1100_mmc_set_power, 296c9af5144SManuel Lauss .card_inserted = db1100_mmc_card_inserted, 297c9af5144SManuel Lauss .card_readonly = db1100_mmc_card_readonly, 298c9af5144SManuel Lauss .led = &db1100_mmc_led, 299c9af5144SManuel Lauss }, 300c9af5144SManuel Lauss [1] = { 301c9af5144SManuel Lauss .cd_setup = db1100_mmc1_cd_setup, 302c9af5144SManuel Lauss .set_power = db1100_mmc1_set_power, 303c9af5144SManuel Lauss .card_inserted = db1100_mmc1_card_inserted, 304c9af5144SManuel Lauss .card_readonly = db1100_mmc1_card_readonly, 305c9af5144SManuel Lauss .led = &db1100_mmc1_led, 306c9af5144SManuel Lauss }, 307c9af5144SManuel Lauss }; 308c9af5144SManuel Lauss 309c9af5144SManuel Lauss static struct resource au1100_mmc0_resources[] = { 310c9af5144SManuel Lauss [0] = { 311c9af5144SManuel Lauss .start = AU1100_SD0_PHYS_ADDR, 312c9af5144SManuel Lauss .end = AU1100_SD0_PHYS_ADDR + 0xfff, 313c9af5144SManuel Lauss .flags = IORESOURCE_MEM, 314c9af5144SManuel Lauss }, 315c9af5144SManuel Lauss [1] = { 316c9af5144SManuel Lauss .start = AU1100_SD_INT, 317c9af5144SManuel Lauss .end = AU1100_SD_INT, 318c9af5144SManuel Lauss .flags = IORESOURCE_IRQ, 319c9af5144SManuel Lauss }, 320c9af5144SManuel Lauss [2] = { 321c9af5144SManuel Lauss .start = DMA_ID_SD0_TX, 322c9af5144SManuel Lauss .end = DMA_ID_SD0_TX, 323c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 324c9af5144SManuel Lauss }, 325c9af5144SManuel Lauss [3] = { 326c9af5144SManuel Lauss .start = DMA_ID_SD0_RX, 327c9af5144SManuel Lauss .end = DMA_ID_SD0_RX, 328c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 329c9af5144SManuel Lauss } 330c9af5144SManuel Lauss }; 331c9af5144SManuel Lauss 332c9af5144SManuel Lauss static struct platform_device db1100_mmc0_dev = { 333c9af5144SManuel Lauss .name = "au1xxx-mmc", 334c9af5144SManuel Lauss .id = 0, 335c9af5144SManuel Lauss .dev = { 336994bc7faSManuel Lauss .dma_mask = &au1xxx_all_dmamask, 337c9af5144SManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 338c9af5144SManuel Lauss .platform_data = &db1100_mmc_platdata[0], 339c9af5144SManuel Lauss }, 340c9af5144SManuel Lauss .num_resources = ARRAY_SIZE(au1100_mmc0_resources), 341c9af5144SManuel Lauss .resource = au1100_mmc0_resources, 342c9af5144SManuel Lauss }; 343c9af5144SManuel Lauss 344c9af5144SManuel Lauss static struct resource au1100_mmc1_res[] = { 345c9af5144SManuel Lauss [0] = { 346c9af5144SManuel Lauss .start = AU1100_SD1_PHYS_ADDR, 347c9af5144SManuel Lauss .end = AU1100_SD1_PHYS_ADDR + 0xfff, 348c9af5144SManuel Lauss .flags = IORESOURCE_MEM, 349c9af5144SManuel Lauss }, 350c9af5144SManuel Lauss [1] = { 351c9af5144SManuel Lauss .start = AU1100_SD_INT, 352c9af5144SManuel Lauss .end = AU1100_SD_INT, 353c9af5144SManuel Lauss .flags = IORESOURCE_IRQ, 354c9af5144SManuel Lauss }, 355c9af5144SManuel Lauss [2] = { 356c9af5144SManuel Lauss .start = DMA_ID_SD1_TX, 357c9af5144SManuel Lauss .end = DMA_ID_SD1_TX, 358c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 359c9af5144SManuel Lauss }, 360c9af5144SManuel Lauss [3] = { 361c9af5144SManuel Lauss .start = DMA_ID_SD1_RX, 362c9af5144SManuel Lauss .end = DMA_ID_SD1_RX, 363c9af5144SManuel Lauss .flags = IORESOURCE_DMA, 364c9af5144SManuel Lauss } 365c9af5144SManuel Lauss }; 366c9af5144SManuel Lauss 367c9af5144SManuel Lauss static struct platform_device db1100_mmc1_dev = { 368c9af5144SManuel Lauss .name = "au1xxx-mmc", 369c9af5144SManuel Lauss .id = 1, 370c9af5144SManuel Lauss .dev = { 371994bc7faSManuel Lauss .dma_mask = &au1xxx_all_dmamask, 372c9af5144SManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 373c9af5144SManuel Lauss .platform_data = &db1100_mmc_platdata[1], 374c9af5144SManuel Lauss }, 375c9af5144SManuel Lauss .num_resources = ARRAY_SIZE(au1100_mmc1_res), 376c9af5144SManuel Lauss .resource = au1100_mmc1_res, 377c9af5144SManuel Lauss }; 378c9af5144SManuel Lauss 379e734ae13SManuel Lauss /******************************************************************************/ 380e734ae13SManuel Lauss 3812a32daf1SManuel Lauss static struct ads7846_platform_data db1100_touch_pd = { 3822a32daf1SManuel Lauss .model = 7846, 3832a32daf1SManuel Lauss .vref_mv = 3300, 3842a32daf1SManuel Lauss .gpio_pendown = 21, 3852a32daf1SManuel Lauss }; 3862a32daf1SManuel Lauss 3872a32daf1SManuel Lauss static struct spi_gpio_platform_data db1100_spictl_pd = { 3882a32daf1SManuel Lauss .num_chipselect = 1, 3892a32daf1SManuel Lauss }; 3902a32daf1SManuel Lauss 3912a32daf1SManuel Lauss static struct spi_board_info db1100_spi_info[] __initdata = { 3922a32daf1SManuel Lauss [0] = { 3932a32daf1SManuel Lauss .modalias = "ads7846", 3942a32daf1SManuel Lauss .max_speed_hz = 3250000, 3952a32daf1SManuel Lauss .bus_num = 0, 3962a32daf1SManuel Lauss .chip_select = 0, 3972a32daf1SManuel Lauss .mode = 0, 3982a32daf1SManuel Lauss .irq = AU1100_GPIO21_INT, 3992a32daf1SManuel Lauss .platform_data = &db1100_touch_pd, 4002a32daf1SManuel Lauss }, 4012a32daf1SManuel Lauss }; 4022a32daf1SManuel Lauss 4032a32daf1SManuel Lauss static struct platform_device db1100_spi_dev = { 4042a32daf1SManuel Lauss .name = "spi_gpio", 4052a32daf1SManuel Lauss .id = 0, 4062a32daf1SManuel Lauss .dev = { 4072a32daf1SManuel Lauss .platform_data = &db1100_spictl_pd, 408994bc7faSManuel Lauss .dma_mask = &au1xxx_all_dmamask, 409994bc7faSManuel Lauss .coherent_dma_mask = DMA_BIT_MASK(32), 4102a32daf1SManuel Lauss }, 4112a32daf1SManuel Lauss }; 4122a32daf1SManuel Lauss 4139b00bc7bSLinus Walleij /* 4149b00bc7bSLinus Walleij * Alchemy GPIO 2 has its base at 200 so the GPIO lines 4159b00bc7bSLinus Walleij * 207 thru 210 are GPIOs at offset 7 thru 10 at this chip. 4169b00bc7bSLinus Walleij */ 4179b00bc7bSLinus Walleij static struct gpiod_lookup_table db1100_spi_gpiod_table = { 4189b00bc7bSLinus Walleij .dev_id = "spi_gpio", 4199b00bc7bSLinus Walleij .table = { 4209b00bc7bSLinus Walleij GPIO_LOOKUP("alchemy-gpio2", 9, 4219b00bc7bSLinus Walleij "sck", GPIO_ACTIVE_HIGH), 4229b00bc7bSLinus Walleij GPIO_LOOKUP("alchemy-gpio2", 8, 4239b00bc7bSLinus Walleij "mosi", GPIO_ACTIVE_HIGH), 4249b00bc7bSLinus Walleij GPIO_LOOKUP("alchemy-gpio2", 7, 4259b00bc7bSLinus Walleij "miso", GPIO_ACTIVE_HIGH), 4269b00bc7bSLinus Walleij GPIO_LOOKUP("alchemy-gpio2", 10, 4279b00bc7bSLinus Walleij "cs", GPIO_ACTIVE_HIGH), 4289b00bc7bSLinus Walleij { }, 4299b00bc7bSLinus Walleij }, 4309b00bc7bSLinus Walleij }; 4312a32daf1SManuel Lauss 432f59c811fSManuel Lauss static struct platform_device *db1x00_devs[] = { 433f59c811fSManuel Lauss &db1x00_codec_dev, 434f59c811fSManuel Lauss &alchemy_ac97c_dma_dev, 435f59c811fSManuel Lauss &alchemy_ac97c_dev, 436f59c811fSManuel Lauss &db1x00_audio_dev, 437f59c811fSManuel Lauss }; 438f59c811fSManuel Lauss 439f59c811fSManuel Lauss static struct platform_device *db1100_devs[] = { 440f59c811fSManuel Lauss &au1100_lcd_device, 441c9af5144SManuel Lauss &db1100_mmc0_dev, 442c9af5144SManuel Lauss &db1100_mmc1_dev, 443f59c811fSManuel Lauss }; 444f59c811fSManuel Lauss 445970e268dSManuel Lauss int __init db1000_dev_setup(void) 446f59c811fSManuel Lauss { 447f59c811fSManuel Lauss int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); 448851d4f5dSManuel Lauss int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1; 4492a32daf1SManuel Lauss unsigned long pfc; 4506b1889c1SManuel Lauss struct clk *c, *p; 451f59c811fSManuel Lauss 452f59c811fSManuel Lauss if (board == BCSR_WHOAMI_DB1500) { 453f59c811fSManuel Lauss c0 = AU1500_GPIO2_INT; 454f59c811fSManuel Lauss c1 = AU1500_GPIO5_INT; 455e34b6fcfSManuel Lauss d0 = 0; /* GPIO number, NOT irq! */ 456e34b6fcfSManuel Lauss d1 = 3; /* GPIO number, NOT irq! */ 457f59c811fSManuel Lauss s0 = AU1500_GPIO1_INT; 458f59c811fSManuel Lauss s1 = AU1500_GPIO4_INT; 459f59c811fSManuel Lauss } else if (board == BCSR_WHOAMI_DB1100) { 460f59c811fSManuel Lauss c0 = AU1100_GPIO2_INT; 461f59c811fSManuel Lauss c1 = AU1100_GPIO5_INT; 462e34b6fcfSManuel Lauss d0 = 0; /* GPIO number, NOT irq! */ 463e34b6fcfSManuel Lauss d1 = 3; /* GPIO number, NOT irq! */ 464f59c811fSManuel Lauss s0 = AU1100_GPIO1_INT; 465f59c811fSManuel Lauss s1 = AU1100_GPIO4_INT; 466c9af5144SManuel Lauss 4674294ad1cSManuel Lauss gpio_request(19, "sd0_cd"); 4684294ad1cSManuel Lauss gpio_request(20, "sd1_cd"); 469c9af5144SManuel Lauss gpio_direction_input(19); /* sd0 cd# */ 470c9af5144SManuel Lauss gpio_direction_input(20); /* sd1 cd# */ 4712a32daf1SManuel Lauss 4722a32daf1SManuel Lauss /* spi_gpio on SSI0 pins */ 4731d09de7dSManuel Lauss pfc = alchemy_rdsys(AU1000_SYS_PINFUNC); 4742a32daf1SManuel Lauss pfc |= (1 << 0); /* SSI0 pins as GPIOs */ 4751d09de7dSManuel Lauss alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); 4762a32daf1SManuel Lauss 4772a32daf1SManuel Lauss spi_register_board_info(db1100_spi_info, 4782a32daf1SManuel Lauss ARRAY_SIZE(db1100_spi_info)); 479c9af5144SManuel Lauss 4806b1889c1SManuel Lauss /* link LCD clock to AUXPLL */ 4816b1889c1SManuel Lauss p = clk_get(NULL, "auxpll_clk"); 4826b1889c1SManuel Lauss c = clk_get(NULL, "lcd_intclk"); 4836b1889c1SManuel Lauss if (!IS_ERR(c) && !IS_ERR(p)) { 4846b1889c1SManuel Lauss clk_set_parent(c, p); 4856b1889c1SManuel Lauss clk_set_rate(c, clk_get_rate(p)); 4866b1889c1SManuel Lauss } 4876b1889c1SManuel Lauss if (!IS_ERR(c)) 4886b1889c1SManuel Lauss clk_put(c); 4896b1889c1SManuel Lauss if (!IS_ERR(p)) 4906b1889c1SManuel Lauss clk_put(p); 4916b1889c1SManuel Lauss 492f59c811fSManuel Lauss platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); 4939b00bc7bSLinus Walleij gpiod_add_lookup_table(&db1100_spi_gpiod_table); 494851d4f5dSManuel Lauss platform_device_register(&db1100_spi_dev); 495f59c811fSManuel Lauss } else if (board == BCSR_WHOAMI_DB1000) { 496f59c811fSManuel Lauss c0 = AU1000_GPIO2_INT; 497f59c811fSManuel Lauss c1 = AU1000_GPIO5_INT; 498e34b6fcfSManuel Lauss d0 = 0; /* GPIO number, NOT irq! */ 499e34b6fcfSManuel Lauss d1 = 3; /* GPIO number, NOT irq! */ 500f59c811fSManuel Lauss s0 = AU1000_GPIO1_INT; 501f59c811fSManuel Lauss s1 = AU1000_GPIO4_INT; 502851d4f5dSManuel Lauss } else if ((board == BCSR_WHOAMI_PB1500) || 503851d4f5dSManuel Lauss (board == BCSR_WHOAMI_PB1500R2)) { 504851d4f5dSManuel Lauss c0 = AU1500_GPIO203_INT; 505e34b6fcfSManuel Lauss d0 = 1; /* GPIO number, NOT irq! */ 506851d4f5dSManuel Lauss s0 = AU1500_GPIO202_INT; 507851d4f5dSManuel Lauss twosocks = 0; 508851d4f5dSManuel Lauss flashsize = 64; 509851d4f5dSManuel Lauss /* RTC and daughtercard irqs */ 510851d4f5dSManuel Lauss irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_LOW); 511851d4f5dSManuel Lauss irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW); 512851d4f5dSManuel Lauss /* EPSON S1D13806 0x1b000000 513851d4f5dSManuel Lauss * SRAM 1MB/2MB 0x1a000000 514851d4f5dSManuel Lauss * DS1693 RTC 0x0c000000 515851d4f5dSManuel Lauss */ 516851d4f5dSManuel Lauss } else if (board == BCSR_WHOAMI_PB1100) { 517851d4f5dSManuel Lauss c0 = AU1100_GPIO11_INT; 518e34b6fcfSManuel Lauss d0 = 9; /* GPIO number, NOT irq! */ 519851d4f5dSManuel Lauss s0 = AU1100_GPIO10_INT; 520851d4f5dSManuel Lauss twosocks = 0; 521851d4f5dSManuel Lauss flashsize = 64; 522851d4f5dSManuel Lauss /* pendown, rtc, daughtercard irqs */ 523851d4f5dSManuel Lauss irq_set_irq_type(AU1100_GPIO8_INT, IRQ_TYPE_LEVEL_LOW); 524851d4f5dSManuel Lauss irq_set_irq_type(AU1100_GPIO12_INT, IRQ_TYPE_LEVEL_LOW); 525851d4f5dSManuel Lauss irq_set_irq_type(AU1100_GPIO13_INT, IRQ_TYPE_LEVEL_LOW); 526851d4f5dSManuel Lauss /* EPSON S1D13806 0x1b000000 527851d4f5dSManuel Lauss * SRAM 1MB/2MB 0x1a000000 528851d4f5dSManuel Lauss * DiskOnChip 0x0d000000 529851d4f5dSManuel Lauss * DS1693 RTC 0x0c000000 530851d4f5dSManuel Lauss */ 531851d4f5dSManuel Lauss platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); 532f59c811fSManuel Lauss } else 533f59c811fSManuel Lauss return 0; /* unknown board, no further dev setup to do */ 534f59c811fSManuel Lauss 535f59c811fSManuel Lauss irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW); 536f59c811fSManuel Lauss irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW); 537f59c811fSManuel Lauss 538f59c811fSManuel Lauss db1x_register_pcmcia_socket( 539f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR, 540f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, 541f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR, 542f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, 543f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR, 544f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, 545f59c811fSManuel Lauss c0, d0, /*s0*/0, 0, 0); 546f59c811fSManuel Lauss 547851d4f5dSManuel Lauss if (twosocks) { 548851d4f5dSManuel Lauss irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW); 549851d4f5dSManuel Lauss irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW); 550851d4f5dSManuel Lauss 551f59c811fSManuel Lauss db1x_register_pcmcia_socket( 552f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, 553f59c811fSManuel Lauss AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, 554f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, 555f59c811fSManuel Lauss AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, 556f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, 557f59c811fSManuel Lauss AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, 558f59c811fSManuel Lauss c1, d1, /*s1*/0, 0, 1); 559851d4f5dSManuel Lauss } 560f59c811fSManuel Lauss 561f59c811fSManuel Lauss platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs)); 562851d4f5dSManuel Lauss db1x_register_norflash(flashsize << 20, 4 /* 32bit */, F_SWAPPED); 563f59c811fSManuel Lauss return 0; 564f59c811fSManuel Lauss } 565