#include "wbsd.h"
#define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.3"
+#define DRIVER_VERSION "1.4"
#ifdef CONFIG_MMC_DEBUG
#define DBG(x...) \
struct wbsd_host* host = mmc_priv(mmc);
u8 clk, setup, pwr;
- DBGF("clock %uHz busmode %u powermode %u Vdd %u\n",
- ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
+ DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u\n",
+ ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
+ ios->vdd);
spin_lock_bh(&host->lock);
/*
* MMC cards need to have pin 1 high during init.
- * Init time corresponds rather nicely with the bus mode.
* It wreaks havoc with the card detection though so
- * that needs to be disabed.
+ * that needs to be disabled.
*/
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
- if ((ios->power_mode == MMC_POWER_ON) &&
- (ios->bus_mode == MMC_BUSMODE_OPENDRAIN))
+ if (ios->chip_select == MMC_CS_HIGH)
{
setup |= WBSD_DAT3_H;
host->flags |= WBSD_FIGNORE_DETECT;
else
{
setup &= ~WBSD_DAT3_H;
- host->flags &= ~WBSD_FIGNORE_DETECT;
+
+ /*
+ * We cannot resume card detection immediatly
+ * because of capacitance and delays in the chip.
+ */
+ mod_timer(&host->ignore_timer, jiffies + HZ/100);
}
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
* *
\*****************************************************************************/
+/*
+ * Helper function to reset detection ignore
+ */
+
+static void wbsd_reset_ignore(unsigned long data)
+{
+ struct wbsd_host *host = (struct wbsd_host*)data;
+
+ BUG_ON(host == NULL);
+
+ DBG("Resetting card detection ignore\n");
+
+ spin_lock_bh(&host->lock);
+
+ host->flags &= ~WBSD_FIGNORE_DETECT;
+
+ /*
+ * Card status might have changed during the
+ * blackout.
+ */
+ tasklet_schedule(&host->card_tasklet);
+
+ spin_unlock_bh(&host->lock);
+}
+
/*
* Helper function for card detection
*/
* Delay card detection to allow electrical connections
* to stabilise.
*/
- mod_timer(&host->timer, jiffies + HZ/2);
+ mod_timer(&host->detect_timer, jiffies + HZ/2);
}
spin_unlock(&host->lock);
mmc_detect_change(host->mmc);
}
+ else
+ spin_unlock(&host->lock);
}
static void wbsd_tasklet_fifo(unsigned long param)
spin_lock_init(&host->lock);
/*
- * Set up detection timer
+ * Set up timers
*/
- init_timer(&host->timer);
- host->timer.data = (unsigned long)host;
- host->timer.function = wbsd_detect_card;
+ init_timer(&host->detect_timer);
+ host->detect_timer.data = (unsigned long)host;
+ host->detect_timer.function = wbsd_detect_card;
+
+ init_timer(&host->ignore_timer);
+ host->ignore_timer.data = (unsigned long)host;
+ host->ignore_timer.function = wbsd_reset_ignore;
/*
* Maximum number of segments. Worst case is one sector per segment
host = mmc_priv(mmc);
BUG_ON(host == NULL);
- del_timer_sync(&host->timer);
+ del_timer_sync(&host->ignore_timer);
+ del_timer_sync(&host->detect_timer);
mmc_free_host(mmc);