static ssize_t __c2port_store_flash_access(struct c2port_device *dev, int status) { int ret; /* Check the device access status */ if (!dev->access) return -EBUSY; dev->flash_access = !!status; /* If flash_access is off we have nothing to do... */ if (dev->flash_access == 0) return 0; /* Target the C2 flash programming control register for C2 data * register access */ c2port_write_ar(dev, C2PORT_FPCTL); /* Write the first keycode to enable C2 Flash programming */ ret = c2port_write_dr(dev, 0x02); if (ret < 0) return ret; /* Write the second keycode to enable C2 Flash programming */ ret = c2port_write_dr(dev, 0x01); if (ret < 0) return ret; /* Delay for at least 20ms to ensure the target is ready for * C2 flash programming */ mdelay(25); return 0; }
static ssize_t __c2port_store_flash_access(struct c2port_device *dev, int status) { int ret; if (!dev->access) return -EBUSY; dev->flash_access = !!status; if (dev->flash_access == 0) return 0; c2port_write_ar(dev, C2PORT_FPCTL); ret = c2port_write_dr(dev, 0x02); if (ret < 0) return ret; ret = c2port_write_dr(dev, 0x01); if (ret < 0) return ret; mdelay(25); return 0; }
static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) { u8 status; int ret; /* Target the C2 flash programming data register for C2 data register * access. */ c2port_write_ar(dev, C2PORT_FPDAT); /* Send device erase command */ c2port_write_dr(dev, C2PORT_DEVICE_ERASE); /* Wait for input acknowledge */ ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Should check status before starting FLASH access sequence */ /* Wait for status information */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; /* Read flash programming interface status */ ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; /* Send a three-byte arming sequence to enable the device erase. * If the sequence is not received correctly, the command will be * ignored. * Sequence is: 0xde, 0xad, 0xa5. */ c2port_write_dr(dev, 0xde); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, 0xad); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, 0xa5); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; return 0; }
static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) { u8 status; int ret; c2port_write_ar(dev, C2PORT_FPDAT); c2port_write_dr(dev, C2PORT_DEVICE_ERASE); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; c2port_write_dr(dev, 0xde); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, 0xad); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, 0xa5); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; return 0; }
static ssize_t __c2port_write_flash_data(struct c2port_device *dev, char *buffer, loff_t offset, size_t count) { struct c2port_ops *ops = dev->ops; u8 status, nwrite = 128; int i, ret; if (nwrite > count) nwrite = count; if (ops->block_size * ops->blocks_num - offset < nwrite) nwrite = ops->block_size * ops->blocks_num - offset; /* Check for flash end */ if (offset >= ops->block_size * ops->blocks_num) return -EINVAL; /* Target the C2 flash programming data register for C2 data register * access */ c2port_write_ar(dev, C2PORT_FPDAT); /* Send flash block write command */ c2port_write_dr(dev, C2PORT_BLOCK_WRITE); /* Wait for input acknowledge */ ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Should check status before starting FLASH access sequence */ /* Wait for status information */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; /* Read flash programming interface status */ ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; /* Send address high byte */ c2port_write_dr(dev, offset >> 8); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Send address low byte */ c2port_write_dr(dev, offset & 0x00ff); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Send address block size */ c2port_write_dr(dev, nwrite); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Should check status before writing FLASH block */ /* Wait for status information */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; /* Read flash programming interface status */ ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; /* Write flash block */ for (i = 0; i < nwrite; i++) { ret = c2port_write_dr(dev, *(buffer+i)); if (ret < 0) return ret; ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; } /* Wait for last flash write to complete */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; return nwrite; }
static ssize_t __c2port_write_flash_data(struct c2port_device *dev, char *buffer, loff_t offset, size_t count) { struct c2port_ops *ops = dev->ops; u8 status, nwrite = 128; int i, ret; if (nwrite > count) nwrite = count; if (ops->block_size * ops->blocks_num - offset < nwrite) nwrite = ops->block_size * ops->blocks_num - offset; if (offset >= ops->block_size * ops->blocks_num) return -EINVAL; c2port_write_ar(dev, C2PORT_FPDAT); c2port_write_dr(dev, C2PORT_BLOCK_WRITE); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; c2port_write_dr(dev, offset >> 8); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, offset & 0x00ff); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; c2port_write_dr(dev, nwrite); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; for (i = 0; i < nwrite; i++) { ret = c2port_write_dr(dev, *(buffer+i)); if (ret < 0) return ret; ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; } ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; return nwrite; }
static ssize_t __c2port_read_flash_data(struct c2port_device *dev, char *buffer, loff_t offset, size_t count) { struct c2port_ops *ops = dev->ops; u8 status, nread = 128; int i, ret; /* Check for flash end */ if (offset >= ops->block_size * ops->blocks_num) return 0; if (ops->block_size * ops->blocks_num - offset < nread) nread = ops->block_size * ops->blocks_num - offset; if (count < nread) nread = count; if (nread == 0) return nread; /* Target the C2 flash programming data register for C2 data register * access */ c2port_write_ar(dev, C2PORT_FPDAT); /* Send flash block read command */ c2port_write_dr(dev, C2PORT_BLOCK_READ); /* Wait for input acknowledge */ ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Should check status before starting FLASH access sequence */ /* Wait for status information */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; /* Read flash programming interface status */ ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; /* Send address high byte */ c2port_write_dr(dev, offset >> 8); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Send address low byte */ c2port_write_dr(dev, offset & 0x00ff); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Send address block size */ c2port_write_dr(dev, nread); ret = c2port_poll_in_busy(dev); if (ret < 0) return ret; /* Should check status before reading FLASH block */ /* Wait for status information */ ret = c2port_poll_out_ready(dev); if (ret < 0) return ret; /* Read flash programming interface status */ ret = c2port_read_dr(dev, &status); if (ret < 0) return ret; if (status != C2PORT_COMMAND_OK) return -EBUSY; /