162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * tps51632-regulator.c -- TI TPS51632
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down Driverless
662306a36Sopenharmony_ci * Controller with serial VID control and DVFS.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (c) 2012, NVIDIA Corporation.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Author: Laxman Dewangan <ldewangan@nvidia.com>
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/err.h>
1462306a36Sopenharmony_ci#include <linux/i2c.h>
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/module.h>
1862306a36Sopenharmony_ci#include <linux/of.h>
1962306a36Sopenharmony_ci#include <linux/of_device.h>
2062306a36Sopenharmony_ci#include <linux/platform_device.h>
2162306a36Sopenharmony_ci#include <linux/regmap.h>
2262306a36Sopenharmony_ci#include <linux/regulator/driver.h>
2362306a36Sopenharmony_ci#include <linux/regulator/machine.h>
2462306a36Sopenharmony_ci#include <linux/regulator/of_regulator.h>
2562306a36Sopenharmony_ci#include <linux/regulator/tps51632-regulator.h>
2662306a36Sopenharmony_ci#include <linux/slab.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* Register definitions */
2962306a36Sopenharmony_ci#define TPS51632_VOLTAGE_SELECT_REG		0x0
3062306a36Sopenharmony_ci#define TPS51632_VOLTAGE_BASE_REG		0x1
3162306a36Sopenharmony_ci#define TPS51632_OFFSET_REG			0x2
3262306a36Sopenharmony_ci#define TPS51632_IMON_REG			0x3
3362306a36Sopenharmony_ci#define TPS51632_VMAX_REG			0x4
3462306a36Sopenharmony_ci#define TPS51632_DVFS_CONTROL_REG		0x5
3562306a36Sopenharmony_ci#define TPS51632_POWER_STATE_REG		0x6
3662306a36Sopenharmony_ci#define TPS51632_SLEW_REGS			0x7
3762306a36Sopenharmony_ci#define TPS51632_FAULT_REG			0x14
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define TPS51632_MAX_REG			0x15
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define TPS51632_VOUT_MASK			0x7F
4262306a36Sopenharmony_ci#define TPS51632_VOUT_OFFSET_MASK		0x1F
4362306a36Sopenharmony_ci#define TPS51632_VMAX_MASK			0x7F
4462306a36Sopenharmony_ci#define TPS51632_VMAX_LOCK			0x80
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* TPS51632_DVFS_CONTROL_REG */
4762306a36Sopenharmony_ci#define TPS51632_DVFS_PWMEN			0x1
4862306a36Sopenharmony_ci#define TPS51632_DVFS_STEP_20			0x2
4962306a36Sopenharmony_ci#define TPS51632_DVFS_VMAX_PG			0x4
5062306a36Sopenharmony_ci#define TPS51632_DVFS_PWMRST			0x8
5162306a36Sopenharmony_ci#define TPS51632_DVFS_OCA_EN			0x10
5262306a36Sopenharmony_ci#define TPS51632_DVFS_FCCM			0x20
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* TPS51632_POWER_STATE_REG */
5562306a36Sopenharmony_ci#define TPS51632_POWER_STATE_MASK		0x03
5662306a36Sopenharmony_ci#define TPS51632_POWER_STATE_MULTI_PHASE_CCM	0x0
5762306a36Sopenharmony_ci#define TPS51632_POWER_STATE_SINGLE_PHASE_CCM	0x1
5862306a36Sopenharmony_ci#define TPS51632_POWER_STATE_SINGLE_PHASE_DCM	0x2
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define TPS51632_MIN_VOLTAGE			500000
6162306a36Sopenharmony_ci#define TPS51632_MAX_VOLTAGE			1520000
6262306a36Sopenharmony_ci#define TPS51632_VOLTAGE_STEP_10mV		10000
6362306a36Sopenharmony_ci#define TPS51632_VOLTAGE_STEP_20mV		20000
6462306a36Sopenharmony_ci#define TPS51632_MAX_VSEL			0x7F
6562306a36Sopenharmony_ci#define TPS51632_MIN_VSEL			0x19
6662306a36Sopenharmony_ci#define TPS51632_DEFAULT_RAMP_DELAY		6000
6762306a36Sopenharmony_ci#define TPS51632_VOLT_VSEL(uV)					\
6862306a36Sopenharmony_ci		(DIV_ROUND_UP(uV - TPS51632_MIN_VOLTAGE,	\
6962306a36Sopenharmony_ci			TPS51632_VOLTAGE_STEP_10mV) +		\
7062306a36Sopenharmony_ci			TPS51632_MIN_VSEL)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* TPS51632 chip information */
7362306a36Sopenharmony_cistruct tps51632_chip {
7462306a36Sopenharmony_ci	struct device *dev;
7562306a36Sopenharmony_ci	struct regulator_desc desc;
7662306a36Sopenharmony_ci	struct regulator_dev *rdev;
7762306a36Sopenharmony_ci	struct regmap *regmap;
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev,
8162306a36Sopenharmony_ci		int ramp_delay)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	struct tps51632_chip *tps = rdev_get_drvdata(rdev);
8462306a36Sopenharmony_ci	int bit;
8562306a36Sopenharmony_ci	int ret;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	if (ramp_delay == 0)
8862306a36Sopenharmony_ci		bit = 0;
8962306a36Sopenharmony_ci	else
9062306a36Sopenharmony_ci		bit = DIV_ROUND_UP(ramp_delay, 6000) - 1;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	ret = regmap_write(tps->regmap, TPS51632_SLEW_REGS, BIT(bit));
9362306a36Sopenharmony_ci	if (ret < 0)
9462306a36Sopenharmony_ci		dev_err(tps->dev, "SLEW reg write failed, err %d\n", ret);
9562306a36Sopenharmony_ci	return ret;
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic const struct regulator_ops tps51632_dcdc_ops = {
9962306a36Sopenharmony_ci	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
10062306a36Sopenharmony_ci	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
10162306a36Sopenharmony_ci	.list_voltage		= regulator_list_voltage_linear,
10262306a36Sopenharmony_ci	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
10362306a36Sopenharmony_ci	.set_ramp_delay		= tps51632_dcdc_set_ramp_delay,
10462306a36Sopenharmony_ci};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic int tps51632_init_dcdc(struct tps51632_chip *tps,
10762306a36Sopenharmony_ci		struct tps51632_regulator_platform_data *pdata)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	int ret;
11062306a36Sopenharmony_ci	uint8_t	control = 0;
11162306a36Sopenharmony_ci	int vsel;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	if (!pdata->enable_pwm_dvfs)
11462306a36Sopenharmony_ci		goto skip_pwm_config;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	control |= TPS51632_DVFS_PWMEN;
11762306a36Sopenharmony_ci	vsel = TPS51632_VOLT_VSEL(pdata->base_voltage_uV);
11862306a36Sopenharmony_ci	ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_BASE_REG, vsel);
11962306a36Sopenharmony_ci	if (ret < 0) {
12062306a36Sopenharmony_ci		dev_err(tps->dev, "BASE reg write failed, err %d\n", ret);
12162306a36Sopenharmony_ci		return ret;
12262306a36Sopenharmony_ci	}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	if (pdata->dvfs_step_20mV)
12562306a36Sopenharmony_ci		control |= TPS51632_DVFS_STEP_20;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	if (pdata->max_voltage_uV) {
12862306a36Sopenharmony_ci		unsigned int vmax;
12962306a36Sopenharmony_ci		/**
13062306a36Sopenharmony_ci		 * TPS51632 hw behavior: VMAX register can be write only
13162306a36Sopenharmony_ci		 * once as it get locked after first write. The lock get
13262306a36Sopenharmony_ci		 * reset only when device is power-reset.
13362306a36Sopenharmony_ci		 * Write register only when lock bit is not enabled.
13462306a36Sopenharmony_ci		 */
13562306a36Sopenharmony_ci		ret = regmap_read(tps->regmap, TPS51632_VMAX_REG, &vmax);
13662306a36Sopenharmony_ci		if (ret < 0) {
13762306a36Sopenharmony_ci			dev_err(tps->dev, "VMAX read failed, err %d\n", ret);
13862306a36Sopenharmony_ci			return ret;
13962306a36Sopenharmony_ci		}
14062306a36Sopenharmony_ci		if (!(vmax & TPS51632_VMAX_LOCK)) {
14162306a36Sopenharmony_ci			vsel = TPS51632_VOLT_VSEL(pdata->max_voltage_uV);
14262306a36Sopenharmony_ci			ret = regmap_write(tps->regmap, TPS51632_VMAX_REG,
14362306a36Sopenharmony_ci					vsel);
14462306a36Sopenharmony_ci			if (ret < 0) {
14562306a36Sopenharmony_ci				dev_err(tps->dev,
14662306a36Sopenharmony_ci					"VMAX write failed, err %d\n", ret);
14762306a36Sopenharmony_ci				return ret;
14862306a36Sopenharmony_ci			}
14962306a36Sopenharmony_ci		}
15062306a36Sopenharmony_ci	}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciskip_pwm_config:
15362306a36Sopenharmony_ci	ret = regmap_write(tps->regmap, TPS51632_DVFS_CONTROL_REG, control);
15462306a36Sopenharmony_ci	if (ret < 0)
15562306a36Sopenharmony_ci		dev_err(tps->dev, "DVFS reg write failed, err %d\n", ret);
15662306a36Sopenharmony_ci	return ret;
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_cistatic bool is_volatile_reg(struct device *dev, unsigned int reg)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	switch (reg) {
16262306a36Sopenharmony_ci	case TPS51632_OFFSET_REG:
16362306a36Sopenharmony_ci	case TPS51632_FAULT_REG:
16462306a36Sopenharmony_ci	case TPS51632_IMON_REG:
16562306a36Sopenharmony_ci		return true;
16662306a36Sopenharmony_ci	default:
16762306a36Sopenharmony_ci		return false;
16862306a36Sopenharmony_ci	}
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistatic bool is_read_reg(struct device *dev, unsigned int reg)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	switch (reg) {
17462306a36Sopenharmony_ci	case 0x08 ... 0x0F:
17562306a36Sopenharmony_ci		return false;
17662306a36Sopenharmony_ci	default:
17762306a36Sopenharmony_ci		return true;
17862306a36Sopenharmony_ci	}
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic bool is_write_reg(struct device *dev, unsigned int reg)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	switch (reg) {
18462306a36Sopenharmony_ci	case TPS51632_VOLTAGE_SELECT_REG:
18562306a36Sopenharmony_ci	case TPS51632_VOLTAGE_BASE_REG:
18662306a36Sopenharmony_ci	case TPS51632_VMAX_REG:
18762306a36Sopenharmony_ci	case TPS51632_DVFS_CONTROL_REG:
18862306a36Sopenharmony_ci	case TPS51632_POWER_STATE_REG:
18962306a36Sopenharmony_ci	case TPS51632_SLEW_REGS:
19062306a36Sopenharmony_ci		return true;
19162306a36Sopenharmony_ci	default:
19262306a36Sopenharmony_ci		return false;
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistatic const struct regmap_config tps51632_regmap_config = {
19762306a36Sopenharmony_ci	.reg_bits		= 8,
19862306a36Sopenharmony_ci	.val_bits		= 8,
19962306a36Sopenharmony_ci	.writeable_reg		= is_write_reg,
20062306a36Sopenharmony_ci	.readable_reg		= is_read_reg,
20162306a36Sopenharmony_ci	.volatile_reg		= is_volatile_reg,
20262306a36Sopenharmony_ci	.max_register		= TPS51632_MAX_REG - 1,
20362306a36Sopenharmony_ci	.cache_type		= REGCACHE_RBTREE,
20462306a36Sopenharmony_ci};
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci#if defined(CONFIG_OF)
20762306a36Sopenharmony_cistatic const struct of_device_id tps51632_of_match[] = {
20862306a36Sopenharmony_ci	{ .compatible = "ti,tps51632",},
20962306a36Sopenharmony_ci	{},
21062306a36Sopenharmony_ci};
21162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, tps51632_of_match);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic struct tps51632_regulator_platform_data *
21462306a36Sopenharmony_ci	of_get_tps51632_platform_data(struct device *dev,
21562306a36Sopenharmony_ci				      const struct regulator_desc *desc)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	struct tps51632_regulator_platform_data *pdata;
21862306a36Sopenharmony_ci	struct device_node *np = dev->of_node;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
22162306a36Sopenharmony_ci	if (!pdata)
22262306a36Sopenharmony_ci		return NULL;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node,
22562306a36Sopenharmony_ci							  desc);
22662306a36Sopenharmony_ci	if (!pdata->reg_init_data) {
22762306a36Sopenharmony_ci		dev_err(dev, "Not able to get OF regulator init data\n");
22862306a36Sopenharmony_ci		return NULL;
22962306a36Sopenharmony_ci	}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	pdata->enable_pwm_dvfs =
23262306a36Sopenharmony_ci			of_property_read_bool(np, "ti,enable-pwm-dvfs");
23362306a36Sopenharmony_ci	pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV");
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? :
23662306a36Sopenharmony_ci					TPS51632_MIN_VOLTAGE;
23762306a36Sopenharmony_ci	pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? :
23862306a36Sopenharmony_ci					TPS51632_MAX_VOLTAGE;
23962306a36Sopenharmony_ci	return pdata;
24062306a36Sopenharmony_ci}
24162306a36Sopenharmony_ci#else
24262306a36Sopenharmony_cistatic struct tps51632_regulator_platform_data *
24362306a36Sopenharmony_ci	of_get_tps51632_platform_data(struct device *dev,
24462306a36Sopenharmony_ci				      const struct regulator_desc *desc)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	return NULL;
24762306a36Sopenharmony_ci}
24862306a36Sopenharmony_ci#endif
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cistatic int tps51632_probe(struct i2c_client *client)
25162306a36Sopenharmony_ci{
25262306a36Sopenharmony_ci	struct tps51632_regulator_platform_data *pdata;
25362306a36Sopenharmony_ci	struct regulator_dev *rdev;
25462306a36Sopenharmony_ci	struct tps51632_chip *tps;
25562306a36Sopenharmony_ci	int ret;
25662306a36Sopenharmony_ci	struct regulator_config config = { };
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	if (client->dev.of_node) {
25962306a36Sopenharmony_ci		const struct of_device_id *match;
26062306a36Sopenharmony_ci		match = of_match_device(of_match_ptr(tps51632_of_match),
26162306a36Sopenharmony_ci				&client->dev);
26262306a36Sopenharmony_ci		if (!match) {
26362306a36Sopenharmony_ci			dev_err(&client->dev, "Error: No device match found\n");
26462306a36Sopenharmony_ci			return -ENODEV;
26562306a36Sopenharmony_ci		}
26662306a36Sopenharmony_ci	}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
26962306a36Sopenharmony_ci	if (!tps)
27062306a36Sopenharmony_ci		return -ENOMEM;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	tps->dev = &client->dev;
27362306a36Sopenharmony_ci	tps->desc.name = client->name;
27462306a36Sopenharmony_ci	tps->desc.id = 0;
27562306a36Sopenharmony_ci	tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
27662306a36Sopenharmony_ci	tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
27762306a36Sopenharmony_ci	tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
27862306a36Sopenharmony_ci	tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
27962306a36Sopenharmony_ci	tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
28062306a36Sopenharmony_ci	tps->desc.ops = &tps51632_dcdc_ops;
28162306a36Sopenharmony_ci	tps->desc.type = REGULATOR_VOLTAGE;
28262306a36Sopenharmony_ci	tps->desc.owner = THIS_MODULE;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	pdata = dev_get_platdata(&client->dev);
28562306a36Sopenharmony_ci	if (!pdata && client->dev.of_node)
28662306a36Sopenharmony_ci		pdata = of_get_tps51632_platform_data(&client->dev, &tps->desc);
28762306a36Sopenharmony_ci	if (!pdata) {
28862306a36Sopenharmony_ci		dev_err(&client->dev, "No Platform data\n");
28962306a36Sopenharmony_ci		return -EINVAL;
29062306a36Sopenharmony_ci	}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	if (pdata->enable_pwm_dvfs) {
29362306a36Sopenharmony_ci		if ((pdata->base_voltage_uV < TPS51632_MIN_VOLTAGE) ||
29462306a36Sopenharmony_ci		    (pdata->base_voltage_uV > TPS51632_MAX_VOLTAGE)) {
29562306a36Sopenharmony_ci			dev_err(&client->dev, "Invalid base_voltage_uV setting\n");
29662306a36Sopenharmony_ci			return -EINVAL;
29762306a36Sopenharmony_ci		}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci		if ((pdata->max_voltage_uV) &&
30062306a36Sopenharmony_ci		    ((pdata->max_voltage_uV < TPS51632_MIN_VOLTAGE) ||
30162306a36Sopenharmony_ci		     (pdata->max_voltage_uV > TPS51632_MAX_VOLTAGE))) {
30262306a36Sopenharmony_ci			dev_err(&client->dev, "Invalid max_voltage_uV setting\n");
30362306a36Sopenharmony_ci			return -EINVAL;
30462306a36Sopenharmony_ci		}
30562306a36Sopenharmony_ci	}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	if (pdata->enable_pwm_dvfs)
30862306a36Sopenharmony_ci		tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG;
30962306a36Sopenharmony_ci	else
31062306a36Sopenharmony_ci		tps->desc.vsel_reg = TPS51632_VOLTAGE_SELECT_REG;
31162306a36Sopenharmony_ci	tps->desc.vsel_mask = TPS51632_VOUT_MASK;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	tps->regmap = devm_regmap_init_i2c(client, &tps51632_regmap_config);
31462306a36Sopenharmony_ci	if (IS_ERR(tps->regmap)) {
31562306a36Sopenharmony_ci		ret = PTR_ERR(tps->regmap);
31662306a36Sopenharmony_ci		dev_err(&client->dev, "regmap init failed, err %d\n", ret);
31762306a36Sopenharmony_ci		return ret;
31862306a36Sopenharmony_ci	}
31962306a36Sopenharmony_ci	i2c_set_clientdata(client, tps);
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	ret = tps51632_init_dcdc(tps, pdata);
32262306a36Sopenharmony_ci	if (ret < 0) {
32362306a36Sopenharmony_ci		dev_err(tps->dev, "Init failed, err = %d\n", ret);
32462306a36Sopenharmony_ci		return ret;
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	/* Register the regulators */
32862306a36Sopenharmony_ci	config.dev = &client->dev;
32962306a36Sopenharmony_ci	config.init_data = pdata->reg_init_data;
33062306a36Sopenharmony_ci	config.driver_data = tps;
33162306a36Sopenharmony_ci	config.regmap = tps->regmap;
33262306a36Sopenharmony_ci	config.of_node = client->dev.of_node;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	rdev = devm_regulator_register(&client->dev, &tps->desc, &config);
33562306a36Sopenharmony_ci	if (IS_ERR(rdev)) {
33662306a36Sopenharmony_ci		dev_err(tps->dev, "regulator register failed\n");
33762306a36Sopenharmony_ci		return PTR_ERR(rdev);
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	tps->rdev = rdev;
34162306a36Sopenharmony_ci	return 0;
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistatic const struct i2c_device_id tps51632_id[] = {
34562306a36Sopenharmony_ci	{.name = "tps51632",},
34662306a36Sopenharmony_ci	{},
34762306a36Sopenharmony_ci};
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, tps51632_id);
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic struct i2c_driver tps51632_i2c_driver = {
35262306a36Sopenharmony_ci	.driver = {
35362306a36Sopenharmony_ci		.name = "tps51632",
35462306a36Sopenharmony_ci		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
35562306a36Sopenharmony_ci		.of_match_table = of_match_ptr(tps51632_of_match),
35662306a36Sopenharmony_ci	},
35762306a36Sopenharmony_ci	.probe = tps51632_probe,
35862306a36Sopenharmony_ci	.id_table = tps51632_id,
35962306a36Sopenharmony_ci};
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic int __init tps51632_init(void)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	return i2c_add_driver(&tps51632_i2c_driver);
36462306a36Sopenharmony_ci}
36562306a36Sopenharmony_cisubsys_initcall(tps51632_init);
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_cistatic void __exit tps51632_cleanup(void)
36862306a36Sopenharmony_ci{
36962306a36Sopenharmony_ci	i2c_del_driver(&tps51632_i2c_driver);
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_cimodule_exit(tps51632_cleanup);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ciMODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
37462306a36Sopenharmony_ciMODULE_DESCRIPTION("TPS51632 voltage regulator driver");
37562306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
376