[PATCH V2 REPOST] i2c: add bcm2835 driver
This implements a very basic I2C host driver for the BCM2835 SoC. Missing features so far are: * 10-bit addressing. * DMA. Signed-off-by: Stephen Warren --- v2: * Implemented clock divider configuration based on desired bus rate. * Make use of module_platform_driver(). * Removed use of devinit. --- .../devicetree/bindings/i2c/brcm,bcm2835-i2c.txt | 20 ++ drivers/i2c/busses/Kconfig | 12 + drivers/i2c/busses/Makefile|1 + drivers/i2c/busses/i2c-bcm2835.c | 346 4 files changed, 379 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/brcm,bcm2835-i2c.txt create mode 100644 drivers/i2c/busses/i2c-bcm2835.c diff --git a/Documentation/devicetree/bindings/i2c/brcm,bcm2835-i2c.txt b/Documentation/devicetree/bindings/i2c/brcm,bcm2835-i2c.txt new file mode 100644 index 000..e9de375 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/brcm,bcm2835-i2c.txt @@ -0,0 +1,20 @@ +Broadcom BCM2835 I2C controller + +Required properties: +- compatible : Should be "brcm,bcm2835-i2c". +- reg: Should contain register location and length. +- interrupts: Should contain interrupt. +- clocks : The clock feeding the I2C controller. + +Recommended properties: +- clock-frequency : desired I2C bus clock frequency in Hz. + +Example: + +i2c@20205000 { + compatible = "brcm,bcm2835-i2c"; + reg = <0x7e205000 0x1000>; + interrupts = <2 21>; + clocks = <&clk_i2c>; + clock-frequency = <10>; +}; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 8bb810e..3cc40ab 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -319,6 +319,18 @@ config I2C_AU1550 This driver can also be built as a module. If so, the module will be called i2c-au1550. +config I2C_BCM2835 + tristate "Broadcom BCM2835 I2C controller" + depends on ARCH_BCM2835 + help + If you say yes to this option, support will be included for the + BCM2835 I2C controller. + + If you don't know what to do here, say N. + + This support is also available as a module. If so, the module + will be called i2c-bcm2835. + config I2C_BLACKFIN_TWI tristate "Blackfin TWI I2C support" depends on BLACKFIN diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 6181f3f..a52a891 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_POWERMAC)+= i2c-powermac.o # Embedded system I2C/SMBus host controller drivers obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o +obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_CBUS_GPIO)+= i2c-cbus-gpio.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c new file mode 100644 index 000..22a29de --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -0,0 +1,346 @@ +/* + * BCM2835 master mode driver + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BCM2835_I2C_C 0x0 +#define BCM2835_I2C_S 0x4 +#define BCM2835_I2C_DLEN 0x8 +#define BCM2835_I2C_A 0xc +#define BCM2835_I2C_FIFO 0x10 +#define BCM2835_I2C_DIV0x14 +#define BCM2835_I2C_DEL0x18 +#define BCM2835_I2C_CLKT 0x1c + +#define BCM2835_I2C_C_READ BIT(0) +#define BCM2835_I2C_C_CLEARBIT(4) /* bits 4 and 5 both clear */ +#define BCM2835_I2C_C_ST BIT(7) +#define BCM2835_I2C_C_INTD BIT(8) +#define BCM2835_I2C_C_INTT BIT(9) +#define BCM2835_I2C_C_INTR BIT(10) +#define BCM2835_I2C_C_I2CENBIT(15) + +#define BCM2835_I2C_S_TA BIT(0) +#define BCM2835_I2C_S_DONE BIT(1) +#define BCM2835_I2C_S_TXW BIT(2) +#define BCM2835_I2C_S_RXR BIT(3) +#define BCM2835_I2C_S_TXD BIT(4) +#define BCM2835_I2C_S_RXD BIT(5) +#define BCM2835_I2C_S_TXE BIT(6) +#define BCM2835_I2C_S_RXF BIT(7) +#define BCM2835_I2C_S_ERR BIT(8) +#define BCM2835_I2C_S_CLKT BIT(9) +#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */ + +#define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000)) + +struct bcm2835_i2c_dev { + struct device *dev; + void __iomem *regs; + struct clk *clk; + struc
[PATCH v3 6/6] Cleanup
This patch corrects checkpatch errors. The changes has also been removed as it has less meaning with version control tools. Signed-off-by: Amaury Decrême --- drivers/i2c/busses/i2c-sis630.c | 210 1 file changed, 106 insertions(+), 104 deletions(-) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 424545b..0376318 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -17,25 +17,6 @@ */ /* - Changes: - 24.08.2002 - Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) - Changed sis630_transaction.(Thanks to Mark M. Hoffman) - 18.09.2002 - Added SIS730 as supported. - 21.09.2002 - Added high_clock module option.If this option is set - used Host Master Clock 56KHz (default 14KHz).For now we save old Host - Master Clock and after transaction completed restore (otherwise - it's confuse BIOS and hung Machine). - 24.09.2002 - Fixed typo in sis630_access - Fixed logical error by restoring of Host Master Clock - 31.07.2003 - Added block data read/write support. -*/ - -/* Status: beta Supports: @@ -150,9 +131,10 @@ static inline void sis630_write(u8 reg, u8 data) outb(data, smbus_base + reg); } -static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock) +static int sis630_transaction_start(struct i2c_adapter *adap, int size, + u8 *oldclock) { -int temp; + int temp; /* Make sure the SMBus host is ready to start transmitting. */ temp = sis630_read(SMB_CNT); @@ -165,17 +147,18 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc if (temp & (SMB_PROBE | SMB_HOSTBUSY)) { dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); return -EBUSY; -} else { + } else { dev_dbg(&adap->dev, "Successful!\n"); } -} + } /* save old clock, so we can prevent machine for hung */ *oldclock = sis630_read(SMB_CNT); dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock); - /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */ + /* disable timeout interrupt, +* set Host Master Clock to 56KHz if requested */ if (high_clock) sis630_write(SMB_CNT, SMBCLK_SEL); else @@ -228,7 +211,8 @@ static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) /* clear all status "sticky" bits */ sis630_write(SMB_STS, 0xFF); - dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); + dev_dbg(&adap->dev, + "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); /* * restore old Host Master Clock if high_clock is set @@ -237,7 +221,8 @@ static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) if (high_clock && !(oldclock & SMBCLK_SEL)) sis630_write(SMB_CNT, sis630_read(SMB_CNT) & ~SMBCLK_SEL); - dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); + dev_dbg(&adap->dev, + "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); } static int sis630_transaction(struct i2c_adapter *adap, int size) @@ -254,7 +239,8 @@ static int sis630_transaction(struct i2c_adapter *adap, int size) return result; } -static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write) +static int sis630_block_data(struct i2c_adapter *adap, + union i2c_smbus_data *data, int read_write) { int i, len = 0, rc = 0; u8 oldclock = 0; @@ -266,22 +252,26 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat else if (len > 32) len = 32; sis630_write(SMB_COUNT, len); - for (i=1; i <= len; i++) { - dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]); + for (i = 1; i <= len; i++) { + dev_dbg(&adap->dev, + "set data 0x%02x\n", data->block[i]); /* set data */ - sis630_write(SMB_BYTE+(i-1)%8, data->block[i]); - if (i==8 || (len<8 && i==len)) { - dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); + sis630_write(SMB_BYTE + (i - 1) % 8, data->block[i]); + if (i == 8 || (len < 8 && i == len)) { + dev_dbg(&adap->dev, + "start trans len=%d i=%d\n", len, i);
[PATCH v3 5/6] Misc: display unsigned hex
This patch corrects the display of the acpi_base unsigned hex value. Signed-off-by: Amaury Decrême --- drivers/i2c/busses/i2c-sis630.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index b2fa741..424545b 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -463,7 +463,7 @@ static int sis630_setup(struct pci_dev *sis630_dev) goto exit; } - dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base); + dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04hx\n", acpi_base); if (supported[i] == PCI_DEVICE_ID_SI_760) smbus_base = acpi_base + 0xE0; -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/6] Cosmetics: hex to constants for SMBus commands
This patch replaces hexadecimal values by constants for SMBus commands. Signed-off-by: Amaury Decrême --- drivers/i2c/busses/i2c-sis630.c | 45 - 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index e152d36..b2fa741 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -81,6 +81,21 @@ #define SMB_COUNT 0x07/* byte count */ #define SMB_BYTE 0x08/* ~0x8F data byte field */ +/* SMB_STS register */ +#define BYTE_DONE_STS 0x10/* Byte Done Status / Block Array */ +#define SMBCOL_STS 0x04/* Collision */ +#define SMBERR_STS 0x02/* Device error */ + +/* SMB_CNT register */ +#define MSTO_EN0x40/* Host Master Timeout Enable */ +#define SMBCLK_SEL 0x20/* Host master clock selection */ +#define SMB_PROBE 0x02/* Bus Probe/Slave busy */ +#define SMB_HOSTBUSY 0x01/* Host Busy */ + +/* SMBHOST_CNT register */ +#define SMB_KILL 0x20/* Kill */ +#define SMB_START 0x10/* Start */ + /* register count for request_region * As we don't use SMB_PCOUNT, 20 is ok for SiS630 and SiS964 */ @@ -140,12 +155,14 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc int temp; /* Make sure the SMBus host is ready to start transmitting. */ - if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { - dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp); + temp = sis630_read(SMB_CNT); + if ((temp & (SMB_PROBE | SMB_HOSTBUSY)) != 0x00) { + dev_dbg(&adap->dev, "SMBus busy (%02x). Resetting...\n", temp); /* kill smbus transaction */ - sis630_write(SMBHOST_CNT, 0x20); + sis630_write(SMBHOST_CNT, SMB_KILL); - if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { + temp = sis630_read(SMB_CNT); + if (temp & (SMB_PROBE | SMB_HOSTBUSY)) { dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); return -EBUSY; } else { @@ -160,16 +177,16 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */ if (high_clock) - sis630_write(SMB_CNT, 0x20); + sis630_write(SMB_CNT, SMBCLK_SEL); else - sis630_write(SMB_CNT, (*oldclock & ~0x40)); + sis630_write(SMB_CNT, (*oldclock & ~MSTO_EN)); /* clear all sticky bits */ temp = sis630_read(SMB_STS); sis630_write(SMB_STS, temp & 0x1e); /* start the transaction by setting bit 4 and size */ - sis630_write(SMBHOST_CNT,0x10 | (size & 0x07)); + sis630_write(SMBHOST_CNT, SMB_START | (size & 0x07)); return 0; } @@ -183,7 +200,7 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) msleep(1); temp = sis630_read(SMB_STS); /* check if block transmitted */ - if (size == SIS630_BLOCK_DATA && (temp & 0x10)) + if (size == SIS630_BLOCK_DATA && (temp & BYTE_DONE_STS)) break; } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); @@ -193,12 +210,12 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) result = -ETIMEDOUT; } - if (temp & 0x02) { + if (temp & SMBERR_STS) { dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); result = -ENXIO; } - if (temp & 0x04) { + if (temp & SMBCOL_STS) { dev_err(&adap->dev, "Bus collision!\n"); result = -EAGAIN; } @@ -217,8 +234,8 @@ static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) * restore old Host Master Clock if high_clock is set * and oldclock was not 56KHz */ - if (high_clock && !(oldclock & 0x20)) - sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20)); + if (high_clock && !(oldclock & SMBCLK_SEL)) + sis630_write(SMB_CNT, sis630_read(SMB_CNT) & ~SMBCLK_SEL); dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); } @@ -270,7 +287,7 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat we must clear sticky bit. clear SMBARY_STS */ - sis630_write(SMB_STS,0x10); + sis630_write(SMB_STS, BYTE_DONE_STS); }
[PATCH v3 3/6] Bugfix: behavior after collision
Datasheet on collision: SMBus Collision (SMBCOL_STS) This bit is set when a SMBus Collision condition occurs and SMBus Host loses in the bus arbitration. The software should clear this bit and re-start SMBus operation. As the status will be cleared in transaction_end, we can remove the sis630_write and prepare to return -EAGAIN to retry. Signed-off-by: Amaury Decrême --- drivers/i2c/busses/i2c-sis630.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 3124d80..e152d36 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -200,12 +200,7 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) if (temp & 0x04) { dev_err(&adap->dev, "Bus collision!\n"); - result = -EIO; - /* - TBD: Datasheet say: - the software should clear this bit and restart SMBUS operation. - Should we do it or user start request again? - */ + result = -EAGAIN; } return result; -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/6] Bugfix: clear sticky bits
The sticky bits must be cleared at the end of the transaction by writing a 1 to all fields. Datasheet: SMBus Status (SMB_STS) The following registers are all sticky bits and only can be cleared by writing a one to their corresponding fields. Signed-off-by: Amaury Decrême --- drivers/i2c/busses/i2c-sis630.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index df8e20a..3124d80 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -213,10 +213,8 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) { - int temp = 0; - /* clear all status "sticky" bits */ - sis630_write(SMB_STS, temp); + sis630_write(SMB_STS, 0xFF); dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/6] Add SIS964 bus support to i2c-sis630.
Signed-off-by: Amaury Decrême --- Documentation/i2c/busses/i2c-sis630 | 9 drivers/i2c/busses/Kconfig | 4 +- drivers/i2c/busses/i2c-sis630.c | 88 - 3 files changed, 69 insertions(+), 32 deletions(-) diff --git a/Documentation/i2c/busses/i2c-sis630 b/Documentation/i2c/busses/i2c-sis630 index 0b96973..ee79436 100644 --- a/Documentation/i2c/busses/i2c-sis630 +++ b/Documentation/i2c/busses/i2c-sis630 @@ -4,9 +4,11 @@ Supported adapters: * Silicon Integrated Systems Corp (SiS) 630 chipset (Datasheet: available at http://www.sfr-fresh.com/linux) 730 chipset + 964 chipset * Possible other SiS chipsets ? Author: Alexander Malysh + Amaury Decrême - SiS964 support Module Parameters - @@ -18,6 +20,7 @@ Module Parameters * high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default, what your BIOS use). DANGEROUS! This should be a bit faster, but freeze some systems (i.e. my Laptop). + SIS630/730 chip only. Description @@ -36,6 +39,12 @@ or like this: 00:00.0 Host bridge: Silicon Integrated Systems [SiS] 730 Host (rev 02) 00:01.0 ISA bridge: Silicon Integrated Systems [SiS] 85C503/5513 +or like this: + +00:00.0 Host bridge: Silicon Integrated Systems [SiS] 760/M760 Host (rev 02) +00:02.0 ISA bridge: Silicon Integrated Systems [SiS] SiS964 [MuTIOL Media IO] + LPC Controller (rev 36) + in your 'lspci' output , then this driver is for your chipset. Thank You diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index bdca511..69a59a5 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -186,11 +186,11 @@ config I2C_SIS5595 will be called i2c-sis5595. config I2C_SIS630 - tristate "SiS 630/730" + tristate "SiS 630/730/964" depends on PCI help If you say yes to this option, support will be included for the - SiS630 and SiS730 SMBus (a subset of I2C) interface. + SiS630, SiS730 and SiS964 SMBus (a subset of I2C) interface. This driver can also be built as a module. If so, the module will be called i2c-sis630. diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index de6dddb..df8e20a 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -41,6 +41,20 @@ Supports: SIS 630 SIS 730 + SIS 964 + + Notable differences between chips: + +++---+ + || SIS630/730 | SIS964 | + +++---+ + | Clock | 14kHz/56kHz| 55.56kHz/27.78kHz | + | SMBus registers offset | 0x80 | 0xE0 | + | SMB_CNT| Bit 1 = Slave Busy | Bit 1 = Bus probe | + | (not used yet) | Bit 3 is reserved | Bit 3 = Last byte | + | SMB_PCOUNT | Offset + 0x06 | Offset + 0x14 | + | SMB_COUNT | 4:0 bits | 5:0 bits | + +++---+ + (Other differences don't affect the functions provided by the driver) Note: we assume there can only be one device, with one SMBus interface. */ @@ -55,22 +69,21 @@ #include #include -/* SIS630 SMBus registers */ -#define SMB_STS0x80/* status */ -#define SMB_EN 0x81/* status enable */ -#define SMB_CNT0x82 -#define SMBHOST_CNT0x83 -#define SMB_ADDR 0x84 -#define SMB_CMD0x85 -#define SMB_PCOUNT 0x86/* processed count */ -#define SMB_COUNT 0x87 -#define SMB_BYTE 0x88/* ~0x8F data byte field */ -#define SMBDEV_ADDR0x90 -#define SMB_DB00x91 -#define SMB_DB10x92 -#define SMB_SAA0x93 - -/* register count for request_region */ +/* SIS964 id is defined here as we are the only file using it */ +#define PCI_DEVICE_ID_SI_964 0x0964 + +/* SIS630/730/964 SMBus registers */ +#define SMB_STS0x00/* status */ +#define SMB_CNT0x02/* control */ +#define SMBHOST_CNT0x03/* host control */ +#define SMB_ADDR 0x04/* address */ +#define SMB_CMD0x05/* command */ +#define SMB_COUNT 0x07/* byte count */ +#define SMB_BYTE 0x08/* ~0x8F data byte field */ + +/* register count for request_region + * As we don't use SMB_PCOUNT, 20 is ok for SiS630 and SiS964 + */ #define SIS630_SMB_IOREGION20
[PATCH v3 0/6] I2C: sis630: add sis964 support
Those patches add sis964 support to i2c-sis630. The SiS datasheets have been used. The SiS964 isn't part of the SIS96X family and behaves like the SiS630 chip family. For I2C, this array show the differences between a SiS630 and a SiS964. +++---+ || SIS630/730 | SIS964 | +++---+ | Clock | 14kHz/56kHz| 55.56kHz/27.78kHz | | SMBus registers offset | 0x80 | 0xE0 | | SMB_CNT| Bit 1 = Slave Busy | Bit 1 = Bus probe | | (not used yet) | Bit 3 is reserved | Bit 3 = Last byte | | SMB_PCOUNT | Offset + 0x06 | Offset + 0x14 | | SMB_COUNT | 4:0 bits | 5:0 bits | +++---+ Other differences don't affect the functions provided by the original driver. Changes v2 -> v3: Added a missing BYTE_DONE_STS in cosmetics patch Unsigned hex patch corrected Checkpatch patch improved Amaury Decrême (6): Add SIS964 bus support to i2c-sis630. Bugfix: clear sticky bits Bugfix: behavior after collision Cosmetics: hex to constants for SMBus commands Misc: display unsigned hex Cleanup Documentation/i2c/busses/i2c-sis630 | 9 + drivers/i2c/busses/Kconfig | 4 +- drivers/i2c/busses/i2c-sis630.c | 356 3 files changed, 209 insertions(+), 160 deletions(-) -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/6] Cleanup
On Mon, Jan 28, 2013 at 07:40:07PM +0100, Jean Delvare wrote: > > Some "80 columns" warnings have been expressly omitted to keep reading > > easy. > > You can get rid of these too by splitting the affected lines. You do > not have to split the strings themselves, but the other parameters can > be on different lines. checkpatch.pl will be silent once you get this > right. > Thanks for the review. "80 columns" warn removed without string splitting in v3. -- Amaury Decrême -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/6] Misc: display unsigned hex
On Mon, Jan 28, 2013 at 07:33:04PM +0100, Jean Delvare wrote: > > - dev_dbg(&adap->dev, "SMBus busy (%02x). Resetting...\n", temp); > > + dev_dbg(&adap->dev, "SMBus busy (%02hx). Resetting...\n", temp); > > %hx is for shorts, not bytes. There is no format specifier for shorts, > so a cast is always needed for these if you want to be strictly > compliant. In practice gcc is smart enough to do the cast > automatically. Same for most cases below. > > My suggestion to use %hx was really only for the cases where the > variable is an unsigned short or u16, you can leave all the rest as is. > I indeed missed that point. Corrected. -- Amaury Decrême -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/6] Cosmetics: hex to constants for SMBus commands
On Mon, Jan 28, 2013 at 06:42:33PM +0100, Jean Delvare wrote: > > Good idea, however you missed one occurrence of BYTE_DONE_STS in > sis630_transaction_wait(). > Thanks, corrected. -- Amaury Decrême -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5] i2c: Adding support for Intel iSMT SMBus 2.0 host controller
The iSMT (Intel SMBus Message Transport) supports multi-master I2C/SMBus, as well as IPMI. It's operation is DMA-based and utilizes descriptors to initiate transactions on the bus. The iSMT hardware can act as both a master and a target, although this driver only supports being a master. Signed-off-by: Neil Horman Signed-off-by: Bill Brown Tested-by: Seth Heasley CC: Seth Heasley CC: Jean Delvare --- Forgive the latency in this reply, Jean, Bill has gone on sabbatical, so I finished this up on behalf of Intel. Change notes for V5) * Remove __devexit, __devinit macros * Convert module parameter to use units of khz * Update Description to reflect current pci db * Improve KConfig dependencies * Improve PCI device id names * Reduce dma buffer size to appropriate value and check mapping result * Fix build failure resulting from missing readq definition * Limit use of memcpy and copy length in ismt_process_desc * Fix off by one error in dma_size * Convert driver to uninterruptible wait on dma transfers * Add spped sync with bus_speed module option * Misc cleanups and fixes * Fix FTBFS when CONFIG_DYNAMIC_DEBUG is off --- Documentation/i2c/busses/i2c-ismt | 36 ++ drivers/i2c/busses/Kconfig| 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-ismt.c | 932 ++ 4 files changed, 979 insertions(+) create mode 100644 Documentation/i2c/busses/i2c-ismt create mode 100644 drivers/i2c/busses/i2c-ismt.c diff --git a/Documentation/i2c/busses/i2c-ismt b/Documentation/i2c/busses/i2c-ismt new file mode 100644 index 000..aa3b60f --- /dev/null +++ b/Documentation/i2c/busses/i2c-ismt @@ -0,0 +1,36 @@ +Kernel driver i2c-ismt + +Supported adapters: + * Intel S12xx series SOCs + +Authors: + Bill Brown + + +Module Parameters +- + +* bus_speed (unsigned int) +Allows changing of the bus speed. Normally, the bus speed is set by the BIOS +and never needs to be changed. However, some SMBus analyzers are too slow for +monitoring the bus during debug, thus the need for this module parameter. +Specify the bus speed in units of KHz. +Available bus frequency settings: + 0 no change + 80 kHz + 100 kHz + 400 kHz + 1000 KHz + + +Description +--- + +The S12xx series of SOCs have a pair of integrated SMBus 2.0 controllers +targeted primarily at the microserver and storage markets. + +The S12xx series contain a pair of PCI functions. An output of lspci will show +something similar to the following: + + 00:13.0 System peripheral: Intel Corporation Centerton SMBus 2.0 Controller 0 + 00:13.1 System peripheral: Intel Corporation Centerton SMBus 2.0 Controller 1 diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index bdca511..0bb7ff4 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -121,6 +121,16 @@ config I2C_ISCH This driver can also be built as a module. If so, the module will be called i2c-isch. +config I2C_ISMT + tristate "Intel iSMT SMBus Controller" + depends on PCI && X86 + help + If you say yes to this option, support will be included for the Intel + iSMT SMBus host controller interface. + + This driver can also be built as a module. If so, the module will be + called i2c-ismt. + config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" depends on PCI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 6181f3f..23c9d55 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_I2C_AMD756_S4882)+= i2c-amd756-s4882.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_ISCH) += i2c-isch.o +obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_NFORCE2_S4985)+= i2c-nforce2-s4985.o obj-$(CONFIG_I2C_PIIX4)+= i2c-piix4.o diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c new file mode 100644 index 000..5ad4680 --- /dev/null +++ b/drivers/i2c/busses/i2c-ismt.c @@ -0,0 +1,932 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2012 Intel Corporation. All rights reserved. + * + * GPL LICENSE SUMMARY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy
Re: [PATCH v2 6/6] Cleanup
On Fri, 4 Jan 2013 14:13:35 +0100, Amaury Decrême wrote: > This patch corrects checkpatch errors. > Some "80 columns" warnings have been expressly omitted to keep reading > easy. You can get rid of these too by splitting the affected lines. You do not have to split the strings themselves, but the other parameters can be on different lines. checkpatch.pl will be silent once you get this right. > The changes has also been removed as it has less meaning with version > control tools. > > Signed-off-by: Amaury Decrême > --- > drivers/i2c/busses/i2c-sis630.c | 175 > ++- > 1 files changed, 82 insertions(+), 93 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c > index 4bc970d..ff08dde 100644 > --- a/drivers/i2c/busses/i2c-sis630.c > +++ b/drivers/i2c/busses/i2c-sis630.c > @@ -16,24 +16,6 @@ > Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > */ > > -/* > - Changes: > - 24.08.2002 > - Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) > - Changed sis630_transaction.(Thanks to Mark M. Hoffman) > - 18.09.2002 > - Added SIS730 as supported. > - 21.09.2002 > - Added high_clock module option.If this option is set > - used Host Master Clock 56KHz (default 14KHz).For now we save old Host > - Master Clock and after transaction completed restore (otherwise > - it's confuse BIOS and hung Machine). > - 24.09.2002 > - Fixed typo in sis630_access > - Fixed logical error by restoring of Host Master Clock > - 31.07.2003 > - Added block data read/write support. > -*/ > You can delete one more blank line. > /* > Status: beta > @@ -150,9 +132,10 @@ static inline void sis630_write(u8 reg, u8 data) > outb(data, smbus_base + reg); > } > > -static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 > *oldclock) > +static int sis630_transaction_start(struct i2c_adapter *adap, int size, > + u8 *oldclock) > { > -u8 temp; > + u8 temp; This doesn't apply as the change is already present in a previous patch. > > /* Make sure the SMBus host is ready to start transmitting. */ > temp = sis630_read(SMB_CNT); > (...) All the rest looks good, thanks for doing that. -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/6] Misc: display unsigned hex
On Fri, 4 Jan 2013 14:13:34 +0100, Amaury Decrême wrote: > This patch corrects the display of unsigned hex values. > > Signed-off-by: Amaury Decrême > --- > drivers/i2c/busses/i2c-sis630.c | 25 ++--- > 1 files changed, 14 insertions(+), 11 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c > index 792bb79..4bc970d 100644 > --- a/drivers/i2c/busses/i2c-sis630.c > +++ b/drivers/i2c/busses/i2c-sis630.c > @@ -152,18 +152,18 @@ static inline void sis630_write(u8 reg, u8 data) > > static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 > *oldclock) > { > -int temp; > + u8 temp; > > /* Make sure the SMBus host is ready to start transmitting. */ > temp = sis630_read(SMB_CNT); > if ((temp & (SMB_PROBE | SMB_HOSTBUSY)) != 0x00) { > - dev_dbg(&adap->dev, "SMBus busy (%02x). Resetting...\n", temp); > + dev_dbg(&adap->dev, "SMBus busy (%02hx). Resetting...\n", temp); %hx is for shorts, not bytes. There is no format specifier for shorts, so a cast is always needed for these if you want to be strictly compliant. In practice gcc is smart enough to do the cast automatically. Same for most cases below. My suggestion to use %hx was really only for the cases where the variable is an unsigned short or u16, you can leave all the rest as is. > /* kill smbus transaction */ > sis630_write(SMBHOST_CNT, SMB_KILL); > > temp = sis630_read(SMB_CNT); > if (temp & (SMB_PROBE | SMB_HOSTBUSY)) { > - dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); > + dev_dbg(&adap->dev, "Failed! (%02hx)\n", temp); > return -EBUSY; > } else { > dev_dbg(&adap->dev, "Successful!\n"); > @@ -173,7 +173,7 @@ static int sis630_transaction_start(struct i2c_adapter > *adap, int size, u8 *oldc > /* save old clock, so we can prevent machine for hung */ > *oldclock = sis630_read(SMB_CNT); > > - dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock); > + dev_dbg(&adap->dev, "saved clock 0x%02hx\n", *oldclock); > > /* disable timeout interrupt , set Host Master Clock to 56KHz if > requested */ > if (high_clock) > @@ -193,7 +193,8 @@ static int sis630_transaction_start(struct i2c_adapter > *adap, int size, u8 *oldc > > static int sis630_transaction_wait(struct i2c_adapter *adap, int size) > { > - int temp, result = 0, timeout = 0; > + u8 temp; > + int result = 0, timeout = 0; > > /* We will always wait for a fraction of a second! */ > do { > @@ -228,7 +229,8 @@ static void sis630_transaction_end(struct i2c_adapter > *adap, u8 oldclock) > /* clear all status "sticky" bits */ > sis630_write(SMB_STS, 0xFF); > > - dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", > sis630_read(SMB_CNT)); > + dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02hx\n", > + sis630_read(SMB_CNT)); > > /* >* restore old Host Master Clock if high_clock is set > @@ -237,7 +239,8 @@ static void sis630_transaction_end(struct i2c_adapter > *adap, u8 oldclock) > if (high_clock && !(oldclock & SMBCLK_SEL)) > sis630_write(SMB_CNT, sis630_read(SMB_CNT) & ~SMBCLK_SEL); > > - dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", > sis630_read(SMB_CNT)); > + dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02hx\n", > + sis630_read(SMB_CNT)); > } > > static int sis630_transaction(struct i2c_adapter *adap, int size) > @@ -266,8 +269,8 @@ static int sis630_block_data(struct i2c_adapter *adap, > union i2c_smbus_data *dat > else if (len > 32) > len = 32; > sis630_write(SMB_COUNT, len); > - for (i=1; i <= len; i++) { > - dev_dbg(&adap->dev, "set data 0x%02x\n", > data->block[i]); > + for (i = 1; i <= len; i++) { > + dev_dbg(&adap->dev, "set data 0x%02hx\n", > data->block[i]); > /* set data */ > sis630_write(SMB_BYTE+(i-1)%8, data->block[i]); > if (i==8 || (len<8 && i==len)) { > @@ -319,7 +322,7 @@ static int sis630_block_data(struct i2c_adapter *adap, > union i2c_smbus_data *dat > if (data->block[0] > 32) > data->block[0] = 32; > > - dev_dbg(&adap->dev, "block data read len=0x%x\n", > data->block[0]); > + dev_dbg(&adap->dev, "block data read len=0x%hx\n", > data->block[0]); > > for (i=0; i < 8 && len < data->block[0]; i++,len++) { > dev_dbg(&adap->dev, "read i=%d len=%d\n", i, > len); > @@ -463,7 +466,7 @@ static int sis630_setup(struct pci_dev *sis630_dev) > goto exit; >
Re: [PATCH v2 4/6] Cosmetics: hex to constants for SMBus commands
On Fri, 4 Jan 2013 14:13:33 +0100, Amaury Decrême wrote: > This patch replaces hexadecimal values by constants for SMBus commands > and bit masks. > > Signed-off-by: Amaury Decrême > --- > drivers/i2c/busses/i2c-sis630.c | 45 ++ > 1 files changed, 31 insertions(+), 14 deletions(-) > (...) Good idea, however you missed one occurrence of BYTE_DONE_STS in sis630_transaction_wait(). -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/6] Bugfix: behavior after collision
On Fri, 4 Jan 2013 14:13:32 +0100, Amaury Decrême wrote: > Datasheet on collision: > SMBus Collision (SMBCOL_STS) > This bit is set when a SMBus Collision condition occurs and > SMBus Host loses in the bus arbitration. The software should > clear this bit and re-start SMBus operation. > > As the status will be cleared in transaction_end, we can remove the > sis630_write and prepare to return -EAGAIN to retry. > > Signed-off-by: Amaury Decrême > --- > drivers/i2c/busses/i2c-sis630.c |7 +-- > 1 files changed, 1 insertions(+), 6 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c > index 3124d80..e152d36 100644 > --- a/drivers/i2c/busses/i2c-sis630.c > +++ b/drivers/i2c/busses/i2c-sis630.c > @@ -200,12 +200,7 @@ static int sis630_transaction_wait(struct i2c_adapter > *adap, int size) > > if (temp & 0x04) { > dev_err(&adap->dev, "Bus collision!\n"); > - result = -EIO; > - /* > - TBD: Datasheet say: > - the software should clear this bit and restart SMBUS > operation. > - Should we do it or user start request again? > - */ > + result = -EAGAIN; > } > > return result; Reviewed-by: Jean Delvare -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/6] Bugfix: clear sticky bits
On Fri, 4 Jan 2013 14:13:31 +0100, Amaury Decrême wrote: > The sticky bits must be cleared at the end of the transaction by writing > a 1 to all fields. > > Datasheet: > SMBus Status (SMB_STS) > The following registers are all sticky bits and only can be > cleared by writing a one to their corresponding fields. > > Signed-off-by: Amaury Decrême > --- > drivers/i2c/busses/i2c-sis630.c |4 +--- > 1 files changed, 1 insertions(+), 3 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c > index df8e20a..3124d80 100644 > --- a/drivers/i2c/busses/i2c-sis630.c > +++ b/drivers/i2c/busses/i2c-sis630.c > @@ -213,10 +213,8 @@ static int sis630_transaction_wait(struct i2c_adapter > *adap, int size) > > static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) > { > - int temp = 0; > - > /* clear all status "sticky" bits */ > - sis630_write(SMB_STS, temp); > + sis630_write(SMB_STS, 0xFF); > > dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", > sis630_read(SMB_CNT)); > Reviewed-by: Jean Delvare -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/6] Add SIS964 bus support to i2c-sis630.
On Fri, 4 Jan 2013 14:13:30 +0100, Amaury Decrême wrote: > Signed-off-by: Amaury Decrême > --- > Documentation/i2c/busses/i2c-sis630 |9 > drivers/i2c/busses/Kconfig |4 +- > drivers/i2c/busses/i2c-sis630.c | 88 > +++ > 3 files changed, 69 insertions(+), 32 deletions(-) > (...) Reviewed-by: Jean Delvare -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] i2c-isch: Add module parameter for backbone clock rate if divider is unset
On Mon, 28 Jan 2013 10:44:12 +0100, Alexander Stein wrote: > It was observed the Host Clock Divider was not written by the driver. It > was still set to (default) 0, if not already set by BIOS, which caused > garbage on SMBus. > This driver adds a parameters which is used to calculate the divider > appropriately for a default bitrate of 100 KHz. This new divider is only > applied if the clock divider is still default 0. > > Signed-off-by: Alexander Stein > --- > Changes in v2: > * Removed useless debug output > * Added description comment about calculation into code > * Some code organization changes > > drivers/i2c/busses/i2c-isch.c | 17 + > 1 file changed, 17 insertions(+) > (...) Reviewed-by: Jean Delvare -- Jean Delvare -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC] misc/at24: distinguish between eeprom and fram chips
On Thursday 24 January 2013 at 08:27:01, Wolfram Sang wrote: > > > > > > I wanted to use a fm24c04 i2c fram chip with linux. I grepped > > > > > > the source and found nothing. I later found that my chip can be > > > > > > handled by at24 eeprom driver. It creates a sysfs file called > > > > > > eeprom to read from and write to the chip. Userspace has no > > > > > > chance to distinguish if it is writing an eeprom or a fram > > > > > > chip. > > > > > > > > > > Why should it? > > > > > > > > Because writes are much faster and it doesn't have to take care on > > > > erase cycles. It could use other write strategies on such devices > > > > and update informations that have to survive power downs more > > > > often. > > > > > > I agree. I think that a seperate attribute named e.g. 'page_size' > > > would be more helpful than renaming the binary file to fram? > > > > Yes, this is a much better solution! Adding a seperate sysfs file > > page_size and a file for the type of device which would read eeprom, > > fram, etc then. If you also think this is the way to go, I would spent > > one of my next free timeslots to this. > > Oops, this mail seems to have dropped off :( Luckily I did not have a free timeslot to invest yet. ;) > I am all for the 'page_size' attribute, but still not convinced what > gain the 'type' attribute would allow. For FRAM, the page size will be > large. Isn't this enough information? Yes, this would be enough information and I think this is the way we should go. I set this on my todo list. Although the change will be quite simple, I think I will not find the time to hit the upcoming merge window. Lars -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] i2c-isch: Add module parameter for backbone clock rate if divider is unset
It was observed the Host Clock Divider was not written by the driver. It was still set to (default) 0, if not already set by BIOS, which caused garbage on SMBus. This driver adds a parameters which is used to calculate the divider appropriately for a default bitrate of 100 KHz. This new divider is only applied if the clock divider is still default 0. Signed-off-by: Alexander Stein --- Changes in v2: * Removed useless debug output * Added description comment about calculation into code * Some code organization changes drivers/i2c/busses/i2c-isch.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 4099f79..8c38aaa 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -40,6 +40,7 @@ /* SCH SMBus address offsets */ #define SMBHSTCNT (0 + sch_smba) #define SMBHSTSTS (1 + sch_smba) +#define SMBHSTCLK (2 + sch_smba) #define SMBHSTADD (4 + sch_smba) /* TSA */ #define SMBHSTCMD (5 + sch_smba) #define SMBHSTDAT0 (6 + sch_smba) @@ -58,6 +59,9 @@ static unsigned short sch_smba; static struct i2c_adapter sch_adapter; +static int backbone_speed = 33000; /* backbone speed in kHz */ +module_param(backbone_speed, int, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(backbone_speed, "Backbone speed in kHz, (default = 33000)"); /* * Start the i2c transaction -- the i2c_access will prepare the transaction @@ -156,6 +160,19 @@ static s32 sch_access(struct i2c_adapter *adap, u16 addr, dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp); return -EAGAIN; } + temp = inw(SMBHSTCLK); + if (!temp) { + /* +* We can't determine if we have 33 or 25 MHz clock for +* SMBus, so expect 33 MHz and calculate a bus clock of +* 100 kHz. If we actually run at 25 MHz the bus will be +* run ~75 kHz instead which should do no harm. +*/ + dev_notice(&sch_adapter.dev, + "Clock divider unitialized. Setting defaults\n"); + outw(backbone_speed / (4 * 100), SMBHSTCLK); + } + dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size, (read_write)?"READ":"WRITE"); switch (size) { -- 1.8.1.1 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html