电源管理芯片nxe2100驱动

    nxe2100芯片是nxe2000的升级芯片,它提供5个DCDC,10个LDO,2个LDORTC。

    High Efficiency Step-down DC/DC Converters
* DCDC1 -3 0.6V-3.5V Max 3000mA
* DCDC4-5 0.6V-3.5V Max 2000mA
* Soft-start circuit
●Low Drop Voltage Regulators
* LDO1 -4 with ECO 0.9V-3.5V Max 300mA
* LDO5-6 with ECO 0.6V-3.5V Max 300mA
* LDO7-10 0.9V-3.5V Max 200mA
* LDORTC1 1.7-3.5V Max 10mA (AlwaysOn, For coin battery)
* LDORTC2 0.9-3.5V Max 10mA (AlwaysOn)

NXE2100的驱动可以在NXE2000的驱动上修改:

linux配置中有以下配置包含了NXE2000:

(1)drivers/power下的kconfig:
config BATTERY_NXE2000(drivers/power/nxe2000-battery.c)。选择它同时会选择MFD_NXE2000(drivers/mfd/nxe2000.c和nxe2000-irq.c)和REGULATOR_NXE2000。
(2)drivers/mfd下的kconfig
config MFD_NXE2000。选择它同时会选择MFD_CORE
(4)    drivers/regulator下的kconfig
config REGULATOR_NXE2000(drivers/regulator/nxe2000-regulator.c)。选择它同时会选择MFD_NXE2000

nxe2000是一个I2C设备,它的驱动挂载到I2C总线上:

static struct i2c_board_info __initdata nxe2000_i2c_boardinfo[] = {
	{
		I2C_BOARD_INFO("nxe2000", NXE2000_I2C_ADDR),
		.irq			= CFG_GPIO_PMIC_INTR,
		.platform_data	= &nxe2000_platform,
	},
};
NXE2000.c是它的驱动,其中probe的实现如下:

static int nxe2000_i2c_probe(struct i2c_client *client,
			      const struct i2c_device_id *id)
{
	struct nxe2000 *nxe2000;
	struct nxe2000_platform_data *pdata = client->dev.platform_data;
	int ret;

	nxe2000 = kzalloc(sizeof(struct nxe2000), GFP_KERNEL);
	if (nxe2000 == NULL)
		return -ENOMEM;

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

	mutex_init(&nxe2000->io_lock);

	nxe2000->bank_num = 0;

	/* For init PMIC_IRQ port */
//	ret = pdata->init_port(client->irq);

	if (client->irq) {
		nxe2000->irq_base       = pdata->irq_base;
		nxe2000->chip_irq       = gpio_to_irq(client->irq);
		nxe2000->chip_irq_type  = pdata->irq_type;

		ret = nxe2000_irq_init(nxe2000);
		if (ret) {
			dev_err(&client->dev, "IRQ init failed: %d\n", ret);
			goto err_irq_init;
		}
	}

	ret = nxe2000_add_subdevs(nxe2000, pdata);
	if (ret) {
		dev_err(&client->dev, "add devices failed: %d\n", ret);
		goto err_add_devs;
	}

	nxe2000_noe_init(nxe2000);

	nxe2000_gpio_init(nxe2000, pdata);

	nxe2000_debuginit(nxe2000);

#ifdef CONFIG_NXE2000_WDG_TEST
	nxe2000_watchdog_init(nxe2000);
#endif

	nxe2000_i2c_client = client;

	backup_pm_power_off = pm_power_off;
	pm_power_off = nxe2000_power_off;

#if (NXE2000_PM_RESTART == 1)
	backup_pm_restart = arm_pm_restart;
	arm_pm_restart = nxe2000_restart;
#endif

	return 0;

err_add_devs:
	if (client->irq)
		nxe2000_irq_exit(nxe2000);
err_irq_init:
	kfree(nxe2000);
	return ret;
}
nxe2000_add_subdevs函数的功能是添加子设备,子设备的定义在结构nxe2000_devs_dcdc中:

#define NXE2000_DEV_REG 		\
	NXE2000_REG(DC1, dc1, 0),	\
	NXE2000_REG(DC2, dc2, 0),	\
	NXE2000_REG(DC3, dc3, 0),	\
	NXE2000_REG(DC4, dc4, 0),	\
	NXE2000_REG(DC5, dc5, 0),	\
	NXE2000_REG(LDO1, ldo1, 0),	\
	NXE2000_REG(LDO2, ldo2, 0),	\
	NXE2000_REG(LDO3, ldo3, 0),	\
	NXE2000_REG(LDO4, ldo4, 0),	\
	NXE2000_REG(LDO5, ldo5, 0),	\
	NXE2000_REG(LDO6, ldo6, 0),	\
	NXE2000_REG(LDO7, ldo7, 0),	\
	NXE2000_REG(LDO8, ldo8, 0),	\
	NXE2000_REG(LDO9, ldo9, 0),	\
	NXE2000_REG(LDO10, ldo10, 0),	\
	NXE2000_REG(LDORTC1, ldortc1, 0),	\
	NXE2000_REG(LDORTC2, ldortc2, 0)

static struct nxe2000_subdev_info nxe2000_devs_dcdc[] = {
	NXE2000_DEV_REG,
	NXE2000_BATTERY_REG,
	NXE2000_PWRKEY_REG,
#ifdef CONFIG_NXE2000_RTC
	NXE2000_RTC_REG,
#endif
};

nxe2000_subdev_info:

struct nxe2000_subdev_info {
	int			id;
	const char	*name;
	void		*platform_data;
};
nxe2000_add_subdevs函数为上面定义的数组中定义的项新建一个设备:

static int nxe2000_add_subdevs(struct nxe2000 *nxe2000,
				struct nxe2000_platform_data *pdata)
{
	struct nxe2000_subdev_info *subdev;
	struct platform_device *pdev;
	int i, ret = 0;

	for (i = 0; i < pdata->num_subdevs; i++) {
		subdev = &pdata->subdevs[i];

		pdev = platform_device_alloc(subdev->name, subdev->id);

		pdev->dev.parent = nxe2000->dev;
		pdev->dev.platform_data = subdev->platform_data;

		ret = platform_device_add(pdev);
		if (ret)
			goto failed;
	}
	return 0;

failed:
	nxe2000_remove_subdevs(nxe2000);
	return ret;
}
其中,每个DCDC、LDO设备是一个nxe2000-regulator设备:

#define NXE2000_REG(_id, _name, _sname)	\
{	\
	.id		= NXE2000_ID_##_id,	\
	.name	= "nxe2000-regulator",	\
	.platform_data	= &pdata_##_name##_##_sname,	\
}

在nxe2000-regulator.c中定义了这个设备。

static int __devinit nxe2000_regulator_probe(struct platform_device *pdev)
{
	struct nxe2000_regulator *ri = NULL;
	struct regulator_dev *rdev;
	struct nxe2000_regulator_platform_data *tps_pdata;
	int id = pdev->id;
	int err;

	ri = find_regulator_info(id);
	if (ri == NULL) {
		dev_err(&pdev->dev, "invalid regulator ID specified\n");
		return -EINVAL;
	}
	tps_pdata = pdev->dev.platform_data;
	ri->dev = &pdev->dev;

	nxe2000_suspend_status = 0;

	err = nxe2000_cache_regulator_register(pdev->dev.parent, ri);
	if (err) {
		dev_err(&pdev->dev, "Fail in caching register\n");
		return err;
	}

	err = nxe2000_regulator_preinit(pdev->dev.parent, ri, tps_pdata);
	if (err) {
		dev_err(&pdev->dev, "Fail in pre-initialisation\n");
		return err;
	}

	rdev = regulator_register(&ri->desc, &pdev->dev,
				&tps_pdata->regulator, ri, NULL);
	if (IS_ERR_OR_NULL(rdev)) {
		dev_err(&pdev->dev, "failed to register regulator %s\n",
				ri->desc.name);
		return PTR_ERR(rdev);
	}

	platform_set_drvdata(pdev, rdev);

	return 0;
}



你可能感兴趣的:(电源管理芯片nxe2100驱动)