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

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>

authored by

Bengt Jonsson and committed by
Liam Girdwood
79568b94 ea05ef31

+279 -3
+2
arch/arm/mach-ux500/board-mop500-regulators.h
··· 14 14 #include <linux/regulator/machine.h> 15 15 #include <linux/regulator/ab8500.h> 16 16 17 + extern struct ab8500_regulator_reg_init 18 + ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; 17 19 extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; 18 20 19 21 #endif
+1
arch/arm/mach-ux500/board-mop500.c
··· 20 20 #include <linux/amba/serial.h> 21 21 #include <linux/spi/spi.h> 22 22 #include <linux/mfd/ab8500.h> 23 + #include <linux/regulator/ab8500.h> 23 24 #include <linux/mfd/tc3589x.h> 24 25 #include <linux/leds-lp5521.h> 25 26 #include <linux/input.h>
+222 -1
drivers/regulator/ab8500.c
··· 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 709 static __devinit int ab8500_regulator_probe(struct platform_device *pdev) 530 710 { 531 711 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); ··· 724 544 725 545 /* make sure the platform data has the correct size */ 726 546 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { 727 - dev_err(&pdev->dev, "platform configuration error\n"); 547 + dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); 728 548 return -EINVAL; 549 + } 550 + 551 + /* initialize registers */ 552 + for (i = 0; i < pdata->num_regulator_reg_init; i++) { 553 + int id; 554 + u8 value; 555 + 556 + id = pdata->regulator_reg_init[i].id; 557 + value = pdata->regulator_reg_init[i].value; 558 + 559 + /* check for configuration errors */ 560 + if (id >= AB8500_NUM_REGULATOR_REGISTERS) { 561 + dev_err(&pdev->dev, 562 + "Configuration error: id outside range.\n"); 563 + return -EINVAL; 564 + } 565 + if (value & ~ab8500_reg_init[id].mask) { 566 + dev_err(&pdev->dev, 567 + "Configuration error: value outside mask.\n"); 568 + return -EINVAL; 569 + } 570 + 571 + /* initialize register */ 572 + err = abx500_mask_and_set_register_interruptible(&pdev->dev, 573 + ab8500_reg_init[id].bank, 574 + ab8500_reg_init[id].addr, 575 + ab8500_reg_init[id].mask, 576 + value); 577 + if (err < 0) { 578 + dev_err(&pdev->dev, 579 + "Failed to initialize 0x%02x, 0x%02x.\n", 580 + ab8500_reg_init[id].bank, 581 + ab8500_reg_init[id].addr); 582 + return err; 583 + } 584 + dev_vdbg(&pdev->dev, 585 + " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 586 + ab8500_reg_init[id].bank, 587 + ab8500_reg_init[id].addr, 588 + ab8500_reg_init[id].mask, 589 + value); 729 590 } 730 591 731 592 /* register all regulators */
+6
include/linux/mfd/ab8500.h
··· 139 139 u8 oldmask[AB8500_NUM_IRQ_REGS]; 140 140 }; 141 141 142 + struct regulator_reg_init; 142 143 struct regulator_init_data; 143 144 144 145 /** 145 146 * struct ab8500_platform_data - AB8500 platform data 146 147 * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used 147 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 152 * @regulator: machine-specific constraints for regulators 149 153 */ 150 154 struct ab8500_platform_data { 151 155 int irq_base; 152 156 void (*init) (struct ab8500 *); 157 + int num_regulator_reg_init; 158 + struct ab8500_regulator_reg_init *regulator_reg_init; 153 159 int num_regulator; 154 160 struct regulator_init_data *regulator; 155 161 };
+48 -2
include/linux/regulator/ab8500.h
··· 3 3 * 4 4 * License Terms: GNU General Public License v2 5 5 * 6 - * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson 7 - * 6 + * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson 7 + * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson 8 8 */ 9 9 10 10 #ifndef __LINUX_MFD_AB8500_REGULATOR_H ··· 25 25 AB8500_LDO_ANA, 26 26 AB8500_NUM_REGULATORS, 27 27 }; 28 + 29 + /* AB8500 register initialization */ 30 + struct 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 */ 42 + enum 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 74 #endif