thanks steve,

i have a doubt that why the eeprom is mtd2?


2008-12-25 



Jammy Dane 



发件人: Steve Chen 
发送时间: 2008-12-24  22:33:20 
收件人: Jammy Dane 
抄送: gasparini; BJ_Opp; davinci-linux-open-source 
主题: Re: FW: dm355 spi 
 
Jammy,
You can use echo/cat to /dev/mtd(x) to write to SPI EEPROM and
strings /dev/mtd(x) to read (determine the proper value of x using
'cat /proc/mtd' of course).  Alternatively, attached are a couple of
simple programs I used to read/write to SPI EEPROM.  Hopefully it would
be helpful to get you started.
Regards,
Steve
On Wed, 2008-12-24 at 21:34 +0800, Jammy Dane wrote:
> Hi, I want use spi in dm355 evm, there is a driver like
> at25xxA_eeprom.c, but there is no example for that, if i want to write
> data to the eeprom or if i want to read data from it, how can use the
> function? what is the process of writing or reading? may you give me
> some advice, and thank you.
> Below is the c code in mtd/devices/at25xxA_eeprom.c:
>  
> #include <linux/module.h>
> #include <linux/init.h>
> #include <linux/types.h>
> #include <linux/device.h>
> #include <linux/spi/spi.h>
> 
> #include <linux/mtd/mtd.h>
> #include <linux/mtd/partitions.h>
> 
> #include <asm/uaccess.h>
> 
> #include <linux/spi/at25xxA_eeprom.h> 
> #include <linux/spi/dm355_spi_master.h>
> 
> static struct davinci_eeprom_info *spi_eeprom_info;
> 
> /*
>  *  Utilities functions
>  */
> struct davinci_eeprom_info dm355_spi_eeprom_info = {
> .eeprom_size = 8192,
> .page_size = 32,
> .page_mask = 0x001F,
> .chip_sel = SCS0_SELECT,
> };
> 
> #if 0
> static int spi_generic_eeprom_open(struct inode * inode, struct file * file)
> {
> file->private_data = spi_eeprom_info;
> return 0;
> }
> 
> static int spi_generic_eeprom_ioctl(struct inode *inode, struct file *file,
>                     unsigned int cmd, unsigned long arg)
> {
> return 0;
> }
> #endif
> static int spi_generic_config(dm355_spi_config_t *spi_cfg)
> {
> if (spi_cfg == NULL) {
> printk("spi_cfg = NULL\n");
> return -1;
> }
> 
> spi_cfg->clkInternal = TRUE;
> spi_cfg->csHold = TRUE;
> spi_cfg->intrLevel = FALSE;
> spi_cfg->pinOpModes = SPI_OPMODE_SPISCS_4PIN;
> spi_cfg->clkHigh = FALSE;
> spi_cfg->lsbFirst = FALSE;
> spi_cfg->parityEnable = TRUE;
> spi_cfg->oddParity = FALSE;
> spi_cfg->phaseIn = TRUE;
> spi_cfg->op_mode = TRUE; /*Polling mode -> FALSE, Interrupt mode -> TRUE */
> spi_cfg->loopBack = FALSE; /* loopback is disabled */
> 
> }
> static int spi_generic_eeprom_read(struct mtd_info *mtd, loff_t from, 
> size_t count, size_t *retlen, u_char *buf)
> {
> u8 *tx_ptr, *rx_ptr;
> int rx_cnt;
> unsigned int addr;
> unsigned long flags;
> struct spi_transfer x[2];
> struct spi_message msg;
> struct davinci_eeprom_info *priv_dat = mtd->priv;
> 
> addr = (u16)from;
> *retlen = 0;
> if(addr > priv_dat->eeprom_size)
> return -EINVAL;
> 
> if (count > priv_dat->eeprom_size)
> return -EINVAL;
> 
> if((addr + count) > priv_dat->eeprom_size)
> return -EINVAL;
> 
> memset(x, 0, sizeof x);
> down(&priv_dat->lock);
> x[0].tx_buf = tx_ptr = priv_dat->tx_buffer;
> 
> tx_ptr[0] = DM355_EEPROM_READ;
> 
> x[0].len = 3;
> 
> /* Handle data return from EEPROM */
> x[1].rx_buf = rx_ptr = priv_dat->rx_buffer;
> 
> while (count > 0) {
> if (likely(count > SPI_BUFFER_SIZE))
> rx_cnt = SPI_BUFFER_SIZE;
> else
> rx_cnt = count;
> 
> spi_message_init(&msg);
> /* setup read command */
> tx_ptr[1] = (addr >> 8) & 0xFF;
> tx_ptr[2] = (addr & 0xFF);
> 
> local_irq_save(flags);
> spi_message_add_tail(&x[0], &msg);
> 
> /* read the eeprom */
> x[1].len = rx_cnt;
> spi_message_add_tail(&x[1], &msg);
> local_irq_restore(flags);
> 
> spi_sync(priv_dat->spi, &msg);
> 
> //spi_read(priv_dat->spi, rx_ptr, rx_cnt);
> memcpy(buf, rx_ptr, rx_cnt);
> 
> buf += rx_cnt;
> count -= rx_cnt;
> addr += rx_cnt;
> *retlen += rx_cnt;
> }
> up(&priv_dat->lock);
> 
> return 0;
> }
> 
> static int spi_generic_eeprom_write (struct mtd_info *mtd, loff_t to, 
> size_t count, size_t *retlen, const u_char *buf)
> {
> char *ptr;
> int status;
> int tx_cnt;
> unsigned int  addr;
> struct spi_transfer xfer[2];
> struct spi_message msg;
> struct davinci_eeprom_info *priv_dat = mtd->priv;
> unsigned long flags;
> 
> addr = (u16)(to);
> *retlen = 0;
> memset(xfer, 0, sizeof xfer);
> if(addr > priv_dat->eeprom_size)
> return -EINVAL;
> 
> if (count > priv_dat->eeprom_size)
> return -EINVAL;
> 
> if((addr + count) > priv_dat->eeprom_size)
> return -EINVAL;
> 
> down(&priv_dat->lock);
> while(count > 0) {
> xfer[0].tx_buf = ptr = priv_dat->tx_buffer;
> 
> /* set write enable */
> ptr[0] = DM355_EEPROM_WREN;
> spi_write(priv_dat->spi, ptr, 1);
> 
> spi_message_init(&msg);
> /* set the write command */
> ptr[0] = DM355_EEPROM_WRITE;
> ptr[1] = (addr >> 8) & 0xFF;
> ptr[2] = (addr & 0xFF);
> xfer[0].len = DAVINCI_SPI_TX_CMD_SIZE;
> local_irq_save(flags);
> //spi_message_add_tail(&xfer[0], &msg);
> 
> /* figure out the max transfer within a page */
> tx_cnt = priv_dat->page_size - (addr & priv_dat->page_mask);
> //if((tx_cnt + DAVINCI_SPI_TX_CMD_SIZE) > SPI_BUFFER_SIZE)
> // tx_cnt = SPI_BUFFER_SIZE - DAVINCI_SPI_TX_CMD_SIZE;
> 
> if (count < tx_cnt)
> tx_cnt = count;
> 
> ptr = &priv_dat->tx_buffer[DAVINCI_SPI_TX_CMD_SIZE];
> //xfer[1].tx_buf = ptr;
> xfer[0].len += tx_cnt;
> memcpy(ptr, buf, tx_cnt);
> //spi_write(priv_dat->spi, ptr, tx_cnt + DAVINCI_SPI_TX_CMD_SIZE);
> spi_message_add_tail(&xfer[0], &msg);
> local_irq_restore(flags);
> status = spi_sync(priv_dat->spi, &msg);
> 
> count -= tx_cnt;
> buf += tx_cnt;
> addr += tx_cnt;
> *retlen += tx_cnt;
> }
> up(&priv_dat->lock);
> 
> return (0);
> }
> 
> #if 0
> static int spi_generic_eeprom_release(struct inode * inode, struct file * 
> file)
> {
> return 0;
> }
> 
> struct file_operations spi_eeprom_ops = {
> 
> .owner = THIS_MODULE,
> .open = spi_generic_eeprom_open,
> .ioctl = spi_generic_eeprom_ioctl,
> .read = spi_generic_eeprom_read,
> .write = spi_generic_eeprom_write,
> .release = spi_generic_eeprom_release,
> 
> };
> #endif
> 
> static int spi_eeprom_generic_erase(struct mtd_info *mtd, 
> struct erase_info *instr)
> {
> *mtd;
> *instr;
> }
> 
> static struct mtd_info davinci_at25;
> static int __devinit eeprom_probe(struct spi_device *spi)
> {
> int ret;
> static struct mtd_info *mtd;
> 
> mtd = &davinci_at25;
> memset(mtd, 0, sizeof(struct mtd_info));
> 
> /* are there any id we need to read? */
> spi_eeprom_info = &dm355_spi_eeprom_info;
> spi_eeprom_info->spi = spi;
> spi_generic_config(spi->controller_data);
> spi_eeprom_info->spi_data = spi_master_get_devdata(spi->master);
> init_MUTEX(&spi_eeprom_info->lock);
> 
> mtd->priv = spi_eeprom_info;
> mtd->size = spi_eeprom_info->eeprom_size;
> mtd->flags = MTD_CAP_RAM;
> mtd->read = spi_generic_eeprom_read;
> mtd->write = spi_generic_eeprom_write;
> mtd->erase = spi_eeprom_generic_erase;
> mtd->type = MTD_RAM;
> mtd->name = "spi_eeprom";
> mtd->erasesize = 0x10;
> 
> ret = add_mtd_device(mtd);
> //ret = register_chrdev(SPI_EEPROM_MAJOR, DAVINCI_SPI_EEPROM_NAME, 
> // &spi_eeprom_ops);
> if (ret < 0) {
> printk("at25xxA_spi_eeprom device register failed\n");
> }
> printk("at25xxA_spi_eeprom device register Succeeded\n");
> return ret;
> }
> 
> static struct spi_driver spi_eeprom_driver = {
>         .driver = {
>                 .name           = DAVINCI_SPI_EEPROM_NAME,
>                 .bus            = &spi_bus_type,
>                 .owner          = THIS_MODULE,
>         },
>         .probe          = eeprom_probe,
> /* since eeprom is soldered on, we don't need to worry about remove */
> };
> 
> static int __init spi_eeprom_init(void)
> {
> printk("at25xxA_spi_eeprom init \n");
>         return spi_register_driver(&spi_eeprom_driver);
> }
> module_init(spi_eeprom_init);
> 
> static void __exit spi_eeprom_exit(void)
> {
> printk("at25xxA_spi_eeprom exit \n");
>         spi_unregister_driver(&spi_eeprom_driver);
> }
> module_exit(spi_eeprom_exit);
> 
> MODULE_LICENSE("GPL");
> MODULE_AUTHOR("Steve Chen");
> MODULE_DESCRIPTION("SPI EEPROM driver");
>  
> 2008-12-24 
> 
> ______________________________________________________________________
> Jammy Dane 
> _______________________________________________
> Davinci-linux-open-source mailing list
> [email protected]
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to