162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// Regulator Driver for Freescale MC13892 PMIC
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright 2010 Yong Shen <yong.shen@linaro.org>
662306a36Sopenharmony_ci//
762306a36Sopenharmony_ci// Based on draft driver from Arnaud Patard <arnaud.patard@rtp-net.org>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/mfd/mc13892.h>
1062306a36Sopenharmony_ci#include <linux/regulator/machine.h>
1162306a36Sopenharmony_ci#include <linux/regulator/driver.h>
1262306a36Sopenharmony_ci#include <linux/platform_device.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/slab.h>
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/err.h>
1762306a36Sopenharmony_ci#include <linux/module.h>
1862306a36Sopenharmony_ci#include "mc13xxx.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define MC13892_REVISION			7
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define MC13892_POWERCTL0			13
2362306a36Sopenharmony_ci#define MC13892_POWERCTL0_USEROFFSPI		3
2462306a36Sopenharmony_ci#define MC13892_POWERCTL0_VCOINCELLVSEL		20
2562306a36Sopenharmony_ci#define MC13892_POWERCTL0_VCOINCELLVSEL_M	(7<<20)
2662306a36Sopenharmony_ci#define MC13892_POWERCTL0_VCOINCELLEN		(1<<23)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define MC13892_SWITCHERS0_SWxHI		(1<<23)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define MC13892_SWITCHERS0			24
3162306a36Sopenharmony_ci#define MC13892_SWITCHERS0_SW1VSEL		0
3262306a36Sopenharmony_ci#define MC13892_SWITCHERS0_SW1VSEL_M		(0x1f<<0)
3362306a36Sopenharmony_ci#define MC13892_SWITCHERS0_SW1HI		(1<<23)
3462306a36Sopenharmony_ci#define MC13892_SWITCHERS0_SW1EN		0
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define MC13892_SWITCHERS1			25
3762306a36Sopenharmony_ci#define MC13892_SWITCHERS1_SW2VSEL		0
3862306a36Sopenharmony_ci#define MC13892_SWITCHERS1_SW2VSEL_M		(0x1f<<0)
3962306a36Sopenharmony_ci#define MC13892_SWITCHERS1_SW2HI		(1<<23)
4062306a36Sopenharmony_ci#define MC13892_SWITCHERS1_SW2EN		0
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define MC13892_SWITCHERS2			26
4362306a36Sopenharmony_ci#define MC13892_SWITCHERS2_SW3VSEL		0
4462306a36Sopenharmony_ci#define MC13892_SWITCHERS2_SW3VSEL_M		(0x1f<<0)
4562306a36Sopenharmony_ci#define MC13892_SWITCHERS2_SW3HI		(1<<23)
4662306a36Sopenharmony_ci#define MC13892_SWITCHERS2_SW3EN		0
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define MC13892_SWITCHERS3			27
4962306a36Sopenharmony_ci#define MC13892_SWITCHERS3_SW4VSEL		0
5062306a36Sopenharmony_ci#define MC13892_SWITCHERS3_SW4VSEL_M		(0x1f<<0)
5162306a36Sopenharmony_ci#define MC13892_SWITCHERS3_SW4HI		(1<<23)
5262306a36Sopenharmony_ci#define MC13892_SWITCHERS3_SW4EN		0
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define MC13892_SWITCHERS4			28
5562306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW1MODE		0
5662306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW1MODE_AUTO		(8<<0)
5762306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW1MODE_M		(0xf<<0)
5862306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW2MODE		10
5962306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW2MODE_AUTO		(8<<10)
6062306a36Sopenharmony_ci#define MC13892_SWITCHERS4_SW2MODE_M		(0xf<<10)
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define MC13892_SWITCHERS5			29
6362306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW3MODE		0
6462306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW3MODE_AUTO		(8<<0)
6562306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW3MODE_M		(0xf<<0)
6662306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW4MODE		8
6762306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW4MODE_AUTO		(8<<8)
6862306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SW4MODE_M		(0xf<<8)
6962306a36Sopenharmony_ci#define MC13892_SWITCHERS5_SWBSTEN		(1<<20)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0		30
7262306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN1VSEL	0
7362306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VDIGVSEL	4
7462306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN2VSEL	6
7562306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VPLLVSEL	9
7662306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VUSB2VSEL	11
7762306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN3VSEL	14
7862306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VCAMVSEL	16
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN1VSEL_M	(3<<0)
8162306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VDIGVSEL_M	(3<<4)
8262306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN2VSEL_M	(7<<6)
8362306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VPLLVSEL_M	(3<<9)
8462306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VUSB2VSEL_M	(3<<11)
8562306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VGEN3VSEL_M	(1<<14)
8662306a36Sopenharmony_ci#define MC13892_REGULATORSETTING0_VCAMVSEL_M	(3<<16)
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1		31
8962306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VVIDEOVSEL	2
9062306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VAUDIOVSEL	4
9162306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VSDVSEL	6
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VVIDEOVSEL_M	(3<<2)
9462306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VAUDIOVSEL_M	(3<<4)
9562306a36Sopenharmony_ci#define MC13892_REGULATORSETTING1_VSDVSEL_M	(7<<6)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#define MC13892_REGULATORMODE0			32
9862306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN1EN		(1<<0)
9962306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN1STDBY	(1<<1)
10062306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN1MODE	(1<<2)
10162306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VIOHIEN		(1<<3)
10262306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VIOHISTDBY	(1<<4)
10362306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VIOHIMODE	(1<<5)
10462306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VDIGEN		(1<<9)
10562306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VDIGSTDBY	(1<<10)
10662306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VDIGMODE		(1<<11)
10762306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN2EN		(1<<12)
10862306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN2STDBY	(1<<13)
10962306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VGEN2MODE	(1<<14)
11062306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VPLLEN		(1<<15)
11162306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VPLLSTDBY	(1<<16)
11262306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VPLLMODE		(1<<17)
11362306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VUSB2EN		(1<<18)
11462306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VUSB2STDBY	(1<<19)
11562306a36Sopenharmony_ci#define MC13892_REGULATORMODE0_VUSB2MODE	(1<<20)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define MC13892_REGULATORMODE1			33
11862306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VGEN3EN		(1<<0)
11962306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VGEN3STDBY	(1<<1)
12062306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VGEN3MODE	(1<<2)
12162306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VCAMEN		(1<<6)
12262306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VCAMSTDBY	(1<<7)
12362306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VCAMMODE		(1<<8)
12462306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VCAMCONFIGEN	(1<<9)
12562306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VVIDEOEN		(1<<12)
12662306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VVIDEOSTDBY	(1<<13)
12762306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VVIDEOMODE	(1<<14)
12862306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VAUDIOEN		(1<<15)
12962306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VAUDIOSTDBY	(1<<16)
13062306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VAUDIOMODE	(1<<17)
13162306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VSDEN		(1<<18)
13262306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VSDSTDBY		(1<<19)
13362306a36Sopenharmony_ci#define MC13892_REGULATORMODE1_VSDMODE		(1<<20)
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define MC13892_POWERMISC			34
13662306a36Sopenharmony_ci#define MC13892_POWERMISC_GPO1EN		(1<<6)
13762306a36Sopenharmony_ci#define MC13892_POWERMISC_GPO2EN		(1<<8)
13862306a36Sopenharmony_ci#define MC13892_POWERMISC_GPO3EN		(1<<10)
13962306a36Sopenharmony_ci#define MC13892_POWERMISC_GPO4EN		(1<<12)
14062306a36Sopenharmony_ci#define MC13892_POWERMISC_PWGT1SPIEN		(1<<15)
14162306a36Sopenharmony_ci#define MC13892_POWERMISC_PWGT2SPIEN		(1<<16)
14262306a36Sopenharmony_ci#define MC13892_POWERMISC_GPO4ADINEN		(1<<21)
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci#define MC13892_POWERMISC_PWGTSPI_M		(3 << 15)
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci#define MC13892_USB1				50
14762306a36Sopenharmony_ci#define MC13892_USB1_VUSBEN			(1<<3)
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic const unsigned int mc13892_vcoincell[] = {
15062306a36Sopenharmony_ci	2500000, 2700000, 2800000, 2900000, 3000000, 3100000,
15162306a36Sopenharmony_ci	3200000, 3300000,
15262306a36Sopenharmony_ci};
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic const unsigned int mc13892_sw1[] = {
15562306a36Sopenharmony_ci	600000,   625000,  650000,  675000,  700000,  725000,
15662306a36Sopenharmony_ci	750000,   775000,  800000,  825000,  850000,  875000,
15762306a36Sopenharmony_ci	900000,   925000,  950000,  975000, 1000000, 1025000,
15862306a36Sopenharmony_ci	1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
15962306a36Sopenharmony_ci	1200000, 1225000, 1250000, 1275000, 1300000, 1325000,
16062306a36Sopenharmony_ci	1350000, 1375000
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci * Note: this table is used to derive SWxVSEL by index into
16562306a36Sopenharmony_ci * the array. Offset the values by the index of 1100000uV
16662306a36Sopenharmony_ci * to get the actual register value for that voltage selector
16762306a36Sopenharmony_ci * if the HI bit is to be set as well.
16862306a36Sopenharmony_ci */
16962306a36Sopenharmony_ci#define MC13892_SWxHI_SEL_OFFSET		20
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistatic const unsigned int mc13892_sw[] = {
17262306a36Sopenharmony_ci	600000,   625000,  650000,  675000,  700000,  725000,
17362306a36Sopenharmony_ci	750000,   775000,  800000,  825000,  850000,  875000,
17462306a36Sopenharmony_ci	900000,   925000,  950000,  975000, 1000000, 1025000,
17562306a36Sopenharmony_ci	1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
17662306a36Sopenharmony_ci	1200000, 1225000, 1250000, 1275000, 1300000, 1325000,
17762306a36Sopenharmony_ci	1350000, 1375000, 1400000, 1425000, 1450000, 1475000,
17862306a36Sopenharmony_ci	1500000, 1525000, 1550000, 1575000, 1600000, 1625000,
17962306a36Sopenharmony_ci	1650000, 1675000, 1700000, 1725000, 1750000, 1775000,
18062306a36Sopenharmony_ci	1800000, 1825000, 1850000, 1875000
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic const unsigned int mc13892_swbst[] = {
18462306a36Sopenharmony_ci	5000000,
18562306a36Sopenharmony_ci};
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic const unsigned int mc13892_viohi[] = {
18862306a36Sopenharmony_ci	2775000,
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistatic const unsigned int mc13892_vpll[] = {
19262306a36Sopenharmony_ci	1050000, 1250000, 1650000, 1800000,
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_cistatic const unsigned int mc13892_vdig[] = {
19662306a36Sopenharmony_ci	1050000, 1250000, 1650000, 1800000,
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistatic const unsigned int mc13892_vsd[] = {
20062306a36Sopenharmony_ci	1800000, 2000000, 2600000, 2700000,
20162306a36Sopenharmony_ci	2800000, 2900000, 3000000, 3150000,
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_cistatic const unsigned int mc13892_vusb2[] = {
20562306a36Sopenharmony_ci	2400000, 2600000, 2700000, 2775000,
20662306a36Sopenharmony_ci};
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistatic const unsigned int mc13892_vvideo[] = {
20962306a36Sopenharmony_ci	2700000, 2775000, 2500000, 2600000,
21062306a36Sopenharmony_ci};
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistatic const unsigned int mc13892_vaudio[] = {
21362306a36Sopenharmony_ci	2300000, 2500000, 2775000, 3000000,
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic const unsigned int mc13892_vcam[] = {
21762306a36Sopenharmony_ci	2500000, 2600000, 2750000, 3000000,
21862306a36Sopenharmony_ci};
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_cistatic const unsigned int mc13892_vgen1[] = {
22162306a36Sopenharmony_ci	1200000, 1500000, 2775000, 3150000,
22262306a36Sopenharmony_ci};
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistatic const unsigned int mc13892_vgen2[] = {
22562306a36Sopenharmony_ci	1200000, 1500000, 1600000, 1800000,
22662306a36Sopenharmony_ci	2700000, 2800000, 3000000, 3150000,
22762306a36Sopenharmony_ci};
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic const unsigned int mc13892_vgen3[] = {
23062306a36Sopenharmony_ci	1800000, 2900000,
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic const unsigned int mc13892_vusb[] = {
23462306a36Sopenharmony_ci	3300000,
23562306a36Sopenharmony_ci};
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_cistatic const unsigned int mc13892_gpo[] = {
23862306a36Sopenharmony_ci	2750000,
23962306a36Sopenharmony_ci};
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic const unsigned int mc13892_pwgtdrv[] = {
24262306a36Sopenharmony_ci	5000000,
24362306a36Sopenharmony_ci};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistatic const struct regulator_ops mc13892_gpo_regulator_ops;
24662306a36Sopenharmony_cistatic const struct regulator_ops mc13892_sw_regulator_ops;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci#define MC13892_FIXED_DEFINE(name, node, reg, voltages)			\
25062306a36Sopenharmony_ci	MC13xxx_FIXED_DEFINE(MC13892_, name, node, reg, voltages,	\
25162306a36Sopenharmony_ci			mc13xxx_fixed_regulator_ops)
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci#define MC13892_GPO_DEFINE(name, node, reg, voltages)			\
25462306a36Sopenharmony_ci	MC13xxx_GPO_DEFINE(MC13892_, name, node, reg, voltages,		\
25562306a36Sopenharmony_ci			mc13892_gpo_regulator_ops)
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci#define MC13892_SW_DEFINE(name, node, reg, vsel_reg, voltages)		\
25862306a36Sopenharmony_ci	MC13xxx_DEFINE(MC13892_, name, node, reg, vsel_reg, voltages,	\
25962306a36Sopenharmony_ci			mc13892_sw_regulator_ops)
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci#define MC13892_DEFINE_REGU(name, node, reg, vsel_reg, voltages)	\
26262306a36Sopenharmony_ci	MC13xxx_DEFINE(MC13892_, name, node, reg, vsel_reg, voltages, \
26362306a36Sopenharmony_ci			mc13xxx_regulator_ops)
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cistatic struct mc13xxx_regulator mc13892_regulators[] = {
26662306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VCOINCELL, vcoincell, POWERCTL0, POWERCTL0, mc13892_vcoincell),
26762306a36Sopenharmony_ci	MC13892_SW_DEFINE(SW1, sw1, SWITCHERS0, SWITCHERS0, mc13892_sw1),
26862306a36Sopenharmony_ci	MC13892_SW_DEFINE(SW2, sw2, SWITCHERS1, SWITCHERS1, mc13892_sw),
26962306a36Sopenharmony_ci	MC13892_SW_DEFINE(SW3, sw3, SWITCHERS2, SWITCHERS2, mc13892_sw),
27062306a36Sopenharmony_ci	MC13892_SW_DEFINE(SW4, sw4, SWITCHERS3, SWITCHERS3, mc13892_sw),
27162306a36Sopenharmony_ci	MC13892_FIXED_DEFINE(SWBST, swbst, SWITCHERS5, mc13892_swbst),
27262306a36Sopenharmony_ci	MC13892_FIXED_DEFINE(VIOHI, viohi, REGULATORMODE0, mc13892_viohi),
27362306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VPLL, vpll, REGULATORMODE0, REGULATORSETTING0,
27462306a36Sopenharmony_ci		mc13892_vpll),
27562306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VDIG, vdig, REGULATORMODE0, REGULATORSETTING0,
27662306a36Sopenharmony_ci		mc13892_vdig),
27762306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VSD, vsd, REGULATORMODE1, REGULATORSETTING1,
27862306a36Sopenharmony_ci		mc13892_vsd),
27962306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VUSB2, vusb2, REGULATORMODE0, REGULATORSETTING0,
28062306a36Sopenharmony_ci		mc13892_vusb2),
28162306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VVIDEO, vvideo, REGULATORMODE1, REGULATORSETTING1,
28262306a36Sopenharmony_ci		mc13892_vvideo),
28362306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VAUDIO, vaudio, REGULATORMODE1, REGULATORSETTING1,
28462306a36Sopenharmony_ci		mc13892_vaudio),
28562306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VCAM, vcam, REGULATORMODE1, REGULATORSETTING0,
28662306a36Sopenharmony_ci		mc13892_vcam),
28762306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VGEN1, vgen1, REGULATORMODE0, REGULATORSETTING0,
28862306a36Sopenharmony_ci		mc13892_vgen1),
28962306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VGEN2, vgen2, REGULATORMODE0, REGULATORSETTING0,
29062306a36Sopenharmony_ci		mc13892_vgen2),
29162306a36Sopenharmony_ci	MC13892_DEFINE_REGU(VGEN3, vgen3, REGULATORMODE1, REGULATORSETTING0,
29262306a36Sopenharmony_ci		mc13892_vgen3),
29362306a36Sopenharmony_ci	MC13892_FIXED_DEFINE(VUSB, vusb, USB1, mc13892_vusb),
29462306a36Sopenharmony_ci	MC13892_GPO_DEFINE(GPO1, gpo1, POWERMISC, mc13892_gpo),
29562306a36Sopenharmony_ci	MC13892_GPO_DEFINE(GPO2, gpo2, POWERMISC, mc13892_gpo),
29662306a36Sopenharmony_ci	MC13892_GPO_DEFINE(GPO3, gpo3, POWERMISC, mc13892_gpo),
29762306a36Sopenharmony_ci	MC13892_GPO_DEFINE(GPO4, gpo4, POWERMISC, mc13892_gpo),
29862306a36Sopenharmony_ci	MC13892_GPO_DEFINE(PWGT1SPI, pwgt1spi, POWERMISC, mc13892_pwgtdrv),
29962306a36Sopenharmony_ci	MC13892_GPO_DEFINE(PWGT2SPI, pwgt2spi, POWERMISC, mc13892_pwgtdrv),
30062306a36Sopenharmony_ci};
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistatic int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
30362306a36Sopenharmony_ci				 u32 val)
30462306a36Sopenharmony_ci{
30562306a36Sopenharmony_ci	struct mc13xxx *mc13892 = priv->mc13xxx;
30662306a36Sopenharmony_ci	int ret;
30762306a36Sopenharmony_ci	u32 valread;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	BUG_ON(val & ~mask);
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
31262306a36Sopenharmony_ci	ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread);
31362306a36Sopenharmony_ci	if (ret)
31462306a36Sopenharmony_ci		goto out;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	/* Update the stored state for Power Gates. */
31762306a36Sopenharmony_ci	priv->powermisc_pwgt_state =
31862306a36Sopenharmony_ci		(priv->powermisc_pwgt_state & ~mask) | val;
31962306a36Sopenharmony_ci	priv->powermisc_pwgt_state &= MC13892_POWERMISC_PWGTSPI_M;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	/* Construct the new register value */
32262306a36Sopenharmony_ci	valread = (valread & ~mask) | val;
32362306a36Sopenharmony_ci	/* Overwrite the PWGTxEN with the stored version */
32462306a36Sopenharmony_ci	valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) |
32562306a36Sopenharmony_ci		priv->powermisc_pwgt_state;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	ret = mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread);
32862306a36Sopenharmony_ciout:
32962306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
33062306a36Sopenharmony_ci	return ret;
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic int mc13892_gpo_regulator_enable(struct regulator_dev *rdev)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
33662306a36Sopenharmony_ci	int id = rdev_get_id(rdev);
33762306a36Sopenharmony_ci	u32 en_val = mc13892_regulators[id].enable_bit;
33862306a36Sopenharmony_ci	u32 mask = mc13892_regulators[id].enable_bit;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	/* Power Gate enable value is 0 */
34362306a36Sopenharmony_ci	if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI)
34462306a36Sopenharmony_ci		en_val = 0;
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	if (id == MC13892_GPO4)
34762306a36Sopenharmony_ci		mask |= MC13892_POWERMISC_GPO4ADINEN;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	return mc13892_powermisc_rmw(priv, mask, en_val);
35062306a36Sopenharmony_ci}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_cistatic int mc13892_gpo_regulator_disable(struct regulator_dev *rdev)
35362306a36Sopenharmony_ci{
35462306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
35562306a36Sopenharmony_ci	int id = rdev_get_id(rdev);
35662306a36Sopenharmony_ci	u32 dis_val = 0;
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	/* Power Gate disable value is 1 */
36162306a36Sopenharmony_ci	if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI)
36262306a36Sopenharmony_ci		dis_val = mc13892_regulators[id].enable_bit;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	return mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit,
36562306a36Sopenharmony_ci		dis_val);
36662306a36Sopenharmony_ci}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistatic int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev)
36962306a36Sopenharmony_ci{
37062306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
37162306a36Sopenharmony_ci	int ret, id = rdev_get_id(rdev);
37262306a36Sopenharmony_ci	unsigned int val;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
37562306a36Sopenharmony_ci	ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val);
37662306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	if (ret)
37962306a36Sopenharmony_ci		return ret;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	/* Power Gates state is stored in powermisc_pwgt_state
38262306a36Sopenharmony_ci	 * where the meaning of bits is negated */
38362306a36Sopenharmony_ci	val = (val & ~MC13892_POWERMISC_PWGTSPI_M) |
38462306a36Sopenharmony_ci		(priv->powermisc_pwgt_state ^ MC13892_POWERMISC_PWGTSPI_M);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	return (val & mc13892_regulators[id].enable_bit) != 0;
38762306a36Sopenharmony_ci}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_cistatic const struct regulator_ops mc13892_gpo_regulator_ops = {
39162306a36Sopenharmony_ci	.enable = mc13892_gpo_regulator_enable,
39262306a36Sopenharmony_ci	.disable = mc13892_gpo_regulator_disable,
39362306a36Sopenharmony_ci	.is_enabled = mc13892_gpo_regulator_is_enabled,
39462306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_table,
39562306a36Sopenharmony_ci	.set_voltage = mc13xxx_fixed_regulator_set_voltage,
39662306a36Sopenharmony_ci};
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_cistatic int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev)
39962306a36Sopenharmony_ci{
40062306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
40162306a36Sopenharmony_ci	int ret, id = rdev_get_id(rdev);
40262306a36Sopenharmony_ci	unsigned int val, selector;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
40762306a36Sopenharmony_ci	ret = mc13xxx_reg_read(priv->mc13xxx,
40862306a36Sopenharmony_ci		mc13892_regulators[id].vsel_reg, &val);
40962306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
41062306a36Sopenharmony_ci	if (ret)
41162306a36Sopenharmony_ci		return ret;
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	/*
41462306a36Sopenharmony_ci	 * Figure out if the HI bit is set inside the switcher mode register
41562306a36Sopenharmony_ci	 * since this means the selector value we return is at a different
41662306a36Sopenharmony_ci	 * offset into the selector table.
41762306a36Sopenharmony_ci	 *
41862306a36Sopenharmony_ci	 * According to the MC13892 documentation note 59 (Table 47) the SW1
41962306a36Sopenharmony_ci	 * buck switcher does not support output range programming therefore
42062306a36Sopenharmony_ci	 * the HI bit must always remain 0. So do not do anything strange if
42162306a36Sopenharmony_ci	 * our register is MC13892_SWITCHERS0.
42262306a36Sopenharmony_ci	 */
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	selector = val & mc13892_regulators[id].vsel_mask;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	if ((mc13892_regulators[id].vsel_reg != MC13892_SWITCHERS0) &&
42762306a36Sopenharmony_ci	    (val & MC13892_SWITCHERS0_SWxHI)) {
42862306a36Sopenharmony_ci		selector += MC13892_SWxHI_SEL_OFFSET;
42962306a36Sopenharmony_ci	}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	dev_dbg(rdev_get_dev(rdev), "%s id: %d val: 0x%08x selector: %d\n",
43262306a36Sopenharmony_ci			__func__, id, val, selector);
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	return selector;
43562306a36Sopenharmony_ci}
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_cistatic int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
43862306a36Sopenharmony_ci						unsigned selector)
43962306a36Sopenharmony_ci{
44062306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
44162306a36Sopenharmony_ci	int volt, mask, id = rdev_get_id(rdev);
44262306a36Sopenharmony_ci	u32 reg_value;
44362306a36Sopenharmony_ci	int ret;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	volt = rdev->desc->volt_table[selector];
44662306a36Sopenharmony_ci	mask = mc13892_regulators[id].vsel_mask;
44762306a36Sopenharmony_ci	reg_value = selector;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	/*
45062306a36Sopenharmony_ci	 * Don't mess with the HI bit or support HI voltage offsets for SW1.
45162306a36Sopenharmony_ci	 *
45262306a36Sopenharmony_ci	 * Since the get_voltage_sel callback has given a fudged value for
45362306a36Sopenharmony_ci	 * the selector offset, we need to back out that offset if HI is
45462306a36Sopenharmony_ci	 * to be set so we write the correct value to the register.
45562306a36Sopenharmony_ci	 *
45662306a36Sopenharmony_ci	 * The HI bit addition and selector offset handling COULD be more
45762306a36Sopenharmony_ci	 * complicated by shifting and masking off the voltage selector part
45862306a36Sopenharmony_ci	 * of the register then logical OR it back in, but since the selector
45962306a36Sopenharmony_ci	 * is at bits 4:0 there is very little point. This makes the whole
46062306a36Sopenharmony_ci	 * thing more readable and we do far less work.
46162306a36Sopenharmony_ci	 */
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	if (mc13892_regulators[id].vsel_reg != MC13892_SWITCHERS0) {
46462306a36Sopenharmony_ci		mask |= MC13892_SWITCHERS0_SWxHI;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci		if (volt > 1375000) {
46762306a36Sopenharmony_ci			reg_value -= MC13892_SWxHI_SEL_OFFSET;
46862306a36Sopenharmony_ci			reg_value |= MC13892_SWITCHERS0_SWxHI;
46962306a36Sopenharmony_ci		} else {
47062306a36Sopenharmony_ci			reg_value &= ~MC13892_SWITCHERS0_SWxHI;
47162306a36Sopenharmony_ci		}
47262306a36Sopenharmony_ci	}
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
47562306a36Sopenharmony_ci	ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
47662306a36Sopenharmony_ci			      mask, reg_value);
47762306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	return ret;
48062306a36Sopenharmony_ci}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_cistatic const struct regulator_ops mc13892_sw_regulator_ops = {
48362306a36Sopenharmony_ci	.list_voltage = regulator_list_voltage_table,
48462306a36Sopenharmony_ci	.map_voltage = regulator_map_voltage_ascend,
48562306a36Sopenharmony_ci	.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
48662306a36Sopenharmony_ci	.get_voltage_sel = mc13892_sw_regulator_get_voltage_sel,
48762306a36Sopenharmony_ci};
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_cistatic int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode)
49062306a36Sopenharmony_ci{
49162306a36Sopenharmony_ci	unsigned int en_val = 0;
49262306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
49362306a36Sopenharmony_ci	int ret, id = rdev_get_id(rdev);
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	if (mode == REGULATOR_MODE_FAST)
49662306a36Sopenharmony_ci		en_val = MC13892_REGULATORMODE1_VCAMCONFIGEN;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
49962306a36Sopenharmony_ci	ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg,
50062306a36Sopenharmony_ci		MC13892_REGULATORMODE1_VCAMCONFIGEN, en_val);
50162306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	return ret;
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_cistatic unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev)
50762306a36Sopenharmony_ci{
50862306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
50962306a36Sopenharmony_ci	int ret, id = rdev_get_id(rdev);
51062306a36Sopenharmony_ci	unsigned int val;
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	mc13xxx_lock(priv->mc13xxx);
51362306a36Sopenharmony_ci	ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val);
51462306a36Sopenharmony_ci	mc13xxx_unlock(priv->mc13xxx);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	if (ret)
51762306a36Sopenharmony_ci		return ret;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	if (val & MC13892_REGULATORMODE1_VCAMCONFIGEN)
52062306a36Sopenharmony_ci		return REGULATOR_MODE_FAST;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	return REGULATOR_MODE_NORMAL;
52362306a36Sopenharmony_ci}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_cistatic struct regulator_ops mc13892_vcam_ops;
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_cistatic int mc13892_regulator_probe(struct platform_device *pdev)
52862306a36Sopenharmony_ci{
52962306a36Sopenharmony_ci	struct mc13xxx_regulator_priv *priv;
53062306a36Sopenharmony_ci	struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
53162306a36Sopenharmony_ci	struct mc13xxx_regulator_platform_data *pdata =
53262306a36Sopenharmony_ci		dev_get_platdata(&pdev->dev);
53362306a36Sopenharmony_ci	struct mc13xxx_regulator_init_data *mc13xxx_data;
53462306a36Sopenharmony_ci	struct regulator_config config = { };
53562306a36Sopenharmony_ci	int i, ret;
53662306a36Sopenharmony_ci	int num_regulators = 0;
53762306a36Sopenharmony_ci	u32 val;
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	num_regulators = mc13xxx_get_num_regulators_dt(pdev);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	if (num_regulators <= 0 && pdata)
54262306a36Sopenharmony_ci		num_regulators = pdata->num_regulators;
54362306a36Sopenharmony_ci	if (num_regulators <= 0)
54462306a36Sopenharmony_ci		return -EINVAL;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	priv = devm_kzalloc(&pdev->dev,
54762306a36Sopenharmony_ci			    struct_size(priv, regulators, num_regulators),
54862306a36Sopenharmony_ci			    GFP_KERNEL);
54962306a36Sopenharmony_ci	if (!priv)
55062306a36Sopenharmony_ci		return -ENOMEM;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	priv->num_regulators = num_regulators;
55362306a36Sopenharmony_ci	priv->mc13xxx_regulators = mc13892_regulators;
55462306a36Sopenharmony_ci	priv->mc13xxx = mc13892;
55562306a36Sopenharmony_ci	platform_set_drvdata(pdev, priv);
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	mc13xxx_lock(mc13892);
55862306a36Sopenharmony_ci	ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val);
55962306a36Sopenharmony_ci	if (ret)
56062306a36Sopenharmony_ci		goto err_unlock;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	/* enable switch auto mode (on 2.0A silicon only) */
56362306a36Sopenharmony_ci	if ((val & 0x0000FFFF) == 0x45d0) {
56462306a36Sopenharmony_ci		ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4,
56562306a36Sopenharmony_ci			MC13892_SWITCHERS4_SW1MODE_M |
56662306a36Sopenharmony_ci			MC13892_SWITCHERS4_SW2MODE_M,
56762306a36Sopenharmony_ci			MC13892_SWITCHERS4_SW1MODE_AUTO |
56862306a36Sopenharmony_ci			MC13892_SWITCHERS4_SW2MODE_AUTO);
56962306a36Sopenharmony_ci		if (ret)
57062306a36Sopenharmony_ci			goto err_unlock;
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci		ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5,
57362306a36Sopenharmony_ci			MC13892_SWITCHERS5_SW3MODE_M |
57462306a36Sopenharmony_ci			MC13892_SWITCHERS5_SW4MODE_M,
57562306a36Sopenharmony_ci			MC13892_SWITCHERS5_SW3MODE_AUTO |
57662306a36Sopenharmony_ci			MC13892_SWITCHERS5_SW4MODE_AUTO);
57762306a36Sopenharmony_ci		if (ret)
57862306a36Sopenharmony_ci			goto err_unlock;
57962306a36Sopenharmony_ci	}
58062306a36Sopenharmony_ci	mc13xxx_unlock(mc13892);
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	/* update mc13892_vcam ops */
58362306a36Sopenharmony_ci	memcpy(&mc13892_vcam_ops, mc13892_regulators[MC13892_VCAM].desc.ops,
58462306a36Sopenharmony_ci						sizeof(struct regulator_ops));
58562306a36Sopenharmony_ci	mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode;
58662306a36Sopenharmony_ci	mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode;
58762306a36Sopenharmony_ci	mc13892_regulators[MC13892_VCAM].desc.ops = &mc13892_vcam_ops;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
59062306a36Sopenharmony_ci					ARRAY_SIZE(mc13892_regulators));
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	for (i = 0; i < priv->num_regulators; i++) {
59362306a36Sopenharmony_ci		struct regulator_init_data *init_data;
59462306a36Sopenharmony_ci		struct regulator_desc *desc;
59562306a36Sopenharmony_ci		struct device_node *node = NULL;
59662306a36Sopenharmony_ci		int id;
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci		if (mc13xxx_data) {
59962306a36Sopenharmony_ci			id = mc13xxx_data[i].id;
60062306a36Sopenharmony_ci			init_data = mc13xxx_data[i].init_data;
60162306a36Sopenharmony_ci			node = mc13xxx_data[i].node;
60262306a36Sopenharmony_ci		} else {
60362306a36Sopenharmony_ci			id = pdata->regulators[i].id;
60462306a36Sopenharmony_ci			init_data = pdata->regulators[i].init_data;
60562306a36Sopenharmony_ci		}
60662306a36Sopenharmony_ci		desc = &mc13892_regulators[id].desc;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci		config.dev = &pdev->dev;
60962306a36Sopenharmony_ci		config.init_data = init_data;
61062306a36Sopenharmony_ci		config.driver_data = priv;
61162306a36Sopenharmony_ci		config.of_node = node;
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci		priv->regulators[i] = devm_regulator_register(&pdev->dev, desc,
61462306a36Sopenharmony_ci							      &config);
61562306a36Sopenharmony_ci		if (IS_ERR(priv->regulators[i])) {
61662306a36Sopenharmony_ci			dev_err(&pdev->dev, "failed to register regulator %s\n",
61762306a36Sopenharmony_ci				mc13892_regulators[i].desc.name);
61862306a36Sopenharmony_ci			return PTR_ERR(priv->regulators[i]);
61962306a36Sopenharmony_ci		}
62062306a36Sopenharmony_ci	}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	return 0;
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_cierr_unlock:
62562306a36Sopenharmony_ci	mc13xxx_unlock(mc13892);
62662306a36Sopenharmony_ci	return ret;
62762306a36Sopenharmony_ci}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistatic struct platform_driver mc13892_regulator_driver = {
63062306a36Sopenharmony_ci	.driver	= {
63162306a36Sopenharmony_ci		.name	= "mc13892-regulator",
63262306a36Sopenharmony_ci		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
63362306a36Sopenharmony_ci	},
63462306a36Sopenharmony_ci	.probe	= mc13892_regulator_probe,
63562306a36Sopenharmony_ci};
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic int __init mc13892_regulator_init(void)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	return platform_driver_register(&mc13892_regulator_driver);
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_cisubsys_initcall(mc13892_regulator_init);
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_cistatic void __exit mc13892_regulator_exit(void)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	platform_driver_unregister(&mc13892_regulator_driver);
64662306a36Sopenharmony_ci}
64762306a36Sopenharmony_cimodule_exit(mc13892_regulator_exit);
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
65062306a36Sopenharmony_ciMODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
65162306a36Sopenharmony_ciMODULE_DESCRIPTION("Regulator Driver for Freescale MC13892 PMIC");
65262306a36Sopenharmony_ciMODULE_ALIAS("platform:mc13892-regulator");
653