Commit 8d41f0e8 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: (44 commits)
  i2c-s3c2410: Fix bug in releasing driver
  i2c-s3c2410: Fix I2C SDA to SCL setup time
  i2c: New i2c-tiny-usb bus driver
  i2c: Documentation update
  i2c: SPIN_LOCK_UNLOCKED cleanup
  i2c: Obsolete i2c-ixp2000, i2c-ixp4xx and scx200_i2c
  i2c: New Simtec I2C bus driver
  i2c: Bitbanging I2C bus driver using the GPIO API
  Use menuconfig objects - I2C
  i2c: Restore i2c_smbus_read_block_data
  i2c-pxa: Clean transaction stop
  i2c-algo-bit: Improve debugging
  i2c-algo-bit: Implement a 50/50 SCL duty cycle
  i2c-omap: Switch to static adapter numbering
  i2c: Blackfin Two Wire Interface driver
  i2c-algo-sgi: Comment and whitespace cleanups
  i2c: Make i2c_del_driver a void function
  i2c: Move i2c-isa-only exported symbol declarations
  i2c: Document i2c_new_device()
  i2c: Add i2c_new_probed_device()
  ...

Fixed trivial conflict in Documentation/feature-removal-schedule.txt manually.
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parents 8bc84930 5b68790c
......@@ -190,18 +190,10 @@ Who: Jean Delvare <khali@linux-fr.org>
---------------------------
What: i2c_adapter.dev
i2c_adapter.list
What: i2c_adapter.list
When: July 2007
Why: Superfluous, given i2c_adapter.class_dev:
* The "dev" was a stand-in for the physical device node that legacy
drivers would not have; but now it's almost always present. Any
remaining legacy drivers must upgrade (they now trigger warnings).
* The "list" duplicates class device children.
The delay in removing this is so upgraded lm_sensors and libsensors
can get deployed. (Removal causes minor changes in the sysfs layout,
notably the location of the adapter type name and parenting the i2c
client hardware directly from their controller.)
Why: Superfluous, this list duplicates the one maintained by the driver
core.
Who: Jean Delvare <khali@linux-fr.org>,
David Brownell <dbrownell@users.sourceforge.net>
......@@ -331,3 +323,10 @@ Who: Cornelia Huck <cornelia.huck@de.ibm.com>
---------------------------
What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
When: September 2007
Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific
I2C-over-GPIO drivers.
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
......@@ -9,6 +9,8 @@ Supported adapters:
* nForce4 MCP-04 10de:0034
* nForce4 MCP51 10de:0264
* nForce4 MCP55 10de:0368
* nForce4 MCP61 10de:03EB
* nForce4 MCP65 10de:0446
Datasheet: not publicly available, but seems to be similar to the
AMD-8111 SMBus 2.0 adapter.
......
Revision 6, 2005-11-20
Revision 7, 2007-04-19
Jean Delvare <khali@linux-fr.org>
Greg KH <greg@kroah.com>
......@@ -20,6 +20,10 @@ yours for best results.
Technical changes:
* [Driver type] Any driver that was relying on i2c-isa has to be
converted to a proper isa, platform or pci driver. This is not
covered by this guide.
* [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
Includes typically look like that:
#include <linux/module.h>
......@@ -27,12 +31,10 @@ Technical changes:
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/i2c-isa.h> /* for ISA drivers */
#include <linux/hwmon.h> /* for hardware monitoring drivers */
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h> /* if you need VRM support */
#include <linux/err.h> /* for class registration */
#include <asm/io.h> /* if you have I/O operations */
Please respect this inclusion order. Some extra headers may be
required for a given driver (e.g. "lm75.h").
......@@ -69,20 +71,16 @@ Technical changes:
sensors mailing list <lm-sensors@lm-sensors.org> by providing a
patch to the Documentation/hwmon/sysfs-interface file.
* [Attach] For I2C drivers, the attach function should make sure
that the adapter's class has I2C_CLASS_HWMON (or whatever class is
suitable for your driver), using the following construct:
* [Attach] The attach function should make sure that the adapter's
class has I2C_CLASS_HWMON (or whatever class is suitable for your
driver), using the following construct:
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
ISA-only drivers of course don't need this.
Call i2c_probe() instead of i2c_detect().
* [Detect] As mentioned earlier, the flags parameter is gone.
The type_name and client_name strings are replaced by a single
name string, which will be filled with a lowercase, short string.
In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
useless. Same for isa-only drivers, as the test would always be
true. Only hybrid drivers (which are quite rare) still need it.
The labels used for error paths are reduced to the number needed.
It is advised that the labels are given descriptive names such as
exit and exit_free. Don't forget to properly set err before
......
......@@ -4,17 +4,23 @@ I2C and SMBus
=============
I2C (pronounce: I squared C) is a protocol developed by Philips. It is a
slow two-wire protocol (10-400 kHz), but it suffices for many types of
devices.
slow two-wire protocol (variable speed, up to 400 kHz), with a high speed
extension (3.4 MHz). It provides an inexpensive bus for connecting many
types of devices with infrequent or low bandwidth communications needs.
I2C is widely used with embedded systems. Some systems use variants that
don't meet branding requirements, and so are not advertised as being I2C.
SMBus (System Management Bus) is a subset of the I2C protocol. Many
modern mainboards have a System Management Bus. There are a lot of
devices which can be connected to a SMBus; the most notable are modern
memory chips with EEPROM memories and chips for hardware monitoring.
SMBus (System Management Bus) is based on the I2C protocol, and is mostly
a subset of I2C protocols and signaling. Many I2C devices will work on an
SMBus, but some SMBus protocols add semantics beyond what is required to
achieve I2C branding. Modern PC mainboards rely on SMBus. The most common
devices connected through SMBus are RAM modules configured using I2C EEPROMs,
and hardware monitoring chips.
Because the SMBus is just a special case of the generalized I2C bus, we
can simulate the SMBus protocol on plain I2C busses. The reverse is
regretfully impossible.
Because the SMBus is mostly a subset of the generalized I2C bus, we can
use its protocols on many I2C systems. However, there are systems that don't
meet both SMBus and I2C electrical constraints; and others which can't
implement all the common SMBus protocol semantics or messages.
Terminology
......@@ -29,6 +35,7 @@ When we talk about I2C, we use the following terms:
An Algorithm driver contains general code that can be used for a whole class
of I2C adapters. Each specific adapter driver depends on one algorithm
driver.
A Driver driver (yes, this sounds ridiculous, sorry) contains the general
code to access some type of device. Each detected device gets its own
data in the Client structure. Usually, Driver and Client are more closely
......@@ -40,6 +47,10 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices
in this package. See the lm_sensors project http://www.lm-sensors.nu
for device drivers.
At this time, Linux only operates I2C (or SMBus) in master mode; you can't
use these APIs to make a Linux system behave as a slave/device, either to
speak a custom protocol or to emulate some other device.
Included Bus Drivers
====================
......
This diff is collapsed.
......@@ -733,6 +733,13 @@ M: tigran@aivazian.fsnet.co.uk
L: linux-kernel@vger.kernel.org
S: Maintained
BLACKFIN I2C TWI DRIVER
P: Sonic Zhang
M: sonic.zhang@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org/
S: Supported
BLOCK LAYER
P: Jens Axboe
M: axboe@kernel.dk
......@@ -1459,6 +1466,11 @@ L: linux-scsi@vger.kernel.org
W: http://www.icp-vortex.com/
S: Supported
GENERIC GPIO I2C DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS
P: Krzysztof Halasa
M: khc@pm.waw.pl
......@@ -1631,6 +1643,13 @@ L: i2c@lm-sensors.org
T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
S: Maintained
I2C-TINY-USB DRIVER
P: Till Harbaum
M: till@harbaum.org
L: i2c@lm-sensors.org
T: http://www.harbaum.org/till/i2c_tiny_usb
S: Maintained
i386 BOOT CODE
P: Riley H. Williams
M: Riley@Williams.Name
......
......@@ -25,7 +25,6 @@
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/i2c.h>
#include <linux/hardirq.h>
#include <asm/prom.h>
#include <asm/machdep.h>
......
......@@ -58,7 +58,7 @@ obj-$(CONFIG_GAMEPORT) += input/gameport/
obj-$(CONFIG_INPUT) += input/
obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_RTC_LIB) += rtc/
obj-$(CONFIG_I2C) += i2c/
obj-y += i2c/
obj-$(CONFIG_W1) += w1/
obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_PHONE) += telephony/
......
......@@ -2,9 +2,7 @@
# I2C subsystem configuration
#
menu "I2C support"
config I2C
menuconfig I2C
tristate "I2C support"
---help---
I2C (pronounce: I-square-C) is a slow serial bus protocol used in
......@@ -22,9 +20,14 @@ config I2C
This I2C support can also be built as a module. If so, the module
will be called i2c-core.
if I2C
config I2C_BOARDINFO
boolean
default y
config I2C_CHARDEV
tristate "I2C device interface"
depends on I2C
help
Say Y here to use i2c-* device files, usually found in the /dev
directory on your system. They make it possible to have user-space
......@@ -40,7 +43,6 @@ source drivers/i2c/chips/Kconfig
config I2C_DEBUG_CORE
bool "I2C Core debugging messages"
depends on I2C
help
Say Y here if you want the I2C core to produce a bunch of debug
messages to the system log. Select this if you are having a
......@@ -48,7 +50,6 @@ config I2C_DEBUG_CORE
config I2C_DEBUG_ALGO
bool "I2C Algorithm debugging messages"
depends on I2C
help
Say Y here if you want the I2C algorithm drivers to produce a bunch
of debug messages to the system log. Select this if you are having
......@@ -57,7 +58,6 @@ config I2C_DEBUG_ALGO
config I2C_DEBUG_BUS
bool "I2C Bus debugging messages"
depends on I2C
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
......@@ -66,12 +66,10 @@ config I2C_DEBUG_BUS
config I2C_DEBUG_CHIP
bool "I2C Chip debugging messages"
depends on I2C
help
Say Y here if you want the I2C chip drivers to produce a bunch of
debug messages to the system log. Select this if you are having
a problem with I2C support and want to see more of what is going
on.
endmenu
endif # I2C
......@@ -2,6 +2,7 @@
# Makefile for the i2c core.
#
obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-y += busses/ chips/ algos/
......
......@@ -3,11 +3,9 @@
#
menu "I2C Algorithms"
depends on I2C
config I2C_ALGOBIT
tristate "I2C bit-banging interfaces"
depends on I2C
help
This allows you to use a range of I2C adapters called bit-banging
adapters. Say Y if you own an I2C adapter belonging to this class
......@@ -18,7 +16,6 @@ config I2C_ALGOBIT
config I2C_ALGOPCF
tristate "I2C PCF 8584 interfaces"
depends on I2C
help
This allows you to use a range of I2C adapters called PCF adapters.
Say Y if you own an I2C adapter belonging to this class and then say
......@@ -29,7 +26,6 @@ config I2C_ALGOPCF
config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
depends on I2C
help
This allows you to use a range of I2C adapters called PCA adapters.
Say Y if you own an I2C adapter belonging to this class and then say
......@@ -40,11 +36,11 @@ config I2C_ALGOPCA
config I2C_ALGO8XX
tristate "MPC8xx CPM I2C interface"
depends on 8xx && I2C
depends on 8xx
config I2C_ALGO_SGI
tristate "I2C SGI interfaces"
depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS)
depends on SGI_IP22 || SGI_IP32 || X86_VISWS
help
Supports the SGI interfaces like the ones found on SGI Indy VINO
or SGI O2 MACE.
......
This diff is collapsed.
/*
* i2c-algo-sgi.c: i2c driver algorithms for SGI adapters.
* i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
* MACE (SGI O2) chips.
*
* This file is subject to the terms and conditions of the GNU General Public
* License version 2 as published by the Free Software Foundation.
......
This diff is collapsed.
......@@ -10,7 +10,9 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_I810) += i2c-i810.o
......@@ -37,10 +39,12 @@ obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
obj-$(CONFIG_I2C_STUB) += i2c-stub.o
obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
obj-$(CONFIG_I2C_VIA) += i2c-via.o
......
......@@ -497,7 +497,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_
/* set up the sysfs linkage to our parent device */
ali1535_adapter.dev.parent = &dev->dev;
snprintf(ali1535_adapter.name, I2C_NAME_SIZE,
snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
"SMBus ALI1535 adapter at %04x", ali1535_smba);
return i2c_add_adapter(&ali1535_adapter);
}
......
......@@ -492,7 +492,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_
/* set up the sysfs linkage to our parent device */
ali15x3_adapter.dev.parent = &dev->dev;
snprintf(ali15x3_adapter.name, I2C_NAME_SIZE,
snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
"SMBus ALI15X3 adapter at %04x", ali15x3_smba);
return i2c_add_adapter(&ali15x3_adapter);
}
......
......@@ -365,7 +365,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
}
smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, I2C_NAME_SIZE,
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base);
smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
smbus->adapter.class = I2C_CLASS_HWMON;
......
This diff is collapsed.
......@@ -35,6 +35,7 @@
#include <linux/pci.h>
#include <linux/wait.h>
#include <linux/isa.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pcf.h>
......@@ -207,7 +208,7 @@ static struct i2c_adapter pcf_isa_ops = {
.name = "i2c-elektor",
};
static int __init i2c_pcfisa_init(void)
static int __devinit elektor_match(struct device *dev, unsigned int id)
{
#ifdef __alpha__
/* check to see we have memory mapped PCF8584 connected to the
......@@ -222,9 +223,8 @@ static int __init i2c_pcfisa_init(void)
/* yeap, we've found cypress, let's check config */
if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
pr_debug("%s: found cy82c693, config "
"register 0x47 = 0x%02x\n",
pcf_isa_ops.name, config);
dev_dbg(dev, "found cy82c693, config "
"register 0x47 = 0x%02x\n", config);
/* UP2000 board has this register set to 0xe1,
but the most significant bit as seems can be
......@@ -244,9 +244,9 @@ static int __init i2c_pcfisa_init(void)
8.25 MHz (PCI/4) clock
(this can be read from cypress) */
clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
pr_info("%s: found API UP2000 like "
dev_info(dev, "found API UP2000 like "
"board, will probe PCF8584 "
"later\n", pcf_isa_ops.name);
"later\n");
}
}
pci_dev_put(cy693_dev);
......@@ -256,22 +256,27 @@ static int __init i2c_pcfisa_init(void)
/* sanity checks for mmapped I/O */
if (mmapped && base < 0xc8000) {
printk(KERN_ERR "%s: incorrect base address (%#x) specified "
"for mmapped I/O\n", pcf_isa_ops.name, base);
return -ENODEV;
dev_err(dev, "incorrect base address (%#x) specified "
"for mmapped I/O\n", base);
return 0;
}
if (base == 0) {
base = DEFAULT_BASE;
}
return 1;
}
static int __devinit elektor_probe(struct device *dev, unsigned int id)
{
init_waitqueue_head(&pcf_wait);
if (pcf_isa_init())
return -ENODEV;
pcf_isa_ops.dev.parent = dev;
if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
goto fail;
dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base);
dev_info(dev, "found device at %#x\n", base);
return 0;
......@@ -291,7 +296,7 @@ static int __init i2c_pcfisa_init(void)
return -ENODEV;
}
static void i2c_pcfisa_exit(void)
static int __devexit elektor_remove(struct device *dev, unsigned int id)
{
i2c_del_adapter(&pcf_isa_ops);
......@@ -307,6 +312,28 @@ static void i2c_pcfisa_exit(void)
iounmap(base_iomem);
release_mem_region(base, 2);
}
return 0;
}
static struct isa_driver i2c_elektor_driver = {
.match = elektor_match,
.probe = elektor_probe,
.remove = __devexit_p(elektor_remove),
.driver = {
.owner = THIS_MODULE,
.name = "i2c-elektor",
},
};
static int __init i2c_pcfisa_init(void)
{
return isa_register_driver(&i2c_elektor_driver, 1);
}
static void __exit i2c_pcfisa_exit(void)
{
isa_unregister_driver(&i2c_elektor_driver);
}
MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
......
/*
* Bitbanging I2C bus driver using the GPIO API
*
* Copyright (C) 2007 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/gpio.h>
/* Toggle SDA by changing the direction of the pin */
static void i2c_gpio_setsda_dir(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
if (state)
gpio_direction_input(pdata->sda_pin);
else
gpio_direction_output(pdata->sda_pin, 0);
}
/*
* Toggle SDA by changing the output value of the pin. This is only
* valid for pins configured as open drain (i.e. setting the value
* high effectively turns off the output driver.)
*/
static void i2c_gpio_setsda_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
gpio_set_value(pdata->sda_pin, state);
}
/* Toggle SCL by changing the direction of the pin. */
static void i2c_gpio_setscl_dir(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
if (state)
gpio_direction_input(pdata->scl_pin);
else
gpio_direction_output(pdata->scl_pin, 0);
}
/*
* Toggle SCL by changing the output value of the pin. This is used
* for pins that are configured as open drain and for output-only
* pins. The latter case will break the i2c protocol, but it will
* often work in practice.
*/
static void i2c_gpio_setscl_val(void *data, int state)
{
struct i2c_gpio_platform_data *pdata = data;
gpio_set_value(pdata->scl_pin, state);
}
int i2c_gpio_getsda(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
return gpio_get_value(pdata->sda_pin);
}
int i2c_gpio_getscl(void *data)
{
struct i2c_gpio_platform_data *pdata = data;
return gpio_get_value(pdata->scl_pin);
}
static int __init i2c_gpio_probe(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
int ret;
pdata = pdev->dev.platform_data;
if (!pdata)
return -ENXIO;
ret = -ENOMEM;
adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
if (!adap)
goto err_alloc_adap;
bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
if (!bit_data)
goto err_alloc_bit_data;
ret = gpio_request(pdata->sda_pin, "sda");
if (ret)
goto err_request_sda;
ret = gpio_request(pdata->scl_pin, "scl");
if (ret)
goto err_request_scl;
if (pdata->sda_is_open_drain) {
gpio_direction_output(pdata->sda_pin, 1);
bit_data->setsda = i2c_gpio_setsda_val;
} else {
gpio_direction_input(pdata->sda_pin);
bit_data->setsda = i2c_gpio_setsda_dir;
}
if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
gpio_direction_output(pdata->scl_pin, 1);
bit_data->setscl = i2c_gpio_setscl_val;
} else {
gpio_direction_input(pdata->scl_pin);
bit_data->setscl = i2c_gpio_setscl_dir;
}
if (!pdata->scl_is_output_only)
bit_data->getscl = i2c_gpio_getscl;
bit_data->getsda = i2c_gpio_getsda;
if (pdata->udelay)
bit_data->udelay = pdata->udelay;
else if (pdata->scl_is_output_only)
bit_data->udelay = 50; /* 10 kHz */
else
bit_data->udelay = 5; /* 100 kHz */
if (pdata->timeout)
bit_data->timeout = pdata->timeout;
else
bit_data->timeout = HZ / 10; /* 100 ms */
bit_data->data = pdata;
adap->owner = THIS_MODULE;
snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
adap->algo_data = bit_data;
adap->dev.parent = &pdev->dev;
ret = i2c_bit_add_bus(adap);
if (ret)
goto err_add_bus;
platform_set_drvdata(pdev, adap);
dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
pdata->sda_pin, pdata->scl_pin,
pdata->scl_is_output_only
? ", no clock stretching" : "");
return 0;
err_add_bus:
gpio_free(pdata->scl_pin);
err_request_scl:
gpio_free(pdata->sda_pin);
err_request_sda:
kfree(bit_data);
err_alloc_bit_data:
kfree(adap);
err_alloc_adap:
return ret;
}
static int __exit i2c_gpio_remove(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap;
adap = platform_get_drvdata(pdev);
pdata = pdev->dev.platform_data;
i2c_del_adapter(adap);
gpio_free(pdata->scl_pin);
gpio_free(pdata->sda_pin);
kfree(adap->algo_data);
kfree(adap);
return 0;
}
static struct platform_driver i2c_gpio_driver = {
.driver = {
.name = "i2c-gpio",
.owner = THIS_MODULE,
},
.remove = __exit_p(i2c_gpio_remove),
};
static int __init i2c_gpio_init(void)
{
int ret;
ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe);
if (ret)
printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
return ret;
}
module_init(i2c_gpio_init);
static void __exit i2c_gpio_exit(void)
{
platform_driver_unregister(&i2c_gpio_driver);
}
module_exit(i2c_gpio_exit);
MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
MODULE_LICENSE("GPL");
......@@ -527,7 +527,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
/* set up the sysfs linkage to our parent device */
i801_adapter.dev.parent = &dev->dev;
snprintf(i801_adapter.name, I2C_NAME_SIZE,
snprintf(i801_adapter.name, sizeof(i801_adapter.name),
"SMBus I801 adapter at %04lx", i801_smba);
err = i2c_add_adapter(&i801_adapter);
if (err) {
......
......@@ -41,6 +41,10 @@
#include <linux/platform_device.h>
#include <linux/completion.h>
/* Exported by i2c-core for i2c-isa only */
extern void i2c_adapter_dev_release(struct device *dev);
extern struct class i2c_adapter_class;
static u32 isa_func(struct i2c_adapter *adapter);
/* This is the actual algorithm we define */
......@@ -64,16 +68,6 @@ static u32 isa_func(struct i2c_adapter *adapter)
}
/* Copied from i2c-core */
static ssize_t show_adapter_name(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
return sprintf(buf, "%s\n", adap->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
/* We implement an interface which resembles i2c_{add,del}_driver,
but for i2c-isa drivers. We don't have to remember and handle lists
of drivers and adapters so this is much more simple, of course. */
......@@ -139,41 +133,18 @@ static int __init i2c_isa_init(void)
isa_adapter.nr = ANY_I2C_ISA_BUS;
isa_adapter.dev.parent = &platform_bus;
sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
isa_adapter.dev.driver = &i2c_adapter_driver;
isa_adapter.dev.release = &i2c_adapter_dev_release;
isa_adapter.dev.class = &i2c_adapter_class;
err = device_register(&isa_adapter.dev);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to register device\n");
goto exit;
}
err = device_create_file(&isa_adapter.dev, &dev_attr_name);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to create name file\n");
goto exit_unregister;
}
/* Add this adapter to the i2c_adapter class */
memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
isa_adapter.class_dev.dev = &isa_adapter.dev;
isa_adapter.class_dev.class = &i2c_adapter_class;
strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
BUS_ID_SIZE);
err = class_device_register(&isa_adapter.class_dev);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to register class device\n");
goto exit_remove_name;
}
dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
return 0;
exit_remove_name:
device_remove_file(&isa_adapter.dev, &dev_attr_name);
exit_unregister:
init_completion(&isa_adapter.dev_released); /* Needed? */
device_unregister(&isa_adapter.dev);
wait_for_completion(&isa_adapter.dev_released);
exit:
return err;
}
......@@ -201,15 +172,11 @@ static void __exit i2c_isa_exit(void)
/* Clean up the sysfs representation */
dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n");
init_completion(&isa_adapter.dev_released);
init_completion(&isa_adapter.class_dev_released);
class_device_unregister(&isa_adapter.class_dev);
device_remove_file(&isa_adapter.dev, &dev_attr_name);
device_unregister(&isa_adapter.dev);
/* Wait for sysfs to drop all references */
dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n");
wait_for_completion(&isa_adapter.dev_released);
wait_for_completion(&isa_adapter.class_dev_released);
dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name);
}
......
......@@ -118,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->adapter.id = I2C_HW_B_IXP2000,
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE);
sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data,
drv_data->adapter.dev.parent = &plat_dev->dev;
......
......@@ -127,7 +127,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->adapter.id = I2C_HW_B_IXP4XX;
drv_data->adapter.class = I2C_CLASS_HWMON;
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE);
sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data;
drv_data->adapter.dev.parent = &plat_dev->dev;
......
......@@ -508,7 +508,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
}
strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
I2C_NAME_SIZE);
sizeof(drv_data->adapter.name));
init_waitqueue_head(&drv_data->waitq);
spin_lock_init(&drv_data->lock);
......
......@@ -33,6 +33,8 @@
nForce4 MCP-04 0034
nForce4 MCP51 0264
nForce4 MCP55 0368
nForce MCP61 03EB
nForce MCP65 0446
This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets.
......@@ -200,6 +202,8 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
{ 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) },
{ 0 }
};
......@@ -240,7 +244,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
smbus->adapter.dev.parent = &dev->dev;
snprintf(smbus->adapter.name, I2C_NAME_SIZE,
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus nForce2 adapter at %04x", smbus->base);
error = i2c_add_adapter(&smbus->adapter);
......
......@@ -605,7 +605,8 @@ omap_i2c_probe(struct platform_device *pdev)
adap->dev.parent = &pdev->dev;
/* i2c device drivers may be active on return from add_adapter() */
r = i2c_add_adapter(adap);
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
goto err_free_irq;
......
/* ------------------------------------------------------------------------ *
* i2c-parport.c I2C bus over parallel port *
* i2c-parport-light.c I2C bus over parallel port *
* ------------------------------------------------------------------------ *
Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
Based on older i2c-velleman.c driver
Copyright (C) 1995-2000 Simon G. Vogl
......@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
......@@ -34,6 +35,9 @@
#include "i2c-parport.h"
#define DEFAULT_BASE 0x378
#define DRVNAME "i2c-parport-light"
static struct platform_device *pdev;
static u16 base;
module_param(base, ushort, 0);
......@@ -106,7 +110,7 @@ static struct i2c_algo_bit_data parport_algo_data = {
.timeout = HZ,
};
/* ----- I2c structure ---------------------------------------------------- */
/* ----- Driver registration ---------------------------------------------- */
static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE,
......@@ -116,55 +120,141 @@ static struct i2c_adapter parport_adapter = {
.name = "Parallel port adapter (light)",
};
/* ----- Module loading, unloading and information ------------------------ */
static int __devinit i2c_parport_probe(struct platform_device *pdev)
{
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) */
parport_setsda(NULL, 1);
parport_setscl(NULL, 1);
/* Other init if needed (power on...) */
if (adapter_parm[type].init.val)
line_set(1, &adapter_parm[type].init);
parport_adapter.dev.parent = &pdev->dev;
err = i2c_bit_add_bus(&parport_adapter);
if (err) {
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;
}
static int __devexit i2c_parport_remove(struct platform_device *pdev)
{
struct resource *res;
i2c_del_adapter(&parport_adapter);
/* Un-init if needed (power off...) */
if (adapter_parm[type].init.val)
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;
}
static struct platform_driver i2c_parport_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRVNAME,
},
.probe = i2c_parport_probe,
.remove = __devexit_p(i2c_parport_remove),
};
static int __init i2c_parport_device_add(u16 address)
{
struct resource res = {
.start = address,
.end = address + 2,
.name = DRVNAME,
.flags = IORESOURCE_IO,
};
int err;
pdev = platform_device_alloc(DRVNAME, -1);
if (!pdev) {
err = -ENOMEM;
printk(KERN_ERR DRVNAME ": Device allocation failed\n");
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);
if (err) {
printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
err);
goto exit_device_put;
}
return 0;
exit_device_put:
platform_device_put(pdev);
exit:
return err;
}
static int __init i2c_parport_init(void)
{
int err;
if (type < 0) {
printk(KERN_WARNING "i2c-parport: adapter type unspecified\n");
printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
return -ENODEV;
}
if (type >= ARRAY_SIZE(adapter_parm)) {
printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type);
return -ENODEV;
}
if (base == 0) {
printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE);
pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE);
base = DEFAULT_BASE;
}
if (!request_region(base, 3, "i2c-parport"))
return -ENODEV;
if (!adapter_parm[type].getscl.val)
parport_algo_data.getscl = NULL;
/* Reset hardware to a sane state (SCL and SDA high) */
parport_setsda(NULL, 1);
parport_setscl(NULL, 1);
/* Other init if needed (power on...) */
if (adapter_parm[type].init.val)
line_set(1, &adapter_parm[type].init);
/* Sets global pdev as a side effect */
err = i2c_parport_device_add(base);
if (err)
goto exit;
if (i2c_bit_add_bus(&parport_adapter) < 0) {
printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
release_region(base, 3);
return -ENODEV;
}
err = platform_driver_register(&i2c_parport_driver);
if (err)
goto exit_device;
return 0;
exit_device:
platform_device_unregister(pdev);
exit:
return err;
}
static void __exit i2c_parport_exit(void)
{
/* Un-init if needed (power off...) */
if (adapter_parm[type].init.val)
line_set(0, &adapter_parm[type].init);
i2c_del_adapter(&parport_adapter);
release_region(base, 3);
platform_driver_unregister(&i2c_parport_driver);
platform_device_unregister(pdev);
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
......
/* ------------------------------------------------------------------------ *
* i2c-parport.c I2C bus over parallel port *
* ------------------------------------------------------------------------ *
Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
Based on older i2c-philips-par.c driver
Copyright (C) 1995-2000 Simon G. Vogl
......@@ -137,19 +137,12 @@ static struct i2c_algo_bit_data parport_algo_data = {
.setscl = parport_setscl,
.getsda = parport_getsda,
.getscl = parport_getscl,
.udelay = 60,
.udelay = 10, /* ~50 kbps */
.timeout = HZ,
};
/* ----- I2c and parallel port call-back functions and structures --------- */
static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.id = I2C_HW_B_LP,
.name = "Parallel port adapter",
};
static void i2c_parport_attach (struct parport *port)
{
struct i2c_par *adapter;
......@@ -169,10 +162,17 @@ static void i2c_parport_attach (struct parport *port)
}
/* Fill the rest of the structure */
adapter->adapter = parport_adapter;
adapter->adapter.owner = THIS_MODULE;
adapter->adapter.class = I2C_CLASS_HWMON;
adapter->adapter.id = I2C_HW_B_LP;
strlcpy(adapter->adapter.name, "Parallel port adapter",
sizeof(adapter->adapter.name));
adapter->algo_data = parport_algo_data;
if (!adapter_parm[type].getscl.val)
/* Slow down if we can't sense SCL */
if (!adapter_parm[type].getscl.val) {
adapter->algo_data.getscl = NULL;
adapter->algo_data.udelay = 50; /* ~10 kbps */
}
adapter->algo_data.data = port;
adapter->adapter.algo_data = &adapter->algo_data;
......@@ -214,11 +214,12 @@ static void i2c_parport_detach (struct parport *port)
for (prev = NULL, adapter = adapter_list; adapter;
prev = adapter, adapter = adapter->next) {
if (adapter->pdev->port == port) {
i2c_del_adapter(&adapter->adapter);
/* Un-init if needed (power off...) */
if (adapter_parm[type].init.val)
line_set(port, 0, &adapter_parm[type].init);
i2c_del_adapter(&adapter->adapter);
parport_unregister_device(adapter->pdev);
if (prev)
prev->next = adapter->next;
......
......@@ -358,7 +358,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
}
smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, I2C_NAME_SIZE,
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"PA Semi SMBus adapter at 0x%lx", smbus->base);
smbus->adapter.class = I2C_CLASS_HWMON;
smbus->adapter.algo = &smbus_algorithm;
......
......@@ -28,6 +28,7 @@
#include <linux/pci.h>
#include <linux/wait.h>
#include <linux/isa.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>
......@@ -119,27 +120,26 @@ static struct i2c_adapter pca_isa_ops = {
.name = "PCA9564 ISA Adapter",
};
static int __init pca_isa_init(void)
static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
{
init_waitqueue_head(&pca_wait);
printk(KERN_INFO "i2c-pca-isa: i/o base %#08lx. irq %d\n", base, irq);
dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
printk(KERN_ERR "i2c-pca-isa: I/O address %#08lx is in use.\n", base);
dev_err(dev, "I/O address %#08lx is in use\n", base);
goto out;
}
if (irq > -1) {
if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) {
printk(KERN_ERR "i2c-pca-isa: Request irq%d failed\n", irq);
dev_err(dev, "Request irq%d failed\n", irq);
goto out_region;
}
}
if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
printk(KERN_ERR "i2c-pca-isa: Failed to add i2c bus\n");
dev_err(dev, "Failed to add i2c bus\n");
goto out_irq;
}
......@@ -154,7 +154,7 @@ static int __init pca_isa_init(void)
return -ENODEV;
}
static void pca_isa_exit(void)
static int __devexit pca_isa_remove(struct device *dev, unsigned int id)
{
i2c_del_adapter(&pca_isa_ops);
......@@ -163,6 +163,27 @@ static void pca_isa_exit(void)
free_irq(irq, &pca_isa_ops);
}
release_region(base, IO_SIZE);
return 0;
}
static struct isa_driver pca_isa_driver = {
.probe = pca_isa_probe,
.remove = __devexit_p(pca_isa_remove),
.driver = {
.owner = THIS_MODULE,
.name = "i2c-pca-isa",
}
};
static int __init pca_isa_init(void)
{
return isa_register_driver(&pca_isa_driver, 1);
}
static void __exit pca_isa_exit(void)
{
isa_unregister_driver(&pca_isa_driver);
}
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
......
......@@ -428,7 +428,7 @@ static int __devinit piix4_probe(struct pci_dev *dev,
/* set up the sysfs linkage to our parent device */
piix4_adapter.dev.parent = &dev->dev;
snprintf(piix4_adapter.name, I2C_NAME_SIZE,
snprintf(piix4_adapter.name, sizeof(piix4_adapter.name),
"SMBus PIIX4 adapter at %04x", piix4_smba);
if ((retval = i2c_add_adapter(&piix4_adapter))) {
......
......@@ -539,6 +539,18 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
writel(icr | ICR_START | ICR_TB, _ICR(i2c));
}
static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
{
u32 icr;
/*
* Clear the STOP and ACK flags
*/
icr = readl(_ICR(i2c));
icr &= ~(ICR_STOP | ICR_ACKNAK);
writel(icr, _IRC(i2c));
}
/*
* We are protected by the adapter bus mutex.
*/
......@@ -581,6 +593,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
* The rest of the processing occurs in the interrupt handler.
*/
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
i2c_pxa_stop_message(i2c);
/*
* We place the return code in i2c->msg_idx.
......@@ -825,7 +838,7 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
};
static struct pxa_i2c i2c_pxa = {
.lock = SPIN_LOCK_UNLOCKED,
.lock = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
.adap = {
.owner = THIS_MODULE,
.algo = &i2c_pxa_algorithm,
......
......@@ -61,6 +61,8 @@ struct s3c24xx_i2c {
unsigned int msg_idx;
unsigned int msg_ptr;
unsigned int tx_setup;
enum s3c24xx_i2c_state state;
void __iomem *regs;
......@@ -199,8 +201,11 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
writeb(addr, i2c->regs + S3C2410_IICDS);
// delay a bit and reset iiccon before setting start (per samsung)
udelay(1);
/* delay here to ensure the data byte has gotten onto the bus
* before the transaction is started */
ndelay(i2c->tx_setup);
dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
writel(iiccon, i2c->regs + S3C2410_IICCON);
......@@ -323,6 +328,14 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + S3C2410_IICDS);
/* delay after writing the byte to allow the
* data setup time on the bus, as writing the
* data to the register causes the first bit
* to appear on SDA, and SCL will change as
* soon as the interrupt is acknowledged */
ndelay(i2c->tx_setup);
} else if (!is_lastmsg(i2c)) {
/* we need to go to the next i2c message */
......@@ -570,8 +583,9 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
};
static struct s3c24xx_i2c s3c24xx_i2c = {
.lock = SPIN_LOCK_UNLOCKED,
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),
.wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
.tx_setup = 50,
.adap = {
.name = "s3c2410-i2c",
.owner = THIS_MODULE,
......@@ -731,26 +745,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
return 0;
}
static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
{
if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
clk_disable(i2c->clk);
clk_put(i2c->clk);
i2c->clk = NULL;
}
if (i2c->regs != NULL) {
iounmap(i2c->regs);
i2c->regs = NULL;
}
if (i2c->ioarea != NULL) {
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
i2c->ioarea = NULL;
}
}
/* s3c24xx_i2c_probe
*
* called by the bus driver when a suitable device is found
......@@ -769,7 +763,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;
goto out;
goto err_noclk;
}
dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
......@@ -782,7 +776,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (res == NULL) {
dev_err(&pdev->dev, "cannot find IO resource\n");
ret = -ENOENT;
goto out;
goto err_clk;
}
i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,
......@@ -791,7 +785,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (i2c->ioarea == NULL) {
dev_err(&pdev->dev, "cannot request IO\n");
ret = -ENXIO;
goto out;
goto err_clk;
}
i2c->regs = ioremap(res->start, (res->end-res->start)+1);
......@@ -799,7 +793,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (i2c->regs == NULL) {
dev_err(&pdev->dev, "cannot map IO\n");
ret = -ENXIO;
goto out;
goto err_ioarea;
}
dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
......@@ -813,7 +807,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
ret = s3c24xx_i2c_init(i2c);
if (ret != 0)
goto out;
goto err_iomap;
/* find the IRQ for this unit (note, this relies on the init call to
* ensure no current IRQs pending
......@@ -823,7 +817,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (res == NULL) {
dev_err(&pdev->dev, "cannot find IRQ\n");
ret = -ENOENT;
goto out;
goto err_iomap;
}
ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED,
......@@ -831,7 +825,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ\n");
goto out;
goto err_iomap;
}
i2c->irq = res;
......@@ -841,17 +835,29 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto out;
goto err_irq;
}
platform_set_drvdata(pdev, i2c);
dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
return 0;
out:
if (ret < 0)
s3c24xx_i2c_free(i2c);
err_irq:
free_irq(i2c->irq->start, i2c);
err_iomap:
iounmap(i2c->regs);
err_ioarea:
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
err_clk:
clk_disable(i2c->clk);
clk_put(i2c->clk);
err_noclk:
return ret;
}
......@@ -864,10 +870,16 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
{
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
if (i2c != NULL) {
s3c24xx_i2c_free(i2c);
platform_set_drvdata(pdev, NULL);
}
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq->start, i2c);
clk_disable(i2c->clk);
clk_put(i2c->clk);
iounmap(i2c->regs);
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
return 0;
}
......
/*
* Copyright (C) 2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Simtec Generic I2C Controller
*
* 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
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>
struct simtec_i2c_data {
struct resource *ioarea;
void __iomem *reg;
struct i2c_adapter adap;
struct i2c_algo_bit_data bit;
};
#define CMD_SET_SDA (1<<2)
#define CMD_SET_SCL (1<<3)
#define STATE_SDA (1<<0)
#define STATE_SCL (1<<1)
/* i2c bit-bus functions */
static void simtec_i2c_setsda(void *pw, int state)
{
struct simtec_i2c_data *pd = pw;
writeb(CMD_SET_SDA | (state ? STATE_SDA : 0), pd->reg);
}
static void simtec_i2c_setscl(void *pw, int state)
{
struct simtec_i2c_data *pd = pw;
writeb(CMD_SET_SCL | (state ? STATE_SCL : 0), pd->reg);
}
static int simtec_i2c_getsda(void *pw)
{
struct simtec_i2c_data *pd = pw;
return readb(pd->reg) & STATE_SDA ? 1 : 0;
}
static int simtec_i2c_getscl(void *pw)
{
struct simtec_i2c_data *pd = pw;
return readb(pd->reg) & STATE_SCL ? 1 : 0;
}
/* device registration */
static int simtec_i2c_probe(struct platform_device *dev)
{
struct simtec_i2c_data *pd;
struct resource *res;
int size;
int ret;
pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL);
if (pd == NULL) {
dev_err(&dev->dev, "cannot allocate private data\n");
return -ENOMEM;
}
platform_set_drvdata(dev, pd);
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&dev->dev, "cannot find IO resource\n");
ret = -ENOENT;
goto err;
}
size = (res->end-res->start)+1;
pd->ioarea = request_mem_region(res->start, size, dev->name);
if (pd->ioarea == NULL) {
dev_err(&dev->dev, "cannot request IO\n");
ret = -ENXIO;
goto err;
}
pd->reg = ioremap(res->start, size);
if (pd->reg == NULL) {
dev_err(&dev->dev, "cannot map IO\n");
ret = -ENXIO;
goto err_res;
}
/* setup the private data */
pd->adap.owner = THIS_MODULE;
pd->adap.algo_data = &pd->bit;
pd->adap.dev.parent = &dev->dev;
strlcpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name));
pd->bit.data = pd;
pd->bit.setsda = simtec_i2c_setsda;
pd->bit.setscl = simtec_i2c_setscl;
pd->bit.getsda = simtec_i2c_getsda;
pd->bit.getscl = simtec_i2c_getscl;
pd->bit.timeout = HZ;
pd->bit.udelay = 20;
ret = i2c_bit_add_bus(&pd->adap);
if (ret)
goto err_all;
return 0;
err_all:
iounmap(pd->reg);
err_res:
release_resource(pd->ioarea);
kfree(pd->ioarea);
err:
kfree(pd);
return ret;
}
static int simtec_i2c_remove(struct platform_device *dev)
{
struct simtec_i2c_data *pd = platform_get_drvdata(dev);
i2c_del_adapter(&pd->adap);
iounmap(pd->reg);
release_resource(pd->ioarea);
kfree(pd->ioarea);
kfree(pd);
return 0;
}
/* device driver */
static struct platform_driver simtec_i2c_driver = {
.driver = {
.name = "simtec-i2c",
.owner = THIS_MODULE,
},
.probe = simtec_i2c_probe,
.remove = simtec_i2c_remove,
};
static int __init i2c_adap_simtec_init(void)
{
return platform_driver_register(&simtec_i2c_driver);
}
static void __exit i2c_adap_simtec_exit(void)
{
platform_driver_unregister(&simtec_i2c_driver);
}
module_init(i2c_adap_simtec_init);
module_exit(i2c_adap_simtec_exit);
MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
......@@ -300,7 +300,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
/* set up the sysfs linkage to our parent device */
sis96x_adapter.dev.parent = &dev->dev;
snprintf(sis96x_adapter.name, I2C_NAME_SIZE,
snprintf(sis96x_adapter.name, sizeof(sis96x_adapter.name),
"SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
if ((retval = i2c_add_adapter(&sis96x_adapter))) {
......
/*
* driver for the i2c-tiny-usb adapter - 1.0
* http://www.harbaum.org/till/i2c_tiny_usb
*
* Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
*
* 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, version 2.
*
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
/* include interfaces to usb layer */
#include <linux/usb.h>
/* include interface to i2c layer */
#include <linux/i2c.h>
/* commands via USB, must match command ids in the firmware */
#define CMD_ECHO 0
#define CMD_GET_FUNC 1
#define CMD_SET_DELAY 2
#define CMD_GET_STATUS 3
#define CMD_I2C_IO 4
#define CMD_I2C_IO_BEGIN (1<<0)
#define CMD_I2C_IO_END (1<<1)
/* i2c bit delay, default is 10us -> 100kHz */
static int delay = 10;
module_param(delay, int, 0);
MODULE_PARM_DESC(delay, "bit delay in microseconds, "
"e.g. 10 for 100kHz (default is 100kHz)");
static int usb_read(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len);
static int usb_write(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len);
/* ----- begin of i2c layer ---------------------------------------------- */
#define STATUS_IDLE 0
#define STATUS_ADDRESS_ACK 1
#define STATUS_ADDRESS_NAK 2
static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
{
unsigned char status;
struct i2c_msg *pmsg;
int i;
dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
for (i = 0 ; i < num ; i++) {
int cmd = CMD_I2C_IO;
if (i == 0)
cmd |= CMD_I2C_IO_BEGIN;
if (i == num-1)
cmd |= CMD_I2C_IO_END;
pmsg = &msgs[i];
dev_dbg(&adapter->dev,
" %d: %s (flags %d) %d bytes to 0x%02x\n",
i, pmsg->flags & I2C_M_RD ? "read" : "write",
pmsg->flags, pmsg->len, pmsg->addr);
/* and directly send the message */
if (pmsg->flags & I2C_M_RD) {
/* read data */
if (usb_read(adapter, cmd,
pmsg->flags, pmsg->addr,
pmsg->buf, pmsg->len) != pmsg->len) {
dev_err(&adapter->dev,
"failure reading data\n");
return -EREMOTEIO;
}
} else {
/* write data */
if (usb_write(adapter, cmd,
pmsg->flags, pmsg->addr,
pmsg->buf, pmsg->len) != pmsg->len) {
dev_err(&adapter->dev,
"failure writing data\n");
return -EREMOTEIO;
}
}
/* read status */
if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) {
dev_err(&adapter->dev, "failure reading status\n");
return -EREMOTEIO;
}
dev_dbg(&adapter->dev, " status = %d\n", status);
if (status == STATUS_ADDRESS_NAK)
return -EREMOTEIO;
}
return i;
}
static u32 usb_func(struct i2c_adapter *adapter)
{
u32 func;
/* get functionality from adapter */
if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
sizeof(func)) {
dev_err(&adapter->dev, "failure reading functionality\n");
return 0;
}
return func;
}
/* This is the actual algorithm we define */
static const struct i2c_algorithm usb_algorithm = {
.master_xfer = usb_xfer,
.functionality = usb_func,
};
/* ----- end of i2c layer ------------------------------------------------ */
/* ----- begin of usb layer ---------------------------------------------- */
/* The usb i2c interface uses a vid/pid pair donated by */
/* Future Technology Devices International Ltd. */
static struct usb_device_id i2c_tiny_usb_table [] = {
{ USB_DEVICE(0x0403, 0xc631) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table);
/* Structure to hold all of our device specific stuff */
struct i2c_tiny_usb {
struct usb_device *usb_dev; /* the usb device for this device */
struct usb_interface *interface; /* the interface for this device */
struct i2c_adapter adapter; /* i2c related things */
};
static int usb_read(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
/* do control transfer */
return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
USB_DIR_IN, value, index, data, len, 2000);
}
static int usb_write(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
/* do control transfer */
return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, index, data, len, 2000);
}
static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
{
usb_put_dev(dev->usb_dev);
kfree(dev);
}
static int i2c_tiny_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct i2c_tiny_usb *dev;
int retval = -ENOMEM;
u16 version;
dev_dbg(&interface->dev, "probing usb device\n");
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&interface->dev, "Out of memory\n");
goto error;
}
dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface;
/* save our data pointer in this interface device */
usb_set_intfdata(interface, dev);
version = le16_to_cpu(dev->usb_dev->descriptor.bcdDevice);
dev_info(&interface->dev,
"version %x.%02x found at bus %03d address %03d\n",
version >> 8, version & 0xff,
dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
/* setup i2c adapter description */
dev->adapter.owner = THIS_MODULE;
dev->adapter.class = I2C_CLASS_HWMON;
dev->adapter.algo = &usb_algorithm;
dev->adapter.algo_data = dev;
snprintf(dev->adapter.name, I2C_NAME_SIZE,
"i2c-tiny-usb at bus %03d device %03d",
dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
if (usb_write(&dev->adapter, CMD_SET_DELAY,
cpu_to_le16(delay), 0, NULL, 0) != 0) {
dev_err(&dev->adapter.dev,
"failure setting delay to %dus\n", delay);
retval = -EIO;
goto error;
}
dev->adapter.dev.parent = &dev->interface->dev;
/* and finally attach to i2c layer */
i2c_add_adapter(&dev->adapter);
/* inform user about successful attachment to i2c layer */
dev_info(&dev->adapter.dev, "connected i2c-tiny-usb device\n");
return 0;
error:
if (dev)
i2c_tiny_usb_free(dev);
return retval;
}
static void i2c_tiny_usb_disconnect(struct usb_interface *interface)
{
struct i2c_tiny_usb *dev = usb_get_intfdata(interface);
i2c_del_adapter(&dev->adapter);
usb_set_intfdata(interface, NULL);
i2c_tiny_usb_free(dev);
dev_dbg(&interface->dev, "disconnected\n");
}
static struct usb_driver i2c_tiny_usb_driver = {
.name = "i2c-tiny-usb",
.probe = i2c_tiny_usb_probe,
.disconnect = i2c_tiny_usb_disconnect,
.id_table = i2c_tiny_usb_table,
};
static int __init usb_i2c_tiny_usb_init(void)
{
/* register this driver with the USB subsystem */
return usb_register(&i2c_tiny_usb_driver);
}
static void __exit usb_i2c_tiny_usb_exit(void)
{
/* deregister this driver with the USB subsystem */
usb_deregister(&i2c_tiny_usb_driver);
}
module_init(usb_i2c_tiny_usb_init);
module_exit(usb_i2c_tiny_usb_exit);
/* ----- end of usb layer ------------------------------------------------ */
MODULE_AUTHOR("Till Harbaum <Till@Harbaum.org>");
MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0");
MODULE_LICENSE("GPL");
......@@ -404,7 +404,7 @@ found:
}
vt596_adapter.dev.parent = &pdev->dev;
snprintf(vt596_adapter.name, I2C_NAME_SIZE,
snprintf(vt596_adapter.name, sizeof(vt596_adapter.name),
"SMBus Via Pro adapter at %04x", vt596_smba);
vt596_pdev = pci_dev_get(pdev);
......
......@@ -441,7 +441,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
adapter = &iface->adapter;
i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index);
snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
adapter->owner = THIS_MODULE;
adapter->id = I2C_HW_SMBUS_SCX200;
adapter->algo = &scx200_acb_algorithm;
......@@ -599,6 +599,7 @@ static __init int scx200_scan_pci(void)
else {
int i;
pci_dev_put(pdev);
for (i = 0; i < MAX_DEVICES; ++i) {
if (base[i] == 0)
continue;
......
......@@ -3,11 +3,10 @@
#
menu "Miscellaneous I2C Chip support"
depends on I2C
config SENSORS_DS1337
tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
help
If you say yes here you get support for Dallas Semiconductor
DS1337 and DS1339 real-time clock chips.
......@@ -17,7 +16,7 @@ config SENSORS_DS1337
config SENSORS_DS1374
tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
help
If you say yes here you get support for Dallas Semiconductor
DS1374 real-time clock chips.
......@@ -27,7 +26,7 @@ config SENSORS_DS1374
config SENSORS_EEPROM
tristate "EEPROM reader"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
help
If you say yes here you get read-only access to the EEPROM data
available on modern memory DIMMs and Sony Vaio laptops. Such
......@@ -38,7 +37,7 @@ config SENSORS_EEPROM
config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
default n
help
If you say yes here you get support for Philips PCF8574 and
......@@ -52,7 +51,7 @@ config SENSORS_PCF8574
config SENSORS_PCA9539
tristate "Philips PCA9539 16-bit I/O port"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
help
If you say yes here you get support for the Philips PCA9539
16-bit I/O port.
......@@ -62,7 +61,7 @@ config SENSORS_PCA9539
config SENSORS_PCF8591
tristate "Philips PCF8591"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
default n
help
If you say yes here you get support for Philips PCF8591 chips.
......@@ -75,7 +74,7 @@ config SENSORS_PCF8591
config ISP1301_OMAP
tristate "Philips ISP1301 with OMAP OTG"
depends on I2C && ARCH_OMAP_OTG
depends on ARCH_OMAP_OTG
help
If you say yes here you get support for the Philips ISP1301
USB-On-The-Go transceiver working with the OMAP OTG controller.
......@@ -90,7 +89,7 @@ config ISP1301_OMAP
# and having mostly OMAP-specific board support
config TPS65010
tristate "TPS6501x Power Management chips"
depends on I2C && ARCH_OMAP
depends on ARCH_OMAP
default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
help
If you say yes here you get support for the TPS6501x series of
......@@ -103,7 +102,7 @@ config TPS65010
config SENSORS_M41T00
tristate "ST M41T00 RTC chip"
depends on I2C && PPC32
depends on PPC32
help
If you say yes here you get support for the ST M41T00 RTC chip.
......@@ -112,7 +111,7 @@ config SENSORS_M41T00
config SENSORS_MAX6875
tristate "Maxim MAX6875 Power supply supervisor"
depends on I2C && EXPERIMENTAL
depends on EXPERIMENTAL
help
If you say yes here you get support for the Maxim MAX6875
EEPROM-programmable, quad power-supply sequencer/supervisor.
......
/*
* i2c-boardinfo.h - collect pre-declarations of I2C devices
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/i2c.h>
#include "i2c-core.h"
/* These symbols are exported ONLY FOR the i2c core.
* No other users will be supported.
*/
DEFINE_MUTEX(__i2c_board_lock);
EXPORT_SYMBOL_GPL(__i2c_board_lock);
LIST_HEAD(__i2c_board_list);
EXPORT_SYMBOL_GPL(__i2c_board_list);
int __i2c_first_dynamic_bus_num;
EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
/**
* i2c_register_board_info - statically declare I2C devices
* @busnum: identifies the bus to which these devices belong
* @info: vector of i2c device descriptors
* @len: how many descriptors in the vector; may be zero to reserve
* the specified bus number.
*
* Systems using the Linux I2C driver stack can declare tables of board info
* while they initialize. This should be done in board-specific init code
* near arch_initcall() time, or equivalent, before any I2C adapter driver is
* registered. For example, mainboard init code could define several devices,
* as could the init code for each daughtercard in a board stack.
*
* The I2C devices will be created later, after the adapter for the relevant
* bus has been registered. After that moment, standard driver model tools
* are used to bind "new style" I2C drivers to the devices. The bus number
* for any device declared using this routine is not available for dynamic
* allocation.
*
* The board info passed can safely be __initdata, but be careful of embedded
* pointers (for platform_data, functions, etc) since that won't be copied.
*/
int __init
i2c_register_board_info(int busnum,
struct i2c_board_info const *info, unsigned len)
{
int status;
mutex_lock(&__i2c_board_lock);
/* dynamic bus numbers will be assigned after the last static one */
if (busnum >= __i2c_first_dynamic_bus_num)
__i2c_first_dynamic_bus_num = busnum + 1;
for (status = 0; len; len--, info++) {
struct i2c_devinfo *devinfo;
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
if (!devinfo) {
pr_debug("i2c-core: can't register boardinfo!\n");
status = -ENOMEM;
break;
}
devinfo->busnum = busnum;
devinfo->board_info = *info;
list_add_tail(&devinfo->list, &__i2c_board_list);
}
mutex_unlock(&__i2c_board_lock);
return status;
}
This diff is collapsed.
/*
* i2c-core.h - interfaces internal to the I2C framework
*
* 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.
*/
struct i2c_devinfo {
struct list_head list;
int busnum;
struct i2c_board_info board_info;
};
/* board_lock protects board_list and first_dynamic_bus_num.
* only i2c core components are allowed to use these symbols.
*/
extern struct mutex __i2c_board_lock;
extern struct list_head __i2c_board_list;
extern int __i2c_first_dynamic_bus_num;
......@@ -459,7 +459,8 @@ therm_of_probe( struct of_device *dev, const struct of_device_id *match )
static int
therm_of_remove( struct of_device *dev )
{
return i2c_del_driver( &g4fan_driver );
i2c_del_driver( &g4fan_driver );
return 0;
}
static struct of_device_id therm_of_match[] = {{
......
......@@ -183,7 +183,8 @@ int flexcop_i2c_init(struct flexcop_device *fc)
mutex_init(&fc->i2c_mutex);
memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",
sizeof(fc->i2c_adap.name));
i2c_set_adapdata(&fc->i2c_adap,fc);
......
......@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
return -EINVAL;
}
strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
#else
......
......@@ -105,9 +105,9 @@ struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enu
}
EXPORT_SYMBOL(dibx000_get_i2c_adapter);
static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst)
static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst)
{
strncpy(i2c_adap->name, name, I2C_NAME_SIZE);
strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
i2c_adap->class = I2C_CLASS_TV_DIGITAL,
i2c_adap->algo = algo;
i2c_adap->algo_data = NULL;
......
......@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/tuner.h>
#include <media/cx2341x.h>
......
......@@ -15,6 +15,7 @@
#ifndef __LINUX_OVCAMCHIP_PRIV_H
#define __LINUX_OVCAMCHIP_PRIV_H
#include <linux/i2c.h>
#include <media/ovcamchip.h>
#ifdef DEBUG
......
......@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/i2c.h>
#include <media/v4l2-dev.h>
#include <media/tuner.h>
#include "usbvision.h"
......
......@@ -104,7 +104,8 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
chan->dinfo = dinfo;
chan->reg = reg;
snprintf(chan->adapter.name, I2C_NAME_SIZE, "intelfb %s", name);
snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"intelfb %s", name);
chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
......
......@@ -111,7 +111,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
b->mask.data = data;
b->mask.clock = clock;
b->adapter = matrox_i2c_adapter_template;
snprintf(b->adapter.name, I2C_NAME_SIZE, name,
snprintf(b->adapter.name, sizeof(b->adapter.name), name,
minfo->fbcon.node);
i2c_set_adapdata(&b->adapter, b);
b->adapter.algo_data = &b->bac;
......
......@@ -38,11 +38,14 @@ struct i2c_algo_bit_data {
int (*getscl) (void *data);
/* local settings */
int udelay; /* half-clock-cycle time in microsecs */
/* i.e. clock is (500 / udelay) KHz */
int udelay; /* half clock cycle time in us,
minimum 2 us for fast-mode I2C,
minimum 5 us for standard-mode I2C and SMBus,
maximum 50 us for SMBus */
int timeout; /* in jiffies */
};
int i2c_bit_add_bus(struct i2c_adapter *);
int i2c_bit_add_numbered_bus(struct i2c_adapter *);
#endif /* _LINUX_I2C_ALGO_BIT_H */
/*
* i2c-gpio interface to platform code
*
* Copyright (C) 2007 Atmel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _LINUX_I2C_GPIO_H
#define _LINUX_I2C_GPIO_H
/**
* struct i2c_gpio_platform_data - Platform-dependent data for i2c-gpio
* @sda_pin: GPIO pin ID to use for SDA
* @scl_pin: GPIO pin ID to use for SCL
* @udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
* @timeout: clock stretching timeout in jiffies. If the slave keeps
* SCL low for longer than this, the transfer will time out.
* @sda_is_open_drain: SDA is configured as open drain, i.e. the pin
* isn't actively driven high when setting the output value high.
* gpio_get_value() must return the actual pin state even if the
* pin is configured as an output.
* @scl_is_open_drain: SCL is set up as open drain. Same requirements
* as for sda_is_open_drain apply.
* @scl_is_output_only: SCL output drivers cannot be turned off.
*/
struct i2c_gpio_platform_data {
unsigned int sda_pin;
unsigned int scl_pin;
int udelay;
int timeout;
unsigned int sda_is_open_drain:1;
unsigned int scl_is_open_drain:1;
unsigned int scl_is_output_only:1;
};
#endif /* _LINUX_I2C_GPIO_H */
......@@ -258,8 +258,9 @@
/* --- MCP107 adapter */
#define I2C_HW_MPC107 0x0d0000
/* --- Marvell mv64xxx i2c adapter */
/* --- Embedded adapters */
#define I2C_HW_MV64XXX 0x190000
#define I2C_HW_BLACKFIN 0x190001 /* ADI Blackfin I2C TWI driver */
/* --- Miscellaneous adapters */
#define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */
......
......@@ -35,11 +35,6 @@
#include <linux/sched.h> /* for completion */
#include <linux/mutex.h>
/* --- For i2c-isa ---------------------------------------------------- */
extern void i2c_adapter_dev_release(struct device *dev);
extern struct device_driver i2c_adapter_driver;
extern struct class i2c_adapter_class;
extern struct bus_type i2c_bus_type;
/* --- General options ------------------------------------------------ */
......@@ -87,6 +82,9 @@ extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value);
/* Returns the number of read bytes */
extern s32 i2c_smbus_read_block_data(struct i2c_client *client,
u8 command, u8 *values);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length,
const u8 *values);
......@@ -114,7 +112,7 @@ struct i2c_driver {
* can be used by the driver to test if the bus meets its conditions
* & seek for the presence of the chip(s) it supports. If found, it
* registers the client(s) that are on the bus to the i2c admin. via
* i2c_attach_client.
* i2c_attach_client. (LEGACY I2C DRIVERS ONLY)
*/
int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *);
......@@ -122,10 +120,17 @@ struct i2c_driver {
/* tells the driver that a client is about to be deleted & gives it
* the chance to remove its private data. Also, if the client struct
* has been dynamically allocated by the driver in the function above,
* it must be freed here.
* it must be freed here. (LEGACY I2C DRIVERS ONLY)
*/
int (*detach_client)(struct i2c_client *);
/* Standard driver model interfaces, for "new style" i2c drivers.
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
int (*probe)(struct i2c_client *);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t mesg);
......@@ -141,25 +146,34 @@ struct i2c_driver {
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
#define I2C_NAME_SIZE 50
#define I2C_NAME_SIZE 20
/*
* i2c_client identifies a single device (i.e. chip) that is connected to an
* i2c bus. The behaviour is defined by the routines of the driver. This
* function is mainly used for lookup & other admin. functions.
/**
* struct i2c_client - represent an I2C slave device
* @addr: Address used on the I2C bus connected to the parent adapter.
* @name: Indicates the type of the device, usually a chip name that's
* generic enough to hide second-sourcing and compatible revisions.
* @dev: Driver model device node for the slave.
* @driver_name: Identifies new-style driver used with this device; also
* used as the module name for hotplug/coldplug modprobe support.
*
* An i2c_client identifies a single device (i.e. chip) connected to an
* i2c bus. The behaviour is defined by the routines of the driver.
*/
struct i2c_client {
unsigned int flags; /* div., see below */
unsigned short flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */
/* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
int usage_count; /* How many accesses currently */
/* to the client */
struct device dev; /* the device structure */
int irq; /* irq issued by device (or -1) */
char driver_name[KOBJ_NAME_LEN];
struct list_head list;
char name[I2C_NAME_SIZE];
struct completion released;
};
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
......@@ -179,6 +193,76 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
dev_set_drvdata (&dev->dev, data);
}
/**
* struct i2c_board_info - template for device creation
* @driver_name: identifies the driver to be bound to the device
* @type: optional chip type information, to initialize i2c_client.name
* @flags: to initialize i2c_client.flags
* @addr: stored in i2c_client.addr
* @platform_data: stored in i2c_client.dev.platform_data
* @irq: stored in i2c_client.irq
* I2C doesn't actually support hardware probing, although controllers and
* devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
* a device at a given address. Drivers commonly need more information than
* that, such as chip type, configuration, associated IRQ, and so on.
*
* i2c_board_info is used to build tables of information listing I2C devices
* that are present. This information is used to grow the driver model tree
* for "new style" I2C drivers. For mainboards this is done statically using
* i2c_register_board_info(), where @bus_num represents an adapter that isn't
* yet available. For add-on boards, i2c_new_device() does this dynamically
* with the adapter already known.
*/
struct i2c_board_info {
char driver_name[KOBJ_NAME_LEN];
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
void *platform_data;
int irq;
};
/**
* I2C_BOARD_INFO - macro used to list an i2c device and its driver
* @driver: identifies the driver to use with the device
* @dev_addr: the device's address on the bus.
*
* This macro initializes essential fields of a struct i2c_board_info,
* declaring what has been provided on a particular board. Optional
* fields (such as the chip type, its associated irq, or device-specific
* platform_data) are provided using conventional syntax.
*/
#define I2C_BOARD_INFO(driver,dev_addr) \
.driver_name = (driver), .addr = (dev_addr)
/* Add-on boards should register/unregister their devices; e.g. a board
* with integrated I2C, a config eeprom, sensors, and a codec that's
* used in conjunction with the primary hardware.
*/
extern struct i2c_client *
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
/* If you don't know the exact address of an I2C device, use this variant
* instead, which can probe for device presence in a list of possible
* addresses.
*/
extern struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
unsigned short const *addr_list);
extern void i2c_unregister_device(struct i2c_client *);
/* Mainboard arch_initcall() code should register all its I2C devices.
* This is done at arch_initcall time, before declaring any i2c adapters.
* Modules for add-on boards must use other calls.
*/
extern int
i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);
/*
* The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can
......@@ -228,17 +312,14 @@ struct i2c_adapter {
int timeout;
int retries;
struct device dev; /* the adapter device */
struct class_device class_dev; /* the class device */
int nr;
struct list_head clients;
struct list_head list;
char name[I2C_NAME_SIZE];
char name[48];
struct completion dev_released;
struct completion class_dev_released;
};
#define dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
#define class_dev_to_i2c_adapter(d) container_of(d, struct i2c_adapter, class_dev)
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
{
......@@ -290,9 +371,10 @@ struct i2c_client_address_data {
*/
extern int i2c_add_adapter(struct i2c_adapter *);
extern int i2c_del_adapter(struct i2c_adapter *);
extern int i2c_add_numbered_adapter(struct i2c_adapter *);
extern int i2c_register_driver(struct module *, struct i2c_driver *);
extern int i2c_del_driver(struct i2c_driver *);
extern void i2c_del_driver(struct i2c_driver *);
static inline int i2c_add_driver(struct i2c_driver *driver)
{
......@@ -365,6 +447,7 @@ struct i2c_msg {
#define I2C_M_REV_DIR_ADDR 0x2000
#define I2C_M_IGNORE_NAK 0x1000
#define I2C_M_NO_RD_ACK 0x0800
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
......
......@@ -1213,11 +1213,13 @@
#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5
#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS 0x03EB
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC
#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE
#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS 0x0446
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448
#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450
#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451
......
......@@ -16,7 +16,6 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/i2c.h>
/* --------------------------------- */
/* ENUMERATIONS */
......
......@@ -23,6 +23,7 @@
#define _TUNER_H
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/tuner-types.h>
extern int tuner_debug;
......
#ifndef _TAS_IOCTL_H_
#define _TAS_IOCTL_H_
#include <linux/i2c.h>
#include <linux/soundcard.h>
......
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