- UID
- 1029342
- 性别
- 男
|
/*****************************************************************************
Description:
This function is the ioctl interface to the driver.
Parameters:
inode ptr to inode
filp ptr to file struct
cmd ioctl command
arg passed in argument
Returns:
0 => success
< 0 => error
******************************************************************************/
int spi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
ioctl_arg_t info;
unsigned int start, end;
int i;
switch(cmd)
{
case IOCTL_ERASE_CHIP:
if( !erase_chip())
{
return (-EFAULT);
}
break;
case IOCTL_ERASE_BLOCK:
if((void *)arg == NULL)
{
return(-EINVAL);
}
//get the ioctl struct passed in by user
if ( copy_from_user(&info, (ioctl_arg_t*)arg, sizeof(ioctl_arg_t)) )
{
SPI_ERR("%s:spi_ioctl::copy_from_user error./n", DRIVERNAME);
return -EFAULT;
}
/* sector & address index start from 0 */
start = (info.data.erase_range.start) >> SPI_FLASH_SECTOR_BIT;
end = (info.data.erase_range.end) >> SPI_FLASH_SECTOR_BIT;
/* start = (info.data.erase_range.start + SPI_FLASH_SECTOR_SIZE -1) >> SPI_FLASH_SECTOR_BIT;
end = (info.data.erase_range.end + SPI_FLASH_SECTOR_SIZE -1) >> SPI_FLASH_SECTOR_BIT;
start--;
end--; */
if(start > end || start < 0 || end >= SPI_FLASH_SIZE/SPI_FLASH_SECTOR_SIZE)
{
return (-EINVAL);
}
SPI_DBG("start=%d,end=%d/n", start, end);
for(i = start; i <= end; i++)
{
if(!erase_4K_sector(i))
{
return (-EFAULT);
}
}
break;
default:
return (-EINVAL);
break;
}
return 0;
}
void EP80579_spi_init(uint32_t base)
{
uint8_t byte;
uint16_t word;
uint32_t dword,val;
uint64_t qword;
uint32_t addr;
/* print some information for debug */
val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
SPI_DBG("status=%08x/n", val);
val = readw((void *)(spi_char.mem_virt+SPI_CTRL));
SPI_DBG("ctrl=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_ADDR));
SPI_DBG("addr=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_DATA0));
SPI_DBG("data0=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_BBAR));
SPI_DBG("BBAR=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_PBAR0));
SPI_DBG("PBAR0=%08x/n", val);
/* enable configuration */
addr = base + SPI_STATUS;
word = readw((void *)addr);
word &= ~SPI_STATUS_CFG_LOCK;
writew(word, (void *)addr);
/* fill opcode */
addr = base + SPI_OPMENU;
val = readl((void *)(spi_char.mem_virt+SPI_OPMENU));
SPI_DBG("before init, SPI_OPMENU.0=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_OPMENU+4));
SPI_DBG("before init, SPI_OPMENU.1=%08x/n", val);
dword = SPI_RD_DATA + (SPI_RD_STATUS<<8) + (SPI_WR_DATA<<16) + (SPI_WR_STATUS<<24);
writel(dword, (void *)addr);
dword = (SPI_4K_ERASE)+(SPI_CHIP_ERASE<<8);
writel(dword, (void *)(addr+4));
val = readl((void *)(spi_char.mem_virt+SPI_OPMENU));
SPI_DBG("after init, SPI_OPMENU.0=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_OPMENU+4));
SPI_DBG("after init, SPI_OPMENU.1=%08x/n", val);
/* fill opcode type */
val = readw((void *)(spi_char.mem_virt+SPI_OPTYPE));
SPI_DBG("before init, SPI_OPTTYPE=%08x/n", val);
val &= 0x0000;
val = val |SPI_RD_ADDR|(SPI_RD_NOADDR<<SPI_OPTYPE_WIDTH)|(SPI_WR_ADDR<<SPI_OPTYPE_WIDTH*2)
|(SPI_WR_NOADDR<<SPI_OPTYPE_WIDTH*3)|(SPI_WR_ADDR<<SPI_OPTYPE_WIDTH*4)|(SPI_WR_NOADDR<<SPI_OPTYPE_WIDTH*5);
writew(val, (void *)(spi_char.mem_virt+SPI_OPTYPE));
val = readw((void *)(spi_char.mem_virt+SPI_OPTYPE));/* check the status */
SPI_DBG("after init, SPI_OPTTYPE=%08x/n", val); |
|