Skip to content

Commit

Permalink
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/jdelvare/staging

Pull i2c updates from Jean Delvare:
 "Most visible changes are the SMBus multiplexing support added to the
  i2c-i801 driver, as well as support for the VIA VX900."

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c-piix4: Fix build failure
  i2c: Correct struct i2c_driver doc about detection
  i2c-i801: Let i2c-mux-gpio find the GPIO chip
  i2c-mux-gpio: Update documentation
  i2c-mux-gpio: Add support for dynamically allocated GPIO pins
  i2c-mux-gpio: Use devm_kzalloc instead of kzalloc
  i2c-i801: Support SMBus multiplexing on Asus Z8 series
  i2c-viapro: Add VIA VX900 device ID
  i2c-parport: i2c_parport_irq can be static
  i2c-designware: i2c_dw_xfer_msg can be static
  i2c/scx200_*: Replace printks with pr_<level>s
  i2c: Make I2C available on UML
  i2c: Convert struct i2c_msg initialization to C99 format
  i2c-smbus: Convert kzalloc to devm_kzalloc
  i2c-mux: Add support for device auto-detection
  • Loading branch information
Linus Torvalds committed Oct 7, 2012
2 parents c0703c1 + c415b30 commit 1b03344
Show file tree
Hide file tree
Showing 23 changed files with 347 additions and 73 deletions.
6 changes: 5 additions & 1 deletion Documentation/i2c/busses/i2c-viapro
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ Supported adapters:
Datasheet: available on http://linux.via.com.tw

* VIA Technologies, Inc. VX855/VX875
Datasheet: Availability unknown
Datasheet: available on http://linux.via.com.tw

* VIA Technologies, Inc. VX900
Datasheet: available on http://linux.via.com.tw

Authors:
Kyösti Mälkki <kmalkki@cc.hut.fi>,
Expand Down Expand Up @@ -57,6 +60,7 @@ Your lspci -n listing must show one of these :
device 1106:8324 (CX700)
device 1106:8353 (VX800/VX820)
device 1106:8409 (VX855/VX875)
device 1106:8410 (VX900)

If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB.
Expand Down
18 changes: 18 additions & 0 deletions Documentation/i2c/muxes/i2c-mux-gpio
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,21 @@ static struct platform_device myboard_i2cmux = {
.platform_data = &myboard_i2cmux_data,
},
};

If you don't know the absolute GPIO pin numbers at registration time,
you can instead provide a chip name (.chip_name) and relative GPIO pin
numbers, and the i2c-gpio-mux driver will do the work for you,
including deferred probing if the GPIO chip isn't immediately
available.

Device Registration
-------------------

When registering your i2c-gpio-mux device, you should pass the number
of any GPIO pin it uses as the device ID. This guarantees that every
instance has a different ID.

Alternatively, if you don't need a stable device name, you can simply
pass PLATFORM_DEVID_AUTO as the device ID, and the platform core will
assign a dynamic ID to your device. If you do not know the absolute
GPIO pin numbers at registration time, this is even the only option.
17 changes: 16 additions & 1 deletion drivers/i2c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

menuconfig I2C
tristate "I2C support"
depends on HAS_IOMEM
depends on !S390
select RT_MUTEXES
---help---
I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
Expand Down Expand Up @@ -49,6 +49,7 @@ config I2C_CHARDEV

config I2C_MUX
tristate "I2C bus multiplexing support"
depends on HAS_IOMEM
help
Say Y here if you want the I2C core to support the ability to
handle multiplexed I2C bus topologies, by presenting each
Expand Down Expand Up @@ -86,6 +87,19 @@ config I2C_SMBUS
source drivers/i2c/algos/Kconfig
source drivers/i2c/busses/Kconfig

config I2C_STUB
tristate "I2C/SMBus Test Stub"
depends on EXPERIMENTAL && m
default 'n'
help
This module may be useful to developers of SMBus client drivers,
especially for certain kinds of sensor chips.

If you do build this module, be sure to read the notes and warnings
in <file:Documentation/i2c/i2c-stub>.

If you don't know what to do here, definitely say N.

config I2C_DEBUG_CORE
bool "I2C Core debugging messages"
help
Expand All @@ -103,6 +117,7 @@ config I2C_DEBUG_ALGO

config I2C_DEBUG_BUS
bool "I2C Bus debugging messages"
depends on HAS_IOMEM
help
Say Y here if you want the I2C bus drivers to produce a bunch of
debug messages to the system log. Select this if you are having
Expand Down
18 changes: 4 additions & 14 deletions drivers/i2c/busses/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

menu "I2C Hardware Bus support"
depends on HAS_IOMEM

comment "PC SMBus host controller drivers"
depends on PCI
Expand Down Expand Up @@ -80,6 +81,7 @@ config I2C_I801
tristate "Intel 82801 (ICH/PCH)"
depends on PCI
select CHECK_SIGNATURE if X86 && DMI
select GPIOLIB if I2C_MUX
help
If you say yes to this option, support will be included for the Intel
801 family of mainboard I2C interfaces. Specifically, the following
Expand Down Expand Up @@ -224,7 +226,7 @@ config I2C_VIA
will be called i2c-via.

config I2C_VIAPRO
tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900"
depends on PCI
help
If you say yes to this option, support will be included for the VIA
Expand All @@ -240,6 +242,7 @@ config I2C_VIAPRO
CX700
VX800/VX820
VX855/VX875
VX900

This driver can also be built as a module. If so, the module
will be called i2c-viapro.
Expand Down Expand Up @@ -849,19 +852,6 @@ config I2C_SIBYTE
help
Supports the SiByte SOC on-chip I2C interfaces (2 channels).

config I2C_STUB
tristate "I2C/SMBus Test Stub"
depends on EXPERIMENTAL && m
default 'n'
help
This module may be useful to developers of SMBus client drivers,
especially for certain kinds of sensor chips.

If you do build this module, be sure to read the notes and warnings
in <file:Documentation/i2c/i2c-stub>.

If you don't know what to do here, definitely say N.

config SCx200_I2C
tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
depends on SCx200_GPIO
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-designware-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
* messages into the tx buffer. Even if the size of i2c_msg data is
* longer than the size of the tx buffer, it handles everything.
*/
void
static void
i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
{
struct i2c_msg *msgs = dev->msgs;
Expand Down
185 changes: 184 additions & 1 deletion drivers/i2c/busses/i2c-i801.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/err.h>

#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
#include <linux/gpio.h>
#include <linux/i2c-mux-gpio.h>
#include <linux/platform_device.h>
#endif

/* I801 SMBus address offsets */
#define SMBHSTSTS(p) (0 + (p)->smba)
Expand Down Expand Up @@ -158,6 +165,15 @@
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22

struct i801_mux_config {
char *gpio_chip;
unsigned values[3];
int n_values;
unsigned classes[3];
unsigned gpios[2]; /* Relative to gpio_chip->base */
int n_gpios;
};

struct i801_priv {
struct i2c_adapter adapter;
unsigned long smba;
Expand All @@ -175,6 +191,11 @@ struct i801_priv {
int count;
int len;
u8 *data;

#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
const struct i801_mux_config *mux_drvdata;
struct platform_device *mux_pdev;
#endif
};

static struct pci_driver i801_driver;
Expand Down Expand Up @@ -900,6 +921,165 @@ static void __init input_apanel_init(void) {}
static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
#endif /* CONFIG_X86 && CONFIG_DMI */

#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
.gpio_chip = "gpio_ich",
.values = { 0x02, 0x03 },
.n_values = 2,
.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
.gpios = { 52, 53 },
.n_gpios = 2,
};

static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
.gpio_chip = "gpio_ich",
.values = { 0x02, 0x03, 0x01 },
.n_values = 3,
.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
.gpios = { 52, 53 },
.n_gpios = 2,
};

static struct dmi_system_id __devinitdata mux_dmi_table[] = {
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
},
.driver_data = &i801_mux_config_asus_z8_d18,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
},
.driver_data = &i801_mux_config_asus_z8_d18,
},
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
},
.driver_data = &i801_mux_config_asus_z8_d12,
},
{ }
};

/* Setup multiplexing if needed */
static int __devinit i801_add_mux(struct i801_priv *priv)
{
struct device *dev = &priv->adapter.dev;
const struct i801_mux_config *mux_config;
struct i2c_mux_gpio_platform_data gpio_data;
int err;

if (!priv->mux_drvdata)
return 0;
mux_config = priv->mux_drvdata;

/* Prepare the platform data */
memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
gpio_data.parent = priv->adapter.nr;
gpio_data.values = mux_config->values;
gpio_data.n_values = mux_config->n_values;
gpio_data.classes = mux_config->classes;
gpio_data.gpio_chip = mux_config->gpio_chip;
gpio_data.gpios = mux_config->gpios;
gpio_data.n_gpios = mux_config->n_gpios;
gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;

/* Register the mux device */
priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
PLATFORM_DEVID_AUTO, &gpio_data,
sizeof(struct i2c_mux_gpio_platform_data));
if (IS_ERR(priv->mux_pdev)) {
err = PTR_ERR(priv->mux_pdev);
priv->mux_pdev = NULL;
dev_err(dev, "Failed to register i2c-mux-gpio device\n");
return err;
}

return 0;
}

static void __devexit i801_del_mux(struct i801_priv *priv)
{
if (priv->mux_pdev)
platform_device_unregister(priv->mux_pdev);
}

static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv)
{
const struct dmi_system_id *id;
const struct i801_mux_config *mux_config;
unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
int i;

id = dmi_first_match(mux_dmi_table);
if (id) {
/* Remove from branch classes from trunk */
mux_config = id->driver_data;
for (i = 0; i < mux_config->n_values; i++)
class &= ~mux_config->classes[i];

/* Remember for later */
priv->mux_drvdata = mux_config;
}

return class;
}
#else
static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
static inline void i801_del_mux(struct i801_priv *priv) { }

static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
{
return I2C_CLASS_HWMON | I2C_CLASS_SPD;
}
#endif

static int __devinit i801_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
Expand All @@ -913,7 +1093,7 @@ static int __devinit i801_probe(struct pci_dev *dev,

i2c_set_adapdata(&priv->adapter, priv);
priv->adapter.owner = THIS_MODULE;
priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
priv->adapter.class = i801_get_adapter_class(priv);
priv->adapter.algo = &smbus_algorithm;

priv->pci_dev = dev;
Expand Down Expand Up @@ -1033,6 +1213,8 @@ static int __devinit i801_probe(struct pci_dev *dev,
}

i801_probe_optional_slaves(priv);
/* We ignore errors - multiplexing is optional */
i801_add_mux(priv);

pci_set_drvdata(dev, priv);

Expand All @@ -1052,6 +1234,7 @@ static void __devexit i801_remove(struct pci_dev *dev)
{
struct i801_priv *priv = pci_get_drvdata(dev);

i801_del_mux(priv);
i2c_del_adapter(&priv->adapter);
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);

Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-parport.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ static const struct i2c_algo_bit_data parport_algo_data = {

/* ----- I2c and parallel port call-back functions and structures --------- */

void i2c_parport_irq(void *data)
static void i2c_parport_irq(void *data)
{
struct i2c_par *adapter = data;
struct i2c_client *ara = adapter->ara;
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/busses/i2c-piix4.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
Expand Down
Loading

0 comments on commit 1b03344

Please sign in to comment.