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 | /* |