cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpcap-regulator.c (18373B)


      1/*
      2 * Motorola CPCAP PMIC regulator driver
      3 *
      4 * Based on cpcap-regulator.c from Motorola Linux kernel tree
      5 * Copyright (C) 2009-2011 Motorola, Inc.
      6 *
      7 * Rewritten for mainline kernel to use device tree and regmap
      8 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
      9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License as
     12 * published by the Free Software Foundation version 2.
     13 *
     14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
     15 * kind, whether express or implied; without even the implied warranty
     16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     17 * GNU General Public License for more details.
     18 */
     19
     20#include <linux/err.h>
     21#include <linux/module.h>
     22#include <linux/of.h>
     23#include <linux/of_platform.h>
     24#include <linux/regmap.h>
     25#include <linux/regulator/driver.h>
     26#include <linux/regulator/machine.h>
     27#include <linux/regulator/of_regulator.h>
     28#include <linux/mfd/motorola-cpcap.h>
     29
     30/*
     31 * Resource assignment register bits. These seem to control the state
     32 * idle modes adn are used at least for omap4.
     33 */
     34
     35/* CPCAP_REG_ASSIGN2 bits - Resource Assignment 2 */
     36#define CPCAP_BIT_VSDIO_SEL		BIT(15)
     37#define CPCAP_BIT_VDIG_SEL		BIT(14)
     38#define CPCAP_BIT_VCAM_SEL		BIT(13)
     39#define CPCAP_BIT_SW6_SEL		BIT(12)
     40#define CPCAP_BIT_SW5_SEL		BIT(11)
     41#define CPCAP_BIT_SW4_SEL		BIT(10)
     42#define CPCAP_BIT_SW3_SEL		BIT(9)
     43#define CPCAP_BIT_SW2_SEL		BIT(8)
     44#define CPCAP_BIT_SW1_SEL		BIT(7)
     45
     46/* CPCAP_REG_ASSIGN3 bits - Resource Assignment 3 */
     47#define CPCAP_BIT_VUSBINT2_SEL		BIT(15)
     48#define CPCAP_BIT_VUSBINT1_SEL		BIT(14)
     49#define CPCAP_BIT_VVIB_SEL		BIT(13)
     50#define CPCAP_BIT_VWLAN1_SEL		BIT(12)
     51#define CPCAP_BIT_VRF1_SEL		BIT(11)
     52#define CPCAP_BIT_VHVIO_SEL		BIT(10)
     53#define CPCAP_BIT_VDAC_SEL		BIT(9)
     54#define CPCAP_BIT_VUSB_SEL		BIT(8)
     55#define CPCAP_BIT_VSIM_SEL		BIT(7)
     56#define CPCAP_BIT_VRFREF_SEL		BIT(6)
     57#define CPCAP_BIT_VPLL_SEL		BIT(5)
     58#define CPCAP_BIT_VFUSE_SEL		BIT(4)
     59#define CPCAP_BIT_VCSI_SEL		BIT(3)
     60#define CPCAP_BIT_SPARE_14_2		BIT(2)
     61#define CPCAP_BIT_VWLAN2_SEL		BIT(1)
     62#define CPCAP_BIT_VRF2_SEL		BIT(0)
     63
     64/* CPCAP_REG_ASSIGN4 bits - Resource Assignment 4 */
     65#define CPCAP_BIT_VAUDIO_SEL		BIT(0)
     66
     67/*
     68 * Enable register bits. At least CPCAP_BIT_AUDIO_LOW_PWR is generic,
     69 * and not limited to audio regulator. Let's use the Motorola kernel
     70 * naming for now until we have a better understanding of the other
     71 * enable register bits. No idea why BIT(3) is not defined.
     72 */
     73#define CPCAP_BIT_AUDIO_LOW_PWR		BIT(6)
     74#define CPCAP_BIT_AUD_LOWPWR_SPEED	BIT(5)
     75#define CPCAP_BIT_VAUDIOPRISTBY		BIT(4)
     76#define CPCAP_BIT_VAUDIO_MODE1		BIT(2)
     77#define CPCAP_BIT_VAUDIO_MODE0		BIT(1)
     78#define CPCAP_BIT_V_AUDIO_EN		BIT(0)
     79
     80#define CPCAP_BIT_AUDIO_NORMAL_MODE	0x00
     81
     82/*
     83 * Off mode configuration bit. Used currently only by SW5 on omap4. There's
     84 * the following comment in Motorola Linux kernel tree for it:
     85 *
     86 * When set in the regulator mode, the regulator assignment will be changed
     87 * to secondary when the regulator is disabled. The mode will be set back to
     88 * primary when the regulator is turned on.
     89 */
     90#define CPCAP_REG_OFF_MODE_SEC		BIT(15)
     91
     92/*
     93 * SoC specific configuration for CPCAP regulator. There are at least three
     94 * different SoCs each with their own parameters: omap3, omap4 and tegra2.
     95 *
     96 * The assign_reg and assign_mask seem to allow toggling between primary
     97 * and secondary mode that at least omap4 uses for off mode.
     98 */
     99struct cpcap_regulator {
    100	struct regulator_desc rdesc;
    101	const u16 assign_reg;
    102	const u16 assign_mask;
    103};
    104
    105#define CPCAP_REG(_ID, reg, assignment_reg, assignment_mask, val_tbl,	\
    106		mode_mask, volt_mask, mode_val, off_val,		\
    107		volt_trans_time) {					\
    108	.rdesc = {							\
    109		.name = #_ID,						\
    110		.of_match = of_match_ptr(#_ID),				\
    111		.ops = &cpcap_regulator_ops,				\
    112		.regulators_node = of_match_ptr("regulators"),		\
    113		.type = REGULATOR_VOLTAGE,				\
    114		.id = CPCAP_##_ID,					\
    115		.owner = THIS_MODULE,					\
    116		.n_voltages = ARRAY_SIZE(val_tbl),			\
    117		.volt_table = (val_tbl),				\
    118		.vsel_reg = (reg),					\
    119		.vsel_mask = (volt_mask),				\
    120		.enable_reg = (reg),					\
    121		.enable_mask = (mode_mask),				\
    122		.enable_val = (mode_val),				\
    123		.disable_val = (off_val),				\
    124		.ramp_delay = (volt_trans_time),			\
    125		.of_map_mode = cpcap_map_mode,				\
    126	},								\
    127	.assign_reg = (assignment_reg),					\
    128	.assign_mask = (assignment_mask),				\
    129}
    130
    131struct cpcap_ddata {
    132	struct regmap *reg;
    133	struct device *dev;
    134	const struct cpcap_regulator *soc;
    135};
    136
    137enum cpcap_regulator_id {
    138	CPCAP_SW1,
    139	CPCAP_SW2,
    140	CPCAP_SW3,
    141	CPCAP_SW4,
    142	CPCAP_SW5,
    143	CPCAP_SW6,
    144	CPCAP_VCAM,
    145	CPCAP_VCSI,
    146	CPCAP_VDAC,
    147	CPCAP_VDIG,
    148	CPCAP_VFUSE,
    149	CPCAP_VHVIO,
    150	CPCAP_VSDIO,
    151	CPCAP_VPLL,
    152	CPCAP_VRF1,
    153	CPCAP_VRF2,
    154	CPCAP_VRFREF,
    155	CPCAP_VWLAN1,
    156	CPCAP_VWLAN2,
    157	CPCAP_VSIM,
    158	CPCAP_VSIMCARD,
    159	CPCAP_VVIB,
    160	CPCAP_VUSB,
    161	CPCAP_VAUDIO,
    162	CPCAP_NR_REGULATORS,
    163};
    164
    165/*
    166 * We need to also configure regulator idle mode for SoC off mode if
    167 * CPCAP_REG_OFF_MODE_SEC is set.
    168 */
    169static int cpcap_regulator_enable(struct regulator_dev *rdev)
    170{
    171	struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
    172	int error;
    173
    174	error = regulator_enable_regmap(rdev);
    175	if (error)
    176		return error;
    177
    178	if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
    179		error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
    180					   regulator->assign_mask,
    181					   regulator->assign_mask);
    182		if (error)
    183			regulator_disable_regmap(rdev);
    184	}
    185
    186	return error;
    187}
    188
    189/*
    190 * We need to also configure regulator idle mode for SoC off mode if
    191 * CPCAP_REG_OFF_MODE_SEC is set.
    192 */
    193static int cpcap_regulator_disable(struct regulator_dev *rdev)
    194{
    195	struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
    196	int error;
    197
    198	if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
    199		error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
    200					   regulator->assign_mask, 0);
    201		if (error)
    202			return error;
    203	}
    204
    205	error = regulator_disable_regmap(rdev);
    206	if (error && (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC)) {
    207		regmap_update_bits(rdev->regmap, regulator->assign_reg,
    208				   regulator->assign_mask,
    209				   regulator->assign_mask);
    210	}
    211
    212	return error;
    213}
    214
    215static unsigned int cpcap_map_mode(unsigned int mode)
    216{
    217	switch (mode) {
    218	case CPCAP_BIT_AUDIO_NORMAL_MODE:
    219		return REGULATOR_MODE_NORMAL;
    220	case CPCAP_BIT_AUDIO_LOW_PWR:
    221		return REGULATOR_MODE_STANDBY;
    222	default:
    223		return REGULATOR_MODE_INVALID;
    224	}
    225}
    226
    227static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev)
    228{
    229	int value;
    230
    231	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
    232
    233	if (value & CPCAP_BIT_AUDIO_LOW_PWR)
    234		return REGULATOR_MODE_STANDBY;
    235
    236	return REGULATOR_MODE_NORMAL;
    237}
    238
    239static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
    240				    unsigned int mode)
    241{
    242	int value;
    243
    244	switch (mode) {
    245	case REGULATOR_MODE_NORMAL:
    246		value = CPCAP_BIT_AUDIO_NORMAL_MODE;
    247		break;
    248	case REGULATOR_MODE_STANDBY:
    249		value = CPCAP_BIT_AUDIO_LOW_PWR;
    250		break;
    251	default:
    252		return -EINVAL;
    253	}
    254
    255	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
    256				  CPCAP_BIT_AUDIO_LOW_PWR, value);
    257}
    258
    259static const struct regulator_ops cpcap_regulator_ops = {
    260	.enable = cpcap_regulator_enable,
    261	.disable = cpcap_regulator_disable,
    262	.is_enabled = regulator_is_enabled_regmap,
    263	.list_voltage = regulator_list_voltage_table,
    264	.map_voltage = regulator_map_voltage_iterate,
    265	.get_voltage_sel = regulator_get_voltage_sel_regmap,
    266	.set_voltage_sel = regulator_set_voltage_sel_regmap,
    267	.get_mode = cpcap_regulator_get_mode,
    268	.set_mode = cpcap_regulator_set_mode,
    269};
    270
    271static const unsigned int unknown_val_tbl[] = { 0, };
    272static const unsigned int sw2_sw4_val_tbl[] = { 612500, 625000, 637500,
    273						650000, 662500, 675000,
    274						687500, 700000, 712500,
    275						725000, 737500, 750000,
    276						762500, 775000, 787500,
    277						800000, 812500, 825000,
    278						837500, 850000, 862500,
    279						875000, 887500, 900000,
    280						912500, 925000, 937500,
    281						950000, 962500, 975000,
    282						987500, 1000000, 1012500,
    283						1025000, 1037500, 1050000,
    284						1062500, 1075000, 1087500,
    285						1100000, 1112500, 1125000,
    286						1137500, 1150000, 1162500,
    287						1175000, 1187500, 1200000,
    288						1212500, 1225000, 1237500,
    289						1250000, 1262500, 1275000,
    290						1287500, 1300000, 1312500,
    291						1325000, 1337500, 1350000,
    292						1362500, 1375000, 1387500,
    293						1400000, 1412500, 1425000,
    294						1437500, 1450000, 1462500, };
    295static const unsigned int sw5_val_tbl[] = { 0, 5050000, };
    296static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000,
    297					     2900000, };
    298static const unsigned int vcsi_val_tbl[] = { 1200000, 1800000, };
    299static const unsigned int vdac_val_tbl[] = { 1200000, 1500000, 1800000,
    300					     2500000,};
    301static const unsigned int vdig_val_tbl[] = { 1200000, 1350000, 1500000,
    302					     1875000, };
    303static const unsigned int vfuse_val_tbl[] = { 1500000, 1600000, 1700000,
    304					      1800000, 1900000, 2000000,
    305					      2100000, 2200000, 2300000,
    306					      2400000, 2500000, 2600000,
    307					      2700000, 3150000, };
    308static const unsigned int vhvio_val_tbl[] = { 2775000, };
    309static const unsigned int vsdio_val_tbl[] = { 1500000, 1600000, 1800000,
    310					      2600000, 2700000, 2800000,
    311					      2900000, 3000000, };
    312static const unsigned int vpll_val_tbl[] = { 1200000, 1300000, 1400000,
    313					     1800000, };
    314/* Quirk: 2775000 is before 2500000 for vrf1 regulator */
    315static const unsigned int vrf1_val_tbl[] = { 2775000, 2500000, };
    316static const unsigned int vrf2_val_tbl[] = { 0, 2775000, };
    317static const unsigned int vrfref_val_tbl[] = { 2500000, 2775000, };
    318static const unsigned int vwlan1_val_tbl[] = { 1800000, 1900000, };
    319static const unsigned int vwlan2_val_tbl[] = { 2775000, 3000000, 3300000,
    320					       3300000, };
    321static const unsigned int vsim_val_tbl[] = { 1800000, 2900000, };
    322static const unsigned int vsimcard_val_tbl[] = { 1800000, 2900000, };
    323static const unsigned int vvib_val_tbl[] = { 1300000, 1800000, 2000000,
    324					     3000000, };
    325static const unsigned int vusb_val_tbl[] = { 0, 3300000, };
    326static const unsigned int vaudio_val_tbl[] = { 0, 2775000, };
    327
    328/*
    329 * SoC specific configuration for omap4. The data below is comes from Motorola
    330 * Linux kernel tree. It's basically the values of cpcap_regltr_data,
    331 * cpcap_regulator_mode_values and cpcap_regulator_off_mode_values, see
    332 * CPCAP_REG macro above.
    333 *
    334 * SW1 to SW4 and SW6 seems to be unused for mapphone. Note that VSIM and
    335 * VSIMCARD have a shared resource assignment bit.
    336 */
    337static const struct cpcap_regulator omap4_regulators[] = {
    338	CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
    339		  CPCAP_BIT_SW1_SEL, unknown_val_tbl,
    340		  0, 0, 0, 0, 0),
    341	CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
    342		  CPCAP_BIT_SW2_SEL, unknown_val_tbl,
    343		  0, 0, 0, 0, 0),
    344	CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
    345		  CPCAP_BIT_SW3_SEL, unknown_val_tbl,
    346		  0, 0, 0, 0, 0),
    347	CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
    348		  CPCAP_BIT_SW4_SEL, unknown_val_tbl,
    349		  0, 0, 0, 0, 0),
    350	CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
    351		  CPCAP_BIT_SW5_SEL, sw5_val_tbl,
    352		  0x28, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0),
    353	CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
    354		  CPCAP_BIT_SW6_SEL, unknown_val_tbl,
    355		  0, 0, 0, 0, 0),
    356	CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
    357		  CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
    358		  0x87, 0x30, 0x3, 0, 420),
    359	CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
    360		  CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
    361		  0x47, 0x10, 0x43, 0x41, 350),
    362	CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
    363		  CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
    364		  0x87, 0x30, 0x3, 0, 420),
    365	CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
    366		  CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
    367		  0x87, 0x30, 0x82, 0, 420),
    368	CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
    369		  CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
    370		  0x80, 0xf, 0x80, 0, 420),
    371	CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
    372		  CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
    373		  0x17, 0, 0, 0x12, 0),
    374	CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
    375		  CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
    376		  0x87, 0x38, 0x82, 0, 420),
    377	CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
    378		  CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
    379		  0x43, 0x18, 0x2, 0, 420),
    380	CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
    381		  CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
    382		  0xac, 0x2, 0x4, 0, 10),
    383	CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
    384		  CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
    385		  0x23, 0x8, 0, 0, 10),
    386	CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
    387		  CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
    388		  0x23, 0x8, 0, 0, 420),
    389	CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
    390		  CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
    391		  0x47, 0x10, 0, 0, 420),
    392	CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
    393		  CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
    394		  0x20c, 0xc0, 0x20c, 0, 420),
    395	CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
    396		  0xffff, vsim_val_tbl,
    397		  0x23, 0x8, 0x3, 0, 420),
    398	CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
    399		  0xffff, vsimcard_val_tbl,
    400		  0x1e80, 0x8, 0x1e00, 0, 420),
    401	CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
    402		  CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
    403		  0x1, 0xc, 0x1, 0, 500),
    404	CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
    405		  CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
    406		  0x11c, 0x40, 0xc, 0, 0),
    407	CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
    408		  CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
    409		  0x16, 0x1, 0x4, 0, 0),
    410	{ /* sentinel */ },
    411};
    412
    413static const struct cpcap_regulator xoom_regulators[] = {
    414	CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
    415		  CPCAP_BIT_SW1_SEL, unknown_val_tbl,
    416		  0, 0, 0, 0, 0),
    417	CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
    418		  CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl,
    419		  0xf00, 0x7f, 0x800, 0, 120),
    420	CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
    421		  CPCAP_BIT_SW3_SEL, unknown_val_tbl,
    422		  0, 0, 0, 0, 0),
    423	CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
    424		  CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl,
    425		  0xf00, 0x7f, 0x900, 0, 100),
    426	CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
    427		  CPCAP_BIT_SW5_SEL, sw5_val_tbl,
    428		  0x2a, 0, 0x22, 0, 0),
    429	CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
    430		  CPCAP_BIT_SW6_SEL, unknown_val_tbl,
    431		  0, 0, 0, 0, 0),
    432	CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
    433		  CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
    434		  0x87, 0x30, 0x7, 0, 420),
    435	CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
    436		  CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
    437		  0x47, 0x10, 0x7, 0, 350),
    438	CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
    439		  CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
    440		  0x87, 0x30, 0x3, 0, 420),
    441	CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
    442		  CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
    443		  0x87, 0x30, 0x5, 0, 420),
    444	CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
    445		  CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
    446		  0x80, 0xf, 0x80, 0, 420),
    447	CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
    448		  CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
    449		  0x17, 0, 0x2, 0, 0),
    450	CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
    451		  CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
    452		  0x87, 0x38, 0x2, 0, 420),
    453	CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
    454		  CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
    455		  0x43, 0x18, 0x1, 0, 420),
    456	CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
    457		  CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
    458		  0xac, 0x2, 0xc, 0, 10),
    459	CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
    460		  CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
    461		  0x23, 0x8, 0x3, 0, 10),
    462	CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
    463		  CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
    464		  0x23, 0x8, 0x3, 0, 420),
    465	CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
    466		  CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
    467		  0x47, 0x10, 0x5, 0, 420),
    468	CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
    469		  CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
    470		  0x20c, 0xc0, 0x8, 0, 420),
    471	CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
    472		  0xffff, vsim_val_tbl,
    473		  0x23, 0x8, 0x3, 0, 420),
    474	CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
    475		  0xffff, vsimcard_val_tbl,
    476		  0x1e80, 0x8, 0x1e00, 0, 420),
    477	CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
    478		  CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
    479		  0x1, 0xc, 0, 0x1, 500),
    480	CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
    481		  CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
    482		  0x11c, 0x40, 0xc, 0, 0),
    483	CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
    484		  CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
    485		  0x16, 0x1, 0x4, 0, 0),
    486	{ /* sentinel */ },
    487};
    488
    489static const struct of_device_id cpcap_regulator_id_table[] = {
    490	{
    491		.compatible = "motorola,cpcap-regulator",
    492	},
    493	{
    494		.compatible = "motorola,mapphone-cpcap-regulator",
    495		.data = omap4_regulators,
    496	},
    497	{
    498		.compatible = "motorola,xoom-cpcap-regulator",
    499		.data = xoom_regulators,
    500	},
    501	{},
    502};
    503MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
    504
    505static int cpcap_regulator_probe(struct platform_device *pdev)
    506{
    507	struct cpcap_ddata *ddata;
    508	const struct cpcap_regulator *match_data;
    509	struct regulator_config config;
    510	int i;
    511
    512	match_data = of_device_get_match_data(&pdev->dev);
    513	if (!match_data) {
    514		dev_err(&pdev->dev, "no configuration data found\n");
    515
    516		return -ENODEV;
    517	}
    518
    519	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
    520	if (!ddata)
    521		return -ENOMEM;
    522
    523	ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
    524	if (!ddata->reg)
    525		return -ENODEV;
    526
    527	ddata->dev = &pdev->dev;
    528	ddata->soc = match_data;
    529	platform_set_drvdata(pdev, ddata);
    530
    531	memset(&config, 0, sizeof(config));
    532	config.dev = &pdev->dev;
    533	config.regmap = ddata->reg;
    534
    535	for (i = 0; i < CPCAP_NR_REGULATORS; i++) {
    536		const struct cpcap_regulator *regulator = &ddata->soc[i];
    537		struct regulator_dev *rdev;
    538
    539		if (!regulator->rdesc.name)
    540			break;
    541
    542		if (regulator->rdesc.volt_table == unknown_val_tbl)
    543			continue;
    544
    545		config.driver_data = (void *)regulator;
    546		rdev = devm_regulator_register(&pdev->dev,
    547					       &regulator->rdesc,
    548					       &config);
    549		if (IS_ERR(rdev)) {
    550			dev_err(&pdev->dev, "failed to register regulator %s\n",
    551				regulator->rdesc.name);
    552
    553			return PTR_ERR(rdev);
    554		}
    555	}
    556
    557	return 0;
    558}
    559
    560static struct platform_driver cpcap_regulator_driver = {
    561	.probe		= cpcap_regulator_probe,
    562	.driver		= {
    563		.name	= "cpcap-regulator",
    564		.of_match_table = of_match_ptr(cpcap_regulator_id_table),
    565	},
    566};
    567
    568module_platform_driver(cpcap_regulator_driver);
    569
    570MODULE_ALIAS("platform:cpcap-regulator");
    571MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
    572MODULE_DESCRIPTION("CPCAP regulator driver");
    573MODULE_LICENSE("GPL v2");