public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* Problems while designing TPS65023 regulator driver
@ 2009-02-26  9:11 Aggarwal, Anuj
  2009-02-26 14:04 ` Mark Brown
  0 siblings, 1 reply; 19+ messages in thread
From: Aggarwal, Anuj @ 2009-02-26  9:11 UTC (permalink / raw)
  To: linux-omap@vger.kernel.org


Hi,

I am working on TPS65023 PMIC (http://focus.ti.com/docs/prod/folders/print/tps65023.html) regulator driver. It supports 3 step-down converters and 2 LDOs, all connected to the same I2C device. I am facing some design related issues and need your opinion on the same.

Since all the five regulators can be controlled using a single i2c device, I made a single i2c_board_info structure in my platform specific file and put all the regulator_init_data information there:

<<<<<code starts>>>>
/* MPU voltage regulator of DCDC type */
struct regulator_consumer_supply tps65023_mpu_consumers = {
	.supply = "vdd1",
};

/* MMC voltage regulator of LDO type */
struct regulator_consumer_supply tps65023_mmc_consumers = {
	.supply = "mmc",
};

struct regulator_init_data tps_regulator_data[] = {
	{
		.constraints = {
			.min_uV = 800000,
			.max_uV = 1600000,
			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
				REGULATOR_CHANGE_STATUS),
		},
		.num_consumer_supplies  = 1,
		.consumer_supplies      = &tps65023_mpu_consumers,
	},
	.
	.
	.
	{
		.constraints = {
			.min_uV = 1050000,
			.max_uV = 3300000,
			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
				REGULATOR_CHANGE_STATUS),
		},
		.num_consumer_supplies  = 1,
		.consumer_supplies      = &tps65023_mmc_consumers,
	},
};

static struct i2c_board_info __initdata tps_65023_i2c_board_info[] = {
	{
		I2C_BOARD_INFO("tps65023", 0x48),
		.flags = I2C_CLIENT_WAKE,
		.platform_data = &tps_regulator_data[0],
	},
};

static int __init omap3_evm_i2c_init(void)
{
	omap_register_i2c_bus(1, 400, tps_65023_i2c_board_info,
		ARRAY_SIZE(tps_65023_i2c_board_info));
        .
        .
}
<<<<<code ends>>>>

Now, in my regulator driver code, I am creating an array of the available regulators, passing that array as driver_data in my i2c_device_id structure and registering my i2c_driver using i2c_add_driver() during initialization, as shown below:

<<<<<code starts>>>>
#define TPS65023_NUM_DCDC		3
#define TPS65023_NUM_LDO		2
#define TPS65023_NUM_REGULATOR	(TPS65023_NUM_DCDC + TPS65023_NUM_LDO)

struct tps_info {
	const char 	*name;
	unsigned		min_uV;
	unsigned		max_uV;
	bool			fixed;
	u8			table_len;
	const u16		*table;
};

struct tps {
	struct regulator_desc	desc[TPS65023_NUM_REGULATOR];
	struct i2c_client		*client;
	struct regulator_dev	*rdev[TPS65023_NUM_REGULATOR];
	const struct tps_info	*info[TPS65023_NUM_REGULATOR];
};

static const struct tps_info tps65023_regs[] = {
	{
	.name = "VDCDC1",
	.min_uV		=  800000,
	.max_uV		= 1600000,
	.fixed = 0,
	.table_len = ARRAY_SIZE(VDCDC1_VSEL_table),
	.table = VDCDC1_VSEL_table,
	},
	.	
	.
	.
	{
	.name = "LDO2",
	.min_uV		= 1000000,
	.max_uV		= 3150000,
	.fixed = 0,
	.table_len = ARRAY_SIZE(LDO2_VSEL_table),
	.table = LDO2_VSEL_table,
	},
};

static const struct i2c_device_id tps_65023_id = {
	.name = "tps65023",
	.driver_data = (unsigned long) &tps65023_regs[0],
};

MODULE_DEVICE_TABLE(i2c, tps_65023_id);

static struct i2c_driver tps_65023_i2c_driver = {
	.driver = {
		.name	=	"tps_65023_pwr",
		.owner	=	THIS_MODULE,
	},
	.probe		= tps_65023_probe,
	.remove	= __devexit_p(tps_65023_remove),
	.id_table	= &tps_65023_id,
};

/**
 * tps_65023_init
 *
 * Module init function
 */
static int __init tps_65023_init(void)
{
	return i2c_add_driver(&tps_65023_i2c_driver);
}
late_initcall(tps_65023_init);
<<<<<code ends>>>>

Now, the problem is in the tps_65023_probe function. Since it will be called only once as there is only one i2c device, I have to register all the regulators in that only. But I am not able to communicate the same to the regulator core layer. Inside the regulator_register(), variable init_data, which equals to dev->platform_data, is always pointing to the first array member, which is coming from the evm specific file. And it fails to register my second regulator instance, set_consumer_device_supply() specifically failing for the second iteration. Because of this, the probe function fails.

How should I handle this scenario? Am I missing something in my implementation?

Regards,
Anuj Aggarwal

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-04-24  8:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-26  9:11 Problems while designing TPS65023 regulator driver Aggarwal, Anuj
2009-02-26 14:04 ` Mark Brown
2009-03-05 12:03   ` Aggarwal, Anuj
2009-03-06 13:34     ` Mark Brown
2009-03-07  0:07       ` David Brownell
2009-03-07 16:22         ` Mark Brown
2009-03-08 20:54           ` David Brownell
2009-03-08 22:41             ` Mark Brown
2009-03-10  0:45               ` David Brownell
2009-03-10 23:33                 ` Mark Brown
2009-04-03  8:03   ` Aggarwal, Anuj
2009-04-03  8:53     ` Mark Brown
2009-04-04  0:05       ` Tony Lindgren
2009-04-23 13:30         ` Trilok Soni
2009-04-23 22:17           ` David Brownell
2009-04-24  6:01             ` Trilok Soni
2009-04-24  6:05               ` Aggarwal, Anuj
2009-04-24  6:32               ` David Brownell
2009-04-24  8:12                 ` Aggarwal, Anuj

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox