aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBengt Jonsson <bengt.g.jonsson@stericsson.com>2011-03-11 05:54:46 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2011-03-26 10:15:05 -0400
commit79568b941277b5986a8a7f0fb8578b2ccfc3e87e (patch)
treeb66551a8bd5c9fa75f01767578e76a19d030ee32
parentea05ef31f2aa98b25d14222300dc9c1d1eb59e41 (diff)
regulator: initialization for ab8500 regulators
The regulators on the AB8500 have a lot of custom hardware control settings pertaining to 8 external signals, settings which are board-specific and need be provided from the platform at startup. Initialization added for regulators Vana, VextSupply1, VextSupply2, VextSupply3, Vaux1, Vaux2, Vaux3, VTVout, Vintcore12, Vaudio, Vdmic, Vamic1, Vamic2, VrefDDR. Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com> Reviewed-by: Rickard Andersson <rickard.andersson@stericsson.com> Reviewed-by: Jonas Aberg <jonas.aberg@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.h2
-rw-r--r--arch/arm/mach-ux500/board-mop500.c1
-rw-r--r--drivers/regulator/ab8500.c223
-rw-r--r--include/linux/mfd/ab8500.h6
-rw-r--r--include/linux/regulator/ab8500.h50
5 files changed, 279 insertions, 3 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h
index 2675fae52537..f979b892e4fa 100644
--- a/arch/arm/mach-ux500/board-mop500-regulators.h
+++ b/arch/arm/mach-ux500/board-mop500-regulators.h
@@ -14,6 +14,8 @@
14#include <linux/regulator/machine.h> 14#include <linux/regulator/machine.h>
15#include <linux/regulator/ab8500.h> 15#include <linux/regulator/ab8500.h>
16 16
17extern struct ab8500_regulator_reg_init
18ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS];
17extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; 19extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS];
18 20
19#endif 21#endif
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 8790d984cac8..d0076453d7ff 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -20,6 +20,7 @@
20#include <linux/amba/serial.h> 20#include <linux/amba/serial.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/mfd/ab8500.h> 22#include <linux/mfd/ab8500.h>
23#include <linux/regulator/ab8500.h>
23#include <linux/mfd/tc3589x.h> 24#include <linux/mfd/tc3589x.h>
24#include <linux/leds-lp5521.h> 25#include <linux/leds-lp5521.h>
25#include <linux/input.h> 26#include <linux/input.h>
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 5a77630095d9..d157146c8655 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -526,6 +526,186 @@ static struct ab8500_regulator_info
526 526
527}; 527};
528 528
529struct ab8500_reg_init {
530 u8 bank;
531 u8 addr;
532 u8 mask;
533};
534
535#define REG_INIT(_id, _bank, _addr, _mask) \
536 [_id] = { \
537 .bank = _bank, \
538 .addr = _addr, \
539 .mask = _mask, \
540 }
541
542static struct ab8500_reg_init ab8500_reg_init[] = {
543 /*
544 * 0x30, VanaRequestCtrl
545 * 0x0C, VpllRequestCtrl
546 * 0xc0, VextSupply1RequestCtrl
547 */
548 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
549 /*
550 * 0x03, VextSupply2RequestCtrl
551 * 0x0c, VextSupply3RequestCtrl
552 * 0x30, Vaux1RequestCtrl
553 * 0xc0, Vaux2RequestCtrl
554 */
555 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
556 /*
557 * 0x03, Vaux3RequestCtrl
558 * 0x04, SwHPReq
559 */
560 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
561 /*
562 * 0x08, VanaSysClkReq1HPValid
563 * 0x20, Vaux1SysClkReq1HPValid
564 * 0x40, Vaux2SysClkReq1HPValid
565 * 0x80, Vaux3SysClkReq1HPValid
566 */
567 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
568 /*
569 * 0x10, VextSupply1SysClkReq1HPValid
570 * 0x20, VextSupply2SysClkReq1HPValid
571 * 0x40, VextSupply3SysClkReq1HPValid
572 */
573 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
574 /*
575 * 0x08, VanaHwHPReq1Valid
576 * 0x20, Vaux1HwHPReq1Valid
577 * 0x40, Vaux2HwHPReq1Valid
578 * 0x80, Vaux3HwHPReq1Valid
579 */
580 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
581 /*
582 * 0x01, VextSupply1HwHPReq1Valid
583 * 0x02, VextSupply2HwHPReq1Valid
584 * 0x04, VextSupply3HwHPReq1Valid
585 */
586 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
587 /*
588 * 0x08, VanaHwHPReq2Valid
589 * 0x20, Vaux1HwHPReq2Valid
590 * 0x40, Vaux2HwHPReq2Valid
591 * 0x80, Vaux3HwHPReq2Valid
592 */
593 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
594 /*
595 * 0x01, VextSupply1HwHPReq2Valid
596 * 0x02, VextSupply2HwHPReq2Valid
597 * 0x04, VextSupply3HwHPReq2Valid
598 */
599 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
600 /*
601 * 0x20, VanaSwHPReqValid
602 * 0x80, Vaux1SwHPReqValid
603 */
604 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
605 /*
606 * 0x01, Vaux2SwHPReqValid
607 * 0x02, Vaux3SwHPReqValid
608 * 0x04, VextSupply1SwHPReqValid
609 * 0x08, VextSupply2SwHPReqValid
610 * 0x10, VextSupply3SwHPReqValid
611 */
612 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
613 /*
614 * 0x02, SysClkReq2Valid1
615 * ...
616 * 0x80, SysClkReq8Valid1
617 */
618 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
619 /*
620 * 0x02, SysClkReq2Valid2
621 * ...
622 * 0x80, SysClkReq8Valid2
623 */
624 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
625 /*
626 * 0x02, VTVoutEna
627 * 0x04, Vintcore12Ena
628 * 0x38, Vintcore12Sel
629 * 0x40, Vintcore12LP
630 * 0x80, VTVoutLP
631 */
632 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
633 /*
634 * 0x02, VaudioEna
635 * 0x04, VdmicEna
636 * 0x08, Vamic1Ena
637 * 0x10, Vamic2Ena
638 */
639 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
640 /*
641 * 0x01, Vamic1_dzout
642 * 0x02, Vamic2_dzout
643 */
644 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
645 /*
646 * 0x0c, VanaRegu
647 * 0x03, VpllRegu
648 */
649 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
650 /*
651 * 0x01, VrefDDREna
652 * 0x02, VrefDDRSleepMode
653 */
654 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
655 /*
656 * 0x03, VextSupply1Regu
657 * 0x0c, VextSupply2Regu
658 * 0x30, VextSupply3Regu
659 * 0x40, ExtSupply2Bypass
660 * 0x80, ExtSupply3Bypass
661 */
662 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
663 /*
664 * 0x03, Vaux1Regu
665 * 0x0c, Vaux2Regu
666 */
667 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
668 /*
669 * 0x03, Vaux3Regu
670 */
671 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
672 /*
673 * 0x3f, Vsmps1Sel1
674 */
675 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
676 /*
677 * 0x0f, Vaux1Sel
678 */
679 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
680 /*
681 * 0x0f, Vaux2Sel
682 */
683 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
684 /*
685 * 0x07, Vaux3Sel
686 */
687 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
688 /*
689 * 0x01, VextSupply12LP
690 */
691 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
692 /*
693 * 0x04, Vaux1Disch
694 * 0x08, Vaux2Disch
695 * 0x10, Vaux3Disch
696 * 0x20, Vintcore12Disch
697 * 0x40, VTVoutDisch
698 * 0x80, VaudioDisch
699 */
700 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
701 /*
702 * 0x02, VanaDisch
703 * 0x04, VdmicPullDownEna
704 * 0x10, VdmicDisch
705 */
706 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
707};
708
529static __devinit int ab8500_regulator_probe(struct platform_device *pdev) 709static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
530{ 710{
531 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); 711 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
@@ -544,10 +724,51 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
544 724
545 /* make sure the platform data has the correct size */ 725 /* make sure the platform data has the correct size */
546 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { 726 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
547 dev_err(&pdev->dev, "platform configuration error\n"); 727 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
548 return -EINVAL; 728 return -EINVAL;
549 } 729 }
550 730
731 /* initialize registers */
732 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
733 int id;
734 u8 value;
735
736 id = pdata->regulator_reg_init[i].id;
737 value = pdata->regulator_reg_init[i].value;
738
739 /* check for configuration errors */
740 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
741 dev_err(&pdev->dev,
742 "Configuration error: id outside range.\n");
743 return -EINVAL;
744 }
745 if (value & ~ab8500_reg_init[id].mask) {
746 dev_err(&pdev->dev,
747 "Configuration error: value outside mask.\n");
748 return -EINVAL;
749 }
750
751 /* initialize register */
752 err = abx500_mask_and_set_register_interruptible(&pdev->dev,
753 ab8500_reg_init[id].bank,
754 ab8500_reg_init[id].addr,
755 ab8500_reg_init[id].mask,
756 value);
757 if (err < 0) {
758 dev_err(&pdev->dev,
759 "Failed to initialize 0x%02x, 0x%02x.\n",
760 ab8500_reg_init[id].bank,
761 ab8500_reg_init[id].addr);
762 return err;
763 }
764 dev_vdbg(&pdev->dev,
765 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
766 ab8500_reg_init[id].bank,
767 ab8500_reg_init[id].addr,
768 ab8500_reg_init[id].mask,
769 value);
770 }
771
551 /* register all regulators */ 772 /* register all regulators */
552 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { 773 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
553 struct ab8500_regulator_info *info = NULL; 774 struct ab8500_regulator_info *info = NULL;
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h
index 56f8dea72152..6e4f77ef4d20 100644
--- a/include/linux/mfd/ab8500.h
+++ b/include/linux/mfd/ab8500.h
@@ -139,17 +139,23 @@ struct ab8500 {
139 u8 oldmask[AB8500_NUM_IRQ_REGS]; 139 u8 oldmask[AB8500_NUM_IRQ_REGS];
140}; 140};
141 141
142struct regulator_reg_init;
142struct regulator_init_data; 143struct regulator_init_data;
143 144
144/** 145/**
145 * struct ab8500_platform_data - AB8500 platform data 146 * struct ab8500_platform_data - AB8500 platform data
146 * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used 147 * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
147 * @init: board-specific initialization after detection of ab8500 148 * @init: board-specific initialization after detection of ab8500
149 * @num_regulator_reg_init: number of regulator init registers
150 * @regulator_reg_init: regulator init registers
151 * @num_regulator: number of regulators
148 * @regulator: machine-specific constraints for regulators 152 * @regulator: machine-specific constraints for regulators
149 */ 153 */
150struct ab8500_platform_data { 154struct ab8500_platform_data {
151 int irq_base; 155 int irq_base;
152 void (*init) (struct ab8500 *); 156 void (*init) (struct ab8500 *);
157 int num_regulator_reg_init;
158 struct ab8500_regulator_reg_init *regulator_reg_init;
153 int num_regulator; 159 int num_regulator;
154 struct regulator_init_data *regulator; 160 struct regulator_init_data *regulator;
155}; 161};
diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h
index d4eacdef2017..76579f964a29 100644
--- a/include/linux/regulator/ab8500.h
+++ b/include/linux/regulator/ab8500.h
@@ -3,8 +3,8 @@
3 * 3 *
4 * License Terms: GNU General Public License v2 4 * License Terms: GNU General Public License v2
5 * 5 *
6 * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson 6 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
7 * 7 * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
8 */ 8 */
9 9
10#ifndef __LINUX_MFD_AB8500_REGULATOR_H 10#ifndef __LINUX_MFD_AB8500_REGULATOR_H
@@ -25,4 +25,50 @@ enum ab8500_regulator_id {
25 AB8500_LDO_ANA, 25 AB8500_LDO_ANA,
26 AB8500_NUM_REGULATORS, 26 AB8500_NUM_REGULATORS,
27}; 27};
28
29/* AB8500 register initialization */
30struct ab8500_regulator_reg_init {
31 int id;
32 u8 value;
33};
34
35#define INIT_REGULATOR_REGISTER(_id, _value) \
36 { \
37 .id = _id, \
38 .value = _value, \
39 }
40
41/* AB8500 registers */
42enum ab8500_regulator_reg {
43 AB8500_REGUREQUESTCTRL2,
44 AB8500_REGUREQUESTCTRL3,
45 AB8500_REGUREQUESTCTRL4,
46 AB8500_REGUSYSCLKREQ1HPVALID1,
47 AB8500_REGUSYSCLKREQ1HPVALID2,
48 AB8500_REGUHWHPREQ1VALID1,
49 AB8500_REGUHWHPREQ1VALID2,
50 AB8500_REGUHWHPREQ2VALID1,
51 AB8500_REGUHWHPREQ2VALID2,
52 AB8500_REGUSWHPREQVALID1,
53 AB8500_REGUSWHPREQVALID2,
54 AB8500_REGUSYSCLKREQVALID1,
55 AB8500_REGUSYSCLKREQVALID2,
56 AB8500_REGUMISC1,
57 AB8500_VAUDIOSUPPLY,
58 AB8500_REGUCTRL1VAMIC,
59 AB8500_VPLLVANAREGU,
60 AB8500_VREFDDR,
61 AB8500_EXTSUPPLYREGU,
62 AB8500_VAUX12REGU,
63 AB8500_VRF1VAUX3REGU,
64 AB8500_VAUX1SEL,
65 AB8500_VAUX2SEL,
66 AB8500_VRF1VAUX3SEL,
67 AB8500_REGUCTRL2SPARE,
68 AB8500_REGUCTRLDISCH,
69 AB8500_REGUCTRLDISCH2,
70 AB8500_VSMPS1SEL1,
71 AB8500_NUM_REGULATOR_REGISTERS,
72};
73
28#endif 74#endif