diff options
| author | Pierre Ossman <drzeus@drzeus.cx> | 2005-09-03 11:45:49 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-09-03 11:45:49 -0400 |
| commit | 1656fa579e44691a860b095016eee910bc0b2793 (patch) | |
| tree | 4373e726038d317d3011adf0bf6ba4028a750cfa /drivers/mmc/wbsd.c | |
| parent | 865e9f13c94891daed4f6a5f69c5d6ec04d4932f (diff) | |
[MMC] support for mmc chip select in wbsd
Use the chip select ios in the wbsd driver.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/wbsd.c')
| -rw-r--r-- | drivers/mmc/wbsd.c | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 402c2d661fb2..08ae22aed9e8 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | #include "wbsd.h" | 42 | #include "wbsd.h" |
| 43 | 43 | ||
| 44 | #define DRIVER_NAME "wbsd" | 44 | #define DRIVER_NAME "wbsd" |
| 45 | #define DRIVER_VERSION "1.3" | 45 | #define DRIVER_VERSION "1.4" |
| 46 | 46 | ||
| 47 | #ifdef CONFIG_MMC_DEBUG | 47 | #ifdef CONFIG_MMC_DEBUG |
| 48 | #define DBG(x...) \ | 48 | #define DBG(x...) \ |
| @@ -960,8 +960,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 960 | struct wbsd_host* host = mmc_priv(mmc); | 960 | struct wbsd_host* host = mmc_priv(mmc); |
| 961 | u8 clk, setup, pwr; | 961 | u8 clk, setup, pwr; |
| 962 | 962 | ||
| 963 | DBGF("clock %uHz busmode %u powermode %u Vdd %u\n", | 963 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u\n", |
| 964 | ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); | 964 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, |
| 965 | ios->vdd); | ||
| 965 | 966 | ||
| 966 | spin_lock_bh(&host->lock); | 967 | spin_lock_bh(&host->lock); |
| 967 | 968 | ||
| @@ -1003,13 +1004,11 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 1003 | 1004 | ||
| 1004 | /* | 1005 | /* |
| 1005 | * MMC cards need to have pin 1 high during init. | 1006 | * MMC cards need to have pin 1 high during init. |
| 1006 | * Init time corresponds rather nicely with the bus mode. | ||
| 1007 | * It wreaks havoc with the card detection though so | 1007 | * It wreaks havoc with the card detection though so |
| 1008 | * that needs to be disabed. | 1008 | * that needs to be disabled. |
| 1009 | */ | 1009 | */ |
| 1010 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | 1010 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); |
| 1011 | if ((ios->power_mode == MMC_POWER_ON) && | 1011 | if (ios->chip_select == MMC_CS_HIGH) |
| 1012 | (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)) | ||
| 1013 | { | 1012 | { |
| 1014 | setup |= WBSD_DAT3_H; | 1013 | setup |= WBSD_DAT3_H; |
| 1015 | host->flags |= WBSD_FIGNORE_DETECT; | 1014 | host->flags |= WBSD_FIGNORE_DETECT; |
| @@ -1017,7 +1016,12 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 1017 | else | 1016 | else |
| 1018 | { | 1017 | { |
| 1019 | setup &= ~WBSD_DAT3_H; | 1018 | setup &= ~WBSD_DAT3_H; |
| 1020 | host->flags &= ~WBSD_FIGNORE_DETECT; | 1019 | |
| 1020 | /* | ||
| 1021 | * We cannot resume card detection immediatly | ||
| 1022 | * because of capacitance and delays in the chip. | ||
| 1023 | */ | ||
| 1024 | mod_timer(&host->ignore_timer, jiffies + HZ/100); | ||
| 1021 | } | 1025 | } |
| 1022 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 1026 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
| 1023 | 1027 | ||
| @@ -1036,6 +1040,31 @@ static struct mmc_host_ops wbsd_ops = { | |||
| 1036 | \*****************************************************************************/ | 1040 | \*****************************************************************************/ |
| 1037 | 1041 | ||
| 1038 | /* | 1042 | /* |
| 1043 | * Helper function to reset detection ignore | ||
| 1044 | */ | ||
| 1045 | |||
| 1046 | static void wbsd_reset_ignore(unsigned long data) | ||
| 1047 | { | ||
| 1048 | struct wbsd_host *host = (struct wbsd_host*)data; | ||
| 1049 | |||
| 1050 | BUG_ON(host == NULL); | ||
| 1051 | |||
| 1052 | DBG("Resetting card detection ignore\n"); | ||
| 1053 | |||
| 1054 | spin_lock_bh(&host->lock); | ||
| 1055 | |||
| 1056 | host->flags &= ~WBSD_FIGNORE_DETECT; | ||
| 1057 | |||
| 1058 | /* | ||
| 1059 | * Card status might have changed during the | ||
| 1060 | * blackout. | ||
| 1061 | */ | ||
| 1062 | tasklet_schedule(&host->card_tasklet); | ||
| 1063 | |||
| 1064 | spin_unlock_bh(&host->lock); | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | /* | ||
| 1039 | * Helper function for card detection | 1068 | * Helper function for card detection |
| 1040 | */ | 1069 | */ |
| 1041 | static void wbsd_detect_card(unsigned long data) | 1070 | static void wbsd_detect_card(unsigned long data) |
| @@ -1097,7 +1126,7 @@ static void wbsd_tasklet_card(unsigned long param) | |||
| 1097 | * Delay card detection to allow electrical connections | 1126 | * Delay card detection to allow electrical connections |
| 1098 | * to stabilise. | 1127 | * to stabilise. |
| 1099 | */ | 1128 | */ |
| 1100 | mod_timer(&host->timer, jiffies + HZ/2); | 1129 | mod_timer(&host->detect_timer, jiffies + HZ/2); |
| 1101 | } | 1130 | } |
| 1102 | 1131 | ||
| 1103 | spin_unlock(&host->lock); | 1132 | spin_unlock(&host->lock); |
| @@ -1124,6 +1153,8 @@ static void wbsd_tasklet_card(unsigned long param) | |||
| 1124 | 1153 | ||
| 1125 | mmc_detect_change(host->mmc); | 1154 | mmc_detect_change(host->mmc); |
| 1126 | } | 1155 | } |
| 1156 | else | ||
| 1157 | spin_unlock(&host->lock); | ||
| 1127 | } | 1158 | } |
| 1128 | 1159 | ||
| 1129 | static void wbsd_tasklet_fifo(unsigned long param) | 1160 | static void wbsd_tasklet_fifo(unsigned long param) |
| @@ -1328,11 +1359,15 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
| 1328 | spin_lock_init(&host->lock); | 1359 | spin_lock_init(&host->lock); |
| 1329 | 1360 | ||
| 1330 | /* | 1361 | /* |
| 1331 | * Set up detection timer | 1362 | * Set up timers |
| 1332 | */ | 1363 | */ |
| 1333 | init_timer(&host->timer); | 1364 | init_timer(&host->detect_timer); |
| 1334 | host->timer.data = (unsigned long)host; | 1365 | host->detect_timer.data = (unsigned long)host; |
| 1335 | host->timer.function = wbsd_detect_card; | 1366 | host->detect_timer.function = wbsd_detect_card; |
| 1367 | |||
| 1368 | init_timer(&host->ignore_timer); | ||
| 1369 | host->ignore_timer.data = (unsigned long)host; | ||
| 1370 | host->ignore_timer.function = wbsd_reset_ignore; | ||
| 1336 | 1371 | ||
| 1337 | /* | 1372 | /* |
| 1338 | * Maximum number of segments. Worst case is one sector per segment | 1373 | * Maximum number of segments. Worst case is one sector per segment |
| @@ -1370,7 +1405,8 @@ static void __devexit wbsd_free_mmc(struct device* dev) | |||
| 1370 | host = mmc_priv(mmc); | 1405 | host = mmc_priv(mmc); |
| 1371 | BUG_ON(host == NULL); | 1406 | BUG_ON(host == NULL); |
| 1372 | 1407 | ||
| 1373 | del_timer_sync(&host->timer); | 1408 | del_timer_sync(&host->ignore_timer); |
| 1409 | del_timer_sync(&host->detect_timer); | ||
| 1374 | 1410 | ||
| 1375 | mmc_free_host(mmc); | 1411 | mmc_free_host(mmc); |
| 1376 | 1412 | ||
