aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/i2c.c')
-rw-r--r--arch/arm/plat-omap/i2c.c98
1 files changed, 72 insertions, 26 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index f044b5927508..eec2b4993c69 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -38,6 +38,7 @@
38#define OMAP2_I2C_BASE1 0x48070000 38#define OMAP2_I2C_BASE1 0x48070000
39#define OMAP2_I2C_BASE2 0x48072000 39#define OMAP2_I2C_BASE2 0x48072000
40#define OMAP2_I2C_BASE3 0x48060000 40#define OMAP2_I2C_BASE3 0x48060000
41#define OMAP4_I2C_BASE4 0x48350000
41 42
42static const char name[] = "i2c_omap"; 43static const char name[] = "i2c_omap";
43 44
@@ -54,11 +55,14 @@ static const char name[] = "i2c_omap";
54 55
55static struct resource i2c_resources[][2] = { 56static struct resource i2c_resources[][2] = {
56 { I2C_RESOURCE_BUILDER(0, 0) }, 57 { I2C_RESOURCE_BUILDER(0, 0) },
57#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 58#if defined(CONFIG_ARCH_OMAP2PLUS)
58 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) }, 59 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) },
59#endif 60#endif
60#if defined(CONFIG_ARCH_OMAP3) 61#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
61 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) }, 62 { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) },
63#endif
64#if defined(CONFIG_ARCH_OMAP4)
65 { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) },
62#endif 66#endif
63}; 67};
64 68
@@ -76,12 +80,15 @@ static struct resource i2c_resources[][2] = {
76static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)]; 80static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)];
77static struct platform_device omap_i2c_devices[] = { 81static struct platform_device omap_i2c_devices[] = {
78 I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), 82 I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
79#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 83#if defined(CONFIG_ARCH_OMAP2PLUS)
80 I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]), 84 I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
81#endif 85#endif
82#if defined(CONFIG_ARCH_OMAP3) 86#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
83 I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]), 87 I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
84#endif 88#endif
89#if defined(CONFIG_ARCH_OMAP4)
90 I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]),
91#endif
85}; 92};
86 93
87#define OMAP_I2C_CMDLINE_SETUP (BIT(31)) 94#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
@@ -96,37 +103,60 @@ static int __init omap_i2c_nr_ports(void)
96 ports = 2; 103 ports = 2;
97 else if (cpu_is_omap34xx()) 104 else if (cpu_is_omap34xx())
98 ports = 3; 105 ports = 3;
106 else if (cpu_is_omap44xx())
107 ports = 4;
99 108
100 return ports; 109 return ports;
101} 110}
102 111
103static int __init omap_i2c_add_bus(int bus_id) 112/* Shared between omap2 and 3 */
113static resource_size_t omap2_i2c_irq[3] __initdata = {
114 INT_24XX_I2C1_IRQ,
115 INT_24XX_I2C2_IRQ,
116 INT_34XX_I2C3_IRQ,
117};
118
119static resource_size_t omap4_i2c_irq[4] __initdata = {
120 OMAP44XX_IRQ_I2C1,
121 OMAP44XX_IRQ_I2C2,
122 OMAP44XX_IRQ_I2C3,
123 OMAP44XX_IRQ_I2C4,
124};
125
126static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
104{ 127{
105 struct platform_device *pdev;
106 struct omap_i2c_bus_platform_data *pd; 128 struct omap_i2c_bus_platform_data *pd;
107 struct resource *res; 129 struct resource *res;
108 resource_size_t base, irq;
109 130
110 pdev = &omap_i2c_devices[bus_id - 1];
111 pd = pdev->dev.platform_data; 131 pd = pdev->dev.platform_data;
132 res = pdev->resource;
133 res[0].start = OMAP1_I2C_BASE;
134 res[0].end = res[0].start + OMAP_I2C_SIZE;
135 res[1].start = INT_I2C;
136 omap1_i2c_mux_pins(bus_id);
137
138 return platform_device_register(pdev);
139}
140
141static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
142{
143 struct resource *res;
144 resource_size_t *irq;
145
146 res = pdev->resource;
147
148 if (!cpu_is_omap44xx())
149 irq = omap2_i2c_irq;
150 else
151 irq = omap4_i2c_irq;
152
112 if (bus_id == 1) { 153 if (bus_id == 1) {
113 res = pdev->resource; 154 res[0].start = OMAP2_I2C_BASE1;
114 if (cpu_class_is_omap1()) { 155 res[0].end = res[0].start + OMAP_I2C_SIZE;
115 base = OMAP1_I2C_BASE;
116 irq = INT_I2C;
117 } else {
118 base = OMAP2_I2C_BASE1;
119 irq = INT_24XX_I2C1_IRQ;
120 }
121 res[0].start = base;
122 res[0].end = base + OMAP_I2C_SIZE;
123 res[1].start = irq;
124 } 156 }
125 157
126 if (cpu_class_is_omap1()) 158 res[1].start = irq[bus_id - 1];
127 omap1_i2c_mux_pins(bus_id); 159 omap2_i2c_mux_pins(bus_id);
128 if (cpu_class_is_omap2())
129 omap2_i2c_mux_pins(bus_id);
130 160
131 /* 161 /*
132 * When waiting for completion of a i2c transfer, we need to 162 * When waiting for completion of a i2c transfer, we need to
@@ -134,12 +164,28 @@ static int __init omap_i2c_add_bus(int bus_id)
134 * ensure quick enough wakeup from idle, when transfer 164 * ensure quick enough wakeup from idle, when transfer
135 * completes. 165 * completes.
136 */ 166 */
137 if (cpu_is_omap34xx()) 167 if (cpu_is_omap34xx()) {
168 struct omap_i2c_bus_platform_data *pd;
169
170 pd = pdev->dev.platform_data;
138 pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat; 171 pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat;
172 }
139 173
140 return platform_device_register(pdev); 174 return platform_device_register(pdev);
141} 175}
142 176
177static int __init omap_i2c_add_bus(int bus_id)
178{
179 struct platform_device *pdev;
180
181 pdev = &omap_i2c_devices[bus_id - 1];
182
183 if (cpu_class_is_omap1())
184 return omap1_i2c_add_bus(pdev, bus_id);
185 else
186 return omap2_i2c_add_bus(pdev, bus_id);
187}
188
143/** 189/**
144 * omap_i2c_bus_setup - Process command line options for the I2C bus speed 190 * omap_i2c_bus_setup - Process command line options for the I2C bus speed
145 * @str: String of options 191 * @str: String of options