12 #include <linux/module.h>
14 #include <linux/kernel.h>
17 #include <linux/version.h>
29 struct wake_lock unifi_sdio_wake_lock;
46 static int card_is_powered = 1;
51 ConvertSdioToCsrSdioResult(
int r)
103 cmd.arg = write ? 0x80000000 : 0x00000000;
105 cmd.arg |= (write &&
out) ? 0x08000000 : 0x00000000;
106 cmd.arg |= addr << 9;
133 *out = (
cmd.resp[0] >> 8) & 0xFF;
136 *out =
cmd.resp[0] & 0xFF;
156 return ConvertSdioToCsrSdioResult(err);
174 return ConvertSdioToCsrSdioResult(err);
191 return ConvertSdioToCsrSdioResult(err);
197 return ConvertSdioToCsrSdioResult(err);
215 b1 = (data >> 8) & 0xFF;
219 return ConvertSdioToCsrSdioResult(err);
226 return ConvertSdioToCsrSdioResult(err);
241 #ifdef MMC_QUIRK_LENIENT_FN0
244 err = csr_io_rw_direct(func->
card, 0, 0, address, 0, data);
250 return ConvertSdioToCsrSdioResult(err);
263 #ifdef MMC_QUIRK_LENIENT_FN0
266 err = csr_io_rw_direct(func->
card, 1, 0, address, data,
NULL);
272 return ConvertSdioToCsrSdioResult(err);
291 return ConvertSdioToCsrSdioResult(err);
309 return ConvertSdioToCsrSdioResult(err);
317 csr_sdio_enable_hs(
struct mmc_card *card)
331 if (!card->
cccr.high_speed)
357 csr_sdio_disable_hs(
struct mmc_card *card)
365 if (!card->
cccr.high_speed)
412 u32 max_khz = maxFrequency/1000;
419 max_hz = 1000 * max_khz;
420 if (max_hz >
host->f_max) {
421 max_hz =
host->f_max;
424 if (max_hz > 25000000) {
425 err = csr_sdio_enable_hs(func->
card);
427 err = csr_sdio_disable_hs(func->
card);
430 printk(
KERN_ERR "SDIO warning: Failed to configure SDIO clock mode\n");
471 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
472 sdio_unblock_card_irq(func);
476 #ifdef MMC_QUIRK_LENIENT_FN0
486 return ConvertSdioToCsrSdioResult(err);
498 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
499 sdio_block_card_irq(func);
503 #ifdef MMC_QUIRK_LENIENT_FN0
513 return ConvertSdioToCsrSdioResult(err);
555 return ConvertSdioToCsrSdioResult(err);
589 return ConvertSdioToCsrSdioResult(err);
642 if (!card_is_powered) {
670 if (card_is_powered) {
674 printk(
KERN_INFO "SDIO: Skip power off; card is already powered off.\n");
685 if (blksz > func->
card->host->max_blk_size)
690 blksz =
min(blksz, 512
u);
697 ret = csr_io_rw_direct(func->
card, 1, 0,
700 if (ret && ret != -
ERANGE)
702 ret = csr_io_rw_direct(func->
card, 1, 0,
704 (blksz >> 8) & 0xff,
NULL);
736 r = sdio_set_block_size_ignore_first_error(func, blockSize);
746 return ConvertSdioToCsrSdioResult(r);
785 uf_glue_sdio_int_handler(
struct sdio_func *func)
796 #ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
803 #ifdef MMC_QUIRK_LENIENT_FN0
809 printk(
KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
814 if (sdio_func_drv && sdio_func_drv->
intr) {
816 func_dsr_callback = sdio_func_drv->
intr(sdio_ctx);
819 if (func_dsr_callback) {
820 func_dsr_callback(sdio_ctx);
896 struct uf_sdio_mmc_pm_notifier
905 static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
924 static struct uf_sdio_mmc_pm_notifier *
928 struct uf_sdio_mmc_pm_notifier *notifier_ctx =
kmalloc(
sizeof(
struct uf_sdio_mmc_pm_notifier),
GFP_KERNEL);
932 notifier_ctx->sdio_ctx = sdio_ctx;
933 notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
935 list_add(¬ifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
937 if (register_pm_notifier(¬ifier_ctx->pm_notifier)) {
948 struct uf_sdio_mmc_pm_notifier *notifier_ctx;
952 notifier_ctx =
list_entry(node,
struct uf_sdio_mmc_pm_notifier,
list);
955 if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
957 if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) {
962 notifier_ctx->sdio_ctx =
NULL;
988 struct uf_sdio_mmc_pm_notifier *notifier_ctx =
container_of(
this,
989 struct uf_sdio_mmc_pm_notifier,
999 if (sdio_func_drv && sdio_func_drv->
resume) {
1000 sdio_func_drv->
resume(notifier_ctx->sdio_ctx);
1007 if (sdio_func_drv && sdio_func_drv->
suspend) {
1008 sdio_func_drv->
suspend(notifier_ctx->sdio_ctx);
1031 uf_glue_sdio_probe(
struct sdio_func *func,
1043 card_is_powered = 1;
1046 instance = func->
card->host->index;
1047 printk(
"sdio bus_id: %16s - UniFi card 0x%X inserted\n",
1053 if (sdio_ctx ==
NULL) {
1064 sdio_ctx->
priv = (
void *)func;
1076 #ifdef MMC_QUIRK_LENIENT_FN0
1085 if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) ==
NULL) {
1092 if (sdio_func_drv && sdio_func_drv->
inserted) {
1100 #ifdef ANDROID_BUILD
1103 wake_lock(&unifi_sdio_wake_lock);
1125 uf_glue_sdio_remove(
struct sdio_func *func)
1139 if (sdio_func_drv && sdio_func_drv->
removed) {
1141 sdio_func_drv->
removed(sdio_ctx);
1146 uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
1184 uf_glue_sdio_suspend(
struct device *
dev)
1215 #ifdef ANDROID_BUILD
1217 wake_lock(&unifi_sdio_wake_lock);
1226 .
suspend = uf_glue_sdio_suspend,
1227 .resume = uf_glue_sdio_resume,
1230 #define UNIFI_PM_OPS (&unifi_pm_ops)
1234 #define UNIFI_PM_OPS NULL
1239 .probe = uf_glue_sdio_probe,
1240 .remove = uf_glue_sdio_remove,
1242 .id_table = unifi_ids,
1268 printk(
"UniFi: Using native Linux MMC driver for SDIO.\n");
1270 if (sdio_func_drv) {
1275 #ifdef ANDROID_BUILD
1276 wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND,
"unifi_sdio_work");
1285 sdio_func_drv = sdio_drv;
1289 INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
1295 printk(
KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r);
1296 return ConvertSdioToCsrSdioResult(r);
1309 #ifdef ANDROID_BUILD
1310 wake_lock_destroy(&unifi_sdio_wake_lock);
1314 sdio_func_drv =
NULL;