15bc12008SAlek Du /* 25bc12008SAlek Du i2c-isch.c - Linux kernel driver for Intel SCH chipset SMBus 35bc12008SAlek Du - Based on i2c-piix4.c 45bc12008SAlek Du Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and 55bc12008SAlek Du Philip Edelbrock <phil@netroedge.com> 65bc12008SAlek Du - Intel SCH support 75bc12008SAlek Du Copyright (c) 2007 - 2008 Jacob Jun Pan <jacob.jun.pan@intel.com> 85bc12008SAlek Du 95bc12008SAlek Du This program is free software; you can redistribute it and/or modify 105bc12008SAlek Du it under the terms of the GNU General Public License version 2 as 115bc12008SAlek Du published by the Free Software Foundation. 125bc12008SAlek Du 135bc12008SAlek Du This program is distributed in the hope that it will be useful, 145bc12008SAlek Du but WITHOUT ANY WARRANTY; without even the implied warranty of 155bc12008SAlek Du MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 165bc12008SAlek Du GNU General Public License for more details. 175bc12008SAlek Du 185bc12008SAlek Du You should have received a copy of the GNU General Public License 195bc12008SAlek Du along with this program; if not, write to the Free Software 205bc12008SAlek Du Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 215bc12008SAlek Du */ 225bc12008SAlek Du 235bc12008SAlek Du /* 245bc12008SAlek Du Supports: 255bc12008SAlek Du Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L) 265bc12008SAlek Du Note: we assume there can only be one device, with one SMBus interface. 275bc12008SAlek Du */ 285bc12008SAlek Du 295bc12008SAlek Du #include <linux/module.h> 30fd46a006SDenis Turischev #include <linux/platform_device.h> 315bc12008SAlek Du #include <linux/kernel.h> 325bc12008SAlek Du #include <linux/delay.h> 335bc12008SAlek Du #include <linux/stddef.h> 345bc12008SAlek Du #include <linux/ioport.h> 355bc12008SAlek Du #include <linux/i2c.h> 365bc12008SAlek Du #include <linux/init.h> 375bc12008SAlek Du #include <linux/io.h> 3854fb4a05SJean Delvare #include <linux/acpi.h> 395bc12008SAlek Du 405bc12008SAlek Du /* SCH SMBus address offsets */ 415bc12008SAlek Du #define SMBHSTCNT (0 + sch_smba) 425bc12008SAlek Du #define SMBHSTSTS (1 + sch_smba) 43b08369a1SAlexander Stein #define SMBHSTCLK (2 + sch_smba) 445bc12008SAlek Du #define SMBHSTADD (4 + sch_smba) /* TSA */ 455bc12008SAlek Du #define SMBHSTCMD (5 + sch_smba) 465bc12008SAlek Du #define SMBHSTDAT0 (6 + sch_smba) 475bc12008SAlek Du #define SMBHSTDAT1 (7 + sch_smba) 485bc12008SAlek Du #define SMBBLKDAT (0x20 + sch_smba) 495bc12008SAlek Du 505bc12008SAlek Du /* Other settings */ 51b3240e68SOlivier Sobrie #define MAX_RETRIES 5000 525bc12008SAlek Du 535bc12008SAlek Du /* I2C constants */ 545bc12008SAlek Du #define SCH_QUICK 0x00 555bc12008SAlek Du #define SCH_BYTE 0x01 565bc12008SAlek Du #define SCH_BYTE_DATA 0x02 575bc12008SAlek Du #define SCH_WORD_DATA 0x03 585bc12008SAlek Du #define SCH_BLOCK_DATA 0x05 595bc12008SAlek Du 605bc12008SAlek Du static unsigned short sch_smba; 615bc12008SAlek Du static struct i2c_adapter sch_adapter; 62b08369a1SAlexander Stein static int backbone_speed = 33000; /* backbone speed in kHz */ 63b08369a1SAlexander Stein module_param(backbone_speed, int, S_IRUSR | S_IWUSR); 64b08369a1SAlexander Stein MODULE_PARM_DESC(backbone_speed, "Backbone speed in kHz, (default = 33000)"); 655bc12008SAlek Du 665bc12008SAlek Du /* 675bc12008SAlek Du * Start the i2c transaction -- the i2c_access will prepare the transaction 685bc12008SAlek Du * and this function will execute it. 695bc12008SAlek Du * return 0 for success and others for failure. 705bc12008SAlek Du */ 715bc12008SAlek Du static int sch_transaction(void) 725bc12008SAlek Du { 735bc12008SAlek Du int temp; 745bc12008SAlek Du int result = 0; 75b3240e68SOlivier Sobrie int retries = 0; 765bc12008SAlek Du 775bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " 785bc12008SAlek Du "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT), 795bc12008SAlek Du inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0), 805bc12008SAlek Du inb(SMBHSTDAT1)); 815bc12008SAlek Du 825bc12008SAlek Du /* Make sure the SMBus host is ready to start transmitting */ 835bc12008SAlek Du temp = inb(SMBHSTSTS) & 0x0f; 845bc12008SAlek Du if (temp) { 855bc12008SAlek Du /* Can not be busy since we checked it in sch_access */ 865bc12008SAlek Du if (temp & 0x01) { 875bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Completion (%02x). " 885bc12008SAlek Du "Clear...\n", temp); 895bc12008SAlek Du } 905bc12008SAlek Du if (temp & 0x06) { 915bc12008SAlek Du dev_dbg(&sch_adapter.dev, "SMBus error (%02x). " 925bc12008SAlek Du "Resetting...\n", temp); 935bc12008SAlek Du } 945bc12008SAlek Du outb(temp, SMBHSTSTS); 955bc12008SAlek Du temp = inb(SMBHSTSTS) & 0x0f; 965bc12008SAlek Du if (temp) { 975bc12008SAlek Du dev_err(&sch_adapter.dev, 985bc12008SAlek Du "SMBus is not ready: (%02x)\n", temp); 995bc12008SAlek Du return -EAGAIN; 1005bc12008SAlek Du } 1015bc12008SAlek Du } 1025bc12008SAlek Du 1035bc12008SAlek Du /* start the transaction by setting bit 4 */ 1045bc12008SAlek Du outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT); 1055bc12008SAlek Du 1065bc12008SAlek Du do { 107b3240e68SOlivier Sobrie usleep_range(100, 200); 1085bc12008SAlek Du temp = inb(SMBHSTSTS) & 0x0f; 109b3240e68SOlivier Sobrie } while ((temp & 0x08) && (retries++ < MAX_RETRIES)); 1105bc12008SAlek Du 1115bc12008SAlek Du /* If the SMBus is still busy, we give up */ 112b3240e68SOlivier Sobrie if (retries > MAX_RETRIES) { 1135bc12008SAlek Du dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); 1145bc12008SAlek Du result = -ETIMEDOUT; 1155bc12008SAlek Du } 1165bc12008SAlek Du if (temp & 0x04) { 1175bc12008SAlek Du result = -EIO; 1185bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be " 1195bc12008SAlek Du "locked until next hard reset. (sorry!)\n"); 1205bc12008SAlek Du /* Clock stops and slave is stuck in mid-transmission */ 1215bc12008SAlek Du } else if (temp & 0x02) { 1225bc12008SAlek Du result = -EIO; 1235bc12008SAlek Du dev_err(&sch_adapter.dev, "Error: no response!\n"); 1245bc12008SAlek Du } else if (temp & 0x01) { 1255bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Post complete!\n"); 1265bc12008SAlek Du outb(temp, SMBHSTSTS); 1275bc12008SAlek Du temp = inb(SMBHSTSTS) & 0x07; 1285bc12008SAlek Du if (temp & 0x06) { 1295bc12008SAlek Du /* Completion clear failed */ 1305bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Failed reset at end of " 1315bc12008SAlek Du "transaction (%02x), Bus error!\n", temp); 1325bc12008SAlek Du } 1335bc12008SAlek Du } else { 1345bc12008SAlek Du result = -ENXIO; 1355bc12008SAlek Du dev_dbg(&sch_adapter.dev, "No such address.\n"); 1365bc12008SAlek Du } 1375bc12008SAlek Du dev_dbg(&sch_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " 1385bc12008SAlek Du "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT), 1395bc12008SAlek Du inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0), 1405bc12008SAlek Du inb(SMBHSTDAT1)); 1415bc12008SAlek Du return result; 1425bc12008SAlek Du } 1435bc12008SAlek Du 1445bc12008SAlek Du /* 1455bc12008SAlek Du * This is the main access entry for i2c-sch access 1465bc12008SAlek Du * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write 1475bc12008SAlek Du * (0 for read and 1 for write), size is i2c transaction type and data is the 14825985edcSLucas De Marchi * union of transaction for data to be transferred or data read from bus. 1495bc12008SAlek Du * return 0 for success and others for failure. 1505bc12008SAlek Du */ 1515bc12008SAlek Du static s32 sch_access(struct i2c_adapter *adap, u16 addr, 1525bc12008SAlek Du unsigned short flags, char read_write, 1535bc12008SAlek Du u8 command, int size, union i2c_smbus_data *data) 1545bc12008SAlek Du { 1555bc12008SAlek Du int i, len, temp, rc; 1565bc12008SAlek Du 1575bc12008SAlek Du /* Make sure the SMBus host is not busy */ 1585bc12008SAlek Du temp = inb(SMBHSTSTS) & 0x0f; 1595bc12008SAlek Du if (temp & 0x08) { 1605bc12008SAlek Du dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp); 1615bc12008SAlek Du return -EAGAIN; 1625bc12008SAlek Du } 163b08369a1SAlexander Stein temp = inw(SMBHSTCLK); 164b08369a1SAlexander Stein if (!temp) { 165b08369a1SAlexander Stein /* 166b08369a1SAlexander Stein * We can't determine if we have 33 or 25 MHz clock for 167b08369a1SAlexander Stein * SMBus, so expect 33 MHz and calculate a bus clock of 168b08369a1SAlexander Stein * 100 kHz. If we actually run at 25 MHz the bus will be 169b08369a1SAlexander Stein * run ~75 kHz instead which should do no harm. 170b08369a1SAlexander Stein */ 171b08369a1SAlexander Stein dev_notice(&sch_adapter.dev, 172b08369a1SAlexander Stein "Clock divider unitialized. Setting defaults\n"); 173b08369a1SAlexander Stein outw(backbone_speed / (4 * 100), SMBHSTCLK); 174b08369a1SAlexander Stein } 175b08369a1SAlexander Stein 1765bc12008SAlek Du dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size, 1775bc12008SAlek Du (read_write)?"READ":"WRITE"); 1785bc12008SAlek Du switch (size) { 1795bc12008SAlek Du case I2C_SMBUS_QUICK: 1805bc12008SAlek Du outb((addr << 1) | read_write, SMBHSTADD); 1815bc12008SAlek Du size = SCH_QUICK; 1825bc12008SAlek Du break; 1835bc12008SAlek Du case I2C_SMBUS_BYTE: 1845bc12008SAlek Du outb((addr << 1) | read_write, SMBHSTADD); 1855bc12008SAlek Du if (read_write == I2C_SMBUS_WRITE) 1865bc12008SAlek Du outb(command, SMBHSTCMD); 1875bc12008SAlek Du size = SCH_BYTE; 1885bc12008SAlek Du break; 1895bc12008SAlek Du case I2C_SMBUS_BYTE_DATA: 1905bc12008SAlek Du outb((addr << 1) | read_write, SMBHSTADD); 1915bc12008SAlek Du outb(command, SMBHSTCMD); 1925bc12008SAlek Du if (read_write == I2C_SMBUS_WRITE) 1935bc12008SAlek Du outb(data->byte, SMBHSTDAT0); 1945bc12008SAlek Du size = SCH_BYTE_DATA; 1955bc12008SAlek Du break; 1965bc12008SAlek Du case I2C_SMBUS_WORD_DATA: 1975bc12008SAlek Du outb((addr << 1) | read_write, SMBHSTADD); 1985bc12008SAlek Du outb(command, SMBHSTCMD); 1995bc12008SAlek Du if (read_write == I2C_SMBUS_WRITE) { 2005bc12008SAlek Du outb(data->word & 0xff, SMBHSTDAT0); 2015bc12008SAlek Du outb((data->word & 0xff00) >> 8, SMBHSTDAT1); 2025bc12008SAlek Du } 2035bc12008SAlek Du size = SCH_WORD_DATA; 2045bc12008SAlek Du break; 2055bc12008SAlek Du case I2C_SMBUS_BLOCK_DATA: 2065bc12008SAlek Du outb((addr << 1) | read_write, SMBHSTADD); 2075bc12008SAlek Du outb(command, SMBHSTCMD); 2085bc12008SAlek Du if (read_write == I2C_SMBUS_WRITE) { 2095bc12008SAlek Du len = data->block[0]; 2105bc12008SAlek Du if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) 2115bc12008SAlek Du return -EINVAL; 2125bc12008SAlek Du outb(len, SMBHSTDAT0); 2135bc12008SAlek Du for (i = 1; i <= len; i++) 2145bc12008SAlek Du outb(data->block[i], SMBBLKDAT+i-1); 2155bc12008SAlek Du } 2165bc12008SAlek Du size = SCH_BLOCK_DATA; 2175bc12008SAlek Du break; 2185bc12008SAlek Du default: 2195bc12008SAlek Du dev_warn(&adap->dev, "Unsupported transaction %d\n", size); 2205bc12008SAlek Du return -EOPNOTSUPP; 2215bc12008SAlek Du } 2225bc12008SAlek Du dev_dbg(&sch_adapter.dev, "write size %d to 0x%04x\n", size, SMBHSTCNT); 2235bc12008SAlek Du outb((inb(SMBHSTCNT) & 0xb0) | (size & 0x7), SMBHSTCNT); 2245bc12008SAlek Du 2255bc12008SAlek Du rc = sch_transaction(); 2265bc12008SAlek Du if (rc) /* Error in transaction */ 2275bc12008SAlek Du return rc; 2285bc12008SAlek Du 2295bc12008SAlek Du if ((read_write == I2C_SMBUS_WRITE) || (size == SCH_QUICK)) 2305bc12008SAlek Du return 0; 2315bc12008SAlek Du 2325bc12008SAlek Du switch (size) { 2335bc12008SAlek Du case SCH_BYTE: 2345bc12008SAlek Du case SCH_BYTE_DATA: 2355bc12008SAlek Du data->byte = inb(SMBHSTDAT0); 2365bc12008SAlek Du break; 2375bc12008SAlek Du case SCH_WORD_DATA: 2385bc12008SAlek Du data->word = inb(SMBHSTDAT0) + (inb(SMBHSTDAT1) << 8); 2395bc12008SAlek Du break; 2405bc12008SAlek Du case SCH_BLOCK_DATA: 2415bc12008SAlek Du data->block[0] = inb(SMBHSTDAT0); 2425bc12008SAlek Du if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) 2435bc12008SAlek Du return -EPROTO; 2445bc12008SAlek Du for (i = 1; i <= data->block[0]; i++) 2455bc12008SAlek Du data->block[i] = inb(SMBBLKDAT+i-1); 2465bc12008SAlek Du break; 2475bc12008SAlek Du } 2485bc12008SAlek Du return 0; 2495bc12008SAlek Du } 2505bc12008SAlek Du 2515bc12008SAlek Du static u32 sch_func(struct i2c_adapter *adapter) 2525bc12008SAlek Du { 2535bc12008SAlek Du return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 2545bc12008SAlek Du I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 2555bc12008SAlek Du I2C_FUNC_SMBUS_BLOCK_DATA; 2565bc12008SAlek Du } 2575bc12008SAlek Du 2585bc12008SAlek Du static const struct i2c_algorithm smbus_algorithm = { 2595bc12008SAlek Du .smbus_xfer = sch_access, 2605bc12008SAlek Du .functionality = sch_func, 2615bc12008SAlek Du }; 2625bc12008SAlek Du 2635bc12008SAlek Du static struct i2c_adapter sch_adapter = { 2645bc12008SAlek Du .owner = THIS_MODULE, 2653401b2ffSJean Delvare .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 2665bc12008SAlek Du .algo = &smbus_algorithm, 2675bc12008SAlek Du }; 2685bc12008SAlek Du 2690b255e92SBill Pemberton static int smbus_sch_probe(struct platform_device *dev) 2705bc12008SAlek Du { 271fd46a006SDenis Turischev struct resource *res; 2725bc12008SAlek Du int retval; 2735bc12008SAlek Du 274fd46a006SDenis Turischev res = platform_get_resource(dev, IORESOURCE_IO, 0); 275fd46a006SDenis Turischev if (!res) 276fd46a006SDenis Turischev return -EBUSY; 2775bc12008SAlek Du 27834d7ffa0SJingoo Han if (!devm_request_region(&dev->dev, res->start, resource_size(res), 27934d7ffa0SJingoo Han dev->name)) { 2805bc12008SAlek Du dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", 2815bc12008SAlek Du sch_smba); 2825bc12008SAlek Du return -EBUSY; 2835bc12008SAlek Du } 284fd46a006SDenis Turischev 285fd46a006SDenis Turischev sch_smba = res->start; 286fd46a006SDenis Turischev 2875bc12008SAlek Du dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba); 2885bc12008SAlek Du 2895bc12008SAlek Du /* set up the sysfs linkage to our parent device */ 2905bc12008SAlek Du sch_adapter.dev.parent = &dev->dev; 2915bc12008SAlek Du 2925bc12008SAlek Du snprintf(sch_adapter.name, sizeof(sch_adapter.name), 2935bc12008SAlek Du "SMBus SCH adapter at %04x", sch_smba); 2945bc12008SAlek Du 2955bc12008SAlek Du retval = i2c_add_adapter(&sch_adapter); 2965bc12008SAlek Du if (retval) { 2975bc12008SAlek Du dev_err(&dev->dev, "Couldn't register adapter!\n"); 2985bc12008SAlek Du sch_smba = 0; 2995bc12008SAlek Du } 3005bc12008SAlek Du 3015bc12008SAlek Du return retval; 3025bc12008SAlek Du } 3035bc12008SAlek Du 3040b255e92SBill Pemberton static int smbus_sch_remove(struct platform_device *pdev) 3055bc12008SAlek Du { 3065bc12008SAlek Du if (sch_smba) { 3075bc12008SAlek Du i2c_del_adapter(&sch_adapter); 3085bc12008SAlek Du sch_smba = 0; 3095bc12008SAlek Du } 310fd46a006SDenis Turischev 311fd46a006SDenis Turischev return 0; 3125bc12008SAlek Du } 3135bc12008SAlek Du 314fd46a006SDenis Turischev static struct platform_driver smbus_sch_driver = { 315fd46a006SDenis Turischev .driver = { 3165bc12008SAlek Du .name = "isch_smbus", 317fd46a006SDenis Turischev .owner = THIS_MODULE, 318fd46a006SDenis Turischev }, 319fd46a006SDenis Turischev .probe = smbus_sch_probe, 3200b255e92SBill Pemberton .remove = smbus_sch_remove, 3215bc12008SAlek Du }; 3225bc12008SAlek Du 323a3664b51SAxel Lin module_platform_driver(smbus_sch_driver); 3245bc12008SAlek Du 3255bc12008SAlek Du MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>"); 3265bc12008SAlek Du MODULE_DESCRIPTION("Intel SCH SMBus driver"); 3275bc12008SAlek Du MODULE_LICENSE("GPL"); 328fd46a006SDenis Turischev MODULE_ALIAS("platform:isch_smbus"); 329