Date: | 2010-04-24 17:25:01 (13 years 7 months ago) |
---|---|
Author: | Lars C. |
Commit: | 3709d7a38e0790b6ec427abbdda084747238a5fe |
Message: | Add n516 board support |
Files: |
arch/mips/include/asm/mach-jz4740/board-n516.h (1 diff) arch/mips/jz4740/Kconfig (1 diff) arch/mips/jz4740/Makefile (1 diff) arch/mips/jz4740/board-n516-display.c (1 diff) arch/mips/jz4740/board-n516.c (1 diff) |
Change Details
arch/mips/include/asm/mach-jz4740/board-n516.h | ||
---|---|---|
1 | /* | |
2 | * linux/include/asm-mips/mach-jz4740/board-n516.h | |
3 | * | |
4 | * JZ4730-based N516 board definition. | |
5 | * | |
6 | * Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | */ | |
13 | ||
14 | #ifndef __ASM_JZ4740_N516_H__ | |
15 | #define __ASM_JZ4740_N516_H__ | |
16 | ||
17 | #include <asm/mach-jz4740/gpio.h> | |
18 | ||
19 | /* | |
20 | * GPIO | |
21 | */ | |
22 | #define GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(17) | |
23 | #define GPIO_SD_CD_N JZ_GPIO_PORTD(7) | |
24 | #define GPIO_SD_WP JZ_GPIO_PORTD(15) | |
25 | #define GPIO_USB_DETECT JZ_GPIO_PORTD(19) | |
26 | #define GPIO_CHARG_STAT_N JZ_GPIO_PORTD(16) | |
27 | #define GPIO_LED_ENABLE JZ_GPIO_PORTD(28) | |
28 | #define GPIO_LPC_INT JZ_GPIO_PORTD(14) | |
29 | #define GPIO_HPHONE_DETECT JZ_GPIO_PORTD(20) | |
30 | #define GPIO_SPEAKER_ENABLE JZ_GPIO_PORTD(21) | |
31 | ||
32 | /* Display */ | |
33 | #define GPIO_DISPLAY_RST_L JZ_GPIO_PORTB(18) | |
34 | #define GPIO_DISPLAY_RDY JZ_GPIO_PORTB(17) | |
35 | #define GPIO_DISPLAY_STBY JZ_GPIO_PORTC(22) | |
36 | #define GPIO_DISPLAY_ERR JZ_GPIO_PORTC(23) | |
37 | #define GPIO_DISPLAY_OFF_N JZ_GPIO_PORTD(1) | |
38 | ||
39 | #endif /* __ASM_JZ4740_N516_H__ */ |
arch/mips/jz4740/Kconfig | ||
---|---|---|
7 | 7 | bool "Qi Hardware Ben NanoNote" |
8 | 8 | select SOC_JZ4740 |
9 | 9 | |
10 | config JZ4740_N516 | |
11 | bool "Hanvon n516 eBook reader" | |
12 | select SOC_JZ4740 | |
13 | ||
10 | 14 | endchoice |
11 | 15 | |
12 | 16 | config SOC_JZ4740 |
arch/mips/jz4740/Makefile | ||
---|---|---|
12 | 12 | # board specific support |
13 | 13 | |
14 | 14 | obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o |
15 | obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o | |
15 | 16 | |
16 | 17 | # PM support |
17 | 18 |
arch/mips/jz4740/board-n516-display.c | ||
---|---|---|
1 | /* | |
2 | * board-n516-display.c -- Platform device for N516 display | |
3 | * | |
4 | * Copyright (C) 2009, Yauhen Kharuzhy <jekhor@gmail.com> | |
5 | * | |
6 | * This file is subject to the terms and conditions of the GNU General Public | |
7 | * License. See the file COPYING in the main directory of this archive for | |
8 | * more details. | |
9 | */ | |
10 | ||
11 | #include <linux/module.h> | |
12 | #include <linux/kernel.h> | |
13 | #include <linux/errno.h> | |
14 | #include <linux/string.h> | |
15 | #include <linux/delay.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/fb.h> | |
18 | #include <linux/init.h> | |
19 | #include <linux/platform_device.h> | |
20 | #include <linux/irq.h> | |
21 | #include <linux/gpio.h> | |
22 | #include <linux/jz4740_fb.h> | |
23 | ||
24 | #include <asm/mach-jz4740/platform.h> | |
25 | #include <asm/mach-jz4740/board-n516.h> | |
26 | ||
27 | #include <video/metronomefb.h> | |
28 | #include <linux/console.h> | |
29 | ||
30 | static struct fb_videomode n516_fb_modes[] = { | |
31 | [0] = { | |
32 | .name = "Metronome 800x600", | |
33 | .refresh = 50, | |
34 | .xres = 400, | |
35 | .yres = 624, | |
36 | .hsync_len = 31, | |
37 | .vsync_len = 23, | |
38 | .right_margin = 31, | |
39 | .left_margin = 5, | |
40 | .upper_margin = 1, | |
41 | .lower_margin = 2, | |
42 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | |
43 | }, | |
44 | }; | |
45 | ||
46 | static struct jz4740_fb_platform_data n516_fb_pdata = { | |
47 | .num_modes = ARRAY_SIZE(n516_fb_modes), | |
48 | .modes = n516_fb_modes, | |
49 | .bpp = 16, | |
50 | .lcd_type = JZ_LCD_TYPE_GENERIC_16_BIT, | |
51 | }; | |
52 | ||
53 | struct n516_board_info { | |
54 | uint8_t *metromem; | |
55 | size_t wfm_size; | |
56 | struct fb_info *host_fbinfo; /* the host LCD controller's fbi */ | |
57 | unsigned int fw; | |
58 | unsigned int fh; | |
59 | }; | |
60 | ||
61 | static struct platform_device *n516_device; | |
62 | static struct n516_board_info n516_board_info; | |
63 | ||
64 | static int metronome_gpios[] = { | |
65 | GPIO_DISPLAY_STBY, | |
66 | GPIO_DISPLAY_RST_L, | |
67 | GPIO_DISPLAY_RDY, | |
68 | GPIO_DISPLAY_ERR, | |
69 | /* GPIO_DISPLAY_OFF,*/ | |
70 | }; | |
71 | ||
72 | static const char *metronome_gpio_names[] = { | |
73 | "Metronome STDBY", | |
74 | "Metronome RST", | |
75 | "Metronome RDY", | |
76 | "Metronome ERR", | |
77 | /* "Metronone OFF",*/ | |
78 | }; | |
79 | ||
80 | static int n516_enable_hostfb(bool enable) | |
81 | { | |
82 | int ret; | |
83 | int blank = enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; | |
84 | ||
85 | acquire_console_sem(); | |
86 | ret = fb_blank(n516_board_info.host_fbinfo, blank); | |
87 | release_console_sem(); | |
88 | ||
89 | return ret; | |
90 | } | |
91 | ||
92 | static int n516_init_metronome_gpios(struct metronomefb_par *par) | |
93 | { | |
94 | int i; | |
95 | int ret; | |
96 | ||
97 | for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i) { | |
98 | ret = gpio_request(metronome_gpios[i], metronome_gpio_names[i]); | |
99 | if (ret) | |
100 | goto err; | |
101 | } | |
102 | ||
103 | gpio_direction_output(GPIO_DISPLAY_OFF, 0); | |
104 | gpio_direction_output(GPIO_DISPLAY_RST_L, 0); | |
105 | gpio_direction_output(GPIO_DISPLAY_STBY, 0); | |
106 | gpio_direction_input(GPIO_DISPLAY_RDY); | |
107 | gpio_direction_input(GPIO_DISPLAY_ERR); | |
108 | ||
109 | return 0; | |
110 | err: | |
111 | for (--i; i >= 0; --i) | |
112 | gpio_free(metronome_gpios[i]); | |
113 | ||
114 | return ret; | |
115 | } | |
116 | ||
117 | static int n516_share_video_mem(struct fb_info *info) | |
118 | { | |
119 | int ret; | |
120 | ||
121 | dev_dbg(&n516_device->dev, "ENTER %s\n", __func__); | |
122 | dev_dbg(&n516_device->dev, "%s, info->var.xres = %u, info->var.yres = %u\n", __func__, info->var.xres, info->var.yres); | |
123 | /* rough check if this is our desired fb and not something else */ | |
124 | if ((info->var.xres != n516_fb_pdata.modes[0].xres) | |
125 | || (info->var.yres != n516_fb_pdata.modes[0].yres)) | |
126 | return 0; | |
127 | ||
128 | /* we've now been notified that we have our new fb */ | |
129 | n516_board_info.metromem = info->screen_base; | |
130 | n516_board_info.host_fbinfo = info; | |
131 | ||
132 | n516_enable_hostfb(false); | |
133 | /* try to refcount host drv since we are the consumer after this */ | |
134 | if (!try_module_get(info->fbops->owner)) | |
135 | return -ENODEV; | |
136 | ||
137 | /* this _add binds metronomefb to n516. metronomefb refcounts n516 */ | |
138 | ret = platform_device_add(n516_device); | |
139 | ||
140 | if (ret) { | |
141 | platform_device_put(n516_device); | |
142 | return ret; | |
143 | } | |
144 | ||
145 | /* request our platform independent driver */ | |
146 | request_module("metronomefb"); | |
147 | ||
148 | return 0; | |
149 | } | |
150 | ||
151 | static int n516_unshare_video_mem(struct fb_info *info) | |
152 | { | |
153 | dev_dbg(&n516_device->dev, "ENTER %s\n", __func__); | |
154 | ||
155 | if (info != n516_board_info.host_fbinfo) | |
156 | return 0; | |
157 | ||
158 | module_put(n516_board_info.host_fbinfo->fbops->owner); | |
159 | return 0; | |
160 | } | |
161 | ||
162 | static int n516_fb_notifier_callback(struct notifier_block *self, | |
163 | unsigned long event, void *data) | |
164 | { | |
165 | struct fb_event *evdata = data; | |
166 | struct fb_info *info = evdata->info; | |
167 | ||
168 | dev_dbg(&n516_device->dev, "ENTER %s\n", __func__); | |
169 | ||
170 | if (event == FB_EVENT_FB_REGISTERED) | |
171 | return n516_share_video_mem(info); | |
172 | else if (event == FB_EVENT_FB_UNREGISTERED) | |
173 | return n516_unshare_video_mem(info); | |
174 | ||
175 | return 0; | |
176 | } | |
177 | ||
178 | static struct notifier_block n516_fb_notif = { | |
179 | .notifier_call = n516_fb_notifier_callback, | |
180 | }; | |
181 | ||
182 | /* this gets called as part of our init. these steps must be done now so | |
183 | * that we can use set_pxa_fb_info */ | |
184 | static void __init n516_presetup_fb(void) | |
185 | { | |
186 | int padding_size; | |
187 | int totalsize; | |
188 | ||
189 | /* the frame buffer is divided as follows: | |
190 | command | CRC | padding | |
191 | 16kb waveform data | CRC | padding | |
192 | image data | CRC | |
193 | */ | |
194 | ||
195 | n516_board_info.fw = 800; | |
196 | n516_board_info.fh = 624; | |
197 | ||
198 | /* waveform must be 16k + 2 for checksum */ | |
199 | n516_board_info.wfm_size = roundup(16*1024 + 2, n516_board_info.fw); | |
200 | ||
201 | padding_size = PAGE_SIZE + (4 * n516_board_info.fw); | |
202 | ||
203 | /* total is 1 cmd , 1 wfm, padding and image */ | |
204 | totalsize = n516_board_info.fw + n516_board_info.wfm_size; | |
205 | totalsize += padding_size + (n516_board_info.fw*n516_board_info.fh); | |
206 | ||
207 | /* save this off because we're manipulating fw after this and | |
208 | * we'll need it when we're ready to setup the framebuffer */ | |
209 | ||
210 | /* the reason we do this adjustment is because we want to acquire | |
211 | * more framebuffer memory without imposing custom awareness on the | |
212 | * underlying driver */ | |
213 | n516_fb_pdata.modes[0].yres = DIV_ROUND_UP(totalsize, n516_board_info.fw); | |
214 | ||
215 | jz4740_framebuffer_device.dev.platform_data = &n516_fb_pdata; | |
216 | platform_device_register(&jz4740_framebuffer_device); | |
217 | } | |
218 | ||
219 | /* this gets called by metronomefb as part of its init, in our case, we | |
220 | * have already completed initial framebuffer init in presetup_fb so we | |
221 | * can just setup the fb access pointers */ | |
222 | static int n516_setup_fb(struct metronomefb_par *par) | |
223 | { | |
224 | /* metromem was set up by the notifier in share_video_mem so now | |
225 | * we can use its value to calculate the other entries */ | |
226 | par->metromem_cmd = (struct metromem_cmd *) n516_board_info.metromem; | |
227 | par->metromem_wfm = n516_board_info.metromem + n516_board_info.fw; | |
228 | par->metromem_img = par->metromem_wfm + n516_board_info.wfm_size; | |
229 | par->metromem_img_csum = (u16 *) (par->metromem_img + (n516_board_info.fw * n516_board_info.fh)); | |
230 | par->metromem_dma = n516_board_info.host_fbinfo->fix.smem_start; | |
231 | ||
232 | return 0; | |
233 | } | |
234 | ||
235 | static int n516_get_panel_type(void) | |
236 | { | |
237 | return 5; | |
238 | } | |
239 | ||
240 | static irqreturn_t n516_handle_irq(int irq, void *dev_id) | |
241 | { | |
242 | struct metronomefb_par *par = dev_id; | |
243 | ||
244 | dev_dbg(&par->pdev->dev, "Metronome IRQ! RDY=%d\n", gpio_get_value(GPIO_DISPLAY_RDY)); | |
245 | wake_up_all(&par->waitq); | |
246 | ||
247 | return IRQ_HANDLED; | |
248 | } | |
249 | ||
250 | static void n516_power_ctl(struct metronomefb_par *par, int cmd) | |
251 | { | |
252 | switch (cmd) { | |
253 | case METRONOME_POWER_OFF: | |
254 | gpio_set_value(GPIO_DISPLAY_OFF, 1); | |
255 | n516_enable_hostfb(false); | |
256 | break; | |
257 | case METRONOME_POWER_ON: | |
258 | gpio_set_value(GPIO_DISPLAY_OFF, 0); | |
259 | n516_enable_hostfb(true); | |
260 | break; | |
261 | } | |
262 | } | |
263 | ||
264 | static int n516_get_rdy(struct metronomefb_par *par) | |
265 | { | |
266 | return gpio_get_value(GPIO_DISPLAY_RDY); | |
267 | } | |
268 | ||
269 | static int n516_get_err(struct metronomefb_par *par) | |
270 | { | |
271 | return gpio_get_value(GPIO_DISPLAY_ERR); | |
272 | } | |
273 | ||
274 | static int n516_setup_irq(struct fb_info *info) | |
275 | { | |
276 | int ret; | |
277 | ||
278 | dev_dbg(&n516_device->dev, "ENTER %s\n", __func__); | |
279 | ||
280 | ret = request_irq(gpio_to_irq(GPIO_DISPLAY_RDY), n516_handle_irq, | |
281 | IRQF_TRIGGER_RISING, | |
282 | "n516", info->par); | |
283 | if (ret) | |
284 | dev_err(&n516_device->dev, "request_irq failed: %d\n", ret); | |
285 | ||
286 | return ret; | |
287 | } | |
288 | ||
289 | static void n516_set_rst(struct metronomefb_par *par, int state) | |
290 | { | |
291 | dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
292 | if (state) | |
293 | gpio_set_value(GPIO_DISPLAY_RST_L, 1); | |
294 | else | |
295 | gpio_set_value(GPIO_DISPLAY_RST_L, 0); | |
296 | } | |
297 | ||
298 | static void n516_set_stdby(struct metronomefb_par *par, int state) | |
299 | { | |
300 | dev_dbg(&n516_device->dev, "ENTER %s, RDY=%d\n", __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
301 | if (state) | |
302 | gpio_set_value(GPIO_DISPLAY_STBY, 1); | |
303 | else | |
304 | gpio_set_value(GPIO_DISPLAY_STBY, 0); | |
305 | } | |
306 | ||
307 | static int n516_wait_event(struct metronomefb_par *par) | |
308 | { | |
309 | unsigned long timeout = jiffies + HZ / 20; | |
310 | ||
311 | dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n", | |
312 | __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
313 | while (n516_get_rdy(par) && time_before(jiffies, timeout)) | |
314 | schedule(); | |
315 | ||
316 | dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n", | |
317 | __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
318 | return wait_event_timeout(par->waitq, | |
319 | n516_get_rdy(par), HZ * 2) ? 0 : -EIO; | |
320 | } | |
321 | ||
322 | static int n516_wait_event_intr(struct metronomefb_par *par) | |
323 | { | |
324 | unsigned long timeout = jiffies + HZ/20; | |
325 | ||
326 | dev_dbg(&n516_device->dev, "ENTER1 %s, RDY=%d\n", | |
327 | __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
328 | while (n516_get_rdy(par) && time_before(jiffies, timeout)) | |
329 | schedule(); | |
330 | ||
331 | dev_dbg(&n516_device->dev, "ENTER2 %s, RDY=%d\n", | |
332 | __func__, gpio_get_value(GPIO_DISPLAY_RDY)); | |
333 | return wait_event_interruptible_timeout(par->waitq, | |
334 | n516_get_rdy(par), HZ * 2) ? 0 : -EIO; | |
335 | } | |
336 | ||
337 | static void n516_cleanup(struct metronomefb_par *par) | |
338 | { | |
339 | int i; | |
340 | ||
341 | free_irq(gpio_to_irq(GPIO_DISPLAY_RDY), par); | |
342 | for (i = 0; i < ARRAY_SIZE(metronome_gpios); ++i) | |
343 | gpio_free(metronome_gpios[i]); | |
344 | } | |
345 | ||
346 | static struct metronome_board n516_board __initdata = { | |
347 | .owner = THIS_MODULE, | |
348 | .power_ctl = n516_power_ctl, | |
349 | .setup_irq = n516_setup_irq, | |
350 | .setup_io = n516_init_metronome_gpios, | |
351 | .setup_fb = n516_setup_fb, | |
352 | .set_rst = n516_set_rst, | |
353 | .get_err = n516_get_err, | |
354 | .get_rdy = n516_get_rdy, | |
355 | .set_stdby = n516_set_stdby, | |
356 | .met_wait_event = n516_wait_event, | |
357 | .met_wait_event_intr = n516_wait_event_intr, | |
358 | .get_panel_type = n516_get_panel_type, | |
359 | .cleanup = n516_cleanup, | |
360 | }; | |
361 | ||
362 | static int __init n516_init(void) | |
363 | { | |
364 | int ret; | |
365 | ||
366 | /* Keep the metronome off, until its driver is loaded */ | |
367 | ret = gpio_request(GPIO_DISPLAY_OFF, "Display off"); | |
368 | if (ret) | |
369 | return ret; | |
370 | ||
371 | gpio_direction_output(GPIO_DISPLAY_OFF, 1); | |
372 | ||
373 | /* before anything else, we request notification for any fb | |
374 | * creation events */ | |
375 | fb_register_client(&n516_fb_notif); | |
376 | ||
377 | n516_device = platform_device_alloc("metronomefb", -1); | |
378 | if (!n516_device) | |
379 | return -ENOMEM; | |
380 | ||
381 | /* the n516_board that will be seen by metronomefb is a copy */ | |
382 | platform_device_add_data(n516_device, &n516_board, | |
383 | sizeof(n516_board)); | |
384 | ||
385 | n516_presetup_fb(); | |
386 | ||
387 | return 0; | |
388 | } | |
389 | module_init(n516_init); | |
390 | ||
391 | MODULE_DESCRIPTION("board driver for n516 display"); | |
392 | MODULE_AUTHOR("Yauhen Kharuzhy"); | |
393 | MODULE_LICENSE("GPL"); |
arch/mips/jz4740/board-n516.c | ||
---|---|---|
1 | /* | |
2 | * linux/arch/mips/jz4740/board-516.c | |
3 | * | |
4 | * JZ4740 n516 board setup routines. | |
5 | * | |
6 | * Copyright (c) 2009, Yauhen Kharuzhy <jekhor@gmail.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | */ | |
13 | ||
14 | #include <linux/init.h> | |
15 | #include <linux/sched.h> | |
16 | #include <linux/ioport.h> | |
17 | #include <linux/mm.h> | |
18 | #include <linux/console.h> | |
19 | #include <linux/delay.h> | |
20 | #include <linux/i2c.h> | |
21 | #include <linux/platform_device.h> | |
22 | #include <linux/mtd/mtd.h> | |
23 | #include <linux/mmc/jz4740_mmc.h> | |
24 | #include <linux/mtd/jz4740_nand.h> | |
25 | #include <linux/leds.h> | |
26 | ||
27 | #include <linux/power_supply.h> | |
28 | #include <linux/power/gpio-charger.h> | |
29 | ||
30 | #include <linux/i2c.h> | |
31 | #include <linux/i2c-gpio.h> | |
32 | ||
33 | #include <asm/mach-jz4740/board-n516.h> | |
34 | #include <asm/mach-jz4740/platform.h> | |
35 | ||
36 | #include "clock.h" | |
37 | ||
38 | static long n516_panic_blink(long time) | |
39 | { | |
40 | gpio_set_value(GPIO_LED_ENABLE, 1); | |
41 | mdelay(200); | |
42 | gpio_set_value(GPIO_LED_ENABLE, 0); | |
43 | mdelay(200); | |
44 | ||
45 | return 400; | |
46 | } | |
47 | ||
48 | static void __init board_gpio_setup(void) | |
49 | { | |
50 | /* jz_gpio_enable_pullup(JZ_GPIO_PORTD(23)); | |
51 | jz_gpio_enable_pullup(JZ_GPIO_PORTD(24));*/ | |
52 | } | |
53 | ||
54 | static struct i2c_gpio_platform_data n516_i2c_pdata = { | |
55 | .sda_pin = JZ_GPIO_PORTD(23), | |
56 | .scl_pin = JZ_GPIO_PORTD(24), | |
57 | .udelay = 2, | |
58 | .timeout = 3 * HZ, | |
59 | }; | |
60 | ||
61 | static struct platform_device n516_i2c_device = { | |
62 | .name = "i2c-gpio", | |
63 | .id = -1, | |
64 | .dev = { | |
65 | .platform_data = &n516_i2c_pdata, | |
66 | }, | |
67 | }; | |
68 | ||
69 | static const struct i2c_board_info n516_i2c_board_info[] = { | |
70 | { | |
71 | .type = "LPC524", | |
72 | .addr = 0x54, | |
73 | }, | |
74 | { | |
75 | .type = "lm75a", | |
76 | .addr = 0x48, | |
77 | } | |
78 | }; | |
79 | ||
80 | static struct jz4740_mmc_platform_data n516_mmc_pdata = { | |
81 | .gpio_card_detect = GPIO_SD_CD_N, | |
82 | .card_detect_active_low = 1, | |
83 | .gpio_read_only = -1, | |
84 | .gpio_power = GPIO_SD_VCC_EN_N, | |
85 | .power_active_low = 1, | |
86 | }; | |
87 | ||
88 | static struct gpio_led n516_leds[] = { | |
89 | { | |
90 | .name = "n516:blue:power", | |
91 | .gpio = GPIO_LED_ENABLE, | |
92 | .default_state = LEDS_GPIO_DEFSTATE_ON, | |
93 | .default_trigger = "nand-disk", | |
94 | } | |
95 | }; | |
96 | ||
97 | static struct gpio_led_platform_data n516_leds_pdata = { | |
98 | .leds = n516_leds, | |
99 | .num_leds = ARRAY_SIZE(n516_leds), | |
100 | }; | |
101 | ||
102 | static struct platform_device n516_leds_device = { | |
103 | .name = "leds-gpio", | |
104 | .id = -1, | |
105 | .dev = { | |
106 | .platform_data = &n516_leds_pdata, | |
107 | }, | |
108 | }; | |
109 | ||
110 | static struct mtd_partition n516_partitions[] = { | |
111 | { .name = "NAND BOOT partition", | |
112 | .offset = 0 * 0x100000, | |
113 | .size = 4 * 0x100000, | |
114 | }, | |
115 | { .name = "NAND KERNEL partition", | |
116 | .offset = 4 * 0x100000, | |
117 | .size = 4 * 0x100000, | |
118 | }, | |
119 | { .name = "NAND ROOTFS partition", | |
120 | .offset = 8 * 0x100000, | |
121 | .size = 504 * 0x100000, | |
122 | }, | |
123 | }; | |
124 | ||
125 | static struct nand_ecclayout n516_ecclayout = { | |
126 | .eccbytes = 36, | |
127 | .eccpos = { | |
128 | 6, 7, 8, 9, 10, 11, 12, 13, 14, | |
129 | 15, 16, 17, 18, 19, 20, 21, 22, 23, | |
130 | 24, 25, 26, 27, 28, 29, 30, 31, 32, | |
131 | 33, 34, 35, 36, 37, 38, 39, 40, 41, | |
132 | }, | |
133 | .oobfree = { | |
134 | { | |
135 | .offset = 2, | |
136 | .length = 4 | |
137 | }, | |
138 | { | |
139 | .offset = 42, | |
140 | .length = 22, | |
141 | } | |
142 | } | |
143 | }; | |
144 | ||
145 | static struct jz_nand_platform_data n516_nand_pdata = { | |
146 | .ecc_layout = &n516_ecclayout, | |
147 | .partitions = n516_partitions, | |
148 | .num_partitions = ARRAY_SIZE(n516_partitions), | |
149 | .busy_gpio = 94, | |
150 | }; | |
151 | ||
152 | static char *n516_batteries[] = { | |
153 | "n516_battery", | |
154 | }; | |
155 | ||
156 | static struct gpio_charger_platform_data n516_charger_pdata = { | |
157 | .name = "usb", | |
158 | .type = POWER_SUPPLY_TYPE_USB, | |
159 | .gpio = GPIO_USB_DETECT, | |
160 | .gpio_active_low = 1, | |
161 | .batteries = n516_batteries, | |
162 | .num_batteries = ARRAY_SIZE(n516_batteries), | |
163 | }; | |
164 | ||
165 | static struct platform_device n516_charger_device = { | |
166 | .name = "gpio-charger", | |
167 | .dev = { | |
168 | .platform_data = &n516_charger_pdata, | |
169 | }, | |
170 | }; | |
171 | ||
172 | static struct platform_device *n516_devices[] __initdata = { | |
173 | &jz4740_nand_device, | |
174 | &n516_leds_device, | |
175 | &jz4740_mmc_device, | |
176 | &jz4740_i2s_device, | |
177 | &jz4740_codec_device, | |
178 | &jz4740_rtc_device, | |
179 | &jz4740_usb_gdt_device, | |
180 | &n516_i2c_device, | |
181 | &n516_charger_device, | |
182 | }; | |
183 | ||
184 | struct jz4740_clock_board_data jz4740_clock_bdata = { | |
185 | .ext_rate = 12000000, | |
186 | .rtc_rate = 32768, | |
187 | }; | |
188 | ||
189 | extern int jz_gpiolib_init(void); | |
190 | ||
191 | static int n516_setup_platform(void) | |
192 | { | |
193 | if (jz_gpiolib_init()) | |
194 | panic("Failed to initalize jz gpio\n"); | |
195 | ||
196 | jz4740_clock_init(); | |
197 | board_gpio_setup(); | |
198 | ||
199 | panic_blink = n516_panic_blink; | |
200 | i2c_register_board_info(0, n516_i2c_board_info, ARRAY_SIZE(n516_i2c_board_info)); | |
201 | jz4740_mmc_device.dev.platform_data = &n516_mmc_pdata; | |
202 | jz4740_nand_device.dev.platform_data = &n516_nand_pdata; | |
203 | ||
204 | return platform_add_devices(n516_devices, ARRAY_SIZE(n516_devices)); | |
205 | } | |
206 | arch_initcall(n516_setup_platform); |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9