/*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; }
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, ®ulator, &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; }