Merge branch 'next' into for-linus
[linux-2.6] / arch / arm / mach-mx2 / pcm970-baseboard.c
1 /*
2  * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16  * MA 02110-1301, USA.
17  */
18
19 #include <linux/platform_device.h>
20 #include <linux/gpio.h>
21 #include <linux/irq.h>
22
23 #include <asm/mach/arch.h>
24
25 #include <mach/hardware.h>
26 #include <mach/common.h>
27 #include <mach/mmc.h>
28 #include <mach/imxfb.h>
29 #include <mach/iomux.h>
30
31 #include "devices.h"
32
33 static int pcm970_sdhc2_get_ro(struct device *dev)
34 {
35         return gpio_get_value(GPIO_PORTC + 28);
36 }
37
38 static int pcm970_sdhc2_pins[] = {
39         PB4_PF_SD2_D0,
40         PB5_PF_SD2_D1,
41         PB6_PF_SD2_D2,
42         PB7_PF_SD2_D3,
43         PB8_PF_SD2_CMD,
44         PB9_PF_SD2_CLK,
45 };
46
47 static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
48 {
49         int ret;
50
51         ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
52                 ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
53         if(ret)
54                 return ret;
55
56         ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
57                                 "imx-mmc-detect", data);
58         if (ret)
59                 goto out_release_gpio;
60
61         set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
62
63         ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
64         if (ret)
65                 goto out_release_gpio;
66
67         mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
68         gpio_direction_input(GPIO_PORTC + 28);
69
70         return 0;
71
72 out_release_gpio:
73         mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
74                         ARRAY_SIZE(pcm970_sdhc2_pins));
75         return ret;
76 }
77
78 static void pcm970_sdhc2_exit(struct device *dev, void *data)
79 {
80         free_irq(IRQ_GPIOC(29), data);
81         gpio_free(GPIO_PORTC + 28);
82         mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
83                         ARRAY_SIZE(pcm970_sdhc2_pins));
84 }
85
86 static struct imxmmc_platform_data sdhc_pdata = {
87         .get_ro = pcm970_sdhc2_get_ro,
88         .init = pcm970_sdhc2_init,
89         .exit = pcm970_sdhc2_exit,
90 };
91
92 static int mxc_fb_pins[] = {
93         PA5_PF_LSCLK,   PA6_PF_LD0,     PA7_PF_LD1,     PA8_PF_LD2,
94         PA9_PF_LD3,     PA10_PF_LD4,    PA11_PF_LD5,    PA12_PF_LD6,
95         PA13_PF_LD7,    PA14_PF_LD8,    PA15_PF_LD9,    PA16_PF_LD10,
96         PA17_PF_LD11,   PA18_PF_LD12,   PA19_PF_LD13,   PA20_PF_LD14,
97         PA21_PF_LD15,   PA22_PF_LD16,   PA23_PF_LD17,   PA24_PF_REV,
98         PA25_PF_CLS,    PA26_PF_PS,     PA27_PF_SPL_SPR, PA28_PF_HSYNC,
99         PA29_PF_VSYNC,  PA30_PF_CONTRAST, PA31_PF_OE_ACD
100 };
101
102 static int pcm038_fb_init(struct platform_device *pdev)
103 {
104         return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
105                         ARRAY_SIZE(mxc_fb_pins), "FB");
106 }
107
108 static int pcm038_fb_exit(struct platform_device *pdev)
109 {
110         mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
111
112         return 0;
113 }
114
115 /*
116  * Connected is a portrait Sharp-QVGA display
117  * of type: LQ035Q7DH06
118  */
119 static struct imx_fb_platform_data pcm038_fb_data = {
120         .pixclock       = 188679, /* in ps (5.3MHz) */
121         .xres           = 240,
122         .yres           = 320,
123
124         .bpp            = 16,
125         .hsync_len      = 7,
126         .left_margin    = 5,
127         .right_margin   = 16,
128
129         .vsync_len      = 1,
130         .upper_margin   = 7,
131         .lower_margin   = 9,
132         .fixed_screen_cpu = 0,
133
134         /*
135          * - HSYNC active high
136          * - VSYNC active high
137          * - clk notenabled while idle
138          * - clock not inverted
139          * - data not inverted
140          * - data enable low active
141          * - enable sharp mode
142          */
143         .pcr            = 0xFA0080C0,
144         .pwmr           = 0x00A903FF,
145         .lscr1          = 0x00120300,
146         .dmacr          = 0x00020010,
147
148         .init = pcm038_fb_init,
149         .exit = pcm038_fb_exit,
150 };
151
152 /*
153  * system init for baseboard usage. Will be called by pcm038 init.
154  *
155  * Add platform devices present on this baseboard and init
156  * them from CPU side as far as required to use them later on
157  */
158 void __init pcm970_baseboard_init(void)
159 {
160         mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
161         mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
162 }