diff options
Diffstat (limited to 'recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch')
-rw-r--r-- | recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch b/recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch new file mode 100644 index 0000000000..d962e82b6d --- /dev/null +++ b/recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch @@ -0,0 +1,397 @@ +Index: git/drivers/mfd/tps6507x.c +=================================================================== +--- git.orig/drivers/mfd/tps6507x.c 2010-01-12 08:43:00.961383768 -0600 ++++ git/drivers/mfd/tps6507x.c 2010-01-12 08:52:41.725819096 -0600 +@@ -57,12 +57,40 @@ + return 0; + } + ++/* ++ * Register a client device. This is non-fatal since there is no need to ++ * fail the entire device init due to a single platform device failing. ++ */ ++static void tps6507x_client_dev_register(struct tps6507x_dev *tps6507x, ++ const char *name, ++ struct platform_device **pdev) ++{ ++ int ret; ++ ++ *pdev = platform_device_alloc(name, -1); ++ if (*pdev == NULL) { ++ dev_err(tps6507x->dev, "Failed to allocate %s\n", name); ++ return; ++ } ++ ++ (*pdev)->dev.parent = tps6507x->dev; ++ platform_set_drvdata(*pdev, tps6507x); ++ ret = platform_device_add(*pdev); ++ if (ret != 0) { ++ dev_err(tps6507x->dev, "Failed to register %s: %d\n", name, ret); ++ platform_device_put(*pdev); ++ *pdev = NULL; ++ } ++} + + int tps6507x_device_init(struct tps6507x_dev *tps6507x, int irq, + struct tps6507x_board *pdata) + { + int ret = 0; ++ struct platform_device *pdev; + ++ tps6507x_client_dev_register(tps6507x, "tps6507x-pmic", ++ &pdev); + return ret; + } + +@@ -71,7 +99,6 @@ + { + struct tps6507x_dev *tps6507x; + int ret = 0; +- + tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL); + if (tps6507x == NULL) { + kfree(i2c); +Index: git/drivers/regulator/tps6507x-regulator.c +=================================================================== +--- git.orig/drivers/regulator/tps6507x-regulator.c 2010-01-12 08:43:01.125399079 -0600 ++++ git/drivers/regulator/tps6507x-regulator.c 2010-01-12 08:53:16.586248235 -0600 +@@ -22,7 +22,6 @@ + #include <linux/platform_device.h> + #include <linux/regulator/driver.h> + #include <linux/regulator/machine.h> +-#include <linux/i2c.h> + #include <linux/delay.h> + #include <linux/mfd/tps6507x.h> + +@@ -105,9 +104,47 @@ + unsigned reg_high:1; + }; + ++static const struct tps_info tps6507x_pmic_regs[] = { ++ { ++ .name = "VDCDC1", ++ .min_uV = 725000, ++ .max_uV = 3300000, ++ .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), ++ .table = VDCDCx_VSEL_table, ++ }, ++ { ++ .name = "VDCDC2", ++ .min_uV = 725000, ++ .max_uV = 3300000, ++ .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), ++ .table = VDCDCx_VSEL_table, ++ }, ++ { ++ .name = "VDCDC3", ++ .min_uV = 725000, ++ .max_uV = 3300000, ++ .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), ++ .table = VDCDCx_VSEL_table, ++ }, ++ { ++ .name = "LDO1", ++ .min_uV = 1000000, ++ .max_uV = 3300000, ++ .table_len = ARRAY_SIZE(LDO1_VSEL_table), ++ .table = LDO1_VSEL_table, ++ }, ++ { ++ .name = "LDO2", ++ .min_uV = 725000, ++ .max_uV = 3300000, ++ .table_len = ARRAY_SIZE(LDO2_VSEL_table), ++ .table = LDO2_VSEL_table, ++ }, ++}; ++ + struct tps_pmic { + struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; +- struct i2c_client *client; ++ struct tps6507x_dev *mfd; + struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; + struct tps_info *info[TPS6507X_NUM_REGULATOR]; + struct mutex io_lock; +@@ -115,12 +152,21 @@ + + static inline int tps6507x_pmic_read(struct tps_pmic *tps, u8 reg) + { +- return i2c_smbus_read_byte_data(tps->client, reg); ++ u8 val; ++ int err; ++ ++ err = tps->mfd->read_dev(tps->mfd, reg, 1, &val); ++ ++ if (err) { ++ return err; ++ } ++ ++ return val; + } + + static inline int tps6507x_pmic_write(struct tps_pmic *tps, u8 reg, u8 val) + { +- return i2c_smbus_write_byte_data(tps->client, reg, val); ++ return tps->mfd->write_dev(tps->mfd, reg, 1, &val); + } + + static int tps6507x_pmic_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) +@@ -131,7 +177,7 @@ + + data = tps6507x_pmic_read(tps, reg); + if (data < 0) { +- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); + err = data; + goto out; + } +@@ -139,7 +185,7 @@ + data |= mask; + err = tps6507x_pmic_write(tps, reg, data); + if (err) +- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); + + out: + mutex_unlock(&tps->io_lock); +@@ -154,7 +200,7 @@ + + data = tps6507x_pmic_read(tps, reg); + if (data < 0) { +- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); + err = data; + goto out; + } +@@ -162,7 +208,7 @@ + data &= ~mask; + err = tps6507x_pmic_write(tps, reg, data); + if (err) +- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); + + out: + mutex_unlock(&tps->io_lock); +@@ -177,7 +223,7 @@ + + data = tps6507x_pmic_read(tps, reg); + if (data < 0) +- dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); + + mutex_unlock(&tps->io_lock); + return data; +@@ -191,7 +237,7 @@ + + err = tps6507x_pmic_write(tps, reg, val); + if (err < 0) +- dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); ++ dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); + + mutex_unlock(&tps->io_lock); + return err; +@@ -494,27 +540,24 @@ + .list_voltage = tps6507x_pmic_ldo_list_voltage, + }; + +-static +-int tps6507x_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) ++static __devinit ++int tps6507x_pmic_probe(struct platform_device *pdev) + { ++ struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); + static int desc_id; +- struct tps_info *info = (void *)id->driver_data; ++ struct tps_info *info = &tps6507x_pmic_regs[0]; + struct regulator_init_data *init_data; + struct regulator_dev *rdev; + struct tps_pmic *tps; +- struct tps6507x_board *tps_board; ++ struct tps6507x_board *tps_board; + int i; + +- if (!i2c_check_functionality(client->adapter, +- I2C_FUNC_SMBUS_BYTE_DATA)) +- return -EIO; +- + /** +- * tps_board points to tps6507x related constants ++ * tps_board points to pmic related constants + * coming from the board-evm file. + */ + +- tps_board = (struct tps6507x_board *)client->dev.platform_data; ++ tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; + + if (!tps_board) + return -EIO; +@@ -536,7 +579,7 @@ + mutex_init(&tps->io_lock); + + /* common for all regulators */ +- tps->client = client; ++ tps->mfd = tps6507x_dev; + + for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { + /* Register the regulators */ +@@ -551,19 +594,16 @@ + tps->desc[i].owner = THIS_MODULE; + + rdev = regulator_register(&tps->desc[i], +- &client->dev, init_data, tps); ++ tps6507x_dev->dev, init_data, tps); + if (IS_ERR(rdev)) { +- dev_err(&client->dev, "failed to register %s\n", +- id->name); ++ dev_err(tps6507x_dev->dev, "failed to register %s regulator\n", ++ pdev->name); + + /* Unregister */ + while (i) + regulator_unregister(tps->rdev[--i]); + +- tps->client = NULL; +- +- /* clear the client data in i2c */ +- i2c_set_clientdata(client, NULL); ++ tps->mfd = NULL; + + kfree(tps); + return PTR_ERR(rdev); +@@ -573,87 +613,34 @@ + tps->rdev[i] = rdev; + } + +- i2c_set_clientdata(client, tps); ++// tps6507x_dev->pmic.pdev = pdev; // XXXX - but tps6507x_dev is pdev !!! + + return 0; + } + +-/** +- * tps6507x_remove - TPS6507x driver i2c remove handler +- * @client: i2c driver client device structure +- * +- * Unregister TPS driver as an i2c client device driver +- */ +-static int __devexit tps6507x_pmic_remove(struct i2c_client *client) ++static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) + { +- struct tps_pmic *tps = i2c_get_clientdata(client); ++ ++ struct tps_pmic *tps = platform_get_drvdata(pdev); //REVISIT this is wrong + int i; + + for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) + regulator_unregister(tps->rdev[i]); + +- tps->client = NULL; ++ tps->mfd = NULL; + +- /* clear the client data in i2c */ +- i2c_set_clientdata(client, NULL); + kfree(tps); + + return 0; + } + +-static const struct tps_info tps6507x_pmic_regs[] = { +- { +- .name = "VDCDC1", +- .min_uV = 725000, +- .max_uV = 3300000, +- .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), +- .table = VDCDCx_VSEL_table, +- }, +- { +- .name = "VDCDC2", +- .min_uV = 725000, +- .max_uV = 3300000, +- .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), +- .table = VDCDCx_VSEL_table, +- }, +- { +- .name = "VDCDC3", +- .min_uV = 725000, +- .max_uV = 3300000, +- .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), +- .table = VDCDCx_VSEL_table, +- }, +- { +- .name = "LDO1", +- .min_uV = 1000000, +- .max_uV = 3300000, +- .table_len = ARRAY_SIZE(LDO1_VSEL_table), +- .table = LDO1_VSEL_table, +- }, +- { +- .name = "LDO2", +- .min_uV = 725000, +- .max_uV = 3300000, +- .table_len = ARRAY_SIZE(LDO2_VSEL_table), +- .table = LDO2_VSEL_table, +- }, +-}; +- +-static const struct i2c_device_id tps6507x_pmic_id[] = { +- {.name = "tps6507x", +- .driver_data = (unsigned long) tps6507x_pmic_regs,}, +- { }, +-}; +-MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); +- +-static struct i2c_driver tps6507x_i2c_driver = { ++static struct platform_driver tps6507x_pmic_driver = { + .driver = { +- .name = "tps6507x", ++ .name = "tps6507x-pmic", + .owner = THIS_MODULE, + }, + .probe = tps6507x_pmic_probe, + .remove = __devexit_p(tps6507x_pmic_remove), +- .id_table = tps6507x_pmic_id, + }; + + /** +@@ -663,7 +650,7 @@ + */ + static int __init tps6507x_pmic_init(void) + { +- return i2c_add_driver(&tps6507x_i2c_driver); ++ return platform_driver_register(&tps6507x_pmic_driver); + } + subsys_initcall(tps6507x_pmic_init); + +@@ -674,10 +661,11 @@ + */ + static void __exit tps6507x_pmic_cleanup(void) + { +- i2c_del_driver(&tps6507x_i2c_driver); ++ platform_driver_unregister(&tps6507x_pmic_driver); + } + module_exit(tps6507x_pmic_cleanup); + + MODULE_AUTHOR("Texas Instruments"); + MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); + MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:tps6507x-pmic"); +Index: git/include/linux/mfd/tps6507x.h +=================================================================== +--- git.orig/include/linux/mfd/tps6507x.h 2010-01-12 08:43:00.961383768 -0600 ++++ git/include/linux/mfd/tps6507x.h 2010-01-12 08:52:41.753688570 -0600 +@@ -156,10 +156,13 @@ + struct device *dev; + struct i2c_client *i2c_client; + int (*read_dev)(struct tps6507x_dev *tps6507x, char reg, int size, +- void *dest); ++ void *dest); + int (*write_dev)(struct tps6507x_dev *tps6507x, char reg, int size, +- void *src); ++ void *src); + struct mutex adc_mutex; ++ ++ /* Client devices */ ++ struct tps6507x_pmic *pmic; + }; + + #endif /* __LINUX_MFD_TPS6507X_H */ |