diff options
Diffstat (limited to 'arch/arm/mach-omap1/board-ams-delta.c')
-rw-r--r-- | arch/arm/mach-omap1/board-ams-delta.c | 104 |
1 files changed, 98 insertions, 6 deletions
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index ce50fe137269..949997c35707 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c | |||
@@ -18,7 +18,11 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/leds.h> | 20 | #include <linux/leds.h> |
21 | #include <linux/mutex.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <linux/regulator/fixed.h> | ||
25 | #include <linux/regulator/machine.h> | ||
22 | #include <linux/serial_8250.h> | 26 | #include <linux/serial_8250.h> |
23 | #include <linux/export.h> | 27 | #include <linux/export.h> |
24 | 28 | ||
@@ -237,11 +241,6 @@ static const struct gpio latch_gpios[] __initconst = { | |||
237 | .label = "scard_cmdvcc", | 241 | .label = "scard_cmdvcc", |
238 | }, | 242 | }, |
239 | { | 243 | { |
240 | .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET, | ||
241 | .flags = GPIOF_OUT_INIT_LOW, | ||
242 | .label = "modem_nreset", | ||
243 | }, | ||
244 | { | ||
245 | .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC, | 244 | .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC, |
246 | .flags = GPIOF_OUT_INIT_LOW, | 245 | .flags = GPIOF_OUT_INIT_LOW, |
247 | .label = "modem_codec", | 246 | .label = "modem_codec", |
@@ -258,6 +257,71 @@ static const struct gpio latch_gpios[] __initconst = { | |||
258 | }, | 257 | }, |
259 | }; | 258 | }; |
260 | 259 | ||
260 | static struct regulator_consumer_supply modem_nreset_consumers[] = { | ||
261 | REGULATOR_SUPPLY("RESET#", "serial8250.1"), | ||
262 | REGULATOR_SUPPLY("POR", "cx20442-codec"), | ||
263 | }; | ||
264 | |||
265 | static struct regulator_init_data modem_nreset_data = { | ||
266 | .constraints = { | ||
267 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
268 | .boot_on = 1, | ||
269 | }, | ||
270 | .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers), | ||
271 | .consumer_supplies = modem_nreset_consumers, | ||
272 | }; | ||
273 | |||
274 | static struct fixed_voltage_config modem_nreset_config = { | ||
275 | .supply_name = "modem_nreset", | ||
276 | .microvolts = 3300000, | ||
277 | .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET, | ||
278 | .startup_delay = 25000, | ||
279 | .enable_high = 1, | ||
280 | .enabled_at_boot = 1, | ||
281 | .init_data = &modem_nreset_data, | ||
282 | }; | ||
283 | |||
284 | static struct platform_device modem_nreset_device = { | ||
285 | .name = "reg-fixed-voltage", | ||
286 | .id = -1, | ||
287 | .dev = { | ||
288 | .platform_data = &modem_nreset_config, | ||
289 | }, | ||
290 | }; | ||
291 | |||
292 | struct modem_private_data { | ||
293 | struct regulator *regulator; | ||
294 | struct { | ||
295 | struct mutex lock; | ||
296 | bool enabled; | ||
297 | } consumer; | ||
298 | }; | ||
299 | |||
300 | static int regulator_toggle(struct modem_private_data *priv, bool enable) | ||
301 | { | ||
302 | int err = 0; | ||
303 | |||
304 | mutex_lock(&priv->consumer.lock); | ||
305 | if (IS_ERR(priv->regulator)) { | ||
306 | err = PTR_ERR(priv->regulator); | ||
307 | } else if (enable) { | ||
308 | if (!priv->consumer.enabled) { | ||
309 | err = regulator_enable(priv->regulator); | ||
310 | priv->consumer.enabled = true; | ||
311 | } | ||
312 | } else { | ||
313 | if (priv->consumer.enabled) { | ||
314 | err = regulator_disable(priv->regulator); | ||
315 | priv->consumer.enabled = false; | ||
316 | } | ||
317 | } | ||
318 | mutex_unlock(&priv->consumer.lock); | ||
319 | |||
320 | return err; | ||
321 | } | ||
322 | |||
323 | static struct modem_private_data modem_priv; | ||
324 | |||
261 | void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) | 325 | void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) |
262 | { | 326 | { |
263 | int bit = 0; | 327 | int bit = 0; |
@@ -266,7 +330,10 @@ void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) | |||
266 | for (; bit < ngpio; bit++, bitpos = bitpos << 1) { | 330 | for (; bit < ngpio; bit++, bitpos = bitpos << 1) { |
267 | if (!(mask & bitpos)) | 331 | if (!(mask & bitpos)) |
268 | continue; | 332 | continue; |
269 | gpio_set_value(base + bit, (value & bitpos) != 0); | 333 | else if (base + bit == AMS_DELTA_GPIO_PIN_MODEM_NRESET) |
334 | regulator_toggle(&modem_priv, (value & bitpos) != 0); | ||
335 | else | ||
336 | gpio_set_value(base + bit, (value & bitpos) != 0); | ||
270 | } | 337 | } |
271 | } | 338 | } |
272 | EXPORT_SYMBOL(ams_delta_latch_write); | 339 | EXPORT_SYMBOL(ams_delta_latch_write); |
@@ -496,6 +563,12 @@ static int __init late_init(void) | |||
496 | 563 | ||
497 | platform_add_devices(late_devices, ARRAY_SIZE(late_devices)); | 564 | platform_add_devices(late_devices, ARRAY_SIZE(late_devices)); |
498 | 565 | ||
566 | err = platform_device_register(&modem_nreset_device); | ||
567 | if (err) { | ||
568 | pr_err("Couldn't register the modem regulator device\n"); | ||
569 | return err; | ||
570 | } | ||
571 | |||
499 | omap_cfg_reg(M14_1510_GPIO2); | 572 | omap_cfg_reg(M14_1510_GPIO2); |
500 | ams_delta_modem_ports[0].irq = | 573 | ams_delta_modem_ports[0].irq = |
501 | gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); | 574 | gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); |
@@ -507,6 +580,10 @@ static int __init late_init(void) | |||
507 | } | 580 | } |
508 | gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); | 581 | gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); |
509 | 582 | ||
583 | /* Initialize the modem_nreset regulator consumer before use */ | ||
584 | mutex_init(&modem_priv.consumer.lock); | ||
585 | modem_priv.regulator = ERR_PTR(-ENODEV); | ||
586 | |||
510 | ams_delta_latch2_write( | 587 | ams_delta_latch2_write( |
511 | AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, | 588 | AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, |
512 | AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC); | 589 | AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC); |
@@ -514,8 +591,23 @@ static int __init late_init(void) | |||
514 | err = platform_device_register(&ams_delta_modem_device); | 591 | err = platform_device_register(&ams_delta_modem_device); |
515 | if (err) | 592 | if (err) |
516 | goto gpio_free; | 593 | goto gpio_free; |
594 | |||
595 | /* | ||
596 | * Once the modem device is registered, the modem_nreset | ||
597 | * regulator can be requested on behalf of that device. | ||
598 | * The regulator is used via ams_delta_latch_write() | ||
599 | * by the modem and ASoC drivers until updated. | ||
600 | */ | ||
601 | modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev, | ||
602 | "RESET#"); | ||
603 | if (IS_ERR(modem_priv.regulator)) { | ||
604 | err = PTR_ERR(modem_priv.regulator); | ||
605 | goto unregister; | ||
606 | } | ||
517 | return 0; | 607 | return 0; |
518 | 608 | ||
609 | unregister: | ||
610 | platform_device_unregister(&ams_delta_modem_device); | ||
519 | gpio_free: | 611 | gpio_free: |
520 | gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); | 612 | gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); |
521 | return err; | 613 | return err; |