diff options
Diffstat (limited to 'drivers/mfd/twl6030-irq.c')
-rw-r--r-- | drivers/mfd/twl6030-irq.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 10bf228ad626..aaedb11d9d2c 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -36,6 +36,9 @@ | |||
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
38 | #include <linux/i2c/twl.h> | 38 | #include <linux/i2c/twl.h> |
39 | #include <linux/platform_device.h> | ||
40 | |||
41 | #include "twl-core.h" | ||
39 | 42 | ||
40 | /* | 43 | /* |
41 | * TWL6030 (unlike its predecessors, which had two level interrupt handling) | 44 | * TWL6030 (unlike its predecessors, which had two level interrupt handling) |
@@ -223,6 +226,78 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset) | |||
223 | } | 226 | } |
224 | EXPORT_SYMBOL(twl6030_interrupt_mask); | 227 | EXPORT_SYMBOL(twl6030_interrupt_mask); |
225 | 228 | ||
229 | int twl6030_mmc_card_detect_config(void) | ||
230 | { | ||
231 | int ret; | ||
232 | u8 reg_val = 0; | ||
233 | |||
234 | /* Unmasking the Card detect Interrupt line for MMC1 from Phoenix */ | ||
235 | twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, | ||
236 | REG_INT_MSK_LINE_B); | ||
237 | twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, | ||
238 | REG_INT_MSK_STS_B); | ||
239 | /* | ||
240 | * Intially Configuring MMC_CTRL for receving interrupts & | ||
241 | * Card status on TWL6030 for MMC1 | ||
242 | */ | ||
243 | ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, TWL6030_MMCCTRL); | ||
244 | if (ret < 0) { | ||
245 | pr_err("twl6030: Failed to read MMCCTRL, error %d\n", ret); | ||
246 | return ret; | ||
247 | } | ||
248 | reg_val &= ~VMMC_AUTO_OFF; | ||
249 | reg_val |= SW_FC; | ||
250 | ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, TWL6030_MMCCTRL); | ||
251 | if (ret < 0) { | ||
252 | pr_err("twl6030: Failed to write MMCCTRL, error %d\n", ret); | ||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | /* Configuring PullUp-PullDown register */ | ||
257 | ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, | ||
258 | TWL6030_CFG_INPUT_PUPD3); | ||
259 | if (ret < 0) { | ||
260 | pr_err("twl6030: Failed to read CFG_INPUT_PUPD3, error %d\n", | ||
261 | ret); | ||
262 | return ret; | ||
263 | } | ||
264 | reg_val &= ~(MMC_PU | MMC_PD); | ||
265 | ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, | ||
266 | TWL6030_CFG_INPUT_PUPD3); | ||
267 | if (ret < 0) { | ||
268 | pr_err("twl6030: Failed to write CFG_INPUT_PUPD3, error %d\n", | ||
269 | ret); | ||
270 | return ret; | ||
271 | } | ||
272 | return 0; | ||
273 | } | ||
274 | EXPORT_SYMBOL(twl6030_mmc_card_detect_config); | ||
275 | |||
276 | int twl6030_mmc_card_detect(struct device *dev, int slot) | ||
277 | { | ||
278 | int ret = -EIO; | ||
279 | u8 read_reg = 0; | ||
280 | struct platform_device *pdev = to_platform_device(dev); | ||
281 | |||
282 | if (pdev->id) { | ||
283 | /* TWL6030 provide's Card detect support for | ||
284 | * only MMC1 controller. | ||
285 | */ | ||
286 | pr_err("Unkown MMC controller %d in %s\n", pdev->id, __func__); | ||
287 | return ret; | ||
288 | } | ||
289 | /* | ||
290 | * BIT0 of MMC_CTRL on TWL6030 provides card status for MMC1 | ||
291 | * 0 - Card not present ,1 - Card present | ||
292 | */ | ||
293 | ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, &read_reg, | ||
294 | TWL6030_MMCCTRL); | ||
295 | if (ret >= 0) | ||
296 | ret = read_reg & STS_MMC; | ||
297 | return ret; | ||
298 | } | ||
299 | EXPORT_SYMBOL(twl6030_mmc_card_detect); | ||
300 | |||
226 | int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | 301 | int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) |
227 | { | 302 | { |
228 | 303 | ||