diff options
author | Bengt Jonsson <bengt.g.jonsson@stericsson.com> | 2011-03-11 05:54:46 -0500 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2011-03-26 10:15:05 -0400 |
commit | 79568b941277b5986a8a7f0fb8578b2ccfc3e87e (patch) | |
tree | b66551a8bd5c9fa75f01767578e76a19d030ee32 /drivers | |
parent | ea05ef31f2aa98b25d14222300dc9c1d1eb59e41 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/ab8500.c | 223 |
1 files changed, 222 insertions, 1 deletions
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 | ||
529 | struct 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 | |||
542 | static 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 | |||
529 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | 709 | static __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; |