aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorkishore kadiyala <kishore.kadiyala@ti.com>2010-09-24 13:13:20 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2010-10-28 18:29:59 -0400
commit72f2e2c763edc41f8eead042b6ff933acb0378e2 (patch)
treeb31ca0ae6be04e9191fdd99fa157c9ec4b4598a2 /drivers
parent8e00593557c3c5a7bc6f636412a1cadcf4624232 (diff)
mfd: Adding twl6030 mmc card detect support for MMC1
Adding card detect callback function and card detect configuration function for MMC1 Controller on OMAP4. Card detect configuration function does initial configuration of the MMC Control & PullUp-PullDown registers of Phoenix. For MMC1 Controller, card detect interrupt source is twl6030 which is non-gpio. The card detect call back function provides card present/absent status by reading MMC Control register present on twl6030. Since OMAP4 doesn't use any GPIO line as used in OMAP3 for card detect, the suspend/resume initialization which was done in omap_hsmmc_gpio_init previously is moved to the probe thus making it generic for both OMAP3 & OMAP4. Cc: Tony Lindgren <tony@atomide.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Madhusudhan Chikkature <madhu.cr@ti.com> Cc: Adrian Hunter <adrian.hunter@nokia.com> Signed-off-by: Kishore Kadiyala <kishore.kadiyala@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/twl6030-irq.c73
-rw-r--r--drivers/mmc/host/omap_hsmmc.c4
2 files changed, 75 insertions, 2 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}
224EXPORT_SYMBOL(twl6030_interrupt_mask); 225EXPORT_SYMBOL(twl6030_interrupt_mask);
225 226
227int 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, &reg_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, &reg_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}
272EXPORT_SYMBOL(twl6030_mmc_card_detect_config);
273
274int 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}
297EXPORT_SYMBOL(twl6030_mmc_card_detect);
298
226int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) 299int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
227{ 300{
228 301
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e865032a52eb..82a1079bbdc7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -483,8 +483,6 @@ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
483 int ret; 483 int ret;
484 484
485 if (gpio_is_valid(pdata->slots[0].switch_pin)) { 485 if (gpio_is_valid(pdata->slots[0].switch_pin)) {
486 pdata->suspend = omap_hsmmc_suspend_cdirq;
487 pdata->resume = omap_hsmmc_resume_cdirq;
488 if (pdata->slots[0].cover) 486 if (pdata->slots[0].cover)
489 pdata->slots[0].get_cover_state = 487 pdata->slots[0].get_cover_state =
490 omap_hsmmc_get_cover_state; 488 omap_hsmmc_get_cover_state;
@@ -2218,6 +2216,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
2218 "Unable to grab MMC CD IRQ\n"); 2216 "Unable to grab MMC CD IRQ\n");
2219 goto err_irq_cd; 2217 goto err_irq_cd;
2220 } 2218 }
2219 pdata->suspend = omap_hsmmc_suspend_cdirq;
2220 pdata->resume = omap_hsmmc_resume_cdirq;
2221 } 2221 }
2222 2222
2223 omap_hsmmc_disable_irq(host); 2223 omap_hsmmc_disable_irq(host);