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

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

Archive Download this file



interactive