}
card->type = MMC_TYPE_SDIO;
+
+ /*
+ * Call the optional HC's init_card function to handle quirks.
+ */
+ if (host->ops->init_card)
+ host->ops->init_card(host, card);
+
/*
* For native busses: set card RCA and quit open drain mode.
{
unsigned mval = min(func->card->host->max_seg_size,
func->card->host->max_blk_size);
- mval = min(mval, func->max_blksize);
+
+ if (mmc_blksz_for_byte_mode(func->card))
+ mval = min(mval, func->cur_blksize);
+ else
+ mval = min(mval, func->max_blksize);
+
return min(mval, 512u); /* maximum size for byte mode */
}
#include <linux/irq.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
+#include <linux/mmc/card.h>
#include <mach/board.h>
#include <mach/rk29_iomap.h>
spin_unlock_irqrestore(&host->lock, flags);
}
+static void rk29_sdmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
+{
+ card->quirks = MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
+}
static const struct mmc_host_ops rk29_sdmmc_ops[] = {
{
.request = rk29_sdmmc_request,
.request = rk29_sdmmc_request,
.set_ios = rk29_sdmmc_set_ios,
.enable_sdio_irq = rk29_sdmmc_enable_sdio_irq,
+ .init_card = rk29_sdmmc_init_card,
},
};
#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
+#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
return c->quirks & MMC_QUIRK_LENIENT_FN0;
}
+static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
+{
+ return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+}
+
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev))
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
+
+ /* optional callback for HC quirks */
+ void (*init_card)(struct mmc_host *host, struct mmc_card *card);
};
struct mmc_card;