aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1/board-ams-delta.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap1/board-ams-delta.c')
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c104
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
260static struct regulator_consumer_supply modem_nreset_consumers[] = {
261 REGULATOR_SUPPLY("RESET#", "serial8250.1"),
262 REGULATOR_SUPPLY("POR", "cx20442-codec"),
263};
264
265static 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
274static 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
284static 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
292struct modem_private_data {
293 struct regulator *regulator;
294 struct {
295 struct mutex lock;
296 bool enabled;
297 } consumer;
298};
299
300static 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
323static struct modem_private_data modem_priv;
324
261void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) 325void 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}
272EXPORT_SYMBOL(ams_delta_latch_write); 339EXPORT_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
609unregister:
610 platform_device_unregister(&ams_delta_modem_device);
519gpio_free: 611gpio_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;