diff options
Diffstat (limited to 'arch/arm/plat-omap/i2c.c')
-rw-r--r-- | arch/arm/plat-omap/i2c.c | 104 |
1 files changed, 89 insertions, 15 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 467531edefd3..a303071d5e36 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c | |||
@@ -98,6 +98,8 @@ static const int omap34xx_pins[][2] = { | |||
98 | static const int omap34xx_pins[][2] = {}; | 98 | static const int omap34xx_pins[][2] = {}; |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) | ||
102 | |||
101 | static void __init omap_i2c_mux_pins(int bus) | 103 | static void __init omap_i2c_mux_pins(int bus) |
102 | { | 104 | { |
103 | int scl, sda; | 105 | int scl, sda; |
@@ -119,14 +121,9 @@ static void __init omap_i2c_mux_pins(int bus) | |||
119 | omap_cfg_reg(scl); | 121 | omap_cfg_reg(scl); |
120 | } | 122 | } |
121 | 123 | ||
122 | int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | 124 | static int __init omap_i2c_nr_ports(void) |
123 | struct i2c_board_info const *info, | ||
124 | unsigned len) | ||
125 | { | 125 | { |
126 | int ports, err; | 126 | int ports = 0; |
127 | struct platform_device *pdev; | ||
128 | struct resource *res; | ||
129 | resource_size_t base, irq; | ||
130 | 127 | ||
131 | if (cpu_class_is_omap1()) | 128 | if (cpu_class_is_omap1()) |
132 | ports = 1; | 129 | ports = 1; |
@@ -135,17 +132,16 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | |||
135 | else if (cpu_is_omap34xx()) | 132 | else if (cpu_is_omap34xx()) |
136 | ports = 3; | 133 | ports = 3; |
137 | 134 | ||
138 | BUG_ON(bus_id < 1 || bus_id > ports); | 135 | return ports; |
136 | } | ||
139 | 137 | ||
140 | if (info) { | 138 | static int __init omap_i2c_add_bus(int bus_id) |
141 | err = i2c_register_board_info(bus_id, info, len); | 139 | { |
142 | if (err) | 140 | struct platform_device *pdev; |
143 | return err; | 141 | struct resource *res; |
144 | } | 142 | resource_size_t base, irq; |
145 | 143 | ||
146 | pdev = &omap_i2c_devices[bus_id - 1]; | 144 | pdev = &omap_i2c_devices[bus_id - 1]; |
147 | *(u32 *)pdev->dev.platform_data = clkrate; | ||
148 | |||
149 | if (bus_id == 1) { | 145 | if (bus_id == 1) { |
150 | res = pdev->resource; | 146 | res = pdev->resource; |
151 | if (cpu_class_is_omap1()) { | 147 | if (cpu_class_is_omap1()) { |
@@ -163,3 +159,81 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | |||
163 | omap_i2c_mux_pins(bus_id - 1); | 159 | omap_i2c_mux_pins(bus_id - 1); |
164 | return platform_device_register(pdev); | 160 | return platform_device_register(pdev); |
165 | } | 161 | } |
162 | |||
163 | /** | ||
164 | * omap_i2c_bus_setup - Process command line options for the I2C bus speed | ||
165 | * @str: String of options | ||
166 | * | ||
167 | * This function allow to override the default I2C bus speed for given I2C | ||
168 | * bus with a command line option. | ||
169 | * | ||
170 | * Format: i2c_bus=bus_id,clkrate (in kHz) | ||
171 | * | ||
172 | * Returns 1 on success, 0 otherwise. | ||
173 | */ | ||
174 | static int __init omap_i2c_bus_setup(char *str) | ||
175 | { | ||
176 | int ports; | ||
177 | int ints[3]; | ||
178 | |||
179 | ports = omap_i2c_nr_ports(); | ||
180 | get_options(str, 3, ints); | ||
181 | if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports) | ||
182 | return 0; | ||
183 | i2c_rate[ints[1] - 1] = ints[2]; | ||
184 | i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP; | ||
185 | |||
186 | return 1; | ||
187 | } | ||
188 | __setup("i2c_bus=", omap_i2c_bus_setup); | ||
189 | |||
190 | /* | ||
191 | * Register busses defined in command line but that are not registered with | ||
192 | * omap_register_i2c_bus from board initialization code. | ||
193 | */ | ||
194 | static int __init omap_register_i2c_bus_cmdline(void) | ||
195 | { | ||
196 | int i, err = 0; | ||
197 | |||
198 | for (i = 0; i < ARRAY_SIZE(i2c_rate); i++) | ||
199 | if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) { | ||
200 | i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP; | ||
201 | err = omap_i2c_add_bus(i + 1); | ||
202 | if (err) | ||
203 | goto out; | ||
204 | } | ||
205 | |||
206 | out: | ||
207 | return err; | ||
208 | } | ||
209 | subsys_initcall(omap_register_i2c_bus_cmdline); | ||
210 | |||
211 | /** | ||
212 | * omap_register_i2c_bus - register I2C bus with device descriptors | ||
213 | * @bus_id: bus id counting from number 1 | ||
214 | * @clkrate: clock rate of the bus in kHz | ||
215 | * @info: pointer into I2C device descriptor table or NULL | ||
216 | * @len: number of descriptors in the table | ||
217 | * | ||
218 | * Returns 0 on success or an error code. | ||
219 | */ | ||
220 | int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | ||
221 | struct i2c_board_info const *info, | ||
222 | unsigned len) | ||
223 | { | ||
224 | int err; | ||
225 | |||
226 | BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports()); | ||
227 | |||
228 | if (info) { | ||
229 | err = i2c_register_board_info(bus_id, info, len); | ||
230 | if (err) | ||
231 | return err; | ||
232 | } | ||
233 | |||
234 | if (!i2c_rate[bus_id - 1]) | ||
235 | i2c_rate[bus_id - 1] = clkrate; | ||
236 | i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP; | ||
237 | |||
238 | return omap_i2c_add_bus(bus_id); | ||
239 | } | ||