Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mach-pcm043.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Sascha Hauer, Pengutronix
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  */
14 
15 #include <linux/types.h>
16 #include <linux/init.h>
17 
18 #include <linux/platform_device.h>
19 #include <linux/mtd/physmap.h>
20 #include <linux/mtd/plat-ram.h>
21 #include <linux/memory.h>
22 #include <linux/gpio.h>
23 #include <linux/smc911x.h>
24 #include <linux/interrupt.h>
25 #include <linux/delay.h>
26 #include <linux/i2c.h>
27 #include <linux/i2c/at24.h>
28 #include <linux/usb/otg.h>
29 #include <linux/usb/ulpi.h>
30 
31 #include <asm/mach-types.h>
32 #include <asm/mach/arch.h>
33 #include <asm/mach/time.h>
34 #include <asm/mach/map.h>
35 
36 #include <mach/hardware.h>
37 #include <mach/common.h>
38 #include <mach/iomux-mx35.h>
39 #include <mach/ulpi.h>
40 
41 #include "devices-imx35.h"
42 
43 static const struct fb_videomode fb_modedb[] = {
44  {
45  /* 240x320 @ 60 Hz */
46  .name = "Sharp-LQ035Q7",
47  .refresh = 60,
48  .xres = 240,
49  .yres = 320,
50  .pixclock = 185925,
51  .left_margin = 9,
52  .right_margin = 16,
53  .upper_margin = 7,
54  .lower_margin = 9,
55  .hsync_len = 1,
56  .vsync_len = 1,
58  .vmode = FB_VMODE_NONINTERLACED,
59  .flag = 0,
60  }, {
61  /* 240x320 @ 60 Hz */
62  .name = "TX090",
63  .refresh = 60,
64  .xres = 240,
65  .yres = 320,
66  .pixclock = 38255,
67  .left_margin = 144,
68  .right_margin = 0,
69  .upper_margin = 7,
70  .lower_margin = 40,
71  .hsync_len = 96,
72  .vsync_len = 1,
74  .vmode = FB_VMODE_NONINTERLACED,
75  .flag = 0,
76  },
77 };
78 
79 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
80  .name = "Sharp-LQ035Q7",
81  .mode = fb_modedb,
82  .num_modes = ARRAY_SIZE(fb_modedb),
83 };
84 
85 static struct physmap_flash_data pcm043_flash_data = {
86  .width = 2,
87 };
88 
89 static struct resource pcm043_flash_resource = {
90  .start = 0xa0000000,
91  .end = 0xa1ffffff,
92  .flags = IORESOURCE_MEM,
93 };
94 
95 static struct platform_device pcm043_flash = {
96  .name = "physmap-flash",
97  .id = 0,
98  .dev = {
99  .platform_data = &pcm043_flash_data,
100  },
101  .resource = &pcm043_flash_resource,
102  .num_resources = 1,
103 };
104 
105 static const struct imxuart_platform_data uart_pdata __initconst = {
106  .flags = IMXUART_HAVE_RTSCTS,
107 };
108 
109 static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
110  .bitrate = 50000,
111 };
112 
113 static struct at24_platform_data board_eeprom = {
114  .byte_len = 4096,
115  .page_size = 32,
116  .flags = AT24_FLAG_ADDR16,
117 };
118 
119 static struct i2c_board_info pcm043_i2c_devices[] = {
120  {
121  I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
122  .platform_data = &board_eeprom,
123  }, {
124  I2C_BOARD_INFO("pcf8563", 0x51),
125  },
126 };
127 
128 static struct platform_device *devices[] __initdata = {
129  &pcm043_flash,
130 };
131 
132 static iomux_v3_cfg_t pcm043_pads[] = {
133  /* UART1 */
138  /* UART2 */
143  /* FEC */
162  /* I2C1 */
165  /* Display */
191  /* gpio */
193  /* USB host */
196  /* SSI */
201  /* CAN2 */
204  /* esdhc */
211  MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
212  MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
213 };
214 
215 #define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31)
216 #define AC97_GPIO_TXD IMX_GPIO_NR(2, 28)
217 #define AC97_GPIO_RESET IMX_GPIO_NR(2, 0)
218 #define SD1_GPIO_WP IMX_GPIO_NR(2, 23)
219 #define SD1_GPIO_CD IMX_GPIO_NR(2, 24)
220 
221 static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
222 {
225  int ret;
226 
227  ret = gpio_request(AC97_GPIO_TXFS, "SSI");
228  if (ret) {
229  printk("failed to get GPIO_TXFS: %d\n", ret);
230  return;
231  }
232 
233  mxc_iomux_v3_setup_pad(txfs_gpio);
234 
235  /* warm reset */
237  udelay(2);
239 
242 }
243 
244 static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
245 {
251  int ret;
252 
253  ret = gpio_request(AC97_GPIO_TXFS, "SSI");
254  if (ret)
255  goto err1;
256 
257  ret = gpio_request(AC97_GPIO_TXD, "SSI");
258  if (ret)
259  goto err2;
260 
261  ret = gpio_request(AC97_GPIO_RESET, "SSI");
262  if (ret)
263  goto err3;
264 
265  mxc_iomux_v3_setup_pad(txfs_gpio);
266  mxc_iomux_v3_setup_pad(txd_gpio);
267  mxc_iomux_v3_setup_pad(reset_gpio);
268 
271 
272  /* cold reset */
274  udelay(10);
276 
279 
281 err3:
283 err2:
285 err1:
286  if (ret)
287  printk("%s failed with %d\n", __func__, ret);
288  mdelay(1);
289 }
290 
291 static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
292  .ac97_reset = pcm043_ac97_cold_reset,
293  .ac97_warm_reset = pcm043_ac97_warm_reset,
294  .flags = IMX_SSI_USE_AC97,
295 };
296 
297 static const struct mxc_nand_platform_data
298 pcm037_nand_board_info __initconst = {
299  .width = 1,
300  .hw_ecc = 1,
301 };
302 
303 static int pcm043_otg_init(struct platform_device *pdev)
304 {
306 }
307 
308 static struct mxc_usbh_platform_data otg_pdata __initdata = {
309  .init = pcm043_otg_init,
310  .portsc = MXC_EHCI_MODE_UTMI,
311 };
312 
313 static int pcm043_usbh1_init(struct platform_device *pdev)
314 {
317 }
318 
319 static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
320  .init = pcm043_usbh1_init,
321  .portsc = MXC_EHCI_MODE_SERIAL,
322 };
323 
324 static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
325  .operating_mode = FSL_USB2_DR_DEVICE,
326  .phy_mode = FSL_USB2_PHY_UTMI,
327 };
328 
329 static bool otg_mode_host __initdata;
330 
331 static int __init pcm043_otg_mode(char *options)
332 {
333  if (!strcmp(options, "host"))
334  otg_mode_host = true;
335  else if (!strcmp(options, "device"))
336  otg_mode_host = false;
337  else
338  pr_info("otg_mode neither \"host\" nor \"device\". "
339  "Defaulting to device\n");
340  return 1;
341 }
342 __setup("otg_mode=", pcm043_otg_mode);
343 
344 static struct esdhc_platform_data sd1_pdata = {
345  .wp_gpio = SD1_GPIO_WP,
346  .cd_gpio = SD1_GPIO_CD,
347  .wp_type = ESDHC_WP_GPIO,
348  .cd_type = ESDHC_CD_GPIO,
349 };
350 
351 /*
352  * Board specific initialization.
353  */
354 static void __init pcm043_init(void)
355 {
356  imx35_soc_init();
357 
358  mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
359 
361  platform_add_devices(devices, ARRAY_SIZE(devices));
363 
364  imx35_add_imx_uart0(&uart_pdata);
365  imx35_add_mxc_nand(&pcm037_nand_board_info);
366  imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
367 
368  imx35_add_imx_uart1(&uart_pdata);
369 
370  i2c_register_board_info(0, pcm043_i2c_devices,
371  ARRAY_SIZE(pcm043_i2c_devices));
372 
373  imx35_add_imx_i2c0(&pcm043_i2c0_data);
374 
376  imx35_add_mx3_sdc_fb(&mx3fb_pdata);
377 
378  if (otg_mode_host) {
379  otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
381  if (otg_pdata.otg)
382  imx35_add_mxc_ehci_otg(&otg_pdata);
383  }
384  imx35_add_mxc_ehci_hs(&usbh1_pdata);
385 
386  if (!otg_mode_host)
387  imx35_add_fsl_usb2_udc(&otg_device_pdata);
388 
390  imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
391 }
392 
393 static void __init pcm043_timer_init(void)
394 {
396 }
397 
398 static struct sys_timer pcm043_timer = {
399  .init = pcm043_timer_init,
400 };
401 
402 MACHINE_START(PCM043, "Phytec Phycore pcm043")
403  /* Maintainer: Pengutronix */
404  .atag_offset = 0x100,
405  .map_io = mx35_map_io,
406  .init_early = imx35_init_early,
407  .init_irq = mx35_init_irq,
408  .handle_irq = imx35_handle_irq,
409  .timer = &pcm043_timer,
410  .init_machine = pcm043_init,
411  .restart = mxc_restart,