17 #include <linux/module.h>
18 #include <linux/types.h>
20 #include <linux/errno.h>
34 #include <asm/uaccess.h>
39 #define NWFLASH_VERSION "6.4"
42 static void kick_open(
void);
43 static int get_flash_id(
void);
44 static int erase_block(
int nBlock);
45 static int write_block(
unsigned long p,
const char __user *
buf,
int count);
47 #define KFLASH_SIZE 1024*1024 //1 Meg
48 #define KFLASH_SIZE4 4*1024*1024 //4 Meg
49 #define KFLASH_ID 0x89A6 //Intel flash
50 #define KFLASH_ID4 0xB0D4 //Intel flash 4Meg
52 static bool flashdebug;
54 static int gbWriteEnable;
55 static int gbWriteBase64Enable;
60 static int get_flash_id(
void)
62 volatile unsigned int c1, c2;
69 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0x90;
78 c2 = *(
volatile unsigned char *) (
FLASH_BASE + 2);
80 c2 = *(
volatile unsigned char *) (
FLASH_BASE + 1);
87 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0xFF;
95 static long flash_ioctl(
struct file *filep,
unsigned int cmd,
unsigned long arg)
100 gbWriteBase64Enable = 0;
109 gbWriteBase64Enable = 1;
113 gbWriteBase64Enable = 0;
129 "buffer=%p, count=0x%zx.\n", *ppos, buf, size);
143 size_t size, loff_t * ppos)
145 unsigned long p = *ppos;
152 printk(
"flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
158 if (p < 64 * 1024 && (!gbWriteBase64Enable))
164 if (p >= gbFlashSize)
165 return count ? -
ENXIO : 0;
167 if (count > gbFlashSize - p)
168 count = gbFlashSize -
p;
181 nBlock = (
int) p >> 16;
186 temp = ((
int) (p + count) >> 16) - nBlock + 1;
191 if (((
int) (p +
count) & 0xFFFF) == 0)
196 "starting at %d.\n", temp, nBlock);
198 for (;
temp; temp--, nBlock++) {
209 rc = erase_block(nBlock);
211 }
while (rc && i < 10);
219 "from buf %p, bytes left %X.\n", p, buf,
225 rc = write_block(p, buf, count - written);
271 static loff_t flash_llseek(
struct file *file, loff_t
offset,
int orig)
278 (
unsigned int) offset, orig);
287 if ((
unsigned int) offset > gbFlashSize) {
292 file->
f_pos = (
unsigned int) offset;
296 if ((file->
f_pos + offset) > gbFlashSize) {
300 if ((file->
f_pos + offset) < 0) {
320 static int erase_block(
int nBlock)
322 volatile unsigned int c1;
323 volatile unsigned char *pWritePtr;
335 c1 = *(
volatile unsigned char *) (
FLASH_BASE + 0x8000);
341 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0x50;
347 pWritePtr = (
unsigned char *) ((
unsigned int) (
FLASH_BASE + 0x8000 + (nBlock << 16)));
357 *(
volatile unsigned char *) pWritePtr = 0x20;
362 *(
volatile unsigned char *) pWritePtr = 0xD0;
374 while (!(c1 & 0x80) &&
time_before(jiffies, timeout)) {
379 c1 = *(
volatile unsigned char *) (pWritePtr);
388 *(
volatile unsigned char *) pWritePtr = 0xFF;
399 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0x50;
408 pWritePtr = (
unsigned char *) ((
unsigned int) (
FLASH_BASE + (nBlock << 16)));
410 for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
411 if ((temp1 = *(
volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
425 static int write_block(
unsigned long p,
const char __user *buf,
int count)
427 volatile unsigned int c1;
428 volatile unsigned int c2;
429 unsigned char *pWritePtr;
430 unsigned int uAddress;
432 unsigned long timeout;
433 unsigned long timeout1;
435 pWritePtr = (
unsigned char *) ((
unsigned int) (
FLASH_BASE +
p));
442 if (offset + count > 0x10000)
450 for (offset = 0; offset <
count; offset++, pWritePtr++) {
451 uAddress = (
unsigned int) pWritePtr;
452 uAddress &= 0xFFFFFFFC;
460 c1 = *(
volatile unsigned char *) (
FLASH_BASE + 0x8000);
475 *(
volatile unsigned char *) (uAddress) = 0x40;
480 *(
volatile unsigned char *) (uAddress) = c2;
485 *(
volatile unsigned char *) (
FLASH_BASE + 0x10000) = 0x70;
497 while (!(c1 & 0x80) &&
time_before(jiffies, timeout1))
498 c1 = *(
volatile unsigned char *) (
FLASH_BASE + 0x8000);
508 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0x50;
519 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0xFF;
530 *(
volatile unsigned char *) (
FLASH_BASE + 0x8000) = 0x50;
560 pWritePtr = (
unsigned char *) ((
unsigned int) (
FLASH_BASE +
p));
562 for (offset = 0; offset <
count; offset++) {
567 if ((c1 = *pWritePtr++) !=
c) {
568 printk(
KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
578 static void kick_open(
void)
599 .llseek = flash_llseek,
602 .unlocked_ioctl = flash_ioctl,
612 static int __init nwflash_init(
void)
627 printk(
"Flash: incorrect ID 0x%04X.\n",
id);
631 printk(
"Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
643 static void __exit nwflash_exit(
void)