aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Fenkart <afenkart@gmail.com>2015-03-20 10:53:54 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2015-03-27 07:19:37 -0400
commitb7a5646fa5d5d319b2b1a3db07f615e40b184205 (patch)
tree07a70f02f9bc0de9441ff098c13618ee19f8b353
parent40433267331bc6b9d70d5cdd14bfa2c8e3e5f0ec (diff)
ARM: OMAP2: HSMMC: explicit fields to declare cover/card detect pin
board-rx51 has no card detect pin in the mmc slot, but can detect that the (cell-phone) cover has been removed and the card is accessible. The semantics between cover/card detect differ, the gpio on the slot informs you after the card has been removed, cover removal does not necessarily mean that the card has been removed. This means different code paths are necessary. To complete this we also want different fields in the platform data for cover and card detect. This separation is not pushed all the way down into struct omap2_hsmmc_info which is used to initialize the platform data. If we did that we had to go over all board files and set the new gpio_cod pin to -EINVAL. If we forget one board or some out-of-tree archicture forgets that the default '0' is used which is a valid pin number. Signed-off-by: Andreas Fenkart <afenkart@gmail.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--arch/arm/mach-omap2/hsmmc.c33
-rw-r--r--drivers/mmc/host/omap_hsmmc.c11
-rw-r--r--include/linux/platform_data/hsmmc-omap.h6
3 files changed, 33 insertions, 17 deletions
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index dc6e79c4484a..9a8611ab5dfa 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -150,9 +150,13 @@ static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
150static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data 150static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data
151 *mmc_controller, int controller_nr) 151 *mmc_controller, int controller_nr)
152{ 152{
153 if (gpio_is_valid(mmc_controller->switch_pin) && 153 if (gpio_is_valid(mmc_controller->gpio_cd) &&
154 (mmc_controller->switch_pin < OMAP_MAX_GPIO_LINES)) 154 (mmc_controller->gpio_cd < OMAP_MAX_GPIO_LINES))
155 omap_mux_init_gpio(mmc_controller->switch_pin, 155 omap_mux_init_gpio(mmc_controller->gpio_cd,
156 OMAP_PIN_INPUT_PULLUP);
157 if (gpio_is_valid(mmc_controller->gpio_cod) &&
158 (mmc_controller->gpio_cod < OMAP_MAX_GPIO_LINES))
159 omap_mux_init_gpio(mmc_controller->gpio_cod,
156 OMAP_PIN_INPUT_PULLUP); 160 OMAP_PIN_INPUT_PULLUP);
157 if (gpio_is_valid(mmc_controller->gpio_wp) && 161 if (gpio_is_valid(mmc_controller->gpio_wp) &&
158 (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES)) 162 (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES))
@@ -250,15 +254,20 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
250 mmc->internal_clock = !c->ext_clock; 254 mmc->internal_clock = !c->ext_clock;
251 mmc->reg_offset = 0; 255 mmc->reg_offset = 0;
252 256
253 mmc->switch_pin = c->gpio_cd; 257 if (c->cover_only) {
258 /* detect if mobile phone cover removed */
259 mmc->gpio_cd = -EINVAL;
260 mmc->gpio_cod = c->gpio_cd;
261 } else {
262 /* card detect pin on the mmc socket itself */
263 mmc->gpio_cd = c->gpio_cd;
264 mmc->gpio_cod = -EINVAL;
265 }
254 mmc->gpio_wp = c->gpio_wp; 266 mmc->gpio_wp = c->gpio_wp;
255 267
256 mmc->remux = c->remux; 268 mmc->remux = c->remux;
257 mmc->init_card = c->init_card; 269 mmc->init_card = c->init_card;
258 270
259 if (c->cover_only)
260 mmc->cover = 1;
261
262 if (c->nonremovable) 271 if (c->nonremovable)
263 mmc->nonremovable = 1; 272 mmc->nonremovable = 1;
264 273
@@ -358,7 +367,15 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
358 if (!mmc_pdata) 367 if (!mmc_pdata)
359 continue; 368 continue;
360 369
361 mmc_pdata->switch_pin = c->gpio_cd; 370 if (c->cover_only) {
371 /* detect if mobile phone cover removed */
372 mmc_pdata->gpio_cd = -EINVAL;
373 mmc_pdata->gpio_cod = c->gpio_cd;
374 } else {
375 /* card detect pin on the mmc socket itself */
376 mmc_pdata->gpio_cd = c->gpio_cd;
377 mmc_pdata->gpio_cod = -EINVAL;
378 }
362 mmc_pdata->gpio_wp = c->gpio_wp; 379 mmc_pdata->gpio_wp = c->gpio_wp;
363 380
364 res = omap_device_register(pdev); 381 res = omap_device_register(pdev);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 833143f81451..08d537797b13 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -427,15 +427,15 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
427{ 427{
428 int ret; 428 int ret;
429 429
430 if (pdata->cover && gpio_is_valid(pdata->switch_pin)) { 430 if (gpio_is_valid(pdata->gpio_cod)) {
431 ret = mmc_gpio_request_cd(mmc, pdata->switch_pin, 0); 431 ret = mmc_gpio_request_cd(mmc, pdata->gpio_cod, 0);
432 if (ret) 432 if (ret)
433 return ret; 433 return ret;
434 434
435 host->get_cover_state = omap_hsmmc_get_cover_state; 435 host->get_cover_state = omap_hsmmc_get_cover_state;
436 mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq); 436 mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq);
437 } else if (!pdata->cover && gpio_is_valid(pdata->switch_pin)) { 437 } else if (gpio_is_valid(pdata->gpio_cd)) {
438 ret = mmc_gpio_request_cd(mmc, pdata->switch_pin, 0); 438 ret = mmc_gpio_request_cd(mmc, pdata->gpio_cd, 0);
439 if (ret) 439 if (ret)
440 return ret; 440 return ret;
441 441
@@ -1920,7 +1920,8 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
1920 if (of_find_property(np, "ti,dual-volt", NULL)) 1920 if (of_find_property(np, "ti,dual-volt", NULL))
1921 pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; 1921 pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT;
1922 1922
1923 pdata->switch_pin = -EINVAL; 1923 pdata->gpio_cd = -EINVAL;
1924 pdata->gpio_cod = -EINVAL;
1924 pdata->gpio_wp = -EINVAL; 1925 pdata->gpio_wp = -EINVAL;
1925 1926
1926 if (of_find_property(np, "ti,non-removable", NULL)) { 1927 if (of_find_property(np, "ti,non-removable", NULL)) {
diff --git a/include/linux/platform_data/hsmmc-omap.h b/include/linux/platform_data/hsmmc-omap.h
index 67bbcf0785f6..8e981be2e2c2 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -55,9 +55,6 @@ struct omap_hsmmc_platform_data {
55 u32 caps; /* Used for the MMC driver on 2430 and later */ 55 u32 caps; /* Used for the MMC driver on 2430 and later */
56 u32 pm_caps; /* PM capabilities of the mmc */ 56 u32 pm_caps; /* PM capabilities of the mmc */
57 57
58 /* switch pin can be for card detect (default) or card cover */
59 unsigned cover:1;
60
61 /* use the internal clock */ 58 /* use the internal clock */
62 unsigned internal_clock:1; 59 unsigned internal_clock:1;
63 60
@@ -73,7 +70,8 @@ struct omap_hsmmc_platform_data {
73#define HSMMC_HAS_HSPE_SUPPORT (1 << 2) 70#define HSMMC_HAS_HSPE_SUPPORT (1 << 2)
74 unsigned features; 71 unsigned features;
75 72
76 int switch_pin; /* gpio (card detect) */ 73 int gpio_cd; /* gpio (card detect) */
74 int gpio_cod; /* gpio (cover detect) */
77 int gpio_wp; /* gpio (write protect) */ 75 int gpio_wp; /* gpio (write protect) */
78 76
79 int (*set_power)(struct device *dev, int power_on, int vdd); 77 int (*set_power)(struct device *dev, int power_on, int vdd);