From d79df329d0bd425c00856915b7b12f54dd100154 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 21 Mar 2013 15:58:58 +0000 Subject: regulator: ab8500: Further populate initialisation registers This patch supplies access to some extra settings provided by the AB8500 regulator device. We also update some of the existing initialisation values in accordance with internal ST-Ericsson code submissions. This single patch was originally a collection of updates which have been squashed together to aid with clarity. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- include/linux/regulator/ab8500.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 7bd73bbdfd1b..2c6c9625013c 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -86,7 +86,15 @@ enum ab8500_regulator_reg { AB8500_REGUCTRL2SPARE, AB8500_REGUCTRLDISCH, AB8500_REGUCTRLDISCH2, + AB8500_ARMREGU2, /* NOTE! PRCMU register */ + AB8500_VBBSEL1, /* NOTE! PRCMU register */ + AB8500_VBBSEL2, /* NOTE! PRCMU register */ + AB8500_VSMPS1REGU, + AB8500_VSMPS2REGU, + AB8500_VSMPS3REGU, /* NOTE! PRCMU register */ AB8500_VSMPS1SEL1, + AB8500_VSMPS3SEL1, /* NOTE! PRCMU register */ + AB8500_VSMPS3SEL2, /* NOTE! PRCMU register */ AB8500_NUM_REGULATOR_REGISTERS, }; -- cgit v1.2.3 From 3c1b8438d4bc99269aba560739e3e6cb640584f4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 21 Mar 2013 15:59:01 +0000 Subject: ARM: ux500: regulators: Add mask for configuration There is already before a register mask in the regulator driver to allow some bits of a register to be initialized. The register value is defined in the board configuration. This patch puts a mask in the board configuration to specify which bits should actually be altered. The purpose with this patch is to avoid future mistakes when updating the allowed bits in the regulator driver. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500-regulators.c | 66 +++++++++++++-------------- drivers/regulator/ab8500.c | 36 ++++++--------- include/linux/regulator/ab8500.h | 10 ++-- 3 files changed, 53 insertions(+), 59 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 4b3c51905071..96dd17490bea 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -129,19 +129,19 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * VpllRequestCtrl = HP/LP depending on VxRequest * VextSupply1RequestCtrl = HP/LP depending on VxRequest */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xfc, 0x00), /* * VextSupply2RequestCtrl = HP/LP depending on VxRequest * VextSupply3RequestCtrl = HP/LP depending on VxRequest * Vaux1RequestCtrl = HP/LP depending on VxRequest * Vaux2RequestCtrl = HP/LP depending on VxRequest */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0xff, 0x00), /* * Vaux3RequestCtrl = HP/LP depending on VxRequest * SwHPReq = Control through SWValid disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00), /* * Vsmps1SysClkReq1HPValid = enabled * Vsmps2SysClkReq1HPValid = enabled @@ -152,44 +152,44 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * Vaux2SysClkReq1HPValid = disabled * Vaux3SysClkReq1HPValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x17), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xff, 0x17), /* * VextSupply1SysClkReq1HPValid = disabled * VextSupply2SysClkReq1HPValid = disabled * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x70, 0x40), /* * VanaHwHPReq1Valid = disabled * Vaux1HwHPreq1Valid = disabled * Vaux2HwHPReq1Valid = disabled * Vaux3HwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0xe8, 0x00), /* * VextSupply1HwHPReq1Valid = disabled * VextSupply2HwHPReq1Valid = disabled * VextSupply3HwHPReq1Valid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x07, 0x00), /* * VanaHwHPReq2Valid = disabled * Vaux1HwHPReq2Valid = disabled * Vaux2HwHPReq2Valid = disabled * Vaux3HwHPReq2Valid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0xe8, 0x00), /* * VextSupply1HwHPReq2Valid = disabled * VextSupply2HwHPReq2Valid = disabled * VextSupply3HwHPReq2Valid = HWReq2 controlled */ - INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04), + INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x07, 0x04), /* * VanaSwHPReqValid = disabled * Vaux1SwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0xa0, 0x00), /* * Vaux2SwHPReqValid = disabled * Vaux3SwHPReqValid = disabled @@ -197,7 +197,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * VextSupply2SwHPReqValid = disabled * VextSupply3SwHPReqValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x1f, 0x00), /* * SysClkReq2Valid1 = SysClkReq2 controlled * SysClkReq3Valid1 = disabled @@ -207,7 +207,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * SysClkReq7Valid1 = disabled * SysClkReq8Valid1 = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0xfe, 0x2a), /* * SysClkReq2Valid2 = disabled * SysClkReq3Valid2 = disabled @@ -217,7 +217,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * SysClkReq7Valid2 = disabled * SysClkReq8Valid2 = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0xfe, 0x20), /* * VTVoutEna = disabled * Vintcore12Ena = disabled @@ -225,57 +225,57 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * Vintcore12LP = inactive (HP) * VTVoutLP = inactive (HP) */ - INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10), + INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0xfe, 0x10), /* * VaudioEna = disabled * VdmicEna = disabled * Vamic1Ena = disabled * Vamic2Ena = disabled */ - INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x1e, 0x00), /* * Vamic1_dzout = high-Z when Vamic1 is disabled * Vamic2_dzout = high-Z when Vamic2 is disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), /* * VBBN = force OFF * VBBP = force OFF * NOTE! PRCMU register */ - INIT_REGULATOR_REGISTER(AB8500_ARMREGU2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_ARMREGU2, 0x0f, 0x00), /* * VBBNSel1 = VBBP = VBBPFB * VBBPSel1 = 0 V * NOTE! PRCMU register */ - INIT_REGULATOR_REGISTER(AB8500_VBBSEL1, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VBBSEL1, 0x0f, 0x00), /* * VBBNSel2 = VBBP = VBBPFB * VBBPSel2 = 0 V * NOTE! PRCMU register */ - INIT_REGULATOR_REGISTER(AB8500_VBBSEL2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VBBSEL2, 0x0f, 0x00), /* * Vsmps1Regu = HW control * Vsmps1SelCtrl = Vsmps1 voltage defined by Vsmsp1Sel2 */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1REGU, 0x06), + INIT_REGULATOR_REGISTER(AB8500_VSMPS1REGU, 0x0f, 0x06), /* * Vsmps2Regu = HW control * Vsmps2SelCtrl = Vsmps2 voltage defined by Vsmsp2Sel2 */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS2REGU, 0x06), + INIT_REGULATOR_REGISTER(AB8500_VSMPS2REGU, 0x0f, 0x06), /* * VPll = Hw controlled * VanaRegu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02), + INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02), /* * VrefDDREna = disabled * VrefDDRSleepMode = inactive (no pulldown) */ - INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00), + INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x03, 0x00), /* * VextSupply1Regu = HW control * VextSupply2Regu = HW control @@ -283,37 +283,37 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 */ - INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a), + INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0xff, 0x1a), /* * Vaux1Regu = force HP * Vaux2Regu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01), + INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01), /* * Vrf1Regu = HW control * Vaux3Regu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x08), + INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x0f, 0x08), /* * Vsmps1 = 1.15V */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24), + INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x3f, 0x24), /* * Vaux1Sel = 2.5 V */ - INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08), + INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x0f, 0x08), /* * Vaux2Sel = 2.9 V */ - INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d), + INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0f, 0x0d), /* * Vaux3Sel = 2.91 V */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07), + INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07, 0x07), /* * VextSupply12LP = disabled (no LP) */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x01, 0x00), /* * Vaux1Disch = short discharge time * Vaux2Disch = short discharge time @@ -322,13 +322,13 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * VTVoutDisch = short discharge time * VaudioDisch = short discharge time */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0xfc, 0x00), /* * VanaDisch = short discharge time * VdmicPullDownEna = pulldown disabled when Vdmic is disabled * VdmicDisch = short discharge time */ - INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x16, 0x00), }; /* AB8500 regulators */ diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 3465ac38bffe..a847744f8c20 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -811,23 +811,20 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), }; -static int -ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) +static int ab8500_regulator_init_registers(struct platform_device *pdev, + int id, int mask, int value) { int err; - if (value & ~ab8500_reg_init[id].mask) { - dev_err(&pdev->dev, - "Configuration error: value outside mask.\n"); - return -EINVAL; - } + BUG_ON(value & ~mask); + BUG_ON(mask & ~ab8500_reg_init[id].mask); + /* initialize register */ err = abx500_mask_and_set_register_interruptible( &pdev->dev, ab8500_reg_init[id].bank, ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); + mask, value); if (err < 0) { dev_err(&pdev->dev, "Failed to initialize 0x%02x, 0x%02x.\n", @@ -835,13 +832,11 @@ ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) ab8500_reg_init[id].addr); return err; } - dev_vdbg(&pdev->dev, - "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); + " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + mask, value); return 0; } @@ -960,19 +955,16 @@ static int ab8500_regulator_probe(struct platform_device *pdev) /* initialize registers */ for (i = 0; i < pdata->num_regulator_reg_init; i++) { - int id, value; + int id, mask, value; id = pdata->regulator_reg_init[i].id; + mask = pdata->regulator_reg_init[i].mask; value = pdata->regulator_reg_init[i].value; /* check for configuration errors */ - if (id >= AB8500_NUM_REGULATOR_REGISTERS) { - dev_err(&pdev->dev, - "Configuration error: id outside range.\n"); - return -EINVAL; - } + BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS); - err = ab8500_regulator_init_registers(pdev, id, value); + err = ab8500_regulator_init_registers(pdev, id, mask, value); if (err < 0) return err; } diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 2c6c9625013c..a1d245f13d9c 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -48,13 +48,15 @@ enum ab9540_regulator_id { /* AB8500 and AB9540 register initialization */ struct ab8500_regulator_reg_init { int id; + u8 mask; u8 value; }; -#define INIT_REGULATOR_REGISTER(_id, _value) \ - { \ - .id = _id, \ - .value = _value, \ +#define INIT_REGULATOR_REGISTER(_id, _mask, _value) \ + { \ + .id = _id, \ + .mask = _mask, \ + .value = _value, \ } /* AB8500 registers */ -- cgit v1.2.3 From 33bc8f46a8ee3fc1836def9713933435b7ff0b90 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 21 Mar 2013 15:59:02 +0000 Subject: regulator: ab8500: Another push to synchronise recent AB8500 developments This patch ensures that many of the recent developments pertaining to the AB8500 regulator device are propagated out into the public arena. It aims to update some of the existing initialisation values in accordance with internal ST-Ericsson code submissions. This single patch was originally a collection of updates which have been squashed together to aid with clarity. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500-regulators.c | 18 ------ drivers/regulator/ab8500.c | 86 +++++++++++++++++---------- include/linux/regulator/ab8500.h | 21 ++++--- 3 files changed, 65 insertions(+), 60 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 96dd17490bea..a8141e3e8ca1 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -238,24 +238,6 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { * Vamic2_dzout = high-Z when Vamic2 is disabled */ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), - /* - * VBBN = force OFF - * VBBP = force OFF - * NOTE! PRCMU register - */ - INIT_REGULATOR_REGISTER(AB8500_ARMREGU2, 0x0f, 0x00), - /* - * VBBNSel1 = VBBP = VBBPFB - * VBBPSel1 = 0 V - * NOTE! PRCMU register - */ - INIT_REGULATOR_REGISTER(AB8500_VBBSEL1, 0x0f, 0x00), - /* - * VBBNSel2 = VBBP = VBBPFB - * VBBPSel2 = 0 V - * NOTE! PRCMU register - */ - INIT_REGULATOR_REGISTER(AB8500_VBBSEL2, 0x0f, 0x00), /* * Vsmps1Regu = HW control * Vsmps1SelCtrl = Vsmps1 voltage defined by Vsmsp1Sel2 diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index a847744f8c20..c7784c4bff4f 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -613,11 +613,19 @@ struct ab8500_reg_init { static struct ab8500_reg_init ab8500_reg_init[] = { /* - * 0x30, VanaRequestCtrl + * 0x03, VarmRequestCtrl + * 0x0c, VapeRequestCtrl + * 0x30, Vsmps1RequestCtrl + * 0xc0, Vsmps2RequestCtrl + */ + REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff), + /* + * 0x03, Vsmps3RequestCtrl * 0x0c, VpllRequestCtrl + * 0x30, VanaRequestCtrl * 0xc0, VextSupply1RequestCtrl */ - REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc), + REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff), /* * 0x03, VextSupply2RequestCtrl * 0x0c, VextSupply3RequestCtrl @@ -642,50 +650,71 @@ static struct ab8500_reg_init ab8500_reg_init[] = { */ REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff), /* + * 0x01, VapeSysClkReq1HPValid + * 0x02, VarmSysClkReq1HPValid + * 0x04, VbbSysClkReq1HPValid + * 0x08, VmodSysClkReq1HPValid * 0x10, VextSupply1SysClkReq1HPValid * 0x20, VextSupply2SysClkReq1HPValid * 0x40, VextSupply3SysClkReq1HPValid */ - REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f), /* + * 0x01, Vsmps1HwHPReq1Valid + * 0x02, Vsmps2HwHPReq1Valid + * 0x04, Vsmps3HwHPReq1Valid * 0x08, VanaHwHPReq1Valid + * 0x10, VpllHwHPReq1Valid * 0x20, Vaux1HwHPReq1Valid * 0x40, Vaux2HwHPReq1Valid * 0x80, Vaux3HwHPReq1Valid */ - REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), + REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff), /* * 0x01, VextSupply1HwHPReq1Valid * 0x02, VextSupply2HwHPReq1Valid * 0x04, VextSupply3HwHPReq1Valid + * 0x08, VmodHwHPReq1Valid */ - REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), + REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f), /* + * 0x01, Vsmps1HwHPReq2Valid + * 0x02, Vsmps2HwHPReq2Valid + * 0x03, Vsmps3HwHPReq2Valid * 0x08, VanaHwHPReq2Valid + * 0x10, VpllHwHPReq2Valid * 0x20, Vaux1HwHPReq2Valid * 0x40, Vaux2HwHPReq2Valid * 0x80, Vaux3HwHPReq2Valid */ - REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), + REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff), /* * 0x01, VextSupply1HwHPReq2Valid * 0x02, VextSupply2HwHPReq2Valid * 0x04, VextSupply3HwHPReq2Valid + * 0x08, VmodHwHPReq2Valid */ - REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), + REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f), /* + * 0x01, VapeSwHPReqValid + * 0x02, VarmSwHPReqValid + * 0x04, Vsmps1SwHPReqValid + * 0x08, Vsmps2SwHPReqValid + * 0x10, Vsmps3SwHPReqValid * 0x20, VanaSwHPReqValid + * 0x40, VpllSwHPReqValid * 0x80, Vaux1SwHPReqValid */ - REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), + REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff), /* * 0x01, Vaux2SwHPReqValid * 0x02, Vaux3SwHPReqValid * 0x04, VextSupply1SwHPReqValid * 0x08, VextSupply2SwHPReqValid * 0x10, VextSupply3SwHPReqValid + * 0x20, VmodSwHPReqValid */ - REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), + REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f), /* * 0x02, SysClkReq2Valid1 * ... @@ -718,37 +747,23 @@ static struct ab8500_reg_init ab8500_reg_init[] = { * 0x02, Vamic2_dzout */ REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), - /* - * 0x0c, VBBNRegu - * 0x03, VBBPRegu - * NOTE! PRCMU register - */ - REG_INIT(AB8500_ARMREGU2, 0x04, 0x01, 0x0f), - /* - * 0x0c, VBBPSel1 - * 0x03, VBBNSel1 - * NOTE! PRCMU register - */ - REG_INIT(AB8500_VBBSEL1, 0x04, 0x11, 0x0f), - /* - * 0x0c, VBBNSel2 - * 0x03, VBBPSel2 - * NOTE! PRCMU register - */ - REG_INIT(AB8500_VBBSEL2, 0x04, 0x12, 0x0f), /* * 0x03, Vsmps1Regu * 0x0c, Vsmps1SelCtrl + * 0x10, Vsmps1AutoMode + * 0x20, Vsmps1PWMMode */ - REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x0f), + REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f), /* * 0x03, Vsmps2Regu * 0x0c, Vsmps2SelCtrl + * 0x10, Vsmps2AutoMode + * 0x20, Vsmps2PWMMode */ - REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x0f), + REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f), /* - * 0x0c, VanaRegu * 0x03, VpllRegu + * 0x0c, VanaRegu */ REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), /* @@ -788,13 +803,16 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), /* * 0x07, Vaux3Sel + * 0x30, Vrf1Sel */ - REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), + REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37), /* * 0x01, VextSupply12LP */ REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), /* + * 0x01, VpllDisch + * 0x02, Vrf1Disch * 0x04, Vaux1Disch * 0x08, Vaux2Disch * 0x10, Vaux3Disch @@ -802,13 +820,15 @@ static struct ab8500_reg_init ab8500_reg_init[] = { * 0x40, VTVoutDisch * 0x80, VaudioDisch */ - REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), + REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff), /* + * 0x01, VsimDisch * 0x02, VanaDisch * 0x04, VdmicPullDownEna + * 0x08, VpllPullDownEna * 0x10, VdmicDisch */ - REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), + REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f), }; static int ab8500_regulator_init_registers(struct platform_device *pdev, diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index a1d245f13d9c..dd7944f735d8 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -61,6 +61,7 @@ struct ab8500_regulator_reg_init { /* AB8500 registers */ enum ab8500_regulator_reg { + AB8500_REGUREQUESTCTRL1, AB8500_REGUREQUESTCTRL2, AB8500_REGUREQUESTCTRL3, AB8500_REGUREQUESTCTRL4, @@ -77,26 +78,28 @@ enum ab8500_regulator_reg { AB8500_REGUMISC1, AB8500_VAUDIOSUPPLY, AB8500_REGUCTRL1VAMIC, + AB8500_VSMPS1REGU, + AB8500_VSMPS2REGU, + AB8500_VSMPS3REGU, /* NOTE! PRCMU register */ AB8500_VPLLVANAREGU, AB8500_VREFDDR, AB8500_EXTSUPPLYREGU, AB8500_VAUX12REGU, AB8500_VRF1VAUX3REGU, + AB8500_VSMPS1SEL1, + AB8500_VSMPS1SEL2, + AB8500_VSMPS1SEL3, + AB8500_VSMPS2SEL1, + AB8500_VSMPS2SEL2, + AB8500_VSMPS2SEL3, + AB8500_VSMPS3SEL1, /* NOTE! PRCMU register */ + AB8500_VSMPS3SEL2, /* NOTE! PRCMU register */ AB8500_VAUX1SEL, AB8500_VAUX2SEL, AB8500_VRF1VAUX3SEL, AB8500_REGUCTRL2SPARE, AB8500_REGUCTRLDISCH, AB8500_REGUCTRLDISCH2, - AB8500_ARMREGU2, /* NOTE! PRCMU register */ - AB8500_VBBSEL1, /* NOTE! PRCMU register */ - AB8500_VBBSEL2, /* NOTE! PRCMU register */ - AB8500_VSMPS1REGU, - AB8500_VSMPS2REGU, - AB8500_VSMPS3REGU, /* NOTE! PRCMU register */ - AB8500_VSMPS1SEL1, - AB8500_VSMPS3SEL1, /* NOTE! PRCMU register */ - AB8500_VSMPS3SEL2, /* NOTE! PRCMU register */ AB8500_NUM_REGULATOR_REGISTERS, }; -- cgit v1.2.3 From 732805a563617aafc7405409c03182afafb3943b Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Thu, 21 Mar 2013 15:59:03 +0000 Subject: regulator: ab8500: Separate regulator and MFD platform data The ab8500 MFD should not have knowledge about regulator- specific platform data like number of regulators and regulator registers. As the regulator platform data is about to grow with external regulators, this information is moved to a new structure provided by the regulator driver. Signed-off-by: Bengt Jonsson Signed-off-by: Lee Jones Reviewed-by: Yvan FILLION Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500-regulators.c | 12 +++++++++--- arch/arm/mach-ux500/board-mop500-regulators.h | 4 +--- drivers/regulator/ab8500.c | 21 +++++++++++++++------ include/linux/regulator/ab8500.h | 7 +++++++ 4 files changed, 32 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index a8141e3e8ca1..0fd84d42e1ec 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -122,8 +122,7 @@ static struct regulator_consumer_supply ab8500_vana_consumers[] = { }; /* ab8500 regulator register initialization */ -struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { +static struct ab8500_regulator_reg_init ab8500_reg_init[] = { /* * VanaRequestCtrl = HP/LP depending on VxRequest * VpllRequestCtrl = HP/LP depending on VxRequest @@ -314,7 +313,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { }; /* AB8500 regulators */ -struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { +static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { /* supplies to the display/camera */ [AB8500_LDO_AUX1] = { .constraints = { @@ -423,3 +422,10 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .consumer_supplies = ab8500_vana_consumers, }, }; + +struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { + .reg_init = ab8500_reg_init, + .num_reg_init = ARRAY_SIZE(ab8500_reg_init), + .regulator = ab8500_regulators, + .num_regulator = ARRAY_SIZE(ab8500_regulators), +}; diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 78a0642a2206..9ca4869a6f23 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -14,9 +14,7 @@ #include #include -extern struct ab8500_regulator_reg_init -ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; -extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; +extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data; extern struct regulator_init_data tps61052_regulator; extern struct regulator_init_data gpio_en_3v3_regulator; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index c7784c4bff4f..f7d1f538c200 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -939,8 +939,9 @@ ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np) static int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); - struct ab8500_platform_data *pdata; struct device_node *np = pdev->dev.of_node; + struct ab8500_platform_data *ppdata; + struct ab8500_regulator_platform_data *pdata; int i, err; if (np) { @@ -961,7 +962,14 @@ static int ab8500_regulator_probe(struct platform_device *pdev) dev_err(&pdev->dev, "null mfd parent\n"); return -EINVAL; } - pdata = dev_get_platdata(ab8500->dev); + + ppdata = dev_get_platdata(ab8500->dev); + if (!ppdata) { + dev_err(&pdev->dev, "null parent pdata\n"); + return -EINVAL; + } + + pdata = ppdata->regulator; if (!pdata) { dev_err(&pdev->dev, "null pdata\n"); return -EINVAL; @@ -974,12 +982,12 @@ static int ab8500_regulator_probe(struct platform_device *pdev) } /* initialize registers */ - for (i = 0; i < pdata->num_regulator_reg_init; i++) { + for (i = 0; i < pdata->num_reg_init; i++) { int id, mask, value; - id = pdata->regulator_reg_init[i].id; - mask = pdata->regulator_reg_init[i].mask; - value = pdata->regulator_reg_init[i].value; + id = pdata->reg_init[i].id; + mask = pdata->reg_init[i].mask; + value = pdata->reg_init[i].value; /* check for configuration errors */ BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS); @@ -1045,5 +1053,6 @@ module_exit(ab8500_regulator_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sundar Iyer "); +MODULE_AUTHOR("Bengt Jonsson "); MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC"); MODULE_ALIAS("platform:ab8500-regulator"); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index dd7944f735d8..3a8e02687f7b 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -152,4 +152,11 @@ enum ab9540_regulator_reg { AB9540_NUM_REGULATOR_REGISTERS, }; +struct ab8500_regulator_platform_data { + int num_reg_init; + struct ab8500_regulator_reg_init *reg_init; + int num_regulator; + struct regulator_init_data *regulator; +}; + #endif -- cgit v1.2.3 From 43a5911b3dcec81add87d833cd8c7ddaaa205a47 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 21 Mar 2013 15:59:15 +0000 Subject: regulator: ab8500: Clean out SoC registers Clean out initialisation that is handled by SoC. Regulator settings for Vpll (partly), Vsmps1, Vsmps2, Vsmps3 (partly), Vrf1, Varm, Vape, Vbb, Vmod are cleaned out. They should not be touched by the kernel. We also update many of the initialisation values to be more in-line with the current development efforts of ST-Ericsson internal engineers. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500-regulators.c | 28 ++------ drivers/regulator/ab8500.c | 98 +++++++-------------------- include/linux/regulator/ab8500.h | 12 ---- 3 files changed, 28 insertions(+), 110 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index c962d1d726bb..3d899c51bbac 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -139,10 +139,9 @@ static struct regulator_consumer_supply ab8500_vana_consumers[] = { static struct ab8500_regulator_reg_init ab8500_reg_init[] = { /* * VanaRequestCtrl = HP/LP depending on VxRequest - * VpllRequestCtrl = HP/LP depending on VxRequest * VextSupply1RequestCtrl = HP/LP depending on VxRequest */ - INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xfc, 0x00), + INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xf0, 0x00), /* * VextSupply2RequestCtrl = HP/LP depending on VxRequest * VextSupply3RequestCtrl = HP/LP depending on VxRequest @@ -156,16 +155,12 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = { */ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00), /* - * Vsmps1SysClkReq1HPValid = enabled - * Vsmps2SysClkReq1HPValid = enabled - * Vsmps3SysClkReq1HPValid = enabled * VanaSysClkReq1HPValid = disabled - * VpllSysClkReq1HPValid = enabled * Vaux1SysClkReq1HPValid = disabled * Vaux2SysClkReq1HPValid = disabled * Vaux3SysClkReq1HPValid = disabled */ - INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xff, 0x17), + INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), /* * VextSupply1SysClkReq1HPValid = disabled * VextSupply2SysClkReq1HPValid = disabled @@ -252,17 +247,7 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = { */ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), /* - * Vsmps1Regu = HW control - * Vsmps1SelCtrl = Vsmps1 voltage defined by Vsmsp1Sel2 - */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1REGU, 0x0f, 0x06), - /* - * Vsmps2Regu = HW control - * Vsmps2SelCtrl = Vsmps2 voltage defined by Vsmsp2Sel2 - */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS2REGU, 0x0f, 0x06), - /* - * VPll = Hw controlled + * VPll = Hw controlled (NOTE! PRCMU bits) * VanaRegu = force off */ INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02), @@ -285,14 +270,9 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = { */ INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01), /* - * Vrf1Regu = HW control * Vaux3Regu = force off */ - INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x0f, 0x08), - /* - * Vsmps1 = 1.15V - */ - INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x3f, 0x24), + INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x03, 0x00), /* * Vaux1Sel = 2.5 V */ diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index f1453a66a0fd..919d9fa9605e 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -613,19 +613,10 @@ struct ab8500_reg_init { static struct ab8500_reg_init ab8500_reg_init[] = { /* - * 0x03, VarmRequestCtrl - * 0x0c, VapeRequestCtrl - * 0x30, Vsmps1RequestCtrl - * 0xc0, Vsmps2RequestCtrl - */ - REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff), - /* - * 0x03, Vsmps3RequestCtrl - * 0x0c, VpllRequestCtrl * 0x30, VanaRequestCtrl * 0xc0, VextSupply1RequestCtrl */ - REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff), + REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xf0), /* * 0x03, VextSupply2RequestCtrl * 0x0c, VextSupply3RequestCtrl @@ -639,91 +630,74 @@ static struct ab8500_reg_init ab8500_reg_init[] = { */ REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), /* - * 0x01, Vsmps1SysClkReq1HPValid - * 0x02, Vsmps2SysClkReq1HPValid - * 0x04, Vsmps3SysClkReq1HPValid * 0x08, VanaSysClkReq1HPValid - * 0x10, VpllSysClkReq1HPValid * 0x20, Vaux1SysClkReq1HPValid * 0x40, Vaux2SysClkReq1HPValid * 0x80, Vaux3SysClkReq1HPValid */ - REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff), + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8), /* - * 0x01, VapeSysClkReq1HPValid - * 0x02, VarmSysClkReq1HPValid - * 0x04, VbbSysClkReq1HPValid - * 0x08, VmodSysClkReq1HPValid * 0x10, VextSupply1SysClkReq1HPValid * 0x20, VextSupply2SysClkReq1HPValid * 0x40, VextSupply3SysClkReq1HPValid */ - REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f), + REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), /* - * 0x01, Vsmps1HwHPReq1Valid - * 0x02, Vsmps2HwHPReq1Valid - * 0x04, Vsmps3HwHPReq1Valid * 0x08, VanaHwHPReq1Valid - * 0x10, VpllHwHPReq1Valid * 0x20, Vaux1HwHPReq1Valid * 0x40, Vaux2HwHPReq1Valid * 0x80, Vaux3HwHPReq1Valid */ - REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff), + REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), /* * 0x01, VextSupply1HwHPReq1Valid * 0x02, VextSupply2HwHPReq1Valid * 0x04, VextSupply3HwHPReq1Valid - * 0x08, VmodHwHPReq1Valid */ - REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f), + REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), /* - * 0x01, Vsmps1HwHPReq2Valid - * 0x02, Vsmps2HwHPReq2Valid - * 0x03, Vsmps3HwHPReq2Valid * 0x08, VanaHwHPReq2Valid - * 0x10, VpllHwHPReq2Valid * 0x20, Vaux1HwHPReq2Valid * 0x40, Vaux2HwHPReq2Valid * 0x80, Vaux3HwHPReq2Valid */ - REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff), + REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), /* * 0x01, VextSupply1HwHPReq2Valid * 0x02, VextSupply2HwHPReq2Valid * 0x04, VextSupply3HwHPReq2Valid - * 0x08, VmodHwHPReq2Valid */ - REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f), + REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), /* - * 0x01, VapeSwHPReqValid - * 0x02, VarmSwHPReqValid - * 0x04, Vsmps1SwHPReqValid - * 0x08, Vsmps2SwHPReqValid - * 0x10, Vsmps3SwHPReqValid * 0x20, VanaSwHPReqValid - * 0x40, VpllSwHPReqValid * 0x80, Vaux1SwHPReqValid */ - REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff), + REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), /* * 0x01, Vaux2SwHPReqValid * 0x02, Vaux3SwHPReqValid * 0x04, VextSupply1SwHPReqValid * 0x08, VextSupply2SwHPReqValid * 0x10, VextSupply3SwHPReqValid - * 0x20, VmodSwHPReqValid */ - REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f), + REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), /* * 0x02, SysClkReq2Valid1 - * ... + * 0x04, SysClkReq3Valid1 + * 0x08, SysClkReq4Valid1 + * 0x10, SysClkReq5Valid1 + * 0x20, SysClkReq6Valid1 + * 0x40, SysClkReq7Valid1 * 0x80, SysClkReq8Valid1 */ REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe), /* * 0x02, SysClkReq2Valid2 - * ... + * 0x04, SysClkReq3Valid2 + * 0x08, SysClkReq4Valid2 + * 0x10, SysClkReq5Valid2 + * 0x20, SysClkReq6Valid2 + * 0x40, SysClkReq7Valid2 * 0x80, SysClkReq8Valid2 */ REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe), @@ -748,21 +722,7 @@ static struct ab8500_reg_init ab8500_reg_init[] = { */ REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), /* - * 0x03, Vsmps1Regu - * 0x0c, Vsmps1SelCtrl - * 0x10, Vsmps1AutoMode - * 0x20, Vsmps1PWMMode - */ - REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f), - /* - * 0x03, Vsmps2Regu - * 0x0c, Vsmps2SelCtrl - * 0x10, Vsmps2AutoMode - * 0x20, Vsmps2PWMMode - */ - REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f), - /* - * 0x03, VpllRegu + * 0x03, VpllRegu (NOTE! PRCMU register bits) * 0x0c, VanaRegu */ REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), @@ -785,14 +745,9 @@ static struct ab8500_reg_init ab8500_reg_init[] = { */ REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f), /* - * 0x0c, Vrf1Regu * 0x03, Vaux3Regu */ - REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f), - /* - * 0x3f, Vsmps1Sel1 - */ - REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f), + REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03), /* * 0x0f, Vaux1Sel */ @@ -803,16 +758,13 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), /* * 0x07, Vaux3Sel - * 0x30, Vrf1Sel */ - REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37), + REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), /* * 0x01, VextSupply12LP */ REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), /* - * 0x01, VpllDisch - * 0x02, Vrf1Disch * 0x04, Vaux1Disch * 0x08, Vaux2Disch * 0x10, Vaux3Disch @@ -820,15 +772,13 @@ static struct ab8500_reg_init ab8500_reg_init[] = { * 0x40, VTVoutDisch * 0x80, VaudioDisch */ - REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff), + REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), /* - * 0x01, VsimDisch * 0x02, VanaDisch * 0x04, VdmicPullDownEna - * 0x08, VpllPullDownEna * 0x10, VdmicDisch */ - REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f), + REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), }; static int ab8500_regulator_init_registers(struct platform_device *pdev, diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 3a8e02687f7b..26792ff360be 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -61,7 +61,6 @@ struct ab8500_regulator_reg_init { /* AB8500 registers */ enum ab8500_regulator_reg { - AB8500_REGUREQUESTCTRL1, AB8500_REGUREQUESTCTRL2, AB8500_REGUREQUESTCTRL3, AB8500_REGUREQUESTCTRL4, @@ -78,22 +77,11 @@ enum ab8500_regulator_reg { AB8500_REGUMISC1, AB8500_VAUDIOSUPPLY, AB8500_REGUCTRL1VAMIC, - AB8500_VSMPS1REGU, - AB8500_VSMPS2REGU, - AB8500_VSMPS3REGU, /* NOTE! PRCMU register */ AB8500_VPLLVANAREGU, AB8500_VREFDDR, AB8500_EXTSUPPLYREGU, AB8500_VAUX12REGU, AB8500_VRF1VAUX3REGU, - AB8500_VSMPS1SEL1, - AB8500_VSMPS1SEL2, - AB8500_VSMPS1SEL3, - AB8500_VSMPS2SEL1, - AB8500_VSMPS2SEL2, - AB8500_VSMPS2SEL3, - AB8500_VSMPS3SEL1, /* NOTE! PRCMU register */ - AB8500_VSMPS3SEL2, /* NOTE! PRCMU register */ AB8500_VAUX1SEL, AB8500_VAUX2SEL, AB8500_VRF1VAUX3SEL, -- cgit v1.2.3 From d1a820011b2fbc11d5af80d1a961fe66c613fa4b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Mar 2013 16:11:01 +0000 Subject: regulator: ab8500-ext: New driver to control external regulators The ABx500 is capable of controlling three external regulator supplies. Most commonly on and off are supported, but if an external regulator chipset or power supply supports high-power and low-power mode settings, we can control those too. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/Makefile | 2 +- drivers/regulator/ab8500-ext.c | 394 +++++++++++++++++++++++++++++++++++++++ drivers/regulator/ab8500.c | 12 +- include/linux/regulator/ab8500.h | 28 +++ 4 files changed, 434 insertions(+), 2 deletions(-) create mode 100644 drivers/regulator/ab8500-ext.c (limited to 'include/linux') diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 6e8250382def..47a34ff88f98 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o -obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o +obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o ab8500-ext.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c new file mode 100644 index 000000000000..95008dec5190 --- /dev/null +++ b/drivers/regulator/ab8500-ext.c @@ -0,0 +1,394 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * + * Authors: Bengt Jonsson + * + * This file is based on drivers/regulator/ab8500.c + * + * AB8500 external regulators + * + * ab8500-ext supports the following regulators: + * - VextSupply3 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct ab8500_ext_regulator_info - ab8500 regulator information + * @dev: device pointer + * @desc: regulator description + * @rdev: regulator device + * @is_enabled: status of regulator (on/off) + * @update_bank: bank to control on/off + * @update_reg: register to control on/off + * @update_mask: mask to enable/disable and set mode of regulator + * @update_val: bits holding the regulator current mode + * @update_val_en: bits to set EN pin active (LPn pin deactive) + * normally this means high power mode + * @update_val_en_lp: bits to set EN pin active and LPn pin active + * normally this means low power mode + * @delay: startup delay in ms + */ +struct ab8500_ext_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + bool is_enabled; + u8 update_bank; + u8 update_reg; + u8 update_mask; + u8 update_val; + u8 update_val_en; + u8 update_val_en_lp; +}; + +static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = abx500_mask_and_set_register_interruptible(info->dev, + info->update_bank, info->update_reg, + info->update_mask, info->update_val); + if (ret < 0) + dev_err(rdev_get_dev(info->rdev), + "couldn't set enable bits for regulator\n"); + + info->is_enabled = true; + + dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):" + " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, info->update_val); + + return ret; +} + +static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = abx500_mask_and_set_register_interruptible(info->dev, + info->update_bank, info->update_reg, + info->update_mask, 0x0); + if (ret < 0) + dev_err(rdev_get_dev(info->rdev), + "couldn't set disable bits for regulator\n"); + + info->is_enabled = false; + + dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):" + " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, 0x0); + + return ret; +} + +static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = abx500_get_register_interruptible(info->dev, + info->update_bank, info->update_reg, ®val); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't read 0x%x register\n", info->update_reg); + return ret; + } + + dev_dbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value):" + " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, regval); + + if (regval & info->update_mask) + info->is_enabled = true; + else + info->is_enabled = false; + + return info->is_enabled; +} + +static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + int ret = 0; + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + switch (mode) { + case REGULATOR_MODE_NORMAL: + info->update_val = info->update_val_hp; + break; + case REGULATOR_MODE_IDLE: + info->update_val = info->update_val_lp; + break; + + default: + return -EINVAL; + } + + if (info->is_enabled) { + u8 regval; + + ret = enable(info, ®val); + if (ret < 0) + dev_err(rdev_get_dev(rdev), + "Could not set regulator mode.\n"); + + dev_dbg(rdev_get_dev(rdev), + "%s-set_mode (bank, reg, mask, value): " + "0x%x, 0x%x, 0x%x, 0x%x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, regval); + } + + return ret; +} + +static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev) +{ + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + if (info->update_val == info->update_val_hp) + ret = REGULATOR_MODE_NORMAL; + else if (info->update_val == info->update_val_lp) + ret = REGULATOR_MODE_IDLE; + else + ret = -EINVAL; + + return ret; +} + +static int ab8500_ext_fixed_get_voltage(struct regulator_dev *rdev) +{ + struct regulation_constraints *regu_constraints = rdev->constraints; + + if (regu_constraints == NULL) { + dev_err(rdev_get_dev(rdev), "regulator constraints null pointer\n"); + return -EINVAL; + } + if (regu_constraints->min_uV && regu_constraints->max_uV) { + if (regu_constraints->min_uV == regu_constraints->max_uV) + return regu_constraints->min_uV; + } + return -EINVAL; +} + +static int ab8500_ext_list_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + struct regulation_constraints *regu_constraints = rdev->constraints; + + if (regu_constraints == NULL) { + dev_err(rdev_get_dev(rdev), "regulator constraints null pointer\n"); + return -EINVAL; + } + /* return the uV for the fixed regulators */ + if (regu_constraints->min_uV && regu_constraints->max_uV) { + if (regu_constraints->min_uV == regu_constraints->max_uV) + return regu_constraints->min_uV; + } + return -EINVAL; +} + +static struct regulator_ops ab8500_ext_regulator_ops = { + .enable = ab8500_ext_regulator_enable, + .disable = ab8500_ext_regulator_disable, + .is_enabled = ab8500_ext_regulator_is_enabled, + .set_mode = ab8500_ext_regulator_set_mode, + .get_mode = ab8500_ext_regulator_get_mode, + .get_voltage = ab8500_ext_fixed_get_voltage, + .list_voltage = ab8500_ext_list_voltage, +}; + + +static struct ab8500_ext_regulator_info + ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = { + [AB8500_EXT_SUPPLY1] = { + .desc = { + .name = "VEXTSUPPLY1", + .ops = &ab8500_ext_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_EXT_SUPPLY1, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x04, + .update_reg = 0x08, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_hp = 0x01, + .update_val_lp = 0x03, + .update_val_hw = 0x02, + }, + [AB8500_EXT_SUPPLY2] = { + .desc = { + .name = "VEXTSUPPLY2", + .ops = &ab8500_ext_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_EXT_SUPPLY2, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x04, + .update_reg = 0x08, + .update_mask = 0x0c, + .update_val = 0x04, + .update_val_hp = 0x04, + .update_val_lp = 0x0c, + .update_val_hw = 0x08, + }, + [AB8500_EXT_SUPPLY3] = { + .desc = { + .name = "VEXTSUPPLY3", + .ops = &ab8500_ext_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_EXT_SUPPLY3, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x04, + .update_reg = 0x08, + .update_mask = 0x30, + .update_val = 0x10, + .update_val_en = 0x10, + .update_val_en_lp = 0x30, + }, +}; + +int ab8500_ext_regulator_init(struct platform_device *pdev) +{ + struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); + struct ab8500_platform_data *ppdata; + struct ab8500_regulator_platform_data *pdata; + struct regulator_config config = { }; + int i, err; + + if (!ab8500) { + dev_err(&pdev->dev, "null mfd parent\n"); + return -EINVAL; + } + ppdata = dev_get_platdata(ab8500->dev); + if (!ppdata) { + dev_err(&pdev->dev, "null parent pdata\n"); + return -EINVAL; + } + + pdata = ppdata->regulator; + if (!pdata) { + dev_err(&pdev->dev, "null pdata\n"); + return -EINVAL; + } + + /* make sure the platform data has the correct size */ + if (pdata->num_ext_regulator != ARRAY_SIZE(ab8500_ext_regulator_info)) { + dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); + return -EINVAL; + } + + /* check for AB8500 2.x */ + if (abx500_get_chip_id(&pdev->dev) < 0x30) { + struct ab8500_ext_regulator_info *info; + + /* VextSupply3LPn is inverted on AB8500 2.x */ + info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3]; + info->update_val = 0x30; + info->update_val_en = 0x30; + info->update_val_en_lp = 0x10; + } + + /* register all regulators */ + for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) { + struct ab8500_ext_regulator_info *info = NULL; + + /* assign per-regulator data */ + info = &ab8500_ext_regulator_info[i]; + info->dev = &pdev->dev; + + config.dev = &pdev->dev; + config.init_data = &pdata->ext_regulator[i]; + config.driver_data = info; + + /* register regulator with framework */ + info->rdev = regulator_register(&info->desc, &config); + + if (IS_ERR(info->rdev)) { + err = PTR_ERR(info->rdev); + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + /* when we fail, un-register all earlier regulators */ + while (--i >= 0) { + info = &ab8500_ext_regulator_info[i]; + regulator_unregister(info->rdev); + } + return err; + } + + dev_dbg(rdev_get_dev(info->rdev), + "%s-probed\n", info->desc.name); + } + + return 0; +} + +int ab8500_ext_regulator_exit(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) { + struct ab8500_ext_regulator_info *info = NULL; + info = &ab8500_ext_regulator_info[i]; + + dev_vdbg(rdev_get_dev(info->rdev), + "%s-remove\n", info->desc.name); + + regulator_unregister(info->rdev); + } + + return 0; +} + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Bengt Jonsson "); +MODULE_DESCRIPTION("AB8500 external regulator driver"); +MODULE_ALIAS("platform:ab8500-ext-regulator"); diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 3a1896655557..49746884923d 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -947,6 +947,11 @@ static int ab8500_regulator_probe(struct platform_device *pdev) return err; } + /* register external regulators (before Vaux1, 2 and 3) */ + err = ab8500_ext_regulator_init(pdev); + if (err) + return err; + /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL); @@ -959,7 +964,7 @@ static int ab8500_regulator_probe(struct platform_device *pdev) static int ab8500_regulator_remove(struct platform_device *pdev) { - int i; + int i, err; for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { struct ab8500_regulator_info *info = NULL; @@ -971,6 +976,11 @@ static int ab8500_regulator_remove(struct platform_device *pdev) regulator_unregister(info->regulator); } + /* remove external regulators (after Vaux1, 2 and 3) */ + err = ab8500_ext_regulator_exit(pdev); + if (err) + return err; + return 0; } diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 26792ff360be..4e92e5b879a5 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -10,6 +10,8 @@ #ifndef __LINUX_MFD_AB8500_REGULATOR_H #define __LINUX_MFD_AB8500_REGULATOR_H +#include + /* AB8500 regulators */ enum ab8500_regulator_id { AB8500_LDO_AUX1, @@ -140,11 +142,37 @@ enum ab9540_regulator_reg { AB9540_NUM_REGULATOR_REGISTERS, }; +/* AB8500 external regulators */ +enum ab8500_ext_regulator_id { + AB8500_EXT_SUPPLY1, + AB8500_EXT_SUPPLY2, + AB8500_EXT_SUPPLY3, + AB8500_NUM_EXT_REGULATORS, +}; + +/* AB8500 regulator platform data */ struct ab8500_regulator_platform_data { int num_reg_init; struct ab8500_regulator_reg_init *reg_init; int num_regulator; struct regulator_init_data *regulator; + int num_ext_regulator; + struct regulator_init_data *ext_regulator; }; +/* AB8500 external regulator functions (internal) */ +#ifdef CONFIG_REGULATOR_AB8500_EXT +int ab8500_ext_regulator_init(struct platform_device *pdev); +int ab8500_ext_regulator_exit(struct platform_device *pdev); +#else +inline int ab8500_ext_regulator_init(struct platform_device *pdev) +{ + return 0; +} +inline int ab8500_ext_regulator_exit(struct platform_device *pdev) +{ + return 0; +} +#endif + #endif -- cgit v1.2.3 From 18bc2b39307b45527efc6c84836953c7a8f2181e Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Thu, 28 Mar 2013 16:11:06 +0000 Subject: regulator: ab8500-ext: Add HW request support Support for HW request is added in the external regulator driver. A flag in the board configuration can be set to let HW control the regulator when there is no SW request. This means that the regulator will be put in high power mode when there is a SW request and in HW-request mode otherwise. Signed-off-by: Bengt Jonsson Signed-off-by: Lee Jones Reviewed-by: Mattias NILSSON Reviewed-by: Jonas ABERG Signed-off-by: Mark Brown --- drivers/regulator/ab8500-ext.c | 98 +++++++++++++++++++++++++++++----------- include/linux/regulator/ab8500.h | 4 ++ 2 files changed, 75 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 95008dec5190..21b9bfb0fc5e 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c @@ -28,80 +28,121 @@ * @dev: device pointer * @desc: regulator description * @rdev: regulator device + * @cfg: regulator configuration (extension of regulator FW configuration) * @is_enabled: status of regulator (on/off) * @update_bank: bank to control on/off * @update_reg: register to control on/off * @update_mask: mask to enable/disable and set mode of regulator * @update_val: bits holding the regulator current mode - * @update_val_en: bits to set EN pin active (LPn pin deactive) + * @update_val_hp: bits to set EN pin active (LPn pin deactive) * normally this means high power mode - * @update_val_en_lp: bits to set EN pin active and LPn pin active - * normally this means low power mode - * @delay: startup delay in ms + * @update_val_lp: bits to set EN pin active and LPn pin active + * normally this means low power mode + * @update_val_hw: bits to set regulator pins in HW control + * SysClkReq pins and logic will choose mode */ struct ab8500_ext_regulator_info { struct device *dev; struct regulator_desc desc; struct regulator_dev *rdev; + struct ab8500_ext_regulator_cfg *cfg; bool is_enabled; u8 update_bank; u8 update_reg; u8 update_mask; u8 update_val; - u8 update_val_en; - u8 update_val_en_lp; + u8 update_val_hp; + u8 update_val_lp; + u8 update_val_hw; }; -static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) +static int enable(struct ab8500_ext_regulator_info *info, u8 *regval) { int ret; - struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); - if (info == NULL) { - dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); - return -EINVAL; - } + *regval = info->update_val; + + /* + * To satisfy both HW high power request and SW request, the regulator + * must be on in high power. + */ + if (info->cfg && info->cfg->hwreq) + *regval = info->update_val_hp; ret = abx500_mask_and_set_register_interruptible(info->dev, info->update_bank, info->update_reg, - info->update_mask, info->update_val); + info->update_mask, *regval); if (ret < 0) dev_err(rdev_get_dev(info->rdev), "couldn't set enable bits for regulator\n"); info->is_enabled = true; - dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):" - " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - info->desc.name, info->update_bank, info->update_reg, - info->update_mask, info->update_val); - return ret; } -static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) +static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) { int ret; struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; } + ret = enable(info, ®val); + + dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):" + " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + info->desc.name, info->update_bank, info->update_reg, + info->update_mask, regval); + + return ret; +} + +static int disable(struct ab8500_ext_regulator_info *info, u8 *regval) +{ + int ret; + + *regval = 0x0; + + /* + * Set the regulator in HW request mode if configured + */ + if (info->cfg && info->cfg->hwreq) + *regval = info->update_val_hw; + ret = abx500_mask_and_set_register_interruptible(info->dev, info->update_bank, info->update_reg, - info->update_mask, 0x0); + info->update_mask, *regval); if (ret < 0) dev_err(rdev_get_dev(info->rdev), "couldn't set disable bits for regulator\n"); info->is_enabled = false; + return ret; +} + +static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = disable(info, ®val); + dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):" " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", info->desc.name, info->update_bank, info->update_reg, - info->update_mask, 0x0); + info->update_mask, regval); return ret; } @@ -130,7 +171,8 @@ static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev) info->desc.name, info->update_bank, info->update_reg, info->update_mask, regval); - if (regval & info->update_mask) + if (((regval & info->update_mask) == info->update_val_lp) || + ((regval & info->update_mask) == info->update_val_hp)) info->is_enabled = true; else info->is_enabled = false; @@ -241,7 +283,6 @@ static struct regulator_ops ab8500_ext_regulator_ops = { .list_voltage = ab8500_ext_list_voltage, }; - static struct ab8500_ext_regulator_info ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = { [AB8500_EXT_SUPPLY1] = { @@ -291,8 +332,9 @@ static struct ab8500_ext_regulator_info .update_reg = 0x08, .update_mask = 0x30, .update_val = 0x10, - .update_val_en = 0x10, - .update_val_en_lp = 0x30, + .update_val_hp = 0x10, + .update_val_lp = 0x30, + .update_val_hw = 0x20, }, }; @@ -333,8 +375,8 @@ int ab8500_ext_regulator_init(struct platform_device *pdev) /* VextSupply3LPn is inverted on AB8500 2.x */ info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3]; info->update_val = 0x30; - info->update_val_en = 0x30; - info->update_val_en_lp = 0x10; + info->update_val_hp = 0x30; + info->update_val_lp = 0x10; } /* register all regulators */ @@ -344,6 +386,8 @@ int ab8500_ext_regulator_init(struct platform_device *pdev) /* assign per-regulator data */ info = &ab8500_ext_regulator_info[i]; info->dev = &pdev->dev; + info->cfg = (struct ab8500_ext_regulator_cfg *) + pdata->ext_regulator[i].driver_data; config.dev = &pdev->dev; config.init_data = &pdata->ext_regulator[i]; diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 4e92e5b879a5..cf496e93c0cf 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -143,6 +143,10 @@ enum ab9540_regulator_reg { }; /* AB8500 external regulators */ +struct ab8500_ext_regulator_cfg { + bool hwreq; /* requires hw mode or high power mode */ +}; + enum ab8500_ext_regulator_id { AB8500_EXT_SUPPLY1, AB8500_EXT_SUPPLY2, -- cgit v1.2.3 From 41a06aa738ad889cf96f56024ddf84ecf4a18a6f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Mar 2013 16:11:08 +0000 Subject: regulator: ab8500: Remove USB regulator The USB regulator is controlled by hardware. The software support was only needed for early hardware (ED) which is no longer supported. Signed-off-by: Bengt Jonsson Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 20 -------------------- include/linux/regulator/ab8500.h | 1 - 2 files changed, 21 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 49746884923d..4d88a604efd1 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -488,25 +488,6 @@ static struct ab8500_regulator_info .update_val_idle = 0x82, .update_val_normal = 0x02, }, - - /* - * Regulators with fixed voltage and normal mode - */ - [AB8500_LDO_USB] = { - .desc = { - .name = "LDO-USB", - .ops = &ab8500_regulator_ops, - .type = REGULATOR_VOLTAGE, - .id = AB8500_LDO_USB, - .owner = THIS_MODULE, - .n_voltages = 1, - .min_uV = 3300000, - .enable_time = 150, - }, - .update_bank = 0x03, - .update_reg = 0x82, - .update_mask = 0x03, - }, [AB8500_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", @@ -862,7 +843,6 @@ static struct of_regulator_match ab8500_regulator_matches[] = { { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index cf496e93c0cf..b86e089195ea 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -19,7 +19,6 @@ enum ab8500_regulator_id { AB8500_LDO_AUX3, AB8500_LDO_INTCORE, AB8500_LDO_TVOUT, - AB8500_LDO_USB, AB8500_LDO_AUDIO, AB8500_LDO_ANAMIC1, AB8500_LDO_ANAMIC2, -- cgit v1.2.3 From da0b0c47dcfd92317e2ece4c3434e1f82b55cf8a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Mar 2013 16:11:09 +0000 Subject: regulator: ab8500: Init debug from regulator driver The purpose of this patch is to guarantee that ab8500-debug will record the regulator registers before they are modified by the ab8500 regulator driver. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 10 ++++++++++ include/linux/regulator/ab8500.h | 14 ++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 4d88a604efd1..bf34c4cd6631 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -911,6 +911,11 @@ static int ab8500_regulator_probe(struct platform_device *pdev) return -EINVAL; } + /* initialize debug (initial state is recorded with this call) */ + err = ab8500_regulator_debug_init(pdev); + if (err) + return err; + /* initialize registers */ for (i = 0; i < pdata->num_reg_init; i++) { int id, mask, value; @@ -961,6 +966,11 @@ static int ab8500_regulator_remove(struct platform_device *pdev) if (err) return err; + /* remove regulator debug */ + err = ab8500_regulator_debug_exit(pdev); + if (err) + return err; + return 0; } diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index b86e089195ea..592a3f3994c0 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -178,4 +178,18 @@ inline int ab8500_ext_regulator_exit(struct platform_device *pdev) } #endif +#ifdef CONFIG_REGULATOR_AB8500_DEBUG +int ab8500_regulator_debug_init(struct platform_device *pdev); +int ab8500_regulator_debug_exit(struct platform_device *pdev); +#else +static inline int ab8500_regulator_debug_init(struct platform_device *pdev) +{ + return 0; +} +static inline int ab8500_regulator_debug_exit(struct platform_device *pdev) +{ + return 0; +} +#endif + #endif -- cgit v1.2.3 From 547f384f33dbd6171607f925ab246e25e315961e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Mar 2013 16:11:14 +0000 Subject: regulator: ab8500: add support for ab8505 To obtain full AB8505 regulator support, the AB8500 regulator driver first needs to know its register layout and their initialisation values for each. That information is provided via a couple of large data structures which we provide here. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500-regulators.c | 511 ++++++++++++++++++++- arch/arm/mach-ux500/board-mop500-regulators.h | 1 + drivers/regulator/ab8500.c | 617 ++++++++++++++++++++++++++ include/linux/regulator/ab8500.h | 75 +++- 4 files changed, 1195 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index c1173a161a04..816151903d46 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -5,6 +5,7 @@ * * Authors: Sundar Iyer * Bengt Jonsson + * Daniel Willerud * * MOP500 board specific initialization for regulators */ @@ -99,6 +100,27 @@ static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { REGULATOR_SUPPLY("vmmc", "sdi0"), }; +static struct regulator_consumer_supply ab8505_vaux4_consumers[] = { +}; + +static struct regulator_consumer_supply ab8505_vaux5_consumers[] = { +}; + +static struct regulator_consumer_supply ab8505_vaux6_consumers[] = { +}; + +static struct regulator_consumer_supply ab8505_vaux8_consumers[] = { + /* AB8500 audio codec device */ + REGULATOR_SUPPLY("v-aux8", NULL), +}; + +static struct regulator_consumer_supply ab8505_vadc_consumers[] = { + /* Internal general-purpose ADC */ + REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), + /* ADC for charger */ + REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"), +}; + static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { /* TV-out DENC supply */ REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), @@ -133,6 +155,11 @@ static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"), }; +static struct regulator_consumer_supply ab8505_usb_consumers[] = { + /* HS USB OTG physical interface */ + REGULATOR_SUPPLY("v-ape", NULL), +}; + static struct regulator_consumer_supply ab8500_vana_consumers[] = { /* External displays, connector on board, 1v8 power supply */ REGULATOR_SUPPLY("vsmps2", "mcde.0"), @@ -469,6 +496,450 @@ static struct regulator_init_data ab8500_ext_regulators[] = { }, }; +/* ab8505 regulator register initialization */ +static struct ab8500_regulator_reg_init ab8505_reg_init[] = { + /* + * VarmRequestCtrl + * VsmpsCRequestCtrl + * VsmpsARequestCtrl + * VsmpsBRequestCtrl + */ + INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL1, 0x00, 0x00), + /* + * VsafeRequestCtrl + * VpllRequestCtrl + * VanaRequestCtrl = HP/LP depending on VxRequest + */ + INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL2, 0x30, 0x00), + /* + * Vaux1RequestCtrl = HP/LP depending on VxRequest + * Vaux2RequestCtrl = HP/LP depending on VxRequest + */ + INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL3, 0xf0, 0x00), + /* + * Vaux3RequestCtrl = HP/LP depending on VxRequest + * SwHPReq = Control through SWValid disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL4, 0x07, 0x00), + /* + * VsmpsASysClkReq1HPValid + * VsmpsBSysClkReq1HPValid + * VsafeSysClkReq1HPValid + * VanaSysClkReq1HPValid = disabled + * VpllSysClkReq1HPValid + * Vaux1SysClkReq1HPValid = disabled + * Vaux2SysClkReq1HPValid = disabled + * Vaux3SysClkReq1HPValid = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), + /* + * VsmpsCSysClkReq1HPValid + * VarmSysClkReq1HPValid + * VbbSysClkReq1HPValid + * VsmpsMSysClkReq1HPValid + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID2, 0x00, 0x00), + /* + * VsmpsAHwHPReq1Valid + * VsmpsBHwHPReq1Valid + * VsafeHwHPReq1Valid + * VanaHwHPReq1Valid = disabled + * VpllHwHPReq1Valid + * Vaux1HwHPreq1Valid = disabled + * Vaux2HwHPReq1Valid = disabled + * Vaux3HwHPReqValid = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID1, 0xe8, 0x00), + /* + * VsmpsMHwHPReq1Valid + */ + INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID2, 0x00, 0x00), + /* + * VsmpsAHwHPReq2Valid + * VsmpsBHwHPReq2Valid + * VsafeHwHPReq2Valid + * VanaHwHPReq2Valid = disabled + * VpllHwHPReq2Valid + * Vaux1HwHPReq2Valid = disabled + * Vaux2HwHPReq2Valid = disabled + * Vaux3HwHPReq2Valid = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID1, 0xe8, 0x00), + /* + * VsmpsMHwHPReq2Valid + */ + INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID2, 0x00, 0x00), + /** + * VsmpsCSwHPReqValid + * VarmSwHPReqValid + * VsmpsASwHPReqValid + * VsmpsBSwHPReqValid + * VsafeSwHPReqValid + * VanaSwHPReqValid + * VanaSwHPReqValid = disabled + * VpllSwHPReqValid + * Vaux1SwHPReqValid = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID1, 0xa0, 0x00), + /* + * Vaux2SwHPReqValid = disabled + * Vaux3SwHPReqValid = disabled + * VsmpsMSwHPReqValid + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID2, 0x03, 0x00), + /* + * SysClkReq2Valid1 = SysClkReq2 controlled + * SysClkReq3Valid1 = disabled + * SysClkReq4Valid1 = SysClkReq4 controlled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID1, 0x0e, 0x0a), + /* + * SysClkReq2Valid2 = disabled + * SysClkReq3Valid2 = disabled + * SysClkReq4Valid2 = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID2, 0x0e, 0x00), + /* + * Vaux4SwHPReqValid + * Vaux4HwHPReq2Valid + * Vaux4HwHPReq1Valid + * Vaux4SysClkReq1HPValid + */ + INIT_REGULATOR_REGISTER(AB8505_REGUVAUX4REQVALID, 0x00, 0x00), + /* + * VadcEna = disabled + * VintCore12Ena = disabled + * VintCore12Sel = 1.25 V + * VintCore12LP = inactive (HP) + * VadcLP = inactive (HP) + */ + INIT_REGULATOR_REGISTER(AB8505_REGUMISC1, 0xfe, 0x10), + /* + * VaudioEna = disabled + * Vaux8Ena = disabled + * Vamic1Ena = disabled + * Vamic2Ena = disabled + */ + INIT_REGULATOR_REGISTER(AB8505_VAUDIOSUPPLY, 0x1e, 0x00), + /* + * Vamic1_dzout = high-Z when Vamic1 is disabled + * Vamic2_dzout = high-Z when Vamic2 is disabled + */ + INIT_REGULATOR_REGISTER(AB8505_REGUCTRL1VAMIC, 0x03, 0x00), + /* + * VsmpsARegu + * VsmpsASelCtrl + * VsmpsAAutoMode + * VsmpsAPWMMode + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSAREGU, 0x00, 0x00), + /* + * VsmpsBRegu + * VsmpsBSelCtrl + * VsmpsBAutoMode + * VsmpsBPWMMode + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSBREGU, 0x00, 0x00), + /* + * VsafeRegu + * VsafeSelCtrl + * VsafeAutoMode + * VsafePWMMode + */ + INIT_REGULATOR_REGISTER(AB8505_VSAFEREGU, 0x00, 0x00), + /* + * VPll = Hw controlled (NOTE! PRCMU bits) + * VanaRegu = force off + */ + INIT_REGULATOR_REGISTER(AB8505_VPLLVANAREGU, 0x0f, 0x02), + /* + * VextSupply1Regu = force OFF (OTP_ExtSupply12LPnPolarity 1) + * VextSupply2Regu = force OFF (OTP_ExtSupply12LPnPolarity 1) + * VextSupply3Regu = force OFF (OTP_ExtSupply3LPnPolarity 0) + * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 + * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 + */ + INIT_REGULATOR_REGISTER(AB8505_EXTSUPPLYREGU, 0xff, 0x30), + /* + * Vaux1Regu = force HP + * Vaux2Regu = force off + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX12REGU, 0x0f, 0x01), + /* + * Vaux3Regu = force off + */ + INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3REGU, 0x03, 0x00), + /* + * VsmpsASel1 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL1, 0x00, 0x00), + /* + * VsmpsASel2 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL2, 0x00, 0x00), + /* + * VsmpsASel3 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL3, 0x00, 0x00), + /* + * VsmpsBSel1 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL1, 0x00, 0x00), + /* + * VsmpsBSel2 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL2, 0x00, 0x00), + /* + * VsmpsBSel3 + */ + INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL3, 0x00, 0x00), + /* + * VsafeSel1 + */ + INIT_REGULATOR_REGISTER(AB8505_VSAFESEL1, 0x00, 0x00), + /* + * VsafeSel2 + */ + INIT_REGULATOR_REGISTER(AB8505_VSAFESEL2, 0x00, 0x00), + /* + * VsafeSel3 + */ + INIT_REGULATOR_REGISTER(AB8505_VSAFESEL3, 0x00, 0x00), + /* + * Vaux1Sel = 2.8 V + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX1SEL, 0x0f, 0x0C), + /* + * Vaux2Sel = 2.9 V + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX2SEL, 0x0f, 0x0d), + /* + * Vaux3Sel = 2.91 V + */ + INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3SEL, 0x07, 0x07), + /* + * Vaux4RequestCtrl + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX4REQCTRL, 0x00, 0x00), + /* + * Vaux4Regu + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX4REGU, 0x00, 0x00), + /* + * Vaux4Sel + */ + INIT_REGULATOR_REGISTER(AB8505_VAUX4SEL, 0x00, 0x00), + /* + * Vaux1Disch = short discharge time + * Vaux2Disch = short discharge time + * Vaux3Disch = short discharge time + * Vintcore12Disch = short discharge time + * VTVoutDisch = short discharge time + * VaudioDisch = short discharge time + */ + INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH, 0xfc, 0x00), + /* + * VanaDisch = short discharge time + * Vaux8PullDownEna = pulldown disabled when Vaux8 is disabled + * Vaux8Disch = short discharge time + */ + INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH2, 0x16, 0x00), + /* + * Vaux4Disch = short discharge time + */ + INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH3, 0x01, 0x00), + /* + * Vaux5Sel + * Vaux5LP + * Vaux5Ena + * Vaux5Disch + * Vaux5DisSfst + * Vaux5DisPulld + */ + INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX5, 0x00, 0x00), + /* + * Vaux6Sel + * Vaux6LP + * Vaux6Ena + * Vaux6DisPulld + */ + INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX6, 0x00, 0x00), +}; + +struct regulator_init_data ab8505_regulators[AB8505_NUM_REGULATORS] = { + /* supplies to the display/camera */ + [AB8505_LDO_AUX1] = { + .constraints = { + .name = "V-DISPLAY", + .min_uV = 2800000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .boot_on = 1, /* display is on at boot */ + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), + .consumer_supplies = ab8500_vaux1_consumers, + }, + /* supplies to the on-board eMMC */ + [AB8505_LDO_AUX2] = { + .constraints = { + .name = "V-eMMC1", + .min_uV = 1100000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), + .consumer_supplies = ab8500_vaux2_consumers, + }, + /* supply for VAUX3, supplies to SDcard slots */ + [AB8505_LDO_AUX3] = { + .constraints = { + .name = "V-MMC-SD", + .min_uV = 1100000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), + .consumer_supplies = ab8500_vaux3_consumers, + }, + /* supply for VAUX4, supplies to NFC and standalone secure element */ + [AB8505_LDO_AUX4] = { + .constraints = { + .name = "V-NFC-SE", + .min_uV = 1100000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux4_consumers), + .consumer_supplies = ab8505_vaux4_consumers, + }, + /* supply for VAUX5, supplies to TBD */ + [AB8505_LDO_AUX5] = { + .constraints = { + .name = "V-AUX5", + .min_uV = 1050000, + .max_uV = 2790000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux5_consumers), + .consumer_supplies = ab8505_vaux5_consumers, + }, + /* supply for VAUX6, supplies to TBD */ + [AB8505_LDO_AUX6] = { + .constraints = { + .name = "V-AUX6", + .min_uV = 1050000, + .max_uV = 2790000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux6_consumers), + .consumer_supplies = ab8505_vaux6_consumers, + }, + /* supply for gpadc, ADC LDO */ + [AB8505_LDO_ADC] = { + .constraints = { + .name = "V-ADC", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_vadc_consumers), + .consumer_supplies = ab8505_vadc_consumers, + }, + /* supply for ab8500-vaudio, VAUDIO LDO */ + [AB8505_LDO_AUDIO] = { + .constraints = { + .name = "V-AUD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers), + .consumer_supplies = ab8500_vaud_consumers, + }, + /* supply for v-anamic1 VAMic1-LDO */ + [AB8505_LDO_ANAMIC1] = { + .constraints = { + .name = "V-AMIC1", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers), + .consumer_supplies = ab8500_vamic1_consumers, + }, + /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ + [AB8505_LDO_ANAMIC2] = { + .constraints = { + .name = "V-AMIC2", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers), + .consumer_supplies = ab8500_vamic2_consumers, + }, + /* supply for v-aux8, VAUX8 LDO */ + [AB8505_LDO_AUX8] = { + .constraints = { + .name = "V-AUX8", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux8_consumers), + .consumer_supplies = ab8505_vaux8_consumers, + }, + /* supply for v-intcore12, VINTCORE12 LDO */ + [AB8505_LDO_INTCORE] = { + .constraints = { + .name = "V-INTCORE", + .min_uV = 1250000, + .max_uV = 1350000, + .input_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE | + REGULATOR_CHANGE_DRMS, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), + .consumer_supplies = ab8500_vintcore_consumers, + }, + /* supply for LDO USB */ + [AB8505_LDO_USB] = { + .constraints = { + .name = "V-USB", + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_IDLE, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8505_usb_consumers), + .consumer_supplies = ab8505_usb_consumers, + }, + /* supply for U8500 CSI-DSI, VANA LDO */ + [AB8505_LDO_ANA] = { + .constraints = { + .name = "V-CSI-DSI", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), + .consumer_supplies = ab8500_vana_consumers, + }, +}; + struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { .reg_init = ab8500_reg_init, .num_reg_init = ARRAY_SIZE(ab8500_reg_init), @@ -478,18 +949,39 @@ struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { .num_ext_regulator = ARRAY_SIZE(ab8500_ext_regulators), }; +/* Use the AB8500 init settings for AB8505 as they are the same right now */ +struct ab8500_regulator_platform_data ab8505_regulator_plat_data = { + .reg_init = ab8505_reg_init, + .num_reg_init = ARRAY_SIZE(ab8505_reg_init), + .regulator = ab8505_regulators, + .num_regulator = ARRAY_SIZE(ab8505_regulators), +}; + static void ab8500_modify_reg_init(int id, u8 mask, u8 value) { int i; - for (i = ARRAY_SIZE(ab8500_reg_init) - 1; i >= 0; i--) { - if (ab8500_reg_init[i].id == id) { - u8 initval = ab8500_reg_init[i].value; - initval = (initval & ~mask) | (value & mask); - ab8500_reg_init[i].value = initval; + if (cpu_is_u8520()) { + for (i = ARRAY_SIZE(ab8505_reg_init) - 1; i >= 0; i--) { + if (ab8505_reg_init[i].id == id) { + u8 initval = ab8505_reg_init[i].value; + initval = (initval & ~mask) | (value & mask); + ab8505_reg_init[i].value = initval; - BUG_ON(mask & ~ab8500_reg_init[i].mask); - return; + BUG_ON(mask & ~ab8505_reg_init[i].mask); + return; + } + } + } else { + for (i = ARRAY_SIZE(ab8500_reg_init) - 1; i >= 0; i--) { + if (ab8500_reg_init[i].id == id) { + u8 initval = ab8500_reg_init[i].value; + initval = (initval & ~mask) | (value & mask); + ab8500_reg_init[i].value = initval; + + BUG_ON(mask & ~ab8500_reg_init[i].mask); + return; + } } } @@ -511,6 +1003,11 @@ void mop500_regulator_init(void) regulator->constraints.state_standby.disabled = 1; } + if (cpu_is_u8520()) { + /* Vaux2 initialized to be on */ + ab8500_modify_reg_init(AB8505_VAUX12REGU, 0x0f, 0x05); + } + /* * Handle AB8500_EXT_SUPPLY2 on HREFP_V20_V50 boards (do it for * all HREFP_V20 boards) diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 3d4c412d0b7a..9bece38fe933 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h @@ -15,6 +15,7 @@ #include extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data; +extern struct ab8500_regulator_platform_data ab8505_regulator_plat_data; extern struct regulator_init_data tps61052_regulator; extern struct regulator_init_data gpio_en_3v3_regulator; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 9de3a211b0b4..1ab0f8a7c862 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -5,11 +5,15 @@ * * Authors: Sundar Iyer for ST-Ericsson * Bengt Jonsson for ST-Ericsson + * Daniel Willerud for ST-Ericsson * * AB8500 peripheral regulators * * AB8500 supports the following regulators: * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA + * + * AB8505 supports the following regulators: + * VAUX1/2/3/4/5/6, VINTCORE, VADC, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA */ #include #include @@ -92,6 +96,17 @@ static const unsigned int ldo_vaux3_voltages[] = { 2910000, }; +static const int ldo_vaux56_voltages[] = { + 1800000, + 1050000, + 1100000, + 1200000, + 1500000, + 2200000, + 2500000, + 2790000, +}; + static const unsigned int ldo_vintcore_voltages[] = { 1200000, 1225000, @@ -589,6 +604,313 @@ static struct ab8500_regulator_info }, }; +/* AB8505 regulator information */ +static struct ab8500_regulator_info + ab8505_regulator_info[AB8505_NUM_REGULATORS] = { + /* + * Variable Voltage Regulators + * name, min mV, max mV, + * update bank, reg, mask, enable val + * volt bank, reg, mask, table, table length + */ + [AB8505_LDO_AUX1] = { + .desc = { + .name = "LDO-AUX1", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX1, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x1f, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8505_LDO_AUX2] = { + .desc = { + .name = "LDO-AUX2", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX2, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x0c, + .update_val = 0x04, + .update_val_idle = 0x0c, + .update_val_normal = 0x04, + .voltage_bank = 0x04, + .voltage_reg = 0x20, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8505_LDO_AUX3] = { + .desc = { + .name = "LDO-AUX3", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX3, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x0a, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x21, + .voltage_mask = 0x07, + .voltages = ldo_vaux3_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux3_voltages), + }, + [AB8505_LDO_AUX4] = { + .desc = { + .name = "LDO-AUX4", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB9540_LDO_AUX4, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .load_lp_uA = 5000, + /* values for Vaux4Regu register */ + .update_bank = 0x04, + .update_reg = 0x2e, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + /* values for Vaux4SEL register */ + .voltage_bank = 0x04, + .voltage_reg = 0x2f, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8505_LDO_AUX5] = { + .desc = { + .name = "LDO-AUX5", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_LDO_AUX5, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux56_voltages), + }, + .min_uV = 1050000, + .max_uV = 2790000, + .load_lp_uA = 2000, + /* values for CtrlVaux5 register */ + .update_bank = 0x01, + .update_reg = 0x55, + .update_mask = 0x08, + .update_val = 0x00, + .update_val_idle = 0x01, + .update_val_normal = 0x00, + .voltage_bank = 0x01, + .voltage_reg = 0x55, + .voltage_mask = 0x07, + .voltages = ldo_vaux56_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux56_voltages), + }, + [AB8505_LDO_AUX6] = { + .desc = { + .name = "LDO-AUX6", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_LDO_AUX6, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux56_voltages), + }, + .min_uV = 1050000, + .max_uV = 2790000, + .load_lp_uA = 2000, + /* values for CtrlVaux6 register */ + .update_bank = 0x01, + .update_reg = 0x56, + .update_mask = 0x08, + .update_val = 0x00, + .update_val_idle = 0x01, + .update_val_normal = 0x00, + .voltage_bank = 0x01, + .voltage_reg = 0x56, + .voltage_mask = 0x07, + .voltages = ldo_vaux56_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux56_voltages), + }, + [AB8505_LDO_INTCORE] = { + .desc = { + .name = "LDO-INTCORE", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_INTCORE, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), + }, + .min_uV = 1100000, + .max_uV = 3300000, + .load_lp_uA = 5000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x44, + .update_val = 0x04, + .update_val_idle = 0x44, + .update_val_normal = 0x04, + .voltage_bank = 0x03, + .voltage_reg = 0x80, + .voltage_mask = 0x38, + .voltages = ldo_vintcore_voltages, + .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), + .voltage_shift = 3, + }, + + /* + * Fixed Voltage Regulators + * name, fixed mV, + * update bank, reg, mask, enable val + */ + [AB8505_LDO_ADC] = { + .desc = { + .name = "LDO-ADC", + .ops = &ab8500_regulator_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_LDO_ADC, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .delay = 10000, + .fixed_uV = 2000000, + .load_lp_uA = 1000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x82, + .update_val = 0x02, + .update_val_idle = 0x82, + .update_val_normal = 0x02, + }, + [AB8505_LDO_USB] = { + .desc = { + .name = "LDO-USB", + .ops = &ab8500_regulator_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB9540_LDO_USB, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 3300000, + .update_bank = 0x03, + .update_reg = 0x82, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + }, + [AB8505_LDO_AUDIO] = { + .desc = { + .name = "LDO-AUDIO", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUDIO, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2000000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x02, + .update_val = 0x02, + }, + [AB8505_LDO_ANAMIC1] = { + .desc = { + .name = "LDO-ANAMIC1", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC1, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2050000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x08, + .update_val = 0x08, + }, + [AB8505_LDO_ANAMIC2] = { + .desc = { + .name = "LDO-ANAMIC2", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC2, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 2050000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x10, + .update_val = 0x10, + }, + [AB8505_LDO_AUX8] = { + .desc = { + .name = "LDO-AUX8", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_LDO_AUX8, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1800000, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x04, + .update_val = 0x04, + }, + /* + * Regulators with fixed voltage and normal/idle modes + */ + [AB8505_LDO_ANA] = { + .desc = { + .name = "LDO-ANA", + .ops = &ab8500_regulator_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANA, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1200000, + .load_lp_uA = 1000, + .update_bank = 0x04, + .update_reg = 0x06, + .update_mask = 0x0c, + .update_val = 0x04, + .update_val_idle = 0x0c, + .update_val_normal = 0x04, + }, +}; + /* AB9540 regulator information */ static struct ab8500_regulator_info ab9540_regulator_info[AB9540_NUM_REGULATORS] = { @@ -1031,6 +1353,276 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), }; +/* AB8505 register init */ +static struct ab8500_reg_init ab8505_reg_init[] = { + /* + * 0x03, VarmRequestCtrl + * 0x0c, VsmpsCRequestCtrl + * 0x30, VsmpsARequestCtrl + * 0xc0, VsmpsBRequestCtrl + */ + REG_INIT(AB8505_REGUREQUESTCTRL1, 0x03, 0x03, 0xff), + /* + * 0x03, VsafeRequestCtrl + * 0x0c, VpllRequestCtrl + * 0x30, VanaRequestCtrl + */ + REG_INIT(AB8505_REGUREQUESTCTRL2, 0x03, 0x04, 0x3f), + /* + * 0x30, Vaux1RequestCtrl + * 0xc0, Vaux2RequestCtrl + */ + REG_INIT(AB8505_REGUREQUESTCTRL3, 0x03, 0x05, 0xf0), + /* + * 0x03, Vaux3RequestCtrl + * 0x04, SwHPReq + */ + REG_INIT(AB8505_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), + /* + * 0x01, VsmpsASysClkReq1HPValid + * 0x02, VsmpsBSysClkReq1HPValid + * 0x04, VsafeSysClkReq1HPValid + * 0x08, VanaSysClkReq1HPValid + * 0x10, VpllSysClkReq1HPValid + * 0x20, Vaux1SysClkReq1HPValid + * 0x40, Vaux2SysClkReq1HPValid + * 0x80, Vaux3SysClkReq1HPValid + */ + REG_INIT(AB8505_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff), + /* + * 0x01, VsmpsCSysClkReq1HPValid + * 0x02, VarmSysClkReq1HPValid + * 0x04, VbbSysClkReq1HPValid + * 0x08, VsmpsMSysClkReq1HPValid + */ + REG_INIT(AB8505_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x0f), + /* + * 0x01, VsmpsAHwHPReq1Valid + * 0x02, VsmpsBHwHPReq1Valid + * 0x04, VsafeHwHPReq1Valid + * 0x08, VanaHwHPReq1Valid + * 0x10, VpllHwHPReq1Valid + * 0x20, Vaux1HwHPReq1Valid + * 0x40, Vaux2HwHPReq1Valid + * 0x80, Vaux3HwHPReq1Valid + */ + REG_INIT(AB8505_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff), + /* + * 0x08, VsmpsMHwHPReq1Valid + */ + REG_INIT(AB8505_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x08), + /* + * 0x01, VsmpsAHwHPReq2Valid + * 0x02, VsmpsBHwHPReq2Valid + * 0x04, VsafeHwHPReq2Valid + * 0x08, VanaHwHPReq2Valid + * 0x10, VpllHwHPReq2Valid + * 0x20, Vaux1HwHPReq2Valid + * 0x40, Vaux2HwHPReq2Valid + * 0x80, Vaux3HwHPReq2Valid + */ + REG_INIT(AB8505_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff), + /* + * 0x08, VsmpsMHwHPReq2Valid + */ + REG_INIT(AB8505_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x08), + /* + * 0x01, VsmpsCSwHPReqValid + * 0x02, VarmSwHPReqValid + * 0x04, VsmpsASwHPReqValid + * 0x08, VsmpsBSwHPReqValid + * 0x10, VsafeSwHPReqValid + * 0x20, VanaSwHPReqValid + * 0x40, VpllSwHPReqValid + * 0x80, Vaux1SwHPReqValid + */ + REG_INIT(AB8505_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff), + /* + * 0x01, Vaux2SwHPReqValid + * 0x02, Vaux3SwHPReqValid + * 0x20, VsmpsMSwHPReqValid + */ + REG_INIT(AB8505_REGUSWHPREQVALID2, 0x03, 0x0e, 0x23), + /* + * 0x02, SysClkReq2Valid1 + * 0x04, SysClkReq3Valid1 + * 0x08, SysClkReq4Valid1 + */ + REG_INIT(AB8505_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0x0e), + /* + * 0x02, SysClkReq2Valid2 + * 0x04, SysClkReq3Valid2 + * 0x08, SysClkReq4Valid2 + */ + REG_INIT(AB8505_REGUSYSCLKREQVALID2, 0x03, 0x10, 0x0e), + /* + * 0x01, Vaux4SwHPReqValid + * 0x02, Vaux4HwHPReq2Valid + * 0x04, Vaux4HwHPReq1Valid + * 0x08, Vaux4SysClkReq1HPValid + */ + REG_INIT(AB8505_REGUVAUX4REQVALID, 0x03, 0x11, 0x0f), + /* + * 0x02, VadcEna + * 0x04, VintCore12Ena + * 0x38, VintCore12Sel + * 0x40, VintCore12LP + * 0x80, VadcLP + */ + REG_INIT(AB8505_REGUMISC1, 0x03, 0x80, 0xfe), + /* + * 0x02, VaudioEna + * 0x04, VdmicEna + * 0x08, Vamic1Ena + * 0x10, Vamic2Ena + */ + REG_INIT(AB8505_VAUDIOSUPPLY, 0x03, 0x83, 0x1e), + /* + * 0x01, Vamic1_dzout + * 0x02, Vamic2_dzout + */ + REG_INIT(AB8505_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), + /* + * 0x03, VsmpsARegu + * 0x0c, VsmpsASelCtrl + * 0x10, VsmpsAAutoMode + * 0x20, VsmpsAPWMMode + */ + REG_INIT(AB8505_VSMPSAREGU, 0x04, 0x03, 0x3f), + /* + * 0x03, VsmpsBRegu + * 0x0c, VsmpsBSelCtrl + * 0x10, VsmpsBAutoMode + * 0x20, VsmpsBPWMMode + */ + REG_INIT(AB8505_VSMPSBREGU, 0x04, 0x04, 0x3f), + /* + * 0x03, VsafeRegu + * 0x0c, VsafeSelCtrl + * 0x10, VsafeAutoMode + * 0x20, VsafePWMMode + */ + REG_INIT(AB8505_VSAFEREGU, 0x04, 0x05, 0x3f), + /* + * 0x03, VpllRegu (NOTE! PRCMU register bits) + * 0x0c, VanaRegu + */ + REG_INIT(AB8505_VPLLVANAREGU, 0x04, 0x06, 0x0f), + /* + * 0x03, VextSupply1Regu + * 0x0c, VextSupply2Regu + * 0x30, VextSupply3Regu + * 0x40, ExtSupply2Bypass + * 0x80, ExtSupply3Bypass + */ + REG_INIT(AB8505_EXTSUPPLYREGU, 0x04, 0x08, 0xff), + /* + * 0x03, Vaux1Regu + * 0x0c, Vaux2Regu + */ + REG_INIT(AB8505_VAUX12REGU, 0x04, 0x09, 0x0f), + /* + * 0x0f, Vaux3Regu + */ + REG_INIT(AB8505_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f), + /* + * 0x3f, VsmpsASel1 + */ + REG_INIT(AB8505_VSMPSASEL1, 0x04, 0x13, 0x3f), + /* + * 0x3f, VsmpsASel2 + */ + REG_INIT(AB8505_VSMPSASEL2, 0x04, 0x14, 0x3f), + /* + * 0x3f, VsmpsASel3 + */ + REG_INIT(AB8505_VSMPSASEL3, 0x04, 0x15, 0x3f), + /* + * 0x3f, VsmpsBSel1 + */ + REG_INIT(AB8505_VSMPSBSEL1, 0x04, 0x17, 0x3f), + /* + * 0x3f, VsmpsBSel2 + */ + REG_INIT(AB8505_VSMPSBSEL2, 0x04, 0x18, 0x3f), + /* + * 0x3f, VsmpsBSel3 + */ + REG_INIT(AB8505_VSMPSBSEL3, 0x04, 0x19, 0x3f), + /* + * 0x7f, VsafeSel1 + */ + REG_INIT(AB8505_VSAFESEL1, 0x04, 0x1b, 0x7f), + /* + * 0x3f, VsafeSel2 + */ + REG_INIT(AB8505_VSAFESEL2, 0x04, 0x1c, 0x7f), + /* + * 0x3f, VsafeSel3 + */ + REG_INIT(AB8505_VSAFESEL3, 0x04, 0x1d, 0x7f), + /* + * 0x0f, Vaux1Sel + */ + REG_INIT(AB8505_VAUX1SEL, 0x04, 0x1f, 0x0f), + /* + * 0x0f, Vaux2Sel + */ + REG_INIT(AB8505_VAUX2SEL, 0x04, 0x20, 0x0f), + /* + * 0x07, Vaux3Sel + * 0x30, VRF1Sel + */ + REG_INIT(AB8505_VRF1VAUX3SEL, 0x04, 0x21, 0x37), + /* + * 0x03, Vaux4RequestCtrl + */ + REG_INIT(AB8505_VAUX4REQCTRL, 0x04, 0x2d, 0x03), + /* + * 0x03, Vaux4Regu + */ + REG_INIT(AB8505_VAUX4REGU, 0x04, 0x2e, 0x03), + /* + * 0x0f, Vaux4Sel + */ + REG_INIT(AB8505_VAUX4SEL, 0x04, 0x2f, 0x0f), + /* + * 0x04, Vaux1Disch + * 0x08, Vaux2Disch + * 0x10, Vaux3Disch + * 0x20, Vintcore12Disch + * 0x40, VTVoutDisch + * 0x80, VaudioDisch + */ + REG_INIT(AB8505_REGUCTRLDISCH, 0x04, 0x43, 0xfc), + /* + * 0x02, VanaDisch + * 0x04, VdmicPullDownEna + * 0x10, VdmicDisch + */ + REG_INIT(AB8505_REGUCTRLDISCH2, 0x04, 0x44, 0x16), + /* + * 0x01, Vaux4Disch + */ + REG_INIT(AB8505_REGUCTRLDISCH3, 0x04, 0x48, 0x01), + /* + * 0x07, Vaux5Sel + * 0x08, Vaux5LP + * 0x10, Vaux5Ena + * 0x20, Vaux5Disch + * 0x40, Vaux5DisSfst + * 0x80, Vaux5DisPulld + */ + REG_INIT(AB8505_CTRLVAUX5, 0x01, 0x55, 0xff), + /* + * 0x07, Vaux6Sel + * 0x08, Vaux6LP + * 0x10, Vaux6Ena + * 0x80, Vaux6DisPulld + */ + REG_INIT(AB8505_CTRLVAUX6, 0x01, 0x56, 0x9f), +}; + /* AB9540 register init */ static struct ab8500_reg_init ab9540_reg_init[] = { /* @@ -1396,6 +1988,22 @@ static struct of_regulator_match ab8500_regulator_match[] = { { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; +static struct of_regulator_match ab8505_regulator_match[] = { + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8505_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8505_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8505_LDO_AUX3, }, + { .name = "ab8500_ldo_aux4", .driver_data = (void *) AB8505_LDO_AUX4, }, + { .name = "ab8500_ldo_aux5", .driver_data = (void *) AB8505_LDO_AUX5, }, + { .name = "ab8500_ldo_aux6", .driver_data = (void *) AB8505_LDO_AUX6, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8505_LDO_INTCORE, }, + { .name = "ab8500_ldo_adc", .driver_data = (void *) AB8505_LDO_ADC, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8505_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8505_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_aux8", .driver_data = (void *) AB8505_LDO_AUX8, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8505_LDO_ANA, }, +}; + static struct of_regulator_match ab9540_regulator_match[] = { { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB9540_LDO_AUX1, }, { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB9540_LDO_AUX2, }, @@ -1450,6 +2058,11 @@ static int ab8500_regulator_probe(struct platform_device *pdev) reg_init_size = AB9540_NUM_REGULATOR_REGISTERS; match = ab9540_regulator_match; match_size = ARRAY_SIZE(ab9540_regulator_match) + } else if (is_ab8505(ab8500)) { + regulator_info = ab8505_regulator_info; + regulator_info_size = ARRAY_SIZE(ab8505_regulator_info); + reg_init = ab8505_reg_init; + reg_init_size = AB8505_NUM_REGULATOR_REGISTERS; } else { regulator_info = ab8500_regulator_info; regulator_info_size = ARRAY_SIZE(ab8500_regulator_info); @@ -1543,6 +2156,9 @@ static int ab8500_regulator_remove(struct platform_device *pdev) if (is_ab9540(ab8500)) { regulator_info = ab9540_regulator_info; regulator_info_size = ARRAY_SIZE(ab9540_regulator_info); + } else if (is_ab8505(ab8500)) { + regulator_info = ab8505_regulator_info; + regulator_info_size = ARRAY_SIZE(ab8505_regulator_info); } else { regulator_info = ab8500_regulator_info; regulator_info_size = ARRAY_SIZE(ab8500_regulator_info); @@ -1601,5 +2217,6 @@ module_exit(ab8500_regulator_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sundar Iyer "); MODULE_AUTHOR("Bengt Jonsson "); +MODULE_AUTHOR("Daniel Willerud "); MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC"); MODULE_ALIAS("platform:ab8500-regulator"); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 592a3f3994c0..9a7cf97e5040 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -5,6 +5,7 @@ * * Authors: Sundar Iyer for ST-Ericsson * Bengt Jonsson for ST-Ericsson + * Daniel Willerud for ST-Ericsson */ #ifndef __LINUX_MFD_AB8500_REGULATOR_H @@ -27,7 +28,28 @@ enum ab8500_regulator_id { AB8500_NUM_REGULATORS, }; -/* AB9450 regulators */ +/* AB8505 regulators */ +enum ab8505_regulator_id { + AB8505_LDO_AUX1, + AB8505_LDO_AUX2, + AB8505_LDO_AUX3, + AB8505_LDO_AUX4, + AB8505_LDO_AUX5, + AB8505_LDO_AUX6, + AB8505_LDO_INTCORE, + AB8505_LDO_ADC, + AB8505_LDO_USB, + AB8505_LDO_AUDIO, + AB8505_LDO_ANAMIC1, + AB8505_LDO_ANAMIC2, + AB8505_LDO_AUX8, + AB8505_LDO_ANA, + AB8505_SYSCLKREQ_2, + AB8505_SYSCLKREQ_4, + AB8505_NUM_REGULATORS, +}; + +/* AB9540 regulators */ enum ab9540_regulator_id { AB9540_LDO_AUX1, AB9540_LDO_AUX2, @@ -46,7 +68,7 @@ enum ab9540_regulator_id { AB9540_NUM_REGULATORS, }; -/* AB8500 and AB9540 register initialization */ +/* AB8500, AB8505, and AB9540 register initialization */ struct ab8500_regulator_reg_init { int id; u8 mask; @@ -92,6 +114,55 @@ enum ab8500_regulator_reg { AB8500_NUM_REGULATOR_REGISTERS, }; +/* AB8505 registers */ +enum ab8505_regulator_reg { + AB8505_REGUREQUESTCTRL1, + AB8505_REGUREQUESTCTRL2, + AB8505_REGUREQUESTCTRL3, + AB8505_REGUREQUESTCTRL4, + AB8505_REGUSYSCLKREQ1HPVALID1, + AB8505_REGUSYSCLKREQ1HPVALID2, + AB8505_REGUHWHPREQ1VALID1, + AB8505_REGUHWHPREQ1VALID2, + AB8505_REGUHWHPREQ2VALID1, + AB8505_REGUHWHPREQ2VALID2, + AB8505_REGUSWHPREQVALID1, + AB8505_REGUSWHPREQVALID2, + AB8505_REGUSYSCLKREQVALID1, + AB8505_REGUSYSCLKREQVALID2, + AB8505_REGUVAUX4REQVALID, + AB8505_REGUMISC1, + AB8505_VAUDIOSUPPLY, + AB8505_REGUCTRL1VAMIC, + AB8505_VSMPSAREGU, + AB8505_VSMPSBREGU, + AB8505_VSAFEREGU, /* NOTE! PRCMU register */ + AB8505_VPLLVANAREGU, + AB8505_EXTSUPPLYREGU, + AB8505_VAUX12REGU, + AB8505_VRF1VAUX3REGU, + AB8505_VSMPSASEL1, + AB8505_VSMPSASEL2, + AB8505_VSMPSASEL3, + AB8505_VSMPSBSEL1, + AB8505_VSMPSBSEL2, + AB8505_VSMPSBSEL3, + AB8505_VSAFESEL1, /* NOTE! PRCMU register */ + AB8505_VSAFESEL2, /* NOTE! PRCMU register */ + AB8505_VSAFESEL3, /* NOTE! PRCMU register */ + AB8505_VAUX1SEL, + AB8505_VAUX2SEL, + AB8505_VRF1VAUX3SEL, + AB8505_VAUX4REQCTRL, + AB8505_VAUX4REGU, + AB8505_VAUX4SEL, + AB8505_REGUCTRLDISCH, + AB8505_REGUCTRLDISCH2, + AB8505_REGUCTRLDISCH3, + AB8505_CTRLVAUX5, + AB8505_CTRLVAUX6, + AB8505_NUM_REGULATOR_REGISTERS, +}; /* AB9540 registers */ enum ab9540_regulator_reg { -- cgit v1.2.3 From ae0a9a3efce22e77b5f0f2b266646431f492f7ed Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Mar 2013 16:11:16 +0000 Subject: regulator: ab8500: Add support for the ab8540 To obtain full AB8540 regulator support, the AB8500 regulator driver first needs to know its register layout and their initialisation values for each. That information is provided via a couple of large data structures which we provide here. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 686 ++++++++++++++++++++++++++++++++++++++- include/linux/regulator/ab8500.h | 86 +++++ 2 files changed, 764 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 1ab0f8a7c862..ec609ab747ae 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -107,6 +107,18 @@ static const int ldo_vaux56_voltages[] = { 2790000, }; +static const int ldo_vaux3_ab8540_voltages[] = { + 1200000, + 1500000, + 1800000, + 2100000, + 2500000, + 2750000, + 2790000, + 2910000, + 3050000, +}; + static const unsigned int ldo_vintcore_voltages[] = { 1200000, 1225000, @@ -117,6 +129,17 @@ static const unsigned int ldo_vintcore_voltages[] = { 1350000, }; +static const int ldo_sdio_voltages[] = { + 1160000, + 1050000, + 1100000, + 1500000, + 1800000, + 2200000, + 2910000, + 3050000, +}; + static int ab8500_regulator_enable(struct regulator_dev *rdev) { int ret; @@ -726,10 +749,10 @@ static struct ab8500_regulator_info /* values for CtrlVaux5 register */ .update_bank = 0x01, .update_reg = 0x55, - .update_mask = 0x08, - .update_val = 0x00, - .update_val_idle = 0x01, - .update_val_normal = 0x00, + .update_mask = 0x18, + .update_val = 0x10, + .update_val_idle = 0x18, + .update_val_normal = 0x10, .voltage_bank = 0x01, .voltage_reg = 0x55, .voltage_mask = 0x07, @@ -751,10 +774,10 @@ static struct ab8500_regulator_info /* values for CtrlVaux6 register */ .update_bank = 0x01, .update_reg = 0x56, - .update_mask = 0x08, - .update_val = 0x00, - .update_val_idle = 0x01, - .update_val_normal = 0x00, + .update_mask = 0x18, + .update_val = 0x10, + .update_val_idle = 0x18, + .update_val_normal = 0x10, .voltage_bank = 0x01, .voltage_reg = 0x56, .voltage_mask = 0x07, @@ -1169,6 +1192,255 @@ static struct ab8500_regulator_info }, }; +/* AB8540 regulator information */ +static struct ab8500_regulator_info + ab8540_regulator_info[AB8540_NUM_REGULATORS] = { + /* + * Variable Voltage Regulators + * name, min mV, max mV, + * update bank, reg, mask, enable val + * volt bank, reg, mask, table, table length + */ + [AB8540_LDO_AUX1] = { + .desc = { + .name = "LDO-AUX1", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX1, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x1f, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8540_LDO_AUX2] = { + .desc = { + .name = "LDO-AUX2", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX2, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x09, + .update_mask = 0x0c, + .update_val = 0x04, + .update_val_idle = 0x0c, + .update_val_normal = 0x04, + .voltage_bank = 0x04, + .voltage_reg = 0x20, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8540_LDO_AUX3] = { + .desc = { + .name = "LDO-AUX3", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUX3, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux3_ab8540_voltages), + }, + .load_lp_uA = 5000, + .update_bank = 0x04, + .update_reg = 0x0a, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x21, + .voltage_mask = 0x07, + .voltages = ldo_vaux3_ab8540_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux3_ab8540_voltages), + }, + [AB8540_LDO_AUX4] = { + .desc = { + .name = "LDO-AUX4", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB9540_LDO_AUX4, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages), + }, + .load_lp_uA = 5000, + /* values for Vaux4Regu register */ + .update_bank = 0x04, + .update_reg = 0x2e, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + /* values for Vaux4SEL register */ + .voltage_bank = 0x04, + .voltage_reg = 0x2f, + .voltage_mask = 0x0f, + .voltages = ldo_vauxn_voltages, + .voltages_len = ARRAY_SIZE(ldo_vauxn_voltages), + }, + [AB8540_LDO_INTCORE] = { + .desc = { + .name = "LDO-INTCORE", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_INTCORE, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), + }, + .load_lp_uA = 5000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x44, + .update_val = 0x44, + .update_val_idle = 0x44, + .update_val_normal = 0x04, + .voltage_bank = 0x03, + .voltage_reg = 0x80, + .voltage_mask = 0x38, + .voltages = ldo_vintcore_voltages, + .voltages_len = ARRAY_SIZE(ldo_vintcore_voltages), + .voltage_shift = 3, + }, + + /* + * Fixed Voltage Regulators + * name, fixed mV, + * update bank, reg, mask, enable val + */ + [AB8540_LDO_TVOUT] = { + .desc = { + .name = "LDO-TVOUT", + .ops = &ab8500_regulator_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_TVOUT, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .delay = 10000, + .load_lp_uA = 1000, + .update_bank = 0x03, + .update_reg = 0x80, + .update_mask = 0x82, + .update_val = 0x02, + .update_val_idle = 0x82, + .update_val_normal = 0x02, + }, + [AB8540_LDO_AUDIO] = { + .desc = { + .name = "LDO-AUDIO", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_AUDIO, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x02, + .update_val = 0x02, + }, + [AB8540_LDO_ANAMIC1] = { + .desc = { + .name = "LDO-ANAMIC1", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC1, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x08, + .update_val = 0x08, + }, + [AB8540_LDO_ANAMIC2] = { + .desc = { + .name = "LDO-ANAMIC2", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANAMIC2, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x10, + .update_val = 0x10, + }, + [AB8540_LDO_DMIC] = { + .desc = { + .name = "LDO-DMIC", + .ops = &ab8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_DMIC, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .update_bank = 0x03, + .update_reg = 0x83, + .update_mask = 0x04, + .update_val = 0x04, + }, + + /* + * Regulators with fixed voltage and normal/idle modes + */ + [AB8540_LDO_ANA] = { + .desc = { + .name = "LDO-ANA", + .ops = &ab8500_regulator_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_LDO_ANA, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .load_lp_uA = 1000, + .update_bank = 0x04, + .update_reg = 0x06, + .update_mask = 0x0c, + .update_val = 0x04, + .update_val_idle = 0x0c, + .update_val_normal = 0x04, + }, + [AB8540_LDO_SDIO] = { + .desc = { + .name = "LDO-SDIO", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8540_LDO_SDIO, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_sdio_voltages), + }, + .min_uV = 1050000, + .max_uV = 3050000, + .load_lp_uA = 5000, + .update_bank = 0x03, + .update_reg = 0x88, + .update_mask = 0x30, + .update_val = 0x10, + .update_val_idle = 0x30, + .update_val_normal = 0x10, + .voltage_bank = 0x03, + .voltage_reg = 0x88, + .voltage_mask = 0x07, + .voltages = ldo_sdio_voltages, + .voltages_len = ARRAY_SIZE(ldo_sdio_voltages), + }, +}; + struct ab8500_reg_init { u8 bank; u8 addr; @@ -1898,6 +2170,384 @@ static struct ab8500_reg_init ab9540_reg_init[] = { REG_INIT(AB9540_REGUCTRLDISCH3, 0x04, 0x48, 0x01), }; +/* AB8540 register init */ +static struct ab8500_reg_init ab8540_reg_init[] = { + /* + * 0x01, VSimSycClkReq1Valid + * 0x02, VSimSycClkReq2Valid + * 0x04, VSimSycClkReq3Valid + * 0x08, VSimSycClkReq4Valid + * 0x10, VSimSycClkReq5Valid + * 0x20, VSimSycClkReq6Valid + * 0x40, VSimSycClkReq7Valid + * 0x80, VSimSycClkReq8Valid + */ + REG_INIT(AB8540_VSIMSYSCLKCTRL, 0x02, 0x33, 0xff), + /* + * 0x03, VarmRequestCtrl + * 0x0c, VapeRequestCtrl + * 0x30, Vsmps1RequestCtrl + * 0xc0, Vsmps2RequestCtrl + */ + REG_INIT(AB8540_REGUREQUESTCTRL1, 0x03, 0x03, 0xff), + /* + * 0x03, Vsmps3RequestCtrl + * 0x0c, VpllRequestCtrl + * 0x30, VanaRequestCtrl + * 0xc0, VextSupply1RequestCtrl + */ + REG_INIT(AB8540_REGUREQUESTCTRL2, 0x03, 0x04, 0xff), + /* + * 0x03, VextSupply2RequestCtrl + * 0x0c, VextSupply3RequestCtrl + * 0x30, Vaux1RequestCtrl + * 0xc0, Vaux2RequestCtrl + */ + REG_INIT(AB8540_REGUREQUESTCTRL3, 0x03, 0x05, 0xff), + /* + * 0x03, Vaux3RequestCtrl + * 0x04, SwHPReq + */ + REG_INIT(AB8540_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), + /* + * 0x01, Vsmps1SysClkReq1HPValid + * 0x02, Vsmps2SysClkReq1HPValid + * 0x04, Vsmps3SysClkReq1HPValid + * 0x08, VanaSysClkReq1HPValid + * 0x10, VpllSysClkReq1HPValid + * 0x20, Vaux1SysClkReq1HPValid + * 0x40, Vaux2SysClkReq1HPValid + * 0x80, Vaux3SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff), + /* + * 0x01, VapeSysClkReq1HPValid + * 0x02, VarmSysClkReq1HPValid + * 0x04, VbbSysClkReq1HPValid + * 0x10, VextSupply1SysClkReq1HPValid + * 0x20, VextSupply2SysClkReq1HPValid + * 0x40, VextSupply3SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x77), + /* + * 0x01, Vsmps1HwHPReq1Valid + * 0x02, Vsmps2HwHPReq1Valid + * 0x04, Vsmps3HwHPReq1Valid + * 0x08, VanaHwHPReq1Valid + * 0x10, VpllHwHPReq1Valid + * 0x20, Vaux1HwHPReq1Valid + * 0x40, Vaux2HwHPReq1Valid + * 0x80, Vaux3HwHPReq1Valid + */ + REG_INIT(AB8540_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff), + /* + * 0x01, VextSupply1HwHPReq1Valid + * 0x02, VextSupply2HwHPReq1Valid + * 0x04, VextSupply3HwHPReq1Valid + */ + REG_INIT(AB8540_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), + /* + * 0x01, Vsmps1HwHPReq2Valid + * 0x02, Vsmps2HwHPReq2Valid + * 0x03, Vsmps3HwHPReq2Valid + * 0x08, VanaHwHPReq2Valid + * 0x10, VpllHwHPReq2Valid + * 0x20, Vaux1HwHPReq2Valid + * 0x40, Vaux2HwHPReq2Valid + * 0x80, Vaux3HwHPReq2Valid + */ + REG_INIT(AB8540_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff), + /* + * 0x01, VextSupply1HwHPReq2Valid + * 0x02, VextSupply2HwHPReq2Valid + * 0x04, VextSupply3HwHPReq2Valid + */ + REG_INIT(AB8540_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), + /* + * 0x01, VapeSwHPReqValid + * 0x02, VarmSwHPReqValid + * 0x04, Vsmps1SwHPReqValid + * 0x08, Vsmps2SwHPReqValid + * 0x10, Vsmps3SwHPReqValid + * 0x20, VanaSwHPReqValid + * 0x40, VpllSwHPReqValid + * 0x80, Vaux1SwHPReqValid + */ + REG_INIT(AB8540_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff), + /* + * 0x01, Vaux2SwHPReqValid + * 0x02, Vaux3SwHPReqValid + * 0x04, VextSupply1SwHPReqValid + * 0x08, VextSupply2SwHPReqValid + * 0x10, VextSupply3SwHPReqValid + */ + REG_INIT(AB8540_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), + /* + * 0x02, SysClkReq2Valid1 + * ... + * 0x80, SysClkReq8Valid1 + */ + REG_INIT(AB8540_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xff), + /* + * 0x02, SysClkReq2Valid2 + * ... + * 0x80, SysClkReq8Valid2 + */ + REG_INIT(AB8540_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xff), + /* + * 0x01, Vaux4SwHPReqValid + * 0x02, Vaux4HwHPReq2Valid + * 0x04, Vaux4HwHPReq1Valid + * 0x08, Vaux4SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUVAUX4REQVALID, 0x03, 0x11, 0x0f), + /* + * 0x01, Vaux5SwHPReqValid + * 0x02, Vaux5HwHPReq2Valid + * 0x04, Vaux5HwHPReq1Valid + * 0x08, Vaux5SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUVAUX5REQVALID, 0x03, 0x12, 0x0f), + /* + * 0x01, Vaux6SwHPReqValid + * 0x02, Vaux6HwHPReq2Valid + * 0x04, Vaux6HwHPReq1Valid + * 0x08, Vaux6SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUVAUX6REQVALID, 0x03, 0x13, 0x0f), + /* + * 0x01, VclkbSwHPReqValid + * 0x02, VclkbHwHPReq2Valid + * 0x04, VclkbHwHPReq1Valid + * 0x08, VclkbSysClkReq1HPValid + */ + REG_INIT(AB8540_REGUVCLKBREQVALID, 0x03, 0x14, 0x0f), + /* + * 0x01, Vrf1SwHPReqValid + * 0x02, Vrf1HwHPReq2Valid + * 0x04, Vrf1HwHPReq1Valid + * 0x08, Vrf1SysClkReq1HPValid + */ + REG_INIT(AB8540_REGUVRF1REQVALID, 0x03, 0x15, 0x0f), + /* + * 0x02, VTVoutEna + * 0x04, Vintcore12Ena + * 0x38, Vintcore12Sel + * 0x40, Vintcore12LP + * 0x80, VTVoutLP + */ + REG_INIT(AB8540_REGUMISC1, 0x03, 0x80, 0xfe), + /* + * 0x02, VaudioEna + * 0x04, VdmicEna + * 0x08, Vamic1Ena + * 0x10, Vamic2Ena + * 0x20, Vamic12LP + * 0xC0, VdmicSel + */ + REG_INIT(AB8540_VAUDIOSUPPLY, 0x03, 0x83, 0xfe), + /* + * 0x01, Vamic1_dzout + * 0x02, Vamic2_dzout + */ + REG_INIT(AB8540_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), + /* + * 0x07, VHSICSel + * 0x08, VHSICOffState + * 0x10, VHSIEna + * 0x20, VHSICLP + */ + REG_INIT(AB8540_VHSIC, 0x03, 0x87, 0x3f), + /* + * 0x07, VSDIOSel + * 0x08, VSDIOOffState + * 0x10, VSDIOEna + * 0x20, VSDIOLP + */ + REG_INIT(AB8540_VSDIO, 0x03, 0x88, 0x3f), + /* + * 0x03, Vsmps1Regu + * 0x0c, Vsmps1SelCtrl + * 0x10, Vsmps1AutoMode + * 0x20, Vsmps1PWMMode + */ + REG_INIT(AB8540_VSMPS1REGU, 0x04, 0x03, 0x3f), + /* + * 0x03, Vsmps2Regu + * 0x0c, Vsmps2SelCtrl + * 0x10, Vsmps2AutoMode + * 0x20, Vsmps2PWMMode + */ + REG_INIT(AB8540_VSMPS2REGU, 0x04, 0x04, 0x3f), + /* + * 0x03, Vsmps3Regu + * 0x0c, Vsmps3SelCtrl + * 0x10, Vsmps3AutoMode + * 0x20, Vsmps3PWMMode + * NOTE! PRCMU register + */ + REG_INIT(AB8540_VSMPS3REGU, 0x04, 0x05, 0x0f), + /* + * 0x03, VpllRegu + * 0x0c, VanaRegu + */ + REG_INIT(AB8540_VPLLVANAREGU, 0x04, 0x06, 0x0f), + /* + * 0x03, VextSupply1Regu + * 0x0c, VextSupply2Regu + * 0x30, VextSupply3Regu + * 0x40, ExtSupply2Bypass + * 0x80, ExtSupply3Bypass + */ + REG_INIT(AB8540_EXTSUPPLYREGU, 0x04, 0x08, 0xff), + /* + * 0x03, Vaux1Regu + * 0x0c, Vaux2Regu + */ + REG_INIT(AB8540_VAUX12REGU, 0x04, 0x09, 0x0f), + /* + * 0x0c, VRF1Regu + * 0x03, Vaux3Regu + */ + REG_INIT(AB8540_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f), + /* + * 0x3f, Vsmps1Sel1 + */ + REG_INIT(AB8540_VSMPS1SEL1, 0x04, 0x13, 0x3f), + /* + * 0x3f, Vsmps1Sel2 + */ + REG_INIT(AB8540_VSMPS1SEL2, 0x04, 0x14, 0x3f), + /* + * 0x3f, Vsmps1Sel3 + */ + REG_INIT(AB8540_VSMPS1SEL3, 0x04, 0x15, 0x3f), + /* + * 0x3f, Vsmps2Sel1 + */ + REG_INIT(AB8540_VSMPS2SEL1, 0x04, 0x17, 0x3f), + /* + * 0x3f, Vsmps2Sel2 + */ + REG_INIT(AB8540_VSMPS2SEL2, 0x04, 0x18, 0x3f), + /* + * 0x3f, Vsmps2Sel3 + */ + REG_INIT(AB8540_VSMPS2SEL3, 0x04, 0x19, 0x3f), + /* + * 0x7f, Vsmps3Sel1 + * NOTE! PRCMU register + */ + REG_INIT(AB8540_VSMPS3SEL1, 0x04, 0x1b, 0x7f), + /* + * 0x7f, Vsmps3Sel2 + * NOTE! PRCMU register + */ + REG_INIT(AB8540_VSMPS3SEL2, 0x04, 0x1c, 0x7f), + /* + * 0x0f, Vaux1Sel + */ + REG_INIT(AB8540_VAUX1SEL, 0x04, 0x1f, 0x0f), + /* + * 0x0f, Vaux2Sel + */ + REG_INIT(AB8540_VAUX2SEL, 0x04, 0x20, 0x0f), + /* + * 0x07, Vaux3Sel + * 0x70, Vrf1Sel + */ + REG_INIT(AB8540_VRF1VAUX3SEL, 0x04, 0x21, 0x77), + /* + * 0x01, VextSupply12LP + */ + REG_INIT(AB8540_REGUCTRL2SPARE, 0x04, 0x22, 0x01), + /* + * 0x07, Vanasel + * 0x30, Vpllsel + */ + REG_INIT(AB8540_VANAVPLLSEL, 0x04, 0x29, 0x37), + /* + * 0x03, Vaux4RequestCtrl + */ + REG_INIT(AB8540_VAUX4REQCTRL, 0x04, 0x2d, 0x03), + /* + * 0x03, Vaux4Regu + */ + REG_INIT(AB8540_VAUX4REGU, 0x04, 0x2e, 0x03), + /* + * 0x0f, Vaux4Sel + */ + REG_INIT(AB8540_VAUX4SEL, 0x04, 0x2f, 0x0f), + /* + * 0x03, Vaux5RequestCtrl + */ + REG_INIT(AB8540_VAUX5REQCTRL, 0x04, 0x31, 0x03), + /* + * 0x03, Vaux5Regu + */ + REG_INIT(AB8540_VAUX5REGU, 0x04, 0x32, 0x03), + /* + * 0x3f, Vaux5Sel + */ + REG_INIT(AB8540_VAUX5SEL, 0x04, 0x33, 0x3f), + /* + * 0x03, Vaux6RequestCtrl + */ + REG_INIT(AB8540_VAUX6REQCTRL, 0x04, 0x34, 0x03), + /* + * 0x03, Vaux6Regu + */ + REG_INIT(AB8540_VAUX6REGU, 0x04, 0x35, 0x03), + /* + * 0x3f, Vaux6Sel + */ + REG_INIT(AB8540_VAUX6SEL, 0x04, 0x36, 0x3f), + /* + * 0x03, VCLKBRequestCtrl + */ + REG_INIT(AB8540_VCLKBREQCTRL, 0x04, 0x37, 0x03), + /* + * 0x03, VCLKBRegu + */ + REG_INIT(AB8540_VCLKBREGU, 0x04, 0x38, 0x03), + /* + * 0x07, VCLKBSel + */ + REG_INIT(AB8540_VCLKBSEL, 0x04, 0x39, 0x07), + /* + * 0x03, Vrf1RequestCtrl + */ + REG_INIT(AB8540_VRF1REQCTRL, 0x04, 0x3a, 0x03), + /* + * 0x01, VpllDisch + * 0x02, Vrf1Disch + * 0x04, Vaux1Disch + * 0x08, Vaux2Disch + * 0x10, Vaux3Disch + * 0x20, Vintcore12Disch + * 0x40, VTVoutDisch + * 0x80, VaudioDisch + */ + REG_INIT(AB8540_REGUCTRLDISCH, 0x04, 0x43, 0xff), + /* + * 0x02, VanaDisch + * 0x04, VdmicPullDownEna + * 0x08, VpllPullDownEna + * 0x10, VdmicDisch + */ + REG_INIT(AB8540_REGUCTRLDISCH2, 0x04, 0x44, 0x1e), + /* + * 0x01, Vaux4Disch + */ + REG_INIT(AB8540_REGUCTRLDISCH3, 0x04, 0x48, 0x01), + /* + * 0x01, Vaux5Disch + * 0x02, Vaux6Disch + * 0x04, VCLKBDisch + */ + REG_INIT(AB8540_REGUCTRLDISCH4, 0x04, 0x49, 0x07), +}; + static int ab8500_regulator_init_registers(struct platform_device *pdev, struct ab8500_reg_init *reg_init, int id, int mask, int value) @@ -2004,6 +2654,21 @@ static struct of_regulator_match ab8505_regulator_match[] = { { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8505_LDO_ANA, }, }; +static struct of_regulator_match ab8540_regulator_match[] = { + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8540_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8540_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8540_LDO_AUX3, }, + { .name = "ab8500_ldo_aux4", .driver_data = (void *) AB8540_LDO_AUX4, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8540_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8540_LDO_TVOUT, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8540_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8540_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8540_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8540_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8540_LDO_ANA, }, + { .name = "ab8500_ldo_sdio", .driver_data = (void *) AB8540_LDO_SDIO, }, +}; + static struct of_regulator_match ab9540_regulator_match[] = { { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB9540_LDO_AUX1, }, { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB9540_LDO_AUX2, }, @@ -2063,6 +2728,11 @@ static int ab8500_regulator_probe(struct platform_device *pdev) regulator_info_size = ARRAY_SIZE(ab8505_regulator_info); reg_init = ab8505_reg_init; reg_init_size = AB8505_NUM_REGULATOR_REGISTERS; + } else if (is_ab8540(ab8500)) { + regulator_info = ab8540_regulator_info; + regulator_info_size = ARRAY_SIZE(ab8540_regulator_info); + reg_init = ab8540_reg_init; + reg_init_size = AB8540_NUM_REGULATOR_REGISTERS; } else { regulator_info = ab8500_regulator_info; regulator_info_size = ARRAY_SIZE(ab8500_regulator_info); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 9a7cf97e5040..bb0140c9d4f4 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -68,6 +68,25 @@ enum ab9540_regulator_id { AB9540_NUM_REGULATORS, }; +/* AB8540 regulators */ +enum ab8540_regulator_id { + AB8540_LDO_AUX1, + AB8540_LDO_AUX2, + AB8540_LDO_AUX3, + AB8540_LDO_AUX4, + AB8540_LDO_INTCORE, + AB8540_LDO_TVOUT, + AB8540_LDO_AUDIO, + AB8540_LDO_ANAMIC1, + AB8540_LDO_ANAMIC2, + AB8540_LDO_DMIC, + AB8540_LDO_ANA, + AB8540_LDO_SDIO, + AB8540_SYSCLKREQ_2, + AB8540_SYSCLKREQ_4, + AB8540_NUM_REGULATORS, +}; + /* AB8500, AB8505, and AB9540 register initialization */ struct ab8500_regulator_reg_init { int id; @@ -212,6 +231,73 @@ enum ab9540_regulator_reg { AB9540_NUM_REGULATOR_REGISTERS, }; +/* AB8540 registers */ +enum ab8540_regulator_reg { + AB8540_REGUREQUESTCTRL1, + AB8540_REGUREQUESTCTRL2, + AB8540_REGUREQUESTCTRL3, + AB8540_REGUREQUESTCTRL4, + AB8540_REGUSYSCLKREQ1HPVALID1, + AB8540_REGUSYSCLKREQ1HPVALID2, + AB8540_REGUHWHPREQ1VALID1, + AB8540_REGUHWHPREQ1VALID2, + AB8540_REGUHWHPREQ2VALID1, + AB8540_REGUHWHPREQ2VALID2, + AB8540_REGUSWHPREQVALID1, + AB8540_REGUSWHPREQVALID2, + AB8540_REGUSYSCLKREQVALID1, + AB8540_REGUSYSCLKREQVALID2, + AB8540_REGUVAUX4REQVALID, + AB8540_REGUVAUX5REQVALID, + AB8540_REGUVAUX6REQVALID, + AB8540_REGUVCLKBREQVALID, + AB8540_REGUVRF1REQVALID, + AB8540_REGUMISC1, + AB8540_VAUDIOSUPPLY, + AB8540_REGUCTRL1VAMIC, + AB8540_VHSIC, + AB8540_VSDIO, + AB8540_VSMPS1REGU, + AB8540_VSMPS2REGU, + AB8540_VSMPS3REGU, + AB8540_VPLLVANAREGU, + AB8540_EXTSUPPLYREGU, + AB8540_VAUX12REGU, + AB8540_VRF1VAUX3REGU, + AB8540_VSMPS1SEL1, + AB8540_VSMPS1SEL2, + AB8540_VSMPS1SEL3, + AB8540_VSMPS2SEL1, + AB8540_VSMPS2SEL2, + AB8540_VSMPS2SEL3, + AB8540_VSMPS3SEL1, + AB8540_VSMPS3SEL2, + AB8540_VAUX1SEL, + AB8540_VAUX2SEL, + AB8540_VRF1VAUX3SEL, + AB8540_REGUCTRL2SPARE, + AB8540_VAUX4REQCTRL, + AB8540_VAUX4REGU, + AB8540_VAUX4SEL, + AB8540_VAUX5REQCTRL, + AB8540_VAUX5REGU, + AB8540_VAUX5SEL, + AB8540_VAUX6REQCTRL, + AB8540_VAUX6REGU, + AB8540_VAUX6SEL, + AB8540_VCLKBREQCTRL, + AB8540_VCLKBREGU, + AB8540_VCLKBSEL, + AB8540_VRF1REQCTRL, + AB8540_REGUCTRLDISCH, + AB8540_REGUCTRLDISCH2, + AB8540_REGUCTRLDISCH3, + AB8540_REGUCTRLDISCH4, + AB8540_VSIMSYSCLKCTRL, + AB8540_VANAVPLLSEL, + AB8540_NUM_REGULATOR_REGISTERS, +}; + /* AB8500 external regulators */ struct ab8500_ext_regulator_cfg { bool hwreq; /* requires hw mode or high power mode */ -- cgit v1.2.3 From 35e1d5f6344ed1bb2fab61ac7934aa0f19908b2c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 2 Apr 2013 13:24:05 +0100 Subject: regulator: ab8500-ext: Remove unused REGULATOR_AB8500_EXT guard Before the AB8500 External Regulator driver was Mainlined, it used to be conditionally compiled in using the CONFIG_REGULATOR_AB8500_EXT flag. During the review process that capability was removed, but the guard controlling prototyping slipped though the net. This patch cleans it up. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- include/linux/regulator/ab8500.h | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index bb0140c9d4f4..44f67e8f1a6d 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -320,21 +320,6 @@ struct ab8500_regulator_platform_data { struct regulator_init_data *ext_regulator; }; -/* AB8500 external regulator functions (internal) */ -#ifdef CONFIG_REGULATOR_AB8500_EXT -int ab8500_ext_regulator_init(struct platform_device *pdev); -int ab8500_ext_regulator_exit(struct platform_device *pdev); -#else -inline int ab8500_ext_regulator_init(struct platform_device *pdev) -{ - return 0; -} -inline int ab8500_ext_regulator_exit(struct platform_device *pdev) -{ - return 0; -} -#endif - #ifdef CONFIG_REGULATOR_AB8500_DEBUG int ab8500_regulator_debug_init(struct platform_device *pdev); int ab8500_regulator_debug_exit(struct platform_device *pdev); @@ -349,4 +334,8 @@ static inline int ab8500_regulator_debug_exit(struct platform_device *pdev) } #endif +/* AB8500 external regulator functions. */ +int ab8500_ext_regulator_init(struct platform_device *pdev); +int ab8500_ext_regulator_exit(struct platform_device *pdev); + #endif -- cgit v1.2.3 From 684d5ce4afafddb2ad08f36ea30ca7d7adc88ebe Mon Sep 17 00:00:00 2001 From: Zhenhua HUANG Date: Tue, 2 Apr 2013 13:24:15 +0100 Subject: regulator: ab8500: Introduce aux5, aux6 regulators for AB8540 Introduce aux5, aux6 into ab8540 regulator framework. Signed-off-by: Zhenhua HUANG Signed-off-by: Lee Jones Reviewed-by: Maxime COQUELIN Reviewed-by: David PARIS Reviewed-by: Philippe LANGLAIS Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 65 ++++++++++++++++++++++++++++++++++++++++ include/linux/regulator/ab8500.h | 2 ++ 2 files changed, 67 insertions(+) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 9cb634807ff8..433cac4396df 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -149,6 +149,21 @@ static const unsigned int ldo_vaux3_ab8540_voltages[] = { 3050000, }; +static const unsigned int ldo_vaux56_ab8540_voltages[] = { + 750000, 760000, 770000, 780000, 790000, 800000, + 810000, 820000, 830000, 840000, 850000, 860000, + 870000, 880000, 890000, 900000, 910000, 920000, + 930000, 940000, 950000, 960000, 970000, 980000, + 990000, 1000000, 1010000, 1020000, 1030000, + 1040000, 1050000, 1060000, 1070000, 1080000, + 1090000, 1100000, 1110000, 1120000, 1130000, + 1140000, 1150000, 1160000, 1170000, 1180000, + 1190000, 1200000, 1210000, 1220000, 1230000, + 1240000, 1250000, 1260000, 1270000, 1280000, + 1290000, 1300000, 1310000, 1320000, 1330000, + 1340000, 1350000, 1360000, 1800000, 2790000, +}; + static const unsigned int ldo_vintcore_voltages[] = { 1200000, 1225000, @@ -1569,6 +1584,54 @@ static struct ab8500_regulator_info .voltage_reg = 0x2f, .voltage_mask = 0x0f, }, + [AB8540_LDO_AUX5] = { + .desc = { + .name = "LDO-AUX5", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8540_LDO_AUX5, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux56_ab8540_voltages), + }, + .load_lp_uA = 20000, + /* values for Vaux5Regu register */ + .update_bank = 0x04, + .update_reg = 0x32, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + /* values for Vaux5SEL register */ + .voltage_bank = 0x04, + .voltage_reg = 0x33, + .voltage_mask = 0x3f, + .voltages = ldo_vaux56_ab8540_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux56_ab8540_voltages), + }, + [AB8540_LDO_AUX6] = { + .desc = { + .name = "LDO-AUX6", + .ops = &ab8500_regulator_volt_mode_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8540_LDO_AUX6, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(ldo_vaux56_ab8540_voltages), + }, + .load_lp_uA = 20000, + /* values for Vaux6Regu register */ + .update_bank = 0x04, + .update_reg = 0x35, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + /* values for Vaux6SEL register */ + .voltage_bank = 0x04, + .voltage_reg = 0x36, + .voltage_mask = 0x3f, + .voltages = ldo_vaux56_ab8540_voltages, + .voltages_len = ARRAY_SIZE(ldo_vaux56_ab8540_voltages), + }, [AB8540_LDO_INTCORE] = { .desc = { .name = "LDO-INTCORE", @@ -2979,6 +3042,8 @@ static struct of_regulator_match ab8540_regulator_match[] = { { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8540_LDO_AUX2, }, { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8540_LDO_AUX3, }, { .name = "ab8500_ldo_aux4", .driver_data = (void *) AB8540_LDO_AUX4, }, + { .name = "ab8500_ldo_aux5", .driver_data = (void *) AB8540_LDO_AUX5, }, + { .name = "ab8500_ldo_aux6", .driver_data = (void *) AB8540_LDO_AUX6, }, { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8540_LDO_INTCORE, }, { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8540_LDO_TVOUT, }, { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8540_LDO_AUDIO, }, diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 44f67e8f1a6d..90b8b5ae9a4e 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -74,6 +74,8 @@ enum ab8540_regulator_id { AB8540_LDO_AUX2, AB8540_LDO_AUX3, AB8540_LDO_AUX4, + AB8540_LDO_AUX5, + AB8540_LDO_AUX6, AB8540_LDO_INTCORE, AB8540_LDO_TVOUT, AB8540_LDO_AUDIO, -- cgit v1.2.3 From c4e67bbc99ce661808c3ee77b0bb5779d0df11ca Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 2 Apr 2013 13:24:19 +0100 Subject: ARM: ux500: Pass regulator platform data using the new format Regulator platform data is now passed though a single structure as opposed to the old way where four separate struct elements were required. This patch makes use of the new format. Signed-off-by: Lee Jones Signed-off-by: Mark Brown --- arch/arm/mach-ux500/board-mop500.c | 5 +---- include/linux/mfd/abx500/ab8500.h | 11 ++--------- 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index b03457881c4b..b1124bd34a6c 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -198,10 +198,7 @@ static struct platform_device snowball_sbnet_dev = { struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, - .regulator_reg_init = ab8500_regulator_reg_init, - .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), - .regulator = ab8500_regulators, - .num_regulator = ARRAY_SIZE(ab8500_regulators), + .regulator = &ab8500_regulator_plat_data, .gpio = &ab8500_gpio_pdata, .codec = &ab8500_codec_pdata, }; diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 9db0bda446a0..84f449475c25 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h @@ -364,8 +364,7 @@ struct ab8500 { const int *irq_reg_offset; }; -struct regulator_reg_init; -struct regulator_init_data; +struct ab8500_regulator_platform_data; struct ab8500_gpio_platform_data; struct ab8500_codec_platform_data; struct ab8500_sysctrl_platform_data; @@ -375,19 +374,13 @@ struct ab8500_sysctrl_platform_data; * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @pm_power_off: Should machine pm power off hook be registered or not * @init: board-specific initialization after detection of ab8500 - * @num_regulator_reg_init: number of regulator init registers - * @regulator_reg_init: regulator init registers - * @num_regulator: number of regulators * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; bool pm_power_off; void (*init) (struct ab8500 *); - int num_regulator_reg_init; - struct ab8500_regulator_reg_init *regulator_reg_init; - int num_regulator; - struct regulator_init_data *regulator; + struct ab8500_regulator_platform_data *regulator; struct abx500_gpio_platform_data *gpio; struct ab8500_codec_platform_data *codec; struct ab8500_sysctrl_platform_data *sysctrl; -- cgit v1.2.3 From 3480c0cab6e1a25fdeb63147b0b643b7825a36fb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 11 Apr 2013 12:04:18 +0800 Subject: regulator: ab8500-ext: Make the return type of ab8500_ext_regulator_exit() void ab8500_ext_regulator_exit() never fails. Signed-off-by: Axel Lin Acked-by: Bengt Jonsson Signed-off-by: Mark Brown --- drivers/regulator/ab8500-ext.c | 4 +--- drivers/regulator/ab8500.c | 9 +++------ include/linux/regulator/ab8500.h | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 9aee21cad379..20680f30a968 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c @@ -394,7 +394,7 @@ int ab8500_ext_regulator_init(struct platform_device *pdev) return 0; } -int ab8500_ext_regulator_exit(struct platform_device *pdev) +void ab8500_ext_regulator_exit(struct platform_device *pdev) { int i; @@ -407,8 +407,6 @@ int ab8500_ext_regulator_exit(struct platform_device *pdev) regulator_unregister(info->rdev); } - - return 0; } MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 9ebd131b2ec6..c200f8bb61db 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -3194,12 +3194,9 @@ static int ab8500_regulator_remove(struct platform_device *pdev) regulator_unregister(info->regulator); } - if (!is_ab8505(ab8500)) { - /* remove external regulators (after Vaux1, 2 and 3) */ - err = ab8500_ext_regulator_exit(pdev); - if (err) - return err; - } + /* remove external regulators (after Vaux1, 2 and 3) */ + if (!is_ab8505(ab8500)) + ab8500_ext_regulator_exit(pdev); /* remove regulator debug */ err = ab8500_regulator_debug_exit(pdev); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 90b8b5ae9a4e..7c5ff0c55773 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -338,6 +338,6 @@ static inline int ab8500_regulator_debug_exit(struct platform_device *pdev) /* AB8500 external regulator functions. */ int ab8500_ext_regulator_init(struct platform_device *pdev); -int ab8500_ext_regulator_exit(struct platform_device *pdev); +void ab8500_ext_regulator_exit(struct platform_device *pdev); #endif -- cgit v1.2.3