blob: e2cc5f921538dd0ca3e5d8531c9017fb8138b1b9 [file] [log] [blame]
Manuel Lauss63323ec2009-11-02 21:21:43 +01001/*
2 * DBAu1200 board platform device registration
3 *
Manuel Lauss7c4b24d2011-11-10 12:06:21 +00004 * Copyright (C) 2008-2011 Manuel Lauss
Manuel Lauss63323ec2009-11-02 21:21:43 +01005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <linux/dma-mapping.h>
22#include <linux/gpio.h>
23#include <linux/i2c.h>
24#include <linux/init.h>
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000025#include <linux/interrupt.h>
Manuel Lauss63323ec2009-11-02 21:21:43 +010026#include <linux/io.h>
27#include <linux/leds.h>
28#include <linux/mmc/host.h>
29#include <linux/mtd/mtd.h>
30#include <linux/mtd/nand.h>
31#include <linux/mtd/partitions.h>
32#include <linux/platform_device.h>
33#include <linux/serial_8250.h>
34#include <linux/spi/spi.h>
35#include <linux/spi/flash.h>
36#include <linux/smc91x.h>
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000037#include <asm/mach-au1x00/au1000.h>
Manuel Lauss63323ec2009-11-02 21:21:43 +010038#include <asm/mach-au1x00/au1100_mmc.h>
39#include <asm/mach-au1x00/au1xxx_dbdma.h>
Manuel Laussa9b71a82011-11-10 12:06:21 +000040#include <asm/mach-au1x00/au1200fb.h>
Manuel Lauss63323ec2009-11-02 21:21:43 +010041#include <asm/mach-au1x00/au1550_spi.h>
42#include <asm/mach-db1x00/bcsr.h>
43#include <asm/mach-db1x00/db1200.h>
44
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000045#include "platform.h"
46
47
48const char *get_system_type(void)
49{
50 return "DB1200";
51}
52
53void __init board_setup(void)
54{
55 unsigned long freq0, clksrc, div, pfc;
56 unsigned short whoami;
57
58 bcsr_init(DB1200_BCSR_PHYS_ADDR,
59 DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
60
61 whoami = bcsr_read(BCSR_WHOAMI);
62 printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
63 " Board-ID %d Daughtercard ID %d\n",
64 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
65
66 /* SMBus/SPI on PSC0, Audio on PSC1 */
67 pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
68 pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
69 pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
70 pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
71 __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
72 wmb();
73
74 /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
75 * CPU clock; all other clock generators off/unused.
76 */
77 div = (get_au1x00_speed() + 25000000) / 50000000;
78 if (div & 1)
79 div++;
80 div = ((div >> 1) - 1) & 0xff;
81
82 freq0 = div << SYS_FC_FRDIV0_BIT;
83 __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
84 wmb();
85 freq0 |= SYS_FC_FE0; /* enable F0 */
86 __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
87 wmb();
88
89 /* psc0_intclk comes 1:1 from F0 */
90 clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
91 __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
92 wmb();
93}
94
95/******************************************************************************/
Manuel Lauss63323ec2009-11-02 21:21:43 +010096
97static struct mtd_partition db1200_spiflash_parts[] = {
98 {
99 .name = "DB1200 SPI flash",
100 .offset = 0,
101 .size = MTDPART_SIZ_FULL,
102 },
103};
104
105static struct flash_platform_data db1200_spiflash_data = {
106 .name = "s25fl001",
107 .parts = db1200_spiflash_parts,
108 .nr_parts = ARRAY_SIZE(db1200_spiflash_parts),
109 .type = "m25p10",
110};
111
112static struct spi_board_info db1200_spi_devs[] __initdata = {
113 {
114 /* TI TMP121AIDBVR temp sensor */
115 .modalias = "tmp121",
116 .max_speed_hz = 2000000,
117 .bus_num = 0,
118 .chip_select = 0,
119 .mode = 0,
120 },
121 {
122 /* Spansion S25FL001D0FMA SPI flash */
123 .modalias = "m25p80",
124 .max_speed_hz = 50000000,
125 .bus_num = 0,
126 .chip_select = 1,
127 .mode = 0,
128 .platform_data = &db1200_spiflash_data,
129 },
130};
131
132static struct i2c_board_info db1200_i2c_devs[] __initdata = {
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000133 { I2C_BOARD_INFO("24c04", 0x52), }, /* AT24C04-10 I2C eeprom */
134 { I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */
135 { I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec WM8731 */
Manuel Lauss63323ec2009-11-02 21:21:43 +0100136};
137
138/**********************************************************************/
139
140static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
141 unsigned int ctrl)
142{
143 struct nand_chip *this = mtd->priv;
144 unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
145
146 ioaddr &= 0xffffff00;
147
148 if (ctrl & NAND_CLE) {
149 ioaddr += MEM_STNAND_CMD;
150 } else if (ctrl & NAND_ALE) {
151 ioaddr += MEM_STNAND_ADDR;
152 } else {
153 /* assume we want to r/w real data by default */
154 ioaddr += MEM_STNAND_DATA;
155 }
156 this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
157 if (cmd != NAND_CMD_NONE) {
158 __raw_writeb(cmd, this->IO_ADDR_W);
159 wmb();
160 }
161}
162
163static int au1200_nand_device_ready(struct mtd_info *mtd)
164{
165 return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
166}
167
168static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
169
170static struct mtd_partition db1200_nand_parts[] = {
171 {
172 .name = "NAND FS 0",
173 .offset = 0,
174 .size = 8 * 1024 * 1024,
175 },
176 {
177 .name = "NAND FS 1",
178 .offset = MTDPART_OFS_APPEND,
179 .size = MTDPART_SIZ_FULL
180 },
181};
182
183struct platform_nand_data db1200_nand_platdata = {
184 .chip = {
185 .nr_chips = 1,
186 .chip_offset = 0,
187 .nr_partitions = ARRAY_SIZE(db1200_nand_parts),
188 .partitions = db1200_nand_parts,
189 .chip_delay = 20,
190 .part_probe_types = db1200_part_probes,
191 },
192 .ctrl = {
193 .dev_ready = au1200_nand_device_ready,
194 .cmd_ctrl = au1200_nand_cmd_ctrl,
195 },
196};
197
198static struct resource db1200_nand_res[] = {
199 [0] = {
200 .start = DB1200_NAND_PHYS_ADDR,
201 .end = DB1200_NAND_PHYS_ADDR + 0xff,
202 .flags = IORESOURCE_MEM,
203 },
204};
205
206static struct platform_device db1200_nand_dev = {
207 .name = "gen_nand",
208 .num_resources = ARRAY_SIZE(db1200_nand_res),
209 .resource = db1200_nand_res,
210 .id = -1,
211 .dev = {
212 .platform_data = &db1200_nand_platdata,
213 }
214};
215
216/**********************************************************************/
217
218static struct smc91x_platdata db1200_eth_data = {
219 .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
220 .leda = RPC_LED_100_10,
221 .ledb = RPC_LED_TX_RX,
222};
223
224static struct resource db1200_eth_res[] = {
225 [0] = {
226 .start = DB1200_ETH_PHYS_ADDR,
227 .end = DB1200_ETH_PHYS_ADDR + 0xf,
228 .flags = IORESOURCE_MEM,
229 },
230 [1] = {
231 .start = DB1200_ETH_INT,
232 .end = DB1200_ETH_INT,
233 .flags = IORESOURCE_IRQ,
234 },
235};
236
237static struct platform_device db1200_eth_dev = {
238 .dev = {
239 .platform_data = &db1200_eth_data,
240 },
241 .name = "smc91x",
242 .id = -1,
243 .num_resources = ARRAY_SIZE(db1200_eth_res),
244 .resource = db1200_eth_res,
245};
246
247/**********************************************************************/
248
249static struct resource db1200_ide_res[] = {
250 [0] = {
251 .start = DB1200_IDE_PHYS_ADDR,
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000252 .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100253 .flags = IORESOURCE_MEM,
254 },
255 [1] = {
256 .start = DB1200_IDE_INT,
257 .end = DB1200_IDE_INT,
258 .flags = IORESOURCE_IRQ,
Manuel Laussd4f07ae2011-08-18 11:11:58 +0200259 },
260 [2] = {
Manuel Laussf2e442f2011-08-12 11:39:42 +0200261 .start = AU1200_DSCR_CMD0_DMA_REQ1,
262 .end = AU1200_DSCR_CMD0_DMA_REQ1,
Manuel Laussd4f07ae2011-08-18 11:11:58 +0200263 .flags = IORESOURCE_DMA,
264 },
Manuel Lauss63323ec2009-11-02 21:21:43 +0100265};
266
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000267static u64 au1200_ide_dmamask = DMA_BIT_MASK(32);
Manuel Lauss63323ec2009-11-02 21:21:43 +0100268
269static struct platform_device db1200_ide_dev = {
270 .name = "au1200-ide",
271 .id = 0,
272 .dev = {
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000273 .dma_mask = &au1200_ide_dmamask,
FUJITA Tomonori25c8f832010-06-24 01:26:09 +0900274 .coherent_dma_mask = DMA_BIT_MASK(32),
Manuel Lauss63323ec2009-11-02 21:21:43 +0100275 },
276 .num_resources = ARRAY_SIZE(db1200_ide_res),
277 .resource = db1200_ide_res,
278};
279
280/**********************************************************************/
281
282static struct platform_device db1200_rtc_dev = {
283 .name = "rtc-au1xxx",
284 .id = -1,
285};
286
287/**********************************************************************/
288
289/* SD carddetects: they're supposed to be edge-triggered, but ack
290 * doesn't seem to work (CPLD Rev 2). Instead, the screaming one
291 * is disabled and its counterpart enabled. The 500ms timeout is
292 * because the carddetect isn't debounced in hardware.
293 */
294static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
295{
296 void(*mmc_cd)(struct mmc_host *, unsigned long);
297
298 if (irq == DB1200_SD0_INSERT_INT) {
299 disable_irq_nosync(DB1200_SD0_INSERT_INT);
300 enable_irq(DB1200_SD0_EJECT_INT);
301 } else {
302 disable_irq_nosync(DB1200_SD0_EJECT_INT);
303 enable_irq(DB1200_SD0_INSERT_INT);
304 }
305
306 /* link against CONFIG_MMC=m */
307 mmc_cd = symbol_get(mmc_detect_change);
308 if (mmc_cd) {
309 mmc_cd(ptr, msecs_to_jiffies(500));
310 symbol_put(mmc_detect_change);
311 }
312
313 return IRQ_HANDLED;
314}
315
316static int db1200_mmc_cd_setup(void *mmc_host, int en)
317{
318 int ret;
319
320 if (en) {
321 ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
322 IRQF_DISABLED, "sd_insert", mmc_host);
323 if (ret)
324 goto out;
325
326 ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
327 IRQF_DISABLED, "sd_eject", mmc_host);
328 if (ret) {
329 free_irq(DB1200_SD0_INSERT_INT, mmc_host);
330 goto out;
331 }
332
333 if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT)
334 enable_irq(DB1200_SD0_EJECT_INT);
335 else
336 enable_irq(DB1200_SD0_INSERT_INT);
337
338 } else {
339 free_irq(DB1200_SD0_INSERT_INT, mmc_host);
340 free_irq(DB1200_SD0_EJECT_INT, mmc_host);
341 }
342 ret = 0;
343out:
344 return ret;
345}
346
347static void db1200_mmc_set_power(void *mmc_host, int state)
348{
349 if (state) {
350 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
351 msleep(400); /* stabilization time */
352 } else
353 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
354}
355
356static int db1200_mmc_card_readonly(void *mmc_host)
357{
358 return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
359}
360
361static int db1200_mmc_card_inserted(void *mmc_host)
362{
363 return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
364}
365
366static void db1200_mmcled_set(struct led_classdev *led,
367 enum led_brightness brightness)
368{
369 if (brightness != LED_OFF)
370 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
371 else
372 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
373}
374
375static struct led_classdev db1200_mmc_led = {
376 .brightness_set = db1200_mmcled_set,
377};
378
Manuel Lauss37663862011-08-12 11:39:45 +0200379static struct au1xmmc_platform_data db1200mmc_platdata = {
380 .cd_setup = db1200_mmc_cd_setup,
381 .set_power = db1200_mmc_set_power,
382 .card_inserted = db1200_mmc_card_inserted,
383 .card_readonly = db1200_mmc_card_readonly,
384 .led = &db1200_mmc_led,
385};
386
387static struct resource au1200_mmc0_resources[] = {
Manuel Lauss63323ec2009-11-02 21:21:43 +0100388 [0] = {
Manuel Lauss37663862011-08-12 11:39:45 +0200389 .start = AU1100_SD0_PHYS_ADDR,
390 .end = AU1100_SD0_PHYS_ADDR + 0xfff,
391 .flags = IORESOURCE_MEM,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100392 },
Manuel Lauss37663862011-08-12 11:39:45 +0200393 [1] = {
394 .start = AU1200_SD_INT,
395 .end = AU1200_SD_INT,
396 .flags = IORESOURCE_IRQ,
397 },
398 [2] = {
399 .start = AU1200_DSCR_CMD0_SDMS_TX0,
400 .end = AU1200_DSCR_CMD0_SDMS_TX0,
401 .flags = IORESOURCE_DMA,
402 },
403 [3] = {
404 .start = AU1200_DSCR_CMD0_SDMS_RX0,
405 .end = AU1200_DSCR_CMD0_SDMS_RX0,
406 .flags = IORESOURCE_DMA,
407 }
408};
409
410static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
411
412static struct platform_device db1200_mmc0_dev = {
413 .name = "au1xxx-mmc",
414 .id = 0,
415 .dev = {
416 .dma_mask = &au1xxx_mmc_dmamask,
417 .coherent_dma_mask = DMA_BIT_MASK(32),
418 .platform_data = &db1200mmc_platdata,
419 },
420 .num_resources = ARRAY_SIZE(au1200_mmc0_resources),
421 .resource = au1200_mmc0_resources,
422};
423
424/**********************************************************************/
425
Manuel Laussa9b71a82011-11-10 12:06:21 +0000426static int db1200fb_panel_index(void)
427{
428 return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
429}
430
431static int db1200fb_panel_init(void)
432{
433 /* Apply power */
434 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
435 BCSR_BOARD_LCDBL);
436 return 0;
437}
438
439static int db1200fb_panel_shutdown(void)
440{
441 /* Remove power */
442 bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
443 BCSR_BOARD_LCDBL, 0);
444 return 0;
445}
446
447static struct au1200fb_platdata db1200fb_pd = {
448 .panel_index = db1200fb_panel_index,
449 .panel_init = db1200fb_panel_init,
450 .panel_shutdown = db1200fb_panel_shutdown,
451};
452
Manuel Lauss37663862011-08-12 11:39:45 +0200453static struct resource au1200_lcd_res[] = {
454 [0] = {
455 .start = AU1200_LCD_PHYS_ADDR,
456 .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
457 .flags = IORESOURCE_MEM,
458 },
459 [1] = {
460 .start = AU1200_LCD_INT,
461 .end = AU1200_LCD_INT,
462 .flags = IORESOURCE_IRQ,
463 }
464};
465
466static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
467
468static struct platform_device au1200_lcd_dev = {
469 .name = "au1200-lcd",
470 .id = 0,
471 .dev = {
472 .dma_mask = &au1200_lcd_dmamask,
473 .coherent_dma_mask = DMA_BIT_MASK(32),
Manuel Laussa9b71a82011-11-10 12:06:21 +0000474 .platform_data = &db1200fb_pd,
Manuel Lauss37663862011-08-12 11:39:45 +0200475 },
476 .num_resources = ARRAY_SIZE(au1200_lcd_res),
477 .resource = au1200_lcd_res,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100478};
479
480/**********************************************************************/
481
482static struct resource au1200_psc0_res[] = {
483 [0] = {
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200484 .start = AU1550_PSC0_PHYS_ADDR,
485 .end = AU1550_PSC0_PHYS_ADDR + 0xfff,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100486 .flags = IORESOURCE_MEM,
487 },
488 [1] = {
489 .start = AU1200_PSC0_INT,
490 .end = AU1200_PSC0_INT,
491 .flags = IORESOURCE_IRQ,
492 },
493 [2] = {
Manuel Laussf2e442f2011-08-12 11:39:42 +0200494 .start = AU1200_DSCR_CMD0_PSC0_TX,
495 .end = AU1200_DSCR_CMD0_PSC0_TX,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100496 .flags = IORESOURCE_DMA,
497 },
498 [3] = {
Manuel Laussf2e442f2011-08-12 11:39:42 +0200499 .start = AU1200_DSCR_CMD0_PSC0_RX,
500 .end = AU1200_DSCR_CMD0_PSC0_RX,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100501 .flags = IORESOURCE_DMA,
502 },
503};
504
505static struct platform_device db1200_i2c_dev = {
506 .name = "au1xpsc_smbus",
507 .id = 0, /* bus number */
508 .num_resources = ARRAY_SIZE(au1200_psc0_res),
509 .resource = au1200_psc0_res,
510};
511
512static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
513{
514 if (cs)
515 bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL);
516 else
517 bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0);
518}
519
520static struct au1550_spi_info db1200_spi_platdata = {
521 .mainclk_hz = 50000000, /* PSC0 clock */
522 .num_chipselect = 2,
523 .activate_cs = db1200_spi_cs_en,
524};
525
FUJITA Tomonori25c8f832010-06-24 01:26:09 +0900526static u64 spi_dmamask = DMA_BIT_MASK(32);
Manuel Lauss63323ec2009-11-02 21:21:43 +0100527
528static struct platform_device db1200_spi_dev = {
529 .dev = {
530 .dma_mask = &spi_dmamask,
FUJITA Tomonori25c8f832010-06-24 01:26:09 +0900531 .coherent_dma_mask = DMA_BIT_MASK(32),
Manuel Lauss63323ec2009-11-02 21:21:43 +0100532 .platform_data = &db1200_spi_platdata,
533 },
534 .name = "au1550-spi",
535 .id = 0, /* bus number */
536 .num_resources = ARRAY_SIZE(au1200_psc0_res),
537 .resource = au1200_psc0_res,
538};
539
Manuel Lauss05ae3232009-11-02 21:21:44 +0100540static struct resource au1200_psc1_res[] = {
541 [0] = {
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200542 .start = AU1550_PSC1_PHYS_ADDR,
543 .end = AU1550_PSC1_PHYS_ADDR + 0xfff,
Manuel Lauss05ae3232009-11-02 21:21:44 +0100544 .flags = IORESOURCE_MEM,
545 },
546 [1] = {
547 .start = AU1200_PSC1_INT,
548 .end = AU1200_PSC1_INT,
549 .flags = IORESOURCE_IRQ,
550 },
551 [2] = {
Manuel Laussf2e442f2011-08-12 11:39:42 +0200552 .start = AU1200_DSCR_CMD0_PSC1_TX,
553 .end = AU1200_DSCR_CMD0_PSC1_TX,
Manuel Lauss05ae3232009-11-02 21:21:44 +0100554 .flags = IORESOURCE_DMA,
555 },
556 [3] = {
Manuel Laussf2e442f2011-08-12 11:39:42 +0200557 .start = AU1200_DSCR_CMD0_PSC1_RX,
558 .end = AU1200_DSCR_CMD0_PSC1_RX,
Manuel Lauss05ae3232009-11-02 21:21:44 +0100559 .flags = IORESOURCE_DMA,
560 },
561};
562
Manuel Laussadbc7a52011-07-25 13:45:03 +0200563/* AC97 or I2S device */
Manuel Lauss05ae3232009-11-02 21:21:44 +0100564static struct platform_device db1200_audio_dev = {
565 /* name assigned later based on switch setting */
566 .id = 1, /* PSC ID */
567 .num_resources = ARRAY_SIZE(au1200_psc1_res),
568 .resource = au1200_psc1_res,
569};
570
Manuel Laussadbc7a52011-07-25 13:45:03 +0200571/* DB1200 ASoC card device */
572static struct platform_device db1200_sound_dev = {
573 /* name assigned later based on switch setting */
574 .id = 1, /* PSC ID */
575};
576
Manuel Laussffc4fdb2010-08-26 14:53:51 +0200577static struct platform_device db1200_stac_dev = {
578 .name = "ac97-codec",
579 .id = 1, /* on PSC1 */
580};
581
Manuel Lauss5b0912b2011-07-25 13:45:02 +0200582static struct platform_device db1200_audiodma_dev = {
583 .name = "au1xpsc-pcm",
584 .id = 1, /* PSC ID */
585};
586
Manuel Lauss63323ec2009-11-02 21:21:43 +0100587static struct platform_device *db1200_devs[] __initdata = {
588 NULL, /* PSC0, selected by S6.8 */
589 &db1200_ide_dev,
Manuel Lauss37663862011-08-12 11:39:45 +0200590 &db1200_mmc0_dev,
591 &au1200_lcd_dev,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100592 &db1200_eth_dev,
593 &db1200_rtc_dev,
594 &db1200_nand_dev,
Manuel Lauss5b0912b2011-07-25 13:45:02 +0200595 &db1200_audiodma_dev,
Manuel Lauss05ae3232009-11-02 21:21:44 +0100596 &db1200_audio_dev,
Manuel Laussffc4fdb2010-08-26 14:53:51 +0200597 &db1200_stac_dev,
Manuel Laussadbc7a52011-07-25 13:45:03 +0200598 &db1200_sound_dev,
Manuel Lauss63323ec2009-11-02 21:21:43 +0100599};
600
601static int __init db1200_dev_init(void)
602{
603 unsigned long pfc;
604 unsigned short sw;
605 int swapped;
606
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000607 /* GPIO7 is low-level triggered CPLD cascade */
608 irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
609 bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
610
611 /* insert/eject pairs: one of both is always screaming. To avoid
612 * issues they must not be automatically enabled when initially
613 * requested.
614 */
615 irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
616 irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
617 irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
618 irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
619 irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
620 irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
621
Manuel Lauss63323ec2009-11-02 21:21:43 +0100622 i2c_register_board_info(0, db1200_i2c_devs,
623 ARRAY_SIZE(db1200_i2c_devs));
624 spi_register_board_info(db1200_spi_devs,
625 ARRAY_SIZE(db1200_i2c_devs));
626
627 /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
Manuel Lauss05ae3232009-11-02 21:21:44 +0100628 * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
Manuel Lauss63323ec2009-11-02 21:21:43 +0100629 */
630
631 /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
632 * this pin is claimed by PSC0 (unused though, but pinmux doesn't
633 * allow to free it without crippling the SPI interface).
634 * As a result, in SPI mode, OTG simply won't work (PSC0 uses
635 * it as an input pin which is pulled high on the boards).
636 */
637 pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
638
639 /* switch off OTG VBUS supply */
640 gpio_request(215, "otg-vbus");
641 gpio_direction_output(215, 1);
642
643 printk(KERN_INFO "DB1200 device configuration:\n");
644
645 sw = bcsr_read(BCSR_SWITCHES);
646 if (sw & BCSR_SWITCHES_DIP_8) {
647 db1200_devs[0] = &db1200_i2c_dev;
648 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
649
650 pfc |= (2 << 17); /* GPIO2 block owns GPIO215 */
651
652 printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
653 printk(KERN_INFO " OTG port VBUS supply available!\n");
654 } else {
655 db1200_devs[0] = &db1200_spi_dev;
656 bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);
657
658 pfc |= (1 << 17); /* PSC0 owns GPIO215 */
659
660 printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
661 printk(KERN_INFO " OTG port VBUS supply disabled\n");
662 }
663 __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
664 wmb();
665
Manuel Lauss05ae3232009-11-02 21:21:44 +0100666 /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
667 * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
668 */
669 sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
670 if (sw == BCSR_SWITCHES_DIP_8) {
671 bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
672 db1200_audio_dev.name = "au1xpsc_i2s";
Manuel Laussadbc7a52011-07-25 13:45:03 +0200673 db1200_sound_dev.name = "db1200-i2s";
Manuel Lauss05ae3232009-11-02 21:21:44 +0100674 printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
675 } else {
676 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
677 db1200_audio_dev.name = "au1xpsc_ac97";
Manuel Laussadbc7a52011-07-25 13:45:03 +0200678 db1200_sound_dev.name = "db1200-ac97";
Manuel Lauss05ae3232009-11-02 21:21:44 +0100679 printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
680 }
681
682 /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
683 __raw_writel(PSC_SEL_CLK_SERCLK,
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000684 (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
Manuel Lauss05ae3232009-11-02 21:21:44 +0100685 wmb();
686
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200687 db1x_register_pcmcia_socket(
688 AU1000_PCMCIA_ATTR_PHYS_ADDR,
689 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
690 AU1000_PCMCIA_MEM_PHYS_ADDR,
691 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
692 AU1000_PCMCIA_IO_PHYS_ADDR,
693 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
694 DB1200_PC0_INT, DB1200_PC0_INSERT_INT,
695 /*DB1200_PC0_STSCHG_INT*/0, DB1200_PC0_EJECT_INT, 0);
Manuel Lauss63323ec2009-11-02 21:21:43 +0100696
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200697 db1x_register_pcmcia_socket(
698 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
699 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
700 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
701 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
702 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
703 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
704 DB1200_PC1_INT, DB1200_PC1_INSERT_INT,
705 /*DB1200_PC1_STSCHG_INT*/0, DB1200_PC1_EJECT_INT, 1);
Manuel Lauss63323ec2009-11-02 21:21:43 +0100706
707 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
708 db1x_register_norflash(64 << 20, 2, swapped);
709
710 return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
711}
712device_initcall(db1200_dev_init);