Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Add regulator support for twl6040 VIO, V2V1 supplies

twl6040 has three power supply source:
VBAT needs to be connected to VBAT, VIO, and V2V1.
Add regulator support for the VIO, V2V1 supplies.
Initially handle the two supply together with bulk commands.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Peter Ujfalusi and committed by
Samuel Ortiz
5af7df6b 5a2f1b5f

+31 -4
+29 -4
drivers/mfd/twl6040-core.c
··· 27 27 #include <linux/types.h> 28 28 #include <linux/slab.h> 29 29 #include <linux/kernel.h> 30 + #include <linux/err.h> 30 31 #include <linux/platform_device.h> 31 32 #include <linux/gpio.h> 32 33 #include <linux/delay.h> ··· 36 35 #include <linux/err.h> 37 36 #include <linux/mfd/core.h> 38 37 #include <linux/mfd/twl6040.h> 38 + #include <linux/regulator/consumer.h> 39 39 40 40 #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) 41 + #define TWL6040_NUM_SUPPLIES (2) 41 42 42 43 int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) 43 44 { ··· 535 532 536 533 i2c_set_clientdata(client, twl6040); 537 534 535 + twl6040->supplies[0].supply = "vio"; 536 + twl6040->supplies[1].supply = "v2v1"; 537 + ret = regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, 538 + twl6040->supplies); 539 + if (ret != 0) { 540 + dev_err(&client->dev, "Failed to get supplies: %d\n", ret); 541 + goto regulator_get_err; 542 + } 543 + 544 + ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); 545 + if (ret != 0) { 546 + dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); 547 + goto power_err; 548 + } 549 + 538 550 twl6040->dev = &client->dev; 539 551 twl6040->irq = client->irq; 540 552 twl6040->irq_base = pdata->irq_base; ··· 570 552 ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW, 571 553 "audpwron"); 572 554 if (ret) 573 - goto gpio1_err; 555 + goto gpio_err; 574 556 } 575 557 576 558 /* codec interrupt */ 577 559 ret = twl6040_irq_init(twl6040); 578 560 if (ret) 579 - goto gpio2_err; 561 + goto irq_init_err; 580 562 581 563 ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY, 582 564 NULL, twl6040_naudint_handler, 0, ··· 636 618 free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); 637 619 irq_err: 638 620 twl6040_irq_exit(twl6040); 639 - gpio2_err: 621 + irq_init_err: 640 622 if (gpio_is_valid(twl6040->audpwron)) 641 623 gpio_free(twl6040->audpwron); 642 - gpio1_err: 624 + gpio_err: 625 + regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); 626 + power_err: 627 + regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies); 628 + regulator_get_err: 643 629 i2c_set_clientdata(client, NULL); 644 630 err: 645 631 return ret; ··· 664 642 665 643 mfd_remove_devices(&client->dev); 666 644 i2c_set_clientdata(client, NULL); 645 + 646 + regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); 647 + regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies); 667 648 668 649 return 0; 669 650 }
+2
include/linux/mfd/twl6040.h
··· 27 27 28 28 #include <linux/interrupt.h> 29 29 #include <linux/mfd/core.h> 30 + #include <linux/regulator/consumer.h> 30 31 31 32 #define TWL6040_REG_ASICID 0x01 32 33 #define TWL6040_REG_ASICREV 0x02 ··· 204 203 struct twl6040 { 205 204 struct device *dev; 206 205 struct regmap *regmap; 206 + struct regulator_bulk_data supplies[2]; /* supplies for vio, v2v1 */ 207 207 struct mutex mutex; 208 208 struct mutex io_mutex; 209 209 struct mutex irq_mutex;