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/ezx-a780.c
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx-a780.c 2007-05-24 00:44:14.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/ezx-a780.c 2007-05-24 00:47:01.000000000 -0300
@@ -14,11 +14,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"
@@ -26,6 +29,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 a780_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 a780_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);
+
+ a780_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 a780_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 a780_mci_exit(struct device *dev, void *data)
+{
+ ezx_pcap_mmcsd_power(0);
+ free_irq(0x49, data);
+}
+
+static struct pxamci_platform_data a780_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 = a780_mci_init,
+ .setpower = a780_mci_setpower,
+ .exit = a780_mci_exit,
+};
+
static struct pxafb_mode_info mode_a780 = {
.pixclock = 150000,
.xres = 240,
@@ -66,6 +158,7 @@
PSLR = 0x05800f00;
set_pxa_fb_info(&a780_fb_info);
+ pxa_set_mci_info(&a780_mci_platform_data);
/* clear EMU MUX1/MUX2 (low) to close the audio path to EMU */
pxa_gpio_mode(GPIO_EMU_MUX1|GPIO_OUT);
Index: linux-2.6.21/arch/arm/mach-pxa/Kconfig
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/Kconfig 2007-05-24 00:47:13.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/Kconfig 2007-05-24 00:48:11.000000000 -0300
@@ -87,6 +87,7 @@
config PXA_EZX_A780
bool "Motorola A780 GSM Phone"
select PXA27x
+ select EZX_MCI_TF
config PXA_EZX_E2
bool "Motorola E2 GSM Phone"
|