Root/target/linux/xburst/patches-2.6.36/007-add-n526-board-support.patch

1From c1eb3a8a799e859b95725b85281c8460e6455135 Mon Sep 17 00:00:00 2001
2From: Lars-Peter Clausen <lars@metafoo.de>
3Date: Sat, 24 Apr 2010 17:25:23 +0200
4Subject: [PATCH] Add n526 board support
5
6---
7 arch/mips/jz4740/Kconfig | 3 +
8 arch/mips/jz4740/Makefile | 1 +
9 arch/mips/jz4740/board-n526.c | 320 +++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 324 insertions(+), 0 deletions(-)
11 create mode 100644 arch/mips/jz4740/board-n526.c
12
13--- a/arch/mips/jz4740/Kconfig
14+++ b/arch/mips/jz4740/Kconfig
15@@ -9,6 +9,9 @@ config JZ4740_QI_LB60
16 config JZ4740_N516
17     bool "Hanvon n516 eBook reader"
18 
19+config JZ4740_N526
20+ bool "Hanvon n526 eBook reader"
21+
22 endchoice
23 
24 config HAVE_PWM
25--- a/arch/mips/jz4740/Makefile
26+++ b/arch/mips/jz4740/Makefile
27@@ -13,6 +13,7 @@ obj-$(CONFIG_DEBUG_FS) += clock-debugfs.
28 
29 obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
30 obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
31+obj-$(CONFIG_JZ4740_N526) += board-n526.o
32 
33 # PM support
34 
35--- /dev/null
36+++ b/arch/mips/jz4740/board-n526.c
37@@ -0,0 +1,320 @@
38+/*
39+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
40+ * N526 eBook reader support
41+ *
42+ * This program is free software; you can redistribute it and/or modify it
43+ * under the terms of the GNU General Public License as published by the
44+ * Free Software Foundation; either version 2 of the License, or (at your
45+ * option) any later version.
46+ *
47+ * You should have received a copy of the GNU General Public License along
48+ * with this program; if not, write to the Free Software Foundation, Inc.,
49+ * 675 Mass Ave, Cambridge, MA 02139, USA.
50+ *
51+ */
52+
53+#include <linux/kernel.h>
54+#include <linux/init.h>
55+#include <linux/gpio.h>
56+
57+#include <linux/mutex.h>
58+#include <linux/wait.h>
59+#include <video/broadsheetfb.h>
60+#include <linux/delay.h>
61+#include <linux/interrupt.h>
62+
63+#include <linux/input.h>
64+#include <linux/gpio_keys.h>
65+
66+#include <linux/leds.h>
67+
68+#include <linux/i2c.h>
69+
70+#include "clock.h"
71+
72+#include <asm/mach-jz4740/jz4740_mmc.h>
73+#include <asm/mach-jz4740/jz4740_nand.h>
74+#include <asm/mach-jz4740/jz4740_fb.h>
75+
76+#include <asm/mach-jz4740/platform.h>
77+
78+/* NAND */
79+static struct nand_ecclayout n526_ecclayout = {
80+/* .eccbytes = 36,
81+ .eccpos = {
82+ 6, 7, 8, 9, 10, 11, 12, 13,
83+ 14, 15, 16, 17, 18, 19, 20, 21,
84+ 22, 23, 24, 25, 26, 27, 28, 29,
85+ 30, 31, 32, 33, 34, 35, 36, 37,
86+ 38, 39, 40, 41},*/
87+ .oobfree = {
88+ {
89+ .offset = 2,
90+ .length = 4,
91+ },
92+ {
93+ .offset = 42,
94+ .length = 22,
95+ },
96+ }
97+};
98+
99+static struct mtd_partition n526_partitions[] = {
100+ { .name = "NAND BOOT partition",
101+ .offset = 0 * 0x100000,
102+ .size = 4 * 0x100000,
103+ },
104+ { .name = "NAND KERNEL partition",
105+ .offset = 4 * 0x100000,
106+ .size = 4 * 0x100000,
107+ },
108+ { .name = "NAND ROOTFS partition",
109+ .offset = 16 * 0x100000,
110+ .size = 498 * 0x100000,
111+ },
112+};
113+
114+static struct jz_nand_platform_data n526_nand_pdata = {
115+ .ecc_layout = &n526_ecclayout,
116+ .partitions = n526_partitions,
117+ .num_partitions = ARRAY_SIZE(n526_partitions),
118+ .busy_gpio = JZ_GPIO_PORTC(30),
119+};
120+
121+static struct jz4740_mmc_platform_data n526_mmc_pdata = {
122+ .gpio_card_detect = JZ_GPIO_PORTD(7),
123+ .card_detect_active_low = 1,
124+ .gpio_read_only = -1,
125+ .gpio_power = JZ_GPIO_PORTD(17),
126+ .power_active_low = 1,
127+};
128+
129+static struct gpio_led n526_leds[] = {
130+ {
131+ .name = "n526:blue:power",
132+ .gpio = JZ_GPIO_PORTD(28),
133+ .default_state = LEDS_GPIO_DEFSTATE_ON,
134+ }
135+};
136+
137+static struct gpio_led_platform_data n526_leds_pdata = {
138+ .leds = n526_leds,
139+ .num_leds = ARRAY_SIZE(n526_leds),
140+};
141+
142+static struct platform_device n526_leds_device = {
143+ .name = "leds-gpio",
144+ .id = -1,
145+ .dev = {
146+ .platform_data = &n526_leds_pdata,
147+ },
148+};
149+
150+static void __init board_gpio_setup(void)
151+{
152+ /* We only need to enable/disable pullup here for pins used in generic
153+ * drivers. Everything else is done by the drivers themselfs. */
154+ jz_gpio_disable_pullup(JZ_GPIO_PORTD(17));
155+ jz_gpio_enable_pullup(JZ_GPIO_PORTD(7));
156+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(19));
157+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(20));
158+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(21));
159+ jz_gpio_disable_pullup(JZ_GPIO_PORTC(23));
160+}
161+
162+
163+static const int n526_eink_ctrl_gpios[] = {
164+ 0,
165+ JZ_GPIO_PORTC(23),
166+ JZ_GPIO_PORTC(19),
167+ JZ_GPIO_PORTC(20),
168+};
169+
170+static void n526_eink_set_ctl(struct broadsheetfb_par * par, unsigned char ctrl, u8
171+value)
172+{
173+ gpio_set_value(n526_eink_ctrl_gpios[ctrl], value);
174+}
175+
176+
177+static int n526_eink_wait(struct broadsheetfb_par *par)
178+{
179+ wait_event(par->waitq, gpio_get_value(JZ_GPIO_PORTB(17)));
180+
181+ return 0;
182+}
183+
184+static u16 n526_eink_get_hdb(struct broadsheetfb_par *par)
185+{
186+ u16 value = 0;
187+ jz_gpio_port_direction_input(JZ_GPIO_PORTC(0), 0xffff);
188+ gpio_set_value(JZ_GPIO_PORTC(21), 0);
189+ mdelay(100);
190+
191+ value = jz_gpio_port_get_value(JZ_GPIO_PORTC(0), 0xffff);
192+
193+ gpio_set_value(JZ_GPIO_PORTC(21), 1);
194+ jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
195+ return value;
196+}
197+
198+static void n526_eink_set_hdb(struct broadsheetfb_par *par, u16 value)
199+{
200+ jz_gpio_port_set_value(JZ_GPIO_PORTC(0), value, 0xffff);
201+}
202+
203+static int n526_eink_init(struct broadsheetfb_par *par)
204+{
205+ int i;
206+
207+ gpio_request(JZ_GPIO_PORTD(1), "display reset");
208+ gpio_direction_output(JZ_GPIO_PORTD(1), 1);
209+ mdelay(10);
210+ gpio_set_value(JZ_GPIO_PORTD(1), 0);
211+
212+ gpio_request(JZ_GPIO_PORTB(18), "eink enable");
213+ gpio_direction_output(JZ_GPIO_PORTB(18), 0);
214+
215+ gpio_request(JZ_GPIO_PORTB(29), "foobar");
216+ gpio_direction_output(JZ_GPIO_PORTB(29), 1);
217+
218+ for(i = 1; i < ARRAY_SIZE(n526_eink_ctrl_gpios); ++i) {
219+ gpio_request(n526_eink_ctrl_gpios[i], "eink display ctrl");
220+ gpio_direction_output(n526_eink_ctrl_gpios[i], 0);
221+ }
222+
223+ gpio_request(JZ_GPIO_PORTC(22), "foobar");
224+ gpio_direction_input(JZ_GPIO_PORTC(22));
225+ gpio_request(JZ_GPIO_PORTC(21), "eink nRD");
226+ gpio_direction_output(JZ_GPIO_PORTC(21), 1);
227+
228+ for(i = 0; i < 16; ++i) {
229+ gpio_request(JZ_GPIO_PORTC(i), "eink display data");
230+ }
231+ jz_gpio_port_direction_output(JZ_GPIO_PORTC(0), 0xffff);
232+
233+ gpio_set_value(JZ_GPIO_PORTB(18), 1);
234+
235+ return 0;
236+}
237+
238+static irqreturn_t n526_eink_busy_irq(int irq, void *devid)
239+{
240+ struct broadsheetfb_par *par = devid;
241+ wake_up(&par->waitq);
242+
243+ return IRQ_HANDLED;
244+}
245+
246+static int n526_eink_setup_irq(struct fb_info *info)
247+{
248+ int ret;
249+ struct broadsheetfb_par *par = info->par;
250+
251+ gpio_request(JZ_GPIO_PORTB(17), "eink busy");
252+ gpio_direction_input(JZ_GPIO_PORTB(17));
253+
254+ ret = request_irq(gpio_to_irq(JZ_GPIO_PORTB(17)), n526_eink_busy_irq,
255+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
256+ "eink busyline", par);
257+ if (ret)
258+ printk("n526 display: Failed to request busyline irq: %d\n", ret);
259+ return 0;
260+}
261+
262+static void n526_eink_cleanup(struct broadsheetfb_par *par)
263+{
264+}
265+
266+static struct broadsheet_board broadsheet_pdata = {
267+ .owner = THIS_MODULE,
268+ .init = n526_eink_init,
269+ .wait_for_rdy = n526_eink_wait,
270+ .set_ctl = n526_eink_set_ctl,
271+ .set_hdb = n526_eink_set_hdb,
272+ .get_hdb = n526_eink_get_hdb,
273+ .cleanup = n526_eink_cleanup,
274+ .setup_irq = n526_eink_setup_irq,
275+};
276+
277+static struct platform_device n526_broadsheet_device = {
278+ .name = "broadsheetfb",
279+ .id = -1,
280+ .dev = {
281+ .platform_data = &broadsheet_pdata,
282+ },
283+};
284+
285+/* Buttons */
286+static struct gpio_keys_button n526_gpio_keys_buttons[] = {
287+ [0] = {
288+ .code = KEY_ENTER,
289+ .gpio = 0,
290+ .active_low = 1,
291+ .desc = "Power",
292+ },
293+};
294+
295+static struct gpio_keys_platform_data n526_gpio_keys_data = {
296+ .nbuttons = ARRAY_SIZE(n526_gpio_keys_buttons),
297+ .buttons = n526_gpio_keys_buttons,
298+};
299+
300+static struct platform_device n526_gpio_keys_device = {
301+ .name = "gpio-keys",
302+ .id = -1,
303+ .dev = {
304+ .platform_data = &n526_gpio_keys_data,
305+ }
306+};
307+
308+static struct i2c_board_info n526_i2c_board_info = {
309+ .type = "n526-lpc",
310+ .addr = 0x54,
311+};
312+
313+static struct platform_device *n526_platform_devices[] __initdata = {
314+ &jz4740_usb_ohci_device,
315+ &jz4740_udc_device,
316+ &jz4740_mmc_device,
317+ &jz4740_nand_device,
318+ &jz4740_i2s_device,
319+ &jz4740_codec_device,
320+ &jz4740_pcm_device,
321+ &jz4740_rtc_device,
322+ &jz4740_i2c_device,
323+ &n526_leds_device,
324+ &n526_broadsheet_device,
325+ &n526_gpio_keys_device,
326+};
327+
328+static int __init n526_init_platform_devices(void)
329+{
330+ jz4740_nand_device.dev.platform_data = &n526_nand_pdata;
331+ jz4740_mmc_device.dev.platform_data = &n526_mmc_pdata;
332+
333+ jz4740_serial_device_register();
334+
335+ n526_i2c_board_info.irq = gpio_to_irq(JZ_GPIO_PORTD(14)),
336+ i2c_register_board_info(0, &n526_i2c_board_info, 1);
337+
338+ return platform_add_devices(n526_platform_devices,
339+ ARRAY_SIZE(n526_platform_devices));
340+
341+}
342+
343+struct jz4740_clock_board_data jz4740_clock_bdata = {
344+ .ext_rate = 12000000,
345+ .rtc_rate = 32768,
346+};
347+
348+static int __init n526_board_setup(void)
349+{
350+ board_gpio_setup();
351+
352+ if (n526_init_platform_devices())
353+ panic("Failed to initalize platform devices\n");
354+
355+ return 0;
356+}
357+arch_initcall(n526_board_setup);
358

Archive Download this file



interactive