aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-davinci/0005-tps6507x_regulator_mfd_integration.patch
diff options
context:
space:
mode:
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.patch397
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 */