2 * linux/drivers/mmc/moxasd.c - Moxa CPU SD/MMC driver
4 * Copyright (C) 2005 Moxa Tech., All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #if 1 // add by Victor Yu. 02-09-2007
12 #include <linux/version.h>
14 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) // add by Victor Yu. 02-09-2007
15 #include <linux/config.h>
17 #include <asm/arch/cpe/cpe.h>
18 #include <asm/arch/cpe_int.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/ioport.h>
22 #include <linux/device.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
25 #include <linux/blkdev.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/mmc/host.h>
28 #include <linux/sched.h>
29 #include <linux/delay.h>
30 #include <linux/mmc/sd.h>
31 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) // add by Victor Yu. 03-07-2007
32 #include <linux/platform_device.h>
34 #include <linux/device.h>
35 #endif // LINUX_VERSION_CODE
40 #include <asm/sizes.h>
41 #include <asm/arch/gpio.h>
45 //#define MSD_SUPPORT_GET_CLOCK 1
47 #define MSD_RETRY_COUNT 1000
49 //#define CONFIG_MMC_DEBUG
50 #ifdef CONFIG_MMC_DEBUG
51 #define DBG(x...) printk(x)
61 #ifdef MSD_SUPPORT_GET_CLOCK
64 struct mmc_request *mrq;
65 struct mmc_data *data;
67 struct scatterlist *cur_sg; /* Current SG entry */
68 unsigned int num_sg; /* Number of entries left */
69 void *mapped_sg; /* vaddr of mapped sg */
70 unsigned int offset; /* Offset into current entry */
71 unsigned int remain; /* Data left in curren entry */
72 int size; /* Total size of transfer */
74 struct tasklet_struct card_change_tasklet;
75 struct tasklet_struct fifo_run_tasklet;
77 struct tasklet_struct data_end_tasklet;
78 struct tasklet_struct data_crc_tasklet;
79 struct tasklet_struct data_timeout_tasklet;
83 static inline void moxasd_init_sg(struct moxasd_host* host, struct mmc_data* data)
86 * Get info. about SG list from data structure.
89 host->cur_sg = data->sg;
90 host->num_sg = data->sg_len;
93 host->remain = host->cur_sg->length;
94 #if 1 // add by Victor Yu. 07-04-2007
95 if ( host->remain > host->size )
96 host->remain = host->size;
97 host->mapped_sg = NULL;
99 data->error = MMC_ERR_NONE;
102 static inline int moxasd_next_sg(struct moxasd_host* host)
105 * Skip to next SG entry.
114 if (host->num_sg > 0) {
116 host->remain = host->cur_sg->length;
122 static inline char *moxasd_kmap_sg(struct moxasd_host* host)
124 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
125 host->cur_sg->offset;
126 return host->mapped_sg;
129 static inline void moxasd_check_data_crc(struct moxasd_host *host, struct mmc_data *data)
133 status = readl(&host->reg->status);
135 if ( status & MSD_DATA_CRC_OK ) {
136 writel(MSD_CLR_DATA_CRC_OK, &host->reg->clear);
137 host->mrq->cmd->data->error=MMC_ERR_NONE;
139 else if ( status & MSD_DATA_CRC_FAIL ) {
140 writel(MSD_CLR_DATA_CRC_FAIL, &host->reg->clear);
141 //data->error = MMC_ERR_TIMEOUT;
142 host->mrq->cmd->data->error=MMC_ERR_BADCRC;
143 }else host->mrq->cmd->data->error=MMC_ERR_TIMEOUT;
144 /*if ( status & MSD_DATA_END ) {
145 writel(MSD_CLR_DATA_END, &host->reg->clear);
148 if ( status & MSD_DATA_TIMEOUT ) {
149 writel(MSD_DATA_TIMEOUT, &host->reg->clear);
150 host->mrq->cmd->data->error=MMC_ERR_TIMEOUT;
154 static inline int moxasd_check_fifo_ready(struct moxasd_host *host)
158 status = readl(&host->reg->status);
159 if ( status & MSD_CARD_DETECT ) { // card is removed
162 if ( status & (MSD_FIFO_URUN|MSD_FIFO_ORUN) ) {
163 writel(status&(MSD_FIFO_URUN|MSD_FIFO_ORUN), &host->reg->clear);
165 if ( status & MSD_DATA_TIMEOUT ) {
166 writel(MSD_CLR_DATA_TIMEOUT, &host->reg->clear);
172 static void moxasd_do_fifo(struct moxasd_host *host, struct mmc_data *data)
177 if ( host->size == data->bytes_xfered ) {
180 //buffer = moxasd_kmap_sg(host) + host->offset;
181 buffer = moxasd_kmap_sg(host);
182 if ( host->size > MSD_FIFO_LENB && host->dma ) {
183 apb_dma_conf_param param;
184 param.size = host->remain;
185 param.burst_mode = APB_DMAB_BURST_MODE;
186 param.data_width = APB_DMAB_DATA_WIDTH_4;
187 if ( data->flags & MMC_DATA_WRITE ) {
188 param.source_addr = (unsigned int)buffer;
189 param.dest_addr = (unsigned int)&host->reg->data_window;
190 param.dest_inc = APB_DMAB_DEST_INC_0;
191 param.source_inc = APB_DMAB_DEST_INC_4_16;
192 param.dest_sel = APB_DMAB_DEST_APB;
193 param.source_sel = APB_DMAB_SOURCE_AHB;
195 param.dest_addr = (unsigned int)buffer;
196 param.source_addr = (unsigned int)&host->reg->data_window;
197 param.source_inc = APB_DMAB_DEST_INC_0;
198 param.dest_inc = APB_DMAB_DEST_INC_4_16;
199 param.source_sel = APB_DMAB_DEST_APB;
200 param.dest_sel = APB_DMAB_SOURCE_AHB;
202 data->bytes_xfered += host->remain;
203 #if 0 // don't need to do this
204 host->offset = host->remain;
207 apb_dma_conf(host->dma, ¶m);
208 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
209 moxasd_next_sg(host);
210 apb_dma_enable(host->dma);
213 if ( host->remain >= MSD_FIFO_LENB )
214 wcnt = MSD_FIFO_LENW;
217 wcnt = host->remain >> 2;
218 if ( data->flags & MMC_DATA_WRITE ) {
219 for ( i=0; i<wcnt; i++, buffer+=4 )
220 writel(*(unsigned int *)buffer, &host->reg->data_window);
222 for ( i=0; i<wcnt; i++, buffer+=4 )
223 *(unsigned int *)buffer = readl(&host->reg->data_window);
226 host->offset += wcnt;
227 host->remain -= wcnt;
228 data->bytes_xfered += wcnt;
229 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
231 /* because this will be just one time
232 if ( host->remain <= 0 )
233 moxasd_next_sg(host);
238 static void moxasd_request_done(struct moxasd_host *host)
240 struct mmc_request *mrq=host->mrq;
247 mmc_request_done(host->mmc, mrq);
250 static void moxasd_prepare_data(struct moxasd_host *host, struct mmc_data *data)
252 unsigned int timeout, datactrl;
253 unsigned int blksz_bit=ffs(data->blksz) - 1;
256 moxasd_init_sg(host, data);
258 // initialize the timeout value
259 timeout = (host->mmc->f_max/1000000) * (data->timeout_ns/1000);
260 timeout += data->timeout_clks;
261 writel(timeout, &host->reg->data_timer);
263 // initialize the data size
264 //host->remain=host->size = data->blocks << data->blksz;//johnson
265 host->remain=host->size = data->blocks << blksz_bit;//johnson
266 writel(host->size, &host->reg->data_length);
268 // initialize the data control
269 //datactrl = (data->blksz & MSD_BLK_SIZE_MASK) | MSD_DATA_EN;
270 datactrl = (blksz_bit & MSD_BLK_SIZE_MASK) | MSD_DATA_EN;
272 if ( data->flags & MMC_DATA_WRITE ) {
273 datactrl |= MSD_DATA_WRITE;
275 if ( host->size > MSD_FIFO_LENB && host->dma ) {
276 datactrl |= MSD_DMA_EN;
278 writel(datactrl, &host->reg->data_control);
279 writel(4, &host->reg->argument);
280 //printk("DCR:%x data_length:%x data->blocks:%x host->remain:%x\n",host->reg->data_control,host->reg->data_length,data->blocks, host->remain);//johnson
283 //if ( host->size > MSD_FIFO_LENB && (data->flags & MMC_DATA_READ) ) {
284 if ( host->size > MSD_FIFO_LENB ) {
285 // disable the overrun & underrun interrupt
287 local_save_flags/*save_flags*/(flags);
288 local_irq_disable/*cli*/();
289 writel(MSD_INT_CARD_CHANGE|/*MSD_INT_DATA_CRC_OK|MSD_INT_DATA_CRC_FAIL*/MSD_INT_DATA_END|MSD_INT_DATA_TIMEOUT, &host->reg->interrupt_mask);
290 local_irq_restore/*restore_flags*/(flags);
291 moxasd_do_fifo(host, data);
293 // enable the overrun & underrun interrupt
295 local_save_flags/*save_flags*/(flags);
296 local_irq_disable/*cli*/();
297 writel(MSD_INT_FIFO_URUN|MSD_INT_FIFO_ORUN|MSD_INT_CARD_CHANGE, &host->reg->interrupt_mask);
298 local_irq_restore/*restore_flags*/(flags);
303 static void moxasd_send_command(struct moxasd_host *host, struct mmc_command *cmd)
305 unsigned int status, cmdctrl;
308 // first clear status
309 writel(MSD_CLR_RSP_TIMEOUT|MSD_CLR_RSP_CRC_OK|MSD_CLR_RSP_CRC_FAIL|MSD_CLR_CMD_SENT, &host->reg->clear);
312 writel(cmd->arg, &host->reg->argument);
315 cmdctrl = cmd->opcode & MSD_CMD_IDX_MASK;
316 if ( cmdctrl == SD_APP_SET_BUS_WIDTH ||
317 cmdctrl == SD_APP_OP_COND ||
318 cmdctrl == SD_APP_SEND_SCR ) // this is SD application specific command
319 cmdctrl |= MSD_APP_CMD;
321 if ( cmd->flags & /*MMC_RSP_LONG*/MMC_RSP_136 )
322 cmdctrl |= (MSD_LONG_RSP|MSD_NEED_RSP);
323 else if ( cmd->flags & /*MMC_RSP_SHORT*/MMC_RSP_PRESENT )
324 cmdctrl |= MSD_NEED_RSP;
326 //writel(cmd->flags, &host->reg->argument);
327 writel(cmdctrl|MSD_CMD_EN, &host->reg->command);
330 while ( retry++ < MSD_RETRY_COUNT ) {
331 status = readl(&host->reg->status);
332 if ( status & MSD_CARD_DETECT ) { // card is removed
333 cmd->error = MMC_ERR_TIMEOUT;
336 if ( cmdctrl & MSD_NEED_RSP ) {
337 if ( status & MSD_RSP_TIMEOUT ) {
338 writel(MSD_CLR_RSP_TIMEOUT, &host->reg->clear);
339 cmd->error = MMC_ERR_TIMEOUT;
343 if ( status & MSD_RSP_CRC_FAIL ) {
345 if ( (cmd->flags&MMC_RSP_CRC) && (status&MSD_RSP_CRC_FAIL) ) {
347 writel(MSD_CLR_RSP_CRC_FAIL, &host->reg->clear);
348 cmd->error = MMC_ERR_BADCRC;
351 if ( status & MSD_RSP_CRC_OK ) {
352 writel(MSD_CLR_RSP_CRC_OK, &host->reg->clear);
354 cmd->resp[0] = readl(&host->reg->response0);
355 cmd->resp[1] = readl(&host->reg->response1);
356 cmd->resp[2] = readl(&host->reg->response2);
357 cmd->resp[3] = readl(&host->reg->response3);
358 cmd->error = MMC_ERR_NONE;
362 if ( status & MSD_CMD_SENT ) {
363 writel(MSD_CLR_CMD_SENT, &host->reg->clear);
364 cmd->error = MMC_ERR_NONE;
369 // cmd->error = MMC_ERR_TIMEOUT;
370 cmd->error = MMC_ERR_NONE;
373 //static int moxasd_inited=0;
374 //static void moxasd_dma_irq(void *);
375 static irqreturn_t moxasd_irq(int irq, void *devid/*, struct pt_regs *regs*/)
377 struct moxasd_host *host=devid;
380 // get the interrupt status
382 status = readl(&host->reg->status);
384 // acknowledge the interurpt
385 if ( status & MSD_CARD_CHANGE ) { // has card inserted or removed
386 //writel(MSD_CLR_CARD_CHANGE, &host->reg->clear);
387 tasklet_schedule(&host->card_change_tasklet);
390 if ( status & (MSD_FIFO_ORUN|MSD_FIFO_URUN) ) {
391 writel(status&(MSD_FIFO_ORUN|MSD_FIFO_URUN), &host->reg->clear);
392 tasklet_schedule(&host->fifo_run_tasklet);
395 if(status & MSD_DATA_CRC_OK){//printk("MSD_DATA_CRC_OK\n");
396 writel(status&MSD_DATA_CRC_OK, &host->reg->clear);
397 tasklet_schedule(&host->data_end_tasklet);
401 /*if(status & (MSD_DATA_CRC_FAIL)){printk("MSD_DATA_CRC_FAIL\n");
402 writel(status&(MSD_DATA_CRC_FAIL|MSD_DATA_END), &host->reg->clear);
403 tasklet_schedule(&host->data_crc_tasklet);
407 if(status & MSD_DATA_END){//printk("MSD_DATA_END\n");
408 writel(status&(MSD_DATA_CRC_FAIL|MSD_DATA_END), &host->reg->clear);
409 tasklet_schedule(&host->data_end_tasklet);
412 if(status & MSD_DATA_TIMEOUT){printk("MSD_DATA_TIMEOUT\n");
413 writel(status&MSD_DATA_TIMEOUT, &host->reg->clear);
414 tasklet_schedule(&host->data_timeout_tasklet);
420 static void moxasd_fifo_run(unsigned long param)
422 struct moxasd_host *host=(struct moxasd_host *)param;
423 struct mmc_data *data;
426 if ( !moxasd_check_fifo_ready(host) && host->data ) {
427 host->size = host->data->bytes_xfered;
428 host->data->error = MMC_ERR_TIMEOUT;
429 if ( host->dma && host->size > MSD_FIFO_LENB ) {
430 apb_dma_disable(host->dma);
433 writel(readl(&host->reg->status)&(MSD_FIFO_URUN|MSD_FIFO_ORUN), &host->reg->clear);
436 spin_lock(&host->lock);
437 if ( host->mrq == NULL ) {
438 spin_unlock(&host->lock);
441 #if 0 // never happened
442 if ( host->data == NULL ) {
443 goto moxasd_fifo_run_done;
447 moxasd_do_fifo(host, data);
449 if ( host->size == data->bytes_xfered )
451 moxasd_request_done(host);
452 //tasklet_schedule(&host->data_end_tasklet);
455 if ( host->size == data->bytes_xfered ){
456 if(!(data->flags & MMC_DATA_WRITE) ){
457 //printk("fifo_run:moxasd_request_done\n");
458 moxasd_request_done(host);
462 if ( host->size == data->bytes_xfered ) {
464 // maybe need to check the data is OK or fail
465 if ( data->error == MMC_ERR_NONE ) {
466 moxasd_check_data_crc(host, data);
471 moxasd_send_command(host, data->stop);
475 spin_unlock(&host->lock);
476 //tasklet_schedule(&host->fifo_run_tasklet);
479 //moxasd_fifo_run_done:
480 moxasd_request_done(host);
482 spin_unlock(&host->lock);
485 static inline struct mmc_data *moxasd_get_data(struct moxasd_host *host)
491 if (!host->mrq->cmd->data)
493 return host->mrq->cmd->data;
496 static void moxasd_data_end(unsigned long param)
498 struct moxasd_host *host=(struct moxasd_host *)param;
499 struct mmc_data *data;
501 spin_lock(&host->lock);
503 data=moxasd_get_data(host);
506 //goto moxasd_request_done;
507 spin_unlock(&host->lock);
512 moxasd_send_command(host, data->stop);
515 //if ( host->size == data->bytes_xfered ){
516 if(!(host->data->flags & MMC_DATA_WRITE)){
517 spin_unlock(&host->lock);
522 //moxasd_request_done:
523 //printk("data_end:moxasd_request_done\n");
524 moxasd_request_done(host);
525 spin_unlock(&host->lock);
528 static void moxasd_data_crc(unsigned long param)
530 struct moxasd_host *host = (struct moxasd_host *)param;
531 struct mmc_data *data;
533 spin_lock(&host->lock);
538 data = moxasd_get_data(host);
542 data->error = MMC_ERR_BADCRC;
544 tasklet_schedule(&host->data_end_tasklet);
547 spin_unlock(&host->lock);
550 static void moxasd_data_timeout(unsigned long param)
552 struct moxasd_host *host = (struct moxasd_host *)param;
553 struct mmc_data *data;
555 spin_lock(&host->lock);
560 data = moxasd_get_data(host);
563 data->error = MMC_ERR_TIMEOUT;
564 tasklet_schedule(&host->data_end_tasklet);
567 spin_unlock(&host->lock);
570 static void moxasd_card_change(unsigned long param)
572 struct moxasd_host *host=(struct moxasd_host *)param;
576 spin_lock(&host->lock);
577 udelay(3000); // to wait the hardware stably for card inserted or removed
578 status = readl(&host->reg->status);
579 if ( status & MSD_CARD_DETECT ) { // card removed
580 printk("Moxa CPU SD/MMC card is removed.\n");
583 if ( host->dma && host->size > MSD_FIFO_LENB )
584 apb_dma_disable(host->dma);
585 host->size = host->data->bytes_xfered;
586 spin_unlock(&host->lock);
587 moxasd_fifo_run(*(unsigned long *)host);
588 spin_lock(&host->lock);
590 } else { // card inserted
591 printk("Moxa CPU SD/MMC card is inserted.\n");
592 if ( readl(&host->reg->clock_control) & MSD_CLK_SD ) { // SD
593 host->mmc->f_max = 25000000;
594 host->mmc->mode = MMC_MODE_SD;
596 host->mmc->f_max = 20000000;
597 host->mmc->mode = MMC_MODE_MMC;
601 writel(MSD_CLR_CARD_CHANGE, &host->reg->clear);
602 spin_unlock(&host->lock);
603 mmc_detect_change(host->mmc, msecs_to_jiffies(delay));
606 static void moxasd_dma_irq(void *param)
608 struct moxasd_host *host=(struct moxasd_host *)param;
610 if ( host->data ) {//printk("moxasd_dma_irq\n");
611 struct mmc_data *data=host->data;
612 if ( host->dma->error_flag ) {
613 host->size = data->bytes_xfered;
614 data->error = MMC_ERR_TIMEOUT;
617 tasklet_schedule(&host->fifo_run_tasklet);
622 static void moxasd_request(struct mmc_host *mmc, struct mmc_request *mrq)
624 struct moxasd_host *host=mmc_priv(mmc);
625 struct mmc_command *cmd;
627 spin_lock(&host->lock);
631 // if no card inserted, return timeout error
632 if ( readl(&host->reg->status) & MSD_CARD_DETECT ) { // card is removed
633 cmd->error = MMC_ERR_TIMEOUT;
637 // request include data or not
639 moxasd_prepare_data(host, cmd->data);
642 // do request command
643 moxasd_send_command(host, cmd);
645 if ( cmd->data && cmd->error == MMC_ERR_NONE ) {
646 spin_unlock(&host->lock);
652 moxasd_request_done(host);
653 spin_unlock(&host->lock);
656 #define MIN_POWER (/*MMC_VDD_360*/23 - MSD_SD_POWER_MASK)
657 static void moxasd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
659 struct moxasd_host *host=mmc_priv(mmc);
661 spin_lock(&host->lock);
664 #ifdef MSD_SUPPORT_GET_CLOCK
665 div = (host->sysclk / (host->mmc->f_max * 2)) - 1;
667 div = (APB_CLK / (host->mmc->f_max * 2)) - 1;
669 if ( div > MSD_CLK_DIV_MASK )
670 div = MSD_CLK_DIV_MASK;
673 if ( host->mmc->mode == MMC_MODE_SD )
675 writel(div, &host->reg->clock_control);
676 } else if ( !(readl(&host->reg->clock_control) & MSD_CLK_DIS) ) {
678 * Ensure that the clock is off.
680 writel(readl(&host->reg->clock_control)|MSD_CLK_DIS, &host->reg->clock_control);
683 if ( ios->power_mode == MMC_POWER_OFF ) {
684 writel(readl(&host->reg->power_control)&~MSD_SD_POWER_ON, &host->reg->power_control);
686 unsigned short power;
687 if ( ios->vdd < MIN_POWER )
690 power = ios->vdd - MIN_POWER;
691 writel(MSD_SD_POWER_ON|(unsigned int)power, &host->reg->power_control);
695 if ( ios->bus_width == MMC_BUS_WIDTH_1 ) {
696 writel(MSD_SINGLE_BUS, &host->reg->bus_width);
698 writel(MSD_WIDE_BUS, &host->reg->bus_width);
701 spin_unlock(&host->lock);
705 * To check write protect or not. Return 0 for none, 1 for write protect.
707 static int moxasd_get_ro(struct mmc_host *mmc)
709 struct moxasd_host *host=mmc_priv(mmc);
711 if ( readl(&host->reg->status) & MSD_WRITE_PROT )
717 static struct mmc_host_ops moxasd_ops = {
718 .request = moxasd_request,
719 .set_ios = moxasd_set_ios,
720 .get_ro = moxasd_get_ro,
723 //static int moxasd_probe(struct device *dev)
724 static int moxasd_probe(struct platform_device *pdev)
726 struct device *dev = &pdev->dev;
727 struct mmc_host *mmc;
728 struct moxasd_host *host=NULL;
731 mmc = mmc_alloc_host(sizeof(struct moxasd_host), dev);
737 mmc->ops = &moxasd_ops;
739 mmc->f_max = 25000000;
741 mmc->mode = MMC_MODE_SD;
743 mmc->ocr_avail = 0xffff00; // support 2.0v - 3.6v power
745 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
746 mmc->caps = MMC_CAP_4_BIT_DATA;
747 mmc->max_hw_segs = 128;
748 mmc->max_phys_segs = 128;
749 mmc->max_sectors = 128;
750 mmc->max_seg_size = mmc->max_sectors * 512;
752 host = mmc_priv(mmc);
754 spin_lock_init(&host->lock);
755 tasklet_init(&host->card_change_tasklet, moxasd_card_change, (unsigned long)host);
756 tasklet_init(&host->fifo_run_tasklet, moxasd_fifo_run, (unsigned long)host);
758 tasklet_init(&host->data_end_tasklet, moxasd_data_end, (unsigned long)host);
759 tasklet_init(&host->data_crc_tasklet, moxasd_data_crc, (unsigned long)host);
760 tasklet_init(&host->data_timeout_tasklet, moxasd_data_timeout, (unsigned long)host);
762 host->reg = (moxasd_reg *)CPE_SD_VA_BASE;
763 host->dma = apb_dma_alloc(APB_DMA_SD_REQ_NO);
766 apb_dma_set_irq(host->dma, moxasd_dma_irq, host);
769 #ifdef MSD_SUPPORT_GET_CLOCK
772 unsigned int mul, val, div;
773 mul = (*(volatile unsigned int *)(CPE_PMU_VA_BASE+0x30) >> 3) & 0x1ff;
774 val = (*(volatile unsigned int *)(CPE_PMU_VA_BASE+0x0c) >> 4) & 0x7;
776 case 0 : div = 2; break;
777 case 1 : div = 3; break;
778 case 2 : div = 4; break;
779 case 3 : div = 6; break;
780 case 4 : div = 8; break;
781 default : div = 2; break;
783 host->sysclk = (38684*mul + 10000) / (div * 10000);
784 host->sysclk = (host->sysclk * 1000000) / 2;
788 // change I/O multiplexing to SD, so the GPIO 17-10 will be fail
789 #if 0 // mask by Victor Yu. 03-06-2006
790 *(volatile unsigned int *)(CPE_PMU_VA_BASE+0x100) &= (~(0xff<<10));
791 #else // add by Victor Yu. 03-06-2006
792 mcpu_gpio_mp_clear(0xff<<10);
796 * Ensure that the host controller is shut down, and setup
799 writel(0, &host->reg->interrupt_mask); // disable all interrupt
800 writel(MSD_SDC_RST, &host->reg->command); // reset chip
801 while ( readl(&host->reg->command) & MSD_SDC_RST); // wait for reset finished
802 writel(0, &host->reg->interrupt_mask); // disable all interrupt
804 // to check any card inserted or not
806 if ( !(readl(&host->reg->status) & MSD_CARD_DETECT) ) { // is inserted
807 if ( readl(&host->reg->clock_control) & MSD_CLK_SD ) { // is SD card
808 mmc->f_max = 25000000;
809 mmc->mode = MMC_MODE_SD;
810 } else { // is MMC card
811 mmc->f_max = 20000000;
812 mmc->mode = MMC_MODE_MMC;
817 mmc->caps = MMC_CAP_4_BIT_DATA;
818 writel(MSD_WIDE_BUS, &host->reg->bus_width);
820 cpe_int_set_irq(IRQ_SD, EDGE, H_ACTIVE);
821 ret = request_irq(IRQ_SD, moxasd_irq, /*IRQF_SHARED*/SA_INTERRUPT, "moxart-sd"/*"MOXASD"*/, host);
825 //writel(MSD_INT_CARD_CHANGE|MSD_INT_FIFO_ORUN|MSD_INT_FIFO_URUN, &host->reg->interrupt_mask);
826 writel(MSD_INT_CARD_CHANGE, &host->reg->interrupt_mask);
827 dev_set_drvdata(dev, mmc);
839 static int moxasd_remove(struct platform_device *pdev)
841 struct device *dev = &pdev->dev;
842 struct mmc_host *mmc=dev_get_drvdata(dev);
844 dev_set_drvdata(dev, NULL);
847 struct moxasd_host *host=mmc_priv(mmc);
849 mmc_remove_host(mmc);
853 apb_dma_disable(host->dma);
854 apb_dma_release_irq(host->dma);
855 apb_dma_release(host->dma);
857 writel(0, &host->reg->interrupt_mask);
858 writel(0, &host->reg->power_control);
859 writel(readl(&host->reg->clock_control)|MSD_CLK_DIS, &host->reg->clock_control);
861 free_irq(IRQ_SD, host);
862 tasklet_kill(&host->card_change_tasklet);
863 tasklet_kill(&host->fifo_run_tasklet);
865 tasklet_kill(&host->data_end_tasklet);
866 tasklet_kill(&host->data_crc_tasklet);
867 tasklet_kill(&host->data_timeout_tasklet);
874 static struct platform_device moxasd_device = {
879 static struct device_driver moxasd_driver = {
881 .bus = &platform_bus_type,
882 .probe = moxasd_probe,
883 .remove = moxasd_remove,
886 static int __init moxasd_init(void)
890 printk("Moxa CPU SD/MMC Device Driver V1.0 initialize ");
891 platform_device_register(&moxasd_device);
892 ret = driver_register(&moxasd_driver);
895 platform_device_unregister(&moxasd_device);
902 static void __exit moxasd_exit(void)
904 platform_device_unregister(&moxasd_device);
905 driver_unregister(&moxasd_driver);
908 module_init(moxasd_init);
909 module_exit(moxasd_exit);
911 MODULE_DESCRIPTION("Moxa CPU SD/Multimedia Card Interface Driver");
912 MODULE_LICENSE("GPL");