Merge with rsync://fileserver/linux
[linux-2.6] / arch / arm / mach-pxa / idp.c
1 /*
2  *  linux/arch/arm/mach-pxa/idp.c
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License version 2 as
6  *  published by the Free Software Foundation.
7  *
8  *  Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
9  *
10  *  2001-09-13: Cliff Brake <cbrake@accelent.com>
11  *              Initial code
12  *
13  *  2005-02-15: Cliff Brake <cliff.brake@gmail.com>
14  *              <http://www.vibren.com> <http://bec-systems.com>
15  *              Updated for 2.6 kernel
16  *
17  */
18
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/device.h>
22 #include <linux/fb.h>
23
24 #include <asm/setup.h>
25 #include <asm/memory.h>
26 #include <asm/mach-types.h>
27 #include <asm/hardware.h>
28 #include <asm/irq.h>
29
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
32
33 #include <asm/arch/pxa-regs.h>
34 #include <asm/arch/idp.h>
35 #include <asm/arch/pxafb.h>
36 #include <asm/arch/bitfield.h>
37 #include <asm/arch/mmc.h>
38
39 #include "generic.h"
40
41 /* TODO:
42  * - add pxa2xx_audio_ops_t device structure
43  * - Ethernet interrupt
44  */
45
46 static struct resource smc91x_resources[] = {
47         [0] = {
48                 .start  = (IDP_ETH_PHYS + 0x300),
49                 .end    = (IDP_ETH_PHYS + 0xfffff),
50                 .flags  = IORESOURCE_MEM,
51         },
52         [1] = {
53                 .start  = IRQ_GPIO(4),
54                 .end    = IRQ_GPIO(4),
55                 .flags  = IORESOURCE_IRQ,
56         }
57 };
58
59 static struct platform_device smc91x_device = {
60         .name           = "smc91x",
61         .id             = 0,
62         .num_resources  = ARRAY_SIZE(smc91x_resources),
63         .resource       = smc91x_resources,
64 };
65
66 static void idp_backlight_power(int on)
67 {
68         if (on) {
69                 IDP_CPLD_LCD |= (1<<1);
70         } else {
71                 IDP_CPLD_LCD &= ~(1<<1);
72         }
73 }
74
75 static void idp_vlcd(int on)
76 {
77         if (on) {
78                 IDP_CPLD_LCD |= (1<<2);
79         } else {
80                 IDP_CPLD_LCD &= ~(1<<2);
81         }
82 }
83
84 static void idp_lcd_power(int on)
85 {
86         if (on) {
87                 IDP_CPLD_LCD |= (1<<0);
88         } else {
89                 IDP_CPLD_LCD &= ~(1<<0);
90         }
91
92         /* call idp_vlcd for now as core driver does not support
93          * both power and vlcd hooks.  Note, this is not technically
94          * the correct sequence, but seems to work.  Disclaimer:
95          * this may eventually damage the display.
96          */
97
98         idp_vlcd(on);
99 }
100
101 static struct pxafb_mach_info sharp_lm8v31 __initdata = {
102         .pixclock       = 270000,
103         .xres           = 640,
104         .yres           = 480,
105         .bpp            = 16,
106         .hsync_len      = 1,
107         .left_margin    = 3,
108         .right_margin   = 3,
109         .vsync_len      = 1,
110         .upper_margin   = 0,
111         .lower_margin   = 0,
112         .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
113         .cmap_greyscale = 0,
114         .cmap_inverse   = 0,
115         .cmap_static    = 0,
116         .lccr0          = LCCR0_SDS,
117         .lccr3          = LCCR3_PCP | LCCR3_Acb(255),
118         .pxafb_backlight_power = &idp_backlight_power,
119         .pxafb_lcd_power = &idp_lcd_power
120 };
121
122 static int idp_mci_init(struct device *dev, irqreturn_t (*idp_detect_int)(int, void *, struct pt_regs *), void *data)
123 {
124         /* setup GPIO for PXA25x MMC controller */
125         pxa_gpio_mode(GPIO6_MMCCLK_MD);
126         pxa_gpio_mode(GPIO8_MMCCS0_MD);
127
128         return 0;
129 }
130
131 static struct pxamci_platform_data idp_mci_platform_data = {
132         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
133         .init           = idp_mci_init,
134 };
135
136 static void __init idp_init(void)
137 {
138         printk("idp_init()\n");
139
140         platform_device_register(&smc91x_device);
141         //platform_device_register(&mst_audio_device);
142         set_pxa_fb_info(&sharp_lm8v31);
143         pxa_set_mci_info(&idp_mci_platform_data);
144 }
145
146 static void __init idp_init_irq(void)
147 {
148
149         pxa_init_irq();
150
151         set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
152 }
153
154 static struct map_desc idp_io_desc[] __initdata = {
155  /* virtual     physical    length      type */
156
157   { IDP_COREVOLT_VIRT,
158     IDP_COREVOLT_PHYS,
159     IDP_COREVOLT_SIZE,
160     MT_DEVICE },
161   { IDP_CPLD_VIRT,
162     IDP_CPLD_PHYS,
163     IDP_CPLD_SIZE,
164     MT_DEVICE }
165 };
166
167 static void __init idp_map_io(void)
168 {
169         pxa_map_io();
170         iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
171
172         // serial ports 2 & 3
173         pxa_gpio_mode(GPIO42_BTRXD_MD);
174         pxa_gpio_mode(GPIO43_BTTXD_MD);
175         pxa_gpio_mode(GPIO44_BTCTS_MD);
176         pxa_gpio_mode(GPIO45_BTRTS_MD);
177         pxa_gpio_mode(GPIO46_STRXD_MD);
178         pxa_gpio_mode(GPIO47_STTXD_MD);
179
180 }
181
182
183 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
184         /* Maintainer: Vibren Technologies */
185         .phys_ram       = 0xa0000000,
186         .phys_io        = 0x40000000,
187         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
188         .map_io         = idp_map_io,
189         .init_irq       = idp_init_irq,
190         .timer          = &pxa_timer,
191         .init_machine   = idp_init,
192 MACHINE_END