Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2000  Frodo Looijaard <frodol@dds.nl>,
0004  *                      Philip Edelbrock <phil@netroedge.com>,
0005  *                      Mark D. Studebaker <mdsxyz123@yahoo.com>,
0006  *                      Dan Eaton <dan.eaton@rocketlogix.com> and
0007  *                      Stephen Rousset <stephen.rousset@rocketlogix.com>
0008 */
0009 
0010 /*
0011     This is the driver for the SMB Host controller on
0012     Acer Labs Inc. (ALI) M1535 South Bridge.
0013 
0014     The M1535 is a South bridge for portable systems.
0015     It is very similar to the M15x3 South bridges also produced
0016     by Acer Labs Inc.  Some of the registers within the part
0017     have moved and some have been redefined slightly. Additionally,
0018     the sequencing of the SMBus transactions has been modified
0019     to be more consistent with the sequencing recommended by
0020     the manufacturer and observed through testing.  These
0021     changes are reflected in this driver and can be identified
0022     by comparing this driver to the i2c-ali15x3 driver.
0023     For an overview of these chips see http://www.acerlabs.com
0024 
0025     The SMB controller is part of the 7101 device, which is an
0026     ACPI-compliant Power Management Unit (PMU).
0027 
0028     The whole 7101 device has to be enabled for the SMB to work.
0029     You can't just enable the SMB alone.
0030     The SMB and the ACPI have separate I/O spaces.
0031     We make sure that the SMB is enabled. We leave the ACPI alone.
0032 
0033     This driver controls the SMB Host only.
0034 
0035     This driver does not use interrupts.
0036 */
0037 
0038 
0039 /* Note: we assume there can only be one ALI1535, with one SMBus interface */
0040 
0041 #include <linux/module.h>
0042 #include <linux/pci.h>
0043 #include <linux/kernel.h>
0044 #include <linux/stddef.h>
0045 #include <linux/delay.h>
0046 #include <linux/ioport.h>
0047 #include <linux/i2c.h>
0048 #include <linux/acpi.h>
0049 #include <linux/io.h>
0050 
0051 
0052 /* ALI1535 SMBus address offsets */
0053 #define SMBHSTSTS   (0 + ali1535_smba)
0054 #define SMBHSTTYP   (1 + ali1535_smba)
0055 #define SMBHSTPORT  (2 + ali1535_smba)
0056 #define SMBHSTCMD   (7 + ali1535_smba)
0057 #define SMBHSTADD   (3 + ali1535_smba)
0058 #define SMBHSTDAT0  (4 + ali1535_smba)
0059 #define SMBHSTDAT1  (5 + ali1535_smba)
0060 #define SMBBLKDAT   (6 + ali1535_smba)
0061 
0062 /* PCI Address Constants */
0063 #define SMBCOM      0x004
0064 #define SMBREV      0x008
0065 #define SMBCFG      0x0D1
0066 #define SMBBA       0x0E2
0067 #define SMBHSTCFG   0x0F0
0068 #define SMBCLK      0x0F2
0069 
0070 /* Other settings */
0071 #define MAX_TIMEOUT     500 /* times 1/100 sec */
0072 #define ALI1535_SMB_IOSIZE  32
0073 
0074 #define ALI1535_SMB_DEFAULTBASE 0x8040
0075 
0076 /* ALI1535 address lock bits */
0077 #define ALI1535_LOCK        0x06    /* dwe */
0078 
0079 /* ALI1535 command constants */
0080 #define ALI1535_QUICK       0x00
0081 #define ALI1535_BYTE        0x10
0082 #define ALI1535_BYTE_DATA   0x20
0083 #define ALI1535_WORD_DATA   0x30
0084 #define ALI1535_BLOCK_DATA  0x40
0085 #define ALI1535_I2C_READ    0x60
0086 
0087 #define ALI1535_DEV10B_EN   0x80    /* Enable 10-bit addressing in  */
0088                     /*  I2C read            */
0089 #define ALI1535_T_OUT       0x08    /* Time-out Command (write) */
0090 #define ALI1535_A_HIGH_BIT9 0x08    /* Bit 9 of 10-bit address in   */
0091                     /* Alert-Response-Address   */
0092                     /* (read)           */
0093 #define ALI1535_KILL        0x04    /* Kill Command (write)     */
0094 #define ALI1535_A_HIGH_BIT8 0x04    /* Bit 8 of 10-bit address in   */
0095                     /*  Alert-Response-Address  */
0096                     /*  (read)          */
0097 
0098 #define ALI1535_D_HI_MASK   0x03    /* Mask for isolating bits 9-8  */
0099                     /*  of 10-bit address in I2C    */
0100                     /*  Read Command        */
0101 
0102 /* ALI1535 status register bits */
0103 #define ALI1535_STS_IDLE    0x04
0104 #define ALI1535_STS_BUSY    0x08    /* host busy */
0105 #define ALI1535_STS_DONE    0x10    /* transaction complete */
0106 #define ALI1535_STS_DEV     0x20    /* device error */
0107 #define ALI1535_STS_BUSERR  0x40    /* bus error    */
0108 #define ALI1535_STS_FAIL    0x80    /* failed bus transaction */
0109 #define ALI1535_STS_ERR     0xE0    /* all the bad error bits */
0110 
0111 #define ALI1535_BLOCK_CLR   0x04    /* reset block data index */
0112 
0113 /* ALI1535 device address register bits */
0114 #define ALI1535_RD_ADDR     0x01    /* Read/Write Bit in Device */
0115                     /*  Address field       */
0116                     /*  -> Write = 0        */
0117                     /*  -> Read  = 1        */
0118 #define ALI1535_SMBIO_EN    0x04    /* SMB I/O Space enable     */
0119 
0120 static struct pci_driver ali1535_driver;
0121 static unsigned long ali1535_smba;
0122 static unsigned short ali1535_offset;
0123 
0124 /* Detect whether a ALI1535 can be found, and initialize it, where necessary.
0125    Note the differences between kernels with the old PCI BIOS interface and
0126    newer kernels with the real PCI interface. In compat.h some things are
0127    defined to make the transition easier. */
0128 static int ali1535_setup(struct pci_dev *dev)
0129 {
0130     int retval;
0131     unsigned char temp;
0132 
0133     /* Check the following things:
0134         - SMB I/O address is initialized
0135         - Device is enabled
0136         - We can use the addresses
0137     */
0138 
0139     retval = pci_enable_device(dev);
0140     if (retval) {
0141         dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
0142         goto exit;
0143     }
0144 
0145     /* Determine the address of the SMBus area */
0146     pci_read_config_word(dev, SMBBA, &ali1535_offset);
0147     dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
0148     ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
0149     if (ali1535_offset == 0) {
0150         dev_warn(&dev->dev,
0151             "ALI1535_smb region uninitialized - upgrade BIOS?\n");
0152         retval = -ENODEV;
0153         goto exit;
0154     }
0155 
0156     if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
0157         ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
0158     else
0159         ali1535_smba = ali1535_offset;
0160 
0161     retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
0162                    ali1535_driver.name);
0163     if (retval)
0164         goto exit;
0165 
0166     if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
0167                 ali1535_driver.name)) {
0168         dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
0169             ali1535_smba);
0170         retval = -EBUSY;
0171         goto exit;
0172     }
0173 
0174     /* check if whole device is enabled */
0175     pci_read_config_byte(dev, SMBCFG, &temp);
0176     if ((temp & ALI1535_SMBIO_EN) == 0) {
0177         dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
0178         retval = -ENODEV;
0179         goto exit_free;
0180     }
0181 
0182     /* Is SMB Host controller enabled? */
0183     pci_read_config_byte(dev, SMBHSTCFG, &temp);
0184     if ((temp & 1) == 0) {
0185         dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
0186         retval = -ENODEV;
0187         goto exit_free;
0188     }
0189 
0190     /* set SMB clock to 74KHz as recommended in data sheet */
0191     pci_write_config_byte(dev, SMBCLK, 0x20);
0192 
0193     /*
0194       The interrupt routing for SMB is set up in register 0x77 in the
0195       1533 ISA Bridge device, NOT in the 7101 device.
0196       Don't bother with finding the 1533 device and reading the register.
0197     if ((....... & 0x0F) == 1)
0198         dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n");
0199     */
0200     pci_read_config_byte(dev, SMBREV, &temp);
0201     dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
0202     dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);
0203 
0204     return 0;
0205 
0206 exit_free:
0207     release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
0208 exit:
0209     return retval;
0210 }
0211 
0212 static int ali1535_transaction(struct i2c_adapter *adap)
0213 {
0214     int temp;
0215     int result = 0;
0216     int timeout = 0;
0217 
0218     dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
0219         "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
0220         inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
0221         inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0222 
0223     /* get status */
0224     temp = inb_p(SMBHSTSTS);
0225 
0226     /* Make sure the SMBus host is ready to start transmitting */
0227     /* Check the busy bit first */
0228     if (temp & ALI1535_STS_BUSY) {
0229         /* If the host controller is still busy, it may have timed out
0230          * in the previous transaction, resulting in a "SMBus Timeout"
0231          * printk.  I've tried the following to reset a stuck busy bit.
0232          *   1. Reset the controller with an KILL command. (this
0233          *      doesn't seem to clear the controller if an external
0234          *      device is hung)
0235          *   2. Reset the controller and the other SMBus devices with a
0236          *      T_OUT command. (this clears the host busy bit if an
0237          *      external device is hung, but it comes back upon a new
0238          *      access to a device)
0239          *   3. Disable and reenable the controller in SMBHSTCFG. Worst
0240          *      case, nothing seems to work except power reset.
0241          */
0242 
0243         /* Try resetting entire SMB bus, including other devices - This
0244          * may not work either - it clears the BUSY bit but then the
0245          * BUSY bit may come back on when you try and use the chip
0246          * again.  If that's the case you are stuck.
0247          */
0248         dev_info(&adap->dev,
0249             "Resetting entire SMB Bus to clear busy condition (%02x)\n",
0250             temp);
0251         outb_p(ALI1535_T_OUT, SMBHSTTYP);
0252         temp = inb_p(SMBHSTSTS);
0253     }
0254 
0255     /* now check the error bits and the busy bit */
0256     if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
0257         /* do a clear-on-write */
0258         outb_p(0xFF, SMBHSTSTS);
0259         temp = inb_p(SMBHSTSTS);
0260         if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
0261             /* This is probably going to be correctable only by a
0262              * power reset as one of the bits now appears to be
0263              * stuck */
0264             /* This may be a bus or device with electrical problems. */
0265             dev_err(&adap->dev,
0266                 "SMBus reset failed! (0x%02x) - controller or "
0267                 "device on bus is probably hung\n", temp);
0268             return -EBUSY;
0269         }
0270     } else {
0271         /* check and clear done bit */
0272         if (temp & ALI1535_STS_DONE)
0273             outb_p(temp, SMBHSTSTS);
0274     }
0275 
0276     /* start the transaction by writing anything to the start register */
0277     outb_p(0xFF, SMBHSTPORT);
0278 
0279     /* We will always wait for a fraction of a second! */
0280     timeout = 0;
0281     do {
0282         usleep_range(1000, 2000);
0283         temp = inb_p(SMBHSTSTS);
0284     } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
0285          && (timeout++ < MAX_TIMEOUT));
0286 
0287     /* If the SMBus is still busy, we give up */
0288     if (timeout > MAX_TIMEOUT) {
0289         result = -ETIMEDOUT;
0290         dev_err(&adap->dev, "SMBus Timeout!\n");
0291     }
0292 
0293     if (temp & ALI1535_STS_FAIL) {
0294         result = -EIO;
0295         dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
0296     }
0297 
0298     /* Unfortunately the ALI SMB controller maps "no response" and "bus
0299      * collision" into a single bit. No response is the usual case so don't
0300      * do a printk.  This means that bus collisions go unreported.
0301      */
0302     if (temp & ALI1535_STS_BUSERR) {
0303         result = -ENXIO;
0304         dev_dbg(&adap->dev,
0305             "Error: no response or bus collision ADD=%02x\n",
0306             inb_p(SMBHSTADD));
0307     }
0308 
0309     /* haven't ever seen this */
0310     if (temp & ALI1535_STS_DEV) {
0311         result = -EIO;
0312         dev_err(&adap->dev, "Error: device error\n");
0313     }
0314 
0315     /* check to see if the "command complete" indication is set */
0316     if (!(temp & ALI1535_STS_DONE)) {
0317         result = -ETIMEDOUT;
0318         dev_err(&adap->dev, "Error: command never completed\n");
0319     }
0320 
0321     dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
0322         "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
0323         inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
0324         inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0325 
0326     /* take consequent actions for error conditions */
0327     if (!(temp & ALI1535_STS_DONE)) {
0328         /* issue "kill" to reset host controller */
0329         outb_p(ALI1535_KILL, SMBHSTTYP);
0330         outb_p(0xFF, SMBHSTSTS);
0331     } else if (temp & ALI1535_STS_ERR) {
0332         /* issue "timeout" to reset all devices on bus */
0333         outb_p(ALI1535_T_OUT, SMBHSTTYP);
0334         outb_p(0xFF, SMBHSTSTS);
0335     }
0336 
0337     return result;
0338 }
0339 
0340 /* Return negative errno on error. */
0341 static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
0342               unsigned short flags, char read_write, u8 command,
0343               int size, union i2c_smbus_data *data)
0344 {
0345     int i, len;
0346     int temp;
0347     int timeout;
0348     s32 result = 0;
0349 
0350     /* make sure SMBus is idle */
0351     temp = inb_p(SMBHSTSTS);
0352     for (timeout = 0;
0353          (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
0354          timeout++) {
0355         usleep_range(1000, 2000);
0356         temp = inb_p(SMBHSTSTS);
0357     }
0358     if (timeout >= MAX_TIMEOUT)
0359         dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
0360 
0361     /* clear status register (clear-on-write) */
0362     outb_p(0xFF, SMBHSTSTS);
0363 
0364     switch (size) {
0365     case I2C_SMBUS_QUICK:
0366         outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0367                SMBHSTADD);
0368         size = ALI1535_QUICK;
0369         outb_p(size, SMBHSTTYP);    /* output command */
0370         break;
0371     case I2C_SMBUS_BYTE:
0372         outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0373                SMBHSTADD);
0374         size = ALI1535_BYTE;
0375         outb_p(size, SMBHSTTYP);    /* output command */
0376         if (read_write == I2C_SMBUS_WRITE)
0377             outb_p(command, SMBHSTCMD);
0378         break;
0379     case I2C_SMBUS_BYTE_DATA:
0380         outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0381                SMBHSTADD);
0382         size = ALI1535_BYTE_DATA;
0383         outb_p(size, SMBHSTTYP);    /* output command */
0384         outb_p(command, SMBHSTCMD);
0385         if (read_write == I2C_SMBUS_WRITE)
0386             outb_p(data->byte, SMBHSTDAT0);
0387         break;
0388     case I2C_SMBUS_WORD_DATA:
0389         outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0390                SMBHSTADD);
0391         size = ALI1535_WORD_DATA;
0392         outb_p(size, SMBHSTTYP);    /* output command */
0393         outb_p(command, SMBHSTCMD);
0394         if (read_write == I2C_SMBUS_WRITE) {
0395             outb_p(data->word & 0xff, SMBHSTDAT0);
0396             outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
0397         }
0398         break;
0399     case I2C_SMBUS_BLOCK_DATA:
0400         outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0401                SMBHSTADD);
0402         size = ALI1535_BLOCK_DATA;
0403         outb_p(size, SMBHSTTYP);    /* output command */
0404         outb_p(command, SMBHSTCMD);
0405         if (read_write == I2C_SMBUS_WRITE) {
0406             len = data->block[0];
0407             if (len < 0) {
0408                 len = 0;
0409                 data->block[0] = len;
0410             }
0411             if (len > 32) {
0412                 len = 32;
0413                 data->block[0] = len;
0414             }
0415             outb_p(len, SMBHSTDAT0);
0416             /* Reset SMBBLKDAT */
0417             outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
0418             for (i = 1; i <= len; i++)
0419                 outb_p(data->block[i], SMBBLKDAT);
0420         }
0421         break;
0422     default:
0423         dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
0424         result = -EOPNOTSUPP;
0425         goto EXIT;
0426     }
0427 
0428     result = ali1535_transaction(adap);
0429     if (result)
0430         goto EXIT;
0431 
0432     if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
0433         result = 0;
0434         goto EXIT;
0435     }
0436 
0437     switch (size) {
0438     case ALI1535_BYTE:  /* Result put in SMBHSTDAT0 */
0439         data->byte = inb_p(SMBHSTDAT0);
0440         break;
0441     case ALI1535_BYTE_DATA:
0442         data->byte = inb_p(SMBHSTDAT0);
0443         break;
0444     case ALI1535_WORD_DATA:
0445         data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
0446         break;
0447     case ALI1535_BLOCK_DATA:
0448         len = inb_p(SMBHSTDAT0);
0449         if (len > 32)
0450             len = 32;
0451         data->block[0] = len;
0452         /* Reset SMBBLKDAT */
0453         outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
0454         for (i = 1; i <= data->block[0]; i++) {
0455             data->block[i] = inb_p(SMBBLKDAT);
0456             dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
0457                 len, i, data->block[i]);
0458         }
0459         break;
0460     }
0461 EXIT:
0462     return result;
0463 }
0464 
0465 
0466 static u32 ali1535_func(struct i2c_adapter *adapter)
0467 {
0468     return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
0469         I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
0470         I2C_FUNC_SMBUS_BLOCK_DATA;
0471 }
0472 
0473 static const struct i2c_algorithm smbus_algorithm = {
0474     .smbus_xfer = ali1535_access,
0475     .functionality  = ali1535_func,
0476 };
0477 
0478 static struct i2c_adapter ali1535_adapter = {
0479     .owner      = THIS_MODULE,
0480     .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
0481     .algo       = &smbus_algorithm,
0482 };
0483 
0484 static const struct pci_device_id ali1535_ids[] = {
0485     { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
0486     { },
0487 };
0488 
0489 MODULE_DEVICE_TABLE(pci, ali1535_ids);
0490 
0491 static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
0492 {
0493     if (ali1535_setup(dev)) {
0494         dev_warn(&dev->dev,
0495             "ALI1535 not detected, module not inserted.\n");
0496         return -ENODEV;
0497     }
0498 
0499     /* set up the sysfs linkage to our parent device */
0500     ali1535_adapter.dev.parent = &dev->dev;
0501 
0502     snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
0503         "SMBus ALI1535 adapter at %04x", ali1535_offset);
0504     return i2c_add_adapter(&ali1535_adapter);
0505 }
0506 
0507 static void ali1535_remove(struct pci_dev *dev)
0508 {
0509     i2c_del_adapter(&ali1535_adapter);
0510     release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
0511 
0512     /*
0513      * do not call pci_disable_device(dev) since it can cause hard hangs on
0514      * some systems during power-off
0515      */
0516 }
0517 
0518 static struct pci_driver ali1535_driver = {
0519     .name       = "ali1535_smbus",
0520     .id_table   = ali1535_ids,
0521     .probe      = ali1535_probe,
0522     .remove     = ali1535_remove,
0523 };
0524 
0525 module_pci_driver(ali1535_driver);
0526 
0527 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
0528 MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
0529 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
0530 MODULE_AUTHOR("Dan Eaton <dan.eaton@rocketlogix.com>");
0531 MODULE_DESCRIPTION("ALI1535 SMBus driver");
0532 MODULE_LICENSE("GPL");