Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / arch / avr32 / boards / merisc / setup.c
1 /*
2  * Board-specific setup code for the Merisc
3  *
4  * Copyright (C) 2008 Martinsson Elektronik AB
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/clk.h>
11 #include <linux/etherdevice.h>
12 #include <linux/i2c.h>
13 #include <linux/i2c-gpio.h>
14 #include <linux/gpio.h>
15 #include <linux/init.h>
16 #include <linux/linkage.h>
17 #include <linux/platform_device.h>
18 #include <linux/types.h>
19 #include <linux/leds.h>
20 #include <linux/spi/spi.h>
21 #include <linux/spi/ads7846.h>
22 #include <linux/irq.h>
23 #include <linux/fb.h>
24 #include <linux/atmel-mci.h>
25
26 #include <asm/io.h>
27 #include <asm/setup.h>
28 #include <asm/gpio.h>
29
30 #include <mach/at32ap700x.h>
31 #include <mach/board.h>
32 #include <mach/init.h>
33 #include <mach/portmux.h>
34
35 #include "merisc.h"
36
37 /* Holds the autodetected board model and revision */
38 static int merisc_board_id;
39
40 /* Initialized by bootloader-specific startup code. */
41 struct tag *bootloader_tags __initdata;
42
43 /* Oscillator frequencies. These are board specific */
44 unsigned long at32_board_osc_rates[3] = {
45         [0]     = 32768,        /* 32.768 kHz on RTC osc */
46         [1]     = 20000000,     /* 20 MHz on osc0 */
47         [2]     = 12000000,     /* 12 MHz on osc1 */
48 };
49
50 struct eth_addr {
51         u8 addr[6];
52 };
53
54 static struct eth_addr __initdata hw_addr[2];
55 static struct eth_platform_data __initdata eth_data[2];
56
57 static int ads7846_get_pendown_state_PB26(void)
58 {
59         return !gpio_get_value(GPIO_PIN_PB(26));
60 }
61
62 static int ads7846_get_pendown_state_PB28(void)
63 {
64         return !gpio_get_value(GPIO_PIN_PB(28));
65 }
66
67 static struct ads7846_platform_data __initdata ads7846_data = {
68         .model                          = 7846,
69         .vref_delay_usecs               = 100,
70         .vref_mv                        = 0,
71         .keep_vref_on                   = 0,
72         .settle_delay_usecs             = 150,
73         .penirq_recheck_delay_usecs     = 1,
74         .x_plate_ohms                   = 800,
75         .debounce_rep                   = 4,
76         .debounce_max                   = 10,
77         .debounce_tol                   = 50,
78         .get_pendown_state              = ads7846_get_pendown_state_PB26,
79         .filter_init                    = NULL,
80         .filter                         = NULL,
81         .filter_cleanup                 = NULL,
82 };
83
84 static struct spi_board_info __initdata spi0_board_info[] = {
85         {
86                 .modalias       = "ads7846",
87                 .max_speed_hz   = 3250000,
88                 .chip_select    = 0,
89                 .bus_num        = 0,
90                 .platform_data  = &ads7846_data,
91                 .mode           = SPI_MODE_0,
92         },
93 };
94
95 static struct mci_platform_data __initdata mci0_data = {
96         .slot[0] = {
97                 .bus_width              = 4,
98                 .detect_pin             = GPIO_PIN_PE(19),
99                 .wp_pin                 = GPIO_PIN_PE(20),
100                 .detect_is_active_high  = true,
101         },
102 };
103
104 static int __init parse_tag_ethernet(struct tag *tag)
105 {
106         int i;
107
108         i = tag->u.ethernet.mac_index;
109         if (i < ARRAY_SIZE(hw_addr)) {
110                 memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
111                        sizeof(hw_addr[i].addr));
112         }
113
114         return 0;
115 }
116 __tagtable(ATAG_ETHERNET, parse_tag_ethernet);
117
118 static void __init set_hw_addr(struct platform_device *pdev)
119 {
120         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
121         const u8 *addr;
122         void __iomem *regs;
123         struct clk *pclk;
124
125         if (!res)
126                 return;
127
128         if (pdev->id >= ARRAY_SIZE(hw_addr))
129                 return;
130
131         addr = hw_addr[pdev->id].addr;
132         if (!is_valid_ether_addr(addr))
133                 return;
134
135         regs = (void __iomem __force *)res->start;
136         pclk = clk_get(&pdev->dev, "pclk");
137         if (IS_ERR(pclk))
138                 return;
139
140         clk_enable(pclk);
141         __raw_writel((addr[3] << 24) | (addr[2] << 16)
142                      | (addr[1] << 8) | addr[0], regs + 0x98);
143         __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
144         clk_disable(pclk);
145         clk_put(pclk);
146 }
147
148 static struct i2c_gpio_platform_data i2c_gpio_data = {
149         .sda_pin                = GPIO_PIN_PA(6),
150         .scl_pin                = GPIO_PIN_PA(7),
151         .sda_is_open_drain      = 1,
152         .scl_is_open_drain      = 1,
153         .udelay                 = 2,
154 };
155
156 static struct platform_device i2c_gpio_device = {
157         .name   = "i2c-gpio",
158         .id     = 0,
159         .dev    = {
160                 .platform_data  = &i2c_gpio_data,
161         },
162 };
163
164 static struct i2c_board_info __initdata i2c_info[] = {
165         {
166                 I2C_BOARD_INFO("pcf8563", 0x51)
167         },
168 };
169
170 #ifdef CONFIG_LEDS_ATMEL_PWM
171 static struct gpio_led stk_pwm_led[] = {
172         {
173                 .name   = "backlight",
174                 .gpio   = 0,            /* PWM channel 0 (LCD backlight) */
175         },
176 };
177
178 static struct gpio_led_platform_data stk_pwm_led_data = {
179         .num_leds       = ARRAY_SIZE(stk_pwm_led),
180         .leds           = stk_pwm_led,
181 };
182
183 static struct platform_device stk_pwm_led_dev = {
184         .name   = "leds-atmel-pwm",
185         .id     = -1,
186         .dev    = {
187                 .platform_data  = &stk_pwm_led_data,
188         },
189 };
190 #endif
191
192 const char *merisc_model(void)
193 {
194         switch (merisc_board_id) {
195         case 0:
196         case 1:
197                 return "500-01";
198         case 2:
199                 return "BT";
200         default:
201                 return "Unknown";
202         }
203 }
204
205 const char *merisc_revision(void)
206 {
207         switch (merisc_board_id) {
208         case 0:
209                 return "B";
210         case 1:
211                 return "D";
212         case 2:
213                 return "A";
214         default:
215                 return "Unknown";
216         }
217 }
218
219 static void detect_merisc_board_id(void)
220 {
221         /* Board ID pins MUST be set as input or the board may be damaged */
222         at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
223         at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
224         at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
225         at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);
226
227         merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
228                 !gpio_get_value(GPIO_PIN_PA(25)) * 2 +
229                 !gpio_get_value(GPIO_PIN_PA(26)) * 4 +
230                 !gpio_get_value(GPIO_PIN_PA(27)) * 8;
231 }
232
233 void __init setup_board(void)
234 {
235         at32_map_usart(0, 0, 0);
236         at32_map_usart(1, 1, 0);
237         at32_map_usart(3, 3, 0);
238         at32_setup_serial_console(1);
239 }
240
241 static int __init merisc_init(void)
242 {
243         detect_merisc_board_id();
244
245         printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
246                merisc_revision());
247
248         /* Reserve pins for SDRAM */
249         at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));
250
251         if (merisc_board_id >= 1)
252                 at32_map_usart(2, 2, 0);
253
254         at32_add_device_usart(0);
255         at32_add_device_usart(1);
256         if (merisc_board_id >= 1)
257                 at32_add_device_usart(2);
258         at32_add_device_usart(3);
259         set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
260
261         /* ADS7846 PENIRQ */
262         if (merisc_board_id == 0) {
263                 ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
264                 at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
265                                    GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
266                 spi0_board_info[0].irq = AT32_EXTINT(1);
267         } else {
268                 ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
269                 at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
270                                    AT32_GPIOF_PULLUP);
271                 spi0_board_info[0].irq = AT32_EXTINT(3);
272         }
273
274         /* ADS7846 busy pin */
275         at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);
276
277         at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
278
279         at32_add_device_mci(0, &mci0_data);
280
281 #ifdef CONFIG_LEDS_ATMEL_PWM
282         at32_add_device_pwm((1 << 0) | (1 << 2));
283         platform_device_register(&stk_pwm_led_dev);
284 #else
285         at32_add_device_pwm((1 << 2));
286 #endif
287
288         at32_select_gpio(i2c_gpio_data.sda_pin,
289                 AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
290         at32_select_gpio(i2c_gpio_data.scl_pin,
291                 AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
292         platform_device_register(&i2c_gpio_device);
293
294         i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
295
296         return 0;
297 }
298 postcore_initcall(merisc_init);