2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 * This driver was originally based on the INCA-IP driver, but due to
17 * fundamental conceptual drawbacks there has been changed a lot.
19 * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de>
20 * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies.
22 * Copyright (C) 2006 infineon
23 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
27 #define IFAP_EEPROM_DRV_VERSION "0.0.1"
29 #include <linux/module.h>
30 #include <linux/errno.h>
31 #include <linux/signal.h>
32 #include <linux/sched.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/major.h>
36 #include <linux/string.h>
38 #include <linux/fcntl.h>
39 #include <linux/ptrace.h>
41 #include <linux/ioport.h>
42 #include <linux/init.h>
43 #include <linux/delay.h>
44 #include <linux/spinlock.h>
45 #include <linux/slab.h>
46 #include <asm/system.h>
49 #include <asm/uaccess.h>
50 #include <asm/bitops.h>
52 #include <linux/types.h>
53 #include <linux/kernel.h>
54 #include <linux/version.h>
56 #include <asm/ifxmips/ifxmips.h>
57 #include <asm/ifxmips/ifxmips_irq.h>
58 #include <asm/ifxmips/ifx_ssc_defines.h>
59 #include <asm/ifxmips/ifx_ssc.h>
61 /* allow the user to set the major device number */
62 static int ifxmips_eeprom_maj
= 0;
64 extern int ifx_ssc_init (void);
65 extern int ifx_ssc_open (struct inode
*inode
, struct file
*filp
);
66 extern int ifx_ssc_close (struct inode
*inode
, struct file
*filp
);
67 extern void ifx_ssc_cleanup_module (void);
68 extern int ifx_ssc_ioctl (struct inode
*inode
, struct file
*filp
,
69 unsigned int cmd
, unsigned long data
);
70 extern ssize_t
ifx_ssc_kwrite (int port
, const char *kbuf
, size_t len
);
71 extern ssize_t
ifx_ssc_kread (int port
, char *kbuf
, size_t len
);
73 extern int ifx_ssc_cs_low (unsigned int pin
);
74 extern int ifx_ssc_cs_high (unsigned int pin
);
75 extern int ifx_ssc_txrx (char *tx_buf
, unsigned int tx_len
, char *rx_buf
, unsigned int rx_len
);
76 extern int ifx_ssc_tx (char *tx_buf
, unsigned int tx_len
);
77 extern int ifx_ssc_rx (char *rx_buf
, unsigned int rx_len
);
79 #define EEPROM_CS IFX_SSC_WHBGPOSTAT_OUT0_POS
81 /* commands for EEPROM, x25160, x25140 */
82 #define EEPROM_WREN ((unsigned char)0x06)
83 #define EEPROM_WRDI ((unsigned char)0x04)
84 #define EEPROM_RDSR ((unsigned char)0x05)
85 #define EEPROM_WRSR ((unsigned char)0x01)
86 #define EEPROM_READ ((unsigned char)0x03)
87 #define EEPROM_WRITE ((unsigned char)0x02)
88 #define EEPROM_PAGE_SIZE 4
89 #define EEPROM_SIZE 512
95 unsigned char cmd
= EEPROM_RDSR
;
101 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)) == 0)
102 if ((ret
= ifx_ssc_txrx(&cmd
, 1, &status
, 1)) >= 0)
105 ifx_ssc_cs_high(EEPROM_CS
);
106 local_irq_restore(flag
);
112 eeprom_wip_over (void)
114 while (eeprom_rdsr())
115 printk("waiting for eeprom\n");
121 unsigned char cmd
= EEPROM_WREN
;
125 local_irq_save(flag
);
126 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)) == 0)
127 if ((ret
= ifx_ssc_tx(&cmd
, 1)) >= 0)
130 ifx_ssc_cs_high(EEPROM_CS
);
131 local_irq_restore(flag
);
143 unsigned char cmd
[2];
146 cmd
[0] = EEPROM_WRSR
;
149 if ((ret
= eeprom_wren()))
151 printk ("eeprom_wren fails\n");
155 local_irq_save(flag
);
157 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)))
160 if ((ret
= ifx_ssc_tx(cmd
, 2)) < 0) {
161 ifx_ssc_cs_high(EEPROM_CS
);
165 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)))
168 local_irq_restore(flag
);
174 local_irq_restore (flag
);
182 eeprom_read (unsigned int addr
, unsigned char *buf
, unsigned int len
)
185 unsigned char write_buf
[2];
186 unsigned int eff
= 0;
192 eff
= EEPROM_PAGE_SIZE
- (addr
% EEPROM_PAGE_SIZE
);
193 eff
= (eff
< len
) ? eff
: len
;
194 local_irq_save(flag
);
196 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)) < 0)
199 write_buf
[0] = EEPROM_READ
| ((unsigned char) ((addr
& 0x100) >> 5));
200 write_buf
[1] = (addr
& 0xff);
202 if ((ret
= ifx_ssc_txrx (write_buf
, 2, buf
, eff
)) != eff
)
204 printk("ssc_txrx fails %d\n", ret
);
205 ifx_ssc_cs_high (EEPROM_CS
);
213 if ((ret
= ifx_ssc_cs_high(EEPROM_CS
)))
216 local_irq_restore(flag
);
223 local_irq_restore (flag
);
229 eeprom_write (unsigned int addr
, unsigned char *buf
, unsigned int len
)
232 unsigned int eff
= 0;
233 unsigned char write_buf
[2];
235 unsigned char rx_buf
[EEPROM_PAGE_SIZE
];
241 if ((ret
= eeprom_wren()))
243 printk("eeprom_wren fails\n");
247 write_buf
[0] = EEPROM_WRITE
| ((unsigned char) ((addr
& 0x100) >> 5));
248 write_buf
[1] = (addr
& 0xff);
250 eff
= EEPROM_PAGE_SIZE
- (addr
% EEPROM_PAGE_SIZE
);
251 eff
= (eff
< len
) ? eff
: len
;
253 printk("EEPROM Write:\n");
254 for (i
= 0; i
< eff
; i
++) {
255 printk("%2x ", buf
[i
]);
261 if ((ret
= ifx_ssc_cs_low(EEPROM_CS
)))
264 if ((ret
= ifx_ssc_tx (write_buf
, 2)) < 0)
266 printk("ssc_tx fails %d\n", ret
);
267 ifx_ssc_cs_high(EEPROM_CS
);
271 if ((ret
= ifx_ssc_tx (buf
, eff
)) != eff
)
273 printk("ssc_tx fails %d\n", ret
);
274 ifx_ssc_cs_high(EEPROM_CS
);
282 if ((ret
= ifx_ssc_cs_high (EEPROM_CS
)))
286 eeprom_read((addr
- eff
), rx_buf
, eff
);
287 for (i
= 0; i
< eff
; i
++)
289 printk ("[%x]", rx_buf
[i
]);
302 ifxmips_eeprom_open (struct inode
*inode
, struct file
*filp
)
309 ifxmips_eeprom_close (struct inode
*inode
, struct file
*filp
)
315 ifxmips_eeprom_ioctl (struct inode
*inode
, struct file
*filp
, unsigned int cmd
, unsigned long data
)
321 ifxmips_eeprom_read (char *buf
, size_t len
, unsigned int addr
)
326 printk("addr:=%d\n", addr
);
327 printk("len:=%d\n", len
);
329 if ((addr
+ len
) > EEPROM_SIZE
)
331 printk("invalid len\n");
333 len
= EEPROM_SIZE
/ 2;
336 if ((ret
= ifx_ssc_open((struct inode
*) 0, NULL
)))
338 printk("ifxmips_eeprom_open fails\n");
342 data
= (unsigned int)IFX_SSC_MODE_RXTX
;
344 if ((ret
= ifx_ssc_ioctl((struct inode
*) 0, NULL
, IFX_SSC_RXTX_MODE_SET
, (unsigned long) &data
)))
346 printk("set RXTX mode fails\n");
350 if ((ret
= eeprom_wrsr()))
352 printk("EEPROM reset fails\n");
356 if ((ret
= eeprom_read(addr
, buf
, len
)))
358 printk("eeprom read fails\n");
363 if (ifx_ssc_close((struct inode
*) 0, NULL
))
364 printk("ifxmips_eeprom_close fails\n");
368 EXPORT_SYMBOL(ifxmips_eeprom_read
);
371 ifxmips_eeprom_fops_read (struct file
*filp
, char *ubuf
, size_t len
, loff_t
* off
)
374 unsigned char ssc_rx_buf
[EEPROM_SIZE
];
377 if (*off
>= EEPROM_SIZE
)
380 if (*off
+ len
> EEPROM_SIZE
)
381 len
= EEPROM_SIZE
- *off
;
386 local_irq_save(flag
);
388 if ((ret
= ifxmips_eeprom_read(ssc_rx_buf
, len
, *off
)) < 0)
390 printk("read fails, err=%x\n", ret
);
391 local_irq_restore(flag
);
395 if (copy_to_user((void*)ubuf
, ssc_rx_buf
, ret
) != 0)
397 local_irq_restore(flag
);
401 local_irq_restore(flag
);
408 ifxmips_eeprom_write (char *buf
, size_t len
, unsigned int addr
)
413 if ((ret
= ifx_ssc_open ((struct inode
*) 0, NULL
)))
415 printk ("ifxmips_eeprom_open fails\n");
419 data
= (unsigned int) IFX_SSC_MODE_RXTX
;
421 if ((ret
= ifx_ssc_ioctl ((struct inode
*) 0, NULL
, IFX_SSC_RXTX_MODE_SET
, (unsigned long) &data
)))
423 printk ("set RXTX mode fails\n");
427 if ((ret
= eeprom_wrsr ())) {
428 printk ("EEPROM reset fails\n");
432 if ((ret
= eeprom_write (addr
, buf
, len
))) {
433 printk ("eeprom write fails\n");
438 if (ifx_ssc_close ((struct inode
*) 0, NULL
))
439 printk ("ifxmips_eeprom_close fails\n");
443 EXPORT_SYMBOL(ifxmips_eeprom_write
);
446 ifxmips_eeprom_fops_write (struct file
*filp
, const char *ubuf
, size_t len
, loff_t
* off
)
449 unsigned char ssc_tx_buf
[EEPROM_SIZE
];
451 if (*off
>= EEPROM_SIZE
)
454 if (len
+ *off
> EEPROM_SIZE
)
455 len
= EEPROM_SIZE
- *off
;
457 if ((ret
= copy_from_user (ssc_tx_buf
, ubuf
, len
)))
460 ret
= ifxmips_eeprom_write (ssc_tx_buf
, len
, *off
);
469 ifxmips_eeprom_llseek (struct file
* filp
, loff_t off
, int whence
)
478 newpos
= filp
->f_pos
+ off
;
488 filp
->f_pos
= newpos
;
493 static struct file_operations ifxmips_eeprom_fops
= {
495 llseek
:ifxmips_eeprom_llseek
,
496 read
:ifxmips_eeprom_fops_read
,
497 write
:ifxmips_eeprom_fops_write
,
498 ioctl
:ifxmips_eeprom_ioctl
,
499 open
:ifxmips_eeprom_open
,
500 release
:ifxmips_eeprom_close
,
504 ifxmips_eeprom_init (void)
508 ifxmips_eeprom_maj
= register_chrdev(0, "eeprom", &ifxmips_eeprom_fops
);
510 if (ifxmips_eeprom_maj
< 0)
512 printk("failed to register eeprom device\n");
518 printk("ifxmips_eeprom : /dev/eeprom mayor %d\n", ifxmips_eeprom_maj
);
525 ifxmips_eeprom_cleanup_module (void)
527 /*if (unregister_chrdev (ifxmips_eeprom_maj, "eeprom")) {
528 printk ("Unable to unregister major %d for the EEPROM\n",
533 module_exit (ifxmips_eeprom_cleanup_module
);
534 module_init (ifxmips_eeprom_init
);
536 MODULE_LICENSE ("GPL");
537 MODULE_AUTHOR ("Peng Liu");
538 MODULE_DESCRIPTION ("IFAP EEPROM driver");
539 MODULE_SUPPORTED_DEVICE ("ifxmips_eeprom");