root/drivers/i2c/busses/scx200_acb.c

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

DEFINITIONS

This source file includes following definitions.
  1. scx200_acb_machine
  2. scx200_acb_poll
  3. scx200_acb_reset
  4. scx200_acb_smbus_xfer
  5. scx200_acb_func
  6. scx200_acb_probe
  7. scx200_create_iface
  8. scx200_acb_create
  9. scx200_create_dev
  10. scx200_probe
  11. scx200_cleanup_iface
  12. scx200_remove
  13. scx200_scan_isa
  14. scx200_acb_init
  15. scx200_acb_cleanup

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3     Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
   4 
   5     National Semiconductor SCx200 ACCESS.bus support
   6     Also supports the AMD CS5535 and AMD CS5536
   7 
   8     Based on i2c-keywest.c which is:
   9         Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
  10         Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
  11 
  12 */
  13 
  14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15 
  16 #include <linux/module.h>
  17 #include <linux/errno.h>
  18 #include <linux/kernel.h>
  19 #include <linux/init.h>
  20 #include <linux/i2c.h>
  21 #include <linux/pci.h>
  22 #include <linux/platform_device.h>
  23 #include <linux/delay.h>
  24 #include <linux/mutex.h>
  25 #include <linux/slab.h>
  26 #include <linux/io.h>
  27 
  28 #include <linux/scx200.h>
  29 
  30 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
  31 MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
  32 MODULE_ALIAS("platform:cs5535-smb");
  33 MODULE_LICENSE("GPL");
  34 
  35 #define MAX_DEVICES 4
  36 static int base[MAX_DEVICES] = { 0x820, 0x840 };
  37 module_param_hw_array(base, int, ioport, NULL, 0);
  38 MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
  39 
  40 #define POLL_TIMEOUT    (HZ/5)
  41 
  42 enum scx200_acb_state {
  43         state_idle,
  44         state_address,
  45         state_command,
  46         state_repeat_start,
  47         state_quick,
  48         state_read,
  49         state_write,
  50 };
  51 
  52 static const char *scx200_acb_state_name[] = {
  53         "idle",
  54         "address",
  55         "command",
  56         "repeat_start",
  57         "quick",
  58         "read",
  59         "write",
  60 };
  61 
  62 /* Physical interface */
  63 struct scx200_acb_iface {
  64         struct scx200_acb_iface *next;
  65         struct i2c_adapter adapter;
  66         unsigned base;
  67         struct mutex mutex;
  68 
  69         /* State machine data */
  70         enum scx200_acb_state state;
  71         int result;
  72         u8 address_byte;
  73         u8 command;
  74         u8 *ptr;
  75         char needs_reset;
  76         unsigned len;
  77 };
  78 
  79 /* Register Definitions */
  80 #define ACBSDA          (iface->base + 0)
  81 #define ACBST           (iface->base + 1)
  82 #define    ACBST_SDAST          0x40 /* SDA Status */
  83 #define    ACBST_BER            0x20
  84 #define    ACBST_NEGACK         0x10 /* Negative Acknowledge */
  85 #define    ACBST_STASTR         0x08 /* Stall After Start */
  86 #define    ACBST_MASTER         0x02
  87 #define ACBCST          (iface->base + 2)
  88 #define    ACBCST_BB            0x02
  89 #define ACBCTL1         (iface->base + 3)
  90 #define    ACBCTL1_STASTRE      0x80
  91 #define    ACBCTL1_NMINTE       0x40
  92 #define    ACBCTL1_ACK          0x10
  93 #define    ACBCTL1_STOP         0x02
  94 #define    ACBCTL1_START        0x01
  95 #define ACBADDR         (iface->base + 4)
  96 #define ACBCTL2         (iface->base + 5)
  97 #define    ACBCTL2_ENABLE       0x01
  98 
  99 /************************************************************************/
 100 
 101 static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
 102 {
 103         const char *errmsg;
 104 
 105         dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
 106                 scx200_acb_state_name[iface->state], status);
 107 
 108         if (status & ACBST_BER) {
 109                 errmsg = "bus error";
 110                 goto error;
 111         }
 112         if (!(status & ACBST_MASTER)) {
 113                 errmsg = "not master";
 114                 goto error;
 115         }
 116         if (status & ACBST_NEGACK) {
 117                 dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
 118                         scx200_acb_state_name[iface->state]);
 119 
 120                 iface->state = state_idle;
 121                 iface->result = -ENXIO;
 122 
 123                 outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
 124                 outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
 125 
 126                 /* Reset the status register */
 127                 outb(0, ACBST);
 128                 return;
 129         }
 130 
 131         switch (iface->state) {
 132         case state_idle:
 133                 dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
 134                 break;
 135 
 136         case state_address:
 137                 /* Do a pointer write first */
 138                 outb(iface->address_byte & ~1, ACBSDA);
 139 
 140                 iface->state = state_command;
 141                 break;
 142 
 143         case state_command:
 144                 outb(iface->command, ACBSDA);
 145 
 146                 if (iface->address_byte & 1)
 147                         iface->state = state_repeat_start;
 148                 else
 149                         iface->state = state_write;
 150                 break;
 151 
 152         case state_repeat_start:
 153                 outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
 154                 /* fallthrough */
 155 
 156         case state_quick:
 157                 if (iface->address_byte & 1) {
 158                         if (iface->len == 1)
 159                                 outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
 160                         else
 161                                 outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
 162                         outb(iface->address_byte, ACBSDA);
 163 
 164                         iface->state = state_read;
 165                 } else {
 166                         outb(iface->address_byte, ACBSDA);
 167 
 168                         iface->state = state_write;
 169                 }
 170                 break;
 171 
 172         case state_read:
 173                 /* Set ACK if _next_ byte will be the last one */
 174                 if (iface->len == 2)
 175                         outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
 176                 else
 177                         outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
 178 
 179                 if (iface->len == 1) {
 180                         iface->result = 0;
 181                         iface->state = state_idle;
 182                         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
 183                 }
 184 
 185                 *iface->ptr++ = inb(ACBSDA);
 186                 --iface->len;
 187 
 188                 break;
 189 
 190         case state_write:
 191                 if (iface->len == 0) {
 192                         iface->result = 0;
 193                         iface->state = state_idle;
 194                         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
 195                         break;
 196                 }
 197 
 198                 outb(*iface->ptr++, ACBSDA);
 199                 --iface->len;
 200 
 201                 break;
 202         }
 203 
 204         return;
 205 
 206  error:
 207         dev_err(&iface->adapter.dev,
 208                 "%s in state %s (addr=0x%02x, len=%d, status=0x%02x)\n", errmsg,
 209                 scx200_acb_state_name[iface->state], iface->address_byte,
 210                 iface->len, status);
 211 
 212         iface->state = state_idle;
 213         iface->result = -EIO;
 214         iface->needs_reset = 1;
 215 }
 216 
 217 static void scx200_acb_poll(struct scx200_acb_iface *iface)
 218 {
 219         u8 status;
 220         unsigned long timeout;
 221 
 222         timeout = jiffies + POLL_TIMEOUT;
 223         while (1) {
 224                 status = inb(ACBST);
 225 
 226                 /* Reset the status register to avoid the hang */
 227                 outb(0, ACBST);
 228 
 229                 if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
 230                         scx200_acb_machine(iface, status);
 231                         return;
 232                 }
 233                 if (time_after(jiffies, timeout))
 234                         break;
 235                 cpu_relax();
 236                 cond_resched();
 237         }
 238 
 239         dev_err(&iface->adapter.dev, "timeout in state %s\n",
 240                 scx200_acb_state_name[iface->state]);
 241 
 242         iface->state = state_idle;
 243         iface->result = -EIO;
 244         iface->needs_reset = 1;
 245 }
 246 
 247 static void scx200_acb_reset(struct scx200_acb_iface *iface)
 248 {
 249         /* Disable the ACCESS.bus device and Configure the SCL
 250            frequency: 16 clock cycles */
 251         outb(0x70, ACBCTL2);
 252         /* Polling mode */
 253         outb(0, ACBCTL1);
 254         /* Disable slave address */
 255         outb(0, ACBADDR);
 256         /* Enable the ACCESS.bus device */
 257         outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
 258         /* Free STALL after START */
 259         outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
 260         /* Send a STOP */
 261         outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
 262         /* Clear BER, NEGACK and STASTR bits */
 263         outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
 264         /* Clear BB bit */
 265         outb(inb(ACBCST) | ACBCST_BB, ACBCST);
 266 }
 267 
 268 static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
 269                                  u16 address, unsigned short flags,
 270                                  char rw, u8 command, int size,
 271                                  union i2c_smbus_data *data)
 272 {
 273         struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
 274         int len;
 275         u8 *buffer;
 276         u16 cur_word;
 277         int rc;
 278 
 279         switch (size) {
 280         case I2C_SMBUS_QUICK:
 281                 len = 0;
 282                 buffer = NULL;
 283                 break;
 284 
 285         case I2C_SMBUS_BYTE:
 286                 len = 1;
 287                 buffer = rw ? &data->byte : &command;
 288                 break;
 289 
 290         case I2C_SMBUS_BYTE_DATA:
 291                 len = 1;
 292                 buffer = &data->byte;
 293                 break;
 294 
 295         case I2C_SMBUS_WORD_DATA:
 296                 len = 2;
 297                 cur_word = cpu_to_le16(data->word);
 298                 buffer = (u8 *)&cur_word;
 299                 break;
 300 
 301         case I2C_SMBUS_I2C_BLOCK_DATA:
 302                 len = data->block[0];
 303                 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
 304                         return -EINVAL;
 305                 buffer = &data->block[1];
 306                 break;
 307 
 308         default:
 309                 return -EINVAL;
 310         }
 311 
 312         dev_dbg(&adapter->dev,
 313                 "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
 314                 size, address, command, len, rw);
 315 
 316         if (!len && rw == I2C_SMBUS_READ) {
 317                 dev_dbg(&adapter->dev, "zero length read\n");
 318                 return -EINVAL;
 319         }
 320 
 321         mutex_lock(&iface->mutex);
 322 
 323         iface->address_byte = (address << 1) | rw;
 324         iface->command = command;
 325         iface->ptr = buffer;
 326         iface->len = len;
 327         iface->result = -EINVAL;
 328         iface->needs_reset = 0;
 329 
 330         outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
 331 
 332         if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
 333                 iface->state = state_quick;
 334         else
 335                 iface->state = state_address;
 336 
 337         while (iface->state != state_idle)
 338                 scx200_acb_poll(iface);
 339 
 340         if (iface->needs_reset)
 341                 scx200_acb_reset(iface);
 342 
 343         rc = iface->result;
 344 
 345         mutex_unlock(&iface->mutex);
 346 
 347         if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
 348                 data->word = le16_to_cpu(cur_word);
 349 
 350 #ifdef DEBUG
 351         dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
 352         if (buffer) {
 353                 int i;
 354                 printk(" data:");
 355                 for (i = 0; i < len; ++i)
 356                         printk(" %02x", buffer[i]);
 357         }
 358         printk("\n");
 359 #endif
 360 
 361         return rc;
 362 }
 363 
 364 static u32 scx200_acb_func(struct i2c_adapter *adapter)
 365 {
 366         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 367                I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
 368                I2C_FUNC_SMBUS_I2C_BLOCK;
 369 }
 370 
 371 /* For now, we only handle combined mode (smbus) */
 372 static const struct i2c_algorithm scx200_acb_algorithm = {
 373         .smbus_xfer     = scx200_acb_smbus_xfer,
 374         .functionality  = scx200_acb_func,
 375 };
 376 
 377 static struct scx200_acb_iface *scx200_acb_list;
 378 static DEFINE_MUTEX(scx200_acb_list_mutex);
 379 
 380 static int scx200_acb_probe(struct scx200_acb_iface *iface)
 381 {
 382         u8 val;
 383 
 384         /* Disable the ACCESS.bus device and Configure the SCL
 385            frequency: 16 clock cycles */
 386         outb(0x70, ACBCTL2);
 387 
 388         if (inb(ACBCTL2) != 0x70) {
 389                 pr_debug("ACBCTL2 readback failed\n");
 390                 return -ENXIO;
 391         }
 392 
 393         outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
 394 
 395         val = inb(ACBCTL1);
 396         if (val) {
 397                 pr_debug("disabled, but ACBCTL1=0x%02x\n", val);
 398                 return -ENXIO;
 399         }
 400 
 401         outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
 402 
 403         outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
 404 
 405         val = inb(ACBCTL1);
 406         if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
 407                 pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n",
 408                          val);
 409                 return -ENXIO;
 410         }
 411 
 412         return 0;
 413 }
 414 
 415 static struct scx200_acb_iface *scx200_create_iface(const char *text,
 416                 struct device *dev, int index)
 417 {
 418         struct scx200_acb_iface *iface;
 419         struct i2c_adapter *adapter;
 420 
 421         iface = kzalloc(sizeof(*iface), GFP_KERNEL);
 422         if (!iface)
 423                 return NULL;
 424 
 425         adapter = &iface->adapter;
 426         i2c_set_adapdata(adapter, iface);
 427         snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
 428         adapter->owner = THIS_MODULE;
 429         adapter->algo = &scx200_acb_algorithm;
 430         adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 431         adapter->dev.parent = dev;
 432 
 433         mutex_init(&iface->mutex);
 434 
 435         return iface;
 436 }
 437 
 438 static int scx200_acb_create(struct scx200_acb_iface *iface)
 439 {
 440         struct i2c_adapter *adapter;
 441         int rc;
 442 
 443         adapter = &iface->adapter;
 444 
 445         rc = scx200_acb_probe(iface);
 446         if (rc) {
 447                 pr_warn("probe failed\n");
 448                 return rc;
 449         }
 450 
 451         scx200_acb_reset(iface);
 452 
 453         if (i2c_add_adapter(adapter) < 0) {
 454                 pr_err("failed to register\n");
 455                 return -ENODEV;
 456         }
 457 
 458         if (!adapter->dev.parent) {
 459                 /* If there's no dev, we're tracking (ISA) ifaces manually */
 460                 mutex_lock(&scx200_acb_list_mutex);
 461                 iface->next = scx200_acb_list;
 462                 scx200_acb_list = iface;
 463                 mutex_unlock(&scx200_acb_list_mutex);
 464         }
 465 
 466         return 0;
 467 }
 468 
 469 static struct scx200_acb_iface *scx200_create_dev(const char *text,
 470                 unsigned long base, int index, struct device *dev)
 471 {
 472         struct scx200_acb_iface *iface;
 473         int rc;
 474 
 475         iface = scx200_create_iface(text, dev, index);
 476 
 477         if (iface == NULL)
 478                 return NULL;
 479 
 480         if (!request_region(base, 8, iface->adapter.name)) {
 481                 pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1);
 482                 goto errout_free;
 483         }
 484 
 485         iface->base = base;
 486         rc = scx200_acb_create(iface);
 487 
 488         if (rc == 0)
 489                 return iface;
 490 
 491         release_region(base, 8);
 492  errout_free:
 493         kfree(iface);
 494         return NULL;
 495 }
 496 
 497 static int scx200_probe(struct platform_device *pdev)
 498 {
 499         struct scx200_acb_iface *iface;
 500         struct resource *res;
 501 
 502         res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 503         if (!res) {
 504                 dev_err(&pdev->dev, "can't fetch device resource info\n");
 505                 return -ENODEV;
 506         }
 507 
 508         iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev);
 509         if (!iface)
 510                 return -EIO;
 511 
 512         dev_info(&pdev->dev, "SCx200 device '%s' registered\n",
 513                         iface->adapter.name);
 514         platform_set_drvdata(pdev, iface);
 515 
 516         return 0;
 517 }
 518 
 519 static void scx200_cleanup_iface(struct scx200_acb_iface *iface)
 520 {
 521         i2c_del_adapter(&iface->adapter);
 522         release_region(iface->base, 8);
 523         kfree(iface);
 524 }
 525 
 526 static int scx200_remove(struct platform_device *pdev)
 527 {
 528         struct scx200_acb_iface *iface;
 529 
 530         iface = platform_get_drvdata(pdev);
 531         scx200_cleanup_iface(iface);
 532 
 533         return 0;
 534 }
 535 
 536 static struct platform_driver scx200_pci_driver = {
 537         .driver = {
 538                 .name = "cs5535-smb",
 539         },
 540         .probe = scx200_probe,
 541         .remove = scx200_remove,
 542 };
 543 
 544 static const struct pci_device_id scx200_isa[] = {
 545         { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
 546         { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
 547         { 0, }
 548 };
 549 
 550 static __init void scx200_scan_isa(void)
 551 {
 552         int i;
 553 
 554         if (!pci_dev_present(scx200_isa))
 555                 return;
 556 
 557         for (i = 0; i < MAX_DEVICES; ++i) {
 558                 if (base[i] == 0)
 559                         continue;
 560 
 561                 /* XXX: should we care about failures? */
 562                 scx200_create_dev("SCx200", base[i], i, NULL);
 563         }
 564 }
 565 
 566 static int __init scx200_acb_init(void)
 567 {
 568         pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
 569 
 570         /* First scan for ISA-based devices */
 571         scx200_scan_isa();      /* XXX: should we care about errors? */
 572 
 573         /* If at least one bus was created, init must succeed */
 574         if (scx200_acb_list)
 575                 return 0;
 576 
 577         /* No ISA devices; register the platform driver for PCI-based devices */
 578         return platform_driver_register(&scx200_pci_driver);
 579 }
 580 
 581 static void __exit scx200_acb_cleanup(void)
 582 {
 583         struct scx200_acb_iface *iface;
 584 
 585         platform_driver_unregister(&scx200_pci_driver);
 586 
 587         mutex_lock(&scx200_acb_list_mutex);
 588         while ((iface = scx200_acb_list) != NULL) {
 589                 scx200_acb_list = iface->next;
 590                 mutex_unlock(&scx200_acb_list_mutex);
 591 
 592                 scx200_cleanup_iface(iface);
 593 
 594                 mutex_lock(&scx200_acb_list_mutex);
 595         }
 596         mutex_unlock(&scx200_acb_list_mutex);
 597 }
 598 
 599 module_init(scx200_acb_init);
 600 module_exit(scx200_acb_cleanup);

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