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