Commit 278429cf authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  i2c-viapro: Add support for SMBus Process Call transactions
  i2c: Restore i2c_smbus_process_call function
  i2c: Do earlier driver model init
  i2c: Only build Tyan SMBus mux drivers on x86
  i2c: Guard against oopses from bad init sequences
  i2c: Document the implementation details of the /dev interface
  i2c: Improve dev-interface documentation
  i2c-parport-light: Don't register a platform device resource
  hwmon: (dme1737) Convert to a new-style i2c driver
  hwmon: (dme1737) Be less i2c-centric
  i2c/tps65010: Vibrator hookup to gpiolib
  i2c-viapro: Add VX800/VX820 support
  i2c: Renesas Highlander FPGA SMBus support
  i2c-pca-isa: Don't grab arbitrary resources
  i2c/isp1301_omap: Convert to a new-style i2c driver, part 2
  i2c/isp1301_omap: Convert to a new-style i2c driver, part 1
parents e413b210 a05f2c5a
...@@ -16,6 +16,9 @@ Supported adapters: ...@@ -16,6 +16,9 @@ Supported adapters:
* VIA Technologies, Inc. CX700 * VIA Technologies, Inc. CX700
Datasheet: available on request and under NDA from VIA Datasheet: available on request and under NDA from VIA
* VIA Technologies, Inc. VX800/VX820
Datasheet: available on http://linux.via.com.tw
Authors: Authors:
Kyösti Mälkki <kmalkki@cc.hut.fi>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark D. Studebaker <mdsxyz123@yahoo.com>, Mark D. Studebaker <mdsxyz123@yahoo.com>,
...@@ -49,6 +52,7 @@ Your lspci -n listing must show one of these : ...@@ -49,6 +52,7 @@ Your lspci -n listing must show one of these :
device 1106:3372 (VT8237S) device 1106:3372 (VT8237S)
device 1106:3287 (VT8251) device 1106:3287 (VT8251)
device 1106:8324 (CX700) device 1106:8324 (CX700)
device 1106:8353 (VX800/VX820)
If none of these show up, you should look in the BIOS for settings like If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB. enable ACPI / SMBus or even USB.
...@@ -57,5 +61,5 @@ Except for the oldest chips (VT82C596A/B, VT82C686A and most probably ...@@ -57,5 +61,5 @@ Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
VT8231), this driver supports I2C block transactions. Such transactions VT8231), this driver supports I2C block transactions. Such transactions
are mainly useful to read from and write to EEPROMs. are mainly useful to read from and write to EEPROMs.
The CX700 additionally appears to support SMBus PEC, although this driver The CX700/VX800/VX820 additionally appears to support SMBus PEC, although
doesn't implement it yet. this driver doesn't implement it yet.
...@@ -4,6 +4,10 @@ the /dev interface. You need to load module i2c-dev for this. ...@@ -4,6 +4,10 @@ the /dev interface. You need to load module i2c-dev for this.
Each registered i2c adapter gets a number, counting from 0. You can Each registered i2c adapter gets a number, counting from 0. You can
examine /sys/class/i2c-dev/ to see what number corresponds to which adapter. examine /sys/class/i2c-dev/ to see what number corresponds to which adapter.
Alternatively, you can run "i2cdetect -l" to obtain a formated list of all
i2c adapters present on your system at a given time. i2cdetect is part of
the i2c-tools package.
I2C device files are character device files with major device number 89 I2C device files are character device files with major device number 89
and a minor device number corresponding to the number assigned as and a minor device number corresponding to the number assigned as
explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
...@@ -17,30 +21,34 @@ So let's say you want to access an i2c adapter from a C program. The ...@@ -17,30 +21,34 @@ So let's say you want to access an i2c adapter from a C program. The
first thing to do is "#include <linux/i2c-dev.h>". Please note that first thing to do is "#include <linux/i2c-dev.h>". Please note that
there are two files named "i2c-dev.h" out there, one is distributed there are two files named "i2c-dev.h" out there, one is distributed
with the Linux kernel and is meant to be included from kernel with the Linux kernel and is meant to be included from kernel
driver code, the other one is distributed with lm_sensors and is driver code, the other one is distributed with i2c-tools and is
meant to be included from user-space programs. You obviously want meant to be included from user-space programs. You obviously want
the second one here. the second one here.
Now, you have to decide which adapter you want to access. You should Now, you have to decide which adapter you want to access. You should
inspect /sys/class/i2c-dev/ to decide this. Adapter numbers are assigned inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
somewhat dynamically, so you can not even assume /dev/i2c-0 is the Adapter numbers are assigned somewhat dynamically, so you can not
first adapter. assume much about them. They can even change from one boot to the next.
Next thing, open the device file, as follows: Next thing, open the device file, as follows:
int file; int file;
int adapter_nr = 2; /* probably dynamically determined */ int adapter_nr = 2; /* probably dynamically determined */
char filename[20]; char filename[20];
sprintf(filename,"/dev/i2c-%d",adapter_nr); snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
if ((file = open(filename,O_RDWR)) < 0) { file = open(filename, O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */ /* ERROR HANDLING; you can check errno to see what went wrong */
exit(1); exit(1);
} }
When you have opened the device, you must specify with what device When you have opened the device, you must specify with what device
address you want to communicate: address you want to communicate:
int addr = 0x40; /* The I2C address */ int addr = 0x40; /* The I2C address */
if (ioctl(file,I2C_SLAVE,addr) < 0) {
if (ioctl(file, I2C_SLAVE, addr) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */ /* ERROR HANDLING; you can check errno to see what went wrong */
exit(1); exit(1);
} }
...@@ -48,31 +56,41 @@ address you want to communicate: ...@@ -48,31 +56,41 @@ address you want to communicate:
Well, you are all set up now. You can now use SMBus commands or plain Well, you are all set up now. You can now use SMBus commands or plain
I2C to communicate with your device. SMBus commands are preferred if I2C to communicate with your device. SMBus commands are preferred if
the device supports them. Both are illustrated below. the device supports them. Both are illustrated below.
__u8 register = 0x10; /* Device register to access */ __u8 register = 0x10; /* Device register to access */
__s32 res; __s32 res;
char buf[10]; char buf[10];
/* Using SMBus commands */ /* Using SMBus commands */
res = i2c_smbus_read_word_data(file,register); res = i2c_smbus_read_word_data(file, register);
if (res < 0) { if (res < 0) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} else { } else {
/* res contains the read word */ /* res contains the read word */
} }
/* Using I2C Write, equivalent of /* Using I2C Write, equivalent of
i2c_smbus_write_word_data(file,register,0x6543) */ i2c_smbus_write_word_data(file, register, 0x6543) */
buf[0] = register; buf[0] = register;
buf[1] = 0x43; buf[1] = 0x43;
buf[2] = 0x65; buf[2] = 0x65;
if ( write(file,buf,3) != 3) { if (write(file, buf, 3) ! =3) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} }
/* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */ /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */
if (read(file,buf,1) != 1) { if (read(file, buf, 1) != 1) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
} else { } else {
/* buf[0] contains the read byte */ /* buf[0] contains the read byte */
} }
Note that only a subset of the I2C and SMBus protocols can be achieved by
the means of read() and write() calls. In particular, so-called combined
transactions (mixing read and write messages in the same transaction)
aren't supported. For this reason, this interface is almost never used by
user-space programs.
IMPORTANT: because of the use of inline functions, you *have* to use IMPORTANT: because of the use of inline functions, you *have* to use
'-O' or some variation when you compile your program! '-O' or some variation when you compile your program!
...@@ -80,31 +98,29 @@ IMPORTANT: because of the use of inline functions, you *have* to use ...@@ -80,31 +98,29 @@ IMPORTANT: because of the use of inline functions, you *have* to use
Full interface description Full interface description
========================== ==========================
The following IOCTLs are defined and fully supported The following IOCTLs are defined:
(see also i2c-dev.h):
ioctl(file,I2C_SLAVE,long addr) ioctl(file, I2C_SLAVE, long addr)
Change slave address. The address is passed in the 7 lower bits of the Change slave address. The address is passed in the 7 lower bits of the
argument (except for 10 bit addresses, passed in the 10 lower bits in this argument (except for 10 bit addresses, passed in the 10 lower bits in this
case). case).
ioctl(file,I2C_TENBIT,long select) ioctl(file, I2C_TENBIT, long select)
Selects ten bit addresses if select not equals 0, selects normal 7 bit Selects ten bit addresses if select not equals 0, selects normal 7 bit
addresses if select equals 0. Default 0. This request is only valid addresses if select equals 0. Default 0. This request is only valid
if the adapter has I2C_FUNC_10BIT_ADDR. if the adapter has I2C_FUNC_10BIT_ADDR.
ioctl(file,I2C_PEC,long select) ioctl(file, I2C_PEC, long select)
Selects SMBus PEC (packet error checking) generation and verification Selects SMBus PEC (packet error checking) generation and verification
if select not equals 0, disables if select equals 0. Default 0. if select not equals 0, disables if select equals 0. Default 0.
Used only for SMBus transactions. This request only has an effect if the Used only for SMBus transactions. This request only has an effect if the
the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just
doesn't have any effect. doesn't have any effect.
ioctl(file,I2C_FUNCS,unsigned long *funcs) ioctl(file, I2C_FUNCS, unsigned long *funcs)
Gets the adapter functionality and puts it in *funcs. Gets the adapter functionality and puts it in *funcs.
ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset) ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
Do combined read/write transaction without stop in between. Do combined read/write transaction without stop in between.
Only valid if the adapter has I2C_FUNC_I2C. The argument is Only valid if the adapter has I2C_FUNC_I2C. The argument is
a pointer to a a pointer to a
...@@ -120,10 +136,9 @@ ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset) ...@@ -120,10 +136,9 @@ ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset)
The slave address and whether to use ten bit address mode has to be The slave address and whether to use ten bit address mode has to be
set in each message, overriding the values set with the above ioctl's. set in each message, overriding the values set with the above ioctl's.
ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
Other values are NOT supported at this moment, except for I2C_SMBUS, Not meant to be called directly; instead, use the access functions
which you should never directly call; instead, use the access functions below.
below.
You can do plain i2c transactions by using read(2) and write(2) calls. You can do plain i2c transactions by using read(2) and write(2) calls.
You do not need to pass the address byte; instead, set it through You do not need to pass the address byte; instead, set it through
...@@ -148,7 +163,52 @@ what happened. The 'write' transactions return 0 on success; the ...@@ -148,7 +163,52 @@ what happened. The 'write' transactions return 0 on success; the
returns the number of values read. The block buffers need not be longer returns the number of values read. The block buffers need not be longer
than 32 bytes. than 32 bytes.
The above functions are all macros, that resolve to calls to the The above functions are all inline functions, that resolve to calls to
i2c_smbus_access function, that on its turn calls a specific ioctl the i2c_smbus_access function, that on its turn calls a specific ioctl
with the data in a specific format. Read the source code if you with the data in a specific format. Read the source code if you
want to know what happens behind the screens. want to know what happens behind the screens.
Implementation details
======================
For the interested, here's the code flow which happens inside the kernel
when you use the /dev interface to I2C:
1* Your program opens /dev/i2c-N and calls ioctl() on it, as described in
section "C example" above.
2* These open() and ioctl() calls are handled by the i2c-dev kernel
driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(),
respectively. You can think of i2c-dev as a generic I2C chip driver
that can be programmed from user-space.
3* Some ioctl() calls are for administrative tasks and are handled by
i2c-dev directly. Examples include I2C_SLAVE (set the address of the
device you want to access) and I2C_PEC (enable or disable SMBus error
checking on future transactions.)
4* Other ioctl() calls are converted to in-kernel function calls by
i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter
functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which
performs an SMBus transaction using i2c-core.c:i2c_smbus_xfer().
The i2c-dev driver is responsible for checking all the parameters that
come from user-space for validity. After this point, there is no
difference between these calls that came from user-space through i2c-dev
and calls that would have been performed by kernel I2C chip drivers
directly. This means that I2C bus drivers don't need to implement
anything special to support access from user-space.
5* These i2c-core.c/i2c.h functions are wrappers to the actual
implementation of your I2C bus driver. Each adapter must declare
callback functions implementing these standard calls.
i2c.h:i2c_get_functionality() calls i2c_adapter.algo->functionality(),
while i2c-core.c:i2c_smbus_xfer() calls either
adapter.algo->smbus_xfer() if it is implemented, or if not,
i2c-core.c:i2c_smbus_xfer_emulated() which in turn calls
i2c_adapter.algo->master_xfer().
After your I2C bus driver has processed these requests, execution runs
up the call chain, with almost no processing done, except by i2c-dev to
package the returned data, if any, in suitable format for the ioctl.
...@@ -109,8 +109,8 @@ specified through the Comm byte. ...@@ -109,8 +109,8 @@ specified through the Comm byte.
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
SMBus Process Call SMBus Process Call: i2c_smbus_process_call()
================== =============================================
This command selects a device register (through the Comm byte), sends This command selects a device register (through the Comm byte), sends
16 bits of data to it, and reads 16 bits of data in return. 16 bits of data to it, and reads 16 bits of data in return.
......
...@@ -606,6 +606,8 @@ SMBus communication ...@@ -606,6 +606,8 @@ SMBus communication
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client, extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value); u8 command, u16 value);
extern s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
extern s32 i2c_smbus_read_block_data(struct i2c_client * client, extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
u8 command, u8 *values); u8 command, u8 *values);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client, extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
...@@ -621,8 +623,6 @@ These ones were removed from i2c-core because they had no users, but could ...@@ -621,8 +623,6 @@ These ones were removed from i2c-core because they had no users, but could
be added back later if needed: be added back later if needed:
extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
extern s32 i2c_smbus_process_call(struct i2c_client * client,
u8 command, u16 value);
extern s32 i2c_smbus_block_process_call(struct i2c_client *client, extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
u8 command, u8 length, u8 command, u8 length,
u8 *values) u8 *values)
......
...@@ -476,6 +476,10 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { ...@@ -476,6 +476,10 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = {
I2C_BOARD_INFO("tps65013", 0x48), I2C_BOARD_INFO("tps65013", 0x48),
/* .irq = OMAP_GPIO_IRQ(??), */ /* .irq = OMAP_GPIO_IRQ(??), */
}, },
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(14),
},
}; };
static struct omap_gpio_switch h3_gpio_switches[] __initdata = { static struct omap_gpio_switch h3_gpio_switches[] __initdata = {
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -391,6 +392,13 @@ static struct omap_board_config_kernel h4_config[] = { ...@@ -391,6 +392,13 @@ static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_LCD, &h4_lcd_config }, { OMAP_TAG_LCD, &h4_lcd_config },
}; };
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
};
static void __init omap_h4_init(void) static void __init omap_h4_init(void)
{ {
/* /*
...@@ -411,6 +419,9 @@ static void __init omap_h4_init(void) ...@@ -411,6 +419,9 @@ static void __init omap_h4_init(void)
} }
#endif #endif
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
omap_board_config = h4_config; omap_board_config = h4_config;
omap_board_config_size = ARRAY_SIZE(h4_config); omap_board_config_size = ARRAY_SIZE(h4_config);
......
This diff is collapsed.
...@@ -55,7 +55,7 @@ config I2C_AMD756 ...@@ -55,7 +55,7 @@ config I2C_AMD756
config I2C_AMD756_S4882 config I2C_AMD756_S4882
tristate "SMBus multiplexing on the Tyan S4882" tristate "SMBus multiplexing on the Tyan S4882"
depends on I2C_AMD756 && EXPERIMENTAL depends on I2C_AMD756 && X86 && EXPERIMENTAL
help help
Enabling this option will add specific SMBus support for the Tyan Enabling this option will add specific SMBus support for the Tyan
S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed
...@@ -148,7 +148,7 @@ config I2C_NFORCE2 ...@@ -148,7 +148,7 @@ config I2C_NFORCE2
config I2C_NFORCE2_S4985 config I2C_NFORCE2_S4985
tristate "SMBus multiplexing on the Tyan S4985" tristate "SMBus multiplexing on the Tyan S4985"
depends on I2C_NFORCE2 && EXPERIMENTAL depends on I2C_NFORCE2 && X86 && EXPERIMENTAL
help help
Enabling this option will add specific SMBus support for the Tyan Enabling this option will add specific SMBus support for the Tyan
S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed
...@@ -209,7 +209,7 @@ config I2C_VIA ...@@ -209,7 +209,7 @@ config I2C_VIA
will be called i2c-via. will be called i2c-via.
config I2C_VIAPRO config I2C_VIAPRO
tristate "VIA VT82C596/82C686/82xx and CX700" tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820"
depends on PCI depends on PCI
help help
If you say yes to this option, support will be included for the VIA If you say yes to this option, support will be included for the VIA
...@@ -223,6 +223,8 @@ config I2C_VIAPRO ...@@ -223,6 +223,8 @@ config I2C_VIAPRO
VT8237R/A/S VT8237R/A/S
VT8251 VT8251
CX700 CX700
VX800
VX820
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-viapro. will be called i2c-viapro.
...@@ -330,6 +332,18 @@ config I2C_GPIO ...@@ -330,6 +332,18 @@ config I2C_GPIO
This is a very simple bitbanging I2C driver utilizing the This is a very simple bitbanging I2C driver utilizing the
arch-neutral GPIO API to control the SCL and SDA lines. arch-neutral GPIO API to control the SCL and SDA lines.
config I2C_HIGHLANDER
tristate "Highlander FPGA SMBus interface"
depends on SH_HIGHLANDER
help
If you say yes to this option, support will be included for
the SMBus interface located in the FPGA on various Highlander
boards, particularly the R0P7780LC0011RL and R0P7785LC0011RL
FPGAs. This is wholly unrelated to the SoC I2C.
This driver can also be built as a module. If so, the module
will be called i2c-highlander.
config I2C_IBM_IIC config I2C_IBM_IIC
tristate "IBM PPC 4xx on-chip I2C interface" tristate "IBM PPC 4xx on-chip I2C interface"
depends on 4xx depends on 4xx
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
......
This diff is collapsed.
...@@ -123,11 +123,6 @@ static struct i2c_adapter parport_adapter = { ...@@ -123,11 +123,6 @@ static struct i2c_adapter parport_adapter = {
static int __devinit i2c_parport_probe(struct platform_device *pdev) static int __devinit i2c_parport_probe(struct platform_device *pdev)
{ {
int err; int err;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, res->end - res->start + 1, DRVNAME))
return -EBUSY;
/* Reset hardware to a sane state (SCL and SDA high) */ /* Reset hardware to a sane state (SCL and SDA high) */
parport_setsda(NULL, 1); parport_setsda(NULL, 1);
...@@ -138,29 +133,19 @@ static int __devinit i2c_parport_probe(struct platform_device *pdev) ...@@ -138,29 +133,19 @@ static int __devinit i2c_parport_probe(struct platform_device *pdev)
parport_adapter.dev.parent = &pdev->dev; parport_adapter.dev.parent = &pdev->dev;
err = i2c_bit_add_bus(&parport_adapter); err = i2c_bit_add_bus(&parport_adapter);
if (err) { if (err)
dev_err(&pdev->dev, "Unable to register with I2C\n"); dev_err(&pdev->dev, "Unable to register with I2C\n");
goto exit_region;
}
return 0;
exit_region:
release_region(res->start, res->end - res->start + 1);
return err; return err;
} }
static int __devexit i2c_parport_remove(struct platform_device *pdev) static int __devexit i2c_parport_remove(struct platform_device *pdev)
{ {
struct resource *res;
i2c_del_adapter(&parport_adapter); i2c_del_adapter(&parport_adapter);
/* Un-init if needed (power off...) */ /* Un-init if needed (power off...) */
if (adapter_parm[type].init.val) if (adapter_parm[type].init.val)
line_set(0, &adapter_parm[type].init); line_set(0, &adapter_parm[type].init);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, res->end - res->start + 1);
return 0; return 0;
} }
...@@ -175,12 +160,6 @@ static struct platform_driver i2c_parport_driver = { ...@@ -175,12 +160,6 @@ static struct platform_driver i2c_parport_driver = {
static int __init i2c_parport_device_add(u16 address) static int __init i2c_parport_device_add(u16 address)
{ {
struct resource res = {
.start = address,
.end = address + 2,
.name = DRVNAME,
.flags = IORESOURCE_IO,
};
int err; int err;
pdev = platform_device_alloc(DRVNAME, -1); pdev = platform_device_alloc(DRVNAME, -1);
...@@ -190,13 +169,6 @@ static int __init i2c_parport_device_add(u16 address) ...@@ -190,13 +169,6 @@ static int __init i2c_parport_device_add(u16 address)
goto exit; goto exit;
} }
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
"(%d)\n", err);
goto exit_device_put;
}
err = platform_device_add(pdev); err = platform_device_add(pdev);
if (err) { if (err) {
printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
...@@ -231,13 +203,16 @@ static int __init i2c_parport_init(void) ...@@ -231,13 +203,16 @@ static int __init i2c_parport_init(void)
base = DEFAULT_BASE; base = DEFAULT_BASE;
} }
if (!request_region(base, 3, DRVNAME))
return -EBUSY;
if (!adapter_parm[type].getscl.val) if (!adapter_parm[type].getscl.val)
parport_algo_data.getscl = NULL; parport_algo_data.getscl = NULL;
/* Sets global pdev as a side effect */ /* Sets global pdev as a side effect */
err = i2c_parport_device_add(base); err = i2c_parport_device_add(base);
if (err) if (err)
goto exit; goto exit_release;
err = platform_driver_register(&i2c_parport_driver); err = platform_driver_register(&i2c_parport_driver);
if (err) if (err)
...@@ -247,7 +222,8 @@ static int __init i2c_parport_init(void) ...@@ -247,7 +222,8 @@ static int __init i2c_parport_init(void)
exit_device: exit_device:
platform_device_unregister(pdev); platform_device_unregister(pdev);
exit: exit_release:
release_region(base, 3);
return err; return err;
} }
...@@ -255,6 +231,7 @@ static void __exit i2c_parport_exit(void) ...@@ -255,6 +231,7 @@ static void __exit i2c_parport_exit(void)
{ {
platform_driver_unregister(&i2c_parport_driver); platform_driver_unregister(&i2c_parport_driver);
platform_device_unregister(pdev); platform_device_unregister(pdev);
release_region(base, 3);
} }
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
......
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
#define DRIVER "i2c-pca-isa" #define DRIVER "i2c-pca-isa"
#define IO_SIZE 4 #define IO_SIZE 4
static unsigned long base = 0x330; static unsigned long base;
static int irq = 10; static int irq = -1;
/* Data sheet recommends 59kHz for 100kHz operation due to variation /* Data sheet recommends 59kHz for 100kHz operation due to variation
* in the actual clock rate */ * in the actual clock rate */
...@@ -107,6 +107,19 @@ static struct i2c_adapter pca_isa_ops = { ...@@ -107,6 +107,19 @@ static struct i2c_adapter pca_isa_ops = {
.timeout = 100, .timeout = 100,
}; };
static int __devinit pca_isa_match(struct device *dev, unsigned int id)
{
int match = base != 0;
if (match) {
if (irq <= -1)
dev_warn(dev, "Using polling mode (specify irq)\n");
} else
dev_err(dev, "Please specify I/O base\n");
return match;
}
static int __devinit pca_isa_probe(struct device *dev, unsigned int id) static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
{ {
init_waitqueue_head(&pca_wait); init_waitqueue_head(&pca_wait);
...@@ -153,7 +166,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) ...@@ -153,7 +166,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
{ {
i2c_del_adapter(&pca_isa_ops); i2c_del_adapter(&pca_isa_ops);
if (irq > 0) { if (irq > -1) {
disable_irq(irq); disable_irq(irq);
free_irq(irq, &pca_isa_ops); free_irq(irq, &pca_isa_ops);
} }
...@@ -163,6 +176,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) ...@@ -163,6 +176,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
} }
static struct isa_driver pca_isa_driver = { static struct isa_driver pca_isa_driver = {
.match = pca_isa_match,
.probe = pca_isa_probe, .probe = pca_isa_probe,
.remove = __devexit_p(pca_isa_remove), .remove = __devexit_p(pca_isa_remove),
.driver = { .driver = {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
VT8237S 0x3372 yes VT8237S 0x3372 yes
VT8251 0x3287 yes VT8251 0x3287 yes
CX700 0x8324 yes CX700 0x8324 yes
VX800/VX820 0x8353 yes
Note: we assume there can only be one device, with one SMBus interface. Note: we assume there can only be one device, with one SMBus interface.
*/ */
...@@ -82,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2; ...@@ -82,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2;
#define VT596_BYTE 0x04 #define VT596_BYTE 0x04
#define VT596_BYTE_DATA 0x08 #define VT596_BYTE_DATA 0x08
#define VT596_WORD_DATA 0x0C #define VT596_WORD_DATA 0x0C
#define VT596_PROC_CALL 0x10
#define VT596_BLOCK_DATA 0x14 #define VT596_BLOCK_DATA 0x14
#define VT596_I2C_BLOCK_DATA 0x34 #define VT596_I2C_BLOCK_DATA 0x34
...@@ -232,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -232,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
} }
size = VT596_WORD_DATA; size = VT596_WORD_DATA;
break; break;
case I2C_SMBUS_PROC_CALL:
outb_p(command, SMBHSTCMD);
outb_p(data->word & 0xff, SMBHSTDAT0);
outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
size = VT596_PROC_CALL;
break;
case I2C_SMBUS_I2C_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA:
if (!(vt596_features & FEATURE_I2CBLOCK)) if (!(vt596_features & FEATURE_I2CBLOCK))
goto exit_unsupported; goto exit_unsupported;
...@@ -262,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -262,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
if (status) if (status)
return status; return status;
if (size == VT596_PROC_CALL)
read_write = I2C_SMBUS_READ;
if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
return 0; return 0;
...@@ -271,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ...@@ -271,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
data->byte = inb_p(SMBHSTDAT0); data->byte = inb_p(SMBHSTDAT0);
break; break;
case VT596_WORD_DATA: case VT596_WORD_DATA:
case VT596_PROC_CALL:
data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
break; break;
case VT596_I2C_BLOCK_DATA: case VT596_I2C_BLOCK_DATA:
...@@ -295,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter) ...@@ -295,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter)
{ {
u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA; I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA;
if (vt596_features & FEATURE_I2CBLOCK) if (vt596_features & FEATURE_I2CBLOCK)
func |= I2C_FUNC_SMBUS_I2C_BLOCK; func |= I2C_FUNC_SMBUS_I2C_BLOCK;
...@@ -396,6 +408,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, ...@@ -396,6 +408,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_VIA_CX700: case PCI_DEVICE_ID_VIA_CX700:
case PCI_DEVICE_ID_VIA_VX800:
case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8251:
case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237A: case PCI_DEVICE_ID_VIA_8237A:
...@@ -459,6 +472,8 @@ static struct pci_device_id vt596_ids[] = { ...@@ -459,6 +472,8 @@ static struct pci_device_id vt596_ids[] = {
.driver_data = SMBBA3 }, .driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700), { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700),
.driver_data = SMBBA3 }, .driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
.driver_data = SMBBA3 },
{ 0, } { 0, }
}; };
......
This diff is collapsed.
...@@ -456,14 +456,17 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) ...@@ -456,14 +456,17 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
/* offsets 0..3 == GPIO1..GPIO4 /* offsets 0..3 == GPIO1..GPIO4
* offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes) * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes)
* offset 6 == vibrator motor driver
*/ */
static void static void
tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value) tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{ {
if (offset < 4) if (offset < 4)
tps65010_set_gpio_out_value(offset + 1, value); tps65010_set_gpio_out_value(offset + 1, value);
else else if (offset < 6)
tps65010_set_led(offset - 3, value ? ON : OFF); tps65010_set_led(offset - 3, value ? ON : OFF);
else
tps65010_set_vib(value);
} }
static int static int
...@@ -477,8 +480,10 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value) ...@@ -477,8 +480,10 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value)
if (!(tps->outmask & (1 << offset))) if (!(tps->outmask & (1 << offset)))
return -EINVAL; return -EINVAL;
tps65010_set_gpio_out_value(offset + 1, value); tps65010_set_gpio_out_value(offset + 1, value);
} else } else if (offset < 6)
tps65010_set_led(offset - 3, value ? ON : OFF); tps65010_set_led(offset - 3, value ? ON : OFF);
else
tps65010_set_vib(value);
return 0; return 0;
} }
...@@ -646,7 +651,7 @@ static int tps65010_probe(struct i2c_client *client, ...@@ -646,7 +651,7 @@ static int tps65010_probe(struct i2c_client *client,
tps->chip.get = tps65010_gpio_get; tps->chip.get = tps65010_gpio_get;
tps->chip.base = board->base; tps->chip.base = board->base;
tps->chip.ngpio = 6; tps->chip.ngpio = 7;
tps->chip.can_sleep = 1; tps->chip.can_sleep = 1;
status = gpiochip_add(&tps->chip); status = gpiochip_add(&tps->chip);
...@@ -675,6 +680,7 @@ static const struct i2c_device_id tps65010_id[] = { ...@@ -675,6 +680,7 @@ static const struct i2c_device_id tps65010_id[] = {
{ "tps65011", TPS65011 }, { "tps65011", TPS65011 },
{ "tps65012", TPS65012 }, { "tps65012", TPS65012 },
{ "tps65013", TPS65013 }, { "tps65013", TPS65013 },
{ "tps65014", TPS65011 }, /* tps65011 charging at 6.5V max */
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, tps65010_id); MODULE_DEVICE_TABLE(i2c, tps65010_id);
......
...@@ -437,6 +437,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap) ...@@ -437,6 +437,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
{ {
int res = 0, dummy; int res = 0, dummy;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
mutex_init(&adap->bus_lock); mutex_init(&adap->bus_lock);
mutex_init(&adap->clist_lock); mutex_init(&adap->clist_lock);
INIT_LIST_HEAD(&adap->clients); INIT_LIST_HEAD(&adap->clients);
...@@ -696,6 +700,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) ...@@ -696,6 +700,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{ {
int res; int res;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
/* new style driver methods can't mix with legacy ones */ /* new style driver methods can't mix with legacy ones */
if (is_newstyle_driver(driver)) { if (is_newstyle_driver(driver)) {
if (driver->attach_adapter || driver->detach_adapter if (driver->attach_adapter || driver->detach_adapter
...@@ -978,7 +986,10 @@ static void __exit i2c_exit(void) ...@@ -978,7 +986,10 @@ static void __exit i2c_exit(void)
bus_unregister(&i2c_bus_type); bus_unregister(&i2c_bus_type);
} }
subsys_initcall(i2c_init); /* We must initialize early, because some subsystems register i2c drivers
* in subsys_initcall() code, but are linked (and initialized) before i2c.
*/
postcore_initcall(i2c_init);
module_exit(i2c_exit); module_exit(i2c_exit);
/* ---------------------------------------------------- /* ----------------------------------------------------
...@@ -1676,6 +1687,28 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) ...@@ -1676,6 +1687,28 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
} }
EXPORT_SYMBOL(i2c_smbus_write_word_data); EXPORT_SYMBOL(i2c_smbus_write_word_data);
/**
* i2c_smbus_process_call - SMBus "process call" protocol
* @client: Handle to slave device
* @command: Byte interpreted by slave
* @value: 16-bit "word" being written
*
* This executes the SMBus "process call" protocol, returning negative errno
* else a 16-bit unsigned "word" received from the device.
*/
s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value)
{
union i2c_smbus_data data;
int status;
data.word = value;
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_PROC_CALL, &data);
return (status < 0) ? status : data.word;
}
EXPORT_SYMBOL(i2c_smbus_process_call);
/** /**
* i2c_smbus_read_block_data - SMBus "block read" protocol * i2c_smbus_read_block_data - SMBus "block read" protocol
* @client: Handle to slave device * @client: Handle to slave device
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment