static struct tps51632_regulator_platform_data *
of_get_tps51632_platform_data(struct device *dev)
{
    struct tps51632_regulator_platform_data *pdata;
    struct device_node *np = dev->of_node;

    pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
    if (!pdata) {
        dev_err(dev, "Memory alloc failed for platform data\n");
        return NULL;
    }

    pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
    if (!pdata->reg_init_data) {
        dev_err(dev, "Not able to get OF regulator init data\n");
        return NULL;
    }

    pdata->enable_pwm_dvfs =
        of_property_read_bool(np, "ti,enable-pwm-dvfs");
    pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV");

    pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? :
                             TPS51632_MIN_VOLATGE;
    pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? :
                            TPS51632_MAX_VOLATGE;
    return pdata;
}
static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
					struct regulator_config *config)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct arizona_micsupp *micsupp = config->driver_data;
	struct device_node *np;
	struct regulator_init_data *init_data;

	np = of_get_child_by_name(arizona->dev->of_node, "micvdd");

	if (np) {
		config->of_node = np;

		init_data = of_get_regulator_init_data(arizona->dev, np);

		if (init_data) {
			init_data->consumer_supplies = &micsupp->supply;
			init_data->num_consumer_supplies = 1;

			pdata->micvdd = init_data;
		}
	}

	return 0;
}
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
                                     struct regulator_config *config)
{
    struct arizona_pdata *pdata = &arizona->pdata;
    struct arizona_ldo1 *ldo1 = config->driver_data;
    struct device_node *init_node, *dcvdd_node;
    struct regulator_init_data *init_data;

    pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true);

    init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1");
    dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0);

    if (init_node) {
        config->of_node = init_node;

        init_data = of_get_regulator_init_data(arizona->dev, init_node);

        if (init_data) {
            init_data->consumer_supplies = &ldo1->supply;
            init_data->num_consumer_supplies = 1;

            if (dcvdd_node && dcvdd_node != init_node)
                arizona->external_dcvdd = true;

            pdata->ldo1 = init_data;
        }
    } else if (dcvdd_node) {
        arizona->external_dcvdd = true;
    }

    of_node_put(dcvdd_node);

    return 0;
}
static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
{
	struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
	struct regulator_config config = { };
	int ret;

	/* First disable the external VMMC if it's active */
	ret = regmap_update_bits(stw481x->map, STW_CONF2,
				 STW_CONF2_VMMC_EXT, 0);
	if (ret) {
		dev_err(&pdev->dev, "could not disable external VMMC\n");
		return ret;
	}

	/* Register VMMC regulator */
	config.dev = &pdev->dev;
	config.driver_data = stw481x;
	config.regmap = stw481x->map;
	config.of_node = pdev->dev.of_node;
	config.init_data = of_get_regulator_init_data(&pdev->dev,
						      pdev->dev.of_node);

	stw481x->vmmc_regulator = regulator_register(&vmmc_regulator, &config);
	if (IS_ERR(stw481x->vmmc_regulator)) {
		dev_err(&pdev->dev,
			"error initializing STw481x VMMC regulator\n");
		return PTR_ERR(stw481x->vmmc_regulator);
	}

	dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n");
	return 0;
}
示例#5
0
文件: 88pm8607.c 项目: 020gzh/linux
static int pm8607_regulator_dt_init(struct platform_device *pdev,
				    struct pm8607_regulator_info *info,
				    struct regulator_config *config)
{
	struct device_node *nproot, *np;
	nproot = pdev->dev.parent->of_node;
	if (!nproot)
		return -ENODEV;
	nproot = of_get_child_by_name(nproot, "regulators");
	if (!nproot) {
		dev_err(&pdev->dev, "failed to find regulators node\n");
		return -ENODEV;
	}
	for_each_child_of_node(nproot, np) {
		if (!of_node_cmp(np->name, info->desc.name)) {
			config->init_data =
				of_get_regulator_init_data(&pdev->dev, np,
							   &info->desc);
			config->of_node = np;
			break;
		}
	}
	of_node_put(nproot);
	return 0;
}
示例#6
0
static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
				     struct regulator_config *config,
				     const struct regulator_desc *desc,
				     bool *external_dcvdd)
{
	struct arizona_ldo1 *ldo1 = config->driver_data;
	struct device_node *np = config->dev->of_node;
	struct device_node *init_node, *dcvdd_node;
	struct regulator_init_data *init_data;

	init_node = of_get_child_by_name(np, "ldo1");
	dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0);

	if (init_node) {
		config->of_node = init_node;

		init_data = of_get_regulator_init_data(config->dev, init_node,
						       desc);
		if (init_data) {
			init_data->consumer_supplies = &ldo1->supply;
			init_data->num_consumer_supplies = 1;

			if (dcvdd_node && dcvdd_node != init_node)
				*external_dcvdd = true;

			pdata->init_data = init_data;
		}
	} else if (dcvdd_node) {
		*external_dcvdd = true;
	}

	of_node_put(dcvdd_node);

	return 0;
}
示例#7
0
/**
 * of_regulator_match - extract multiple regulator init data from device tree.
 * @dev: device requesting the data
 * @node: parent device node of the regulators
 * @matches: match table for the regulators
 * @num_matches: number of entries in match table
 *
 * This function uses a match table specified by the regulator driver to
 * parse regulator init data from the device tree. @node is expected to
 * contain a set of child nodes, each providing the init data for one
 * regulator. The data parsed from a child node will be matched to a regulator
 * based on either the deprecated property regulator-compatible if present,
 * or otherwise the child node's name. Note that the match table is modified
 * in place and an additional of_node reference is taken for each matched
 * regulator.
 *
 * Returns the number of matches found or a negative error code on failure.
 */
int of_regulator_match(struct device *dev, struct device_node *node,
		       struct of_regulator_match *matches,
		       unsigned int num_matches)
{
	unsigned int count = 0;
	unsigned int i;
	const char *name;
	struct device_node *child;
	struct devm_of_regulator_matches *devm_matches;

	if (!dev || !node)
		return -EINVAL;

	devm_matches = devres_alloc(devm_of_regulator_put_matches,
				    sizeof(struct devm_of_regulator_matches),
				    GFP_KERNEL);
	if (!devm_matches)
		return -ENOMEM;

	devm_matches->matches = matches;
	devm_matches->num_matches = num_matches;

	devres_add(dev, devm_matches);

	for (i = 0; i < num_matches; i++) {
		struct of_regulator_match *match = &matches[i];
		match->init_data = NULL;
		match->of_node = NULL;
	}

	for_each_child_of_node(node, child) {
		name = of_get_property(child,
					"regulator-compatible", NULL);
		if (!name)
			name = child->name;
		for (i = 0; i < num_matches; i++) {
			struct of_regulator_match *match = &matches[i];
			if (match->of_node)
				continue;

			if (strcmp(match->name, name))
				continue;

			match->init_data =
				of_get_regulator_init_data(dev, child,
							   match->desc);
			if (!match->init_data) {
				dev_err(dev,
					"failed to parse DT for regulator %pOFn\n",
					child);
				of_node_put(child);
				return -EINVAL;
			}
			match->of_node = of_node_get(child);
			count++;
			break;
		}
	}
示例#8
0
/**
 * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
 * @dev: device requesting for fixed_voltage_config
 *
 * Populates fixed_voltage_config structure by extracting data from device
 * tree node, returns a pointer to the populated structure of NULL if memory
 * alloc fails.
 */
static struct fixed_voltage_config *
of_get_fixed_voltage_config(struct device *dev)
{
	struct fixed_voltage_config *config;
	struct device_node *np = dev->of_node;
	const __be32 *delay;
	struct regulator_init_data *init_data;

	config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
								 GFP_KERNEL);
	if (!config)
		return ERR_PTR(-ENOMEM);

	config->init_data = of_get_regulator_init_data(dev, dev->of_node);
	if (!config->init_data)
		return ERR_PTR(-EINVAL);

	init_data = config->init_data;
	init_data->constraints.apply_uV = 0;

	config->supply_name = init_data->constraints.name;
	if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
		config->microvolts = init_data->constraints.min_uV;
	} else {
		dev_err(dev,
			 "Fixed regulator specified with variable voltages\n");
		return ERR_PTR(-EINVAL);
	}

	if (init_data->constraints.boot_on)
		config->enabled_at_boot = true;

	config->gpio = of_get_named_gpio(np, "gpio", 0);
	/*
	 * of_get_named_gpio() currently returns ENODEV rather than
	 * EPROBE_DEFER. This code attempts to be compatible with both
	 * for now; the ENODEV check can be removed once the API is fixed.
	 * of_get_named_gpio() doesn't differentiate between a missing
	 * property (which would be fine here, since the GPIO is optional)
	 * and some other error. Patches have been posted for both issues.
	 * Once they are check in, we should replace this with:
	 * if (config->gpio < 0 && config->gpio != -ENOENT)
	 */
	if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER))
		return ERR_PTR(-EPROBE_DEFER);

	delay = of_get_property(np, "startup-delay-us", NULL);
	if (delay)
		config->startup_delay = be32_to_cpu(*delay);

	if (of_find_property(np, "enable-active-high", NULL))
		config->enable_high = true;

	if (of_find_property(np, "parent-supply", NULL))
		init_data->supply_regulator = "parent";

	return config;
}
示例#9
0
文件: s2mps13.c 项目: qkdang/m462
static int s2mps13_pmic_dt_parse_pdata(struct sec_pmic_dev *iodev,
					struct sec_platform_data *pdata)
{
	struct device_node *pmic_np, *regulators_np, *reg_np;
	struct sec_regulator_data *rdata;
	unsigned int i;

	pmic_np = iodev->dev->of_node;
	if (!pmic_np) {
		dev_err(iodev->dev, "could not find pmic sub-node\n");
		return -ENODEV;
	}

	regulators_np = of_find_node_by_name(pmic_np, "regulators");
	if (!regulators_np) {
		dev_err(iodev->dev, "could not find regulators sub-node\n");
		return -EINVAL;
	}

	/* count the number of regulators to be supported in pmic */
	pdata->num_regulators = 0;
	for_each_child_of_node(regulators_np, reg_np) {
		pdata->num_regulators++;
	}

	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
				pdata->num_regulators, GFP_KERNEL);
	if (!rdata) {
		dev_err(iodev->dev,
			"could not allocate memory for regulator data\n");
		return -ENOMEM;
	}

	pdata->regulators = rdata;
	s2mps13_desc_type = iodev->rev_num ? S2MPS13_DESC_TYPE1 : S2MPS13_DESC_TYPE0;
	for_each_child_of_node(regulators_np, reg_np) {
		for (i = 0; i < ARRAY_SIZE(regulators[s2mps13_desc_type]); i++)
			if (!of_node_cmp(reg_np->name,
					regulators[s2mps13_desc_type][i].name))
				break;

		if (i == ARRAY_SIZE(regulators[s2mps13_desc_type])) {
			dev_warn(iodev->dev,
			"don't know how to configure regulator %s\n",
			reg_np->name);
			continue;
		}

		rdata->id = i;
		rdata->initdata = of_get_regulator_init_data(
						iodev->dev, reg_np);
		rdata->reg_node = reg_np;
		rdata++;
	}

	return 0;
}
static int mem_acc_regulator_probe(struct platform_device *pdev)
{
	struct mem_acc_regulator *mem_acc_vreg;
	struct regulator_desc *rdesc;
	struct regulator_init_data *init_data;
	int rc;

	if (!pdev->dev.of_node) {
		pr_err("Device tree node is missing\n");
		return -EINVAL;
	}

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
	if (!init_data) {
		pr_err("regulator init data is missing\n");
		return -EINVAL;
	} else {
		init_data->constraints.input_uV
			= init_data->constraints.max_uV;
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_VOLTAGE;
	}

	mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg),
			GFP_KERNEL);
	if (!mem_acc_vreg) {
		pr_err("Can't allocate mem_acc_vreg memory\n");
		return -ENOMEM;
	}
	mem_acc_vreg->dev = &pdev->dev;

	rc = mem_acc_init(pdev, mem_acc_vreg);
	if (rc) {
		pr_err("Unable to initialize mem_acc configuration rc=%d\n",
				rc);
		return rc;
	}

	rdesc			= &mem_acc_vreg->rdesc;
	rdesc->owner		= THIS_MODULE;
	rdesc->type		= REGULATOR_VOLTAGE;
	rdesc->ops		= &mem_acc_corner_ops;
	rdesc->name		= init_data->constraints.name;

	mem_acc_vreg->rdev = regulator_register(rdesc, &pdev->dev,
				init_data, mem_acc_vreg, pdev->dev.of_node);
	if (IS_ERR(mem_acc_vreg->rdev)) {
		rc = PTR_ERR(mem_acc_vreg->rdev);
		if (rc != -EPROBE_DEFER)
			pr_err("regulator_register failed: rc=%d\n", rc);
		return rc;
	}

	platform_set_drvdata(pdev, mem_acc_vreg);

	return 0;
}
示例#11
0
static int pwm_regulator_probe(struct platform_device *pdev)
{
	const struct regulator_init_data *init_data;
	struct pwm_regulator_data *drvdata;
	struct regulator_dev *regulator;
	struct regulator_config config = { };
	struct device_node *np = pdev->dev.of_node;
	int ret;

	if (!np) {
		dev_err(&pdev->dev, "Device Tree node missing\n");
		return -EINVAL;
	}

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

	if (of_find_property(np, "voltage-table", NULL))
		ret = pwm_regulator_init_table(pdev, drvdata);
	else
		ret = pwm_regulator_init_continuous(pdev, drvdata);
	if (ret)
		return ret;

	init_data = of_get_regulator_init_data(&pdev->dev, np,
					       &pwm_regulator_desc);
	if (!init_data)
		return -ENOMEM;

	config.of_node = np;
	config.dev = &pdev->dev;
	config.driver_data = drvdata;
	config.init_data = init_data;

	drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(drvdata->pwm)) {
		dev_err(&pdev->dev, "Failed to get PWM\n");
		return PTR_ERR(drvdata->pwm);
	}

	regulator = devm_regulator_register(&pdev->dev,
					    &pwm_regulator_desc, &config);
	if (IS_ERR(regulator)) {
		dev_err(&pdev->dev, "Failed to register regulator %s\n",
			pwm_regulator_desc.name);
		return PTR_ERR(regulator);
	}

	return 0;
}
示例#12
0
struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
	int num_regulators)
{
	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
	struct mc13xxx_regulator_init_data *data, *p;
	struct device_node *parent, *child;
	int i, parsed = 0;

	if (!pdev->dev.parent->of_node)
		return NULL;

	parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
	if (!parent)
		return NULL;

	data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators,
			    GFP_KERNEL);
	if (!data) {
		of_node_put(parent);
		return NULL;
	}

	p = data;

	for_each_child_of_node(parent, child) {
		int found = 0;

		for (i = 0; i < num_regulators; i++) {
			if (!regulators[i].desc.name)
				continue;
			if (!of_node_cmp(child->name,
					 regulators[i].desc.name)) {
				p->id = i;
				p->init_data = of_get_regulator_init_data(
							&pdev->dev, child,
							&regulators[i].desc);
				p->node = child;
				p++;

				parsed++;
				found = 1;
				break;
			}
		}

		if (!found)
			dev_warn(&pdev->dev,
				 "Unknown regulator: %s\n", child->name);
	}
示例#13
0
static int stm32_vrefbuf_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct stm32_vrefbuf *priv;
	struct regulator_config config = { };
	struct regulator_dev *rdev;
	int ret;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	priv->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->clk))
		return PTR_ERR(priv->clk);

	ret = clk_prepare_enable(priv->clk);
	if (ret) {
		dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret);
		return ret;
	}

	config.dev = &pdev->dev;
	config.driver_data = priv;
	config.of_node = pdev->dev.of_node;
	config.init_data = of_get_regulator_init_data(&pdev->dev,
						      pdev->dev.of_node,
						      &stm32_vrefbuf_regu);

	rdev = regulator_register(&stm32_vrefbuf_regu, &config);
	if (IS_ERR(rdev)) {
		ret = PTR_ERR(rdev);
		dev_err(&pdev->dev, "register failed with error %d\n", ret);
		goto err_clk_dis;
	}
	platform_set_drvdata(pdev, rdev);

	return 0;

err_clk_dis:
	clk_disable_unprepare(priv->clk);

	return ret;
}
示例#14
0
文件: max8952.c 项目: 020gzh/linux
static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
{
	struct max8952_platform_data *pd;
	struct device_node *np = dev->of_node;
	int ret;
	int i;

	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
	if (!pd)
		return NULL;

	pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0);
	pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1);
	pd->gpio_en = of_get_named_gpio(np, "max8952,en-gpio", 0);

	if (of_property_read_u32(np, "max8952,default-mode", &pd->default_mode))
		dev_warn(dev, "Default mode not specified, assuming 0\n");

	ret = of_property_read_u32_array(np, "max8952,dvs-mode-microvolt",
					pd->dvs_mode, ARRAY_SIZE(pd->dvs_mode));
	if (ret) {
		dev_err(dev, "max8952,dvs-mode-microvolt property not specified");
		return NULL;
	}

	for (i = 0; i < ARRAY_SIZE(pd->dvs_mode); ++i) {
		if (pd->dvs_mode[i] < 770000 || pd->dvs_mode[i] > 1400000) {
			dev_err(dev, "DVS voltage %d out of range\n", i);
			return NULL;
		}
		pd->dvs_mode[i] = (pd->dvs_mode[i] - 770000) / 10000;
	}

	if (of_property_read_u32(np, "max8952,sync-freq", &pd->sync_freq))
		dev_warn(dev, "max8952,sync-freq property not specified, defaulting to 26MHz\n");

	if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed))
		dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n");

	pd->reg_data = of_get_regulator_init_data(dev, np, &regulator);
	if (!pd->reg_data) {
		dev_err(dev, "Failed to parse regulator init data\n");
		return NULL;
	}

	return pd;
}
示例#15
0
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
				     struct regulator_config *config,
				     const struct regulator_desc *desc)
{
	struct arizona_pdata *pdata = &arizona->pdata;
	struct arizona_ldo1 *ldo1 = config->driver_data;
	struct device_node *np = arizona->dev->of_node;
	struct device_node *init_node, *dcvdd_node;
	struct regulator_init_data *init_data;

	pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0);
	if (pdata->ldoena < 0) {
		dev_warn(arizona->dev,
			 "LDOENA GPIO property missing/malformed: %d\n",
			 pdata->ldoena);
		pdata->ldoena = 0;
	} else {
		config->ena_gpio_initialized = true;
	}

	init_node = of_get_child_by_name(np, "ldo1");
	dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0);

	if (init_node) {
		config->of_node = init_node;

		init_data = of_get_regulator_init_data(arizona->dev, init_node,
						       desc);

		if (init_data) {
			init_data->consumer_supplies = &ldo1->supply;
			init_data->num_consumer_supplies = 1;

			if (dcvdd_node && dcvdd_node != init_node)
				arizona->external_dcvdd = true;

			pdata->ldo1 = init_data;
		}
	} else if (dcvdd_node) {
		arizona->external_dcvdd = true;
	}

	of_node_put(dcvdd_node);

	return 0;
}
示例#16
0
/**
 * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
 * @dev: device requesting for fixed_voltage_config
 *
 * Populates fixed_voltage_config structure by extracting data from device
 * tree node, returns a pointer to the populated structure of NULL if memory
 * alloc fails.
 */
static struct fixed_voltage_config *
of_get_fixed_voltage_config(struct device *dev)
{
	struct fixed_voltage_config *config;
	struct device_node *np = dev->of_node;
	const __be32 *delay;
	struct regulator_init_data *init_data;

	config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
								 GFP_KERNEL);
	if (!config)
		return NULL;

	config->init_data = of_get_regulator_init_data(dev, dev->of_node);
	if (!config->init_data)
		return NULL;

	init_data = config->init_data;
	init_data->constraints.apply_uV = 0;

	config->supply_name = init_data->constraints.name;
	if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
		config->microvolts = init_data->constraints.min_uV;
	} else {
		dev_err(dev,
			 "Fixed regulator specified with variable voltages\n");
		return NULL;
	}

	if (init_data->constraints.boot_on)
		config->enabled_at_boot = true;

	config->gpio = of_get_named_gpio(np, "gpio", 0);
	delay = of_get_property(np, "startup-delay-us", NULL);
	if (delay)
		config->startup_delay = be32_to_cpu(*delay);

	if (of_find_property(np, "enable-active-high", NULL))
		config->enable_high = true;

	return config;
}
示例#17
0
static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
					      struct device_node *np,
					      const struct regulator_desc *desc)
{
	struct fan53555_platform_data *pdata;
	int ret;
	u32 tmp;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return NULL;

	pdata->regulator = of_get_regulator_init_data(dev, np, desc);

	ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
				   &tmp);
	if (!ret)
		pdata->sleep_vsel_id = tmp;

	return pdata;
}
示例#18
0
static struct fan53555_platform_data *
	fan53555_get_of_platform_data(struct i2c_client *client)
{
	struct fan53555_platform_data *pdata = NULL;
	struct regulator_init_data *init_data;
	u32 sleep_sel;

	init_data = of_get_regulator_init_data(&client->dev,
			client->dev.of_node);
	if (!init_data) {
		dev_err(&client->dev, "regulator init data is missing\n");
		return pdata;
	}

	if (fan53555_parse_backup_reg(client, &sleep_sel))
		return pdata;

	pdata = devm_kzalloc(&client->dev,
			sizeof(struct fan53555_platform_data), GFP_KERNEL);
	if (!pdata) {
		dev_err(&client->dev,
			"fan53555_platform_data allocation failed.\n");
		return pdata;
	}

	init_data->constraints.input_uV = init_data->constraints.max_uV;
	init_data->constraints.valid_ops_mask |=
		REGULATOR_CHANGE_STATUS	| REGULATOR_CHANGE_VOLTAGE |
		REGULATOR_CHANGE_MODE;
	init_data->constraints.valid_modes_mask =
				REGULATOR_MODE_NORMAL |
				REGULATOR_MODE_FAST;
	init_data->constraints.initial_mode = REGULATOR_MODE_NORMAL;

	pdata->regulator = init_data;
	pdata->sleep_vsel_id = sleep_sel;

	return pdata;
}
示例#19
0
static int smb349_regulator_init(struct smb349_charger *chip)
{
	int rc = 0;
	struct regulator_init_data *init_data;
	struct regulator_config cfg = {};

	init_data = of_get_regulator_init_data(chip->dev, chip->dev->of_node);
	if (!init_data) {
		dev_err(chip->dev, "Unable to allocate memory\n");
		return -ENOMEM;
	}

	if (init_data->constraints.name) {
		chip->otg_vreg.rdesc.owner = THIS_MODULE;
		chip->otg_vreg.rdesc.type = REGULATOR_VOLTAGE;
		chip->otg_vreg.rdesc.ops = &smb349_chg_otg_reg_ops;
		chip->otg_vreg.rdesc.name = init_data->constraints.name;

		cfg.dev = chip->dev;
		cfg.init_data = init_data;
		cfg.driver_data = chip;
		cfg.of_node = chip->dev->of_node;

		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_STATUS;

		chip->otg_vreg.rdev = regulator_register(
						&chip->otg_vreg.rdesc, &cfg);
		if (IS_ERR(chip->otg_vreg.rdev)) {
			rc = PTR_ERR(chip->otg_vreg.rdev);
			chip->otg_vreg.rdev = NULL;
			if (rc != -EPROBE_DEFER)
				dev_err(chip->dev,
					"OTG reg failed, rc=%d\n", rc);
		}
	}

	return rc;
}
struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
	int num_regulators)
{
	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
	struct mc13xxx_regulator_init_data *data, *p;
	struct device_node *parent, *child;
	int i;

	of_node_get(pdev->dev.parent->of_node);
	parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
	if (!parent)
		return NULL;

	data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators,
			    GFP_KERNEL);
	if (!data)
		return NULL;
	p = data;

	for_each_child_of_node(parent, child) {
		for (i = 0; i < num_regulators; i++) {
			if (!of_node_cmp(child->name,
					 regulators[i].desc.name)) {
				p->id = i;
				p->init_data = of_get_regulator_init_data(
							&pdev->dev, child);
				p->node = child;
				p++;
				break;
			}
		}
	}

	return data;
}
static int __devinit anatop_regulator_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct regulator_desc *rdesc;
	struct regulator_dev *rdev;
	struct anatop_regulator *sreg;
	struct regulator_init_data *initdata;
	struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
	int ret = 0;

	initdata = of_get_regulator_init_data(dev, np);
	sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
	if (!sreg)
		return -ENOMEM;
	sreg->initdata = initdata;
	sreg->name = kstrdup(of_get_property(np, "regulator-name", NULL),
			     GFP_KERNEL);
	rdesc = &sreg->rdesc;
	memset(rdesc, 0, sizeof(*rdesc));
	rdesc->name = sreg->name;
	rdesc->ops = &anatop_rops;
	rdesc->type = REGULATOR_VOLTAGE;
	rdesc->owner = THIS_MODULE;
	sreg->mfd = anatopmfd;
	ret = of_property_read_u32(np, "anatop-reg-offset",
				   &sreg->control_reg);
	if (ret) {
		dev_err(dev, "no anatop-reg-offset property set\n");
		goto anatop_probe_end;
	}
	ret = of_property_read_u32(np, "anatop-vol-bit-width",
				   &sreg->vol_bit_width);
	if (ret) {
		dev_err(dev, "no anatop-vol-bit-width property set\n");
		goto anatop_probe_end;
	}
	ret = of_property_read_u32(np, "anatop-vol-bit-shift",
				   &sreg->vol_bit_shift);
	if (ret) {
		dev_err(dev, "no anatop-vol-bit-shift property set\n");
		goto anatop_probe_end;
	}
	ret = of_property_read_u32(np, "anatop-min-bit-val",
				   &sreg->min_bit_val);
	if (ret) {
		dev_err(dev, "no anatop-min-bit-val property set\n");
		goto anatop_probe_end;
	}
	ret = of_property_read_u32(np, "anatop-min-voltage",
				   &sreg->min_voltage);
	if (ret) {
		dev_err(dev, "no anatop-min-voltage property set\n");
		goto anatop_probe_end;
	}
	ret = of_property_read_u32(np, "anatop-max-voltage",
				   &sreg->max_voltage);
	if (ret) {
		dev_err(dev, "no anatop-max-voltage property set\n");
		goto anatop_probe_end;
	}

	rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
		/ 25000 + 1;

	
	rdev = regulator_register(rdesc, dev,
				  initdata, sreg, pdev->dev.of_node);
	if (IS_ERR(rdev)) {
		dev_err(dev, "failed to register %s\n",
			rdesc->name);
		ret = PTR_ERR(rdev);
		goto anatop_probe_end;
	}

	platform_set_drvdata(pdev, rdev);

anatop_probe_end:
	if (ret)
		kfree(sreg->name);

	return ret;
}
static int regulator_stub_probe(struct platform_device *pdev)
{
	struct regulator_config reg_config = {};
	struct regulator_init_data *init_data = NULL;
	struct device *dev = &pdev->dev;
	struct stub_regulator_pdata *vreg_pdata;
	struct regulator_desc *rdesc;
	struct regulator_stub *vreg_priv;
	int rc;

	vreg_priv = kzalloc(sizeof(*vreg_priv), GFP_KERNEL);
	if (!vreg_priv) {
		dev_err(dev, "%s: Unable to allocate memory\n",
				__func__);
		return -ENOMEM;
	}

	if (dev->of_node) {
		/* Use device tree. */
		init_data = of_get_regulator_init_data(dev,
						       dev->of_node);
		if (!init_data) {
			dev_err(dev, "%s: unable to allocate memory\n",
					__func__);
			rc = -ENOMEM;
			goto err_probe;
		}

		if (init_data->constraints.name == NULL) {
			dev_err(dev, "%s: regulator name not specified\n",
				__func__);
			rc = -EINVAL;
			goto err_probe;
		}

		if (of_get_property(dev->of_node, "parent-supply", NULL))
			init_data->supply_regulator = "parent";

		of_property_read_u32(dev->of_node, "qcom,system-load",
					&vreg_priv->system_uA);
		of_property_read_u32(dev->of_node, "qcom,hpm-min-load",
					&vreg_priv->hpm_min_load);

		init_data->constraints.input_uV	= init_data->constraints.max_uV;

		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_STATUS;
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_VOLTAGE;
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_DRMS;
		init_data->constraints.valid_modes_mask
			= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
	} else {
		/* Use platform data. */
		vreg_pdata = dev->platform_data;
		if (!vreg_pdata) {
			dev_err(dev, "%s: no platform data\n", __func__);
			rc = -EINVAL;
			goto err_probe;
		}
		init_data = &vreg_pdata->init_data;

		vreg_priv->system_uA = vreg_pdata->system_uA;
		vreg_priv->hpm_min_load = vreg_pdata->hpm_min_load;
	}

	dev_set_drvdata(dev, vreg_priv);

	rdesc = &vreg_priv->rdesc;
	strlcpy(vreg_priv->name, init_data->constraints.name,
						   STUB_REGULATOR_MAX_NAME);
	rdesc->name = vreg_priv->name;
	rdesc->ops = &regulator_stub_ops;

	/*
	 * Ensure that voltage set points are handled correctly for regulators
	 * which have a specified voltage constraint range, as well as those
	 * that do not.
	 */
	if (init_data->constraints.min_uV == 0 &&
	    init_data->constraints.max_uV == 0)
		rdesc->n_voltages = 0;
	else
		rdesc->n_voltages = 2;

	rdesc->id    = pdev->id;
	rdesc->owner = THIS_MODULE;
	rdesc->type  = REGULATOR_VOLTAGE;
	vreg_priv->voltage = init_data->constraints.min_uV;
	if (vreg_priv->system_uA >= vreg_priv->hpm_min_load)
		vreg_priv->mode = REGULATOR_MODE_NORMAL;
	else
		vreg_priv->mode = REGULATOR_MODE_IDLE;

	reg_config.dev = dev;
	reg_config.init_data = init_data;
	reg_config.driver_data = vreg_priv;
	reg_config.of_node = dev->of_node;
	vreg_priv->rdev = regulator_register(rdesc, &reg_config);

	if (IS_ERR(vreg_priv->rdev)) {
		rc = PTR_ERR(vreg_priv->rdev);
		vreg_priv->rdev = NULL;
		if (rc != -EPROBE_DEFER)
			dev_err(dev, "%s: regulator_register failed\n",
				__func__);
		goto err_probe;
	}

	return 0;

err_probe:
	regulator_stub_cleanup(vreg_priv);
	return rc;
}
示例#23
0
文件: gdsc.c 项目: Skin1980/bass-MM
static int gdsc_probe(struct platform_device *pdev)
{
	static atomic_t gdsc_count = ATOMIC_INIT(-1);
	struct regulator_config reg_config = {};
	struct regulator_init_data *init_data;
	struct resource *res;
	struct gdsc *sc;
	uint32_t regval;
	bool retain_mem, retain_periph, support_hw_trigger;
	int i, ret;

	sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL);
	if (sc == NULL)
		return -ENOMEM;

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
	if (init_data == NULL)
		return -ENOMEM;

	if (of_get_property(pdev->dev.of_node, "parent-supply", NULL))
		init_data->supply_regulator = "parent";

	ret = of_property_read_string(pdev->dev.of_node, "regulator-name",
				      &sc->rdesc.name);
	if (ret)
		return ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
		return -EINVAL;
	sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (sc->gdscr == NULL)
		return -ENOMEM;

	sc->clock_count = of_property_count_strings(pdev->dev.of_node,
					    "clock-names");
	if (sc->clock_count == -EINVAL) {
		sc->clock_count = 0;
	} else if (IS_ERR_VALUE(sc->clock_count)) {
		dev_err(&pdev->dev, "Failed to get clock names\n");
		return -EINVAL;
	}

	sc->clocks = devm_kzalloc(&pdev->dev,
			sizeof(struct clk *) * sc->clock_count, GFP_KERNEL);
	if (!sc->clocks)
		return -ENOMEM;

	sc->root_en = of_property_read_bool(pdev->dev.of_node,
						"qcom,enable-root-clk");

	for (i = 0; i < sc->clock_count; i++) {
		const char *clock_name;
		of_property_read_string_index(pdev->dev.of_node, "clock-names",
					      i, &clock_name);
		sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name);
		if (IS_ERR(sc->clocks[i])) {
			int rc = PTR_ERR(sc->clocks[i]);
			if (rc != -EPROBE_DEFER)
				dev_err(&pdev->dev, "Failed to get %s\n",
					clock_name);
			return rc;
		}
	}

	sc->rdesc.id = atomic_inc_return(&gdsc_count);
	sc->rdesc.ops = &gdsc_ops;
	sc->rdesc.type = REGULATOR_VOLTAGE;
	sc->rdesc.owner = THIS_MODULE;
	platform_set_drvdata(pdev, sc);

	/*
	 * Disable HW trigger: collapse/restore occur based on registers writes.
	 * Disable SW override: Use hardware state-machine for sequencing.
	 */
	regval = readl_relaxed(sc->gdscr);
	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);

	/* Configure wait time between states. */
	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
	writel_relaxed(regval, sc->gdscr);

	retain_mem = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-mem");
	sc->toggle_mem = !retain_mem;
	retain_periph = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-periph");
	sc->toggle_periph = !retain_periph;
	sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node,
						"qcom,skip-logic-collapse");
	support_hw_trigger = of_property_read_bool(pdev->dev.of_node,
						    "qcom,support-hw-trigger");
	if (support_hw_trigger) {
		init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
		init_data->constraints.valid_modes_mask |=
				REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST;
	}

	if (!sc->toggle_logic) {
		regval &= ~SW_COLLAPSE_MASK;
		writel_relaxed(regval, sc->gdscr);

		ret = readl_tight_poll_timeout(sc->gdscr, regval,
					regval & PWR_ON_MASK, TIMEOUT_US);
		if (ret) {
			dev_err(&pdev->dev, "%s enable timed out: 0x%x\n",
				sc->rdesc.name, regval);
			return ret;
		}
	}

	for (i = 0; i < sc->clock_count; i++) {
		if (retain_mem || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM);

		if (retain_periph || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
	}

	reg_config.dev = &pdev->dev;
	reg_config.init_data = init_data;
	reg_config.driver_data = sc;
	reg_config.of_node = pdev->dev.of_node;
	sc->rdev = regulator_register(&sc->rdesc, &reg_config);
	if (IS_ERR(sc->rdev)) {
		dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n",
			sc->rdesc.name);
		return PTR_ERR(sc->rdev);
	}

	return 0;
}
static struct ncp6335d_platform_data *
	ncp6335d_get_of_platform_data(struct i2c_client *client)
{
	struct ncp6335d_platform_data *pdata = NULL;
	struct regulator_init_data *init_data;
	const char *mode_name;
	int rc;

	init_data = of_get_regulator_init_data(&client->dev,
				client->dev.of_node);
	if (!init_data) {
		dev_err(&client->dev, "regulator init data is missing\n");
		return pdata;
	}

	pdata = devm_kzalloc(&client->dev,
			sizeof(struct ncp6335d_platform_data), GFP_KERNEL);
	if (!pdata) {
		dev_err(&client->dev, "ncp6335d_platform_data allocation failed.\n");
		return pdata;
	}

	rc = of_property_read_u32(client->dev.of_node,
			"onnn,vsel", &pdata->default_vsel);
	if (rc < 0) {
		dev_err(&client->dev, "onnn,vsel property missing: rc = %d.\n",
			rc);
		return NULL;
	}

	rc = of_property_read_u32(client->dev.of_node,
			"onnn,slew-ns", &pdata->slew_rate_ns);
	if (rc < 0) {
		dev_err(&client->dev, "onnn,slew-ns property missing: rc = %d.\n",
			rc);
		return NULL;
	}

	pdata->discharge_enable = of_property_read_bool(client->dev.of_node,
						"onnn,discharge-enable");

	pdata->sleep_enable = of_property_read_bool(client->dev.of_node,
						"onnn,sleep-enable");

	pdata->init_data = init_data;

	init_data->constraints.input_uV = init_data->constraints.max_uV;
	init_data->constraints.valid_ops_mask =
				REGULATOR_CHANGE_VOLTAGE |
				REGULATOR_CHANGE_STATUS |
				REGULATOR_CHANGE_MODE;
	init_data->constraints.valid_modes_mask =
				REGULATOR_MODE_NORMAL |
				REGULATOR_MODE_FAST;

	rc = of_property_read_string(client->dev.of_node, "onnn,mode",
					&mode_name);
	if (!rc) {
		if (strcmp("pwm", mode_name) == 0) {
			init_data->constraints.initial_mode =
							REGULATOR_MODE_FAST;
		} else if (strcmp("auto", mode_name) == 0) {
			init_data->constraints.initial_mode =
							REGULATOR_MODE_NORMAL;
		} else {
			dev_err(&client->dev, "onnn,mode, unknown regulator mode: %s\n",
				mode_name);
			return NULL;
		}
	}

	return pdata;
}
示例#25
0
static struct gpio_regulator_config *
of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
{
	struct gpio_regulator_config *config;
	struct property *prop;
	const char *regtype;
	int proplen, gpio, i;
	int ret;

	config = devm_kzalloc(dev,
			sizeof(struct gpio_regulator_config),
			GFP_KERNEL);
	if (!config)
		return ERR_PTR(-ENOMEM);

	config->init_data = of_get_regulator_init_data(dev, np);
	if (!config->init_data)
		return ERR_PTR(-EINVAL);

	config->supply_name = config->init_data->constraints.name;

	if (of_property_read_bool(np, "enable-active-high"))
		config->enable_high = true;

	if (of_property_read_bool(np, "enable-at-boot"))
		config->enabled_at_boot = true;

	of_property_read_u32(np, "startup-delay-us", &config->startup_delay);

	config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);

	/* Fetch GPIOs. */
	config->nr_gpios = of_gpio_count(np);

	config->gpios = devm_kzalloc(dev,
				sizeof(struct gpio) * config->nr_gpios,
				GFP_KERNEL);
	if (!config->gpios)
		return ERR_PTR(-ENOMEM);

	prop = of_find_property(np, "gpios-states", NULL);
	if (prop) {
		proplen = prop->length / sizeof(int);
		if (proplen != config->nr_gpios) {
			/* gpios <-> gpios-states mismatch */
			prop = NULL;
		}
	}

	for (i = 0; i < config->nr_gpios; i++) {
		gpio = of_get_named_gpio(np, "gpios", i);
		if (gpio < 0)
			break;
		config->gpios[i].gpio = gpio;
		if (prop && be32_to_cpup((int *)prop->value + i))
			config->gpios[i].flags = GPIOF_OUT_INIT_HIGH;
	}

	/* Fetch states. */
	prop = of_find_property(np, "states", NULL);
	if (!prop) {
		dev_err(dev, "No 'states' property found\n");
		return ERR_PTR(-EINVAL);
	}

	proplen = prop->length / sizeof(int);

	config->states = devm_kzalloc(dev,
				sizeof(struct gpio_regulator_state)
				* (proplen / 2),
				GFP_KERNEL);
	if (!config->states)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < proplen / 2; i++) {
		config->states[i].value =
			be32_to_cpup((int *)prop->value + (i * 2));
		config->states[i].gpios =
			be32_to_cpup((int *)prop->value + (i * 2 + 1));
	}
	config->nr_states = i;

	config->type = REGULATOR_VOLTAGE;
	ret = of_property_read_string(np, "regulator-type", &regtype);
	if (ret >= 0) {
		if (!strncmp("voltage", regtype, 7))
			config->type = REGULATOR_VOLTAGE;
		else if (!strncmp("current", regtype, 7))
			config->type = REGULATOR_CURRENT;
		else
			dev_warn(dev, "Unknown regulator-type '%s'\n",
				 regtype);
	}

	return config;
}
示例#26
0
{
	int				i, id;
	struct twlreg_info		*info;
	const struct twlreg_info	*template;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;
	struct twl_regulator_driver_data	*drvdata;
	const struct of_device_id	*match;
	struct regulator_config		config = { };

	match = of_match_device(twl_of_match, &pdev->dev);
	if (match) {
		template = match->data;
		id = template->desc.id;
		initdata = of_get_regulator_init_data(&pdev->dev,
						      pdev->dev.of_node);
		drvdata = NULL;
	} else {
		id = pdev->id;
		initdata = pdev->dev.platform_data;
		for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
			template = twl_of_match[i].data;
			if (template && template->desc.id == id)
				break;
		}
		if (i == ARRAY_SIZE(twl_of_match))
			return -ENODEV;

		drvdata = initdata->driver_data;
		if (!drvdata)
			return -EINVAL;
static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev,
					struct max17135_platform_data *pdata)
{
	struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent);
	struct device_node *pmic_np, *regulators_np, *reg_np;
	struct max17135_regulator_data *rdata;
	int i, ret;

	pmic_np = of_node_get(max17135->dev->of_node);
	if (!pmic_np) {
		dev_err(&pdev->dev, "could not find pmic sub-node\n");
		return -ENODEV;
	}

	regulators_np = of_find_node_by_name(pmic_np, "regulators");
	if (!regulators_np) {
		dev_err(&pdev->dev, "could not find regulators sub-node\n");
		return -EINVAL;
	}

	pdata->num_regulators = of_get_child_count(regulators_np);
	dev_dbg(&pdev->dev, "num_regulators %d\n", pdata->num_regulators);

	rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
				pdata->num_regulators, GFP_KERNEL);
	if (!rdata) {
		of_node_put(regulators_np);
		dev_err(&pdev->dev, "could not allocate memory for"
			"regulator data\n");
		return -ENOMEM;
	}

	pdata->regulators = rdata;
	for_each_child_of_node(regulators_np, reg_np) {
		for (i = 0; i < ARRAY_SIZE(max17135_reg); i++)
			if (!of_node_cmp(reg_np->name, max17135_reg[i].name))
				break;

		if (i == ARRAY_SIZE(max17135_reg)) {
			dev_warn(&pdev->dev, "don't know how to configure"
				"regulator %s\n", reg_np->name);
			continue;
		}

		rdata->id = i;
		rdata->initdata = of_get_regulator_init_data(&pdev->dev,
							     reg_np,
							     &max17135_reg[i]);
		rdata->reg_node = reg_np;
		rdata++;
	}
	of_node_put(regulators_np);

	CHECK_PROPERTY_ERROR_KFREE(vneg_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvee_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(vpos_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(vpos_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(gvee_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(vneg_pwrdn);

	dev_dbg(&pdev->dev, "vneg_pwrup %d, vneg_pwrdn %d, vpos_pwrup %d,"
		"vpos_pwrdn %d, gvdd_pwrup %d, gvdd_pwrdn %d, gvee_pwrup %d,"
		"gvee_pwrdn %d\n", max17135->vneg_pwrup, max17135->vneg_pwrdn,
		max17135->vpos_pwrup, max17135->vpos_pwrdn,
		max17135->gvdd_pwrup, max17135->gvdd_pwrdn,
		max17135->gvee_pwrup, max17135->gvee_pwrdn);

	max17135->max_wait = max17135->vpos_pwrup + max17135->vneg_pwrup +
		max17135->gvdd_pwrup + max17135->gvee_pwrup;

	max17135->gpio_pmic_wakeup = of_get_named_gpio(pmic_np,
					"gpio_pmic_wakeup", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_wakeup)) {
		dev_err(&pdev->dev, "no epdc pmic wakeup pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_wakeup,
				GPIOF_OUT_INIT_LOW, "epdc-pmic-wake");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_vcom_ctrl = of_get_named_gpio(pmic_np,
					"gpio_pmic_vcom_ctrl", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_vcom_ctrl)) {
		dev_err(&pdev->dev, "no epdc pmic vcom_ctrl pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_vcom_ctrl,
				GPIOF_OUT_INIT_LOW, "epdc-vcom");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_v3p3 = of_get_named_gpio(pmic_np,
					"gpio_pmic_v3p3", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_v3p3)) {
		dev_err(&pdev->dev, "no epdc pmic v3p3 pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_v3p3,
				GPIOF_OUT_INIT_LOW, "epdc-v3p3");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_intr = of_get_named_gpio(pmic_np,
					"gpio_pmic_intr", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_intr)) {
		dev_err(&pdev->dev, "no epdc pmic intr pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_intr,
				GPIOF_IN, "epdc-pmic-int");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_pwrgood = of_get_named_gpio(pmic_np,
					"gpio_pmic_pwrgood", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_pwrgood)) {
		dev_err(&pdev->dev, "no epdc pmic pwrgood pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_pwrgood,
				GPIOF_IN, "epdc-pwrstat");
	if (ret < 0)
		goto err;

err:
	return 0;

}
/**
 * ti_abb_probe() - Initialize an ABB ldo instance
 * @pdev: ABB platform device
 *
 * Initializes an individual ABB LDO for required Body-Bias. ABB is used to
 * addional bias supply to SoC modules for power savings or mandatory stability
 * configuration at certain Operating Performance Points(OPPs).
 *
 * Return: 0 on success or appropriate error value when fails
 */
static int ti_abb_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct of_device_id *match;
	struct resource *res;
	struct ti_abb *abb;
	struct regulator_init_data *initdata = NULL;
	struct regulator_dev *rdev = NULL;
	struct regulator_desc *desc;
	struct regulation_constraints *c;
	struct regulator_config config = { };
	char *pname;
	int ret = 0;

	match = of_match_device(ti_abb_of_match, dev);
	if (!match) {
		/* We do not expect this to happen */
		dev_err(dev, "%s: Unable to match device\n", __func__);
		return -ENODEV;
	}
	if (!match->data) {
		dev_err(dev, "%s: Bad data in match\n", __func__);
		return -EINVAL;
	}

	abb = devm_kzalloc(dev, sizeof(struct ti_abb), GFP_KERNEL);
	if (!abb)
		return -ENOMEM;
	abb->regs = match->data;

	/* Map ABB resources */
	if (abb->regs->setup_off || abb->regs->control_off) {
		pname = "base-address";
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
		abb->base = devm_ioremap_resource(dev, res);
		if (IS_ERR(abb->base))
			return PTR_ERR(abb->base);

		abb->setup_reg = abb->base + abb->regs->setup_off;
		abb->control_reg = abb->base + abb->regs->control_off;

	} else {
		pname = "control-address";
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
		abb->control_reg = devm_ioremap_resource(dev, res);
		if (IS_ERR(abb->control_reg))
			return PTR_ERR(abb->control_reg);

		pname = "setup-address";
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
		abb->setup_reg = devm_ioremap_resource(dev, res);
		if (IS_ERR(abb->setup_reg))
			return PTR_ERR(abb->setup_reg);
	}

	pname = "int-address";
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
	if (!res) {
		dev_err(dev, "Missing '%s' IO resource\n", pname);
		return -ENODEV;
	}
	/*
	 * We may have shared interrupt register offsets which are
	 * write-1-to-clear between domains ensuring exclusivity.
	 */
	abb->int_base = devm_ioremap_nocache(dev, res->start,
					     resource_size(res));
	if (!abb->int_base) {
		dev_err(dev, "Unable to map '%s'\n", pname);
		return -ENOMEM;
	}

	/* Map Optional resources */
	pname = "efuse-address";
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
	if (!res) {
		dev_dbg(dev, "Missing '%s' IO resource\n", pname);
		ret = -ENODEV;
		goto skip_opt;
	}

	/*
	 * We may have shared efuse register offsets which are read-only
	 * between domains
	 */
	abb->efuse_base = devm_ioremap_nocache(dev, res->start,
					       resource_size(res));
	if (!abb->efuse_base) {
		dev_err(dev, "Unable to map '%s'\n", pname);
		return -ENOMEM;
	}

	pname = "ldo-address";
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
	if (!res) {
		dev_dbg(dev, "Missing '%s' IO resource\n", pname);
		ret = -ENODEV;
		goto skip_opt;
	}
	abb->ldo_base = devm_ioremap_resource(dev, res);
	if (IS_ERR(abb->ldo_base))
		return PTR_ERR(abb->ldo_base);

	/* IF ldo_base is set, the following are mandatory */
	pname = "ti,ldovbb-override-mask";
	ret =
	    of_property_read_u32(pdev->dev.of_node, pname,
				 &abb->ldovbb_override_mask);
	if (ret) {
		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
		return ret;
	}
	if (!abb->ldovbb_override_mask) {
		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
		return -EINVAL;
	}

	pname = "ti,ldovbb-vset-mask";
	ret =
	    of_property_read_u32(pdev->dev.of_node, pname,
				 &abb->ldovbb_vset_mask);
	if (ret) {
		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
		return ret;
	}
	if (!abb->ldovbb_vset_mask) {
		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
		return -EINVAL;
	}

skip_opt:
	pname = "ti,tranxdone-status-mask";
	ret =
	    of_property_read_u32(pdev->dev.of_node, pname,
				 &abb->txdone_mask);
	if (ret) {
		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
		return ret;
	}
	if (!abb->txdone_mask) {
		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
		return -EINVAL;
	}

	initdata = of_get_regulator_init_data(dev, pdev->dev.of_node);
	if (!initdata) {
		dev_err(dev, "%s: Unable to alloc regulator init data\n",
			__func__);
		return -ENOMEM;
	}

	/* init ABB opp_sel table */
	ret = ti_abb_init_table(dev, abb, initdata);
	if (ret)
		return ret;

	/* init ABB timing */
	ret = ti_abb_init_timings(dev, abb);
	if (ret)
		return ret;

	desc = &abb->rdesc;
	desc->name = dev_name(dev);
	desc->owner = THIS_MODULE;
	desc->type = REGULATOR_VOLTAGE;
	desc->ops = &ti_abb_reg_ops;

	c = &initdata->constraints;
	if (desc->n_voltages > 1)
		c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
	c->always_on = true;

	config.dev = dev;
	config.init_data = initdata;
	config.driver_data = abb;
	config.of_node = pdev->dev.of_node;

	rdev = devm_regulator_register(dev, desc, &config);
	if (IS_ERR(rdev)) {
		ret = PTR_ERR(rdev);
		dev_err(dev, "%s: failed to register regulator(%d)\n",
			__func__, ret);
		return ret;
	}
	platform_set_drvdata(pdev, rdev);

	/* Enable the ldo if not already done by bootloader */
	ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg);

	return 0;
}
示例#29
0
static int s2mps13_pmic_dt_parse_pdata(struct sec_pmic_dev *iodev,
					struct sec_platform_data *pdata)
{
	struct device_node *pmic_np, *regulators_np, *reg_np;
	struct sec_regulator_data *rdata;
	unsigned int i, s2mps13_desc_type;
	int ret;
	u32 val;

	pmic_np = iodev->dev->of_node;
	if (!pmic_np) {
		dev_err(iodev->dev, "could not find pmic sub-node\n");
		return -ENODEV;
	}
	/* If pmic revision number over 0x02, get 3 gpio values */
	if (SEC_PMIC_REV(iodev) > 0x02) {
		if (of_gpio_count(pmic_np) < 3) {
			dev_err(iodev->dev, "could not find pmic gpios\n");
			return -EINVAL;
		}
		pdata->smpl_warn = of_get_gpio(pmic_np, 0);
		pdata->g3d_pin = of_get_gpio(pmic_np, 1);
		pdata->dvs_pin = of_get_gpio(pmic_np, 2);

		ret = of_property_read_u32(pmic_np, "g3d_en", &val);
		if (ret)
			return -EINVAL;
		pdata->g3d_en = !!val;

		ret = of_property_read_u32(pmic_np, "dvs_en", &val);
		if (ret)
			return -EINVAL;
		pdata->dvs_en = !!val;

		ret = of_property_read_u32(pmic_np, "smpl_warn_en", &val);
		if (ret)
			return -EINVAL;
		pdata->smpl_warn_en = !!val;
	} else {
		dev_err(iodev->dev, "cannot control g3d_en & dvs_en\n");
	}

	pdata->ap_buck_avp_en = false;
	pdata->sub_buck_avp_en = false;
	if (of_find_property(pmic_np, "ap-buck-avp-en", NULL))
		pdata->ap_buck_avp_en = true;

	if (of_find_property(pmic_np, "sub-buck-avp-en", NULL))
		pdata->sub_buck_avp_en = true;

	regulators_np = of_find_node_by_name(pmic_np, "regulators");
	if (!regulators_np) {
		dev_err(iodev->dev, "could not find regulators sub-node\n");
		return -EINVAL;
	}

	/* count the number of regulators to be supported in pmic */
	pdata->num_regulators = 0;
	for_each_child_of_node(regulators_np, reg_np) {
		pdata->num_regulators++;
	}

	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
				pdata->num_regulators, GFP_KERNEL);
	if (!rdata) {
		dev_err(iodev->dev,
			"could not allocate memory for regulator data\n");
		return -ENOMEM;
	}

	pdata->regulators = rdata;
	s2mps13_desc_type = SEC_PMIC_REV(iodev) ? S2MPS13_DESC_TYPE1 : S2MPS13_DESC_TYPE0;
	for_each_child_of_node(regulators_np, reg_np) {
		for (i = 0; i < ARRAY_SIZE(regulators[s2mps13_desc_type]); i++)
			if (!of_node_cmp(reg_np->name,
					regulators[s2mps13_desc_type][i].name))
				break;

		if (i == ARRAY_SIZE(regulators[s2mps13_desc_type])) {
			dev_warn(iodev->dev,
			"don't know how to configure regulator %s\n",
			reg_np->name);
			continue;
		}

		rdata->id = i;
		rdata->initdata = of_get_regulator_init_data(
						iodev->dev, reg_np);
		rdata->reg_node = reg_np;
		rdata++;
	}

	return 0;
}
示例#30
0
static int __devinit gdsc_probe(struct platform_device *pdev)
{
	static atomic_t gdsc_count = ATOMIC_INIT(-1);
	struct regulator_init_data *init_data;
	struct resource *res;
	struct gdsc *sc;
	uint32_t regval;
	bool retain_mem, retain_periph;
	int i, ret;
#ifdef CONFIG_MACH_LGE
	int use_lge_workaround = 0; /* default: all not applied */
#endif

	sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL);
	if (sc == NULL)
		return -ENOMEM;

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
	if (init_data == NULL)
		return -ENOMEM;

	if (of_get_property(pdev->dev.of_node, "parent-supply", NULL))
		init_data->supply_regulator = "parent";

	ret = of_property_read_string(pdev->dev.of_node, "regulator-name",
				      &sc->rdesc.name);
	if (ret)
		return ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
		return -EINVAL;
	sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (sc->gdscr == NULL)
		return -ENOMEM;

	sc->clock_count = of_property_count_strings(pdev->dev.of_node,
					    "qcom,clock-names");
	if (sc->clock_count == -EINVAL) {
		sc->clock_count = 0;
	} else if (IS_ERR_VALUE(sc->clock_count)) {
		dev_err(&pdev->dev, "Failed to get clock names\n");
		return -EINVAL;
	}

	sc->clocks = devm_kzalloc(&pdev->dev,
			sizeof(struct clk *) * sc->clock_count, GFP_KERNEL);
	if (!sc->clocks)
		return -ENOMEM;
	for (i = 0; i < sc->clock_count; i++) {
		const char *clock_name;
		of_property_read_string_index(pdev->dev.of_node,
					      "qcom,clock-names", i,
					      &clock_name);
		sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name);
		if (IS_ERR(sc->clocks[i])) {
			int rc = PTR_ERR(sc->clocks[i]);
			if (rc != -EPROBE_DEFER)
				dev_err(&pdev->dev, "Failed to get %s\n",
					clock_name);
			return rc;
		}
	}
#ifdef CONFIG_MACH_LGE
	of_property_read_u32(pdev->dev.of_node, "lge,use_workaround",
			&use_lge_workaround);
	sc->use_lge_workaround = !(!use_lge_workaround);
#endif
	sc->rdesc.id = atomic_inc_return(&gdsc_count);
	sc->rdesc.ops = &gdsc_ops;
	sc->rdesc.type = REGULATOR_VOLTAGE;
	sc->rdesc.owner = THIS_MODULE;
	platform_set_drvdata(pdev, sc);

	/*
	 * Disable HW trigger: collapse/restore occur based on registers writes.
	 * Disable SW override: Use hardware state-machine for sequencing.
	 */
	regval = readl_relaxed(sc->gdscr);
	regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);

	/* Configure wait time between states. */
	regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
	regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
	writel_relaxed(regval, sc->gdscr);

	retain_mem = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-mem");
	retain_periph = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-periph");
	for (i = 0; i < sc->clock_count; i++) {
		if (retain_mem || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM);

		if (retain_periph || (regval & PWR_ON_MASK))
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
	}
	sc->toggle_mem = !retain_mem;
	sc->toggle_periph = !retain_periph;
	sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node,
						"qcom,skip-logic-collapse");
	if (!sc->toggle_logic) {
#ifdef CONFIG_MACH_LGE
		/* LGE workaround is not used if a device is good pdn revision */
		if (lge_get_board_revno() >= use_lge_workaround) {
			regval &= ~SW_COLLAPSE_MASK;
			writel_relaxed(regval, sc->gdscr);

			ret = readl_tight_poll_timeout(sc->gdscr, regval,
					regval & PWR_ON_MASK, TIMEOUT_US);
			if (ret) {
				dev_err(&pdev->dev, "%s enable timed out\n",
						sc->rdesc.name);
				return ret;
			}
		} else {
			pr_info("%s: %s is enabled only at first by lge workaround\n",
					__func__, sc->rdesc.name);
			ret = lge_gdsc_enable(sc);
			if (ret) {
				dev_err(&pdev->dev, "%s enable timed out\n",
						sc->rdesc.name);
				return ret;
			}
		}
#else /* qmc */
		regval &= ~SW_COLLAPSE_MASK;
		writel_relaxed(regval, sc->gdscr);

		ret = readl_tight_poll_timeout(sc->gdscr, regval,
					regval & PWR_ON_MASK, TIMEOUT_US);
		if (ret) {
			dev_err(&pdev->dev, "%s enable timed out\n",
				sc->rdesc.name);
			return ret;
		}
#endif
	}

	sc->rdev = regulator_register(&sc->rdesc, &pdev->dev, init_data, sc,
				      pdev->dev.of_node);
	if (IS_ERR(sc->rdev)) {
		dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n",
			sc->rdesc.name);
		return PTR_ERR(sc->rdev);
	}

	return 0;
}