diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2012-01-04 07:58:33 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-03-22 08:05:49 -0400 |
commit | 364cedb2f97063d649b2950c099883b89b60c000 (patch) | |
tree | 3cba9d57d17e681f94e27d821869545a9f3a6bc3 /drivers/mfd | |
parent | ec1a07b3440cc28946a77a974c21570bbef6ffa1 (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.c | 59 |
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 | ||
1157 | static int twl_remove(struct i2c_client *client) | 1159 | static 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 | ||