- UID
- 1029342
- 性别
- 男
|
/*****************************************************************************
Description:
This function is called when the driver interface is closed
Parameters:
none
Returns:
0 => success
< 0 => error
******************************************************************************/
int spi_release(struct inode *inode, struct file *filp)
{
spi_char.fp = 0;
SPI_DBG("spi_char.fp = %08x/n", spi_char.fp);
SPI_DBG("%s:spi_release-module released/n", DRIVERNAME);
return 0;
}
int spi_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
int i;
uint32_t addr, val;
uint16_t word;
unsigned char data[BUF_SIZE];
ssize_t retval = 0;
/* print some information for debug */
SPI_DBG("start spi_read/n");
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 = readw((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.0=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_DATA0+4));
SPI_DBG("data0.1=%08x/n", val);
/* check count */
if(count > BUF_SIZE)
{
count = BUF_SIZE;
}
if(spi_char.fp+count > SPI_FLASH_SIZE)
{
count = SPI_FLASH_SIZE-spi_char.fp;
}
SPI_DBG("spi_char.fp = %08x/n", spi_char.fp);
addr = spi_char.fp;
SPI_DBG("spi_read: addr = %08x/n", addr);
for(i = 0; i < count; i++)
{
data[i] = read_byte(addr+i);
}
if(copy_to_user(buf, data, count))
{
SPI_ERR("spi_read::copty_to_user eror/n");
return (-EFAULT);
}
spi_char.fp += count;
SPI_DBG("leave spi_read, count=%d/n", count);
return (count);
}
int spi_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
int i;
uint32_t addr, val;
uint16_t word;
unsigned char data[BUF_SIZE];
ssize_t retval = 0;
/* print some information for debug */
SPI_DBG("start spi_write/n");
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 = readw((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.0=%08x/n", val);
val = readl((void *)(spi_char.mem_virt+SPI_DATA0+4));
SPI_DBG("data0.1=%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);
/* check count */
if(count > BUF_SIZE)
{
count = BUF_SIZE;
}
if(spi_char.fp+count > SPI_FLASH_SIZE)
{
count = SPI_FLASH_SIZE-spi_char.fp;
}
if(copy_from_user(data, buf, count))
{
SPI_ERR("spi_read::copy_from_user error/n");
return(-EFAULT);
}
/* disable flash protection */
if(is_flash_protection())
{
if(!disable_flash_protection())
{
SPI_ERR("can't disable flash protection/n");
return(-EFAULT);
}
}
addr = spi_char.fp;
for(i = 0; i < count; i++)
{
if(!write_byte(addr+i, data[i]))
{
SPI_ERR("spi_write error/n");
}
/* print some information for debug */
val = readl((void *)(spi_char.mem_virt+SPI_DATA0));
SPI_DBG("after write, data=%08x/n", val);
val = readw((void *)(spi_char.mem_virt+SPI_CTRL));
SPI_DBG("after write, ctrl=%08x/n", val);
val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
SPI_DBG("after write, status=%08x/n", val);
word = readw((void *)(spi_char.mem_virt+SPI_STATUS));
word |= SPI_STATUS_CDS;
word |= SPI_STATUS_BAS;
writew(word, (void *)(spi_char.mem_virt+SPI_STATUS));
val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
SPI_DBG("after write1, status=%08x/n", val);
}
spi_char.fp += count;
SPI_DBG("leave spi_write, count=%d/n", count);
return (count);
} |
|