aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2012-01-04 07:58:33 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-22 08:05:49 -0400
commit364cedb2f97063d649b2950c099883b89b60c000 (patch)
tree3cba9d57d17e681f94e27d821869545a9f3a6bc3 /drivers/mfd
parentec1a07b3440cc28946a77a974c21570bbef6ffa1 (diff)
mfd: Detach twl6040 from the pmic mfd driver
On OMAP4 platform audio has separate IC, it is no longer part of the pmic chip. Prevent twl-core to claim the 0x4b address, which belongs to the twl6040 audio IC. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Benoit Cousson <b-cousson@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/twl-core.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index eb9bd203e497..8bff96848102 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -113,8 +113,8 @@
113#define twl_has_watchdog() false 113#define twl_has_watchdog() false
114#endif 114#endif
115 115
116#if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\ 116#if defined(CONFIG_MFD_TWL4030_AUDIO) || \
117 defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE) 117 defined(CONFIG_MFD_TWL4030_AUDIO_MODULE)
118#define twl_has_codec() true 118#define twl_has_codec() true
119#else 119#else
120#define twl_has_codec() false 120#define twl_has_codec() false
@@ -144,6 +144,7 @@
144#define SUB_CHIP_ID1 1 144#define SUB_CHIP_ID1 1
145#define SUB_CHIP_ID2 2 145#define SUB_CHIP_ID2 2
146#define SUB_CHIP_ID3 3 146#define SUB_CHIP_ID3 3
147#define SUB_CHIP_ID_INVAL 0xff
147 148
148#define TWL_MODULE_LAST TWL4030_MODULE_LAST 149#define TWL_MODULE_LAST TWL4030_MODULE_LAST
149 150
@@ -312,7 +313,7 @@ static struct twl_mapping twl6030_map[] = {
312 * so they continue to match the order in this table. 313 * so they continue to match the order in this table.
313 */ 314 */
314 { SUB_CHIP_ID1, TWL6030_BASEADD_USB }, 315 { SUB_CHIP_ID1, TWL6030_BASEADD_USB },
315 { SUB_CHIP_ID3, TWL6030_BASEADD_AUDIO }, 316 { SUB_CHIP_ID_INVAL, TWL6030_BASEADD_AUDIO },
316 { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID }, 317 { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID },
317 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 318 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
318 { SUB_CHIP_ID1, TWL6030_BASEADD_PIH }, 319 { SUB_CHIP_ID1, TWL6030_BASEADD_PIH },
@@ -374,6 +375,11 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
374 return -EPERM; 375 return -EPERM;
375 } 376 }
376 sid = twl_map[mod_no].sid; 377 sid = twl_map[mod_no].sid;
378 if (unlikely(sid == SUB_CHIP_ID_INVAL)) {
379 pr_err("%s: module %d is not part of the pmic\n",
380 DRIVER_NAME, mod_no);
381 return -EINVAL;
382 }
377 twl = &twl_modules[sid]; 383 twl = &twl_modules[sid];
378 384
379 mutex_lock(&twl->xfer_lock); 385 mutex_lock(&twl->xfer_lock);
@@ -431,6 +437,11 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
431 return -EPERM; 437 return -EPERM;
432 } 438 }
433 sid = twl_map[mod_no].sid; 439 sid = twl_map[mod_no].sid;
440 if (unlikely(sid == SUB_CHIP_ID_INVAL)) {
441 pr_err("%s: module %d is not part of the pmic\n",
442 DRIVER_NAME, mod_no);
443 return -EINVAL;
444 }
434 twl = &twl_modules[sid]; 445 twl = &twl_modules[sid];
435 446
436 mutex_lock(&twl->xfer_lock); 447 mutex_lock(&twl->xfer_lock);
@@ -832,15 +843,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
832 return PTR_ERR(child); 843 return PTR_ERR(child);
833 } 844 }
834 845
835 if (twl_has_codec() && pdata->audio && twl_class_is_6030()) {
836 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
837 child = add_child(sub_chip_id, "twl6040",
838 pdata->audio, sizeof(*pdata->audio),
839 false, 0, 0);
840 if (IS_ERR(child))
841 return PTR_ERR(child);
842 }
843
844 /* twl4030 regulators */ 846 /* twl4030 regulators */
845 if (twl_has_regulator() && twl_class_is_4030()) { 847 if (twl_has_regulator() && twl_class_is_4030()) {
846 child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, 848 child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
@@ -1156,18 +1158,21 @@ static void clocks_init(struct device *dev,
1156 1158
1157static int twl_remove(struct i2c_client *client) 1159static int twl_remove(struct i2c_client *client)
1158{ 1160{
1159 unsigned i; 1161 unsigned i, num_slaves;
1160 int status; 1162 int status;
1161 1163
1162 if (twl_class_is_4030()) 1164 if (twl_class_is_4030()) {
1163 status = twl4030_exit_irq(); 1165 status = twl4030_exit_irq();
1164 else 1166 num_slaves = TWL_NUM_SLAVES;
1167 } else {
1165 status = twl6030_exit_irq(); 1168 status = twl6030_exit_irq();
1169 num_slaves = TWL_NUM_SLAVES - 1;
1170 }
1166 1171
1167 if (status < 0) 1172 if (status < 0)
1168 return status; 1173 return status;
1169 1174
1170 for (i = 0; i < TWL_NUM_SLAVES; i++) { 1175 for (i = 0; i < num_slaves; i++) {
1171 struct twl_client *twl = &twl_modules[i]; 1176 struct twl_client *twl = &twl_modules[i];
1172 1177
1173 if (twl->client && twl->client != client) 1178 if (twl->client && twl->client != client)
@@ -1186,7 +1191,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1186 struct device_node *node = client->dev.of_node; 1191 struct device_node *node = client->dev.of_node;
1187 int irq_base = 0; 1192 int irq_base = 0;
1188 int status; 1193 int status;
1189 unsigned i; 1194 unsigned i, num_slaves;
1190 1195
1191 if (node && !pdata) { 1196 if (node && !pdata) {
1192 /* 1197 /*
@@ -1215,7 +1220,17 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1215 return -EBUSY; 1220 return -EBUSY;
1216 } 1221 }
1217 1222
1218 for (i = 0; i < TWL_NUM_SLAVES; i++) { 1223 if ((id->driver_data) & TWL6030_CLASS) {
1224 twl_id = TWL6030_CLASS_ID;
1225 twl_map = &twl6030_map[0];
1226 num_slaves = TWL_NUM_SLAVES - 1;
1227 } else {
1228 twl_id = TWL4030_CLASS_ID;
1229 twl_map = &twl4030_map[0];
1230 num_slaves = TWL_NUM_SLAVES;
1231 }
1232
1233 for (i = 0; i < num_slaves; i++) {
1219 struct twl_client *twl = &twl_modules[i]; 1234 struct twl_client *twl = &twl_modules[i];
1220 1235
1221 twl->address = client->addr + i; 1236 twl->address = client->addr + i;
@@ -1236,14 +1251,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1236 1251
1237 inuse = true; 1252 inuse = true;
1238 1253
1239 if ((id->driver_data) & TWL6030_CLASS) {
1240 twl_id = TWL6030_CLASS_ID;
1241 twl_map = &twl6030_map[0];
1242 } else {
1243 twl_id = TWL4030_CLASS_ID;
1244 twl_map = &twl4030_map[0];
1245 }
1246
1247 /* setup clock framework */ 1254 /* setup clock framework */
1248 clocks_init(&client->dev, pdata->clock); 1255 clocks_init(&client->dev, pdata->clock);
1249 1256