1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * KFR2R09 board support code |
4 | * |
5 | * Copyright (C) 2009 Magnus Damm |
6 | */ |
7 | |
8 | #include <asm/clock.h> |
9 | #include <asm/io.h> |
10 | #include <asm/machvec.h> |
11 | #include <asm/suspend.h> |
12 | |
13 | #include <cpu/sh7724.h> |
14 | |
15 | #include <linux/clkdev.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/gpio.h> |
18 | #include <linux/gpio/machine.h> |
19 | #include <linux/i2c.h> |
20 | #include <linux/init.h> |
21 | #include <linux/input.h> |
22 | #include <linux/input/sh_keysc.h> |
23 | #include <linux/interrupt.h> |
24 | #include <linux/memblock.h> |
25 | #include <linux/mfd/tmio.h> |
26 | #include <linux/mmc/host.h> |
27 | #include <linux/mtd/physmap.h> |
28 | #include <linux/platform_data/lv5207lp.h> |
29 | #include <linux/platform_device.h> |
30 | #include <linux/regulator/fixed.h> |
31 | #include <linux/regulator/machine.h> |
32 | #include <linux/sh_intc.h> |
33 | #include <linux/usb/r8a66597.h> |
34 | #include <linux/videodev2.h> |
35 | #include <linux/dma-map-ops.h> |
36 | |
37 | #include <mach/kfr2r09.h> |
38 | |
39 | #include <media/drv-intf/renesas-ceu.h> |
40 | #include <media/i2c/rj54n1cb0c.h> |
41 | |
42 | #include <video/sh_mobile_lcdc.h> |
43 | |
44 | #define CEU_BUFFER_MEMORY_SIZE (4 << 20) |
45 | static phys_addr_t ceu_dma_membase; |
46 | |
47 | /* set VIO_CKO clock to 25MHz */ |
48 | #define CEU_MCLK_FREQ 25000000 |
49 | #define DRVCRB 0xA405018C |
50 | |
51 | static struct mtd_partition kfr2r09_nor_flash_partitions[] = |
52 | { |
53 | { |
54 | .name = "boot" , |
55 | .offset = 0, |
56 | .size = (4 * 1024 * 1024), |
57 | .mask_flags = MTD_WRITEABLE, /* Read-only */ |
58 | }, |
59 | { |
60 | .name = "other" , |
61 | .offset = MTDPART_OFS_APPEND, |
62 | .size = MTDPART_SIZ_FULL, |
63 | }, |
64 | }; |
65 | |
66 | static struct physmap_flash_data kfr2r09_nor_flash_data = { |
67 | .width = 2, |
68 | .parts = kfr2r09_nor_flash_partitions, |
69 | .nr_parts = ARRAY_SIZE(kfr2r09_nor_flash_partitions), |
70 | }; |
71 | |
72 | static struct resource kfr2r09_nor_flash_resources[] = { |
73 | [0] = { |
74 | .name = "NOR Flash" , |
75 | .start = 0x00000000, |
76 | .end = 0x03ffffff, |
77 | .flags = IORESOURCE_MEM, |
78 | } |
79 | }; |
80 | |
81 | static struct platform_device kfr2r09_nor_flash_device = { |
82 | .name = "physmap-flash" , |
83 | .resource = kfr2r09_nor_flash_resources, |
84 | .num_resources = ARRAY_SIZE(kfr2r09_nor_flash_resources), |
85 | .dev = { |
86 | .platform_data = &kfr2r09_nor_flash_data, |
87 | }, |
88 | }; |
89 | |
90 | static struct resource kfr2r09_nand_flash_resources[] = { |
91 | [0] = { |
92 | .name = "NAND Flash" , |
93 | .start = 0x10000000, |
94 | .end = 0x1001ffff, |
95 | .flags = IORESOURCE_MEM, |
96 | } |
97 | }; |
98 | |
99 | static struct platform_device kfr2r09_nand_flash_device = { |
100 | .name = "onenand-flash" , |
101 | .resource = kfr2r09_nand_flash_resources, |
102 | .num_resources = ARRAY_SIZE(kfr2r09_nand_flash_resources), |
103 | }; |
104 | |
105 | static struct sh_keysc_info kfr2r09_sh_keysc_info = { |
106 | .mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */ |
107 | .scan_timing = 3, |
108 | .delay = 10, |
109 | .keycodes = { |
110 | KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER, |
111 | KEY_1, KEY_2, KEY_3, 0, KEY_UP, |
112 | KEY_4, KEY_5, KEY_6, 0, KEY_LEFT, |
113 | KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT, |
114 | KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN, |
115 | 0, 0, 0, 0, 0 |
116 | }, |
117 | }; |
118 | |
119 | static struct resource kfr2r09_sh_keysc_resources[] = { |
120 | [0] = { |
121 | .name = "KEYSC" , |
122 | .start = 0x044b0000, |
123 | .end = 0x044b000f, |
124 | .flags = IORESOURCE_MEM, |
125 | }, |
126 | [1] = { |
127 | .start = evt2irq(0xbe0), |
128 | .flags = IORESOURCE_IRQ, |
129 | }, |
130 | }; |
131 | |
132 | static struct platform_device kfr2r09_sh_keysc_device = { |
133 | .name = "sh_keysc" , |
134 | .id = 0, /* "keysc0" clock */ |
135 | .num_resources = ARRAY_SIZE(kfr2r09_sh_keysc_resources), |
136 | .resource = kfr2r09_sh_keysc_resources, |
137 | .dev = { |
138 | .platform_data = &kfr2r09_sh_keysc_info, |
139 | }, |
140 | }; |
141 | |
142 | static const struct fb_videomode kfr2r09_lcdc_modes[] = { |
143 | { |
144 | .name = "TX07D34VM0AAA" , |
145 | .xres = 240, |
146 | .yres = 400, |
147 | .left_margin = 0, |
148 | .right_margin = 16, |
149 | .hsync_len = 8, |
150 | .upper_margin = 0, |
151 | .lower_margin = 1, |
152 | .vsync_len = 1, |
153 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
154 | }, |
155 | }; |
156 | |
157 | static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { |
158 | .clock_source = LCDC_CLK_BUS, |
159 | .ch[0] = { |
160 | .chan = LCDC_CHAN_MAINLCD, |
161 | .fourcc = V4L2_PIX_FMT_RGB565, |
162 | .interface_type = SYS18, |
163 | .clock_divider = 6, |
164 | .flags = LCDC_FLAGS_DWPOL, |
165 | .lcd_modes = kfr2r09_lcdc_modes, |
166 | .num_modes = ARRAY_SIZE(kfr2r09_lcdc_modes), |
167 | .panel_cfg = { |
168 | .width = 35, |
169 | .height = 58, |
170 | .setup_sys = kfr2r09_lcd_setup, |
171 | .start_transfer = kfr2r09_lcd_start, |
172 | }, |
173 | .sys_bus_cfg = { |
174 | .ldmt2r = 0x07010904, |
175 | .ldmt3r = 0x14012914, |
176 | /* set 1s delay to encourage fsync() */ |
177 | .deferred_io_msec = 1000, |
178 | }, |
179 | } |
180 | }; |
181 | |
182 | static struct resource kfr2r09_sh_lcdc_resources[] = { |
183 | [0] = { |
184 | .name = "LCDC" , |
185 | .start = 0xfe940000, /* P4-only space */ |
186 | .end = 0xfe942fff, |
187 | .flags = IORESOURCE_MEM, |
188 | }, |
189 | [1] = { |
190 | .start = evt2irq(0xf40), |
191 | .flags = IORESOURCE_IRQ, |
192 | }, |
193 | }; |
194 | |
195 | static struct platform_device kfr2r09_sh_lcdc_device = { |
196 | .name = "sh_mobile_lcdc_fb" , |
197 | .num_resources = ARRAY_SIZE(kfr2r09_sh_lcdc_resources), |
198 | .resource = kfr2r09_sh_lcdc_resources, |
199 | .dev = { |
200 | .platform_data = &kfr2r09_sh_lcdc_info, |
201 | }, |
202 | }; |
203 | |
204 | static struct lv5207lp_platform_data kfr2r09_backlight_data = { |
205 | .dev = &kfr2r09_sh_lcdc_device.dev, |
206 | .def_value = 13, |
207 | .max_value = 13, |
208 | }; |
209 | |
210 | static struct i2c_board_info kfr2r09_backlight_board_info = { |
211 | I2C_BOARD_INFO("lv5207lp" , 0x75), |
212 | .platform_data = &kfr2r09_backlight_data, |
213 | }; |
214 | |
215 | static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { |
216 | .on_chip = 1, |
217 | }; |
218 | |
219 | static struct resource kfr2r09_usb0_gadget_resources[] = { |
220 | [0] = { |
221 | .start = 0x04d80000, |
222 | .end = 0x04d80123, |
223 | .flags = IORESOURCE_MEM, |
224 | }, |
225 | [1] = { |
226 | .start = evt2irq(0xa20), |
227 | .end = evt2irq(0xa20), |
228 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, |
229 | }, |
230 | }; |
231 | |
232 | static struct platform_device kfr2r09_usb0_gadget_device = { |
233 | .name = "r8a66597_udc" , |
234 | .id = 0, |
235 | .dev = { |
236 | .dma_mask = NULL, /* not use dma */ |
237 | .coherent_dma_mask = 0xffffffff, |
238 | .platform_data = &kfr2r09_usb0_gadget_data, |
239 | }, |
240 | .num_resources = ARRAY_SIZE(kfr2r09_usb0_gadget_resources), |
241 | .resource = kfr2r09_usb0_gadget_resources, |
242 | }; |
243 | |
244 | static struct ceu_platform_data ceu_pdata = { |
245 | .num_subdevs = 1, |
246 | .subdevs = { |
247 | { /* [0] = rj54n1cb0c */ |
248 | .flags = 0, |
249 | .bus_width = 8, |
250 | .bus_shift = 0, |
251 | .i2c_adapter_id = 1, |
252 | .i2c_address = 0x50, |
253 | }, |
254 | }, |
255 | }; |
256 | |
257 | static struct resource kfr2r09_ceu_resources[] = { |
258 | [0] = { |
259 | .name = "CEU" , |
260 | .start = 0xfe910000, |
261 | .end = 0xfe91009f, |
262 | .flags = IORESOURCE_MEM, |
263 | }, |
264 | [1] = { |
265 | .start = evt2irq(0x880), |
266 | .end = evt2irq(0x880), |
267 | .flags = IORESOURCE_IRQ, |
268 | }, |
269 | }; |
270 | |
271 | static struct platform_device kfr2r09_ceu_device = { |
272 | .name = "renesas-ceu" , |
273 | .id = 0, /* "ceu0" clock */ |
274 | .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), |
275 | .resource = kfr2r09_ceu_resources, |
276 | .dev = { |
277 | .platform_data = &ceu_pdata, |
278 | }, |
279 | }; |
280 | |
281 | static struct rj54n1_pdata rj54n1_priv = { |
282 | .mclk_freq = CEU_MCLK_FREQ, |
283 | .ioctl_high = false, |
284 | }; |
285 | |
286 | static struct i2c_board_info kfr2r09_i2c_camera = { |
287 | I2C_BOARD_INFO("rj54n1cb0c" , 0x50), |
288 | .platform_data = &rj54n1_priv, |
289 | }; |
290 | |
291 | static struct gpiod_lookup_table rj54n1_gpios = { |
292 | .dev_id = "1-0050" , |
293 | .table = { |
294 | GPIO_LOOKUP("sh7724_pfc" , GPIO_PTB4, "poweron" , |
295 | GPIO_ACTIVE_HIGH), |
296 | GPIO_LOOKUP("sh7724_pfc" , GPIO_PTB7, "enable" , |
297 | GPIO_ACTIVE_HIGH), |
298 | }, |
299 | }; |
300 | |
301 | /* Fixed 3.3V regulator to be used by SDHI0 */ |
302 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = |
303 | { |
304 | REGULATOR_SUPPLY("vmmc" , "sh_mobile_sdhi.0" ), |
305 | REGULATOR_SUPPLY("vqmmc" , "sh_mobile_sdhi.0" ), |
306 | }; |
307 | |
308 | static struct resource kfr2r09_sh_sdhi0_resources[] = { |
309 | [0] = { |
310 | .name = "SDHI0" , |
311 | .start = 0x04ce0000, |
312 | .end = 0x04ce00ff, |
313 | .flags = IORESOURCE_MEM, |
314 | }, |
315 | [1] = { |
316 | .start = evt2irq(0xe80), |
317 | .flags = IORESOURCE_IRQ, |
318 | }, |
319 | }; |
320 | |
321 | static struct tmio_mmc_data sh7724_sdhi0_data = { |
322 | .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, |
323 | .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, |
324 | .capabilities = MMC_CAP_SDIO_IRQ, |
325 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, |
326 | }; |
327 | |
328 | static struct platform_device kfr2r09_sh_sdhi0_device = { |
329 | .name = "sh_mobile_sdhi" , |
330 | .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), |
331 | .resource = kfr2r09_sh_sdhi0_resources, |
332 | .dev = { |
333 | .platform_data = &sh7724_sdhi0_data, |
334 | }, |
335 | }; |
336 | |
337 | static struct platform_device *kfr2r09_devices[] __initdata = { |
338 | &kfr2r09_nor_flash_device, |
339 | &kfr2r09_nand_flash_device, |
340 | &kfr2r09_sh_keysc_device, |
341 | &kfr2r09_sh_lcdc_device, |
342 | &kfr2r09_sh_sdhi0_device, |
343 | }; |
344 | |
345 | #define BSC_CS0BCR 0xfec10004 |
346 | #define BSC_CS0WCR 0xfec10024 |
347 | #define BSC_CS4BCR 0xfec10010 |
348 | #define BSC_CS4WCR 0xfec10030 |
349 | #define PORT_MSELCRB 0xa4050182 |
350 | |
351 | #ifdef CONFIG_I2C |
352 | static int kfr2r09_usb0_gadget_i2c_setup(void) |
353 | { |
354 | struct i2c_adapter *a; |
355 | struct i2c_msg msg; |
356 | unsigned char buf[2]; |
357 | int ret; |
358 | |
359 | a = i2c_get_adapter(nr: 0); |
360 | if (!a) |
361 | return -ENODEV; |
362 | |
363 | /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */ |
364 | buf[0] = 0x13; |
365 | msg.addr = 0x09; |
366 | msg.buf = buf; |
367 | msg.len = 1; |
368 | msg.flags = 0; |
369 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
370 | if (ret != 1) |
371 | return -ENODEV; |
372 | |
373 | buf[0] = 0; |
374 | msg.addr = 0x09; |
375 | msg.buf = buf; |
376 | msg.len = 1; |
377 | msg.flags = I2C_M_RD; |
378 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
379 | if (ret != 1) |
380 | return -ENODEV; |
381 | |
382 | buf[1] = buf[0] | (1 << 1); |
383 | buf[0] = 0x13; |
384 | msg.addr = 0x09; |
385 | msg.buf = buf; |
386 | msg.len = 2; |
387 | msg.flags = 0; |
388 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
389 | if (ret != 1) |
390 | return -ENODEV; |
391 | |
392 | return 0; |
393 | } |
394 | |
395 | static int kfr2r09_serial_i2c_setup(void) |
396 | { |
397 | struct i2c_adapter *a; |
398 | struct i2c_msg msg; |
399 | unsigned char buf[2]; |
400 | int ret; |
401 | |
402 | a = i2c_get_adapter(nr: 0); |
403 | if (!a) |
404 | return -ENODEV; |
405 | |
406 | /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */ |
407 | buf[0] = 0x13; |
408 | msg.addr = 0x09; |
409 | msg.buf = buf; |
410 | msg.len = 1; |
411 | msg.flags = 0; |
412 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
413 | if (ret != 1) |
414 | return -ENODEV; |
415 | |
416 | buf[0] = 0; |
417 | msg.addr = 0x09; |
418 | msg.buf = buf; |
419 | msg.len = 1; |
420 | msg.flags = I2C_M_RD; |
421 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
422 | if (ret != 1) |
423 | return -ENODEV; |
424 | |
425 | buf[1] = buf[0] | (1 << 6); |
426 | buf[0] = 0x13; |
427 | msg.addr = 0x09; |
428 | msg.buf = buf; |
429 | msg.len = 2; |
430 | msg.flags = 0; |
431 | ret = i2c_transfer(adap: a, msgs: &msg, num: 1); |
432 | if (ret != 1) |
433 | return -ENODEV; |
434 | |
435 | return 0; |
436 | } |
437 | #else |
438 | static int kfr2r09_usb0_gadget_i2c_setup(void) |
439 | { |
440 | return -ENODEV; |
441 | } |
442 | |
443 | static int kfr2r09_serial_i2c_setup(void) |
444 | { |
445 | return -ENODEV; |
446 | } |
447 | #endif |
448 | |
449 | static int kfr2r09_usb0_gadget_setup(void) |
450 | { |
451 | int plugged_in; |
452 | |
453 | gpio_request(gpio: GPIO_PTN4, NULL); /* USB_DET */ |
454 | gpio_direction_input(gpio: GPIO_PTN4); |
455 | plugged_in = gpio_get_value(gpio: GPIO_PTN4); |
456 | if (!plugged_in) |
457 | return -ENODEV; /* no cable plugged in */ |
458 | |
459 | if (kfr2r09_usb0_gadget_i2c_setup() != 0) |
460 | return -ENODEV; /* unable to configure using i2c */ |
461 | |
462 | __raw_writew(val: (__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); |
463 | gpio_request(gpio: GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */ |
464 | gpio_request(gpio: GPIO_PTV6, NULL); /* USBCLK_ON */ |
465 | gpio_direction_output(gpio: GPIO_PTV6, value: 1); /* USBCLK_ON = H */ |
466 | msleep(msecs: 20); /* wait 20ms to let the clock settle */ |
467 | clk_enable(clk_get(NULL, "usb0" )); |
468 | __raw_writew(val: 0x0600, addr: 0xa40501d4); |
469 | |
470 | return 0; |
471 | } |
472 | |
473 | extern char kfr2r09_sdram_enter_start; |
474 | extern char kfr2r09_sdram_enter_end; |
475 | extern char kfr2r09_sdram_leave_start; |
476 | extern char kfr2r09_sdram_leave_end; |
477 | |
478 | static int __init kfr2r09_devices_setup(void) |
479 | { |
480 | struct clk *camera_clk; |
481 | |
482 | /* register board specific self-refresh code */ |
483 | sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | |
484 | SUSP_SH_RSTANDBY, |
485 | &kfr2r09_sdram_enter_start, |
486 | &kfr2r09_sdram_enter_end, |
487 | &kfr2r09_sdram_leave_start, |
488 | &kfr2r09_sdram_leave_end); |
489 | |
490 | regulator_register_always_on(id: 0, name: "fixed-3.3V" , supplies: fixed3v3_power_consumers, |
491 | ARRAY_SIZE(fixed3v3_power_consumers), uv: 3300000); |
492 | |
493 | /* enable SCIF1 serial port for YC401 console support */ |
494 | gpio_request(gpio: GPIO_FN_SCIF1_RXD, NULL); |
495 | gpio_request(gpio: GPIO_FN_SCIF1_TXD, NULL); |
496 | kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */ |
497 | gpio_request(gpio: GPIO_PTG3, NULL); /* HPON_ON */ |
498 | gpio_direction_output(gpio: GPIO_PTG3, value: 1); /* HPON_ON = H */ |
499 | |
500 | /* setup NOR flash at CS0 */ |
501 | __raw_writel(val: 0x36db0400, BSC_CS0BCR); |
502 | __raw_writel(val: 0x00000500, BSC_CS0WCR); |
503 | |
504 | /* setup NAND flash at CS4 */ |
505 | __raw_writel(val: 0x36db0400, BSC_CS4BCR); |
506 | __raw_writel(val: 0x00000500, BSC_CS4WCR); |
507 | |
508 | /* setup KEYSC pins */ |
509 | gpio_request(gpio: GPIO_FN_KEYOUT0, NULL); |
510 | gpio_request(gpio: GPIO_FN_KEYOUT1, NULL); |
511 | gpio_request(gpio: GPIO_FN_KEYOUT2, NULL); |
512 | gpio_request(gpio: GPIO_FN_KEYOUT3, NULL); |
513 | gpio_request(gpio: GPIO_FN_KEYOUT4_IN6, NULL); |
514 | gpio_request(gpio: GPIO_FN_KEYIN0, NULL); |
515 | gpio_request(gpio: GPIO_FN_KEYIN1, NULL); |
516 | gpio_request(gpio: GPIO_FN_KEYIN2, NULL); |
517 | gpio_request(gpio: GPIO_FN_KEYIN3, NULL); |
518 | gpio_request(gpio: GPIO_FN_KEYIN4, NULL); |
519 | gpio_request(gpio: GPIO_FN_KEYOUT5_IN5, NULL); |
520 | |
521 | /* setup LCDC pins for SYS panel */ |
522 | gpio_request(gpio: GPIO_FN_LCDD17, NULL); |
523 | gpio_request(gpio: GPIO_FN_LCDD16, NULL); |
524 | gpio_request(gpio: GPIO_FN_LCDD15, NULL); |
525 | gpio_request(gpio: GPIO_FN_LCDD14, NULL); |
526 | gpio_request(gpio: GPIO_FN_LCDD13, NULL); |
527 | gpio_request(gpio: GPIO_FN_LCDD12, NULL); |
528 | gpio_request(gpio: GPIO_FN_LCDD11, NULL); |
529 | gpio_request(gpio: GPIO_FN_LCDD10, NULL); |
530 | gpio_request(gpio: GPIO_FN_LCDD9, NULL); |
531 | gpio_request(gpio: GPIO_FN_LCDD8, NULL); |
532 | gpio_request(GPIO_FN_LCDD7, NULL); |
533 | gpio_request(GPIO_FN_LCDD6, NULL); |
534 | gpio_request(GPIO_FN_LCDD5, NULL); |
535 | gpio_request(GPIO_FN_LCDD4, NULL); |
536 | gpio_request(GPIO_FN_LCDD3, NULL); |
537 | gpio_request(GPIO_FN_LCDD2, NULL); |
538 | gpio_request(GPIO_FN_LCDD1, NULL); |
539 | gpio_request(GPIO_FN_LCDD0, NULL); |
540 | gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */ |
541 | gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */ |
542 | gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */ |
543 | gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */ |
544 | gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */ |
545 | gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */ |
546 | gpio_direction_output(GPIO_PTE4, 1); |
547 | gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */ |
548 | gpio_direction_output(GPIO_PTF4, 1); |
549 | gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */ |
550 | gpio_direction_output(GPIO_PTU0, 1); |
551 | |
552 | /* setup USB function */ |
553 | if (kfr2r09_usb0_gadget_setup() == 0) |
554 | platform_device_register(&kfr2r09_usb0_gadget_device); |
555 | |
556 | /* CEU */ |
557 | gpio_request(GPIO_FN_VIO_CKO, NULL); |
558 | gpio_request(GPIO_FN_VIO0_CLK, NULL); |
559 | gpio_request(GPIO_FN_VIO0_VD, NULL); |
560 | gpio_request(GPIO_FN_VIO0_HD, NULL); |
561 | gpio_request(GPIO_FN_VIO0_FLD, NULL); |
562 | gpio_request(GPIO_FN_VIO0_D7, NULL); |
563 | gpio_request(GPIO_FN_VIO0_D6, NULL); |
564 | gpio_request(GPIO_FN_VIO0_D5, NULL); |
565 | gpio_request(GPIO_FN_VIO0_D4, NULL); |
566 | gpio_request(GPIO_FN_VIO0_D3, NULL); |
567 | gpio_request(GPIO_FN_VIO0_D2, NULL); |
568 | gpio_request(GPIO_FN_VIO0_D1, NULL); |
569 | gpio_request(GPIO_FN_VIO0_D0, NULL); |
570 | |
571 | /* SDHI0 connected to yc304 */ |
572 | gpio_request(GPIO_FN_SDHI0CD, NULL); |
573 | gpio_request(GPIO_FN_SDHI0D3, NULL); |
574 | gpio_request(GPIO_FN_SDHI0D2, NULL); |
575 | gpio_request(GPIO_FN_SDHI0D1, NULL); |
576 | gpio_request(GPIO_FN_SDHI0D0, NULL); |
577 | gpio_request(GPIO_FN_SDHI0CMD, NULL); |
578 | gpio_request(GPIO_FN_SDHI0CLK, NULL); |
579 | |
580 | i2c_register_board_info(busnum: 0, info: &kfr2r09_backlight_board_info, n: 1); |
581 | |
582 | /* Set camera clock frequency and register and alias for rj54n1. */ |
583 | camera_clk = clk_get(NULL, "video_clk" ); |
584 | if (!IS_ERR(ptr: camera_clk)) { |
585 | clk_set_rate(camera_clk, |
586 | clk_round_rate(camera_clk, CEU_MCLK_FREQ)); |
587 | clk_put(camera_clk); |
588 | } |
589 | clk_add_alias(NULL, "1-0050" , "video_clk" , NULL); |
590 | |
591 | /* set DRVCRB |
592 | * |
593 | * use 1.8 V for VccQ_VIO |
594 | * use 2.85V for VccQ_SR |
595 | */ |
596 | __raw_writew(val: (__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); |
597 | |
598 | gpiod_add_lookup_table(table: &rj54n1_gpios); |
599 | |
600 | i2c_register_board_info(busnum: 1, info: &kfr2r09_i2c_camera, n: 1); |
601 | |
602 | /* Initialize CEU platform device separately to map memory first */ |
603 | device_initialize(dev: &kfr2r09_ceu_device.dev); |
604 | dma_declare_coherent_memory(dev: &kfr2r09_ceu_device.dev, |
605 | phys_addr: ceu_dma_membase, device_addr: ceu_dma_membase, |
606 | CEU_BUFFER_MEMORY_SIZE); |
607 | |
608 | platform_device_add(pdev: &kfr2r09_ceu_device); |
609 | |
610 | return platform_add_devices(kfr2r09_devices, |
611 | ARRAY_SIZE(kfr2r09_devices)); |
612 | } |
613 | device_initcall(kfr2r09_devices_setup); |
614 | |
615 | /* Return the board specific boot mode pin configuration */ |
616 | static int kfr2r09_mode_pins(void) |
617 | { |
618 | /* MD0=1, MD1=1, MD2=0: Clock Mode 3 |
619 | * MD3=0: 16-bit Area0 Bus Width |
620 | * MD5=1: Little Endian |
621 | * MD8=1: Test Mode Disabled |
622 | */ |
623 | return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8; |
624 | } |
625 | |
626 | /* Reserve a portion of memory for CEU buffers */ |
627 | static void __init kfr2r09_mv_mem_reserve(void) |
628 | { |
629 | phys_addr_t phys; |
630 | phys_addr_t size = CEU_BUFFER_MEMORY_SIZE; |
631 | |
632 | phys = memblock_phys_alloc(size, PAGE_SIZE); |
633 | if (!phys) |
634 | panic(fmt: "Failed to allocate CEU memory\n" ); |
635 | |
636 | memblock_phys_free(base: phys, size); |
637 | memblock_remove(base: phys, size); |
638 | |
639 | ceu_dma_membase = phys; |
640 | } |
641 | |
642 | /* |
643 | * The Machine Vector |
644 | */ |
645 | static struct sh_machine_vector mv_kfr2r09 __initmv = { |
646 | .mv_name = "kfr2r09" , |
647 | .mv_mode_pins = kfr2r09_mode_pins, |
648 | .mv_mem_reserve = kfr2r09_mv_mem_reserve, |
649 | }; |
650 | |