From 764c16918fb2347b3cbc8f6030b2b6561911bc32 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:40 +0100 Subject: i2c: Document the different ways to instantiate i2c devices On popular demand, here comes some documentation about how to instantiate i2c devices in the new (standard) i2c device driver binding model. I have also clarified how the class bitfield lets driver authors control which buses are probed in the auto-detect case, and warned more loudly against the abuse of this method. Signed-off-by: Jean Delvare Acked-by: Michael Lawnick Acked-by: Hans Verkuil diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices new file mode 100644 index 0000000..b55ce57 --- /dev/null +++ b/Documentation/i2c/instantiating-devices @@ -0,0 +1,167 @@ +How to instantiate I2C devices +============================== + +Unlike PCI or USB devices, I2C devices are not enumerated at the hardware +level. Instead, the software must know which devices are connected on each +I2C bus segment, and what address these devices are using. For this +reason, the kernel code must instantiate I2C devices explicitly. There are +several ways to achieve this, depending on the context and requirements. + + +Method 1: Declare the I2C devices by bus number +----------------------------------------------- + +This method is appropriate when the I2C bus is a system bus as is the case +for many embedded systems. On such systems, each I2C bus has a number +which is known in advance. It is thus possible to pre-declare the I2C +devices which live on this bus. This is done with an array of struct +i2c_board_info which is registered by calling i2c_register_board_info(). + +Example (from omap2 h4): + +static struct i2c_board_info __initdata h4_i2c_board_info[] = { + { + I2C_BOARD_INFO("isp1301_omap", 0x2d), + .irq = OMAP_GPIO_IRQ(125), + }, + { /* EEPROM on mainboard */ + I2C_BOARD_INFO("24c01", 0x52), + .platform_data = &m24c01, + }, + { /* EEPROM on cpu card */ + I2C_BOARD_INFO("24c01", 0x57), + .platform_data = &m24c01, + }, +}; + +static void __init omap_h4_init(void) +{ + (...) + i2c_register_board_info(1, h4_i2c_board_info, + ARRAY_SIZE(h4_i2c_board_info)); + (...) +} + +The above code declares 3 devices on I2C bus 1, including their respective +addresses and custom data needed by their drivers. When the I2C bus in +question is registered, the I2C devices will be instantiated automatically +by i2c-core. + +The devices will be automatically unbound and destroyed when the I2C bus +they sit on goes away (if ever.) + + +Method 2: Instantiate the devices explicitly +-------------------------------------------- + +This method is appropriate when a larger device uses an I2C bus for +internal communication. A typical case is TV adapters. These can have a +tuner, a video decoder, an audio decoder, etc. usually connected to the +main chip by the means of an I2C bus. You won't know the number of the I2C +bus in advance, so the method 1 described above can't be used. Instead, +you can instantiate your I2C devices explicitly. This is done by filling +a struct i2c_board_info and calling i2c_new_device(). + +Example (from the sfe4001 network driver): + +static struct i2c_board_info sfe4001_hwmon_info = { + I2C_BOARD_INFO("max6647", 0x4e), +}; + +int sfe4001_init(struct efx_nic *efx) +{ + (...) + efx->board_info.hwmon_client = + i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info); + + (...) +} + +The above code instantiates 1 I2C device on the I2C bus which is on the +network adapter in question. + +A variant of this is when you don't know for sure if an I2C device is +present or not (for example for an optional feature which is not present +on cheap variants of a board but you have no way to tell them apart), or +it may have different addresses from one board to the next (manufacturer +changing its design without notice). In this case, you can call +i2c_new_probed_device() instead of i2c_new_device(). + +Example (from the pnx4008 OHCI driver): + +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; + +static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) +{ + (...) + struct i2c_adapter *i2c_adap; + struct i2c_board_info i2c_info; + + (...) + i2c_adap = i2c_get_adapter(2); + memset(&i2c_info, 0, sizeof(struct i2c_board_info)); + strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); + isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, + normal_i2c); + i2c_put_adapter(i2c_adap); + (...) +} + +The above code instantiates up to 1 I2C device on the I2C bus which is on +the OHCI adapter in question. It first tries at address 0x2c, if nothing +is found there it tries address 0x2d, and if still nothing is found, it +simply gives up. + +The driver which instantiated the I2C device is responsible for destroying +it on cleanup. This is done by calling i2c_unregister_device() on the +pointer that was earlier returned by i2c_new_device() or +i2c_new_probed_device(). + + +Method 3: Probe an I2C bus for certain devices +---------------------------------------------- + +Sometimes you do not have enough information about an I2C device, not even +to call i2c_new_probed_device(). The typical case is hardware monitoring +chips on PC mainboards. There are several dozen models, which can live +at 25 different addresses. Given the huge number of mainboards out there, +it is next to impossible to build an exhaustive list of the hardware +monitoring chips being used. Fortunately, most of these chips have +manufacturer and device ID registers, so they can be identified by +probing. + +In that case, I2C devices are neither declared nor instantiated +explicitly. Instead, i2c-core will probe for such devices as soon as their +drivers are loaded, and if any is found, an I2C device will be +instantiated automatically. In order to prevent any misbehavior of this +mechanism, the following restrictions apply: +* The I2C device driver must implement the detect() method, which + identifies a supported device by reading from arbitrary registers. +* Only buses which are likely to have a supported device and agree to be + probed, will be probed. For example this avoids probing for hardware + monitoring chips on a TV adapter. + +Example: +See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c + +I2C devices instantiated as a result of such a successful probe will be +destroyed automatically when the driver which detected them is removed, +or when the underlying I2C bus is itself destroyed, whichever happens +first. + +Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6 +kernels will find out that this method 3 is essentially similar to what +was done there. Two significant differences are: +* Probing is only one way to instantiate I2C devices now, while it was the + only way back then. Where possible, methods 1 and 2 should be preferred. + Method 3 should only be used when there is no other way, as it can have + undesirable side effects. +* I2C buses must now explicitly say which I2C driver classes can probe + them (by the means of the class bitfield), while all I2C buses were + probed by default back then. The default is an empty class which means + that no probing happens. The purpose of the class bitfield is to limit + the aforementioned undesirable side effects. + +Once again, method 3 should be avoided wherever possible. Explicit device +instantiation (methods 1 and 2) is much preferred for it is safer and +faster. diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 6b9af7d..c1a06f9 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -207,15 +207,26 @@ You simply have to define a detect callback which will attempt to identify supported devices (returning 0 for supported ones and -ENODEV for unsupported ones), a list of addresses to probe, and a device type (or class) so that only I2C buses which may have that type of device -connected (and not otherwise enumerated) will be probed. The i2c -core will then call you back as needed and will instantiate a device -for you for every successful detection. +connected (and not otherwise enumerated) will be probed. For example, +a driver for a hardware monitoring chip for which auto-detection is +needed would set its class to I2C_CLASS_HWMON, and only I2C adapters +with a class including I2C_CLASS_HWMON would be probed by this driver. +Note that the absence of matching classes does not prevent the use of +a device of that type on the given I2C adapter. All it prevents is +auto-detection; explicit instantiation of devices is still possible. Note that this mechanism is purely optional and not suitable for all devices. You need some reliable way to identify the supported devices (typically using device-specific, dedicated identification registers), otherwise misdetections are likely to occur and things can get wrong -quickly. +quickly. Keep in mind that the I2C protocol doesn't include any +standard way to detect the presence of a chip at a given address, let +alone a standard way to identify devices. Even worse is the lack of +semantics associated to bus transfers, which means that the same +transfer can be seen as a read operation by a chip and as a write +operation by another chip. For these reasons, explicit device +instantiation should always be preferred to auto-detection where +possible. Device Deletion -- cgit v0.10.2 From f02e3d74e9f89e3d49284e7c99217993b657f5b7 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:40 +0100 Subject: i2c: Let checkpatch shout on users of the legacy model As suggested by Mauro Carvalho Chehab. Signed-off-by: Jean Delvare Cc: Mauro Carvalho Chehab diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 02ea377..7907586 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -340,7 +340,8 @@ Who: Krzysztof Piotr Oledzki --------------------------- What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() -When: 2.6.29 (ideally) or 2.6.30 (more likely) +When: 2.6.30 +Check: i2c_attach_client i2c_detach_client Why: Deprecated by the new (standard) device driver binding model. Use i2c_driver->probe() and ->remove() instead. Who: Jean Delvare -- cgit v0.10.2 From acec211ca605d79083058e6037bbf131c3f993fc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:40 +0100 Subject: i2c: Clarify which clients are auto-removed The automatic removal of i2c clients only affects the clients which were created automatically in the first place. Add a comment saying that to avoid any confusion. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index fbb9030..456caa8 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -581,7 +581,8 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data) struct i2c_client *client, *_n; int res; - /* Remove the devices we created ourselves */ + /* Remove the devices we created ourselves as the result of hardware + * probing (using a driver's detect method) */ list_for_each_entry_safe(client, _n, &driver->clients, detected) { if (client->adapter == adapter) { dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", @@ -749,6 +750,8 @@ static int __detach_adapter(struct device *dev, void *data) struct i2c_driver *driver = data; struct i2c_client *client, *_n; + /* Remove the devices we created ourselves as the result of hardware + * probing (using a driver's detect method) */ list_for_each_entry_safe(client, _n, &driver->clients, detected) { dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", client->name, client->addr); -- cgit v0.10.2 From d2dd14ac1847082d4bb955619e86ed315c0ecd20 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:41 +0100 Subject: i2c-nforce2: Add support for MCP67, MCP73, MCP78S and MCP79 The MCP78S and MCP79 appear to be compatible with the previous nForce chips as far as the SMBus controller is concerned. The MCP67 and MCP73 were not tested yet but I'd be very surprised if they weren't compatible too. Signed-off-by: Jean Delvare Cc: Oleg Ryjkov Cc: Malcolm Lalkaka Cc: Zbigniew Luszpinski diff --git a/Documentation/i2c/busses/i2c-nforce2 b/Documentation/i2c/busses/i2c-nforce2 index fae3495..9698c39 100644 --- a/Documentation/i2c/busses/i2c-nforce2 +++ b/Documentation/i2c/busses/i2c-nforce2 @@ -7,10 +7,14 @@ Supported adapters: * nForce3 250Gb MCP 10de:00E4 * nForce4 MCP 10de:0052 * nForce4 MCP-04 10de:0034 - * nForce4 MCP51 10de:0264 - * nForce4 MCP55 10de:0368 - * nForce4 MCP61 10de:03EB - * nForce4 MCP65 10de:0446 + * nForce MCP51 10de:0264 + * nForce MCP55 10de:0368 + * nForce MCP61 10de:03EB + * nForce MCP65 10de:0446 + * nForce MCP67 10de:0542 + * nForce MCP73 10de:07D8 + * nForce MCP78S 10de:0752 + * nForce MCP79 10de:0AA2 Datasheet: not publicly available, but seems to be similar to the AMD-8111 SMBus 2.0 adapter. diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 05af6cd..2ff4683 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -31,10 +31,14 @@ nForce3 250Gb MCP 00E4 nForce4 MCP 0052 nForce4 MCP-04 0034 - nForce4 MCP51 0264 - nForce4 MCP55 0368 + nForce MCP51 0264 + nForce MCP55 0368 nForce MCP61 03EB nForce MCP65 0446 + nForce MCP67 0542 + nForce MCP73 07D8 + nForce MCP78S 0752 + nForce MCP79 0AA2 This driver supports the 2 SMBuses that are included in the MCP of the nForce2/3/4/5xx chipsets. @@ -315,6 +319,10 @@ static struct pci_device_id nforce2_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) }, { 0 } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 05dfa7c..5109fec 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1237,6 +1237,7 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 #define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 #define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS 0x0542 #define PCI_DEVICE_ID_NVIDIA_NVENET_24 0x054C #define PCI_DEVICE_ID_NVIDIA_NVENET_25 0x054D #define PCI_DEVICE_ID_NVIDIA_NVENET_26 0x054E @@ -1247,11 +1248,14 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_31 0x07DF #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 #define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760 #define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761 #define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762 #define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2 #define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0 #define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1 #define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2 -- cgit v0.10.2 From 781b8a2a31b7009a0baa8d700feafa6afc3fb861 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Mar 2009 21:34:41 +0100 Subject: eeprom/at24: Remove EXPERIMENTAL This driver has been widely used since inclusion and no problems have been reported. Signed-off-by: Wolfram Sang Cc: David Brownell Signed-off-by: Jean Delvare diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index c76df8c..89fec05 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -2,7 +2,7 @@ menu "EEPROM support" config EEPROM_AT24 tristate "I2C EEPROMs from most vendors" - depends on I2C && SYSFS && EXPERIMENTAL + depends on I2C && SYSFS help Enable this driver to get read/write support to most I2C EEPROMs, after you configure the driver to know about each EEPROM on -- cgit v0.10.2 From 0c168ceb9e1898a7f2895e80ce9915835b083bd3 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 28 Mar 2009 21:34:42 +0100 Subject: i2c-algo-pcf: Style cleanups cleanup whitespace, fix comments and remove the unused STUB_I2C. Signed-off-by: Roel Kluin Signed-off-by: Jean Delvare Acked-by: Eric Brower diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 3e01992..5906986 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -1,31 +1,30 @@ -/* ------------------------------------------------------------------------- */ -/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */ -/* ------------------------------------------------------------------------- */ -/* Copyright (C) 1995-1997 Simon G. Vogl - 1998-2000 Hans Berglund - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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 of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* ------------------------------------------------------------------------- */ - -/* With some changes from Kyösti Mälkki and - Frodo Looijaard ,and also from Martin Bailey - */ - -/* Partially rewriten by Oleg I. Vdovikin to handle multiple - messages, proper stop/repstart signaling during receive, - added detect code */ +/* + * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters + * + * Copyright (C) 1995-1997 Simon G. Vogl + * 1998-2000 Hans Berglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * With some changes from Kyösti Mälkki and + * Frodo Looijaard , and also from Martin Bailey + * + * + * Partially rewriten by Oleg I. Vdovikin to handle multiple + * messages, proper stop/repstart signaling during receive, added detect code + */ #include #include @@ -38,17 +37,18 @@ #include "i2c-algo-pcf.h" -#define DEB2(x) if (i2c_debug>=2) x -#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/ -#define DEBPROTO(x) if (i2c_debug>=9) x; - /* debug the protocol by showing transferred bits */ +#define DEB2(x) if (i2c_debug >= 2) x +#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug >= 9) x; + /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 16 -/* module parameters: +/* + * module parameters: */ static int i2c_debug; -/* --- setting states on the bus with the right timing: --------------- */ +/* setting states on the bus with the right timing: */ #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl) @@ -57,22 +57,21 @@ static int i2c_debug; #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val) #define i2c_inb(adap) adap->getpcf(adap->data, 0) -/* --- other auxiliary functions -------------------------------------- */ +/* other auxiliary functions */ -static void i2c_start(struct i2c_algo_pcf_data *adap) +static void i2c_start(struct i2c_algo_pcf_data *adap) { DEBPROTO(printk("S ")); set_pcf(adap, 1, I2C_PCF_START); } -static void i2c_repstart(struct i2c_algo_pcf_data *adap) +static void i2c_repstart(struct i2c_algo_pcf_data *adap) { DEBPROTO(printk(" Sr ")); set_pcf(adap, 1, I2C_PCF_REPSTART); } - -static void i2c_stop(struct i2c_algo_pcf_data *adap) +static void i2c_stop(struct i2c_algo_pcf_data *adap) { DEBPROTO(printk("P\n")); set_pcf(adap, 1, I2C_PCF_STOP); @@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) { DEB2(printk(KERN_INFO "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", - *status)); - - /* Cleanup from LAB -- reset and enable ESO. + *status)); + /* + * Cleanup from LAB -- reset and enable ESO. * This resets the PCF8584; since we've lost the bus, no * further attempts should be made by callers to clean up * (no i2c_stop() etc.) */ set_pcf(adap, 1, I2C_PCF_PIN); set_pcf(adap, 1, I2C_PCF_ESO); - - /* We pause for a time period sufficient for any running + /* + * We pause for a time period sufficient for any running * I2C transaction to complete -- the arbitration logic won't * work properly until the next START is seen. * It is assumed the bus driver or client has set a proper value. @@ -108,48 +107,48 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) get_pcf(adap, 1))); } -static int wait_for_bb(struct i2c_algo_pcf_data *adap) { +static int wait_for_bb(struct i2c_algo_pcf_data *adap) +{ int timeout = DEF_TIMEOUT; int status; status = get_pcf(adap, 1); -#ifndef STUB_I2C + while (timeout-- && !(status & I2C_PCF_BB)) { udelay(100); /* wait for 100 us */ status = get_pcf(adap, 1); } -#endif - if (timeout <= 0) { + + if (timeout <= 0) printk(KERN_ERR "Timeout waiting for Bus Busy\n"); - } - - return (timeout<=0); -} + return timeout <= 0; +} -static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { +static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) +{ int timeout = DEF_TIMEOUT; *status = get_pcf(adap, 1); -#ifndef STUB_I2C + while (timeout-- && (*status & I2C_PCF_PIN)) { adap->waitforpin(adap->data); *status = get_pcf(adap, 1); } if (*status & I2C_PCF_LAB) { handle_lab(adap, status); - return(-EINTR); + return -EINTR; } -#endif + if (timeout <= 0) - return(-1); + return -1; else - return(0); + return 0; } -/* +/* * This should perform the 'PCF8584 initialization sequence' as described * in the Philips IC12 data book (1995, Aug 29). * There should be a 30 clock cycle wait after reset, I assume this @@ -164,18 +163,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; - DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", + get_pcf(adap, 1))); /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); - /* check to see S1 now used as R/W ctrl - - PCF8584 does that when ESO is zero */ + /* + * check to see S1 now used as R/W ctrl - + * PCF8584 does that when ESO is zero + */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* definetly not PCF8584 */ } - /* load own address in S0, effective address is (own << 1) */ + /* load own address in S0, effective address is (own << 1) */ i2c_outb(adap, get_own(adap)); /* check it's really written */ if ((temp = i2c_inb(adap)) != get_own(adap)) { @@ -183,7 +185,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* S1=0xA0, next byte in S2 */ + /* S1=0xA0, next byte in S2 */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { @@ -191,7 +193,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* load clock register S2 */ + /* load clock register S2 */ i2c_outb(adap, get_clock(adap)); /* check it's really written, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { @@ -199,7 +201,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* Enable serial interface, idle, S0 selected */ + /* Enable serial interface, idle, S0 selected */ set_pcf(adap, 1, I2C_PCF_IDLE); /* check to see PCF is really idled and we can access status register */ @@ -207,57 +209,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } - + printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); return 0; } - -/* ----- Utility functions - */ - static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, - int count, int last) + int count, int last) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wrcount, status, timeout; - + for (wrcount=0; wrcountdev, "i2c_write: writing %2.2X\n", - buf[wrcount]&0xff)); + buf[wrcount] & 0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { - if (timeout == -EINTR) { - /* arbitration lost */ - return -EINTR; - } + if (timeout == -EINTR) + return -EINTR; /* arbitration lost */ + i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); return -EREMOTEIO; /* got a better one ?? */ } -#ifndef STUB_I2C if (status & I2C_PCF_LRB) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); return -EREMOTEIO; /* got a better one ?? */ } -#endif } - if (last) { + if (last) i2c_stop(adap); - } - else { + else i2c_repstart(adap); - } - return (wrcount); + return wrcount; } - static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, - int count, int last) + int count, int last) { int i, status; struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; @@ -267,42 +259,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, for (i = 0; i <= count; i++) { if ((wfp = wait_for_pin(adap, &status))) { - if (wfp == -EINTR) { - /* arbitration lost */ - return -EINTR; - } + if (wfp == -EINTR) + return -EINTR; /* arbitration lost */ + i2c_stop(adap); dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); - return (-1); + return -1; } -#ifndef STUB_I2C if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); - return (-1); + return -1; } -#endif - + if (i == count - 1) { set_pcf(adap, 1, I2C_PCF_ESO); - } else - if (i == count) { - if (last) { + } else if (i == count) { + if (last) i2c_stop(adap); - } else { + else i2c_repstart(adap); - } - }; + } - if (i) { + if (i) buf[i - 1] = i2c_inb(adap); - } else { + else i2c_inb(adap); /* dummy read */ - } } - return (i - 1); + return i - 1; } @@ -323,14 +309,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap, } static int pcf_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, + struct i2c_msg *msgs, int num) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; int ret=0, timeout, status; - + if (adap->xfer_begin) adap->xfer_begin(adap->data); @@ -338,25 +324,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, timeout = wait_for_bb(adap); if (timeout) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " - "Timeout waiting for BB in pcf_xfer\n");) + "Timeout waiting for BB in pcf_xfer\n");) i = -EIO; goto out; } - + for (i = 0;ret >= 0 && i < num; i++) { pmsg = &msgs[i]; DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", pmsg->flags & I2C_M_RD ? "read" : "write", - pmsg->len, pmsg->addr, i + 1, num);) - + pmsg->len, pmsg->addr, i + 1, num);) + ret = pcf_doAddress(adap, pmsg); /* Send START */ - if (i == 0) { - i2c_start(adap); - } - + if (i == 0) + i2c_start(adap); + /* Wait for PIN (pending interrupt NOT) */ timeout = wait_for_pin(adap, &status); if (timeout) { @@ -371,8 +356,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, i = -EREMOTEIO; goto out; } - -#ifndef STUB_I2C + /* Check LRB (last rcvd bit - slave ack) */ if (status & I2C_PCF_LRB) { i2c_stop(adap); @@ -380,27 +364,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, i = -EREMOTEIO; goto out; } -#endif - + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", i, msgs[i].addr, msgs[i].flags, msgs[i].len);) - - /* Read */ + if (pmsg->flags & I2C_M_RD) { - /* read bytes into buffer*/ ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, - (i + 1 == num)); - + (i + 1 == num)); + if (ret != pmsg->len) { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only read %d bytes.\n",ret)); } else { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); } - } else { /* Write */ + } else { ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, - (i + 1 == num)); - + (i + 1 == num)); + if (ret != pmsg->len) { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only wrote %d bytes.\n",ret)); @@ -413,24 +394,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, out: if (adap->xfer_end) adap->xfer_end(adap->data); - return (i); + return i; } static u32 pcf_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; } -/* -----exported algorithm data: ------------------------------------- */ - +/* exported algorithm data: */ static const struct i2c_algorithm pcf_algo = { .master_xfer = pcf_xfer, .functionality = pcf_func, }; -/* - * registering functions to load algorithms at runtime +/* + * registering functions to load algorithms at runtime */ int i2c_pcf_add_bus(struct i2c_adapter *adap) { @@ -458,4 +438,4 @@ MODULE_LICENSE("GPL"); module_param(i2c_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); -- cgit v0.10.2 From 94d78e180c0323422854bc1718e657ac2d0cac1b Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 28 Mar 2009 21:34:42 +0100 Subject: i2c-algo-pcf: Handle timeout correctly With a postfix decrement these timeouts reach -1 rather than 0, but after the loop it is tested whether they have become 0. As pointed out by Jean Delvare, the msg_num should be tested before the timeout. With the current order, you could exit with a timeout error while all the messages were successfully transferred. Signed-off-by: Roel Kluin Signed-off-by: Jean Delvare Acked-by: Eric Brower diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 5906986..65a769f 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -115,15 +115,17 @@ static int wait_for_bb(struct i2c_algo_pcf_data *adap) status = get_pcf(adap, 1); - while (timeout-- && !(status & I2C_PCF_BB)) { + while (!(status & I2C_PCF_BB) && --timeout) { udelay(100); /* wait for 100 us */ status = get_pcf(adap, 1); } - if (timeout <= 0) + if (timeout == 0) { printk(KERN_ERR "Timeout waiting for Bus Busy\n"); + return -ETIMEDOUT; + } - return timeout <= 0; + return 0; } static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) @@ -133,7 +135,7 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) *status = get_pcf(adap, 1); - while (timeout-- && (*status & I2C_PCF_PIN)) { + while ((*status & I2C_PCF_PIN) && --timeout) { adap->waitforpin(adap->data); *status = get_pcf(adap, 1); } @@ -142,10 +144,10 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) return -EINTR; } - if (timeout <= 0) - return -1; - else - return 0; + if (timeout == 0) + return -ETIMEDOUT; + + return 0; } /* -- cgit v0.10.2 From 154d22b04ae1741c5fcfd5d747b813a9a279abff Mon Sep 17 00:00:00 2001 From: Frank Seidel Date: Sat, 28 Mar 2009 21:34:42 +0100 Subject: i2c: Add missing KERN_* constants to printks According to kerneljanitors todo list all printk calls (beginning a new line) should have an according KERN_* constant. Those are the missing pieces here for the i2c subsystem. Signed-off-by: Frank Seidel Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 65a769f..d31147e 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -61,7 +61,7 @@ static int i2c_debug; static void i2c_start(struct i2c_algo_pcf_data *adap) { - DEBPROTO(printk("S ")); + DEBPROTO(printk(KERN_DEBUG "S ")); set_pcf(adap, 1, I2C_PCF_START); } diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 4aa8138..c420a7c 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -49,7 +49,8 @@ static void pca_isa_writebyte(void *pd, int reg, int val) { #ifdef DEBUG_IO static char *names[] = { "T/O", "DAT", "ADR", "CON" }; - printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val); + printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg], + base+reg, val); #endif outb(val, base+reg); } @@ -60,7 +61,7 @@ static int pca_isa_readbyte(void *pd, int reg) #ifdef DEBUG_IO { static char *names[] = { "STA", "DAT", "ADR", "CON" }; - printk("*** read %s => %#04x\n", names[reg], res); + printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res); } #endif return res; diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 60ca917..3c9d71f 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev) i2c_set_adapdata(adapter, NULL); /* We aren't that prepared to deal with this... */ if (rc) - printk("i2c-powermac.c: Failed to remove bus %s !\n", + printk(KERN_WARNING + "i2c-powermac.c: Failed to remove bus %s !\n", adapter->name); platform_set_drvdata(dev, NULL); kfree(adapter); diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index bdb1f751..c1405c8 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id); static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why) { unsigned int i; - printk("i2c: error: %s\n", why); - printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n", + printk(KERN_ERR "i2c: error: %s\n", why); + printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n", i2c->msg_num, i2c->msg_idx, i2c->msg_ptr); - printk("i2c: ICR: %08x ISR: %08x\n" - "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c))); + printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n", + readl(_ICR(i2c)), readl(_ISR(i2c))); + printk(KERN_DEBUG "i2c: log: "); for (i = 0; i < i2c->irqlogidx; i++) printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]); printk("\n"); -- cgit v0.10.2 From 8fcfef6e65c5b58e6482eae0b793319c8d9efd44 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:43 +0100 Subject: i2c: Set a default timeout value for all adapters Setting a default timeout value on a per-algo basis doesn't make any sense. Move the default value setting to i2c-core. Individual adapter drivers can specify a different (non-zero) value if they wish. Also express the timeout value in a way which results in the same duration regarless of the value of HZ. Signed-off-by: Jean Delvare Acked-by: Wolfram Sang diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index eb8f72c..d420cc5 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; - - adap->timeout = 100; /* default values, should */ - adap->retries = 3; /* be replaced by defines */ + adap->retries = 3; return 0; } diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index d31147e..7ce7577 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -423,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) /* register new adapter to i2c module... */ adap->algo = &pcf_algo; - adap->timeout = 100; if ((rval = pcf_init_8584(pcf_adap))) return rval; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 456caa8..e361033 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -459,6 +459,11 @@ static int i2c_register_adapter(struct i2c_adapter *adap) pr_debug("I2C adapter driver [%s] forgot to specify " "physical device\n", adap->name); } + + /* Set default timeout to 1 second if not already set */ + if (adap->timeout == 0) + adap->timeout = HZ; + dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; -- cgit v0.10.2 From 8a52c6b4d55b2960d93a90a7cf6afd252357fa54 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:43 +0100 Subject: i2c: Adapter timeout is in jiffies i2c_adapter.timeout is in jiffies. Fix all drivers which thought otherwise. It didn't really matter as long as the value was only used inside the driver, but soon i2c-core will use it too so it must have the proper unit. Note: for the i2c-mpc driver, this fixes a bug in polling mode. Timeout would trigger after 1 jiffy, which is most probably not what the author wanted. Signed-off-by: Jean Delvare Cc: Clifford Wolf Acked-by: Sean MacLennan Cc: Stefan Roese Acked-by: Lennert Buytenhek Cc: Dan Williams Cc: Grant Likely Acked-by: Mark A. Greer diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 88f0db7..8b92a46 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ if (dev->irq >= 0){ /* Interrupt mode */ ret = wait_event_interruptible_timeout(dev->wq, - !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ); + !(in_8(&iic->sts) & STS_PT), dev->adap.timeout); if (unlikely(ret < 0)) DBG("%d: wait interrupted\n", dev->idx); @@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ } else { /* Polling mode */ - unsigned long x = jiffies + dev->adap.timeout * HZ; + unsigned long x = jiffies + dev->adap.timeout; while (in_8(&iic->sts) & STS_PT){ if (unlikely(time_after(jiffies, x))){ @@ -748,7 +748,7 @@ static int __devinit iic_probe(struct of_device *ofdev, i2c_set_adapdata(adap, dev); adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->algo = &iic_algo; - adap->timeout = 1; + adap->timeout = HZ; ret = i2c_add_adapter(adap); if (ret < 0) { diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 3190690..a75c75e 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -488,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device *pdev) /* * Default values...should these come in from board code? */ - new_adapter->timeout = 100; + new_adapter->timeout = HZ; new_adapter->algo = &iop3xx_i2c_algo; init_waitqueue_head(&adapter_data->waitq); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index aedbbe6..2b847d8 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -116,7 +116,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) } else { /* Interrupt mode */ result = wait_event_interruptible_timeout(i2c->queue, - (i2c->interrupt & CSR_MIF), timeout * HZ); + (i2c->interrupt & CSR_MIF), timeout); if (unlikely(result < 0)) { pr_debug("I2C: wait interrupted\n"); @@ -311,7 +311,7 @@ static struct i2c_adapter mpc_ops = { .owner = THIS_MODULE, .name = "MPC adapter", .algo = &mpc_algo, - .timeout = 1, + .timeout = HZ, }; static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 7f186bb..5a4945d 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) char abort = 0; time_left = wait_event_interruptible_timeout(drv_data->waitq, - !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout)); + !drv_data->block, drv_data->adapter.timeout); spin_lock_irqsave(&drv_data->lock, flags); if (!time_left) { /* Timed out */ @@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) spin_unlock_irqrestore(&drv_data->lock, flags); time_left = wait_event_timeout(drv_data->waitq, - !drv_data->block, - msecs_to_jiffies(drv_data->adapter.timeout)); + !drv_data->block, drv_data->adapter.timeout); if ((time_left <= 0) && drv_data->block) { drv_data->state = MV64XXX_I2C_STATE_IDLE; @@ -530,7 +529,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) drv_data->adapter.algo = &mv64xxx_i2c_algo; drv_data->adapter.owner = THIS_MODULE; drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - drv_data->adapter.timeout = pdata->timeout; + drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout); drv_data->adapter.nr = pd->id; platform_set_drvdata(pd, drv_data); i2c_set_adapdata(&drv_data->adapter, drv_data); -- cgit v0.10.2 From 98a679cad56c0ba4677821836179abbe0aff8769 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Mar 2009 21:34:43 +0100 Subject: i2c-davinci: Fix timeout handling Properly set the adapter timeout value in jiffies, and then use that value in the driver, rather than a hard-coded constant. Signed-off-by: Jean Delvare Tested-by: Troy Kisky Cc: Kevin Hilman diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 5d77898..3fae3a9 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, { unsigned long timeout; - timeout = jiffies + DAVINCI_I2C_TIMEOUT; + timeout = jiffies + dev->adapter.timeout; while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) { if (time_after(jiffies, timeout)) { @@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - DAVINCI_I2C_TIMEOUT); + dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); i2c_davinci_init(dev); @@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name)); adap->algo = &i2c_davinci_algo; adap->dev.parent = &pdev->dev; - - /* FIXME */ - adap->timeout = 1; + adap->timeout = DAVINCI_I2C_TIMEOUT; adap->nr = pdev->id; r = i2c_add_numbered_adapter(adap); -- cgit v0.10.2 From bac3e7c2aa2575a1c71f6fa643499676ca7c12c3 Mon Sep 17 00:00:00 2001 From: Frank Seidel Date: Sat, 28 Mar 2009 21:34:44 +0100 Subject: i2c: Adapt debug macros for KERN_* constants According to kerneljanitors todo list all printk calls (beginning a new line) should have an according KERN_* constant. Those are the changes to the debug macros in the i2c subsystem to meet this requirement. Also changing no-debug statements to raw printks again. Signed-off-by: Frank Seidel Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index d50b329..943d70e 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -27,9 +27,12 @@ #include #include -#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0) -#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0) -#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0) +#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \ + printk(KERN_DEBUG fmt, ## args); } while (0) +#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \ + printk(KERN_DEBUG fmt, ## args); } while (0) +#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \ + printk(KERN_DEBUG fmt, ## args); } while (0) static int i2c_debug; @@ -313,7 +316,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, ret = curmsg; out: - DEB1(KERN_CRIT "}}} transfered %d/%d messages. " + DEB1("}}} transfered %d/%d messages. " "status is %#04x. control is %#04x\n", curmsg, num, pca_status(adap), pca_get_con(adap)); @@ -347,7 +350,8 @@ static int pca_init(struct i2c_adapter *adap) pca_reset(pca_data); clock = pca_clock(pca_data); - DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); + printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, + freqs[clock]); pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); udelay(500); /* 500 us for oscilator to stabilise */ -- cgit v0.10.2 From eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57 Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa Date: Sat, 28 Mar 2009 21:34:44 +0100 Subject: i2c-algo-pca: Add PCA9665 support Add support for the PCA9665 I2C controller. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 943d70e..a8e51bd 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -46,6 +46,14 @@ static int i2c_debug; #define pca_wait(adap) adap->wait_for_completion(adap->data) #define pca_reset(adap) adap->reset_chip(adap->data) +static void pca9665_reset(void *pd) +{ + struct i2c_algo_pca_data *adap = pd; + pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); + pca_outw(adap, I2C_PCA_IND, 0xA5); + pca_outw(adap, I2C_PCA_IND, 0x5A); +} + /* * Generate a start condition on the i2c bus. * @@ -333,27 +341,171 @@ static const struct i2c_algorithm pca_algo = { .functionality = pca_func, }; -static int pca_init(struct i2c_adapter *adap) +static unsigned int pca_probe_chip(struct i2c_adapter *adap) { - static int freqs[] = {330,288,217,146,88,59,44,36}; - int clock; struct i2c_algo_pca_data *pca_data = adap->algo_data; - - if (pca_data->i2c_clock > 7) { - printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", - adap->name); - pca_data->i2c_clock = I2C_PCA_CON_59kHz; + /* The trick here is to check if there is an indirect register + * available. If there is one, we will read the value we first + * wrote on I2C_PCA_IADR. Otherwise, we will read the last value + * we wrote on I2C_PCA_ADR + */ + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); + pca_outw(pca_data, I2C_PCA_IND, 0xAA); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO); + pca_outw(pca_data, I2C_PCA_IND, 0x00); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); + if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { + printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); + return I2C_PCA_CHIP_9665; + } else { + printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); + return I2C_PCA_CHIP_9564; } +} + +static int pca_init(struct i2c_adapter *adap) +{ + struct i2c_algo_pca_data *pca_data = adap->algo_data; adap->algo = &pca_algo; - pca_reset(pca_data); + if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) { + static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36}; + int clock; + + if (pca_data->i2c_clock > 7) { + switch (pca_data->i2c_clock) { + case 330000: + pca_data->i2c_clock = I2C_PCA_CON_330kHz; + break; + case 288000: + pca_data->i2c_clock = I2C_PCA_CON_288kHz; + break; + case 217000: + pca_data->i2c_clock = I2C_PCA_CON_217kHz; + break; + case 146000: + pca_data->i2c_clock = I2C_PCA_CON_146kHz; + break; + case 88000: + pca_data->i2c_clock = I2C_PCA_CON_88kHz; + break; + case 59000: + pca_data->i2c_clock = I2C_PCA_CON_59kHz; + break; + case 44000: + pca_data->i2c_clock = I2C_PCA_CON_44kHz; + break; + case 36000: + pca_data->i2c_clock = I2C_PCA_CON_36kHz; + break; + default: + printk(KERN_WARNING + "%s: Invalid I2C clock speed selected." + " Using default 59kHz.\n", adap->name); + pca_data->i2c_clock = I2C_PCA_CON_59kHz; + } + } else { + printk(KERN_WARNING "%s: " + "Choosing the clock frequency based on " + "index is deprecated." + " Use the nominal frequency.\n", adap->name); + } + + pca_reset(pca_data); + + clock = pca_clock(pca_data); + printk(KERN_INFO "%s: Clock frequency is %dkHz\n", + adap->name, freqs[clock]); + + pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); + } else { + int clock; + int mode; + int tlow, thi; + /* Values can be found on PCA9665 datasheet section 7.3.2.6 */ + int min_tlow, min_thi; + /* These values are the maximum raise and fall values allowed + * by the I2C operation mode (Standard, Fast or Fast+) + * They are used (added) below to calculate the clock dividers + * of PCA9665. Note that they are slightly different of the + * real maximum, to allow the change on mode exactly on the + * maximum clock rate for each mode + */ + int raise_fall_time; + + struct i2c_algo_pca_data *pca_data = adap->algo_data; + + /* Ignore the reset function from the module, + * we can use the parallel bus reset + */ + pca_data->reset_chip = pca9665_reset; + + if (pca_data->i2c_clock > 1265800) { + printk(KERN_WARNING "%s: I2C clock speed too high." + " Using 1265.8kHz.\n", adap->name); + pca_data->i2c_clock = 1265800; + } + + if (pca_data->i2c_clock < 60300) { + printk(KERN_WARNING "%s: I2C clock speed too low." + " Using 60.3kHz.\n", adap->name); + pca_data->i2c_clock = 60300; + } + + /* To avoid integer overflow, use clock/100 for calculations */ + clock = pca_clock(pca_data) / 100; + + if (pca_data->i2c_clock > 10000) { + mode = I2C_PCA_MODE_TURBO; + min_tlow = 14; + min_thi = 5; + raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ + } else if (pca_data->i2c_clock > 4000) { + mode = I2C_PCA_MODE_FASTP; + min_tlow = 17; + min_thi = 9; + raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ + } else if (pca_data->i2c_clock > 1000) { + mode = I2C_PCA_MODE_FAST; + min_tlow = 44; + min_thi = 20; + raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */ + } else { + mode = I2C_PCA_MODE_STD; + min_tlow = 157; + min_thi = 134; + raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */ + } + + /* The minimum clock that respects the thi/tlow = 134/157 is + * 64800 Hz. Below that, we have to fix the tlow to 255 and + * calculate the thi factor. + */ + if (clock < 648) { + tlow = 255; + thi = 1000000 - clock * raise_fall_time; + thi /= (I2C_PCA_OSC_PER * clock) - tlow; + } else { + tlow = (1000000 - clock * raise_fall_time) * min_tlow; + tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow); + thi = tlow * min_thi / min_tlow; + } + + pca_reset(pca_data); - clock = pca_clock(pca_data); - printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, - freqs[clock]); + printk(KERN_INFO + "%s: Clock frequency is %dHz\n", adap->name, clock * 100); - pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); + pca_outw(pca_data, I2C_PCA_IND, mode); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); + pca_outw(pca_data, I2C_PCA_IND, tlow); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); + pca_outw(pca_data, I2C_PCA_IND, thi); + + pca_set_con(pca_data, I2C_PCA_CON_ENSIO); + } udelay(500); /* 500 us for oscilator to stabilise */ return 0; @@ -388,7 +540,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus); MODULE_AUTHOR("Ian Campbell , " "Wolfram Sang "); -MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); +MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); MODULE_LICENSE("GPL"); module_param(i2c_debug, int, 0); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7f95905..6865064 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -617,12 +617,12 @@ config I2C_ELEKTOR will be called i2c-elektor. config I2C_PCA_ISA - tristate "PCA9564 on an ISA bus" + tristate "PCA9564/PCA9665 on an ISA bus" depends on ISA select I2C_ALGOPCA default n help - This driver supports ISA boards using the Philips PCA9564 + This driver supports ISA boards using the Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module @@ -634,11 +634,11 @@ config I2C_PCA_ISA time). If unsure, say N. config I2C_PCA_PLATFORM - tristate "PCA9564 as platform device" + tristate "PCA9564/PCA9665 as platform device" select I2C_ALGOPCA default n help - This driver supports a memory mapped Philips PCA9564 + This driver supports a memory mapped Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index c420a7c..0cc8017 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -41,7 +41,7 @@ static int irq = -1; /* Data sheet recommends 59kHz for 100kHz operation due to variation * in the actual clock rate */ -static int clock = I2C_PCA_CON_59kHz; +static int clock = 59000; static wait_queue_head_t pca_wait; @@ -103,7 +103,7 @@ static struct i2c_algo_pca_data pca_isa_data = { static struct i2c_adapter pca_isa_ops = { .owner = THIS_MODULE, .algo_data = &pca_isa_data, - .name = "PCA9564 ISA Adapter", + .name = "PCA9564/PCA9665 ISA Adapter", .timeout = 100, }; @@ -196,7 +196,7 @@ static void __exit pca_isa_exit(void) } MODULE_AUTHOR("Ian Campbell "); -MODULE_DESCRIPTION("ISA base PCA9564 driver"); +MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); MODULE_LICENSE("GPL"); module_param(base, ulong, 0); @@ -205,7 +205,13 @@ MODULE_PARM_DESC(base, "I/O base address"); module_param(irq, int, 0); MODULE_PARM_DESC(irq, "IRQ"); module_param(clock, int, 0); -MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); +MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" + "For PCA9564: 330000,288000,217000,146000," + "88000,59000,44000,36000\n" + "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" + "\t\t\t\tFast: 100100 - 400099\n" + "\t\t\t\tFast+: 400100 - 10000099\n" + "\t\t\t\tTurbo: Up to 1265800"); module_init(pca_isa_init); module_exit(pca_isa_exit); diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 6bb15ad..51d179b 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -172,8 +172,9 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; i2c->adap.owner = THIS_MODULE; - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx", - (unsigned long) res->start); + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + "PCA9564/PCA9665 at 0x%08lx", + (unsigned long) res->start); i2c->adap.algo_data = &i2c->algo_data; i2c->adap.dev.parent = &pdev->dev; i2c->adap.timeout = platform_data->timeout; @@ -246,7 +247,7 @@ e_remap: e_alloc: release_mem_region(res->start, res_len(res)); e_print: - printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret); + printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret); return ret; } @@ -290,7 +291,7 @@ static void __exit i2c_pca_pf_exit(void) } MODULE_AUTHOR("Wolfram Sang "); -MODULE_DESCRIPTION("I2C-PCA9564 platform driver"); +MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); MODULE_LICENSE("GPL"); module_init(i2c_pca_pf_init); diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h index adcb3dc..1364d62 100644 --- a/include/linux/i2c-algo-pca.h +++ b/include/linux/i2c-algo-pca.h @@ -1,7 +1,14 @@ #ifndef _LINUX_I2C_ALGO_PCA_H #define _LINUX_I2C_ALGO_PCA_H -/* Clock speeds for the bus */ +/* Chips known to the pca algo */ +#define I2C_PCA_CHIP_9564 0x00 +#define I2C_PCA_CHIP_9665 0x01 + +/* Internal period for PCA9665 oscilator */ +#define I2C_PCA_OSC_PER 3 /* e10-8s */ + +/* Clock speeds for the bus for PCA9564*/ #define I2C_PCA_CON_330kHz 0x00 #define I2C_PCA_CON_288kHz 0x01 #define I2C_PCA_CON_217kHz 0x02 @@ -18,6 +25,26 @@ #define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */ #define I2C_PCA_CON 0x03 /* CONTROL Read/Write */ +/* PCA9665 registers */ +#define I2C_PCA_INDPTR 0x00 /* INDIRECT Pointer Write Only */ +#define I2C_PCA_IND 0x02 /* INDIRECT Read/Write */ + +/* PCA9665 indirect registers */ +#define I2C_PCA_ICOUNT 0x00 /* Byte Count for buffered mode */ +#define I2C_PCA_IADR 0x01 /* OWN ADR */ +#define I2C_PCA_ISCLL 0x02 /* SCL LOW period */ +#define I2C_PCA_ISCLH 0x03 /* SCL HIGH period */ +#define I2C_PCA_ITO 0x04 /* TIMEOUT */ +#define I2C_PCA_IPRESET 0x05 /* Parallel bus reset */ +#define I2C_PCA_IMODE 0x06 /* I2C Bus mode */ + +/* PCA9665 I2C bus mode */ +#define I2C_PCA_MODE_STD 0x00 /* Standard mode */ +#define I2C_PCA_MODE_FAST 0x01 /* Fast mode */ +#define I2C_PCA_MODE_FASTP 0x02 /* Fast Plus mode */ +#define I2C_PCA_MODE_TURBO 0x03 /* Turbo mode */ + + #define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */ #define I2C_PCA_CON_ENSIO 0x40 /* Enable */ #define I2C_PCA_CON_STA 0x20 /* Start */ @@ -31,7 +58,9 @@ struct i2c_algo_pca_data { int (*read_byte) (void *data, int reg); int (*wait_for_completion) (void *data); void (*reset_chip) (void *data); - /* i2c_clock values are defined in linux/i2c-algo-pca.h */ + /* For PCA9564, use one of the predefined frequencies: + * 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000 + * For PCA9665, use the frequency you want here. */ unsigned int i2c_clock; }; -- cgit v0.10.2 From 8e99ada8deaa9033600cd2c7d0a9366b0e99ab68 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Mar 2009 21:34:45 +0100 Subject: i2c-algo-pca: Rework waiting for a free bus Waiting for a free bus now accepts the timeout value in jiffies and does proper checking using time_before. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index 94c0296..6f94f17 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -229,7 +229,7 @@ static struct resource i2c_resources[] = { static struct i2c_pca9564_pf_platform_data i2c_platform_data = { .gpio = 0, .i2c_clock_speed = I2C_PCA_CON_330kHz, - .timeout = 100, + .timeout = HZ, }; static struct platform_device i2c_device = { diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index a8e51bd..9e134fa 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -186,14 +187,16 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, int numbytes = 0; int state; int ret; - int timeout = i2c_adap->timeout; + unsigned long timeout = jiffies + i2c_adap->timeout; - while ((state = pca_status(adap)) != 0xf8 && timeout--) { - msleep(10); - } - if (state != 0xf8) { - dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state); - return -EAGAIN; + while (pca_status(adap) != 0xf8) { + if (time_before(jiffies, timeout)) { + msleep(10); + } else { + dev_dbg(&i2c_adap->dev, "bus is not idle. status is " + "%#04x\n", state); + return -EAGAIN; + } } DEB1("{{{ XFER %d messages\n", num); diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 0cc8017..b9403fd 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -104,7 +104,7 @@ static struct i2c_adapter pca_isa_ops = { .owner = THIS_MODULE, .algo_data = &pca_isa_data, .name = "PCA9564/PCA9665 ISA Adapter", - .timeout = 100, + .timeout = HZ, }; static int __devinit pca_isa_match(struct device *dev, unsigned int id) diff --git a/include/linux/i2c-pca-platform.h b/include/linux/i2c-pca-platform.h index 3d19187..aba3375 100644 --- a/include/linux/i2c-pca-platform.h +++ b/include/linux/i2c-pca-platform.h @@ -6,7 +6,7 @@ struct i2c_pca9564_pf_platform_data { * not supplied (negative value), but it * cannot exit some error conditions then */ int i2c_clock_speed; /* values are defined in linux/i2c-algo-pca.h */ - int timeout; /* timeout = this value * 10us */ + int timeout; /* timeout in jiffies */ }; #endif /* I2C_PCA9564_PLATFORM_H */ -- cgit v0.10.2 From 2378bc09b91b0702fac7823828a614fd8016a29f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Mar 2009 21:34:45 +0100 Subject: i2c-algo-pca: Use timeout for checking the state machine We now timeout also if the state machine does not change within the given time. For that, the driver-specific completion-functions are extended to return true or false depending on the timeout. This then gets checked in the algorithm. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 9e134fa..f68e5f8 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -60,14 +60,14 @@ static void pca9665_reset(void *pd) * * returns after the start condition has occurred */ -static void pca_start(struct i2c_algo_pca_data *adap) +static int pca_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -75,14 +75,14 @@ static void pca_start(struct i2c_algo_pca_data *adap) * * return after the repeated start condition has occurred */ -static void pca_repeated_start(struct i2c_algo_pca_data *adap) +static int pca_repeated_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== REPEATED START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -108,7 +108,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap) * * returns after the address has been sent */ -static void pca_address(struct i2c_algo_pca_data *adap, +static int pca_address(struct i2c_algo_pca_data *adap, struct i2c_msg *msg) { int sta = pca_get_con(adap); @@ -125,7 +125,7 @@ static void pca_address(struct i2c_algo_pca_data *adap, sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -133,7 +133,7 @@ static void pca_address(struct i2c_algo_pca_data *adap, * * Returns after the byte has been transmitted */ -static void pca_tx_byte(struct i2c_algo_pca_data *adap, +static int pca_tx_byte(struct i2c_algo_pca_data *adap, __u8 b) { int sta = pca_get_con(adap); @@ -143,7 +143,7 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap, sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -163,7 +163,7 @@ static void pca_rx_byte(struct i2c_algo_pca_data *adap, * * Returns after next byte has arrived. */ -static void pca_rx_ack(struct i2c_algo_pca_data *adap, +static int pca_rx_ack(struct i2c_algo_pca_data *adap, int ack) { int sta = pca_get_con(adap); @@ -174,7 +174,7 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap, sta |= I2C_PCA_CON_AA; pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } static int pca_xfer(struct i2c_adapter *i2c_adap, @@ -187,6 +187,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, int numbytes = 0; int state; int ret; + int completed = 1; unsigned long timeout = jiffies + i2c_adap->timeout; while (pca_status(adap) != 0xf8) { @@ -232,18 +233,19 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, switch (state) { case 0xf8: /* On reset or stop the bus is idle */ - pca_start(adap); + completed = pca_start(adap); break; case 0x08: /* A START condition has been transmitted */ case 0x10: /* A repeated start condition has been transmitted */ - pca_address(adap, msg); + completed = pca_address(adap, msg); break; case 0x18: /* SLA+W has been transmitted; ACK has been received */ case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ if (numbytes < msg->len) { - pca_tx_byte(adap, msg->buf[numbytes]); + completed = pca_tx_byte(adap, + msg->buf[numbytes]); numbytes++; break; } @@ -251,7 +253,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); break; case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ @@ -260,21 +262,22 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, goto out; case 0x40: /* SLA+R has been transmitted; ACK has been received */ - pca_rx_ack(adap, msg->len > 1); + completed = pca_rx_ack(adap, msg->len > 1); break; case 0x50: /* Data bytes has been received; ACK has been returned */ if (numbytes < msg->len) { pca_rx_byte(adap, &msg->buf[numbytes], 1); numbytes++; - pca_rx_ack(adap, numbytes < msg->len - 1); + completed = pca_rx_ack(adap, + numbytes < msg->len - 1); break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); break; case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ @@ -297,7 +300,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); } else { DEB2("NOT ACK sent after data byte received. " "Not final byte. numbytes %d. len %d\n", @@ -323,6 +326,8 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, break; } + if (!completed) + goto out; } ret = curmsg; diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index b9403fd..0ed68e2 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ static int irq = -1; * in the actual clock rate */ static int clock = 59000; +static struct i2c_adapter pca_isa_ops; static wait_queue_head_t pca_wait; static void pca_isa_writebyte(void *pd, int reg, int val) @@ -69,16 +71,22 @@ static int pca_isa_readbyte(void *pd, int reg) static int pca_isa_waitforcompletion(void *pd) { - int ret = 0; + long ret = ~0; + unsigned long timeout; if (irq > -1) { - ret = wait_event_interruptible(pca_wait, - pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI); + ret = wait_event_interruptible_timeout(pca_wait, + pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI, pca_isa_ops.timeout); } else { - while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + /* Do polling */ + timeout = jiffies + pca_isa_ops.timeout; + while (((pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI) == 0) + && (ret = time_before(jiffies, timeout))) udelay(100); } - return ret; + return ret > 0; } static void pca_isa_resetchip(void *pd) diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 51d179b..df5e593 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) static int i2c_pca_pf_waitforcompletion(void *pd) { struct i2c_pca_pf_data *i2c = pd; - int ret = 0; + long ret = ~0; + unsigned long timeout; if (i2c->irq) { - ret = wait_event_interruptible(i2c->wait, + ret = wait_event_interruptible_timeout(i2c->wait, i2c->algo_data.read_byte(i2c, I2C_PCA_CON) - & I2C_PCA_CON_SI); + & I2C_PCA_CON_SI, i2c->adap.timeout); } else { - /* - * Do polling... - * XXX: Could get stuck in extreme cases! - * Maybe add timeout, but using irqs is preferred anyhow. - */ - while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + /* Do polling */ + timeout = jiffies + i2c->adap.timeout; + while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + && (ret = time_before(jiffies, timeout))) udelay(100); } - return ret; + return ret > 0; } static void i2c_pca_pf_dummyreset(void *pd) -- cgit v0.10.2 From 6b110d13aacc9c4ef5f01af12a5e2b7f1d23f106 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Mar 2009 21:34:45 +0100 Subject: i2c-pca-platform: Use defaults if no platform_data given Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index df5e593..7b23891 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -177,10 +177,20 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) (unsigned long) res->start); i2c->adap.algo_data = &i2c->algo_data; i2c->adap.dev.parent = &pdev->dev; - i2c->adap.timeout = platform_data->timeout; - i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed; + if (platform_data) { + i2c->adap.timeout = platform_data->timeout; + i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed; + i2c->gpio = platform_data->gpio; + } else { + i2c->adap.timeout = HZ; + i2c->algo_data.i2c_clock = 59000; + i2c->gpio = -1; + } + i2c->algo_data.data = i2c; + i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion; + i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset; switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { case IORESOURCE_MEM_32BIT: @@ -198,11 +208,6 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) break; } - i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion; - - i2c->gpio = platform_data->gpio; - i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset; - /* Use gpio_is_valid() when in mainline */ if (i2c->gpio > -1) { ret = gpio_request(i2c->gpio, i2c->adap.name); -- cgit v0.10.2 From 87e1960e93fe792c4f4344a6f3a970f9573c76aa Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Sat, 28 Mar 2009 21:34:46 +0100 Subject: i2c-piix4: Add support to SB800 SMBus changes Add support for the AMD SB800 Family series of products. Major changes include the changes to addressing the SMBus registers at different location from the locations in the previous compatible parts from AMD such as SB400/SB600/SB700. For SB800, the main features and register definitions of SMBus and other interfaces are still compatible with the previous products with the only change being in how to access the internal registers for these blocks. Signed-off-by: Shane Huang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 761f9dd..63d5e59 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, return 0; } +static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, + const struct pci_device_id *id) +{ + unsigned short smba_idx = 0xcd6; + u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; + + /* SB800 SMBus does not support forcing address */ + if (force || force_addr) { + dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support " + "forcing address!\n"); + return -EINVAL; + } + + /* Determine the address of the SMBus areas */ + if (!request_region(smba_idx, 2, "smba_idx")) { + dev_err(&PIIX4_dev->dev, "SMBus base address index region " + "0x%x already in use!\n", smba_idx); + return -EBUSY; + } + outb_p(smb_en, smba_idx); + smba_en_lo = inb_p(smba_idx + 1); + outb_p(smb_en + 1, smba_idx); + smba_en_hi = inb_p(smba_idx + 1); + release_region(smba_idx, 2); + + if ((smba_en_lo & 1) == 0) { + dev_err(&PIIX4_dev->dev, + "Host SMBus controller not enabled!\n"); + return -ENODEV; + } + + piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) + return -EBUSY; + + if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { + dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", + piix4_smba); + return -EBUSY; + } + + /* Request the SMBus I2C bus config region */ + if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { + dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " + "0x%x already in use!\n", piix4_smba + i2ccfg_offset); + release_region(piix4_smba, SMBIOSIZE); + piix4_smba = 0; + return -EBUSY; + } + i2ccfg = inb_p(piix4_smba + i2ccfg_offset); + release_region(piix4_smba + i2ccfg_offset, 1); + + if (i2ccfg & 1) + dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); + else + dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); + + dev_info(&PIIX4_dev->dev, + "SMBus Host Controller at 0x%x, revision %d\n", + piix4_smba, i2ccfg >> 4); + + return 0; +} + static int piix4_transaction(void) { int temp; @@ -433,7 +497,14 @@ static int __devinit piix4_probe(struct pci_dev *dev, { int retval; - retval = piix4_setup(dev, id); + if ((dev->vendor == PCI_VENDOR_ID_ATI) && + (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) && + (dev->revision >= 0x40)) + /* base address location etc changed in SB800 */ + retval = piix4_setup_sb800(dev, id); + else + retval = piix4_setup(dev, id); + if (retval) return retval; -- cgit v0.10.2 From 506a8b6c27cb08998dc13069fbdf6eb7ec748b99 Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Sat, 28 Mar 2009 21:34:46 +0100 Subject: i2c-piix4: Add support for the Broadcom HT1100 chipset Add support for the Broadcom HT1100 LD chipset (SMBus function.) Signed-off-by: Flavio Leitner Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4 index ef1efa7..f889481 100644 --- a/Documentation/i2c/busses/i2c-piix4 +++ b/Documentation/i2c/busses/i2c-piix4 @@ -4,7 +4,7 @@ Supported adapters: * Intel 82371AB PIIX4 and PIIX4E * Intel 82443MX (440MX) Datasheet: Publicly available at the Intel website - * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges + * ServerWorks OSB4, CSB5, CSB6, HT-1000 and HT-1100 southbridges Datasheet: Only available via NDA from ServerWorks * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges Datasheet: Not publicly available diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 6865064..da809ad 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -132,6 +132,7 @@ config I2C_PIIX4 Serverworks CSB5 Serverworks CSB6 Serverworks HT-1000 + Serverworks HT-1100 SMSC Victory66 This driver can also be built as a module. If so, the module diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 63d5e59..0249a7d 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -20,7 +20,7 @@ /* Supports: Intel PIIX4, 440MX - Serverworks OSB4, CSB5, CSB6, HT-1000 + Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 SMSC Victory66 @@ -487,6 +487,8 @@ static struct pci_device_id piix4_ids[] = { PCI_DEVICE_ID_SERVERWORKS_CSB6) }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, + PCI_DEVICE_ID_SERVERWORKS_HT1100LD) }, { 0, } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5109fec..2c9e808 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1479,6 +1479,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 +#define PCI_DEVICE_ID_SERVERWORKS_HT1100LD 0x0408 #define PCI_VENDOR_ID_SBE 0x1176 #define PCI_DEVICE_ID_SBE_WANXL100 0x0301 -- cgit v0.10.2 From 09b8ce0a691d8e76f14a16ac6cbfde899f6c68e3 Mon Sep 17 00:00:00 2001 From: Zhenwen Xu Date: Sat, 28 Mar 2009 21:34:46 +0100 Subject: i2c-core: Some style cleanups Some lines over 80. The printk(KERN_ERR ... ) should be dev_err. And some blankspace should be deleted. Signed-off-by: Zhenwen Xu Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e361033..b6f3a0d 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -152,7 +152,7 @@ static void i2c_device_shutdown(struct device *dev) driver->shutdown(to_i2c_client(dev)); } -static int i2c_device_suspend(struct device * dev, pm_message_t mesg) +static int i2c_device_suspend(struct device *dev, pm_message_t mesg) { struct i2c_driver *driver; @@ -164,7 +164,7 @@ static int i2c_device_suspend(struct device * dev, pm_message_t mesg) return driver->suspend(to_i2c_client(dev), mesg); } -static int i2c_device_resume(struct device * dev) +static int i2c_device_resume(struct device *dev) { struct i2c_driver *driver; @@ -187,13 +187,15 @@ static void i2c_client_dev_release(struct device *dev) kfree(to_i2c_client(dev)); } -static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t +show_client_name(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); return sprintf(buf, "%s\n", client->name); } -static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t +show_modalias(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); @@ -365,8 +367,7 @@ static struct i2c_driver dummy_driver = { * This returns the new i2c client, which should be saved for later use with * i2c_unregister_device(); or NULL to indicate an error. */ -struct i2c_client * -i2c_new_dummy(struct i2c_adapter *adapter, u16 address) +struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) { struct i2c_board_info info = { I2C_BOARD_INFO("dummy", address), @@ -413,8 +414,8 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter, &devinfo->board_info)) - printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n", - i2c_adapter_id(adapter), + dev_err(&adapter->dev, + "Can't create device at 0x%02x\n", devinfo->board_info.addr); } mutex_unlock(&__i2c_board_lock); @@ -1020,7 +1021,7 @@ module_exit(i2c_exit); * Note that there is no requirement that each message be sent to * the same slave address, although that is the most common model. */ -int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) +int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { int ret; @@ -1527,8 +1528,7 @@ EXPORT_SYMBOL(i2c_put_adapter); /* The SMBus parts */ #define POLY (0x1070U << 3) -static u8 -crc8(u16 data) +static u8 crc8(u16 data) { int i; @@ -1992,9 +1992,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, * This executes an SMBus protocol operation, and returns a negative * errno code else zero on success. */ -s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, +s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int protocol, - union i2c_smbus_data * data) + union i2c_smbus_data *data) { s32 res; -- cgit v0.10.2