Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1/*
  2 * arch/arm/mach-shmobile/board-ag5evm.c
  3 *
  4 * Copyright (C) 2010  Takashi Yoshii <yoshii.takashi.zj@renesas.com>
  5 * Copyright (C) 2009  Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
  6 *
  7 * This program is free software; you can redistribute it and/or modify
  8 * it under the terms of the GNU General Public License as published by
  9 * the Free Software Foundation; version 2 of the License.
 10 *
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU General Public License
 17 * along with this program; if not, write to the Free Software
 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 19 *
 20 */
 21
 22#include <linux/kernel.h>
 23#include <linux/init.h>
 24#include <linux/interrupt.h>
 25#include <linux/irq.h>
 26#include <linux/platform_device.h>
 27#include <linux/delay.h>
 28#include <linux/io.h>
 29#include <linux/dma-mapping.h>
 30#include <linux/serial_sci.h>
 31#include <linux/smsc911x.h>
 32#include <linux/gpio.h>
 33#include <linux/videodev2.h>
 34#include <linux/input.h>
 35#include <linux/input/sh_keysc.h>
 36#include <linux/mmc/host.h>
 37#include <linux/mmc/sh_mmcif.h>
 38#include <linux/mmc/sh_mobile_sdhi.h>
 39#include <linux/mfd/tmio.h>
 40#include <linux/sh_clk.h>
 41#include <linux/videodev2.h>
 42#include <video/sh_mobile_lcdc.h>
 43#include <video/sh_mipi_dsi.h>
 44#include <sound/sh_fsi.h>
 45#include <mach/hardware.h>
 46#include <mach/irqs.h>
 47#include <mach/sh73a0.h>
 48#include <mach/common.h>
 49#include <asm/mach-types.h>
 50#include <asm/mach/arch.h>
 51#include <asm/hardware/gic.h>
 52#include <asm/hardware/cache-l2x0.h>
 53#include <asm/traps.h>
 54
 55static struct resource smsc9220_resources[] = {
 56	[0] = {
 57		.start		= 0x14000000,
 58		.end		= 0x14000000 + SZ_64K - 1,
 59		.flags		= IORESOURCE_MEM,
 60	},
 61	[1] = {
 62		.start		= SH73A0_PINT0_IRQ(2), /* PINTA2 */
 63		.flags		= IORESOURCE_IRQ,
 64	},
 65};
 66
 67static struct smsc911x_platform_config smsc9220_platdata = {
 68	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 69	.phy_interface	= PHY_INTERFACE_MODE_MII,
 70	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 71	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
 72};
 73
 74static struct platform_device eth_device = {
 75	.name		= "smsc911x",
 76	.id		= 0,
 77	.dev  = {
 78		.platform_data = &smsc9220_platdata,
 79	},
 80	.resource	= smsc9220_resources,
 81	.num_resources	= ARRAY_SIZE(smsc9220_resources),
 82};
 83
 84static struct sh_keysc_info keysc_platdata = {
 85	.mode		= SH_KEYSC_MODE_6,
 86	.scan_timing	= 3,
 87	.delay		= 100,
 88	.keycodes	= {
 89		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
 90		KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
 91		KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
 92		KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
 93		KEY_SPACE, KEY_9, KEY_6, KEY_3, KEY_WAKEUP, KEY_RIGHT, \
 94		KEY_COFFEE,
 95		KEY_0, KEY_8, KEY_5, KEY_2, KEY_DOWN, KEY_ENTER, KEY_UP,
 96		KEY_KPASTERISK, KEY_7, KEY_4, KEY_1, KEY_STOP, KEY_LEFT, \
 97		KEY_COMPUTER,
 98	},
 99};
100
101static struct resource keysc_resources[] = {
102	[0] = {
103		.name	= "KEYSC",
104		.start	= 0xe61b0000,
105		.end	= 0xe61b0098 - 1,
106		.flags	= IORESOURCE_MEM,
107	},
108	[1] = {
109		.start	= gic_spi(71),
110		.flags	= IORESOURCE_IRQ,
111	},
112};
113
114static struct platform_device keysc_device = {
115	.name		= "sh_keysc",
116	.id		= 0,
117	.num_resources	= ARRAY_SIZE(keysc_resources),
118	.resource	= keysc_resources,
119	.dev		= {
120		.platform_data	= &keysc_platdata,
121	},
122};
123
124/* FSI A */
125static struct resource fsi_resources[] = {
126	[0] = {
127		.name	= "FSI",
128		.start	= 0xEC230000,
129		.end	= 0xEC230400 - 1,
130		.flags	= IORESOURCE_MEM,
131	},
132	[1] = {
133		.start  = gic_spi(146),
134		.flags  = IORESOURCE_IRQ,
135	},
136};
137
138static struct platform_device fsi_device = {
139	.name		= "sh_fsi2",
140	.id		= -1,
141	.num_resources	= ARRAY_SIZE(fsi_resources),
142	.resource	= fsi_resources,
143};
144
145static struct resource sh_mmcif_resources[] = {
146	[0] = {
147		.name	= "MMCIF",
148		.start	= 0xe6bd0000,
149		.end	= 0xe6bd00ff,
150		.flags	= IORESOURCE_MEM,
151	},
152	[1] = {
153		.start	= gic_spi(141),
154		.flags	= IORESOURCE_IRQ,
155	},
156	[2] = {
157		.start	= gic_spi(140),
158		.flags	= IORESOURCE_IRQ,
159	},
160};
161
162static struct sh_mmcif_plat_data sh_mmcif_platdata = {
163	.sup_pclk	= 0,
164	.ocr		= MMC_VDD_165_195,
165	.caps		= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
166	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
167	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
168};
169
170static struct platform_device mmc_device = {
171	.name		= "sh_mmcif",
172	.id		= 0,
173	.dev		= {
174		.dma_mask		= NULL,
175		.coherent_dma_mask	= 0xffffffff,
176		.platform_data		= &sh_mmcif_platdata,
177	},
178	.num_resources	= ARRAY_SIZE(sh_mmcif_resources),
179	.resource	= sh_mmcif_resources,
180};
181
182/* IrDA */
183static struct resource irda_resources[] = {
184	[0] = {
185		.start	= 0xE6D00000,
186		.end	= 0xE6D01FD4 - 1,
187		.flags  = IORESOURCE_MEM,
188	},
189	[1] = {
190		.start	= gic_spi(95),
191		.flags  = IORESOURCE_IRQ,
192	},
193};
194
195static struct platform_device irda_device = {
196	.name           = "sh_irda",
197	.id		= 0,
198	.resource       = irda_resources,
199	.num_resources  = ARRAY_SIZE(irda_resources),
200};
201
202static unsigned char lcd_backlight_seq[3][2] = {
203	{ 0x04, 0x07 },
204	{ 0x23, 0x80 },
205	{ 0x03, 0x01 },
206};
207
208static void lcd_backlight_on(void)
209{
210	struct i2c_adapter *a;
211	struct i2c_msg msg;
212	int k;
213
214	a = i2c_get_adapter(1);
215	for (k = 0; a && k < 3; k++) {
216		msg.addr = 0x6d;
217		msg.buf = &lcd_backlight_seq[k][0];
218		msg.len = 2;
219		msg.flags = 0;
220		if (i2c_transfer(a, &msg, 1) != 1)
221			break;
222	}
223}
224
225static void lcd_backlight_reset(void)
226{
227	gpio_set_value(GPIO_PORT235, 0);
228	mdelay(24);
229	gpio_set_value(GPIO_PORT235, 1);
230}
231
232/* LCDC0 */
233static const struct fb_videomode lcdc0_modes[] = {
234	{
235		.name		= "R63302(QHD)",
236		.xres		= 544,
237		.yres		= 961,
238		.left_margin	= 72,
239		.right_margin	= 600,
240		.hsync_len	= 16,
241		.upper_margin	= 8,
242		.lower_margin	= 8,
243		.vsync_len	= 2,
244		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
245	},
246};
247
248static struct sh_mobile_lcdc_info lcdc0_info = {
249	.clock_source = LCDC_CLK_PERIPHERAL,
250	.ch[0] = {
251		.chan = LCDC_CHAN_MAINLCD,
252		.interface_type = RGB24,
253		.clock_divider = 1,
254		.flags = LCDC_FLAGS_DWPOL,
255		.fourcc = V4L2_PIX_FMT_RGB565,
256		.lcd_modes = lcdc0_modes,
257		.num_modes = ARRAY_SIZE(lcdc0_modes),
258		.panel_cfg = {
259			.width = 44,
260			.height = 79,
261			.display_on = lcd_backlight_on,
262			.display_off = lcd_backlight_reset,
263		},
264	}
265};
266
267static struct resource lcdc0_resources[] = {
268	[0] = {
269		.name	= "LCDC0",
270		.start	= 0xfe940000, /* P4-only space */
271		.end	= 0xfe943fff,
272		.flags	= IORESOURCE_MEM,
273	},
274	[1] = {
275		.start	= intcs_evt2irq(0x580),
276		.flags	= IORESOURCE_IRQ,
277	},
278};
279
280static struct platform_device lcdc0_device = {
281	.name		= "sh_mobile_lcdc_fb",
282	.num_resources	= ARRAY_SIZE(lcdc0_resources),
283	.resource	= lcdc0_resources,
284	.id             = 0,
285	.dev	= {
286		.platform_data	= &lcdc0_info,
287		.coherent_dma_mask = ~0,
288	},
289};
290
291/* MIPI-DSI */
292static struct resource mipidsi0_resources[] = {
293	[0] = {
294		.name	= "DSI0",
295		.start  = 0xfeab0000,
296		.end    = 0xfeab3fff,
297		.flags  = IORESOURCE_MEM,
298	},
299	[1] = {
300		.name	= "DSI0",
301		.start  = 0xfeab4000,
302		.end    = 0xfeab7fff,
303		.flags  = IORESOURCE_MEM,
304	},
305};
306
307static int sh_mipi_set_dot_clock(struct platform_device *pdev,
308				 void __iomem *base,
309				 int enable)
310{
311	struct clk *pck, *phy;
312	int ret;
313
314	pck = clk_get(&pdev->dev, "dsip_clk");
315	if (IS_ERR(pck)) {
316		ret = PTR_ERR(pck);
317		goto sh_mipi_set_dot_clock_pck_err;
318	}
319
320	phy = clk_get(&pdev->dev, "dsiphy_clk");
321	if (IS_ERR(phy)) {
322		ret = PTR_ERR(phy);
323		goto sh_mipi_set_dot_clock_phy_err;
324	}
325
326	if (enable) {
327		clk_set_rate(pck, clk_round_rate(pck,  24000000));
328		clk_set_rate(phy, clk_round_rate(pck, 510000000));
329		clk_enable(pck);
330		clk_enable(phy);
331	} else {
332		clk_disable(pck);
333		clk_disable(phy);
334	}
335
336	ret = 0;
337
338	clk_put(phy);
339sh_mipi_set_dot_clock_phy_err:
340	clk_put(pck);
341sh_mipi_set_dot_clock_pck_err:
342	return ret;
343}
344
345static struct sh_mipi_dsi_info mipidsi0_info = {
346	.data_format	= MIPI_RGB888,
347	.lcd_chan	= &lcdc0_info.ch[0],
348	.lane		= 2,
349	.vsynw_offset	= 20,
350	.clksrc		= 1,
351	.flags		= SH_MIPI_DSI_HSABM		|
352			  SH_MIPI_DSI_SYNC_PULSES_MODE	|
353			  SH_MIPI_DSI_HSbyteCLK,
354	.set_dot_clock	= sh_mipi_set_dot_clock,
355};
356
357static struct platform_device mipidsi0_device = {
358	.name           = "sh-mipi-dsi",
359	.num_resources  = ARRAY_SIZE(mipidsi0_resources),
360	.resource       = mipidsi0_resources,
361	.id             = 0,
362	.dev	= {
363		.platform_data	= &mipidsi0_info,
364	},
365};
366
367/* SDHI0 */
368static struct sh_mobile_sdhi_info sdhi0_info = {
369	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
370	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
371	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
372	.tmio_caps	= MMC_CAP_SD_HIGHSPEED,
373	.tmio_ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
374	.cd_gpio	= GPIO_PORT251,
375};
376
377static struct resource sdhi0_resources[] = {
378	[0] = {
379		.name	= "SDHI0",
380		.start	= 0xee100000,
381		.end	= 0xee1000ff,
382		.flags	= IORESOURCE_MEM,
383	},
384	[1] = {
385		.name	= SH_MOBILE_SDHI_IRQ_CARD_DETECT,
386		.start	= gic_spi(83),
387		.flags	= IORESOURCE_IRQ,
388	},
389	[2] = {
390		.name	= SH_MOBILE_SDHI_IRQ_SDCARD,
391		.start	= gic_spi(84),
392		.flags	= IORESOURCE_IRQ,
393	},
394	[3] = {
395		.name	= SH_MOBILE_SDHI_IRQ_SDIO,
396		.start	= gic_spi(85),
397		.flags	= IORESOURCE_IRQ,
398	},
399};
400
401static struct platform_device sdhi0_device = {
402	.name		= "sh_mobile_sdhi",
403	.id		= 0,
404	.num_resources	= ARRAY_SIZE(sdhi0_resources),
405	.resource	= sdhi0_resources,
406	.dev	= {
407		.platform_data	= &sdhi0_info,
408	},
409};
410
411void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
412{
413	gpio_set_value(GPIO_PORT114, state);
414}
415
416static struct sh_mobile_sdhi_info sh_sdhi1_info = {
417	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
418	.tmio_caps	= MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
419	.tmio_ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
420	.set_pwr	= ag5evm_sdhi1_set_pwr,
421};
422
423static struct resource sdhi1_resources[] = {
424	[0] = {
425		.name	= "SDHI1",
426		.start	= 0xee120000,
427		.end	= 0xee1200ff,
428		.flags	= IORESOURCE_MEM,
429	},
430	[1] = {
431		.name	= SH_MOBILE_SDHI_IRQ_CARD_DETECT,
432		.start	= gic_spi(87),
433		.flags	= IORESOURCE_IRQ,
434	},
435	[2] = {
436		.name	= SH_MOBILE_SDHI_IRQ_SDCARD,
437		.start	= gic_spi(88),
438		.flags	= IORESOURCE_IRQ,
439	},
440	[3] = {
441		.name	= SH_MOBILE_SDHI_IRQ_SDIO,
442		.start	= gic_spi(89),
443		.flags	= IORESOURCE_IRQ,
444	},
445};
446
447static struct platform_device sdhi1_device = {
448	.name		= "sh_mobile_sdhi",
449	.id		= 1,
450	.dev		= {
451		.platform_data	= &sh_sdhi1_info,
452	},
453	.num_resources	= ARRAY_SIZE(sdhi1_resources),
454	.resource	= sdhi1_resources,
455};
456
457static struct platform_device *ag5evm_devices[] __initdata = {
458	&eth_device,
459	&keysc_device,
460	&fsi_device,
461	&mmc_device,
462	&irda_device,
463	&lcdc0_device,
464	&mipidsi0_device,
465	&sdhi0_device,
466	&sdhi1_device,
467};
468
469static void __init ag5evm_init(void)
470{
471	sh73a0_pinmux_init();
472
473	/* enable SCIFA2 */
474	gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
475	gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
476	gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
477	gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
478
479	/* enable KEYSC */
480	gpio_request(GPIO_FN_KEYIN0_PU, NULL);
481	gpio_request(GPIO_FN_KEYIN1_PU, NULL);
482	gpio_request(GPIO_FN_KEYIN2_PU, NULL);
483	gpio_request(GPIO_FN_KEYIN3_PU, NULL);
484	gpio_request(GPIO_FN_KEYIN4_PU, NULL);
485	gpio_request(GPIO_FN_KEYIN5_PU, NULL);
486	gpio_request(GPIO_FN_KEYIN6_PU, NULL);
487	gpio_request(GPIO_FN_KEYIN7_PU, NULL);
488	gpio_request(GPIO_FN_KEYOUT0, NULL);
489	gpio_request(GPIO_FN_KEYOUT1, NULL);
490	gpio_request(GPIO_FN_KEYOUT2, NULL);
491	gpio_request(GPIO_FN_KEYOUT3, NULL);
492	gpio_request(GPIO_FN_KEYOUT4, NULL);
493	gpio_request(GPIO_FN_KEYOUT5, NULL);
494	gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
495	gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
496	gpio_request(GPIO_FN_KEYOUT8, NULL);
497	gpio_request(GPIO_FN_PORT149_KEYOUT9, NULL);
498
499	/* enable I2C channel 2 and 3 */
500	gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL);
501	gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL);
502	gpio_request(GPIO_FN_PORT248_I2C_SCL3, NULL);
503	gpio_request(GPIO_FN_PORT249_I2C_SDA3, NULL);
504
505	/* enable MMCIF */
506	gpio_request(GPIO_FN_MMCCLK0, NULL);
507	gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
508	gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
509	gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
510	gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
511	gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
512	gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
513	gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
514	gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
515	gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
516	gpio_request(GPIO_PORT208, NULL); /* Reset */
517	gpio_direction_output(GPIO_PORT208, 1);
518
519	/* enable SMSC911X */
520	gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
521	gpio_direction_input(GPIO_PORT144);
522	gpio_request(GPIO_PORT145, NULL); /* RESET */
523	gpio_direction_output(GPIO_PORT145, 1);
524
525	/* FSI A */
526	gpio_request(GPIO_FN_FSIACK, NULL);
527	gpio_request(GPIO_FN_FSIAILR, NULL);
528	gpio_request(GPIO_FN_FSIAIBT, NULL);
529	gpio_request(GPIO_FN_FSIAISLD, NULL);
530	gpio_request(GPIO_FN_FSIAOSLD, NULL);
531
532	/* IrDA */
533	gpio_request(GPIO_FN_PORT241_IRDA_OUT, NULL);
534	gpio_request(GPIO_FN_PORT242_IRDA_IN,  NULL);
535	gpio_request(GPIO_FN_PORT243_IRDA_FIRSEL, NULL);
536
537	/* LCD panel */
538	gpio_request(GPIO_PORT217, NULL); /* RESET */
539	gpio_direction_output(GPIO_PORT217, 0);
540	mdelay(1);
541	gpio_set_value(GPIO_PORT217, 1);
542	mdelay(100);
543
544	/* LCD backlight controller */
545	gpio_request(GPIO_PORT235, NULL); /* RESET */
546	gpio_direction_output(GPIO_PORT235, 0);
547	lcd_backlight_reset();
548
549	/* enable SDHI0 on CN15 [SD I/F] */
550	gpio_request(GPIO_FN_SDHIWP0, NULL);
551	gpio_request(GPIO_FN_SDHICMD0, NULL);
552	gpio_request(GPIO_FN_SDHICLK0, NULL);
553	gpio_request(GPIO_FN_SDHID0_3, NULL);
554	gpio_request(GPIO_FN_SDHID0_2, NULL);
555	gpio_request(GPIO_FN_SDHID0_1, NULL);
556	gpio_request(GPIO_FN_SDHID0_0, NULL);
557
558	/* enable SDHI1 on CN4 [WLAN I/F] */
559	gpio_request(GPIO_FN_SDHICLK1, NULL);
560	gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
561	gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
562	gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
563	gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
564	gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
565	gpio_request(GPIO_PORT114, "sdhi1_power");
566	gpio_direction_output(GPIO_PORT114, 0);
567
568#ifdef CONFIG_CACHE_L2X0
569	/* Shared attribute override enable, 64K*8way */
570	l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff);
571#endif
572	sh73a0_add_standard_devices();
573	platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
574}
575
576MACHINE_START(AG5EVM, "ag5evm")
577	.map_io		= sh73a0_map_io,
578	.init_early	= sh73a0_add_early_devices,
579	.nr_irqs	= NR_IRQS_LEGACY,
580	.init_irq	= sh73a0_init_irq,
581	.handle_irq	= gic_handle_irq,
582	.init_machine	= ag5evm_init,
583	.init_late	= shmobile_init_late,
584	.timer		= &shmobile_timer,
585MACHINE_END