kishore kadiyala wrote:
Adding card detect callback function which gives the status of
the card .For MMC1 Controller, Card detect interrupt source is
twl6030 and card present/absent status is provided by MMCCTRL
register of twl6030.

Signed-off-by: Kishore Kadiyala <kishore.kadiy...@ti.com>
---
 arch/arm/mach-omap2/board-4430sdp.c   |   11 +++++--
 arch/arm/mach-omap2/hsmmc.c           |    1 +
 arch/arm/plat-omap/include/plat/mmc.h |    1 +
 drivers/mfd/twl6030-irq.c             |   23 ++++++++++++++++
 drivers/mmc/host/omap_hsmmc.c         |   30 ++++++++++++++++++---
 include/linux/i2c/twl.h               |   46 +++++++++++++++++++++++++++++++++
 6 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index e4a5d66..1cf6f3b 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -144,6 +144,7 @@ static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
                .wires          = 8,
+               .cd_type        = NON_GPIO,
                .gpio_wp        = -EINVAL,
        },
        {
@@ -174,10 +175,14 @@ static int omap4_twl6030_hsmmc_late_init(struct device 
*dev)
                                struct platform_device, dev);
        struct omap_mmc_platform_data *pdata = dev->platform_data;

-       /* Setting MMC1 Card detect Irq */
-       if (pdev->id == 0)
+       /* MMC1 Card detect Configuration */
+       if (pdev->id == 0) {
+               ret = omap4_hsmmc1_card_detect_config();
+               if (ret < 0)
+                       pr_err("Unable to configure Card detect for MMC1\n");
                pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
-                                               MMCDETECT_INTR_OFFSET;
+                                                       MMCDETECT_INTR_OFFSET;
+       }
        return ret;
 }

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 1ef54b0..8a8f7b1 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -265,6 +265,7 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info 
*controllers)
                mmc->get_context_loss_count = hsmmc_get_context_loss;

                mmc->slots[0].switch_pin = c->gpio_cd;
+               mmc->slots[0].cd_type = c->cd_type;
                mmc->slots[0].gpio_wp = c->gpio_wp;

                mmc->slots[0].remux = c->remux;
diff --git a/arch/arm/plat-omap/include/plat/mmc.h 
b/arch/arm/plat-omap/include/plat/mmc.h
index ed60c0f..cd42c77 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/device.h>
 #include <linux/mmc/host.h>
+#include <linux/i2c/twl.h>

 #include <plat/board.h>

diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index 10bf228..f17e4e7 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -223,6 +223,29 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset)
 }
 EXPORT_SYMBOL(twl6030_interrupt_mask);

+int twl6030_mmc_card_detect(int host_id, int slot)
+{
+       int ret = -ENOSYS;
+       u8 read_reg;
+
+       switch (host_id) {
+       case 0:
+               /*
+                * BIT0 of REG_MMC_CTRL
+                * 0 - Card not present ,1 - Card present
+                */
+               ret = twl_i2c_read_u8(TWL6030_MODULE_ID0,
+                                       &read_reg, TWL6030_MMCCTRL);
+               if (ret >= 0)
+                       ret = read_reg & STS_MMC;
+               break;
+       default:
+               pr_err("Unkown MMC controller %d in %s\n", host_id, __func__);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(twl6030_mmc_card_detect);
+
 int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 {

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b032828..5d5bd29 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c

As per my email 5/5/10, I would suggest the only change to omap_hsmmc is:

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e9caf69..f792cff 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -465,8 +465,6 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
       int ret;

       if (gpio_is_valid(pdata->slots[0].switch_pin)) {
-               pdata->suspend = omap_hsmmc_suspend_cdirq;
-               pdata->resume = omap_hsmmc_resume_cdirq;
               if (pdata->slots[0].cover)
                       pdata->slots[0].get_cover_state =
                                       omap_hsmmc_get_cover_state;
@@ -2160,6 +2158,8 @@ static int __init omap_hsmmc_probe(struct platform_device 
*pdev)
                               "Unable to grab MMC CD IRQ\n");
                       goto err_irq_cd;
               }
+               pdata->suspend = omap_hsmmc_suspend_cdirq;
+               pdata->resume = omap_hsmmc_resume_cdirq;
       }

       OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);


And that the late init function is used to do the rest e.g.
find a home for these 3 functions:

static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
        int ret = 0;
        struct platform_device *pdev = container_of(dev,
                                        struct platform_device, dev);
        struct omap_mmc_platform_data *pdata = dev->platform_data;

        /* MMC1 Card detect Configuration */
        if (pdev->id == 0) {
                ret = omap4_hsmmc1_card_detect_config();
                if (ret < 0)
                        pr_err("Unable to configure Card detect for MMC1\n");
                pdata->slots[0].card_detect = twl6030_mmc_card_detect;
                pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
                                                  MMCDETECT_INTR_OFFSET;
        }
        return ret;
}

static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
        struct omap_mmc_platform_data *pdata = dev->platform_data;

        pdata->init = omap4_twl6030_hsmmc_late_init;
}

void __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
        struct omap2_hsmmc_info *c;

        omap2_hsmmc_init(controllers);

        for (c = controllers; c->mmc; c++)
                omap4_twl6030_hsmmc_set_late_init(c->dev);
}




@@ -189,9 +189,16 @@ struct omap_hsmmc_host {
 static int omap_hsmmc_card_detect(struct device *dev, int slot)
 {
        struct omap_mmc_platform_data *mmc = dev->platform_data;
+       struct platform_device *pdev = container_of(dev,
+                               struct platform_device, dev);
+       int ret = -ENOSYS;

-       /* NOTE: assumes card detect signal is active-low */
-       return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+       if (mmc->slots[0].cd_type == GPIO)
+               /* NOTE: assumes card detect signal is active-low */
+               ret = !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+       else
+               ret = twl6030_mmc_card_detect(pdev->id, slot);
+       return ret;
 }

 static int omap_hsmmc_get_wp(struct device *dev, int slot)
@@ -464,8 +471,6 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
        int ret;

        if (gpio_is_valid(pdata->slots[0].switch_pin)) {
-               pdata->suspend = omap_hsmmc_suspend_cdirq;
-               pdata->resume = omap_hsmmc_resume_cdirq;
                if (pdata->slots[0].cover)
                        pdata->slots[0].get_cover_state =
                                        omap_hsmmc_get_cover_state;
@@ -504,6 +509,15 @@ err_free_sp:
        return ret;
 }

+static int omap_hsmmc_non_gpio_init(struct omap_mmc_platform_data *pdata)
+{
+       if (pdata->slots[0].switch_pin > 0) {
+               pdata->slots[0].card_detect = omap_hsmmc_card_detect;
+               pdata->slots[0].card_detect_irq = pdata->slots[0].switch_pin;
+       }
+       return 0;
+}
+
 static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
 {
        if (gpio_is_valid(pdata->slots[0].gpio_wp))
@@ -1988,7 +2002,11 @@ static int __init omap_hsmmc_probe(struct 
platform_device *pdev)
        if (res == NULL)
                return -EBUSY;

-       ret = omap_hsmmc_gpio_init(pdata);
+       if (pdata->slots[0].cd_type == GPIO)
+               ret = omap_hsmmc_gpio_init(pdata);
+       else
+               ret =  omap_hsmmc_non_gpio_init(pdata);
+
        if (ret)
                goto err;

@@ -2170,6 +2188,8 @@ static int __init omap_hsmmc_probe(struct platform_device 
*pdev)
                                "Unable to grab MMC CD IRQ\n");
                        goto err_irq_cd;
                }
+               pdata->suspend = omap_hsmmc_suspend_cdirq;
+               pdata->resume = omap_hsmmc_resume_cdirq;
        }

        omap_hsmmc_disable_irq(host);
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 6de90bf..38ef529 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -141,6 +141,14 @@
 #define TWL6030_CHARGER_CTRL_INT_MASK  0x10
 #define TWL6030_CHARGER_FAULT_INT_MASK         0x60

+#define TWL6030_MMCCTRL                        0xEE
+#define VMMC_AUTO_OFF                  (0x1 << 3)
+#define SW_FC                          (0x1 << 2)
+#define STS_MMC                                0x1
+
+#define TWL6030_CFG_INPUT_PUPD3                0xF2
+#define MMC_PU                         (0x1 << 3)
+#define MMC_PD                         (0x1 << 2)

 #define TWL4030_CLASS_ID               0x4030
 #define TWL6030_CLASS_ID               0x6030
@@ -173,6 +181,44 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned 
num_bytes);
 int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
 int twl6030_interrupt_mask(u8 bit_mask, u8 offset);

+/* MMC1 Controller on OMAP4 uses Phoenix Irq for Card detect */
+int twl6030_mmc_card_detect(int host_id, int slot);
+
+/* Configuring Card Detect for MMC1 */
+static inline int omap4_hsmmc1_card_detect_config(void)
+{
+       int res = -1;
+       u8 reg_val = 0;
+
+       /* Unmasking the Card detect Interrupt line for MMC1 from Phoenix */
+       if (twl_class_is_6030()) {
+               twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK,
+                                                       REG_INT_MSK_LINE_B);
+               twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK,
+                                                       REG_INT_MSK_STS_B);
+       }
+
+       /*
+        * Intially Configuring MMC_CTRL for receving interrupts &
+        * Card status on TWL6030 for MMC1
+        */
+       res = twl_i2c_read_u8(TWL6030_MODULE_ID0, &reg_val, TWL6030_MMCCTRL);
+       if (res < 0)
+               return res;
+       reg_val &= ~VMMC_AUTO_OFF;
+       reg_val |= SW_FC;
+       twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, TWL6030_MMCCTRL);
+
+        /* Configuring CFG_INPUT_PUPD3 */
+       res = twl_i2c_read_u8(TWL6030_MODULE_ID0, &reg_val,
+                                               TWL6030_CFG_INPUT_PUPD3);
+       if (res < 0)
+               return res;
+       reg_val &= ~(MMC_PU | MMC_PD);
+       twl_i2c_write_u8(TWL6030_MODULE_ID0, reg_val, TWL6030_CFG_INPUT_PUPD3);
+       return res;
+}
+
 /*----------------------------------------------------------------------*/

 /*

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to