int flash_vs_read(uint8_t *buf, loff_t offs, int len, uint32_t extra) { struct spi_transfer addr; int i; addr.spi_addr = offs; addr.spi_command[0] = 0x0B; for (i =0;i<len / 4096;i++) { addr.spi_current_addr[0] = (addr.spi_addr >> 16) & 0xff; addr.spi_current_addr[1] = (addr.spi_addr >> 8) & 0xff; addr.spi_current_addr[2] = addr.spi_addr & 0xff; addr.spi_current_addr[3] = 0; spi_tranfer(buf, NULL, 4096, addr.spi_current_addr, 4, addr.spi_command, 1); addr.spi_addr += 4096; buf += 4096; } if (len % 4096) { addr.spi_current_addr[0] = (addr.spi_addr >> 16) & 0xff; addr.spi_current_addr[1] = (addr.spi_addr >> 8) & 0xff; addr.spi_current_addr[2] = addr.spi_addr & 0xff; addr.spi_current_addr[3] = 0; spi_tranfer(buf, NULL, len % 4096, addr.spi_current_addr, 4, addr.spi_command, 1); }
void spi_init(void) { void *cm_per_vaddr, *ctl_md_vaddr; int32_t value32; int32_t i; int ret; //uint8_t value8 = 0x55; uint8_t rddata[0x110] = {0x55}, txdata[0x110] = {0x33}; uint16_t rx_len; cm_per_vaddr = ioremap_nocache(CM_PER_BASE, CM_PER_Size); iowrite32(0x02 , cm_per_vaddr + CM_PER_SPI1_CLKCTRL); //Enable clk iowrite32(0x02 , cm_per_vaddr + CM_PER_GPIO3_CLKCTRL); //Enable clk iowrite32(0x02 , cm_per_vaddr + CM_PER_GPIO2_CLKCTRL); //Enable clk printk("CM_PER_SPI1_CLKCTRL %#x\n", ioread32(cm_per_vaddr + CM_PER_SPI1_CLKCTRL)); while(ioread32(cm_per_vaddr + CM_PER_SPI1_CLKCTRL) & (0x03 << 16)) ; iounmap(cm_per_vaddr); ctl_md_vaddr = ioremap_nocache(CONTROL_MODULE_BASE, CONTROL_MODULE_Size); iowrite32(PAD_REV | PAD_PULLUP | 0x3, ctl_md_vaddr + conf_mcasp0_fsx); //D0 MISO iowrite32(PAD_REV | PAD_PULLUP | 0x3, ctl_md_vaddr + conf_mcasp0_axr0); //D1 MOSI iowrite32(PAD_PULLUP | 0x3, ctl_md_vaddr + conf_mcasp0_ahclkr); //cs0 iowrite32(PAD_REV | PAD_PULLUP | 0x3, ctl_md_vaddr + conf_mcasp0_aclkx); //clk need input to feedback //iowrite32(PAD_PULLUP | 0x7, ctl_md_vaddr + conf_mcasp0_fsr); //GPIO3_19 //iowrite32(PAD_PULLUP | 0x7, ctl_md_vaddr + conf_mcasp0_ahclkx); //GPIO3_21 iowrite32(PAD_PULLUP | 0x7, ctl_md_vaddr + 0x8a0); //GPIO2_6 lcd data0 iowrite32(PAD_PULLUP | 0x7, ctl_md_vaddr + 0x8a8); //GPIO2_8 lcd data2 #if defined S2 iowrite32(PAD_PULLUP | 0x7, ctl_md_vaddr + 0x8a4); //GPIO2_7 lcd data1 #endif iounmap(ctl_md_vaddr); gpio2_vaddr = ioremap_nocache(GPIO2_BASE, GPIO2_SIZE); value32 = ioread32(gpio2_vaddr + GPIO_OE); iowrite32(value32 & (~(0x01 << 6)), gpio2_vaddr + GPIO_OE); //set output value32 = ioread32(gpio2_vaddr + GPIO_OE); iowrite32(value32 & (~(0x01 << 8)), gpio2_vaddr + GPIO_OE); //set output #if defined S2 value32 = ioread32(gpio2_vaddr + GPIO_OE); iowrite32(value32 & (~(0x01 << 7)), gpio2_vaddr + GPIO_OE); //set output #endif spi_vaddr = ioremap_nocache(McSpi1_Base, McSpi1_Size); printk("spi_vaddr %#x\n", (uint32_t)spi_vaddr); printk("version %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_REVISION)); //reset don't sleep iowrite32((0x01<<3) | (0x01 << 1), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_SYSSCTL); value32 = 0; while((ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_SYSSTATUS) & 0x01) == 0) { if(value32++ == 0xffff) { printk("Reset spi module timeout\n"); break; } } printk("OMAP2_MCSPI_SYSSTATUS %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_SYSSTATUS)); //4针模式(CLK,D0,D1,CS),即CS使能 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL); iowrite32(value32 & (~(0x01 << 1)), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL); //主模式 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL); iowrite32(value32 & (~(0x01 << 2)), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL); //配置单通道模式,发送/接收模式 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL); iowrite32(value32 | (0x01 << 0), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL);//单通道 printk("OMAP2_MCSPI_MODULCTRL %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_MODULCTRL)); //set dir: clk out, d0 MISO, d1 MOSI //value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_SYST); //iowrite32((value32 & (~(0x01 << 10))) | (0x01 << 8) | (0x01 << 5), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_SYST); //DEP1 transmission IS=d0 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32((value32 & (~(0x01 << 18)) & (~(0x01 << 17))) | (0x01 << 16), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); //spi总线时钟配置: 1 =2 分频1clk精度mode1: clk平时高,上升沿采样 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32(((((value32 & (~(0x0f << 2))) | (0x01 << 2)) /*& (~(0x03 << 0))*/ & (~(0x01 << 29))) & (~(0x03 << 0)))|(0x01 << 0), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); //mcspi字长 8bit value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32(value32 | (0x07 << 7), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); //spics 极性low ative TCS=0.5 value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32(value32 | (0x00 << 25) | (0x01 << 6), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); //使能FIFO Transmit/receive modes value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32((value32 | (0x03 << 27)) & (~(0x03 << 12)), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); printk("OMAP2_MCSPI_CHCONF0 %#x\n", value32); //iowrite32((27<<8) | (27), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_XFERLEVEL); //interrupt rx full iowrite32((31<<8) | (31), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_XFERLEVEL); #if SPI_USE_INTERRUPT spi_dev.irq = 141; if (ret = request_irq(spi_dev.irq, mspi_interrupt, IRQF_TRIGGER_LOW, "mspi", (void*)&spi_dev)) { printk(KERN_ERR "mspi: Failed req IRQ %d, error{%d}\n", spi_dev.irq, ret); } mutex_init(&spi_dev.transfer_lock); init_waitqueue_head(&spi_dev.wait_transfer_complete); printk("Initial OMAP2_MCSPI_IRQSTATUS{%#x}OMAP2_MCSPI_IRQENABLE{%#x}\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_IRQSTATUS), ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_IRQENABLE)); #endif #if 0 iowrite32(CH_ENA, spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCTRL0); printk("OMAP2_MCSPI_CHCTRL0 %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCTRL0)); //cs low FORCE==1 iowrite32(ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0) | (0x01 << 20), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); value32 = ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); printk("OMAP2_MCSPI_CHCONF0 %#x\n", value32); printk( "000status %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHSTAT0)); for(i=0; i< 0x0ff; i++) { iowrite32(0x01<<19, gpio3_vaddr + GPIO_SETDATAOUT); iowrite32(i, spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_TX0); //printk( "status %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHSTAT0)); //wait rev cnt = 0; while( 00 == (ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHSTAT0) & (0x01<<0))) { if(cnt++ == 0xff) { printk( "status %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHSTAT0)); break; } } rddata[i]= ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_RX0); //printk("OMAP2_MCSPI_RX0 %#x\n", ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_RX0)); iowrite32(0x01<<19, gpio3_vaddr + GPIO_CLEARDATAOUT); } for(i=0; i< 0x0ff; i++) { if(0 == (i%16)) printk("\n 0x%02x: ", i); printk("%#x, ", rddata[i]); } //cs high iowrite32(ioread32(spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0) & (~(0x01 << 20)), spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCONF0); iowrite32(0, spi_vaddr + OMAP2_MCSPI_OFFSET + OMAP2_MCSPI_CHCTRL0); #endif //while(1) { for(i= 0; i< 0x100; i++) { txdata[i] = i; } i = spi_tranfer(0x55, txdata, 52, rddata, &rx_len); } }