root/drivers/misc/c2port/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. c2port_reset
  2. c2port_strobe_ck
  3. c2port_write_ar
  4. c2port_read_ar
  5. c2port_write_dr
  6. c2port_read_dr
  7. c2port_poll_in_busy
  8. c2port_poll_out_ready
  9. c2port_show_name
  10. c2port_show_flash_blocks_num
  11. c2port_show_flash_block_size
  12. c2port_show_flash_size
  13. access_show
  14. access_store
  15. c2port_store_reset
  16. __c2port_show_dev_id
  17. c2port_show_dev_id
  18. __c2port_show_rev_id
  19. c2port_show_rev_id
  20. c2port_show_flash_access
  21. __c2port_store_flash_access
  22. c2port_store_flash_access
  23. __c2port_write_flash_erase
  24. c2port_store_flash_erase
  25. __c2port_read_flash_data
  26. c2port_read_flash_data
  27. __c2port_write_flash_data
  28. c2port_write_flash_data
  29. c2port_device_register
  30. c2port_device_unregister
  31. c2port_init
  32. c2port_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Silicon Labs C2 port core Linux support
   4  *
   5  *  Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
   6  *  Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/init.h>
  11 #include <linux/device.h>
  12 #include <linux/errno.h>
  13 #include <linux/err.h>
  14 #include <linux/kernel.h>
  15 #include <linux/ctype.h>
  16 #include <linux/delay.h>
  17 #include <linux/idr.h>
  18 #include <linux/sched.h>
  19 #include <linux/slab.h>
  20 
  21 #include <linux/c2port.h>
  22 
  23 #define DRIVER_NAME             "c2port"
  24 #define DRIVER_VERSION          "0.51.0"
  25 
  26 static DEFINE_SPINLOCK(c2port_idr_lock);
  27 static DEFINE_IDR(c2port_idr);
  28 
  29 /*
  30  * Local variables
  31  */
  32 
  33 static struct class *c2port_class;
  34 
  35 /*
  36  * C2 registers & commands defines
  37  */
  38 
  39 /* C2 registers */
  40 #define C2PORT_DEVICEID         0x00
  41 #define C2PORT_REVID            0x01
  42 #define C2PORT_FPCTL            0x02
  43 #define C2PORT_FPDAT            0xB4
  44 
  45 /* C2 interface commands */
  46 #define C2PORT_GET_VERSION      0x01
  47 #define C2PORT_DEVICE_ERASE     0x03
  48 #define C2PORT_BLOCK_READ       0x06
  49 #define C2PORT_BLOCK_WRITE      0x07
  50 #define C2PORT_PAGE_ERASE       0x08
  51 
  52 /* C2 status return codes */
  53 #define C2PORT_INVALID_COMMAND  0x00
  54 #define C2PORT_COMMAND_FAILED   0x02
  55 #define C2PORT_COMMAND_OK       0x0d
  56 
  57 /*
  58  * C2 port low level signal managements
  59  */
  60 
  61 static void c2port_reset(struct c2port_device *dev)
  62 {
  63         struct c2port_ops *ops = dev->ops;
  64 
  65         /* To reset the device we have to keep clock line low for at least
  66          * 20us.
  67          */
  68         local_irq_disable();
  69         ops->c2ck_set(dev, 0);
  70         udelay(25);
  71         ops->c2ck_set(dev, 1);
  72         local_irq_enable();
  73 
  74         udelay(1);
  75 }
  76 
  77 static void c2port_strobe_ck(struct c2port_device *dev)
  78 {
  79         struct c2port_ops *ops = dev->ops;
  80 
  81         /* During hi-low-hi transition we disable local IRQs to avoid
  82          * interructions since C2 port specification says that it must be
  83          * shorter than 5us, otherwise the microcontroller may consider
  84          * it as a reset signal!
  85          */
  86         local_irq_disable();
  87         ops->c2ck_set(dev, 0);
  88         udelay(1);
  89         ops->c2ck_set(dev, 1);
  90         local_irq_enable();
  91 
  92         udelay(1);
  93 }
  94 
  95 /*
  96  * C2 port basic functions
  97  */
  98 
  99 static void c2port_write_ar(struct c2port_device *dev, u8 addr)
 100 {
 101         struct c2port_ops *ops = dev->ops;
 102         int i;
 103 
 104         /* START field */
 105         c2port_strobe_ck(dev);
 106 
 107         /* INS field (11b, LSB first) */
 108         ops->c2d_dir(dev, 0);
 109         ops->c2d_set(dev, 1);
 110         c2port_strobe_ck(dev);
 111         ops->c2d_set(dev, 1);
 112         c2port_strobe_ck(dev);
 113 
 114         /* ADDRESS field */
 115         for (i = 0; i < 8; i++) {
 116                 ops->c2d_set(dev, addr & 0x01);
 117                 c2port_strobe_ck(dev);
 118 
 119                 addr >>= 1;
 120         }
 121 
 122         /* STOP field */
 123         ops->c2d_dir(dev, 1);
 124         c2port_strobe_ck(dev);
 125 }
 126 
 127 static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
 128 {
 129         struct c2port_ops *ops = dev->ops;
 130         int i;
 131 
 132         /* START field */
 133         c2port_strobe_ck(dev);
 134 
 135         /* INS field (10b, LSB first) */
 136         ops->c2d_dir(dev, 0);
 137         ops->c2d_set(dev, 0);
 138         c2port_strobe_ck(dev);
 139         ops->c2d_set(dev, 1);
 140         c2port_strobe_ck(dev);
 141 
 142         /* ADDRESS field */
 143         ops->c2d_dir(dev, 1);
 144         *addr = 0;
 145         for (i = 0; i < 8; i++) {
 146                 *addr >>= 1;    /* shift in 8-bit ADDRESS field LSB first */
 147 
 148                 c2port_strobe_ck(dev);
 149                 if (ops->c2d_get(dev))
 150                         *addr |= 0x80;
 151         }
 152 
 153         /* STOP field */
 154         c2port_strobe_ck(dev);
 155 
 156         return 0;
 157 }
 158 
 159 static int c2port_write_dr(struct c2port_device *dev, u8 data)
 160 {
 161         struct c2port_ops *ops = dev->ops;
 162         int timeout, i;
 163 
 164         /* START field */
 165         c2port_strobe_ck(dev);
 166 
 167         /* INS field (01b, LSB first) */
 168         ops->c2d_dir(dev, 0);
 169         ops->c2d_set(dev, 1);
 170         c2port_strobe_ck(dev);
 171         ops->c2d_set(dev, 0);
 172         c2port_strobe_ck(dev);
 173 
 174         /* LENGTH field (00b, LSB first -> 1 byte) */
 175         ops->c2d_set(dev, 0);
 176         c2port_strobe_ck(dev);
 177         ops->c2d_set(dev, 0);
 178         c2port_strobe_ck(dev);
 179 
 180         /* DATA field */
 181         for (i = 0; i < 8; i++) {
 182                 ops->c2d_set(dev, data & 0x01);
 183                 c2port_strobe_ck(dev);
 184 
 185                 data >>= 1;
 186         }
 187 
 188         /* WAIT field */
 189         ops->c2d_dir(dev, 1);
 190         timeout = 20;
 191         do {
 192                 c2port_strobe_ck(dev);
 193                 if (ops->c2d_get(dev))
 194                         break;
 195 
 196                 udelay(1);
 197         } while (--timeout > 0);
 198         if (timeout == 0)
 199                 return -EIO;
 200 
 201         /* STOP field */
 202         c2port_strobe_ck(dev);
 203 
 204         return 0;
 205 }
 206 
 207 static int c2port_read_dr(struct c2port_device *dev, u8 *data)
 208 {
 209         struct c2port_ops *ops = dev->ops;
 210         int timeout, i;
 211 
 212         /* START field */
 213         c2port_strobe_ck(dev);
 214 
 215         /* INS field (00b, LSB first) */
 216         ops->c2d_dir(dev, 0);
 217         ops->c2d_set(dev, 0);
 218         c2port_strobe_ck(dev);
 219         ops->c2d_set(dev, 0);
 220         c2port_strobe_ck(dev);
 221 
 222         /* LENGTH field (00b, LSB first -> 1 byte) */
 223         ops->c2d_set(dev, 0);
 224         c2port_strobe_ck(dev);
 225         ops->c2d_set(dev, 0);
 226         c2port_strobe_ck(dev);
 227 
 228         /* WAIT field */
 229         ops->c2d_dir(dev, 1);
 230         timeout = 20;
 231         do {
 232                 c2port_strobe_ck(dev);
 233                 if (ops->c2d_get(dev))
 234                         break;
 235 
 236                 udelay(1);
 237         } while (--timeout > 0);
 238         if (timeout == 0)
 239                 return -EIO;
 240 
 241         /* DATA field */
 242         *data = 0;
 243         for (i = 0; i < 8; i++) {
 244                 *data >>= 1;    /* shift in 8-bit DATA field LSB first */
 245 
 246                 c2port_strobe_ck(dev);
 247                 if (ops->c2d_get(dev))
 248                         *data |= 0x80;
 249         }
 250 
 251         /* STOP field */
 252         c2port_strobe_ck(dev);
 253 
 254         return 0;
 255 }
 256 
 257 static int c2port_poll_in_busy(struct c2port_device *dev)
 258 {
 259         u8 addr;
 260         int ret, timeout = 20;
 261 
 262         do {
 263                 ret = (c2port_read_ar(dev, &addr));
 264                 if (ret < 0)
 265                         return -EIO;
 266 
 267                 if (!(addr & 0x02))
 268                         break;
 269 
 270                 udelay(1);
 271         } while (--timeout > 0);
 272         if (timeout == 0)
 273                 return -EIO;
 274 
 275         return 0;
 276 }
 277 
 278 static int c2port_poll_out_ready(struct c2port_device *dev)
 279 {
 280         u8 addr;
 281         int ret, timeout = 10000; /* erase flash needs long time... */
 282 
 283         do {
 284                 ret = (c2port_read_ar(dev, &addr));
 285                 if (ret < 0)
 286                         return -EIO;
 287 
 288                 if (addr & 0x01)
 289                         break;
 290 
 291                 udelay(1);
 292         } while (--timeout > 0);
 293         if (timeout == 0)
 294                 return -EIO;
 295 
 296         return 0;
 297 }
 298 
 299 /*
 300  * sysfs methods
 301  */
 302 
 303 static ssize_t c2port_show_name(struct device *dev,
 304                                 struct device_attribute *attr, char *buf)
 305 {
 306         struct c2port_device *c2dev = dev_get_drvdata(dev);
 307 
 308         return sprintf(buf, "%s\n", c2dev->name);
 309 }
 310 static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
 311 
 312 static ssize_t c2port_show_flash_blocks_num(struct device *dev,
 313                                 struct device_attribute *attr, char *buf)
 314 {
 315         struct c2port_device *c2dev = dev_get_drvdata(dev);
 316         struct c2port_ops *ops = c2dev->ops;
 317 
 318         return sprintf(buf, "%d\n", ops->blocks_num);
 319 }
 320 static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
 321 
 322 static ssize_t c2port_show_flash_block_size(struct device *dev,
 323                                 struct device_attribute *attr, char *buf)
 324 {
 325         struct c2port_device *c2dev = dev_get_drvdata(dev);
 326         struct c2port_ops *ops = c2dev->ops;
 327 
 328         return sprintf(buf, "%d\n", ops->block_size);
 329 }
 330 static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
 331 
 332 static ssize_t c2port_show_flash_size(struct device *dev,
 333                                 struct device_attribute *attr, char *buf)
 334 {
 335         struct c2port_device *c2dev = dev_get_drvdata(dev);
 336         struct c2port_ops *ops = c2dev->ops;
 337 
 338         return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
 339 }
 340 static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
 341 
 342 static ssize_t access_show(struct device *dev, struct device_attribute *attr,
 343                            char *buf)
 344 {
 345         struct c2port_device *c2dev = dev_get_drvdata(dev);
 346 
 347         return sprintf(buf, "%d\n", c2dev->access);
 348 }
 349 
 350 static ssize_t access_store(struct device *dev, struct device_attribute *attr,
 351                             const char *buf, size_t count)
 352 {
 353         struct c2port_device *c2dev = dev_get_drvdata(dev);
 354         struct c2port_ops *ops = c2dev->ops;
 355         int status, ret;
 356 
 357         ret = sscanf(buf, "%d", &status);
 358         if (ret != 1)
 359                 return -EINVAL;
 360 
 361         mutex_lock(&c2dev->mutex);
 362 
 363         c2dev->access = !!status;
 364 
 365         /* If access is "on" clock should be HIGH _before_ setting the line
 366          * as output and data line should be set as INPUT anyway */
 367         if (c2dev->access)
 368                 ops->c2ck_set(c2dev, 1);
 369         ops->access(c2dev, c2dev->access);
 370         if (c2dev->access)
 371                 ops->c2d_dir(c2dev, 1);
 372 
 373         mutex_unlock(&c2dev->mutex);
 374 
 375         return count;
 376 }
 377 static DEVICE_ATTR_RW(access);
 378 
 379 static ssize_t c2port_store_reset(struct device *dev,
 380                                 struct device_attribute *attr,
 381                                 const char *buf, size_t count)
 382 {
 383         struct c2port_device *c2dev = dev_get_drvdata(dev);
 384 
 385         /* Check the device access status */
 386         if (!c2dev->access)
 387                 return -EBUSY;
 388 
 389         mutex_lock(&c2dev->mutex);
 390 
 391         c2port_reset(c2dev);
 392         c2dev->flash_access = 0;
 393 
 394         mutex_unlock(&c2dev->mutex);
 395 
 396         return count;
 397 }
 398 static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
 399 
 400 static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
 401 {
 402         u8 data;
 403         int ret;
 404 
 405         /* Select DEVICEID register for C2 data register accesses */
 406         c2port_write_ar(dev, C2PORT_DEVICEID);
 407 
 408         /* Read and return the device ID register */
 409         ret = c2port_read_dr(dev, &data);
 410         if (ret < 0)
 411                 return ret;
 412 
 413         return sprintf(buf, "%d\n", data);
 414 }
 415 
 416 static ssize_t c2port_show_dev_id(struct device *dev,
 417                                 struct device_attribute *attr, char *buf)
 418 {
 419         struct c2port_device *c2dev = dev_get_drvdata(dev);
 420         ssize_t ret;
 421 
 422         /* Check the device access status */
 423         if (!c2dev->access)
 424                 return -EBUSY;
 425 
 426         mutex_lock(&c2dev->mutex);
 427         ret = __c2port_show_dev_id(c2dev, buf);
 428         mutex_unlock(&c2dev->mutex);
 429 
 430         if (ret < 0)
 431                 dev_err(dev, "cannot read from %s\n", c2dev->name);
 432 
 433         return ret;
 434 }
 435 static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
 436 
 437 static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
 438 {
 439         u8 data;
 440         int ret;
 441 
 442         /* Select REVID register for C2 data register accesses */
 443         c2port_write_ar(dev, C2PORT_REVID);
 444 
 445         /* Read and return the revision ID register */
 446         ret = c2port_read_dr(dev, &data);
 447         if (ret < 0)
 448                 return ret;
 449 
 450         return sprintf(buf, "%d\n", data);
 451 }
 452 
 453 static ssize_t c2port_show_rev_id(struct device *dev,
 454                                 struct device_attribute *attr, char *buf)
 455 {
 456         struct c2port_device *c2dev = dev_get_drvdata(dev);
 457         ssize_t ret;
 458 
 459         /* Check the device access status */
 460         if (!c2dev->access)
 461                 return -EBUSY;
 462 
 463         mutex_lock(&c2dev->mutex);
 464         ret = __c2port_show_rev_id(c2dev, buf);
 465         mutex_unlock(&c2dev->mutex);
 466 
 467         if (ret < 0)
 468                 dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
 469 
 470         return ret;
 471 }
 472 static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
 473 
 474 static ssize_t c2port_show_flash_access(struct device *dev,
 475                                 struct device_attribute *attr, char *buf)
 476 {
 477         struct c2port_device *c2dev = dev_get_drvdata(dev);
 478 
 479         return sprintf(buf, "%d\n", c2dev->flash_access);
 480 }
 481 
 482 static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
 483                                                 int status)
 484 {
 485         int ret;
 486 
 487         /* Check the device access status */
 488         if (!dev->access)
 489                 return -EBUSY;
 490 
 491         dev->flash_access = !!status;
 492 
 493         /* If flash_access is off we have nothing to do... */
 494         if (dev->flash_access == 0)
 495                 return 0;
 496 
 497         /* Target the C2 flash programming control register for C2 data
 498          * register access */
 499         c2port_write_ar(dev, C2PORT_FPCTL);
 500 
 501         /* Write the first keycode to enable C2 Flash programming */
 502         ret = c2port_write_dr(dev, 0x02);
 503         if (ret < 0)
 504                 return ret;
 505 
 506         /* Write the second keycode to enable C2 Flash programming */
 507         ret = c2port_write_dr(dev, 0x01);
 508         if (ret < 0)
 509                 return ret;
 510 
 511         /* Delay for at least 20ms to ensure the target is ready for
 512          * C2 flash programming */
 513         mdelay(25);
 514 
 515         return 0;
 516 }
 517 
 518 static ssize_t c2port_store_flash_access(struct device *dev,
 519                                 struct device_attribute *attr,
 520                                 const char *buf, size_t count)
 521 {
 522         struct c2port_device *c2dev = dev_get_drvdata(dev);
 523         int status;
 524         ssize_t ret;
 525 
 526         ret = sscanf(buf, "%d", &status);
 527         if (ret != 1)
 528                 return -EINVAL;
 529 
 530         mutex_lock(&c2dev->mutex);
 531         ret = __c2port_store_flash_access(c2dev, status);
 532         mutex_unlock(&c2dev->mutex);
 533 
 534         if (ret < 0) {
 535                 dev_err(c2dev->dev, "cannot enable %s flash programming\n",
 536                         c2dev->name);
 537                 return ret;
 538         }
 539 
 540         return count;
 541 }
 542 static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
 543                    c2port_store_flash_access);
 544 
 545 static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
 546 {
 547         u8 status;
 548         int ret;
 549 
 550         /* Target the C2 flash programming data register for C2 data register
 551          * access.
 552          */
 553         c2port_write_ar(dev, C2PORT_FPDAT);
 554 
 555         /* Send device erase command */
 556         c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
 557 
 558         /* Wait for input acknowledge */
 559         ret = c2port_poll_in_busy(dev);
 560         if (ret < 0)
 561                 return ret;
 562 
 563         /* Should check status before starting FLASH access sequence */
 564 
 565         /* Wait for status information */
 566         ret = c2port_poll_out_ready(dev);
 567         if (ret < 0)
 568                 return ret;
 569 
 570         /* Read flash programming interface status */
 571         ret = c2port_read_dr(dev, &status);
 572         if (ret < 0)
 573                 return ret;
 574         if (status != C2PORT_COMMAND_OK)
 575                 return -EBUSY;
 576 
 577         /* Send a three-byte arming sequence to enable the device erase.
 578          * If the sequence is not received correctly, the command will be
 579          * ignored.
 580          * Sequence is: 0xde, 0xad, 0xa5.
 581          */
 582         c2port_write_dr(dev, 0xde);
 583         ret = c2port_poll_in_busy(dev);
 584         if (ret < 0)
 585                 return ret;
 586         c2port_write_dr(dev, 0xad);
 587         ret = c2port_poll_in_busy(dev);
 588         if (ret < 0)
 589                 return ret;
 590         c2port_write_dr(dev, 0xa5);
 591         ret = c2port_poll_in_busy(dev);
 592         if (ret < 0)
 593                 return ret;
 594 
 595         ret = c2port_poll_out_ready(dev);
 596         if (ret < 0)
 597                 return ret;
 598 
 599         return 0;
 600 }
 601 
 602 static ssize_t c2port_store_flash_erase(struct device *dev,
 603                                 struct device_attribute *attr,
 604                                 const char *buf, size_t count)
 605 {
 606         struct c2port_device *c2dev = dev_get_drvdata(dev);
 607         int ret;
 608 
 609         /* Check the device and flash access status */
 610         if (!c2dev->access || !c2dev->flash_access)
 611                 return -EBUSY;
 612 
 613         mutex_lock(&c2dev->mutex);
 614         ret = __c2port_write_flash_erase(c2dev);
 615         mutex_unlock(&c2dev->mutex);
 616 
 617         if (ret < 0) {
 618                 dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
 619                 return ret;
 620         }
 621 
 622         return count;
 623 }
 624 static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
 625 
 626 static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
 627                                 char *buffer, loff_t offset, size_t count)
 628 {
 629         struct c2port_ops *ops = dev->ops;
 630         u8 status, nread = 128;
 631         int i, ret;
 632 
 633         /* Check for flash end */
 634         if (offset >= ops->block_size * ops->blocks_num)
 635                 return 0;
 636 
 637         if (ops->block_size * ops->blocks_num - offset < nread)
 638                 nread = ops->block_size * ops->blocks_num - offset;
 639         if (count < nread)
 640                 nread = count;
 641         if (nread == 0)
 642                 return nread;
 643 
 644         /* Target the C2 flash programming data register for C2 data register
 645          * access */
 646         c2port_write_ar(dev, C2PORT_FPDAT);
 647 
 648         /* Send flash block read command */
 649         c2port_write_dr(dev, C2PORT_BLOCK_READ);
 650 
 651         /* Wait for input acknowledge */
 652         ret = c2port_poll_in_busy(dev);
 653         if (ret < 0)
 654                 return ret;
 655 
 656         /* Should check status before starting FLASH access sequence */
 657 
 658         /* Wait for status information */
 659         ret = c2port_poll_out_ready(dev);
 660         if (ret < 0)
 661                 return ret;
 662 
 663         /* Read flash programming interface status */
 664         ret = c2port_read_dr(dev, &status);
 665         if (ret < 0)
 666                 return ret;
 667         if (status != C2PORT_COMMAND_OK)
 668                 return -EBUSY;
 669 
 670         /* Send address high byte */
 671         c2port_write_dr(dev, offset >> 8);
 672         ret = c2port_poll_in_busy(dev);
 673         if (ret < 0)
 674                 return ret;
 675 
 676         /* Send address low byte */
 677         c2port_write_dr(dev, offset & 0x00ff);
 678         ret = c2port_poll_in_busy(dev);
 679         if (ret < 0)
 680                 return ret;
 681 
 682         /* Send address block size */
 683         c2port_write_dr(dev, nread);
 684         ret = c2port_poll_in_busy(dev);
 685         if (ret < 0)
 686                 return ret;
 687 
 688         /* Should check status before reading FLASH block */
 689 
 690         /* Wait for status information */
 691         ret = c2port_poll_out_ready(dev);
 692         if (ret < 0)
 693                 return ret;
 694 
 695         /* Read flash programming interface status */
 696         ret = c2port_read_dr(dev, &status);
 697         if (ret < 0)
 698                 return ret;
 699         if (status != C2PORT_COMMAND_OK)
 700                 return -EBUSY;
 701 
 702         /* Read flash block */
 703         for (i = 0; i < nread; i++) {
 704                 ret = c2port_poll_out_ready(dev);
 705                 if (ret < 0)
 706                         return ret;
 707 
 708                 ret = c2port_read_dr(dev, buffer+i);
 709                 if (ret < 0)
 710                         return ret;
 711         }
 712 
 713         return nread;
 714 }
 715 
 716 static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
 717                                 struct bin_attribute *attr,
 718                                 char *buffer, loff_t offset, size_t count)
 719 {
 720         struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
 721         ssize_t ret;
 722 
 723         /* Check the device and flash access status */
 724         if (!c2dev->access || !c2dev->flash_access)
 725                 return -EBUSY;
 726 
 727         mutex_lock(&c2dev->mutex);
 728         ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
 729         mutex_unlock(&c2dev->mutex);
 730 
 731         if (ret < 0)
 732                 dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
 733 
 734         return ret;
 735 }
 736 
 737 static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
 738                                 char *buffer, loff_t offset, size_t count)
 739 {
 740         struct c2port_ops *ops = dev->ops;
 741         u8 status, nwrite = 128;
 742         int i, ret;
 743 
 744         if (nwrite > count)
 745                 nwrite = count;
 746         if (ops->block_size * ops->blocks_num - offset < nwrite)
 747                 nwrite = ops->block_size * ops->blocks_num - offset;
 748 
 749         /* Check for flash end */
 750         if (offset >= ops->block_size * ops->blocks_num)
 751                 return -EINVAL;
 752 
 753         /* Target the C2 flash programming data register for C2 data register
 754          * access */
 755         c2port_write_ar(dev, C2PORT_FPDAT);
 756 
 757         /* Send flash block write command */
 758         c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
 759 
 760         /* Wait for input acknowledge */
 761         ret = c2port_poll_in_busy(dev);
 762         if (ret < 0)
 763                 return ret;
 764 
 765         /* Should check status before starting FLASH access sequence */
 766 
 767         /* Wait for status information */
 768         ret = c2port_poll_out_ready(dev);
 769         if (ret < 0)
 770                 return ret;
 771 
 772         /* Read flash programming interface status */
 773         ret = c2port_read_dr(dev, &status);
 774         if (ret < 0)
 775                 return ret;
 776         if (status != C2PORT_COMMAND_OK)
 777                 return -EBUSY;
 778 
 779         /* Send address high byte */
 780         c2port_write_dr(dev, offset >> 8);
 781         ret = c2port_poll_in_busy(dev);
 782         if (ret < 0)
 783                 return ret;
 784 
 785         /* Send address low byte */
 786         c2port_write_dr(dev, offset & 0x00ff);
 787         ret = c2port_poll_in_busy(dev);
 788         if (ret < 0)
 789                 return ret;
 790 
 791         /* Send address block size */
 792         c2port_write_dr(dev, nwrite);
 793         ret = c2port_poll_in_busy(dev);
 794         if (ret < 0)
 795                 return ret;
 796 
 797         /* Should check status before writing FLASH block */
 798 
 799         /* Wait for status information */
 800         ret = c2port_poll_out_ready(dev);
 801         if (ret < 0)
 802                 return ret;
 803 
 804         /* Read flash programming interface status */
 805         ret = c2port_read_dr(dev, &status);
 806         if (ret < 0)
 807                 return ret;
 808         if (status != C2PORT_COMMAND_OK)
 809                 return -EBUSY;
 810 
 811         /* Write flash block */
 812         for (i = 0; i < nwrite; i++) {
 813                 ret = c2port_write_dr(dev, *(buffer+i));
 814                 if (ret < 0)
 815                         return ret;
 816 
 817                 ret = c2port_poll_in_busy(dev);
 818                 if (ret < 0)
 819                         return ret;
 820 
 821         }
 822 
 823         /* Wait for last flash write to complete */
 824         ret = c2port_poll_out_ready(dev);
 825         if (ret < 0)
 826                 return ret;
 827 
 828         return nwrite;
 829 }
 830 
 831 static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
 832                                 struct bin_attribute *attr,
 833                                 char *buffer, loff_t offset, size_t count)
 834 {
 835         struct c2port_device *c2dev = dev_get_drvdata(kobj_to_dev(kobj));
 836         int ret;
 837 
 838         /* Check the device access status */
 839         if (!c2dev->access || !c2dev->flash_access)
 840                 return -EBUSY;
 841 
 842         mutex_lock(&c2dev->mutex);
 843         ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
 844         mutex_unlock(&c2dev->mutex);
 845 
 846         if (ret < 0)
 847                 dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
 848 
 849         return ret;
 850 }
 851 /* size is computed at run-time */
 852 static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
 853                 c2port_write_flash_data, 0);
 854 
 855 /*
 856  * Class attributes
 857  */
 858 static struct attribute *c2port_attrs[] = {
 859         &dev_attr_name.attr,
 860         &dev_attr_flash_blocks_num.attr,
 861         &dev_attr_flash_block_size.attr,
 862         &dev_attr_flash_size.attr,
 863         &dev_attr_access.attr,
 864         &dev_attr_reset.attr,
 865         &dev_attr_dev_id.attr,
 866         &dev_attr_rev_id.attr,
 867         &dev_attr_flash_access.attr,
 868         &dev_attr_flash_erase.attr,
 869         NULL,
 870 };
 871 
 872 static struct bin_attribute *c2port_bin_attrs[] = {
 873         &bin_attr_flash_data,
 874         NULL,
 875 };
 876 
 877 static const struct attribute_group c2port_group = {
 878         .attrs = c2port_attrs,
 879         .bin_attrs = c2port_bin_attrs,
 880 };
 881 
 882 static const struct attribute_group *c2port_groups[] = {
 883         &c2port_group,
 884         NULL,
 885 };
 886 
 887 /*
 888  * Exported functions
 889  */
 890 
 891 struct c2port_device *c2port_device_register(char *name,
 892                                         struct c2port_ops *ops, void *devdata)
 893 {
 894         struct c2port_device *c2dev;
 895         int ret;
 896 
 897         if (unlikely(!ops) || unlikely(!ops->access) || \
 898                 unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
 899                 unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
 900                 return ERR_PTR(-EINVAL);
 901 
 902         c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
 903         if (unlikely(!c2dev))
 904                 return ERR_PTR(-ENOMEM);
 905 
 906         idr_preload(GFP_KERNEL);
 907         spin_lock_irq(&c2port_idr_lock);
 908         ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
 909         spin_unlock_irq(&c2port_idr_lock);
 910         idr_preload_end();
 911 
 912         if (ret < 0)
 913                 goto error_idr_alloc;
 914         c2dev->id = ret;
 915 
 916         bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
 917 
 918         c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
 919                                    "c2port%d", c2dev->id);
 920         if (IS_ERR(c2dev->dev)) {
 921                 ret = PTR_ERR(c2dev->dev);
 922                 goto error_device_create;
 923         }
 924         dev_set_drvdata(c2dev->dev, c2dev);
 925 
 926         strncpy(c2dev->name, name, C2PORT_NAME_LEN);
 927         c2dev->ops = ops;
 928         mutex_init(&c2dev->mutex);
 929 
 930         /* By default C2 port access is off */
 931         c2dev->access = c2dev->flash_access = 0;
 932         ops->access(c2dev, 0);
 933 
 934         dev_info(c2dev->dev, "C2 port %s added\n", name);
 935         dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
 936                                 "(%d bytes total)\n",
 937                                 name, ops->blocks_num, ops->block_size,
 938                                 ops->blocks_num * ops->block_size);
 939 
 940         return c2dev;
 941 
 942 error_device_create:
 943         spin_lock_irq(&c2port_idr_lock);
 944         idr_remove(&c2port_idr, c2dev->id);
 945         spin_unlock_irq(&c2port_idr_lock);
 946 
 947 error_idr_alloc:
 948         kfree(c2dev);
 949 
 950         return ERR_PTR(ret);
 951 }
 952 EXPORT_SYMBOL(c2port_device_register);
 953 
 954 void c2port_device_unregister(struct c2port_device *c2dev)
 955 {
 956         if (!c2dev)
 957                 return;
 958 
 959         dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
 960 
 961         spin_lock_irq(&c2port_idr_lock);
 962         idr_remove(&c2port_idr, c2dev->id);
 963         spin_unlock_irq(&c2port_idr_lock);
 964 
 965         device_destroy(c2port_class, c2dev->id);
 966 
 967         kfree(c2dev);
 968 }
 969 EXPORT_SYMBOL(c2port_device_unregister);
 970 
 971 /*
 972  * Module stuff
 973  */
 974 
 975 static int __init c2port_init(void)
 976 {
 977         printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
 978                 " - (C) 2007 Rodolfo Giometti\n");
 979 
 980         c2port_class = class_create(THIS_MODULE, "c2port");
 981         if (IS_ERR(c2port_class)) {
 982                 printk(KERN_ERR "c2port: failed to allocate class\n");
 983                 return PTR_ERR(c2port_class);
 984         }
 985         c2port_class->dev_groups = c2port_groups;
 986 
 987         return 0;
 988 }
 989 
 990 static void __exit c2port_exit(void)
 991 {
 992         class_destroy(c2port_class);
 993 }
 994 
 995 module_init(c2port_init);
 996 module_exit(c2port_exit);
 997 
 998 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 999 MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
1000 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */