aboutsummaryrefslogtreecommitdiffstats
path: root/packages/linux/linux-ezx-2.6.21/patches/a1200-mci.patch
blob: 0d2640a2e7080df3e7ccfdeb36ef73b637f4404c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig	2007-06-02 20:32:31.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/Kconfig	2007-06-02 20:44:29.000000000 -0300
@@ -97,6 +97,7 @@
 config PXA_EZX_A1200
 	bool "Motorola A1200 GSM Phone"
 	select PXA27x
+	select EZX_MCI_TF
 
 config PXA_EZX_E6
 	bool "Motorola E6 GSM Phone"
Index: linux-2.6.21/arch/arm/mach-pxa/ezx-a1200.c
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx-a1200.c	2007-06-02 20:32:26.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/ezx-a1200.c	2007-06-02 20:44:56.000000000 -0300
@@ -13,11 +13,14 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/fb.h>
+#include <linux/mmc/host.h>
+#include <linux/irq.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
 
 #include "generic.h"
 #include "ezx.h"
@@ -25,6 +28,95 @@
 extern void ezx_lcd_power(int, struct fb_var_screeninfo *);
 extern void ezx_backlight_power(int);
 
+#ifdef CONFIG_EZX_PCAP
+extern int ezx_pcap_mmcsd_power(int);
+extern void ezx_pcap_mmcsd_voltage(u_int32_t);
+#else
+#define ezx_pcap_mmcsd_voltage(x) {}
+#define ezx_pcap_mmcsd_power(x) {}
+#endif
+
+static struct pxamci_platform_data a1200_mci_platform_data;
+
+static u_int8_t mmc_voltage[] = {
+	[MMC_VDD_160] = 5,
+	[MMC_VDD_170] = 5,
+	[MMC_VDD_180] = 6,
+	[MMC_VDD_190] = 6,
+	[MMC_VDD_200] = 7,
+	[MMC_VDD_210] = 7,
+	[MMC_VDD_220] = 8,
+	[MMC_VDD_230] = 8,
+	[MMC_VDD_240] = 9,
+	[MMC_VDD_250] = 9,
+	[MMC_VDD_260] = 10,
+	[MMC_VDD_270] = 10,
+	[MMC_VDD_280] = 11,
+	[MMC_VDD_290] = 11,
+	[MMC_VDD_300] = 12,
+	[MMC_VDD_310] = 12,
+	[MMC_VDD_320] = 13,
+	[MMC_VDD_330] = 13,
+	[MMC_VDD_340] = 14,
+	[MMC_VDD_350] = 14,
+	[MMC_VDD_360] = 15,
+};
+
+static int a1200_mci_init(struct device *dev,
+                       irqreturn_t (*ezx_detect_int)(int, void *),
+                       void *data)
+{
+       int err;
+
+       /* Setup GPIO for PXA27x MMC/SD controller */
+       pxa_gpio_mode(GPIO32_MMCCLK_MD);
+       pxa_gpio_mode(GPIO112_MMCCMD_MD);
+       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+       ezx_pcap_mmcsd_power(1);
+
+       a1200_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+       err = request_irq(0x49, ezx_detect_int, SA_INTERRUPT,
+                       "MMC card detect", data);
+       if (err) {
+               printk(KERN_ERR "ezx_mci_detect: MMC/SD: can't request "
+                       "MMC card detect IRQ\n");
+               return -1;
+       }
+
+       set_irq_type(0x0b, IRQT_BOTHEDGE);
+
+       return 0;
+}
+
+static void a1200_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	if (vdd <= MMC_VDD_360)
+		ezx_pcap_mmcsd_voltage(mmc_voltage[vdd]);
+
+	ezx_pcap_mmcsd_power(1);
+}
+
+static void a1200_mci_exit(struct device *dev, void *data)
+{
+	ezx_pcap_mmcsd_power(0);
+	free_irq(0x49, data);
+}
+
+static struct pxamci_platform_data a1200_mci_platform_data = {
+	.ocr_mask       = MMC_VDD_160_165|MMC_VDD_18_19|MMC_VDD_20_21
+			  |MMC_VDD_22_23|MMC_VDD_24_25|MMC_VDD_26_27
+			  |MMC_VDD_28_29|MMC_VDD_30_31|MMC_VDD_32_33
+			  |MMC_VDD_34_35|MMC_VDD_35_36,
+	.init           = a1200_mci_init,
+	.setpower       = a1200_mci_setpower,
+	.exit           = a1200_mci_exit,
+};
+
 static struct pxafb_mode_info mode_a1200 = {
        .pixclock = 192308,
        .xres = 240,
@@ -54,6 +146,7 @@
 static void __init a1200_init(void)
 {
 	set_pxa_fb_info(&a1200_fb_info);
+	pxa_set_mci_info(&a1200_mci_platform_data);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }