diff options
| -rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 7 | ||||
| -rw-r--r-- | drivers/mfd/twl6030-irq.c | 73 | ||||
| -rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 4 | ||||
| -rw-r--r-- | include/linux/i2c/twl.h | 31 |
4 files changed, 112 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 69a4ae971e41..df5a425a49d1 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
| @@ -269,9 +269,14 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev) | |||
| 269 | struct omap_mmc_platform_data *pdata = dev->platform_data; | 269 | struct omap_mmc_platform_data *pdata = dev->platform_data; |
| 270 | 270 | ||
| 271 | /* Setting MMC1 Card detect Irq */ | 271 | /* Setting MMC1 Card detect Irq */ |
| 272 | if (pdev->id == 0) | 272 | if (pdev->id == 0) { |
| 273 | ret = twl6030_mmc_card_detect_config(); | ||
| 274 | if (ret) | ||
| 275 | pr_err("Failed configuring MMC1 card detect\n"); | ||
| 273 | pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + | 276 | pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + |
| 274 | MMCDETECT_INTR_OFFSET; | 277 | MMCDETECT_INTR_OFFSET; |
| 278 | pdata->slots[0].card_detect = twl6030_mmc_card_detect; | ||
| 279 | } | ||
| 275 | return ret; | 280 | return ret; |
| 276 | } | 281 | } |
| 277 | 282 | ||
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 | ||
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); |
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 53089516c17a..c760991b354a 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h | |||
| @@ -141,6 +141,16 @@ | |||
| 141 | #define TWL6030_CHARGER_CTRL_INT_MASK 0x10 | 141 | #define TWL6030_CHARGER_CTRL_INT_MASK 0x10 |
| 142 | #define TWL6030_CHARGER_FAULT_INT_MASK 0x60 | 142 | #define TWL6030_CHARGER_FAULT_INT_MASK 0x60 |
| 143 | 143 | ||
| 144 | #define TWL6030_MMCCTRL 0xEE | ||
| 145 | #define VMMC_AUTO_OFF (0x1 << 3) | ||
| 146 | #define SW_FC (0x1 << 2) | ||
| 147 | #define STS_MMC 0x1 | ||
| 148 | |||
| 149 | #define TWL6030_CFG_INPUT_PUPD3 0xF2 | ||
| 150 | #define MMC_PU (0x1 << 3) | ||
| 151 | #define MMC_PD (0x1 << 2) | ||
| 152 | |||
| 153 | |||
| 144 | 154 | ||
| 145 | #define TWL4030_CLASS_ID 0x4030 | 155 | #define TWL4030_CLASS_ID 0x4030 |
| 146 | #define TWL6030_CLASS_ID 0x6030 | 156 | #define TWL6030_CLASS_ID 0x6030 |
| @@ -173,6 +183,27 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); | |||
| 173 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); | 183 | int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); |
| 174 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); | 184 | int twl6030_interrupt_mask(u8 bit_mask, u8 offset); |
| 175 | 185 | ||
| 186 | /* Card detect Configuration for MMC1 Controller on OMAP4 */ | ||
| 187 | #ifdef CONFIG_TWL4030_CORE | ||
| 188 | int twl6030_mmc_card_detect_config(void); | ||
| 189 | #else | ||
| 190 | static inline int twl6030_mmc_card_detect_config(void) | ||
| 191 | { | ||
| 192 | pr_debug("twl6030_mmc_card_detect_config not supported\n"); | ||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | #endif | ||
| 196 | |||
| 197 | /* MMC1 Controller on OMAP4 uses Phoenix irq for Card detect */ | ||
| 198 | #ifdef CONFIG_TWL4030_CORE | ||
| 199 | int twl6030_mmc_card_detect(struct device *dev, int slot); | ||
| 200 | #else | ||
| 201 | static inline int twl6030_mmc_card_detect(struct device *dev, int slot) | ||
| 202 | { | ||
| 203 | pr_debug("Call back twl6030_mmc_card_detect not supported\n"); | ||
| 204 | return -EIO; | ||
| 205 | } | ||
| 206 | #endif | ||
| 176 | /*----------------------------------------------------------------------*/ | 207 | /*----------------------------------------------------------------------*/ |
| 177 | 208 | ||
| 178 | /* | 209 | /* |
