#include #include /* #include */ #include /* #include */ /* #include */ /* #include */ #include /* #include */ #include #include "davinci_sdiodrv.h" #include "sdiodrv.h" #include "sdio_protocol.h" #include "ssd_debug.h" #include #include #include #include #include #include #include #include #include #include #include /********************************************************************/ /* SDIO driver prototypes */ /********************************************************************/ static int ifx_sdio_gpio_configure (void); int ifx_sdio_set_ext_reset(int active); #define AMAZON_S_SDIO_VERSION "0.01" // MCLCMD GPIO 3 or 20 #define MCLCMD 20 // MCLCLK GPIO 0 or 19 #define MCLCLK 19 // MCLDATA0 GPIO 17 or 28 #define MCLDATA0 17 // MCLDATA1 GPIO 18 or 27 #define MCLDATA1 18 // MCLDATA2 GPIO 16 or 26 #define MCLDATA2 16 // MCLDATA3 GPIO 15 or 25 #define MCLDATA3 15 #define MCLRESET 13 #define MAX_PIN_PER_PORT 16 /* Every port has 16 pins, up to 4 ports from 0~3 */ #define PIN2PORT(pin) ((((pin) >> 4) & 0x3)) #define PIN2PORTPIN(pin) ((pin) % (MAX_PIN_PER_PORT)) #define IFX_SD_PIN_RESERVE(pin) \ bsp_port_reserve_pin((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_DIR_OUT(pin) \ bsp_port_set_dir_out((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_DIR_IN(pin) \ bsp_port_set_dir_in((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_OUTPUT_SET(pin) \ bsp_port_set_output((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_OUTPUT_CLR(pin) \ bsp_port_clear_output((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_ALTSEL0_SET(pin) \ bsp_port_set_altsel0((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_ALTSEL0_CLR(pin) \ bsp_port_clear_altsel0((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_OD_SET(pin) \ bsp_port_set_open_drain((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_OD_CLR(pin) \ bsp_port_clear_open_drain((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_ALTSEL1_SET(pin) \ bsp_port_set_altsel1((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_ALTSEL1_CLR(pin) \ bsp_port_clear_altsel1((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_PUDSEL_SET(pin) \ bsp_port_set_pudsel((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) #define IFX_SD_PUDEN_SET(pin) \ bsp_port_set_puden((PIN2PORT(pin)), (PIN2PORTPIN(pin)), (PORT_MODULE_SDIO)) /* #define AMAZON_S_SDIO_DEBUG */ #undef AMAZON_S_SDIO_DEBUG #undef AMAZON_S_SDIO_DMSG #ifdef AMAZON_S_SDIO_DEBUG #define AMAZON_S_SDIO_DMSG(fmt, args...) printk( KERN_INFO "%s: " fmt,__FUNCTION__, ## args) #else #define AMAZON_S_SDIO_DMSG(fmt, args...) #endif #define AMAZON_S_SDIO_EMSG(fmt, args...) printk( KERN_ERR "%s: " fmt,__FUNCTION__, ## args) #define AMAZON_S_SD_CONTROLLER_WRITEL(data,addr) do{ *((volatile u32*)(addr)) = (u32)(data); asm("SYNC");} while (0) #define AMAZON_S_SD_CONTROLLER_READL(addr) (*((volatile u32*)(addr))) /*ABsync is defined in kernel MV baseline 1 ABSYNC defnition changed in kernel MV baseline 2*/ /* #if defined(TI_KERNEL_BASELINE2) */ /* #define ABsync ABSYNC */ /* #endif */ /********************************************************************/ /* SDIO driver parameters and structures */ /********************************************************************/ /* static edmacc_paramentry_regs temp_tx1, temp_tx2; */ /* static edmacc_paramentry_regs temp_rx1, temp_rx2; */ /* static volatile edmacc_regs *ptr_edmacc_regs = ((edmacc_regs *) IO_ADDRESS(DAVINCI_DMA_3PCC_BASE)); */ /* /\*Yanir: just a thought: all these globals should be grouped together to a "controller" structure..*\/ */ /* struct mmc_davinci_host *host; */ /* struct IO_request g_request; */ /* volatile mmcsd_regs *mmcsdregs; */ /* struct clk *mmcclkp = NULL; */ static unsigned char cardstate = 1; /* static unsigned char iscardinitialized = 0; */ /* /\* stores the link channel (PaRAM entries that are linked to the TX/RX channels) *\/ */ /* int TX_link_channel; */ /* int RX_link_channel; */ /* unsigned long achieved_clock_rate; */ /* static unsigned long reg_mmctor_val; */ /* #ifdef SSD_DEBUG */ /* /\*for debugging purposes - some memory overrun in ssd_testdrv (not solved yet) *\/ */ /* extern void* debugcallback; */ /* /\* used by the debug code to disable UDP logging from interrupt context. *\/ */ /* int interrupt_context = 0; */ /* #endif */ /********************************************************************/ /* SDIO driver interrupt handling */ /********************************************************************/ #ifdef SSD_DEBUG void debug_print_status_mask(u16 status) { char str[200]; sprintf(str,"debug_print_status_mask: HW status: "); if(status & MMCSD_EVENT_WRITE) strcat(str, "MMCSD_EVENT_WRITE "); if(status & MMCSD_EVENT_READ) strcat(str, "MMCSD_EVENT_READ "); if(status & MMCSD_EVENT_BLOCK_XFERRED) strcat(str, "MMCSD_EVENT_BLOCK_XFERRED "); if(status & MMCSD_EVENT_ERROR_DATATIMEOUT) strcat(str, "MMCSD_EVENT_ERROR_DATATIMEOUT "); if(status & MMCSD_EVENT_ERROR_DATACRC) strcat(str, "MMCSD_EVENT_ERROR_DATACRC "); if(status & MMCSD_EVENT_ERROR_CMDTIMEOUT) strcat(str, "MMCSD_EVENT_ERROR_CMDTIMEOUT "); if(status & MMCSD_EVENT_ERROR_CMDCRC) strcat(str, "MMCSD_EVENT_ERROR_CMDCRC "); if(status & MMCSD_EVENT_EOFCMD) strcat(str, "MMCSD_EVENT_EOFCMD "); if(!status) strcat(str,"0"); strcat(str,"\n"); PDEBUG(str); } static inline void debug_print_req(void) { /* PDEBUG("request print:\n"); */ /* PDEBUG("direction: %d\n",g_request.direction); */ /* PDEBUG("channel: %d\n",g_request.channel); */ /* PDEBUG("callback: 0x%p\n",g_request.callback); */ /* PDEBUG("context: 0x%p\n",g_request.context); */ } static inline void error_print_req(void) { } #else #define debug_print_status_mask(status) #define debug_print_req() #define error_print_req() #endif static u32 report_error( u32 status ) { u32 ret = 0; printk("%s(): error - 0x%8.8x\n",__FUNCTION__,status); error_print_req(); if (status & MCI_STAT_DTO) { printk("data timeout\n"); ret |= MMC_ERR_TIMEOUT; /* cardstate = 0; */ } if (status & MCI_STAT_DCF) { printk("data crc\n"); ret |= MMC_ERR_BADCRC; } if (status & MCI_STAT_CTO) { printk("cmd timeout\n"); ret |= MMC_ERR_TIMEOUT; } if (status & MCI_STAT_CCF) { printk("cmd crc\n"); ret |= MMC_ERR_BADCRC; } return ret; } void davinci_sdio_irq(int irq, void *dev_id, struct pt_regs *regs) { /* u16 status; */ /* int end_transfer = SDIO_ERR_EOT; */ /* int error = 0; */ /* CL_TRACE_START_L2(); */ /* #ifdef SSD_DEBUG */ /* interrupt_context = 1; */ /* #endif */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* /\* Read the interrupt status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* if (status == 0){ */ /* return IRQ_HANDLED; */ /* #ifdef SSD_DEBUG */ /* interrupt_context = 0; */ /* #endif */ /* } */ /* /\* Loop until all events are processed *\/ */ /* while (status != 0) */ /* { */ /* PINFO("davinci_sdio_irq: status: 0x%8.8x\n",status); */ /* debug_print_status_mask(status); */ /* if (status & MMCSD_EVENT_BLOCK_XFERRED) /\* Block sent/received *\/ */ /* end_transfer = 0; */ /* if(status & MMCSD_EVENT_ERROR) */ /* error = -report_error ( status ); */ /* /\* this is where we read the new status. *\/ */ /* status = mmcsdregs->mmcst0; */ /* } */ /* if (g_request.direction == read) */ /* { */ /* volatile int z = 10; */ /* /\* wait for the fifo to be empty *\/ */ /* while ((!(mmcsdregs->mmcst1 & 0x20) || (mmcsdregs->mmcst1 & 0x8)) && --z) */ /* ; */ /* if (z==0) */ /* error = -report_error ( status ); */ /* consistent_sync(g_request.DataBufferPointer,g_request.l1_cache_aligned_datalen,DMA_FROM_DEVICE); */ /* } */ /* davinci_stop_dma(g_request.channel); // ziv: please recheck this remark */ /* /\* if a transfer is completed, call the transfer completion function *\/ */ /* #ifdef SSD_DEBUG */ /* if(g_request.callback &&(debugcallback != g_request.callback)) */ /* { */ /* PERR("ERROR IN INTERRUPT HANDLER: callback corrupted %p,%p\n",g_request.callback,debugcallback); */ /* interrupt_context = 0; */ /* return IRQ_HANDLED; */ /* } */ /* #endif */ /* if(g_request.callback) */ /* g_request.callback(g_request.context, error | end_transfer); */ /* PDEBUG("exiting %s\n",__FUNCTION__); */ /* #ifdef SSD_DEBUG */ /* interrupt_context = 0; */ /* #endif */ /* CL_TRACE_END_L2("ssd.ko", "ISR", "SDIO_DRV_ASYNC", ""); */ /* return IRQ_HANDLED; */ } /********************************************************************/ /* SDIO driver internal functions */ /********************************************************************/ int sdio_davinci_start_dma_transfer(void *DataBufferPointer, int datalen, IO_direction direction) { /* int remainder; */ /* char* ptr; */ /* unsigned int num_eight_words = (datalen) / RW_THRESHOLD; */ /* CL_TRACE_START_L5(); */ /* if(num_eight_words < 2){ */ /* PERR("error - dma cannot be used on such small buffers.exiting %s\n", __FUNCTION__); */ /* return -1; */ /* } */ /* if(!(datalen%RW_THRESHOLD)) */ /* { */ /* num_eight_words--; */ /* remainder = RW_THRESHOLD; */ /* }else */ /* { */ /* remainder = (datalen%RW_THRESHOLD); */ /* } */ /* ptr = DataBufferPointer + (RW_THRESHOLD*num_eight_words); */ /* g_request.DataBufferPointer = DataBufferPointer; */ /* g_request.l1_cache_aligned_datalen = L1_CACHE_ALIGN(datalen); */ /* if (direction == write) */ /* { */ /* g_request.channel = DAVINCI_DMA_MMCTXEVT; */ /* // due to edma bug in driver (replace davinci_stop_dma(g_request.channel)) */ /* ptr_edmacc_regs->shadow[0].ecr |= (1 << DAVINCI_DMA_MMCTXEVT); */ /* consistent_sync(DataBufferPointer,g_request.l1_cache_aligned_datalen,DMA_TO_DEVICE); */ /* temp_tx1.src = (unsigned int)virt_to_phys(DataBufferPointer); */ /* temp_tx1.ccnt = num_eight_words; */ /* davinci_set_dma_params(DAVINCI_DMA_MMCTXEVT, &temp_tx1); */ /* temp_tx2.src = (unsigned int)virt_to_phys(ptr); */ /* temp_tx2.src_dst_cidx &= 0xffff0000; */ /* temp_tx2.src_dst_cidx |= remainder; */ /* temp_tx2.a_b_cnt = (remainder << 16) | 1; */ /* davinci_set_dma_params(TX_link_channel, &temp_tx2); */ /* davinci_start_dma(DAVINCI_DMA_MMCTXEVT); */ /* } */ /* else /\* read *\/ */ /* { */ /* g_request.channel = DAVINCI_DMA_MMCRXEVT; */ /* // due to edma bug in driver (replace davinci_stop_dma(g_request.channel)) */ /* ptr_edmacc_regs->shadow[0].ecr |= (1 << DAVINCI_DMA_MMCRXEVT); */ /* consistent_sync(DataBufferPointer,g_request.l1_cache_aligned_datalen,DMA_FROM_DEVICE); */ /* temp_rx1.dst = (unsigned int)virt_to_phys(DataBufferPointer); */ /* temp_rx1.ccnt = num_eight_words; */ /* davinci_set_dma_params(DAVINCI_DMA_MMCRXEVT, &temp_rx1); */ /* temp_rx2.dst = (unsigned int)virt_to_phys(ptr); */ /* temp_rx2.src_dst_cidx &= 0x0000ffff; */ /* temp_rx2.src_dst_cidx |= ((unsigned long)remainder << 16); */ /* temp_rx2.a_b_cnt = (remainder << 16) | 1; */ /* davinci_set_dma_params(RX_link_channel, &temp_rx2); */ /* davinci_start_dma(DAVINCI_DMA_MMCRXEVT); */ /* } */ /* PDEBUG("exiting %s\n",__FUNCTION__); */ /* CL_TRACE_END_L5("ssd.ko", "INHERIT", "SDIO_DRV_ASYNC", ""); */ return SDIO_SUCCESS; } int sdio_davinci_init_dma( void ) { /* unsigned int result; */ /* int edmach = 0; */ /* int tcc = 0; */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* /\* Alocate a DMA channel for transmit *\/ */ /* result = davinci_request_dma(DAVINCI_DMA_MMCTXEVT, "SDIO_WRITE", NULL, host, &edmach, &tcc, EVENTQ_0); */ /* if (result != 0) { */ /* PERR ("SDIO: %s() failed with %d. exiting\n",__FUNCTION__, result); */ /* return result; */ /* } */ /* /\* allocate a dma channel that is linked to the TX default channel *\/ */ /* result = davinci_request_dma(DAVINCI_EDMA_PARAM_ANY, "SDIO_WRITE", NULL, host, &TX_link_channel, &tcc, EVENTQ_0); */ /* if (result != 0) { */ /* PERR ("SDIO: %s() failed with %d\n",__FUNCTION__, result); */ /* return result; */ /* } */ /* /\* link the channels *\/ */ /* davinci_dma_link_lch(DAVINCI_DMA_MMCTXEVT, TX_link_channel); */ /* /\* Alocate a DMA channel for receive *\/ */ /* result = davinci_request_dma(DAVINCI_DMA_MMCRXEVT, "SDIO_READ", NULL, host, &edmach, &tcc, EVENTQ_0); */ /* if (result != 0) { */ /* PERR ("SDIO: %s() failed with %d\n",__FUNCTION__, result); */ /* return result; */ /* } */ /* /\* allocate a dma channel that is linked to the RX default channel *\/ */ /* result = davinci_request_dma(DAVINCI_EDMA_PARAM_ANY, "SDIO_READ", NULL, host, &RX_link_channel, &tcc, EVENTQ_0); */ /* if (result != 0) { */ /* PERR ("SDIO: %s() failed with %d\n",__FUNCTION__, result); */ /* return result; */ /* } */ /* /\* link the channels *\/ */ /* davinci_dma_link_lch(DAVINCI_DMA_MMCRXEVT, RX_link_channel); */ /* PDEBUG("exiting %s\n",__FUNCTION__); */ return SDIO_SUCCESS; } /********************************************************************/ /* SDIO driver interface functions */ /********************************************************************/ int sdiodrv_init(struct sdio_init_params* param) { uint32_t sdio_id = 0; /* ifx_sd_controller_priv_t *priv; */ printk ("Danube_sdio_controller for WLAN Version:%s\n", AMAZON_S_SDIO_VERSION); sdio_id = AMAZON_S_SD_CONTROLLER_READL (SDIO_ID); if (sdio_id != 0xF041C030) { SDIOERRMSG ("Danube SDIO Controller not found!!\n"); return -ENODEV; } // power on SDIO module SDIO_PMU_SETUP(PMU_ENABLE); // reset sdio //*(AMAZON_S_RCU_RST_REQ) |= (AMAZON_S_RCU_RST_REQ_SDIO); ifx_sdio_gpio_configure (); AMAZON_S_SD_CONTROLLER_WRITEL (0x400, SDIO_CLC); // 100MHz / 4 = 25MHz /* priv->mclk_speed = 25000000; //25 MHz */ ifx_sd_controller_set_ops (SD_SET_FREQENCY, 0); mdelay (1); ifx_sd_controller_set_ops (SD_SET_FREQENCY, 25000000); /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 12500000); */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 8000000); */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 4000000); */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 2000000); */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 1000000); */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 800000); */ /* ok */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, SD_CLK_400K); /\* ok *\/ */ /* ifx_sd_controller_set_ops (SD_SET_FREQENCY, 200000); */ AMAZON_S_SD_CONTROLLER_WRITEL (MCI_PWR_ON, MCI_PWR); // Power On mode AMAZON_S_SD_CONTROLLER_WRITEL (0x7FF, MCI_CL); /* clear pending interrupts */ AMAZON_S_SD_CONTROLLER_WRITEL (SDIO_IMC_SDIO | SDIO_IMC_INTR0, SDIO_ICR); // disable MMC interrupt AMAZON_S_SD_CONTROLLER_WRITEL (0, MCI_IM0); AMAZON_S_SD_CONTROLLER_WRITEL (SDIO_IMC_INTR0, SDIO_IMC); // enable SDIO AMAZON_S_SD_CONTROLLER_WRITEL (SDIO_CTRL_SDIOEN, SDIO_CTRL); PDEBUG("exiting %s\n",__FUNCTION__); return 0; } void sdiodrv_shutdown(void) { PDEBUG("entering %s()\n" , __FUNCTION__ ); PDEBUG("disable the SDIO clock\n"); PDEBUG("exiting %s\n",__FUNCTION__); return; } int sdiodrv_execute_cmd(unsigned long opcode, unsigned long CmdArg, int ReplyType, int BusWidth, void *DataBufferPointer, int datalen, int BlockSize, unsigned int timeout_clks) { printk("opcode=%d, CmdArg=%d, ReplyType=%d, BusWidth=%d, DataBufferPointer=%p, datalen=%d, BlockSize=%d, timeout_clks=%d\n", (unsigned int)opcode, (unsigned int)CmdArg, ReplyType, BusWidth, DataBufferPointer, datalen, BlockSize, timeout_clks); uint32_t sd_cmd = 0; uint32_t reg = 0; uint32_t status = 0; uint32_t response = 0; int ret = 0; int end_command = 0; AMAZON_S_SD_CONTROLLER_WRITEL (CmdArg, MCI_ARG); sd_cmd = opcode; switch (ReplyType) { case SD_RSP_R1: case SD_RSP_R1b: case SD_RSP_R3: case SD_RSP_R4: case SD_RSP_R5: case SD_RSP_R6: sd_cmd |= MCI_CMD_SHORT_RSP; /* AMAZON_S_SD_CONTROLLER_WRITEL (AMAZON_S_SD_CONTROLLER_READL */ /* (MCI_IM0) | MCI_IM_CRE | */ /* MCI_IM_CTO | MCI_IM_CCF, */ /* MCI_IM0); */ break; case SD_RSP_R2: sd_cmd |= MCI_CMD_LONG_RSP; /* AMAZON_S_SD_CONTROLLER_WRITEL (AMAZON_S_SD_CONTROLLER_READL */ /* (MCI_IM0) | MCI_IM_CRE | */ /* MCI_IM_CTO | MCI_IM_CCF, */ /* MCI_IM0); */ break; default: /* AMAZON_S_SD_CONTROLLER_WRITEL (AMAZON_S_SD_CONTROLLER_READL */ /* (MCI_IM0) | MCI_IM_CS, MCI_IM0); */ break; } /* pDev->cmd = pCmd; */ /* pDev->cmd->error = OK; */ sd_cmd |= MCI_CMD_EN; /* clear current status bits */ AMAZON_S_SD_CONTROLLER_WRITEL(0x3ff, MCI_CL); /* start transaction */ AMAZON_S_SD_CONTROLLER_WRITEL (sd_cmd, MCI_CMD); /* Wait for end of write transfer */ while(!end_command) { status = AMAZON_S_SD_CONTROLLER_READL(MCI_STAT); if (status & (MCI_STAT_CS | MCI_STAT_CRE)) { PDEBUG("changing end_command to 1\n"); end_command = TRUE; } if(status & (MCI_STAT_CTO | MCI_STAT_CCF)) { ret = report_error(status); end_command = TRUE; } } if(datalen) { response = AMAZON_S_SD_CONTROLLER_READL(MCI_REP0); memcpy(DataBufferPointer,(char*)(&response),datalen<4?datalen:4); } PDEBUG("exiting %s\n",__FUNCTION__); /* uint32_t start_jiffies = jiffies; */ /* do { */ /* ret = ifx_sd_controller_handle_cmd_int(pDev); */ /* } while (ret == 0); */ /* printk("int_poll took %d jiffies\n", jiffies - start_jiffies); */ /* if (ret == -1) */ /* printk("%s: Error %d\n", __FUNCTION__, pDev->cmd->error); */ /* } */ /* if (cmd_access != 0) { */ /* AMAZON_S_SDIO_DMSG ("cmd access timeout\n"); */ /* pDev->cmd->error = ERROR_TIMEOUT; */ /* cmd_access = 0; */ /* } */ /* return pDev->cmd->error; */ /* u16 status; */ /* int end_command = 0; */ /* u32 ret = 0; */ /* /\* build the request *\/ */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* if(opcode == SD_IO_GO_IDLE_STATE)/\* command 0 implementation on this chip. *\/ */ /* opcode = opcode | (1 << 14); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 0; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = 0; */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* mmcsdregs->mmcim = 0; */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* PWARNING("mmccmd = 0x%lx, mmcarghl = 0x%lx\n", (opcode|(ReplyType << 9)), CmdArg); */ /* mmcsdregs->mmcarghl = CmdArg; */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = ( opcode | */ /* (ReplyType << 9) ); /\* Response type is R5 *\/ */ /* /\* Wait for end of write transfer *\/ */ /* while(!end_command) */ /* { */ /* status = mmcsdregs->mmcst0; */ /* if (status & MMCSD_EVENT_EOFCMD) */ /* { */ /* PDEBUG("changing end_command to 1\n"); */ /* end_command = TRUE; */ /* } */ /* if(status & MMCSD_EVENT_ERROR) */ /* { */ /* ret = report_error(status); */ /* end_command = TRUE; */ /* } */ /* } */ /* if(opcode == SD_IO_RW_DIRECT && !(ret)) */ /* { */ /* iscardinitialized = 1; */ /* cardstate = 1; */ /* } */ /* if(datalen) */ /* { */ /* memcpy(DataBufferPointer,(char*)(&(mmcsdregs->mmcrsp67)),datalen<4?datalen:4); */ /* } */ /* PDEBUG("exiting %s\n",__FUNCTION__); */ return ret; } int sdiodrv_read_sync_prepare(void *sdio_priv, unsigned long opcode, int ReplyType, int BusWidth, int BlockSize, unsigned int timeout_clks) { *(((u32 *)sdio_priv)+MMCCMD) = ( opcode | (1 << 13) | /* There is data transfer */ (1 << 7 ) | /* Push pull mode enable */ (MMC_RSP_R5 << 9) ); /* Response type is R5 */ *(((u32 *)sdio_priv)+MMCTOD) = timeout_clks; return 0; } int sdiodrv_read_sync(void *sdio_priv, void *DataBufferPointer, int sdio_address, int datalen) { int ret; struct sd_cmd cmd; PDEBUG("entering %s()\n" , __FUNCTION__ ); memset(&cmd, 0, sizeof(cmd)); cmd.args = SDIO_CMD53_READ(0, FUNCTION_SELECT_1, 0, 1, sdio_address, datalen); cmd.response[0] = 0; cmd.response_type = MMC_RSP_R5; cmd.op_code = SD_IO_RW_EXTENDED; ret = ifx_sd_controller_read_data_kernel(&cmd, DataBufferPointer, datalen); /* u16 status; */ /* u32 i; */ /* int byteCnt; */ /* int end_transfer = 0; */ /* u32 ret = 0; */ /* int len = (datalen==MAX_STREAM_SIZE_IN_BYTE_MODE ? 0 : datalen); */ /* /\* build the request *\/ */ /* CL_TRACE_START_L3(); */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Write the timeout value to the MMC Data Read Time-Out Register (MMCTOD) *\/ */ /* mmcsdregs->mmctod = *(((u32 *)sdio_priv)+MMCTOD); */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 1; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = datalen; */ /* /\* Configure the FIFO for read *\/ */ /* mmcsdregs->mmcfifoctl = mmcsdregs->mmcfifoctl | 0x1; */ /* mmcsdregs->mmcfifoctl = 0x0; */ /* if (RW_THRESHOLD == 32) */ /* mmcsdregs->mmcfifoctl = (1 << 2); */ /* mmcsdregs->mmcim = 0; */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* PWARNING("mmccmd = 0x%x, mmcarghl = 0x%x\n",(u32)(*(((u32 *)sdio_priv)+MMCCMD)), SDIO_CMD53_READ(0,FUNCTION_SELECT_1,0,1,(sdio_address),len)); */ /* mmcsdregs->mmcarghl = SDIO_CMD53_READ(0,FUNCTION_SELECT_1,0,1,(sdio_address),len); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = (u32)(*(((u32 *)sdio_priv)+MMCCMD)); */ /* CL_TRACE_END_L3("ssd.ko", "INHERIT", "SDIO_DRV_SYNC", ""); */ /* /\* Wait for end of read transfer *\/ */ /* while(!end_transfer) */ /* { */ /* status = mmcsdregs->mmcst0; */ /* if (status & MMCSD_EVENT_READ) */ /* { */ /* if (datalen > 0) */ /* { */ /* if (datalen > RW_THRESHOLD) */ /* byteCnt = RW_THRESHOLD; */ /* else */ /* byteCnt = datalen; */ /* datalen -= byteCnt; */ /* for (i = 0; i < (byteCnt / 4); i++) */ /* { */ /* *((unsigned long*)(DataBufferPointer)) = mmcsdregs->mmcdrr; */ /* DataBufferPointer+=4; */ /* } */ /* } */ /* } */ /* if (status & MMCSD_EVENT_BLOCK_XFERRED) */ /* {/\* Block sent/received *\/ */ /* while (datalen > 0) */ /* { */ /* *((unsigned long*)(DataBufferPointer)) = mmcsdregs->mmcdrr; */ /* DataBufferPointer+=4; */ /* datalen-=4; */ /* } */ /* PDEBUG("changing end_transfer to 1\n"); */ /* end_transfer = TRUE; */ /* } */ /* if(status & MMCSD_EVENT_ERROR) */ /* { */ /* ret = report_error(status); */ /* break; */ /* } */ /* } */ PDEBUG("exiting %s\n",__FUNCTION__); return ret; } int sdiodrv_read_byte(unsigned char *data, int Address) { int arg; int ret; struct sd_cmd cmd = { 0 }; PDEBUG("entering %s()" , __FUNCTION__ ); arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,Address); cmd.args = arg; cmd.response[0] = 0; cmd.response_type = MMC_RSP_R5; cmd.op_code = SD_IO_RW_DIRECT /* SD_CMD_IO_RW_REDIRECT */; ret = ifx_sd_controller_send_cmd_kernel(&cmd); *data = (cmd.response[0]) & 0xff; /* u16 status; */ /* int end_command = 0; */ /* u32 ret = 0; */ /* /\* build the request *\/ */ /* PDEBUG("entering %s()" , __FUNCTION__ ); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 0; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = 0; */ /* mmcsdregs->mmcim = 0; */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* mmcsdregs->mmcarghl = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,(Address)); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = ( SD_IO_RW_DIRECT | */ /* (1 << 7 ) | /\* Push pull mode enable *\/ */ /* (MMC_RSP_R5 << 9) ); /\* Response type is R5 *\/ */ /* /\* Wait for end of read transfer *\/ */ /* while(!end_command) */ /* { */ /* status = mmcsdregs->mmcst0; */ /* if (status & MMCSD_EVENT_EOFCMD) */ /* { */ /* PDEBUG("changing end_command to 1\n"); */ /* end_command = TRUE; */ /* } */ /* if(status & MMCSD_EVENT_ERROR) */ /* { */ /* ret = report_error(status); */ /* break; */ /* } */ /* } */ /* /\* Read the data byte from the response registers *\/ */ /* *data = (unsigned char)(mmcsdregs->mmcrsp67); */ PDEBUG("exiting %s\n",__FUNCTION__); return ret; } int sdiodrv_write_sync_prepare(void *sdio_priv, unsigned long opcode, int ReplyType, int BusWidth, int BlockSize, unsigned int timeout_clks) { *(((u32 *)sdio_priv)+MMCCMD) = ( opcode | (1 << 13) | /* There is data transfer */ (1 << 11) | /* Direction is write */ (1 << 7 ) | /* Push pull mode enable */ (MMC_RSP_R5 << 9) ); /* Response type is R5 */ *(((u32 *)sdio_priv)+MMCTOD) = timeout_clks; return 0; } int sdiodrv_write_sync(void *sdio_priv, void *DataBufferPointer, int sdio_address, int datalen) { int ret; struct sd_cmd cmd; PDEBUG("entering %s()\n" , __FUNCTION__ ); memset(&cmd, 0, sizeof(cmd)); cmd.args = SDIO_CMD53_WRITE(1, FUNCTION_SELECT_1, 0, 1, sdio_address, datalen); cmd.response[0] = 0; cmd.response_type = MMC_RSP_R5; cmd.op_code = SD_IO_RW_EXTENDED; ret = ifx_sd_controller_send_data_kernel(&cmd, DataBufferPointer, datalen); /* u16 status; */ /* u32 i; */ /* int byteCnt; */ /* int end_transfer = 0; */ /* u32 ret = 0; */ /* int len = (datalen==MAX_STREAM_SIZE_IN_BYTE_MODE ? 0 : datalen); */ /* /\* build the request *\/ */ /* CL_TRACE_START_L3(); */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Write the timeout value to the MMC Data Read Time-Out Register (MMCTOD) *\/ */ /* mmcsdregs->mmctod = *(((u32 *)sdio_priv)+MMCTOD); */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 1; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = datalen; */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* /\* Configure the FIFO for write *\/ */ /* mmcsdregs->mmcfifoctl = mmcsdregs->mmcfifoctl | 0x1; */ /* mmcsdregs->mmcfifoctl = 0x0; */ /* mmcsdregs->mmcfifoctl = (1 << 1); */ /* if (RW_THRESHOLD == 32) */ /* mmcsdregs->mmcfifoctl |= (1 << 2); */ /* if (datalen < RW_THRESHOLD) */ /* byteCnt = datalen; */ /* else */ /* byteCnt = RW_THRESHOLD; */ /* /\* write the first bytes to transfer to the FIFO as we are not using the DMA*\/ */ /* for (i = 0; i < (byteCnt / 4); i++) */ /* { */ /* mmcsdregs->mmcdxr = *((unsigned long*)(DataBufferPointer)); */ /* DataBufferPointer+=4; */ /* } */ /* datalen -= byteCnt; */ /* mmcsdregs->mmcim = 0; */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* PWARNING("mmccmd = 0x%x, mmcarghl = 0x%x\n", (u32)(*(((u32 *)sdio_priv)+MMCCMD)), SDIO_CMD53_WRITE(1,FUNCTION_SELECT_1,0,1,(sdio_address),len)); */ /* mmcsdregs->mmcarghl = SDIO_CMD53_WRITE(1,FUNCTION_SELECT_1,0,1,(sdio_address),len); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = (u32)(*(((u32 *)sdio_priv)+MMCCMD)); */ /* CL_TRACE_END_L3("ssd.ko", "INHERIT", "SDIO_DRV_SYNC", ".kick"); */ /* /\* Wait for end of write transfer *\/ */ /* while(!end_transfer) */ /* { */ /* status = mmcsdregs->mmcst0; */ /* if (status & MMCSD_EVENT_WRITE){ */ /* if (datalen > 0) { */ /* if (datalen > RW_THRESHOLD) */ /* byteCnt = RW_THRESHOLD; */ /* else */ /* byteCnt = datalen; */ /* datalen -= byteCnt; */ /* for (i = 0; i < (byteCnt / 4); i++) { */ /* while(mmcsdregs->mmcst1 & 0x40); */ /* mmcsdregs->mmcdxr = *((unsigned long*)(DataBufferPointer)); */ /* DataBufferPointer+=4; */ /* } */ /* } */ /* } */ /* if (status & MMCSD_EVENT_BLOCK_XFERRED) */ /* {/\* Block sent/received *\/ */ /* end_transfer = TRUE; */ /* } */ /* if(status & MMCSD_EVENT_ERROR) */ /* { */ /* ret = report_error(status); */ /* break; */ /* } */ /* } */ PDEBUG("exiting %s\n",__FUNCTION__); return ret; } int sdiodrv_write_byte(unsigned char data, int Address) { int arg; int ret; struct sd_cmd cmd = { 0 }; PDEBUG("entering %s()\n" , __FUNCTION__ ); arg = SDIO_CMD52_WRITE(1,FUNCTION_SELECT_1,0,Address,data); cmd.args = arg; cmd.response[0] = 0; cmd.response_type = MMC_RSP_R5; cmd.op_code = SD_IO_RW_DIRECT /* SD_CMD_IO_RW_REDIRECT */; ret = ifx_sd_controller_send_cmd_kernel(&cmd); /* u16 status; */ /* int end_command = 0; */ /* u32 ret = 0; */ /* /\* build the request *\/ */ /* CL_TRACE_START_L3(); */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 0; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = 0; */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* mmcsdregs->mmcim = 0; */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* mmcsdregs->mmcarghl = SDIO_CMD52_WRITE(1,FUNCTION_SELECT_1,0,(Address),data); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = ( SD_IO_RW_DIRECT | */ /* (1 << 7 ) | /\* Push pull mode enable *\/ */ /* (1 << 11) | /\* Direction is write *\/ */ /* (MMC_RSP_R5 << 9) ); /\* Response type is R5 *\/ */ /* CL_TRACE_END_L3("ssd.ko", "INHERIT", "SDIO_DRV_SYNC", ".kick"); */ /* /\* Wait for end of write transfer *\/ */ /* while(!end_command) */ /* { */ /* status = mmcsdregs->mmcst0; */ /* if (status & MMCSD_EVENT_EOFCMD) */ /* { */ /* PDEBUG("changing end_command to 1\n"); */ /* end_command = TRUE; */ /* } */ /* if(status & MMCSD_EVENT_ERROR) */ /* { */ /* ret = report_error(status); */ /* break; */ /* } */ /* } */ PDEBUG("exiting %s\n",__FUNCTION__); return ret; } int sdiodrv_read_async_prepare(void *sdio_priv,unsigned long opcode, int ReplyType,int BusWidth, int BlockSize, void(*BusTxnCB)(void* handle, int status), void* Handle, int Endless, int dma_mode, void* dma_params, unsigned int timeout_clks) { /* *(((u32 *)sdio_priv)+MMCCMD) = ( opcode | */ /* (1 << 13) | /\* There is data transfer *\/ */ /* (1 << 16 )| /\* generating DMA Xfer event *\/ */ /* (1 << 7 ) | /\* Push pull mode enable *\/ */ /* (MMC_RSP_R5 << 9) ); /\* Response type is R5 *\/ */ /* *(((u32 *)sdio_priv)+MMCTOD) = timeout_clks; */ /* *(((u32 *)sdio_priv)+CONTEXT) = (u32)(Handle); */ /* *(((u32 *)sdio_priv)+CALLBACK) = (u32)(BusTxnCB); */ /* davinci_set_dma_src_params(DAVINCI_DMA_MMCRXEVT, SDIO_DATA_RECEIVE_REG, INCR, W8BIT); */ /* davinci_set_dma_dest_params(DAVINCI_DMA_MMCRXEVT, 0, INCR, W8BIT); */ /* davinci_set_dma_src_index(DAVINCI_DMA_MMCRXEVT, 0, 0); */ /* davinci_set_dma_dest_index(DAVINCI_DMA_MMCRXEVT, 4, RW_THRESHOLD); */ /* davinci_set_dma_transfer_params(DAVINCI_DMA_MMCRXEVT, 4, RW_THRESHOLD/4, 0, 0, ABsync); */ /* davinci_set_dma_src_params(RX_link_channel, SDIO_DATA_RECEIVE_REG, INCR, W8BIT); */ /* davinci_set_dma_dest_params(RX_link_channel, 0, INCR, W8BIT); */ /* davinci_set_dma_src_index(RX_link_channel, 0, 0); */ /* davinci_set_dma_dest_index(RX_link_channel, 1, 0); */ /* davinci_set_dma_transfer_params(RX_link_channel, 1, 0, 1, 1, ABsync); */ /* davinci_dma_link_lch(DAVINCI_DMA_MMCRXEVT, RX_link_channel); */ /* davinci_get_dma_params(DAVINCI_DMA_MMCRXEVT, &temp_rx1); */ /* davinci_get_dma_params(RX_link_channel, &temp_rx2); */ return 0; } int sdiodrv_read_async(void *sdio_priv,void *DataBufferPointer, int sdio_address, int datalen) { /* /\* build the request *\/ */ /* u16 status; */ /* int len = (datalen==MAX_STREAM_SIZE_IN_BYTE_MODE ? 0 : datalen); */ /* CL_TRACE_START_L4(); */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* //memset(g_request,0,sizeof(struct IO_request)); */ /* g_request.direction = read; */ /* g_request.callback = (void *)*(((u32 *)sdio_priv)+CALLBACK); */ /* g_request.context = (void *)*(((u32 *)sdio_priv)+CONTEXT); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* If dma is used, try to activate a DMA transfer *\/ */ /* sdio_davinci_start_dma_transfer(DataBufferPointer,datalen, read); */ /* /\* Write the timeout value to the MMC Data Read Time-Out Register (MMCTOD) *\/ */ /* mmcsdregs->mmctod = *(((u32 *)sdio_priv)+MMCTOD); */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 1; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = datalen; */ /* /\* Configure the FIFO for read *\/ */ /* mmcsdregs->mmcfifoctl = mmcsdregs->mmcfifoctl | 0x1; */ /* mmcsdregs->mmcfifoctl = 0x0; */ /* if (RW_THRESHOLD == 32) */ /* mmcsdregs->mmcfifoctl = (1 << 2); */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* mmcsdregs->mmcim = //(MMCSD_EVENT_EOFCMD | */ /* ( MMCSD_EVENT_ERROR_CMDCRC | */ /* MMCSD_EVENT_ERROR_DATACRC | */ /* MMCSD_EVENT_ERROR_CMDTIMEOUT | */ /* MMCSD_EVENT_ERROR_DATATIMEOUT | */ /* MMCSD_EVENT_BLOCK_XFERRED); */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* PWARNING("mmccmd = 0x%8.8x, mmcarghl = 0x%x\n",*(((u32 *)sdio_priv)+MMCCMD), SDIO_CMD53_READ(0,FUNCTION_SELECT_1,0,1,(sdio_address),len)); */ /* mmcsdregs->mmcarghl = SDIO_CMD53_READ(0,FUNCTION_SELECT_1,0,1,(sdio_address),len); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = *(((u32 *)sdio_priv)+MMCCMD); */ /* PDEBUG("exiting %s\n",__FUNCTION__); */ /* CL_TRACE_END_L4("ssd.ko", "INHERIT", "SDIO_DRV_ASYNC", ""); */ return 0; } int sdiodrv_write_async_prepare(void *sdio_priv,unsigned long opcode, int ReplyType,int BusWidth, int BlockSize, void(*BusTxnCB)(void* handle, int status), void* Handle, int Endless, int dma_mode, void* dma_params, unsigned int timeout_clks) { /* *(((u32 *)sdio_priv)+MMCCMD) = ( opcode | */ /* (1 << 13) | /\* There is data transfer *\/ */ /* (1 << 16 )| /\* generating DMA Xfer event *\/ */ /* (1 << 11) | /\* Direction is write *\/ */ /* (1 << 7 ) | /\* Push pull mode enable *\/ */ /* (MMC_RSP_R5 << 9) ); /\* Response type is R5 *\/ */ /* *(((u32 *)sdio_priv)+MMCTOD) = timeout_clks; */ /* *(((u32 *)sdio_priv)+CONTEXT) = (u32)(Handle); */ /* *(((u32 *)sdio_priv)+CALLBACK) = (u32)(BusTxnCB); */ /* davinci_set_dma_src_params(DAVINCI_DMA_MMCTXEVT, 0, INCR, W8BIT); */ /* davinci_set_dma_dest_params(DAVINCI_DMA_MMCTXEVT, SDIO_DATA_TRANSMIT_REG, INCR, W8BIT); */ /* davinci_set_dma_src_index(DAVINCI_DMA_MMCTXEVT, 4,RW_THRESHOLD); */ /* davinci_set_dma_dest_index(DAVINCI_DMA_MMCTXEVT, 0, 0); */ /* davinci_set_dma_transfer_params(DAVINCI_DMA_MMCTXEVT, 4, RW_THRESHOLD/4, 0, 4, ABsync); */ /* davinci_set_dma_src_params(TX_link_channel, 0, INCR, W8BIT); */ /* davinci_set_dma_dest_params(TX_link_channel, SDIO_DATA_TRANSMIT_REG, INCR, W8BIT); */ /* davinci_set_dma_src_index(TX_link_channel, 1, 0); */ /* davinci_set_dma_dest_index(TX_link_channel, 0, 0); */ /* davinci_set_dma_transfer_params(TX_link_channel, 1, 0, 1, 1, ABsync); */ /* davinci_dma_link_lch(DAVINCI_DMA_MMCTXEVT, TX_link_channel); */ /* davinci_get_dma_params(DAVINCI_DMA_MMCTXEVT, &temp_tx1); */ /* davinci_get_dma_params(TX_link_channel, &temp_tx2); */ return 0; } int sdiodrv_write_async(void *sdio_priv,void *DataBufferPointer, int sdio_address, int datalen) { /* int len = (datalen==MAX_STREAM_SIZE_IN_BYTE_MODE ? 0 : datalen); */ /* u16 status; */ /* CL_TRACE_START_L4(); */ /* PDEBUG("entering %s()\n" , __FUNCTION__ ); */ /* //memset(g_request,0,sizeof(struct IO_request)); */ /* g_request.direction = write; */ /* g_request.callback = (void *)*(((u32 *)sdio_priv)+CALLBACK); */ /* g_request.context = (void *)*(((u32 *)sdio_priv)+CONTEXT); */ /* /\* clear status register *\/ */ /* status = mmcsdregs->mmcst0; */ /* /\* Write the timeout value to the MMC Data Read Time-Out Register (MMCTOD) *\/ */ /* mmcsdregs->mmctod = *(((u32 *)sdio_priv)+MMCTOD); */ /* /\* Set the transfer size in bytes and the number of blocks. right now we only use one block *\/ */ /* mmcsdregs->mmcnblk = 1; /\* eq->blocks; *\/ */ /* mmcsdregs->mmcblen = datalen; */ /* /\* Configure the FIFO for read or write *\/ */ /* mmcsdregs->mmcfifoctl = mmcsdregs->mmcfifoctl | 0x1; */ /* mmcsdregs->mmcfifoctl = 0; */ /* mmcsdregs->mmcfifoctl = (1 << 1); */ /* if (RW_THRESHOLD == 32) */ /* mmcsdregs->mmcfifoctl |= (1 << 2); */ /* /\*set Command timeout *\/ */ /* mmcsdregs->mmctor = reg_mmctor_val; */ /* mmcsdregs->mmcim = //(MMCSD_EVENT_EOFCMD | */ /* (MMCSD_EVENT_ERROR_CMDCRC | */ /* MMCSD_EVENT_ERROR_DATACRC | */ /* MMCSD_EVENT_ERROR_CMDTIMEOUT | */ /* MMCSD_EVENT_ERROR_DATATIMEOUT | */ /* MMCSD_EVENT_BLOCK_XFERRED); */ /* /\* write the command and arguments to the hardware. This will start the request *\/ */ /* /\* If dma is used, try to activate a DMA transfer *\/ */ /* sdio_davinci_start_dma_transfer(DataBufferPointer, datalen, write); */ /* PWARNING("mmccmd = 0x%8.8x, mmcarghl = 0x%x\n",*(((u32 *)sdio_priv)+MMCCMD), SDIO_CMD53_WRITE(1,FUNCTION_SELECT_1,0,1,(sdio_address),len)); */ /* mmcsdregs->mmcarghl = SDIO_CMD53_WRITE(1,FUNCTION_SELECT_1,0,1,(sdio_address),len); */ /* /\* Set command index *\/ */ /* mmcsdregs->mmccmd = *(((u32 *)sdio_priv)+MMCCMD); */ PDEBUG("exiting %s\n",__FUNCTION__); /* CL_TRACE_END_L4("ssd.ko", "INHERIT", "SDIO_DRV_ASYNC", ""); */ return 0; } #ifdef SDIO_IN_BAND_INTERRUPT int sdiodrv_set_4bit(unsigned char fourbit) { int ret = 0; mmcsdregs = (mmcsd_regs *) IO_ADDRESS(MMCSD_REGS_BASE_ADDR); //mmcsdregs->mmcctl = mmcsdregs->mmcctl | 0x1; /*CMD line portion is diabled and in reset state */ //mmcsdregs->mmcctl = mmcsdregs->mmcctl | (1 << 1); /*DAT line portion is diabled and in reset state */ /* Select 4 bits data bus */ if(fourbit == TRUE) { PDEBUG("bus width = 4\n"); mmcsdregs->mmcctl = mmcsdregs->mmcctl | 0x4; } else { PDEBUG("bus width = 1\n"); mmcsdregs->mmcctl = mmcsdregs->mmcctl & ~(0x4); } //mmcsdregs->mmcctl = mmcsdregs->mmcctl & ~(0x1); //mmcsdregs->mmcctl = mmcsdregs->mmcctl & ~(1 << 1); return ret; } #endif /* SDIO_IN_BAND_INTERRUPT */ /* helper functions for Danube */ static int ifx_sdio_gpio_configure (void) { AMAZON_S_SDIO_DMSG ("using GPIO %d as MCLCLK.\n", MCLCLK); IFX_SD_PIN_RESERVE(MCLCLK); IFX_SD_DIR_OUT(MCLCLK); IFX_SD_ALTSEL0_CLR(MCLCLK); IFX_SD_ALTSEL1_SET(MCLCLK); IFX_SD_OD_SET(MCLCLK); IFX_SD_PUDSEL_SET(MCLCLK); IFX_SD_PUDEN_SET(MCLCLK); AMAZON_S_SDIO_DMSG ("using GPIO %d as MCLCMD.\n", MCLCMD); IFX_SD_PIN_RESERVE(MCLCMD); IFX_SD_DIR_IN(MCLCMD); IFX_SD_ALTSEL0_CLR(MCLCMD); IFX_SD_ALTSEL1_SET(MCLCMD); IFX_SD_OD_SET(MCLCMD); IFX_SD_PUDSEL_SET(MCLCMD); IFX_SD_PUDEN_SET(MCLCMD); #if MCLDATA0 == 17 //GPIO17 (P1.1): DIR=0,ALT0=0,ALT1=1,OUT=1, OD=1 AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA0.\n", MCLDATA0); IFX_SD_PIN_RESERVE(MCLDATA0); IFX_SD_ALTSEL0_CLR(MCLDATA0); #elif MCLDATA0 == 28 //GPIO28 (P1.12): DIR=0,ALT0=1,ALT1=1,OUT=1, OD=1 AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA0.\n", MCLDATA0); IFX_SD_PIN_RESERVE(MCLDATA0); IFX_SD_ALTSEL0_SET(MCLDATA0); #else #error MCLDATA0 not defined #endif IFX_SD_DIR_IN(MCLDATA0); IFX_SD_ALTSEL1_SET(MCLDATA0); IFX_SD_OD_SET(MCLDATA0); IFX_SD_PUDSEL_SET(MCLDATA0); IFX_SD_PUDEN_SET(MCLDATA0); AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA1.\n", MCLDATA1); IFX_SD_PIN_RESERVE(MCLDATA1); IFX_SD_DIR_IN(MCLDATA1); IFX_SD_ALTSEL0_CLR(MCLDATA1); IFX_SD_ALTSEL1_SET(MCLDATA1); IFX_SD_OD_SET(MCLDATA1); IFX_SD_PUDSEL_SET(MCLDATA1); IFX_SD_PUDEN_SET(MCLDATA1); #if MCLDATA2 == 16 //GPIO16 (P1.0): DIR=0,ALT0=0,ALT1=1,OUT=1, OD=1 AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA2.\n", MCLDATA2); IFX_SD_PIN_RESERVE(MCLDATA2); IFX_SD_DIR_OUT(MCLDATA2); IFX_SD_ALTSEL0_CLR(MCLDATA2); #elif MCLDATA2 == 26 //GPIO26 (P1.10): DIR=0,ALT0=1,ALT1=1,OUT=1, OD=1 AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA2.\n", MCLDATA2); IFX_SD_PIN_RESERVE(MCLDATA2); IFX_SD_DIR_IN(MCLDATA2); IFX_SD_ALTSEL0_SET(MCLDATA2); #else #error MCLDATA2 not defined #endif IFX_SD_ALTSEL1_SET(MCLDATA2); IFX_SD_OD_SET(MCLDATA2); IFX_SD_PUDSEL_SET(MCLDATA2); IFX_SD_PUDEN_SET(MCLDATA2); AMAZON_S_SDIO_DMSG ("using GPIO %d as DATA3.\n", MCLDATA3); IFX_SD_PIN_RESERVE(MCLDATA3); IFX_SD_DIR_IN(MCLDATA3); IFX_SD_ALTSEL0_CLR(MCLDATA3); IFX_SD_ALTSEL1_SET(MCLDATA3); IFX_SD_OD_SET(MCLDATA3); IFX_SD_PUDSEL_SET(MCLDATA3); IFX_SD_PUDEN_SET(MCLDATA3); return 0; } /* GPIO13 is connected to the WLAN chip */ int ifx_sdio_set_ext_reset(int active) { IFX_SD_PIN_RESERVE(MCLRESET); if (active == 0) { IFX_SD_OUTPUT_SET(MCLRESET); } else { IFX_SD_OUTPUT_CLR(MCLRESET); } IFX_SD_DIR_OUT(MCLRESET); IFX_SD_ALTSEL0_CLR(MCLRESET); IFX_SD_ALTSEL1_CLR(MCLRESET); IFX_SD_OD_SET(MCLRESET); IFX_SD_PUDSEL_SET(MCLRESET); IFX_SD_PUDEN_SET(MCLRESET); return 0; }