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
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html