forked from Minki/linux
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
1b033447bf
@ -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>,
|
||||
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
menu "I2C Hardware Bus support"
|
||||
depends on HAS_IOMEM
|
||||
|
||||
comment "PC SMBus host controller drivers"
|
||||
depends on PCI
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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.
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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)
|
||||
{
|
||||
@ -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;
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -401,6 +401,7 @@ found:
|
||||
case PCI_DEVICE_ID_VIA_CX700:
|
||||
case PCI_DEVICE_ID_VIA_VX800:
|
||||
case PCI_DEVICE_ID_VIA_VX855:
|
||||
case PCI_DEVICE_ID_VIA_VX900:
|
||||
case PCI_DEVICE_ID_VIA_8251:
|
||||
case PCI_DEVICE_ID_VIA_8237:
|
||||
case PCI_DEVICE_ID_VIA_8237A:
|
||||
@ -470,6 +471,8 @@ static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = {
|
||||
.driver_data = SMBBA3 },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
|
||||
.driver_data = SMBBA3 },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900),
|
||||
.driver_data = SMBBA3 },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -37,8 +39,6 @@
|
||||
|
||||
#include <linux/scx200.h>
|
||||
|
||||
#define NAME "scx200_acb"
|
||||
|
||||
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
|
||||
MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
|
||||
MODULE_ALIAS("platform:cs5535-smb");
|
||||
@ -398,7 +398,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
|
||||
outb(0x70, ACBCTL2);
|
||||
|
||||
if (inb(ACBCTL2) != 0x70) {
|
||||
pr_debug(NAME ": ACBCTL2 readback failed\n");
|
||||
pr_debug("ACBCTL2 readback failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -406,8 +406,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
|
||||
|
||||
val = inb(ACBCTL1);
|
||||
if (val) {
|
||||
pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
|
||||
val);
|
||||
pr_debug("disabled, but ACBCTL1=0x%02x\n", val);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -417,8 +416,8 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
|
||||
|
||||
val = inb(ACBCTL1);
|
||||
if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
|
||||
pr_debug(NAME ": enabled, but NMINTE won't be set, "
|
||||
"ACBCTL1=0x%02x\n", val);
|
||||
pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n",
|
||||
val);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -433,7 +432,7 @@ static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text,
|
||||
|
||||
iface = kzalloc(sizeof(*iface), GFP_KERNEL);
|
||||
if (!iface) {
|
||||
printk(KERN_ERR NAME ": can't allocate memory\n");
|
||||
pr_err("can't allocate memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -459,14 +458,14 @@ static int __devinit scx200_acb_create(struct scx200_acb_iface *iface)
|
||||
|
||||
rc = scx200_acb_probe(iface);
|
||||
if (rc) {
|
||||
printk(KERN_WARNING NAME ": probe failed\n");
|
||||
pr_warn("probe failed\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
scx200_acb_reset(iface);
|
||||
|
||||
if (i2c_add_adapter(adapter) < 0) {
|
||||
printk(KERN_ERR NAME ": failed to register\n");
|
||||
pr_err("failed to register\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -493,8 +492,7 @@ static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text,
|
||||
return NULL;
|
||||
|
||||
if (!request_region(base, 8, iface->adapter.name)) {
|
||||
printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
|
||||
base, base + 8 - 1);
|
||||
pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1);
|
||||
goto errout_free;
|
||||
}
|
||||
|
||||
@ -583,7 +581,7 @@ static __init void scx200_scan_isa(void)
|
||||
|
||||
static int __init scx200_acb_init(void)
|
||||
{
|
||||
pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
|
||||
pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
|
||||
|
||||
/* First scan for ISA-based devices */
|
||||
scx200_scan_isa(); /* XXX: should we care about errors? */
|
||||
|
@ -21,6 +21,8 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -31,8 +33,6 @@
|
||||
|
||||
#include <linux/scx200_gpio.h>
|
||||
|
||||
#define NAME "scx200_i2c"
|
||||
|
||||
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
|
||||
MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -88,17 +88,17 @@ static struct i2c_adapter scx200_i2c_ops = {
|
||||
|
||||
static int scx200_i2c_init(void)
|
||||
{
|
||||
pr_debug(NAME ": NatSemi SCx200 I2C Driver\n");
|
||||
pr_debug("NatSemi SCx200 I2C Driver\n");
|
||||
|
||||
if (!scx200_gpio_present()) {
|
||||
printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
|
||||
pr_err("no SCx200 gpio pins available\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pr_debug(NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
|
||||
pr_debug("SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
|
||||
|
||||
if (scl == -1 || sda == -1 || scl == sda) {
|
||||
printk(KERN_ERR NAME ": scl and sda must be specified\n");
|
||||
pr_err("scl and sda must be specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -107,8 +107,7 @@ static int scx200_i2c_init(void)
|
||||
scx200_gpio_configure(sda, ~2, 5);
|
||||
|
||||
if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
|
||||
printk(KERN_ERR NAME ": adapter %s registration failed\n",
|
||||
scx200_i2c_ops.name);
|
||||
pr_err("adapter %s registration failed\n", scx200_i2c_ops.name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1989,12 +1989,22 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
|
||||
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
|
||||
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
|
||||
int num = read_write == I2C_SMBUS_READ ? 2 : 1;
|
||||
struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
|
||||
{ addr, flags | I2C_M_RD, 0, msgbuf1 }
|
||||
};
|
||||
int i;
|
||||
u8 partial_pec = 0;
|
||||
int status;
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = addr,
|
||||
.flags = flags,
|
||||
.len = 1,
|
||||
.buf = msgbuf0,
|
||||
}, {
|
||||
.addr = addr,
|
||||
.flags = flags | I2C_M_RD,
|
||||
.len = 0,
|
||||
.buf = msgbuf1,
|
||||
},
|
||||
};
|
||||
|
||||
msgbuf0[0] = command;
|
||||
switch (size) {
|
||||
|
@ -88,9 +88,23 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)
|
||||
return parent->algo->functionality(parent);
|
||||
}
|
||||
|
||||
/* Return all parent classes, merged */
|
||||
static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
|
||||
{
|
||||
unsigned int class = 0;
|
||||
|
||||
do {
|
||||
class |= parent->class;
|
||||
parent = i2c_parent_is_i2c_adapter(parent);
|
||||
} while (parent);
|
||||
|
||||
return class;
|
||||
}
|
||||
|
||||
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
|
||||
struct device *mux_dev,
|
||||
void *mux_priv, u32 force_nr, u32 chan_id,
|
||||
unsigned int class,
|
||||
int (*select) (struct i2c_adapter *,
|
||||
void *, u32),
|
||||
int (*deselect) (struct i2c_adapter *,
|
||||
@ -127,6 +141,14 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
|
||||
priv->adap.algo_data = priv;
|
||||
priv->adap.dev.parent = &parent->dev;
|
||||
|
||||
/* Sanity check on class */
|
||||
if (i2c_mux_parent_classes(parent) & class)
|
||||
dev_err(&parent->dev,
|
||||
"Segment %d behind mux can't share classes with ancestors\n",
|
||||
chan_id);
|
||||
else
|
||||
priv->adap.class = class;
|
||||
|
||||
/*
|
||||
* Try to populate the mux adapter's of_node, expands to
|
||||
* nothing if !CONFIG_OF.
|
||||
|
@ -142,7 +142,8 @@ static int smbalert_probe(struct i2c_client *ara,
|
||||
struct i2c_adapter *adapter = ara->adapter;
|
||||
int res;
|
||||
|
||||
alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL);
|
||||
alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
|
||||
GFP_KERNEL);
|
||||
if (!alert)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -154,10 +155,8 @@ static int smbalert_probe(struct i2c_client *ara,
|
||||
if (setup->irq > 0) {
|
||||
res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
|
||||
0, "smbus_alert", alert);
|
||||
if (res) {
|
||||
kfree(alert);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_set_clientdata(ara, alert);
|
||||
@ -167,14 +166,12 @@ static int smbalert_probe(struct i2c_client *ara,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IRQ resource is managed so it is freed automatically */
|
||||
/* IRQ and memory resources are managed so they are freed automatically */
|
||||
static int smbalert_remove(struct i2c_client *ara)
|
||||
{
|
||||
struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
|
||||
|
||||
cancel_work_sync(&alert->alert);
|
||||
|
||||
kfree(alert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ struct gpiomux {
|
||||
struct i2c_adapter *parent;
|
||||
struct i2c_adapter **adap; /* child busses */
|
||||
struct i2c_mux_gpio_platform_data data;
|
||||
unsigned gpio_base;
|
||||
};
|
||||
|
||||
static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
|
||||
@ -28,7 +29,8 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mux->data.n_gpios; i++)
|
||||
gpio_set_value(mux->data.gpios[i], val & (1 << i));
|
||||
gpio_set_value(mux->gpio_base + mux->data.gpios[i],
|
||||
val & (1 << i));
|
||||
}
|
||||
|
||||
static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
|
||||
@ -49,13 +51,19 @@ static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
|
||||
void *data)
|
||||
{
|
||||
return !strcmp(chip->label, data);
|
||||
}
|
||||
|
||||
static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpiomux *mux;
|
||||
struct i2c_mux_gpio_platform_data *pdata;
|
||||
struct i2c_adapter *parent;
|
||||
int (*deselect) (struct i2c_adapter *, void *, u32);
|
||||
unsigned initial_state;
|
||||
unsigned initial_state, gpio_base;
|
||||
int i, ret;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
@ -64,6 +72,23 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a GPIO chip name is provided, the GPIO pin numbers provided are
|
||||
* relative to its base GPIO number. Otherwise they are absolute.
|
||||
*/
|
||||
if (pdata->gpio_chip) {
|
||||
struct gpio_chip *gpio;
|
||||
|
||||
gpio = gpiochip_find(pdata->gpio_chip,
|
||||
match_gpio_chip_by_label);
|
||||
if (!gpio)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
gpio_base = gpio->base;
|
||||
} else {
|
||||
gpio_base = 0;
|
||||
}
|
||||
|
||||
parent = i2c_get_adapter(pdata->parent);
|
||||
if (!parent) {
|
||||
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
|
||||
@ -71,7 +96,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_failed;
|
||||
@ -79,11 +104,13 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
mux->parent = parent;
|
||||
mux->data = *pdata;
|
||||
mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
|
||||
GFP_KERNEL);
|
||||
mux->gpio_base = gpio_base;
|
||||
mux->adap = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*mux->adap) * pdata->n_values,
|
||||
GFP_KERNEL);
|
||||
if (!mux->adap) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_failed2;
|
||||
goto alloc_failed;
|
||||
}
|
||||
|
||||
if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) {
|
||||
@ -95,17 +122,19 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->n_gpios; i++) {
|
||||
ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio");
|
||||
ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
|
||||
if (ret)
|
||||
goto err_request_gpio;
|
||||
gpio_direction_output(pdata->gpios[i],
|
||||
gpio_direction_output(gpio_base + pdata->gpios[i],
|
||||
initial_state & (1 << i));
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->n_values; i++) {
|
||||
u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
|
||||
unsigned int class = pdata->classes ? pdata->classes[i] : 0;
|
||||
|
||||
mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, i,
|
||||
mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
|
||||
i, class,
|
||||
i2c_mux_gpio_select, deselect);
|
||||
if (!mux->adap[i]) {
|
||||
ret = -ENODEV;
|
||||
@ -127,10 +156,7 @@ add_adapter_failed:
|
||||
i = pdata->n_gpios;
|
||||
err_request_gpio:
|
||||
for (; i > 0; i--)
|
||||
gpio_free(pdata->gpios[i - 1]);
|
||||
kfree(mux->adap);
|
||||
alloc_failed2:
|
||||
kfree(mux);
|
||||
gpio_free(gpio_base + pdata->gpios[i - 1]);
|
||||
alloc_failed:
|
||||
i2c_put_adapter(parent);
|
||||
|
||||
@ -146,12 +172,10 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
|
||||
i2c_del_mux_adapter(mux->adap[i]);
|
||||
|
||||
for (i = 0; i < mux->data.n_gpios; i++)
|
||||
gpio_free(mux->data.gpios[i]);
|
||||
gpio_free(mux->gpio_base + mux->data.gpios[i]);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
i2c_put_adapter(mux->parent);
|
||||
kfree(mux->adap);
|
||||
kfree(mux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ static int pca9541_probe(struct i2c_client *client,
|
||||
if (pdata)
|
||||
force = pdata->modes[0].adap_id;
|
||||
data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
|
||||
force, 0,
|
||||
force, 0, 0,
|
||||
pca9541_select_chan,
|
||||
pca9541_release_chan);
|
||||
|
||||
|
@ -186,7 +186,7 @@ static int pca954x_probe(struct i2c_client *client,
|
||||
{
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
struct pca954x_platform_data *pdata = client->dev.platform_data;
|
||||
int num, force;
|
||||
int num, force, class;
|
||||
struct pca954x *data;
|
||||
int ret = -ENODEV;
|
||||
|
||||
@ -216,18 +216,20 @@ static int pca954x_probe(struct i2c_client *client,
|
||||
/* Now create an adapter for each channel */
|
||||
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||
force = 0; /* dynamic adap number */
|
||||
class = 0; /* no class by default */
|
||||
if (pdata) {
|
||||
if (num < pdata->num_modes)
|
||||
if (num < pdata->num_modes) {
|
||||
/* force static number */
|
||||
force = pdata->modes[num].adap_id;
|
||||
else
|
||||
class = pdata->modes[num].class;
|
||||
} else
|
||||
/* discard unconfigured channels */
|
||||
break;
|
||||
}
|
||||
|
||||
data->virt_adaps[num] =
|
||||
i2c_add_mux_adapter(adap, &client->dev, client,
|
||||
force, num, pca954x_select_chan,
|
||||
force, num, class, pca954x_select_chan,
|
||||
(pdata && pdata->modes[num].deselect_on_exit)
|
||||
? pca954x_deselect_mux : NULL);
|
||||
|
||||
|
@ -221,7 +221,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
|
||||
(mux->pdata->base_bus_num + i) : 0;
|
||||
|
||||
mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev,
|
||||
mux, bus, i,
|
||||
mux, bus, i, 0,
|
||||
i2c_mux_pinctrl_select,
|
||||
deselect);
|
||||
if (!mux->busses[i]) {
|
||||
|
@ -21,6 +21,9 @@
|
||||
* @values: Array of bitmasks of GPIO settings (low/high) for each
|
||||
* position
|
||||
* @n_values: Number of multiplexer positions (busses to instantiate)
|
||||
* @classes: Optional I2C auto-detection classes
|
||||
* @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given
|
||||
* relative to the base GPIO number of that chip
|
||||
* @gpios: Array of GPIO numbers used to control MUX
|
||||
* @n_gpios: Number of GPIOs used to control MUX
|
||||
* @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
|
||||
@ -30,6 +33,8 @@ struct i2c_mux_gpio_platform_data {
|
||||
int base_nr;
|
||||
const unsigned *values;
|
||||
int n_values;
|
||||
const unsigned *classes;
|
||||
char *gpio_chip;
|
||||
const unsigned *gpios;
|
||||
int n_gpios;
|
||||
unsigned idle;
|
||||
|
@ -36,6 +36,7 @@
|
||||
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
|
||||
struct device *mux_dev,
|
||||
void *mux_priv, u32 force_nr, u32 chan_id,
|
||||
unsigned int class,
|
||||
int (*select) (struct i2c_adapter *,
|
||||
void *mux_dev, u32 chan_id),
|
||||
int (*deselect) (struct i2c_adapter *,
|
||||
|
@ -144,7 +144,7 @@ extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
|
||||
* The driver.owner field should be set to the module owner of this driver.
|
||||
* The driver.name field should be set to the name of this driver.
|
||||
*
|
||||
* For automatic device detection, both @detect and @address_data must
|
||||
* For automatic device detection, both @detect and @address_list must
|
||||
* be defined. @class should also be set, otherwise only devices forced
|
||||
* with module parameters will be created. The detect function must
|
||||
* fill at least the name field of the i2c_board_info structure it is
|
||||
|
@ -36,6 +36,7 @@
|
||||
struct pca954x_platform_mode {
|
||||
int adap_id;
|
||||
unsigned int deselect_on_exit:1;
|
||||
unsigned int class;
|
||||
};
|
||||
|
||||
/* Per mux/switch data, used with i2c_register_board_info */
|
||||
|
@ -1427,6 +1427,7 @@
|
||||
#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
|
||||
#define PCI_DEVICE_ID_VIA_VX800 0x8353
|
||||
#define PCI_DEVICE_ID_VIA_VX855 0x8409
|
||||
#define PCI_DEVICE_ID_VIA_VX900 0x8410
|
||||
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
|
||||
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
|
||||
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
|
||||
|
Loading…
Reference in New Issue
Block a user