• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/avr32/boards/favr-32/
1/*
2 * Favr-32 board-specific setup code.
3 *
4 * Copyright (C) 2008 Atmel Corporation
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/bootmem.h>
13#include <linux/fb.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/types.h>
17#include <linux/linkage.h>
18#include <linux/gpio.h>
19#include <linux/leds.h>
20#include <linux/atmel-mci.h>
21#include <linux/atmel-pwm-bl.h>
22#include <linux/spi/spi.h>
23#include <linux/spi/ads7846.h>
24
25#include <sound/atmel-abdac.h>
26
27#include <video/atmel_lcdc.h>
28
29#include <asm/setup.h>
30
31#include <mach/at32ap700x.h>
32#include <mach/init.h>
33#include <mach/board.h>
34#include <mach/portmux.h>
35
36/* Oscillator frequencies. These are board-specific */
37unsigned long at32_board_osc_rates[3] = {
38	[0] = 32768,	/* 32.768 kHz on RTC osc */
39	[1] = 20000000,	/* 20 MHz on osc0 */
40	[2] = 12000000,	/* 12 MHz on osc1 */
41};
42
43/* Initialized by bootloader-specific startup code. */
44struct tag *bootloader_tags __initdata;
45
46static struct atmel_abdac_pdata __initdata abdac0_data = {
47};
48
49struct eth_addr {
50	u8 addr[6];
51};
52static struct eth_addr __initdata hw_addr[1];
53static struct eth_platform_data __initdata eth_data[1] = {
54	{
55		.phy_mask	= ~(1U << 1),
56	},
57};
58
59static int ads7843_get_pendown_state(void)
60{
61	return !gpio_get_value(GPIO_PIN_PB(3));
62}
63
64static struct ads7846_platform_data ads7843_data = {
65	.model			= 7843,
66	.get_pendown_state	= ads7843_get_pendown_state,
67	.pressure_max		= 255,
68	/*
69	 * Values below are for debounce filtering, these can be experimented
70	 * with further.
71	 */
72	.debounce_max		= 20,
73	.debounce_rep		= 4,
74	.debounce_tol		= 5,
75
76	.keep_vref_on		= true,
77	.settle_delay_usecs	= 500,
78	.penirq_recheck_delay_usecs = 100,
79};
80
81static struct spi_board_info __initdata spi1_board_info[] = {
82	{
83		/* ADS7843 touch controller */
84		.modalias	= "ads7846",
85		.max_speed_hz	= 2000000,
86		.chip_select	= 0,
87		.bus_num	= 1,
88		.platform_data	= &ads7843_data,
89	},
90};
91
92static struct mci_platform_data __initdata mci0_data = {
93	.slot[0] = {
94		.bus_width	= 4,
95		.detect_pin	= -ENODEV,
96		.wp_pin		= -ENODEV,
97	},
98};
99
100static struct fb_videomode __initdata lb104v03_modes[] = {
101	{
102		.name		= "640x480 @ 50",
103		.refresh	= 50,
104		.xres		= 640,		.yres		= 480,
105		.pixclock	= KHZ2PICOS(25100),
106
107		.left_margin	= 90,		.right_margin	= 70,
108		.upper_margin	= 30,		.lower_margin	= 15,
109		.hsync_len	= 12,		.vsync_len	= 2,
110
111		.sync		= 0,
112		.vmode		= FB_VMODE_NONINTERLACED,
113	},
114};
115
116static struct fb_monspecs __initdata favr32_default_monspecs = {
117	.manufacturer		= "LG",
118	.monitor		= "LB104V03",
119	.modedb			= lb104v03_modes,
120	.modedb_len		= ARRAY_SIZE(lb104v03_modes),
121	.hfmin			= 27273,
122	.hfmax			= 31111,
123	.vfmin			= 45,
124	.vfmax			= 60,
125	.dclkmax		= 28000000,
126};
127
128struct atmel_lcdfb_info __initdata favr32_lcdc_data = {
129	.default_bpp		= 16,
130	.default_dmacon		= ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
131	.default_lcdcon2	= (ATMEL_LCDC_DISTYPE_TFT
132				   | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
133				   | ATMEL_LCDC_MEMOR_BIG),
134	.default_monspecs	= &favr32_default_monspecs,
135	.guard_time		= 2,
136};
137
138static struct gpio_led favr32_leds[] = {
139	{
140		.name		 = "green",
141		.gpio		 = GPIO_PIN_PE(19),
142		.default_trigger = "heartbeat",
143		.active_low	 = 1,
144	},
145	{
146		.name		 = "red",
147		.gpio		 = GPIO_PIN_PE(20),
148		.active_low	 = 1,
149	},
150};
151
152static struct gpio_led_platform_data favr32_led_data = {
153	.num_leds	= ARRAY_SIZE(favr32_leds),
154	.leds		= favr32_leds,
155};
156
157static struct platform_device favr32_led_dev = {
158	.name		= "leds-gpio",
159	.id		= 0,
160	.dev		= {
161		.platform_data	= &favr32_led_data,
162	},
163};
164
165/*
166 * The next two functions should go away as the boot loader is
167 * supposed to initialize the macb address registers with a valid
168 * ethernet address. But we need to keep it around for a while until
169 * we can be reasonably sure the boot loader does this.
170 *
171 * The phy_id is ignored as the driver will probe for it.
172 */
173static int __init parse_tag_ethernet(struct tag *tag)
174{
175	int i;
176
177	i = tag->u.ethernet.mac_index;
178	if (i < ARRAY_SIZE(hw_addr))
179		memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
180		       sizeof(hw_addr[i].addr));
181
182	return 0;
183}
184__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
185
186static void __init set_hw_addr(struct platform_device *pdev)
187{
188	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
189	const u8 *addr;
190	void __iomem *regs;
191	struct clk *pclk;
192
193	if (!res)
194		return;
195	if (pdev->id >= ARRAY_SIZE(hw_addr))
196		return;
197
198	addr = hw_addr[pdev->id].addr;
199	if (!is_valid_ether_addr(addr))
200		return;
201
202	/*
203	 * Since this is board-specific code, we'll cheat and use the
204	 * physical address directly as we happen to know that it's
205	 * the same as the virtual address.
206	 */
207	regs = (void __iomem __force *)res->start;
208	pclk = clk_get(&pdev->dev, "pclk");
209	if (!pclk)
210		return;
211
212	clk_enable(pclk);
213	__raw_writel((addr[3] << 24) | (addr[2] << 16)
214		     | (addr[1] << 8) | addr[0], regs + 0x98);
215	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
216	clk_disable(pclk);
217	clk_put(pclk);
218}
219
220void __init favr32_setup_leds(void)
221{
222	unsigned i;
223
224	for (i = 0; i < ARRAY_SIZE(favr32_leds); i++)
225		at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT);
226
227	platform_device_register(&favr32_led_dev);
228}
229
230static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
231	.pwm_channel		= 2,
232	.pwm_frequency		= 200000,
233	.pwm_compare_max	= 345,
234	.pwm_duty_max		= 345,
235	.pwm_duty_min		= 90,
236	.pwm_active_low		= 1,
237	.gpio_on		= GPIO_PIN_PA(28),
238	.on_active_low		= 0,
239};
240
241static struct platform_device atmel_pwm_bl_dev = {
242	.name		= "atmel-pwm-bl",
243	.id		= 0,
244	.dev		= {
245		.platform_data = &atmel_pwm_bl_pdata,
246	},
247};
248
249static void __init favr32_setup_atmel_pwm_bl(void)
250{
251	platform_device_register(&atmel_pwm_bl_dev);
252	at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
253}
254
255void __init setup_board(void)
256{
257	at32_map_usart(3, 0, 0);	/* USART 3 => /dev/ttyS0 */
258	at32_setup_serial_console(0);
259}
260
261static int __init set_abdac_rate(struct platform_device *pdev)
262{
263	int retval;
264	struct clk *osc1;
265	struct clk *pll1;
266	struct clk *abdac;
267
268	if (pdev == NULL)
269		return -ENXIO;
270
271	osc1 = clk_get(NULL, "osc1");
272	if (IS_ERR(osc1)) {
273		retval = PTR_ERR(osc1);
274		goto out;
275	}
276
277	pll1 = clk_get(NULL, "pll1");
278	if (IS_ERR(pll1)) {
279		retval = PTR_ERR(pll1);
280		goto out_osc1;
281	}
282
283	abdac = clk_get(&pdev->dev, "sample_clk");
284	if (IS_ERR(abdac)) {
285		retval = PTR_ERR(abdac);
286		goto out_pll1;
287	}
288
289	retval = clk_set_parent(pll1, osc1);
290	if (retval != 0)
291		goto out_abdac;
292
293	/*
294	 * Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in
295	 * power of 2, to a value above 80 MHz. Power of 2 so it is possible
296	 * for the generic clock to divide it down again and 80 MHz is the
297	 * lowest frequency for the PLL.
298	 */
299	retval = clk_round_rate(pll1,
300			CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
301	if (retval < 0)
302		goto out_abdac;
303
304	retval = clk_set_rate(pll1, retval);
305	if (retval != 0)
306		goto out_abdac;
307
308	retval = clk_set_parent(abdac, pll1);
309	if (retval != 0)
310		goto out_abdac;
311
312out_abdac:
313	clk_put(abdac);
314out_pll1:
315	clk_put(pll1);
316out_osc1:
317	clk_put(osc1);
318out:
319	return retval;
320}
321
322static int __init favr32_init(void)
323{
324	/*
325	 * Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific
326	 * pins so that nobody messes with them.
327	 */
328	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL);
329
330	at32_select_gpio(GPIO_PIN_PB(3), 0);	/* IRQ from ADS7843 */
331
332	at32_add_device_usart(0);
333
334	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
335
336	spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
337
338	set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
339
340	at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
341	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
342	at32_add_device_mci(0, &mci0_data);
343	at32_add_device_usba(0, NULL);
344	at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0);
345
346	favr32_setup_leds();
347
348	favr32_setup_atmel_pwm_bl();
349
350	return 0;
351}
352postcore_initcall(favr32_init);
353