Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2518480 authored by Robin Gong's avatar Robin Gong Committed by Mark Brown
Browse files

regulator: pfuze100: add pfuze200 support



support pfuze200 chip which remove SW1C and SW4 based on pfuze100.

Signed-off-by: default avatarRobin Gong <b38343@freescale.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 6428789e
Loading
Loading
Loading
Loading
+94 −2
Original line number Diff line number Diff line
PFUZE100 family of regulators

Required properties:
- compatible: "fsl,pfuze100"
- compatible: "fsl,pfuze100" or "fsl,pfuze200"
- reg: I2C slave address

Required child node:
@@ -10,11 +10,14 @@ Required child node:
  Documentation/devicetree/bindings/regulator/regulator.txt.

  The valid names for regulators are:
  --PFUZE100
  sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6
  --PFUZE200
  sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6

Each regulator is defined using the standard binding for regulators.

Example:
Example 1: PFUZE100

	pmic: pfuze100@08 {
		compatible = "fsl,pfuze100";
@@ -113,3 +116,92 @@ Example:
			};
		};
	};


Example 2: PFUZE200

	pmic: pfuze200@08 {
		compatible = "fsl,pfuze200";
		reg = <0x08>;

		regulators {
			sw1a_reg: sw1ab {
				regulator-min-microvolt = <300000>;
				regulator-max-microvolt = <1875000>;
				regulator-boot-on;
				regulator-always-on;
				regulator-ramp-delay = <6250>;
			};

			sw2_reg: sw2 {
				regulator-min-microvolt = <800000>;
				regulator-max-microvolt = <3300000>;
				regulator-boot-on;
				regulator-always-on;
			};

			sw3a_reg: sw3a {
				regulator-min-microvolt = <400000>;
				regulator-max-microvolt = <1975000>;
				regulator-boot-on;
				regulator-always-on;
			};

			sw3b_reg: sw3b {
				regulator-min-microvolt = <400000>;
				regulator-max-microvolt = <1975000>;
				regulator-boot-on;
				regulator-always-on;
			};

			swbst_reg: swbst {
				regulator-min-microvolt = <5000000>;
				regulator-max-microvolt = <5150000>;
			};

			snvs_reg: vsnvs {
				regulator-min-microvolt = <1000000>;
				regulator-max-microvolt = <3000000>;
				regulator-boot-on;
				regulator-always-on;
			};

			vref_reg: vrefddr {
				regulator-boot-on;
				regulator-always-on;
			};

			vgen1_reg: vgen1 {
				regulator-min-microvolt = <800000>;
				regulator-max-microvolt = <1550000>;
			};

			vgen2_reg: vgen2 {
				regulator-min-microvolt = <800000>;
				regulator-max-microvolt = <1550000>;
			};

			vgen3_reg: vgen3 {
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;
			};

			vgen4_reg: vgen4 {
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;
				regulator-always-on;
			};

			vgen5_reg: vgen5 {
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;
				regulator-always-on;
			};

			vgen6_reg: vgen6 {
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;
				regulator-always-on;
			};
		};
	};
+143 −53
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@
#define PFUZE100_VGEN5VOL	0x70
#define PFUZE100_VGEN6VOL	0x71

enum chips {PFUZE100, PFUZE200, PFUZE_NUM};

struct pfuze_regulator {
	struct regulator_desc desc;
	unsigned char stby_reg;
@@ -63,6 +65,7 @@ struct pfuze_regulator {
};

struct pfuze_chip {
	int	chip_id;
	struct regmap *regmap;
	struct device *dev;
	struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
@@ -77,15 +80,15 @@ static const int pfuze100_vsnvs[] = {
	1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000,
};

static const struct i2c_device_id pfuze_device_id[] = {
	{.name = "pfuze100"},
	{},
static const struct i2c_device_id pfuze_device_id[PFUZE_NUM] = {
	{.name = "pfuze100", .driver_data = PFUZE100},
	{.name = "pfuze200", .driver_data = PFUZE200},
};
MODULE_DEVICE_TABLE(i2c, pfuze_device_id);

static const struct of_device_id pfuze_dt_ids[] = {
	{ .compatible = "fsl,pfuze100" },
	{},
static const struct of_device_id pfuze_dt_ids[PFUZE_NUM] = {
	{ .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
	{ .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
};
MODULE_DEVICE_TABLE(of, pfuze_dt_ids);

@@ -139,14 +142,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {

};

#define PFUZE100_FIXED_REG(_name, base, voltage)	\
	[PFUZE100_ ## _name] = {	\
#define PFUZE100_FIXED_REG(_chip, _name, base, voltage)	\
	[_chip ## _ ## _name] = {	\
		.desc = {	\
			.name = #_name,	\
			.n_voltages = 1,	\
			.ops = &pfuze100_fixed_regulator_ops,	\
			.type = REGULATOR_VOLTAGE,	\
			.id = PFUZE100_ ## _name,	\
			.id = _chip ## _ ## _name,	\
			.owner = THIS_MODULE,	\
			.min_uV = (voltage),	\
			.enable_reg = (base),	\
@@ -154,14 +157,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
		},	\
	}

#define PFUZE100_SW_REG(_name, base, min, max, step)	\
	[PFUZE100_ ## _name] = {	\
#define PFUZE100_SW_REG(_chip, _name, base, min, max, step)	\
	[_chip ## _ ## _name] = {	\
		.desc = {	\
			.name = #_name,\
			.n_voltages = ((max) - (min)) / (step) + 1,	\
			.ops = &pfuze100_sw_regulator_ops,	\
			.type = REGULATOR_VOLTAGE,	\
			.id = PFUZE100_ ## _name,	\
			.id = _chip ## _ ## _name,	\
			.owner = THIS_MODULE,	\
			.min_uV = (min),	\
			.uV_step = (step),	\
@@ -172,14 +175,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
		.stby_mask = 0x3f,	\
	}

#define PFUZE100_SWB_REG(_name, base, mask, voltages)	\
	[PFUZE100_ ## _name] = {	\
#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages)	\
	[_chip ## _ ##  _name] = {	\
		.desc = {	\
			.name = #_name,	\
			.n_voltages = ARRAY_SIZE(voltages),	\
			.ops = &pfuze100_swb_regulator_ops,	\
			.type = REGULATOR_VOLTAGE,	\
			.id = PFUZE100_ ## _name,	\
			.id = _chip ## _ ## _name,	\
			.owner = THIS_MODULE,	\
			.volt_table = voltages,	\
			.vsel_reg = (base),	\
@@ -187,14 +190,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
		},	\
	}

#define PFUZE100_VGEN_REG(_name, base, min, max, step)	\
	[PFUZE100_ ## _name] = {	\
#define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step)	\
	[_chip ## _ ## _name] = {	\
		.desc = {	\
			.name = #_name,	\
			.n_voltages = ((max) - (min)) / (step) + 1,	\
			.ops = &pfuze100_ldo_regulator_ops,	\
			.type = REGULATOR_VOLTAGE,	\
			.id = PFUZE100_ ## _name,	\
			.id = _chip ## _ ## _name,	\
			.owner = THIS_MODULE,	\
			.min_uV = (min),	\
			.uV_step = (step),	\
@@ -207,25 +210,45 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
		.stby_mask = 0x20,	\
	}

/* PFUZE100 */
static struct pfuze_regulator pfuze100_regulators[] = {
	PFUZE100_SW_REG(SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
	PFUZE100_SW_REG(SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
	PFUZE100_SW_REG(SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
	PFUZE100_SWB_REG(SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
	PFUZE100_SWB_REG(VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
	PFUZE100_FIXED_REG(VREFDDR, PFUZE100_VREFDDRCON, 750000),
	PFUZE100_VGEN_REG(VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
	PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
	PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
	PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
	PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
	PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
	PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};

static struct pfuze_regulator pfuze200_regulators[] = {
	PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
	PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
	PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
	PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
	PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
	PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
	PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};

static struct pfuze_regulator *pfuze_regulators;

#ifdef CONFIG_OF
/* PFUZE100 */
static struct of_regulator_match pfuze100_matches[] = {
	{ .name = "sw1ab",	},
	{ .name = "sw1c",	},
@@ -244,6 +267,26 @@ static struct of_regulator_match pfuze100_matches[] = {
	{ .name = "vgen6",	},
};

/* PFUZE200 */
static struct of_regulator_match pfuze200_matches[] = {

	{ .name = "sw1ab",	},
	{ .name = "sw2",	},
	{ .name = "sw3a",	},
	{ .name = "sw3b",	},
	{ .name = "swbst",	},
	{ .name = "vsnvs",	},
	{ .name = "vrefddr",	},
	{ .name = "vgen1",	},
	{ .name = "vgen2",	},
	{ .name = "vgen3",	},
	{ .name = "vgen4",	},
	{ .name = "vgen5",	},
	{ .name = "vgen6",	},
};

static struct of_regulator_match *pfuze_matches;

static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
{
	struct device *dev = chip->dev;
@@ -260,8 +303,20 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
		return -EINVAL;
	}

	switch (chip->chip_id) {
	case PFUZE200:
		pfuze_matches = pfuze200_matches;
		ret = of_regulator_match(dev, parent, pfuze200_matches,
					 ARRAY_SIZE(pfuze200_matches));
		break;

	case PFUZE100:
	default:
		pfuze_matches = pfuze100_matches;
		ret = of_regulator_match(dev, parent, pfuze100_matches,
					 ARRAY_SIZE(pfuze100_matches));
		break;
	}

	of_node_put(parent);
	if (ret < 0) {
@@ -275,12 +330,12 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)

static inline struct regulator_init_data *match_init_data(int index)
{
	return pfuze100_matches[index].init_data;
	return pfuze_matches[index].init_data;
}

static inline struct device_node *match_of_node(int index)
{
	return pfuze100_matches[index].of_node;
	return pfuze_matches[index].of_node;
}
#else
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
@@ -308,16 +363,14 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
	if (ret)
		return ret;

	switch (value & 0x0f) {
	if (((value & 0x0f) == 0x8) && (pfuze_chip->chip_id == PFUZE100)) {
		/*
		 * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013
	 * as ID=8
		 * as ID=8 in PFUZE100
		 */
	case 0x8:
		dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
	case 0x0:
		break;
	default:
	} else if ((value & 0x0f) != pfuze_chip->chip_id) {
		/* device id NOT match with your setting */
		dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
		return -ENODEV;
	}
@@ -353,17 +406,31 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
	    dev_get_platdata(&client->dev);
	struct regulator_config config = { };
	int i, ret;
	const struct of_device_id *match;
	u32 regulator_num;
	u32 sw_check_start, sw_check_end;

	pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
			GFP_KERNEL);
	if (!pfuze_chip)
		return -ENOMEM;

	i2c_set_clientdata(client, pfuze_chip);

	memcpy(pfuze_chip->regulator_descs, pfuze100_regulators,
		sizeof(pfuze_chip->regulator_descs));
	if (client->dev.of_node) {
		match = of_match_device(of_match_ptr(pfuze_dt_ids),
				&client->dev);
		if (!match) {
			dev_err(&client->dev, "Error: No device match found\n");
			return -ENODEV;
		}
		pfuze_chip->chip_id = (int)(long)match->data;
	} else if (id) {
		pfuze_chip->chip_id = id->driver_data;
	} else {
		dev_err(&client->dev, "No dts match or id table match found\n");
		return -ENODEV;
	}

	i2c_set_clientdata(client, pfuze_chip);
	pfuze_chip->dev = &client->dev;

	pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config);
@@ -380,11 +447,34 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
		return ret;
	}

	/* use the right regulators after identify the right device */
	switch (pfuze_chip->chip_id) {
	case PFUZE200:
		pfuze_regulators = pfuze200_regulators;
		regulator_num = ARRAY_SIZE(pfuze200_regulators);
		sw_check_start = PFUZE200_SW2;
		sw_check_end = PFUZE200_SW3B;
		break;

	case PFUZE100:
	default:
		pfuze_regulators = pfuze100_regulators;
		regulator_num = ARRAY_SIZE(pfuze100_regulators);
		sw_check_start = PFUZE100_SW2;
		sw_check_end = PFUZE100_SW4;
		break;
	}
	dev_info(&client->dev, "pfuze%s found.\n",
		(pfuze_chip->chip_id == PFUZE100) ? "100" : "200");

	memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
		sizeof(pfuze_chip->regulator_descs));

	ret = pfuze_parse_regulators_dt(pfuze_chip);
	if (ret)
		return ret;

	for (i = 0; i < PFUZE100_MAX_REGULATOR; i++) {
	for (i = 0; i < regulator_num; i++) {
		struct regulator_init_data *init_data;
		struct regulator_desc *desc;
		int val;
@@ -397,7 +487,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
			init_data = match_init_data(i);

		/* SW2~SW4 high bit check and modify the voltage value table */
		if (i > PFUZE100_SW1C && i < PFUZE100_SWBST) {
		if (i >= sw_check_start && i <= sw_check_end) {
			regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
			if (val & 0x40) {
				desc->min_uV = 800000;
@@ -415,7 +505,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
			devm_regulator_register(&client->dev, desc, &config);
		if (IS_ERR(pfuze_chip->regulators[i])) {
			dev_err(&client->dev, "register regulator%s failed\n",
				pfuze100_regulators[i].desc.name);
				pfuze_regulators[i].desc.name);
			return PTR_ERR(pfuze_chip->regulators[i]);
		}
	}
+14 −0
Original line number Diff line number Diff line
@@ -35,6 +35,20 @@
#define PFUZE100_VGEN6		14
#define PFUZE100_MAX_REGULATOR	15

#define PFUZE200_SW1AB		0
#define PFUZE200_SW2		1
#define PFUZE200_SW3A		2
#define PFUZE200_SW3B		3
#define PFUZE200_SWBST		4
#define PFUZE200_VSNVS		5
#define PFUZE200_VREFDDR	6
#define PFUZE200_VGEN1		7
#define PFUZE200_VGEN2		8
#define PFUZE200_VGEN3		9
#define PFUZE200_VGEN4		10
#define PFUZE200_VGEN5		11
#define PFUZE200_VGEN6		12

struct regulator_init_data;

struct pfuze_regulator_platform_data {