示例#1
0
/*lmh_add, New set_voltage func. for camera ISP core power setting*/
static int _max8952_set_voltage(struct regulator_dev *rdev,
			       int min_uV, int max_uV, unsigned *selector)
{
	struct max8952_data *max8952 = rdev_get_drvdata(rdev);

	int set_val, uV = min_uV;
	int lim_min_uV, lim_max_uV;

	lim_min_uV = max8952->pdata->reg_data.constraints.min_uV;
	lim_max_uV = max8952->pdata->reg_data.constraints.max_uV;


	if (uV < lim_min_uV && max_uV >= lim_min_uV)
		uV = lim_min_uV;

	if (uV < lim_min_uV || uV > lim_max_uV) {
		pr_err("request v=[%d, %d] is outside possible v=[%d, %d]\n",
			 min_uV, max_uV, lim_min_uV, lim_max_uV);
		return -EINVAL;
	}

	set_val = (uV-MAX8952_DCDC_VMIN) / MAX8952_DCDC_STEP;
	*selector = set_val & 0x3f;

	max8952_write_reg(max8952, MAX8952_REG_MODE3,
				(max8952_read_reg(max8952,
				 MAX8952_REG_MODE3) & 0xC0) | (*selector));

	pr_info("%s voltage is enabled to %d mV by selector value [%d]\n",
		max8952->pdata->reg_data.constraints.name, uV/1000, *selector);
	return 0;
}
示例#2
0
文件: max8952.c 项目: 020gzh/linux
static int max8952_pmic_probe(struct i2c_client *client,
		const struct i2c_device_id *i2c_id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct max8952_platform_data *pdata = dev_get_platdata(&client->dev);
	struct regulator_config config = { };
	struct max8952_data *max8952;
	struct regulator_dev *rdev;

	int ret = 0, err = 0;

	if (client->dev.of_node)
		pdata = max8952_parse_dt(&client->dev);

	if (!pdata) {
		dev_err(&client->dev, "Require the platform data\n");
		return -EINVAL;
	}

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	max8952 = devm_kzalloc(&client->dev, sizeof(struct max8952_data),
			       GFP_KERNEL);
	if (!max8952)
		return -ENOMEM;

	max8952->client = client;
	max8952->pdata = pdata;

	config.dev = &client->dev;
	config.init_data = pdata->reg_data;
	config.driver_data = max8952;
	config.of_node = client->dev.of_node;

	config.ena_gpio = pdata->gpio_en;
	if (client->dev.of_node)
		config.ena_gpio_initialized = true;
	if (pdata->reg_data->constraints.boot_on)
		config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;

	rdev = devm_regulator_register(&client->dev, &regulator, &config);
	if (IS_ERR(rdev)) {
		ret = PTR_ERR(rdev);
		dev_err(&client->dev, "regulator init failed (%d)\n", ret);
		return ret;
	}

	max8952->vid0 = pdata->default_mode & 0x1;
	max8952->vid1 = (pdata->default_mode >> 1) & 0x1;

	if (gpio_is_valid(pdata->gpio_vid0) &&
			gpio_is_valid(pdata->gpio_vid1)) {
		unsigned long gpio_flags;

		gpio_flags = max8952->vid0 ?
			     GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
		if (devm_gpio_request_one(&client->dev, pdata->gpio_vid0,
					  gpio_flags, "MAX8952 VID0"))
			err = 1;

		gpio_flags = max8952->vid1 ?
			     GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
		if (devm_gpio_request_one(&client->dev, pdata->gpio_vid1,
					  gpio_flags, "MAX8952 VID1"))
			err = 2;
	} else
		err = 3;

	if (err) {
		dev_warn(&client->dev, "VID0/1 gpio invalid: "
				"DVS not available.\n");
		max8952->vid0 = 0;
		max8952->vid1 = 0;
		/* Mark invalid */
		pdata->gpio_vid0 = -1;
		pdata->gpio_vid1 = -1;

		/* Disable Pulldown of EN only */
		max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60);

		dev_err(&client->dev, "DVS modes disabled because VID0 and VID1"
				" do not have proper controls.\n");
	} else {
		/*
		 * Disable Pulldown on EN, VID0, VID1 to reduce
		 * leakage current of MAX8952 assuming that MAX8952
		 * is turned on (EN==1). Note that without having VID0/1
		 * properly connected, turning pulldown off can be
		 * problematic. Thus, turn this off only when they are
		 * controllable by GPIO.
		 */
		max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x0);
	}

	max8952_write_reg(max8952, MAX8952_REG_MODE0,
			(max8952_read_reg(max8952,
					  MAX8952_REG_MODE0) & 0xC0) |
			(pdata->dvs_mode[0] & 0x3F));
	max8952_write_reg(max8952, MAX8952_REG_MODE1,
			(max8952_read_reg(max8952,
					  MAX8952_REG_MODE1) & 0xC0) |
			(pdata->dvs_mode[1] & 0x3F));
	max8952_write_reg(max8952, MAX8952_REG_MODE2,
			(max8952_read_reg(max8952,
					  MAX8952_REG_MODE2) & 0xC0) |
			(pdata->dvs_mode[2] & 0x3F));
	max8952_write_reg(max8952, MAX8952_REG_MODE3,
			(max8952_read_reg(max8952,
					  MAX8952_REG_MODE3) & 0xC0) |
			(pdata->dvs_mode[3] & 0x3F));

	max8952_write_reg(max8952, MAX8952_REG_SYNC,
			(max8952_read_reg(max8952, MAX8952_REG_SYNC) & 0x3F) |
			((pdata->sync_freq & 0x3) << 6));
	max8952_write_reg(max8952, MAX8952_REG_RAMP,
			(max8952_read_reg(max8952, MAX8952_REG_RAMP) & 0x1F) |
			((pdata->ramp_speed & 0x7) << 5));

	i2c_set_clientdata(client, max8952);

	return 0;
}