Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Silicon Labs C2 port core Linux support
0004  *
0005  *  Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
0006  *  Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/device.h>
0012 #include <linux/errno.h>
0013 #include <linux/err.h>
0014 #include <linux/kernel.h>
0015 #include <linux/ctype.h>
0016 #include <linux/delay.h>
0017 #include <linux/idr.h>
0018 #include <linux/sched.h>
0019 #include <linux/slab.h>
0020 
0021 #include <linux/c2port.h>
0022 
0023 #define DRIVER_NAME             "c2port"
0024 #define DRIVER_VERSION          "0.51.0"
0025 
0026 static DEFINE_SPINLOCK(c2port_idr_lock);
0027 static DEFINE_IDR(c2port_idr);
0028 
0029 /*
0030  * Local variables
0031  */
0032 
0033 static struct class *c2port_class;
0034 
0035 /*
0036  * C2 registers & commands defines
0037  */
0038 
0039 /* C2 registers */
0040 #define C2PORT_DEVICEID     0x00
0041 #define C2PORT_REVID        0x01
0042 #define C2PORT_FPCTL        0x02
0043 #define C2PORT_FPDAT        0xB4
0044 
0045 /* C2 interface commands */
0046 #define C2PORT_GET_VERSION  0x01
0047 #define C2PORT_DEVICE_ERASE 0x03
0048 #define C2PORT_BLOCK_READ   0x06
0049 #define C2PORT_BLOCK_WRITE  0x07
0050 #define C2PORT_PAGE_ERASE   0x08
0051 
0052 /* C2 status return codes */
0053 #define C2PORT_INVALID_COMMAND  0x00
0054 #define C2PORT_COMMAND_FAILED   0x02
0055 #define C2PORT_COMMAND_OK   0x0d
0056 
0057 /*
0058  * C2 port low level signal managements
0059  */
0060 
0061 static void c2port_reset(struct c2port_device *dev)
0062 {
0063     struct c2port_ops *ops = dev->ops;
0064 
0065     /* To reset the device we have to keep clock line low for at least
0066      * 20us.
0067      */
0068     local_irq_disable();
0069     ops->c2ck_set(dev, 0);
0070     udelay(25);
0071     ops->c2ck_set(dev, 1);
0072     local_irq_enable();
0073 
0074     udelay(1);
0075 }
0076 
0077 static void c2port_strobe_ck(struct c2port_device *dev)
0078 {
0079     struct c2port_ops *ops = dev->ops;
0080 
0081     /* During hi-low-hi transition we disable local IRQs to avoid
0082      * interructions since C2 port specification says that it must be
0083      * shorter than 5us, otherwise the microcontroller may consider
0084      * it as a reset signal!
0085      */
0086     local_irq_disable();
0087     ops->c2ck_set(dev, 0);
0088     udelay(1);
0089     ops->c2ck_set(dev, 1);
0090     local_irq_enable();
0091 
0092     udelay(1);
0093 }
0094 
0095 /*
0096  * C2 port basic functions
0097  */
0098 
0099 static void c2port_write_ar(struct c2port_device *dev, u8 addr)
0100 {
0101     struct c2port_ops *ops = dev->ops;
0102     int i;
0103 
0104     /* START field */
0105     c2port_strobe_ck(dev);
0106 
0107     /* INS field (11b, LSB first) */
0108     ops->c2d_dir(dev, 0);
0109     ops->c2d_set(dev, 1);
0110     c2port_strobe_ck(dev);
0111     ops->c2d_set(dev, 1);
0112     c2port_strobe_ck(dev);
0113 
0114     /* ADDRESS field */
0115     for (i = 0; i < 8; i++) {
0116         ops->c2d_set(dev, addr & 0x01);
0117         c2port_strobe_ck(dev);
0118 
0119         addr >>= 1;
0120     }
0121 
0122     /* STOP field */
0123     ops->c2d_dir(dev, 1);
0124     c2port_strobe_ck(dev);
0125 }
0126 
0127 static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
0128 {
0129     struct c2port_ops *ops = dev->ops;
0130     int i;
0131 
0132     /* START field */
0133     c2port_strobe_ck(dev);
0134 
0135     /* INS field (10b, LSB first) */
0136     ops->c2d_dir(dev, 0);
0137     ops->c2d_set(dev, 0);
0138     c2port_strobe_ck(dev);
0139     ops->c2d_set(dev, 1);
0140     c2port_strobe_ck(dev);
0141 
0142     /* ADDRESS field */
0143     ops->c2d_dir(dev, 1);
0144     *addr = 0;
0145     for (i = 0; i < 8; i++) {
0146         *addr >>= 1;    /* shift in 8-bit ADDRESS field LSB first */
0147 
0148         c2port_strobe_ck(dev);
0149         if (ops->c2d_get(dev))
0150             *addr |= 0x80;
0151     }
0152 
0153     /* STOP field */
0154     c2port_strobe_ck(dev);
0155 
0156     return 0;
0157 }
0158 
0159 static int c2port_write_dr(struct c2port_device *dev, u8 data)
0160 {
0161     struct c2port_ops *ops = dev->ops;
0162     int timeout, i;
0163 
0164     /* START field */
0165     c2port_strobe_ck(dev);
0166 
0167     /* INS field (01b, LSB first) */
0168     ops->c2d_dir(dev, 0);
0169     ops->c2d_set(dev, 1);
0170     c2port_strobe_ck(dev);
0171     ops->c2d_set(dev, 0);
0172     c2port_strobe_ck(dev);
0173 
0174     /* LENGTH field (00b, LSB first -> 1 byte) */
0175     ops->c2d_set(dev, 0);
0176     c2port_strobe_ck(dev);
0177     ops->c2d_set(dev, 0);
0178     c2port_strobe_ck(dev);
0179 
0180     /* DATA field */
0181     for (i = 0; i < 8; i++) {
0182         ops->c2d_set(dev, data & 0x01);
0183         c2port_strobe_ck(dev);
0184 
0185         data >>= 1;
0186     }
0187 
0188     /* WAIT field */
0189     ops->c2d_dir(dev, 1);
0190     timeout = 20;
0191     do {
0192         c2port_strobe_ck(dev);
0193         if (ops->c2d_get(dev))
0194             break;
0195 
0196         udelay(1);
0197     } while (--timeout > 0);
0198     if (timeout == 0)
0199         return -EIO;
0200 
0201     /* STOP field */
0202     c2port_strobe_ck(dev);
0203 
0204     return 0;
0205 }
0206 
0207 static int c2port_read_dr(struct c2port_device *dev, u8 *data)
0208 {
0209     struct c2port_ops *ops = dev->ops;
0210     int timeout, i;
0211 
0212     /* START field */
0213     c2port_strobe_ck(dev);
0214 
0215     /* INS field (00b, LSB first) */
0216     ops->c2d_dir(dev, 0);
0217     ops->c2d_set(dev, 0);
0218     c2port_strobe_ck(dev);
0219     ops->c2d_set(dev, 0);
0220     c2port_strobe_ck(dev);
0221 
0222     /* LENGTH field (00b, LSB first -> 1 byte) */
0223     ops->c2d_set(dev, 0);
0224     c2port_strobe_ck(dev);
0225     ops->c2d_set(dev, 0);
0226     c2port_strobe_ck(dev);
0227 
0228     /* WAIT field */
0229     ops->c2d_dir(dev, 1);
0230     timeout = 20;
0231     do {
0232         c2port_strobe_ck(dev);
0233         if (ops->c2d_get(dev))
0234             break;
0235 
0236         udelay(1);
0237     } while (--timeout > 0);
0238     if (timeout == 0)
0239         return -EIO;
0240 
0241     /* DATA field */
0242     *data = 0;
0243     for (i = 0; i < 8; i++) {
0244         *data >>= 1;    /* shift in 8-bit DATA field LSB first */
0245 
0246         c2port_strobe_ck(dev);
0247         if (ops->c2d_get(dev))
0248             *data |= 0x80;
0249     }
0250 
0251     /* STOP field */
0252     c2port_strobe_ck(dev);
0253 
0254     return 0;
0255 }
0256 
0257 static int c2port_poll_in_busy(struct c2port_device *dev)
0258 {
0259     u8 addr;
0260     int ret, timeout = 20;
0261 
0262     do {
0263         ret = (c2port_read_ar(dev, &addr));
0264         if (ret < 0)
0265             return -EIO;
0266 
0267         if (!(addr & 0x02))
0268             break;
0269 
0270         udelay(1);
0271     } while (--timeout > 0);
0272     if (timeout == 0)
0273         return -EIO;
0274 
0275     return 0;
0276 }
0277 
0278 static int c2port_poll_out_ready(struct c2port_device *dev)
0279 {
0280     u8 addr;
0281     int ret, timeout = 10000; /* erase flash needs long time... */
0282 
0283     do {
0284         ret = (c2port_read_ar(dev, &addr));
0285         if (ret < 0)
0286             return -EIO;
0287 
0288         if (addr & 0x01)
0289             break;
0290 
0291         udelay(1);
0292     } while (--timeout > 0);
0293     if (timeout == 0)
0294         return -EIO;
0295 
0296     return 0;
0297 }
0298 
0299 /*
0300  * sysfs methods
0301  */
0302 
0303 static ssize_t c2port_show_name(struct device *dev,
0304                 struct device_attribute *attr, char *buf)
0305 {
0306     struct c2port_device *c2dev = dev_get_drvdata(dev);
0307 
0308     return sprintf(buf, "%s\n", c2dev->name);
0309 }
0310 static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
0311 
0312 static ssize_t c2port_show_flash_blocks_num(struct device *dev,
0313                 struct device_attribute *attr, char *buf)
0314 {
0315     struct c2port_device *c2dev = dev_get_drvdata(dev);
0316     struct c2port_ops *ops = c2dev->ops;
0317 
0318     return sprintf(buf, "%d\n", ops->blocks_num);
0319 }
0320 static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
0321 
0322 static ssize_t c2port_show_flash_block_size(struct device *dev,
0323                 struct device_attribute *attr, char *buf)
0324 {
0325     struct c2port_device *c2dev = dev_get_drvdata(dev);
0326     struct c2port_ops *ops = c2dev->ops;
0327 
0328     return sprintf(buf, "%d\n", ops->block_size);
0329 }
0330 static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
0331 
0332 static ssize_t c2port_show_flash_size(struct device *dev,
0333                 struct device_attribute *attr, char *buf)
0334 {
0335     struct c2port_device *c2dev = dev_get_drvdata(dev);
0336     struct c2port_ops *ops = c2dev->ops;
0337 
0338     return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
0339 }
0340 static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
0341 
0342 static ssize_t access_show(struct device *dev, struct device_attribute *attr,
0343                char *buf)
0344 {
0345     struct c2port_device *c2dev = dev_get_drvdata(dev);
0346 
0347     return sprintf(buf, "%d\n", c2dev->access);
0348 }
0349 
0350 static ssize_t access_store(struct device *dev, struct device_attribute *attr,
0351                 const char *buf, size_t count)
0352 {
0353     struct c2port_device *c2dev = dev_get_drvdata(dev);
0354     struct c2port_ops *ops = c2dev->ops;
0355     int status, ret;
0356 
0357     ret = sscanf(buf, "%d", &status);
0358     if (ret != 1)
0359         return -EINVAL;
0360 
0361     mutex_lock(&c2dev->mutex);
0362 
0363     c2dev->access = !!status;
0364 
0365     /* If access is "on" clock should be HIGH _before_ setting the line
0366      * as output and data line should be set as INPUT anyway */
0367     if (c2dev->access)
0368         ops->c2ck_set(c2dev, 1);
0369     ops->access(c2dev, c2dev->access);
0370     if (c2dev->access)
0371         ops->c2d_dir(c2dev, 1);
0372 
0373     mutex_unlock(&c2dev->mutex);
0374 
0375     return count;
0376 }
0377 static DEVICE_ATTR_RW(access);
0378 
0379 static ssize_t c2port_store_reset(struct device *dev,
0380                 struct device_attribute *attr,
0381                 const char *buf, size_t count)
0382 {
0383     struct c2port_device *c2dev = dev_get_drvdata(dev);
0384 
0385     /* Check the device access status */
0386     if (!c2dev->access)
0387         return -EBUSY;
0388 
0389     mutex_lock(&c2dev->mutex);
0390 
0391     c2port_reset(c2dev);
0392     c2dev->flash_access = 0;
0393 
0394     mutex_unlock(&c2dev->mutex);
0395 
0396     return count;
0397 }
0398 static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
0399 
0400 static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
0401 {
0402     u8 data;
0403     int ret;
0404 
0405     /* Select DEVICEID register for C2 data register accesses */
0406     c2port_write_ar(dev, C2PORT_DEVICEID);
0407 
0408     /* Read and return the device ID register */
0409     ret = c2port_read_dr(dev, &data);
0410     if (ret < 0)
0411         return ret;
0412 
0413     return sprintf(buf, "%d\n", data);
0414 }
0415 
0416 static ssize_t c2port_show_dev_id(struct device *dev,
0417                 struct device_attribute *attr, char *buf)
0418 {
0419     struct c2port_device *c2dev = dev_get_drvdata(dev);
0420     ssize_t ret;
0421 
0422     /* Check the device access status */
0423     if (!c2dev->access)
0424         return -EBUSY;
0425 
0426     mutex_lock(&c2dev->mutex);
0427     ret = __c2port_show_dev_id(c2dev, buf);
0428     mutex_unlock(&c2dev->mutex);
0429 
0430     if (ret < 0)
0431         dev_err(dev, "cannot read from %s\n", c2dev->name);
0432 
0433     return ret;
0434 }
0435 static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
0436 
0437 static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
0438 {
0439     u8 data;
0440     int ret;
0441 
0442     /* Select REVID register for C2 data register accesses */
0443     c2port_write_ar(dev, C2PORT_REVID);
0444 
0445     /* Read and return the revision ID register */
0446     ret = c2port_read_dr(dev, &data);
0447     if (ret < 0)
0448         return ret;
0449 
0450     return sprintf(buf, "%d\n", data);
0451 }
0452 
0453 static ssize_t c2port_show_rev_id(struct device *dev,
0454                 struct device_attribute *attr, char *buf)
0455 {
0456     struct c2port_device *c2dev = dev_get_drvdata(dev);
0457     ssize_t ret;
0458 
0459     /* Check the device access status */
0460     if (!c2dev->access)
0461         return -EBUSY;
0462 
0463     mutex_lock(&c2dev->mutex);
0464     ret = __c2port_show_rev_id(c2dev, buf);
0465     mutex_unlock(&c2dev->mutex);
0466 
0467     if (ret < 0)
0468         dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
0469 
0470     return ret;
0471 }
0472 static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
0473 
0474 static ssize_t c2port_show_flash_access(struct device *dev,
0475                 struct device_attribute *attr, char *buf)
0476 {
0477     struct c2port_device *c2dev = dev_get_drvdata(dev);
0478 
0479     return sprintf(buf, "%d\n", c2dev->flash_access);
0480 }
0481 
0482 static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
0483                         int status)
0484 {
0485     int ret;
0486 
0487     /* Check the device access status */
0488     if (!dev->access)
0489         return -EBUSY;
0490 
0491     dev->flash_access = !!status;
0492 
0493     /* If flash_access is off we have nothing to do... */
0494     if (dev->flash_access == 0)
0495         return 0;
0496 
0497     /* Target the C2 flash programming control register for C2 data
0498      * register access */
0499     c2port_write_ar(dev, C2PORT_FPCTL);
0500 
0501     /* Write the first keycode to enable C2 Flash programming */
0502     ret = c2port_write_dr(dev, 0x02);
0503     if (ret < 0)
0504         return ret;
0505 
0506     /* Write the second keycode to enable C2 Flash programming */
0507     ret = c2port_write_dr(dev, 0x01);
0508     if (ret < 0)
0509         return ret;
0510 
0511     /* Delay for at least 20ms to ensure the target is ready for
0512      * C2 flash programming */
0513     mdelay(25);
0514 
0515     return 0;
0516 }
0517 
0518 static ssize_t c2port_store_flash_access(struct device *dev,
0519                 struct device_attribute *attr,
0520                 const char *buf, size_t count)
0521 {
0522     struct c2port_device *c2dev = dev_get_drvdata(dev);
0523     int status;
0524     ssize_t ret;
0525 
0526     ret = sscanf(buf, "%d", &status);
0527     if (ret != 1)
0528         return -EINVAL;
0529 
0530     mutex_lock(&c2dev->mutex);
0531     ret = __c2port_store_flash_access(c2dev, status);
0532     mutex_unlock(&c2dev->mutex);
0533 
0534     if (ret < 0) {
0535         dev_err(c2dev->dev, "cannot enable %s flash programming\n",
0536             c2dev->name);
0537         return ret;
0538     }
0539 
0540     return count;
0541 }
0542 static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
0543            c2port_store_flash_access);
0544 
0545 static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
0546 {
0547     u8 status;
0548     int ret;
0549 
0550     /* Target the C2 flash programming data register for C2 data register
0551      * access.
0552      */
0553     c2port_write_ar(dev, C2PORT_FPDAT);
0554 
0555     /* Send device erase command */
0556     c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
0557 
0558     /* Wait for input acknowledge */
0559     ret = c2port_poll_in_busy(dev);
0560     if (ret < 0)
0561         return ret;
0562 
0563     /* Should check status before starting FLASH access sequence */
0564 
0565     /* Wait for status information */
0566     ret = c2port_poll_out_ready(dev);
0567     if (ret < 0)
0568         return ret;
0569 
0570     /* Read flash programming interface status */
0571     ret = c2port_read_dr(dev, &status);
0572     if (ret < 0)
0573         return ret;
0574     if (status != C2PORT_COMMAND_OK)
0575         return -EBUSY;
0576 
0577     /* Send a three-byte arming sequence to enable the device erase.
0578      * If the sequence is not received correctly, the command will be
0579      * ignored.
0580      * Sequence is: 0xde, 0xad, 0xa5.
0581      */
0582     c2port_write_dr(dev, 0xde);
0583     ret = c2port_poll_in_busy(dev);
0584     if (ret < 0)
0585         return ret;
0586     c2port_write_dr(dev, 0xad);
0587     ret = c2port_poll_in_busy(dev);
0588     if (ret < 0)
0589         return ret;
0590     c2port_write_dr(dev, 0xa5);
0591     ret = c2port_poll_in_busy(dev);
0592     if (ret < 0)
0593         return ret;
0594 
0595     ret = c2port_poll_out_ready(dev);
0596     if (ret < 0)
0597         return ret;
0598 
0599     return 0;
0600 }
0601 
0602 static ssize_t c2port_store_flash_erase(struct device *dev,
0603                 struct device_attribute *attr,
0604                 const char *buf, size_t count)
0605 {
0606     struct c2port_device *c2dev = dev_get_drvdata(dev);
0607     int ret;
0608 
0609     /* Check the device and flash access status */
0610     if (!c2dev->access || !c2dev->flash_access)
0611         return -EBUSY;
0612 
0613     mutex_lock(&c2dev->mutex);
0614     ret = __c2port_write_flash_erase(c2dev);
0615     mutex_unlock(&c2dev->mutex);
0616 
0617     if (ret < 0) {
0618         dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
0619         return ret;
0620     }
0621 
0622     return count;
0623 }
0624 static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
0625 
0626 static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
0627                 char *buffer, loff_t offset, size_t count)
0628 {
0629     struct c2port_ops *ops = dev->ops;
0630     u8 status, nread = 128;
0631     int i, ret;
0632 
0633     /* Check for flash end */
0634     if (offset >= ops->block_size * ops->blocks_num)
0635         return 0;
0636 
0637     if (ops->block_size * ops->blocks_num - offset < nread)
0638         nread = ops->block_size * ops->blocks_num - offset;
0639     if (count < nread)
0640         nread = count;
0641     if (nread == 0)
0642         return nread;
0643 
0644     /* Target the C2 flash programming data register for C2 data register
0645      * access */
0646     c2port_write_ar(dev, C2PORT_FPDAT);
0647 
0648     /* Send flash block read command */
0649     c2port_write_dr(dev, C2PORT_BLOCK_READ);
0650 
0651     /* Wait for input acknowledge */
0652     ret = c2port_poll_in_busy(dev);
0653     if (ret < 0)
0654         return ret;
0655 
0656     /* Should check status before starting FLASH access sequence */
0657 
0658     /* Wait for status information */
0659     ret = c2port_poll_out_ready(dev);
0660     if (ret < 0)
0661         return ret;
0662 
0663     /* Read flash programming interface status */
0664     ret = c2port_read_dr(dev, &status);
0665     if (ret < 0)
0666         return ret;
0667     if (status != C2PORT_COMMAND_OK)
0668         return -EBUSY;
0669 
0670     /* Send address high byte */
0671     c2port_write_dr(dev, offset >> 8);
0672     ret = c2port_poll_in_busy(dev);
0673     if (ret < 0)
0674         return ret;
0675 
0676     /* Send address low byte */
0677     c2port_write_dr(dev, offset & 0x00ff);
0678     ret = c2port_poll_in_busy(dev);
0679     if (ret < 0)
0680         return ret;
0681 
0682     /* Send address block size */
0683     c2port_write_dr(dev, nread);
0684     ret = c2port_poll_in_busy(dev);
0685     if (ret < 0)
0686         return ret;
0687 
0688     /* Should check status before reading FLASH block */
0689 
0690     /* Wait for status information */
0691     ret = c2port_poll_out_ready(dev);
0692     if (ret < 0)
0693         return ret;
0694 
0695     /* Read flash programming interface status */
0696     ret = c2port_read_dr(dev, &status);
0697     if (ret < 0)
0698         return ret;
0699     if (status != C2PORT_COMMAND_OK)
0700         return -EBUSY;
0701 
0702     /* Read flash block */
0703     for (i = 0; i < nread; i++) {
0704         ret = c2port_poll_out_ready(dev);
0705         if (ret < 0)
0706             return ret;
0707 
0708         ret = c2port_read_dr(dev, buffer+i);
0709         if (ret < 0)
0710             return ret;
0711     }
0712 
0713     return nread;
0714 }
0715 
0716 static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
0717                 struct bin_attribute *attr,
0718                 char *buffer, loff_t offset, size_t count)
0719 {
0720     struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
0721     ssize_t ret;
0722 
0723     /* Check the device and flash access status */
0724     if (!c2dev->access || !c2dev->flash_access)
0725         return -EBUSY;
0726 
0727     mutex_lock(&c2dev->mutex);
0728     ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
0729     mutex_unlock(&c2dev->mutex);
0730 
0731     if (ret < 0)
0732         dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
0733 
0734     return ret;
0735 }
0736 
0737 static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
0738                 char *buffer, loff_t offset, size_t count)
0739 {
0740     struct c2port_ops *ops = dev->ops;
0741     u8 status, nwrite = 128;
0742     int i, ret;
0743 
0744     if (nwrite > count)
0745         nwrite = count;
0746     if (ops->block_size * ops->blocks_num - offset < nwrite)
0747         nwrite = ops->block_size * ops->blocks_num - offset;
0748 
0749     /* Check for flash end */
0750     if (offset >= ops->block_size * ops->blocks_num)
0751         return -EINVAL;
0752 
0753     /* Target the C2 flash programming data register for C2 data register
0754      * access */
0755     c2port_write_ar(dev, C2PORT_FPDAT);
0756 
0757     /* Send flash block write command */
0758     c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
0759 
0760     /* Wait for input acknowledge */
0761     ret = c2port_poll_in_busy(dev);
0762     if (ret < 0)
0763         return ret;
0764 
0765     /* Should check status before starting FLASH access sequence */
0766 
0767     /* Wait for status information */
0768     ret = c2port_poll_out_ready(dev);
0769     if (ret < 0)
0770         return ret;
0771 
0772     /* Read flash programming interface status */
0773     ret = c2port_read_dr(dev, &status);
0774     if (ret < 0)
0775         return ret;
0776     if (status != C2PORT_COMMAND_OK)
0777         return -EBUSY;
0778 
0779     /* Send address high byte */
0780     c2port_write_dr(dev, offset >> 8);
0781     ret = c2port_poll_in_busy(dev);
0782     if (ret < 0)
0783         return ret;
0784 
0785     /* Send address low byte */
0786     c2port_write_dr(dev, offset & 0x00ff);
0787     ret = c2port_poll_in_busy(dev);
0788     if (ret < 0)
0789         return ret;
0790 
0791     /* Send address block size */
0792     c2port_write_dr(dev, nwrite);
0793     ret = c2port_poll_in_busy(dev);
0794     if (ret < 0)
0795         return ret;
0796 
0797     /* Should check status before writing FLASH block */
0798 
0799     /* Wait for status information */
0800     ret = c2port_poll_out_ready(dev);
0801     if (ret < 0)
0802         return ret;
0803 
0804     /* Read flash programming interface status */
0805     ret = c2port_read_dr(dev, &status);
0806     if (ret < 0)
0807         return ret;
0808     if (status != C2PORT_COMMAND_OK)
0809         return -EBUSY;
0810 
0811     /* Write flash block */
0812     for (i = 0; i < nwrite; i++) {
0813         ret = c2port_write_dr(dev, *(buffer+i));
0814         if (ret < 0)
0815             return ret;
0816 
0817         ret = c2port_poll_in_busy(dev);
0818         if (ret < 0)
0819             return ret;
0820 
0821     }
0822 
0823     /* Wait for last flash write to complete */
0824     ret = c2port_poll_out_ready(dev);
0825     if (ret < 0)
0826         return ret;
0827 
0828     return nwrite;
0829 }
0830 
0831 static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
0832                 struct bin_attribute *attr,
0833                 char *buffer, loff_t offset, size_t count)
0834 {
0835     struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
0836     int ret;
0837 
0838     /* Check the device access status */
0839     if (!c2dev->access || !c2dev->flash_access)
0840         return -EBUSY;
0841 
0842     mutex_lock(&c2dev->mutex);
0843     ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
0844     mutex_unlock(&c2dev->mutex);
0845 
0846     if (ret < 0)
0847         dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
0848 
0849     return ret;
0850 }
0851 /* size is computed at run-time */
0852 static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
0853         c2port_write_flash_data, 0);
0854 
0855 /*
0856  * Class attributes
0857  */
0858 static struct attribute *c2port_attrs[] = {
0859     &dev_attr_name.attr,
0860     &dev_attr_flash_blocks_num.attr,
0861     &dev_attr_flash_block_size.attr,
0862     &dev_attr_flash_size.attr,
0863     &dev_attr_access.attr,
0864     &dev_attr_reset.attr,
0865     &dev_attr_dev_id.attr,
0866     &dev_attr_rev_id.attr,
0867     &dev_attr_flash_access.attr,
0868     &dev_attr_flash_erase.attr,
0869     NULL,
0870 };
0871 
0872 static struct bin_attribute *c2port_bin_attrs[] = {
0873     &bin_attr_flash_data,
0874     NULL,
0875 };
0876 
0877 static const struct attribute_group c2port_group = {
0878     .attrs = c2port_attrs,
0879     .bin_attrs = c2port_bin_attrs,
0880 };
0881 
0882 static const struct attribute_group *c2port_groups[] = {
0883     &c2port_group,
0884     NULL,
0885 };
0886 
0887 /*
0888  * Exported functions
0889  */
0890 
0891 struct c2port_device *c2port_device_register(char *name,
0892                     struct c2port_ops *ops, void *devdata)
0893 {
0894     struct c2port_device *c2dev;
0895     int ret;
0896 
0897     if (unlikely(!ops) || unlikely(!ops->access) || \
0898         unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
0899         unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
0900         return ERR_PTR(-EINVAL);
0901 
0902     c2dev = kzalloc(sizeof(struct c2port_device), GFP_KERNEL);
0903     if (unlikely(!c2dev))
0904         return ERR_PTR(-ENOMEM);
0905 
0906     idr_preload(GFP_KERNEL);
0907     spin_lock_irq(&c2port_idr_lock);
0908     ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
0909     spin_unlock_irq(&c2port_idr_lock);
0910     idr_preload_end();
0911 
0912     if (ret < 0)
0913         goto error_idr_alloc;
0914     c2dev->id = ret;
0915 
0916     bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
0917 
0918     c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
0919                    "c2port%d", c2dev->id);
0920     if (IS_ERR(c2dev->dev)) {
0921         ret = PTR_ERR(c2dev->dev);
0922         goto error_device_create;
0923     }
0924     dev_set_drvdata(c2dev->dev, c2dev);
0925 
0926     strncpy(c2dev->name, name, C2PORT_NAME_LEN - 1);
0927     c2dev->ops = ops;
0928     mutex_init(&c2dev->mutex);
0929 
0930     /* By default C2 port access is off */
0931     c2dev->access = c2dev->flash_access = 0;
0932     ops->access(c2dev, 0);
0933 
0934     dev_info(c2dev->dev, "C2 port %s added\n", name);
0935     dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
0936                 "(%d bytes total)\n",
0937                 name, ops->blocks_num, ops->block_size,
0938                 ops->blocks_num * ops->block_size);
0939 
0940     return c2dev;
0941 
0942 error_device_create:
0943     spin_lock_irq(&c2port_idr_lock);
0944     idr_remove(&c2port_idr, c2dev->id);
0945     spin_unlock_irq(&c2port_idr_lock);
0946 
0947 error_idr_alloc:
0948     kfree(c2dev);
0949 
0950     return ERR_PTR(ret);
0951 }
0952 EXPORT_SYMBOL(c2port_device_register);
0953 
0954 void c2port_device_unregister(struct c2port_device *c2dev)
0955 {
0956     if (!c2dev)
0957         return;
0958 
0959     dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
0960 
0961     spin_lock_irq(&c2port_idr_lock);
0962     idr_remove(&c2port_idr, c2dev->id);
0963     spin_unlock_irq(&c2port_idr_lock);
0964 
0965     device_destroy(c2port_class, c2dev->id);
0966 
0967     kfree(c2dev);
0968 }
0969 EXPORT_SYMBOL(c2port_device_unregister);
0970 
0971 /*
0972  * Module stuff
0973  */
0974 
0975 static int __init c2port_init(void)
0976 {
0977     printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
0978         " - (C) 2007 Rodolfo Giometti\n");
0979 
0980     c2port_class = class_create(THIS_MODULE, "c2port");
0981     if (IS_ERR(c2port_class)) {
0982         printk(KERN_ERR "c2port: failed to allocate class\n");
0983         return PTR_ERR(c2port_class);
0984     }
0985     c2port_class->dev_groups = c2port_groups;
0986 
0987     return 0;
0988 }
0989 
0990 static void __exit c2port_exit(void)
0991 {
0992     class_destroy(c2port_class);
0993 }
0994 
0995 module_init(c2port_init);
0996 module_exit(c2port_exit);
0997 
0998 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
0999 MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
1000 MODULE_LICENSE("GPL");