提交 c3a416a6 编写于 作者: L Linus Torvalds

Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "Most notable:

   - introducing the i2c_quirk infrastructure.  Now, flaws of I2C
     controllers can be described and the core will check if the flaws
     collide with the messages to be sent

   - wait_for_completion return type cleanup series

   - new drivers for Digicolor, Netlogic XLP, Ingenic JZ4780

   - updates to the I2C slave framework which include API changes.  Its
     only user was updated, too.  Documentation was finally added

   - changed dynamic bus numbering for the DT case.  This could change
     bus numbers for users.  However, it fixes a collision where dynamic
     and static busses request the same id.

   - driver bugfixes, cleanups"

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (52 commits)
  i2c: xlp9xx: Driver for Netlogic XLP9XX/5XX I2C controller
  of: Add vendor prefix 'netlogic'
  i2c: davinci: use ICPFUNC to toggle I2C as gpio for bus recovery
  i2c: davinci: use bus recovery infrastructure
  i2c: change input parameter to i2c_adapter for prepare/unprepare_recovery
  i2c: i2c-mux-gpio: remove error messages for probe deferrals
  i2c: jz4780: Add i2c bus controller driver for Ingenic JZ4780
  i2c: dln2: set the device tree node of the adapter
  i2c: davinci: fixup wait_for_completion_timeout handling
  i2c: mpc: Fix ISR return value
  i2c: slave-eeprom: add more info when to increase the pointer
  i2c: slave: add documentation for i2c-slave-eeprom
  Documentation: i2c: describe the new slave mode
  i2c: slave: rework the slave API
  i2c: add support for the Digicolor I2C controller
  i2c: busses with dynamic ids should start after fixed ids for DT
  of: base: add function to get highest id of an alias stem
  i2c: designware: Suppress error message if platform_get_irq() < 0
  i2c: mpc: assign the correct prescaler from SVR
  i2c: img-scb: fixup of wait_for_completion_timeout return handling
  ...
...@@ -10,6 +10,9 @@ Required properties: ...@@ -10,6 +10,9 @@ Required properties:
Recommended properties : Recommended properties :
- interrupts : standard interrupt property. - interrupts : standard interrupt property.
- clock-frequency : desired I2C bus clock frequency in Hz. - clock-frequency : desired I2C bus clock frequency in Hz.
- ti,has-pfunc: boolean; if defined, it indicates that SoC supports PFUNC
registers. PFUNC registers allow to switch I2C pins to function as
GPIOs, so they can by toggled manually.
Example (enbw_cmc board): Example (enbw_cmc board):
i2c@1c22000 { i2c@1c22000 {
......
Conexant Digicolor I2C controller
Required properties:
- compatible: must be "cnxt,cx92755-i2c"
- reg: physical address and length of the device registers
- interrupts: a single interrupt specifier
- clocks: clock for the device
- #address-cells: should be <1>
- #size-cells: should be <0>
Optional properties:
- clock-frequency: the desired I2C bus clock frequency in Hz; in
absence of this property the default value is used (100 kHz).
Example:
i2c: i2c@f0000120 {
compatible = "cnxt,cx92755-i2c";
reg = <0xf0000120 0x10>;
interrupts = <28>;
clocks = <&main_clk>;
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
};
* Ingenic JZ4780 I2C Bus controller
Required properties:
- compatible: should be "ingenic,jz4780-i2c"
- reg: Should contain the address & size of the I2C controller registers.
- interrupts: Should specify the interrupt provided by parent.
- clocks: Should contain a single clock specifier for the JZ4780 I2C clock.
- clock-frequency: desired I2C bus clock frequency in Hz.
Recommended properties:
- pinctrl-names: should be "default";
- pinctrl-0: phandle to pinctrl function
Optional properties:
- interrupt-parent: Should be the phandle of the interrupt controller that
delivers interrupts to the I2C block.
Example
/ {
i2c4: i2c4@0x10054000 {
compatible = "ingenic,jz4780-i2c";
reg = <0x10054000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <56>;
clocks = <&cgu JZ4780_CLK_SMB4>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pins_i2c4_data>;
};
};
Device tree configuration for the I2C controller on the XLP9xx/5xx SoC
Required properties:
- compatible : should be "netlogic,xlp980-i2c"
- reg : bus address start and address range size of device
- interrupts : interrupt number
Optional properties:
- clock-frequency : frequency of bus clock in Hz
Defaults to 100 KHz when the property is not specified
Example:
i2c0: i2c@113100 {
compatible = "netlogic,xlp980-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0x113100 0x100>;
clock-frequency = <400000>;
interrupts = <30>;
interrupt-parent = <&pic>;
};
...@@ -125,6 +125,7 @@ mxicy Macronix International Co., Ltd. ...@@ -125,6 +125,7 @@ mxicy Macronix International Co., Ltd.
national National Semiconductor national National Semiconductor
neonode Neonode Inc. neonode Neonode Inc.
netgear NETGEAR netgear NETGEAR
netlogic Broadcom Corporation (formerly NetLogic Microsystems)
newhaven Newhaven Display International newhaven Newhaven Display International
nintendo Nintendo nintendo Nintendo
nokia Nokia nokia Nokia
......
Linux I2C slave eeprom backend
==============================
by Wolfram Sang <wsa@sang-engineering.com> in 2014-15
This is a proof-of-concept backend which acts like an EEPROM on the connected
I2C bus. The memory contents can be modified from userspace via this file
located in sysfs:
/sys/bus/i2c/devices/<device-direcory>/slave-eeprom
As of 2015, Linux doesn't support poll on binary sysfs files, so there is no
notfication when another master changed the content.
Linux I2C slave interface description
=====================================
by Wolfram Sang <wsa@sang-engineering.com> in 2014-15
Linux can also be an I2C slave in case I2C controllers have slave support.
Besides this HW requirement, one also needs a software backend providing the
actual functionality. An example for this is the slave-eeprom driver, which
acts as a dual memory driver. While another I2C master on the bus can access it
like a regular EEPROM, the Linux I2C slave can access the content via sysfs and
retrieve/provide information as needed. The software backend driver and the I2C
bus driver communicate via events. Here is a small graph visualizing the data
flow and the means by which data is transported. The dotted line marks only one
example. The backend could also use e.g. a character device, be in-kernel
only, or something completely different:
e.g. sysfs I2C slave events I/O registers
+-----------+ v +---------+ v +--------+ v +------------+
| Userspace +........+ Backend +-----------+ Driver +-----+ Controller |
+-----------+ +---------+ +--------+ +------------+
| |
----------------------------------------------------------------+-- I2C
--------------------------------------------------------------+---- Bus
Note: Technically, there is also the I2C core between the backend and the
driver. However, at this time of writing, the layer is transparent.
User manual
===========
I2C slave backends behave like standard I2C clients. So, you can instantiate
them like described in the document 'instantiating-devices'. A quick example
for instantiating the slave-eeprom driver from userspace:
# echo 0-0064 > /sys/bus/i2c/drivers/i2c-slave-eeprom/bind
Each backend should come with separate documentation to describe its specific
behaviour and setup.
Developer manual
================
I2C slave events
----------------
The bus driver sends an event to the backend using the following function:
ret = i2c_slave_event(client, event, &val)
'client' describes the i2c slave device. 'event' is one of the special event
types described hereafter. 'val' holds an u8 value for the data byte to be
read/written and is thus bidirectional. The pointer to val must always be
provided even if val is not used for an event, i.e. don't use NULL here. 'ret'
is the return value from the backend. Mandatory events must be provided by the
bus drivers and must be checked for by backend drivers.
Event types:
* I2C_SLAVE_WRITE_REQUESTED (mandatory)
'val': unused
'ret': always 0
Another I2C master wants to write data to us. This event should be sent once
our own address and the write bit was detected. The data did not arrive yet, so
there is nothing to process or return. Wakeup or initialization probably needs
to be done, though.
* I2C_SLAVE_READ_REQUESTED (mandatory)
'val': backend returns first byte to be sent
'ret': always 0
Another I2C master wants to read data from us. This event should be sent once
our own address and the read bit was detected. After returning, the bus driver
should transmit the first byte.
* I2C_SLAVE_WRITE_RECEIVED (mandatory)
'val': bus driver delivers received byte
'ret': 0 if the byte should be acked, some errno if the byte should be nacked
Another I2C master has sent a byte to us which needs to be set in 'val'. If 'ret'
is zero, the bus driver should ack this byte. If 'ret' is an errno, then the byte
should be nacked.
* I2C_SLAVE_READ_PROCESSED (mandatory)
'val': backend returns next byte to be sent
'ret': always 0
The bus driver requests the next byte to be sent to another I2C master in
'val'. Important: This does not mean that the previous byte has been acked, it
only means that the previous byte is shifted out to the bus! To ensure seamless
transmission, most hardware requests the next byte when the previous one is
still shifted out. If the master sends NACK and stops reading after the byte
currently shifted out, this byte requested here is never used. It very likely
needs to be sent again on the next I2C_SLAVE_READ_REQUEST, depending a bit on
your backend, though.
* I2C_SLAVE_STOP (mandatory)
'val': unused
'ret': always 0
A stop condition was received. This can happen anytime and the backend should
reset its state machine for I2C transfers to be able to receive new requests.
Software backends
-----------------
If you want to write a software backend:
* use a standard i2c_driver and its matching mechanisms
* write the slave_callback which handles the above slave events
(best using a state machine)
* register this callback via i2c_slave_register()
Check the i2c-slave-eeprom driver as an example.
Bus driver support
------------------
If you want to add slave support to the bus driver:
* implement calls to register/unregister the slave and add those to the
struct i2c_algorithm. When registering, you probably need to set the i2c
slave address and enable slave specific interrupts. If you use runtime pm, you
should use pm_runtime_forbid() because your device usually needs to be powered
on always to be able to detect its slave address. When unregistering, do the
inverse of the above.
* Catch the slave interrupts and send appropriate i2c_slave_events to the backend.
Check the i2c-rcar driver as an example.
About ACK/NACK
--------------
It is good behaviour to always ACK the address phase, so the master knows if a
device is basically present or if it mysteriously disappeared. Using NACK to
state being busy is troublesome. SMBus demands to always ACK the address phase,
while the I2C specification is more loose on that. Most I2C controllers also
automatically ACK when detecting their slave addresses, so there is no option
to NACK them. For those reasons, this API does not support NACK in the address
phase.
Currently, there is no slave event to report if the master did ACK or NACK a
byte when it reads from us. We could make this an optional event if the need
arises. However, cases should be extremely rare because the master is expected
to send STOP after that and we have an event for that. Also, keep in mind not
all I2C controllers have the possibility to report that event.
About buffers
-------------
During development of this API, the question of using buffers instead of just
bytes came up. Such an extension might be possible, usefulness is unclear at
this time of writing. Some points to keep in mind when using buffers:
* Buffers should be opt-in and slave drivers will always have to support
byte-based transactions as the ultimate fallback because this is how the
majority of HW works.
* For backends simulating hardware registers, buffers are not helpful because
on writes an action should be immediately triggered. For reads, the data in
the buffer might get stale.
* A master can send STOP at any time. For partially transferred buffers, this
means additional code to handle this exception. Such code tends to be
error-prone.
...@@ -41,7 +41,3 @@ integrated than Algorithm and Adapter. ...@@ -41,7 +41,3 @@ integrated than Algorithm and Adapter.
For a given configuration, you will need a driver for your I2C bus, and For a given configuration, you will need a driver for your I2C bus, and
drivers for your I2C devices (usually one driver for each device). drivers for your I2C devices (usually one driver for each device).
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.
...@@ -485,6 +485,15 @@ config I2C_DESIGNWARE_BAYTRAIL ...@@ -485,6 +485,15 @@ config I2C_DESIGNWARE_BAYTRAIL
the platform firmware controlling it. You should say Y if running on the platform firmware controlling it. You should say Y if running on
a BayTrail system using the AXP288. a BayTrail system using the AXP288.
config I2C_DIGICOLOR
tristate "Conexant Digicolor I2C driver"
depends on ARCH_DIGICOLOR
help
Support for Conexant Digicolor SoCs (CX92755) I2C controller driver.
This driver can also be built as a module. If so, the module
will be called i2c-digicolor.
config I2C_EFM32 config I2C_EFM32
tristate "EFM32 I2C controller" tristate "EFM32 I2C controller"
depends on ARCH_EFM32 || COMPILE_TEST depends on ARCH_EFM32 || COMPILE_TEST
...@@ -574,6 +583,15 @@ config I2C_IOP3XX ...@@ -574,6 +583,15 @@ config I2C_IOP3XX
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-iop3xx. will be called i2c-iop3xx.
config I2C_JZ4780
tristate "JZ4780 I2C controller interface support"
depends on MACH_JZ4780 || COMPILE_TEST
help
If you say yes to this option, support will be included for the
Ingenic JZ4780 I2C controller.
If you don't know what to do here, say N.
config I2C_KEMPLD config I2C_KEMPLD
tristate "Kontron COM I2C Controller" tristate "Kontron COM I2C Controller"
depends on MFD_KEMPLD depends on MFD_KEMPLD
...@@ -898,6 +916,16 @@ config I2C_XLR ...@@ -898,6 +916,16 @@ config I2C_XLR
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-xlr. will be called i2c-xlr.
config I2C_XLP9XX
tristate "XLP9XX I2C support"
depends on CPU_XLP || COMPILE_TEST
help
This driver enables support for the on-chip I2C interface of
the Broadcom XLP9xx/XLP5xx MIPS processors.
This driver can also be built as a module. If so, the module will
be called i2c-xlp9xx.
config I2C_RCAR config I2C_RCAR
tristate "Renesas R-Car I2C Controller" tristate "Renesas R-Car I2C Controller"
depends on ARCH_SHMOBILE || COMPILE_TEST depends on ARCH_SHMOBILE || COMPILE_TEST
......
...@@ -45,6 +45,7 @@ i2c-designware-platform-objs := i2c-designware-platdrv.o ...@@ -45,6 +45,7 @@ i2c-designware-platform-objs := i2c-designware-platdrv.o
i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o
obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-pci-objs := i2c-designware-pcidrv.o
obj-$(CONFIG_I2C_DIGICOLOR) += i2c-digicolor.o
obj-$(CONFIG_I2C_EFM32) += i2c-efm32.o obj-$(CONFIG_I2C_EFM32) += i2c-efm32.o
obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o
...@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o ...@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o
obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
obj-$(CONFIG_I2C_MESON) += i2c-meson.o obj-$(CONFIG_I2C_MESON) += i2c-meson.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
...@@ -87,6 +89,7 @@ obj-$(CONFIG_I2C_WMT) += i2c-wmt.o ...@@ -87,6 +89,7 @@ obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
obj-$(CONFIG_I2C_XLR) += i2c-xlr.o obj-$(CONFIG_I2C_XLR) += i2c-xlr.o
obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o
obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
# External I2C/SMBus adapter drivers # External I2C/SMBus adapter drivers
......
...@@ -381,6 +381,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id) ...@@ -381,6 +381,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
static int at91_do_twi_transfer(struct at91_twi_dev *dev) static int at91_do_twi_transfer(struct at91_twi_dev *dev)
{ {
int ret; int ret;
unsigned long time_left;
bool has_unre_flag = dev->pdata->has_unre_flag; bool has_unre_flag = dev->pdata->has_unre_flag;
dev_dbg(dev->dev, "transfer: %s %d bytes.\n", dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
...@@ -436,9 +437,9 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) ...@@ -436,9 +437,9 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
} }
} }
ret = wait_for_completion_timeout(&dev->cmd_complete, time_left = wait_for_completion_timeout(&dev->cmd_complete,
dev->adapter.timeout); dev->adapter.timeout);
if (ret == 0) { if (time_left == 0) {
dev_err(dev->dev, "controller timed out\n"); dev_err(dev->dev, "controller timed out\n");
at91_init_twi_bus(dev); at91_init_twi_bus(dev);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
...@@ -487,30 +488,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) ...@@ -487,30 +488,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
if (ret < 0) if (ret < 0)
goto out; goto out;
/* if (num == 2) {
* The hardware can handle at most two messages concatenated by a
* repeated start via it's internal address feature.
*/
if (num > 2) {
dev_err(dev->dev,
"cannot handle more than two concatenated messages.\n");
ret = 0;
goto out;
} else if (num == 2) {
int internal_address = 0; int internal_address = 0;
int i; int i;
if (msg->flags & I2C_M_RD) {
dev_err(dev->dev, "first transfer must be write.\n");
ret = -EINVAL;
goto out;
}
if (msg->len > 3) {
dev_err(dev->dev, "first message size must be <= 3.\n");
ret = -EINVAL;
goto out;
}
/* 1st msg is put into the internal address, start with 2nd */ /* 1st msg is put into the internal address, start with 2nd */
m_start = &msg[1]; m_start = &msg[1];
for (i = 0; i < msg->len; ++i) { for (i = 0; i < msg->len; ++i) {
...@@ -540,6 +521,15 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) ...@@ -540,6 +521,15 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
return ret; return ret;
} }
/*
* The hardware can handle at most two messages concatenated by a
* repeated start via it's internal address feature.
*/
static struct i2c_adapter_quirks at91_twi_quirks = {
.flags = I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | I2C_AQ_COMB_SAME_ADDR,
.max_comb_1st_msg_len = 3,
};
static u32 at91_twi_func(struct i2c_adapter *adapter) static u32 at91_twi_func(struct i2c_adapter *adapter)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
...@@ -777,6 +767,7 @@ static int at91_twi_probe(struct platform_device *pdev) ...@@ -777,6 +767,7 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->adapter.owner = THIS_MODULE; dev->adapter.owner = THIS_MODULE;
dev->adapter.class = I2C_CLASS_DEPRECATED; dev->adapter.class = I2C_CLASS_DEPRECATED;
dev->adapter.algo = &at91_twi_algorithm; dev->adapter.algo = &at91_twi_algorithm;
dev->adapter.quirks = &at91_twi_quirks;
dev->adapter.dev.parent = dev->dev; dev->adapter.dev.parent = dev->dev;
dev->adapter.nr = pdev->id; dev->adapter.nr = pdev->id;
dev->adapter.timeout = AT91_I2C_TIMEOUT; dev->adapter.timeout = AT91_I2C_TIMEOUT;
......
...@@ -334,12 +334,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -334,12 +334,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
u32 int_mask = MST_STATUS_ERR | MST_STATUS_SNS; u32 int_mask = MST_STATUS_ERR | MST_STATUS_SNS;
u32 rx_xfer, tx_xfer; u32 rx_xfer, tx_xfer;
u32 addr_1, addr_2; u32 addr_1, addr_2;
int ret; unsigned long time_left;
if (msg->len > 255) {
dev_warn(idev->dev, "unsupported length %u\n", msg->len);
return -EINVAL;
}
idev->msg = msg; idev->msg = msg;
idev->msg_xfrd = 0; idev->msg_xfrd = 0;
...@@ -388,7 +383,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -388,7 +383,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
i2c_int_enable(idev, int_mask); i2c_int_enable(idev, int_mask);
ret = wait_for_completion_timeout(&idev->msg_complete, time_left = wait_for_completion_timeout(&idev->msg_complete,
I2C_XFER_TIMEOUT); I2C_XFER_TIMEOUT);
i2c_int_disable(idev, int_mask); i2c_int_disable(idev, int_mask);
...@@ -396,7 +391,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -396,7 +391,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
if (readl(idev->base + MST_COMMAND) & CMD_BUSY) if (readl(idev->base + MST_COMMAND) & CMD_BUSY)
dev_warn(idev->dev, "busy after xfer\n"); dev_warn(idev->dev, "busy after xfer\n");
if (ret == 0) if (time_left == 0)
idev->msg_err = -ETIMEDOUT; idev->msg_err = -ETIMEDOUT;
if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO) if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO)
...@@ -408,17 +403,17 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -408,17 +403,17 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
static int axxia_i2c_stop(struct axxia_i2c_dev *idev) static int axxia_i2c_stop(struct axxia_i2c_dev *idev)
{ {
u32 int_mask = MST_STATUS_ERR | MST_STATUS_SCC; u32 int_mask = MST_STATUS_ERR | MST_STATUS_SCC;
int ret; unsigned long time_left;
reinit_completion(&idev->msg_complete); reinit_completion(&idev->msg_complete);
/* Issue stop */ /* Issue stop */
writel(0xb, idev->base + MST_COMMAND); writel(0xb, idev->base + MST_COMMAND);
i2c_int_enable(idev, int_mask); i2c_int_enable(idev, int_mask);
ret = wait_for_completion_timeout(&idev->msg_complete, time_left = wait_for_completion_timeout(&idev->msg_complete,
I2C_STOP_TIMEOUT); I2C_STOP_TIMEOUT);
i2c_int_disable(idev, int_mask); i2c_int_disable(idev, int_mask);
if (ret == 0) if (time_left == 0)
return -ETIMEDOUT; return -ETIMEDOUT;
if (readl(idev->base + MST_COMMAND) & CMD_BUSY) if (readl(idev->base + MST_COMMAND) & CMD_BUSY)
...@@ -454,6 +449,11 @@ static const struct i2c_algorithm axxia_i2c_algo = { ...@@ -454,6 +449,11 @@ static const struct i2c_algorithm axxia_i2c_algo = {
.functionality = axxia_i2c_func, .functionality = axxia_i2c_func,
}; };
static struct i2c_adapter_quirks axxia_i2c_quirks = {
.max_read_len = 255,
.max_write_len = 255,
};
static int axxia_i2c_probe(struct platform_device *pdev) static int axxia_i2c_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
...@@ -511,6 +511,7 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -511,6 +511,7 @@ static int axxia_i2c_probe(struct platform_device *pdev)
strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name)); strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
idev->adapter.owner = THIS_MODULE; idev->adapter.owner = THIS_MODULE;
idev->adapter.algo = &axxia_i2c_algo; idev->adapter.algo = &axxia_i2c_algo;
idev->adapter.quirks = &axxia_i2c_quirks;
idev->adapter.dev.parent = &pdev->dev; idev->adapter.dev.parent = &pdev->dev;
idev->adapter.dev.of_node = pdev->dev.of_node; idev->adapter.dev.of_node = pdev->dev.of_node;
......
...@@ -160,14 +160,6 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ...@@ -160,14 +160,6 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
u32 val; u32 val;
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC); unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC);
/* need to reserve one byte in the FIFO for the slave address */
if (msg->len > M_TX_RX_FIFO_SIZE - 1) {
dev_err(iproc_i2c->device,
"only support data length up to %u bytes\n",
M_TX_RX_FIFO_SIZE - 1);
return -EOPNOTSUPP;
}
/* check if bus is busy */ /* check if bus is busy */
if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) &
BIT(M_CMD_START_BUSY_SHIFT))) { BIT(M_CMD_START_BUSY_SHIFT))) {
...@@ -287,6 +279,12 @@ static const struct i2c_algorithm bcm_iproc_algo = { ...@@ -287,6 +279,12 @@ static const struct i2c_algorithm bcm_iproc_algo = {
.functionality = bcm_iproc_i2c_functionality, .functionality = bcm_iproc_i2c_functionality,
}; };
static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
/* need to reserve one byte in the FIFO for the slave address */
.max_read_len = M_TX_RX_FIFO_SIZE - 1,
.max_write_len = M_TX_RX_FIFO_SIZE - 1,
};
static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c)
{ {
unsigned int bus_speed; unsigned int bus_speed;
...@@ -413,6 +411,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev) ...@@ -413,6 +411,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(adap, iproc_i2c); i2c_set_adapdata(adap, iproc_i2c);
strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name));
adap->algo = &bcm_iproc_algo; adap->algo = &bcm_iproc_algo;
adap->quirks = &bcm_iproc_i2c_quirks;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node; adap->dev.of_node = pdev->dev.of_node;
......
...@@ -147,7 +147,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, ...@@ -147,7 +147,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,
struct i2c_msg *msg) struct i2c_msg *msg)
{ {
u32 c; u32 c;
int time_left; unsigned long time_left;
i2c_dev->msg_buf = msg->buf; i2c_dev->msg_buf = msg->buf;
i2c_dev->msg_buf_remaining = msg->len; i2c_dev->msg_buf_remaining = msg->len;
......
...@@ -475,7 +475,7 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap) ...@@ -475,7 +475,7 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap)
static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
struct i2c_adapter *adap) struct i2c_adapter *adap)
{ {
int ret; unsigned long time_left;
u32 reg; u32 reg;
id->p_msg = msg; id->p_msg = msg;
...@@ -501,8 +501,8 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, ...@@ -501,8 +501,8 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
cdns_i2c_msend(id); cdns_i2c_msend(id);
/* Wait for the signal of completion */ /* Wait for the signal of completion */
ret = wait_for_completion_timeout(&id->xfer_done, adap->timeout); time_left = wait_for_completion_timeout(&id->xfer_done, adap->timeout);
if (!ret) { if (time_left == 0) {
cdns_i2c_master_reset(adap); cdns_i2c_master_reset(adap);
dev_err(id->adap.dev.parent, dev_err(id->adap.dev.parent,
"timeout waiting on completion\n"); "timeout waiting on completion\n");
......
...@@ -308,22 +308,12 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -308,22 +308,12 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg; struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram; struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
struct i2c_msg *pmsg; struct i2c_msg *pmsg;
int ret, i; int ret;
int tptr; int tptr;
int rptr; int rptr;
cbd_t __iomem *tbdf; cbd_t __iomem *tbdf;
cbd_t __iomem *rbdf; cbd_t __iomem *rbdf;
if (num > CPM_MAXBD)
return -EINVAL;
/* Check if we have any oversized READ requests */
for (i = 0; i < num; i++) {
pmsg = &msgs[i];
if (pmsg->len >= CPM_MAX_READ)
return -EINVAL;
}
/* Reset to use first buffer */ /* Reset to use first buffer */
out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase)); out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase)); out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
...@@ -424,10 +414,18 @@ static const struct i2c_algorithm cpm_i2c_algo = { ...@@ -424,10 +414,18 @@ static const struct i2c_algorithm cpm_i2c_algo = {
.functionality = cpm_i2c_func, .functionality = cpm_i2c_func,
}; };
/* CPM_MAX_READ is also limiting writes according to the code! */
static struct i2c_adapter_quirks cpm_i2c_quirks = {
.max_num_msgs = CPM_MAXBD,
.max_read_len = CPM_MAX_READ,
.max_write_len = CPM_MAX_READ,
};
static const struct i2c_adapter cpm_ops = { static const struct i2c_adapter cpm_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "i2c-cpm", .name = "i2c-cpm",
.algo = &cpm_i2c_algo, .algo = &cpm_i2c_algo,
.quirks = &cpm_i2c_quirks,
}; };
static int cpm_i2c_setup(struct cpm_i2c *cpm) static int cpm_i2c_setup(struct cpm_i2c *cpm)
......
...@@ -60,6 +60,12 @@ ...@@ -60,6 +60,12 @@
#define DAVINCI_I2C_IVR_REG 0x28 #define DAVINCI_I2C_IVR_REG 0x28
#define DAVINCI_I2C_EMDR_REG 0x2c #define DAVINCI_I2C_EMDR_REG 0x2c
#define DAVINCI_I2C_PSC_REG 0x30 #define DAVINCI_I2C_PSC_REG 0x30
#define DAVINCI_I2C_FUNC_REG 0x48
#define DAVINCI_I2C_DIR_REG 0x4c
#define DAVINCI_I2C_DIN_REG 0x50
#define DAVINCI_I2C_DOUT_REG 0x54
#define DAVINCI_I2C_DSET_REG 0x58
#define DAVINCI_I2C_DCLR_REG 0x5c
#define DAVINCI_I2C_IVR_AAS 0x07 #define DAVINCI_I2C_IVR_AAS 0x07
#define DAVINCI_I2C_IVR_SCD 0x06 #define DAVINCI_I2C_IVR_SCD 0x06
...@@ -93,6 +99,29 @@ ...@@ -93,6 +99,29 @@
#define DAVINCI_I2C_IMR_NACK BIT(1) #define DAVINCI_I2C_IMR_NACK BIT(1)
#define DAVINCI_I2C_IMR_AL BIT(0) #define DAVINCI_I2C_IMR_AL BIT(0)
/* set SDA and SCL as GPIO */
#define DAVINCI_I2C_FUNC_PFUNC0 BIT(0)
/* set SCL as output when used as GPIO*/
#define DAVINCI_I2C_DIR_PDIR0 BIT(0)
/* set SDA as output when used as GPIO*/
#define DAVINCI_I2C_DIR_PDIR1 BIT(1)
/* read SCL GPIO level */
#define DAVINCI_I2C_DIN_PDIN0 BIT(0)
/* read SDA GPIO level */
#define DAVINCI_I2C_DIN_PDIN1 BIT(1)
/*set the SCL GPIO high */
#define DAVINCI_I2C_DSET_PDSET0 BIT(0)
/*set the SDA GPIO high */
#define DAVINCI_I2C_DSET_PDSET1 BIT(1)
/* set the SCL GPIO low */
#define DAVINCI_I2C_DCLR_PDCLR0 BIT(0)
/* set the SDA GPIO low */
#define DAVINCI_I2C_DCLR_PDCLR1 BIT(1)
struct davinci_i2c_dev { struct davinci_i2c_dev {
struct device *dev; struct device *dev;
void __iomem *base; void __iomem *base;
...@@ -129,43 +158,6 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) ...@@ -129,43 +158,6 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
return readw_relaxed(i2c_dev->base + reg); return readw_relaxed(i2c_dev->base + reg);
} }
/* Generate a pulse on the i2c clock pin. */
static void davinci_i2c_clock_pulse(unsigned int scl_pin)
{
u16 i;
if (scl_pin) {
/* Send high and low on the SCL line */
for (i = 0; i < 9; i++) {
gpio_set_value(scl_pin, 0);
udelay(20);
gpio_set_value(scl_pin, 1);
udelay(20);
}
}
}
/* This routine does i2c bus recovery as specified in the
* i2c protocol Rev. 03 section 3.16 titled "Bus clear"
*/
static void davinci_i2c_recover_bus(struct davinci_i2c_dev *dev)
{
u32 flag = 0;
struct davinci_i2c_platform_data *pdata = dev->pdata;
dev_err(dev->dev, "initiating i2c bus recovery\n");
/* Send NACK to the slave */
flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
flag |= DAVINCI_I2C_MDR_NACK;
/* write the data into mode register */
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
davinci_i2c_clock_pulse(pdata->scl_pin);
/* Send STOP */
flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
flag |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
}
static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
int val) int val)
{ {
...@@ -262,6 +254,99 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) ...@@ -262,6 +254,99 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
return 0; return 0;
} }
/*
* This routine does i2c bus recovery by using i2c_generic_gpio_recovery
* which is provided by I2C Bus recovery infrastructure.
*/
static void davinci_i2c_prepare_recovery(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
/* Disable interrupts */
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, 0);
/* put I2C into reset */
davinci_i2c_reset_ctrl(dev, 0);
}
static void davinci_i2c_unprepare_recovery(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
i2c_davinci_init(dev);
}
static struct i2c_bus_recovery_info davinci_i2c_gpio_recovery_info = {
.recover_bus = i2c_generic_gpio_recovery,
.prepare_recovery = davinci_i2c_prepare_recovery,
.unprepare_recovery = davinci_i2c_unprepare_recovery,
};
static void davinci_i2c_set_scl(struct i2c_adapter *adap, int val)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
if (val)
davinci_i2c_write_reg(dev, DAVINCI_I2C_DSET_REG,
DAVINCI_I2C_DSET_PDSET0);
else
davinci_i2c_write_reg(dev, DAVINCI_I2C_DCLR_REG,
DAVINCI_I2C_DCLR_PDCLR0);
}
static int davinci_i2c_get_scl(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
int val;
/* read the state of SCL */
val = davinci_i2c_read_reg(dev, DAVINCI_I2C_DIN_REG);
return val & DAVINCI_I2C_DIN_PDIN0;
}
static int davinci_i2c_get_sda(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
int val;
/* read the state of SDA */
val = davinci_i2c_read_reg(dev, DAVINCI_I2C_DIN_REG);
return val & DAVINCI_I2C_DIN_PDIN1;
}
static void davinci_i2c_scl_prepare_recovery(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
davinci_i2c_prepare_recovery(adap);
/* SCL output, SDA input */
davinci_i2c_write_reg(dev, DAVINCI_I2C_DIR_REG, DAVINCI_I2C_DIR_PDIR0);
/* change to GPIO mode */
davinci_i2c_write_reg(dev, DAVINCI_I2C_FUNC_REG,
DAVINCI_I2C_FUNC_PFUNC0);
}
static void davinci_i2c_scl_unprepare_recovery(struct i2c_adapter *adap)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
/* change back to I2C mode */
davinci_i2c_write_reg(dev, DAVINCI_I2C_FUNC_REG, 0);
davinci_i2c_unprepare_recovery(adap);
}
static struct i2c_bus_recovery_info davinci_i2c_scl_recovery_info = {
.recover_bus = i2c_generic_scl_recovery,
.set_scl = davinci_i2c_set_scl,
.get_scl = davinci_i2c_get_scl,
.get_sda = davinci_i2c_get_sda,
.prepare_recovery = davinci_i2c_scl_prepare_recovery,
.unprepare_recovery = davinci_i2c_scl_unprepare_recovery,
};
/* /*
* Waiting for bus not busy * Waiting for bus not busy
*/ */
...@@ -282,8 +367,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, ...@@ -282,8 +367,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
return -ETIMEDOUT; return -ETIMEDOUT;
} else { } else {
to_cnt = 0; to_cnt = 0;
davinci_i2c_recover_bus(dev); i2c_recover_bus(&dev->adapter);
i2c_davinci_init(dev);
} }
} }
if (allow_sleep) if (allow_sleep)
...@@ -304,7 +388,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) ...@@ -304,7 +388,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
struct davinci_i2c_platform_data *pdata = dev->pdata; struct davinci_i2c_platform_data *pdata = dev->pdata;
u32 flag; u32 flag;
u16 w; u16 w;
int r; unsigned long time_left;
/* Introduce a delay, required for some boards (e.g Davinci EVM) */ /* Introduce a delay, required for some boards (e.g Davinci EVM) */
if (pdata->bus_delay) if (pdata->bus_delay)
...@@ -368,11 +452,11 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) ...@@ -368,11 +452,11 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
flag |= DAVINCI_I2C_MDR_STP; flag |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
r = wait_for_completion_timeout(&dev->cmd_complete, dev->adapter.timeout); time_left = wait_for_completion_timeout(&dev->cmd_complete,
if (r == 0) { dev->adapter.timeout);
if (!time_left) {
dev_err(dev->dev, "controller timed out\n"); dev_err(dev->dev, "controller timed out\n");
davinci_i2c_recover_bus(dev); i2c_recover_bus(adap);
i2c_davinci_init(dev);
dev->buf_len = 0; dev->buf_len = 0;
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -380,17 +464,13 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) ...@@ -380,17 +464,13 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
/* This should be 0 if all bytes were transferred /* This should be 0 if all bytes were transferred
* or dev->cmd_err denotes an error. * or dev->cmd_err denotes an error.
*/ */
if (r >= 0) {
dev_err(dev->dev, "abnormal termination buf_len=%i\n", dev_err(dev->dev, "abnormal termination buf_len=%i\n",
dev->buf_len); dev->buf_len);
r = -EREMOTEIO;
}
dev->terminate = 1; dev->terminate = 1;
wmb(); wmb();
dev->buf_len = 0; dev->buf_len = 0;
return -EREMOTEIO;
} }
if (r < 0)
return r;
/* no error */ /* no error */
if (likely(!dev->cmd_err)) if (likely(!dev->cmd_err))
...@@ -674,6 +754,10 @@ static int davinci_i2c_probe(struct platform_device *pdev) ...@@ -674,6 +754,10 @@ static int davinci_i2c_probe(struct platform_device *pdev)
if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency", if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
&prop)) &prop))
dev->pdata->bus_freq = prop / 1000; dev->pdata->bus_freq = prop / 1000;
dev->pdata->has_pfunc =
of_property_read_bool(pdev->dev.of_node,
"ti,has-pfunc");
} else if (!dev->pdata) { } else if (!dev->pdata) {
dev->pdata = &davinci_i2c_platform_data_default; dev->pdata = &davinci_i2c_platform_data_default;
} }
...@@ -715,6 +799,14 @@ static int davinci_i2c_probe(struct platform_device *pdev) ...@@ -715,6 +799,14 @@ static int davinci_i2c_probe(struct platform_device *pdev)
adap->timeout = DAVINCI_I2C_TIMEOUT; adap->timeout = DAVINCI_I2C_TIMEOUT;
adap->dev.of_node = pdev->dev.of_node; adap->dev.of_node = pdev->dev.of_node;
if (dev->pdata->has_pfunc)
adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
else if (dev->pdata->scl_pin) {
adap->bus_recovery_info = &davinci_i2c_gpio_recovery_info;
adap->bus_recovery_info->scl_gpio = dev->pdata->scl_pin;
adap->bus_recovery_info->sda_gpio = dev->pdata->sda_pin;
}
adap->nr = pdev->id; adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap); r = i2c_add_numbered_adapter(adap);
if (r) { if (r) {
......
...@@ -656,8 +656,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ...@@ -656,8 +656,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
i2c_dw_xfer_init(dev); i2c_dw_xfer_init(dev);
/* wait for tx to complete */ /* wait for tx to complete */
ret = wait_for_completion_timeout(&dev->cmd_complete, HZ); if (!wait_for_completion_timeout(&dev->cmd_complete, HZ)) {
if (ret == 0) {
dev_err(dev->dev, "controller timed out\n"); dev_err(dev->dev, "controller timed out\n");
/* i2c_dw_init implicitly disables the adapter */ /* i2c_dw_init implicitly disables the adapter */
i2c_dw_init(dev); i2c_dw_init(dev);
......
...@@ -143,10 +143,8 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -143,10 +143,8 @@ static int dw_i2c_probe(struct platform_device *pdev)
u32 clk_freq, ht = 0; u32 clk_freq, ht = 0;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0)
dev_err(&pdev->dev, "no irq resource?\n"); return irq;
return irq; /* -ENXIO */
}
dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL);
if (!dev) if (!dev)
......
/*
* I2C bus driver for Conexant Digicolor SoCs
*
* Author: Baruch Siach <baruch@tkos.co.il>
*
* Copyright (C) 2015 Paradox Innovation Ltd.
*
* 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/clk.h>
#include <linux/completion.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#define DEFAULT_FREQ 100000
#define TIMEOUT_MS 100
#define II_CONTROL 0x0
#define II_CONTROL_LOCAL_RESET BIT(0)
#define II_CLOCKTIME 0x1
#define II_COMMAND 0x2
#define II_CMD_START 1
#define II_CMD_RESTART 2
#define II_CMD_SEND_ACK 3
#define II_CMD_GET_ACK 6
#define II_CMD_GET_NOACK 7
#define II_CMD_STOP 10
#define II_COMMAND_GO BIT(7)
#define II_COMMAND_COMPLETION_STATUS(r) (((r) >> 5) & 3)
#define II_CMD_STATUS_NORMAL 0
#define II_CMD_STATUS_ACK_GOOD 1
#define II_CMD_STATUS_ACK_BAD 2
#define II_CMD_STATUS_ABORT 3
#define II_DATA 0x3
#define II_INTFLAG_CLEAR 0x8
#define II_INTENABLE 0xa
struct dc_i2c {
struct i2c_adapter adap;
struct device *dev;
void __iomem *regs;
struct clk *clk;
unsigned int frequency;
struct i2c_msg *msg;
unsigned int msgbuf_ptr;
int last;
spinlock_t lock;
struct completion done;
int state;
int error;
};
enum {
STATE_IDLE,
STATE_START,
STATE_ADDR,
STATE_WRITE,
STATE_READ,
STATE_STOP,
};
static void dc_i2c_cmd(struct dc_i2c *i2c, u8 cmd)
{
writeb_relaxed(cmd | II_COMMAND_GO, i2c->regs + II_COMMAND);
}
static u8 dc_i2c_addr_cmd(struct i2c_msg *msg)
{
u8 addr = (msg->addr & 0x7f) << 1;
if (msg->flags & I2C_M_RD)
addr |= 1;
return addr;
}
static void dc_i2c_data(struct dc_i2c *i2c, u8 data)
{
writeb_relaxed(data, i2c->regs + II_DATA);
}
static void dc_i2c_write_byte(struct dc_i2c *i2c, u8 byte)
{
dc_i2c_data(i2c, byte);
dc_i2c_cmd(i2c, II_CMD_SEND_ACK);
}
static void dc_i2c_write_buf(struct dc_i2c *i2c)
{
dc_i2c_write_byte(i2c, i2c->msg->buf[i2c->msgbuf_ptr++]);
}
static void dc_i2c_next_read(struct dc_i2c *i2c)
{
bool last = (i2c->msgbuf_ptr + 1 == i2c->msg->len);
dc_i2c_cmd(i2c, last ? II_CMD_GET_NOACK : II_CMD_GET_ACK);
}
static void dc_i2c_stop(struct dc_i2c *i2c)
{
i2c->state = STATE_STOP;
if (i2c->last)
dc_i2c_cmd(i2c, II_CMD_STOP);
else
complete(&i2c->done);
}
static u8 dc_i2c_read_byte(struct dc_i2c *i2c)
{
return readb_relaxed(i2c->regs + II_DATA);
}
static void dc_i2c_read_buf(struct dc_i2c *i2c)
{
i2c->msg->buf[i2c->msgbuf_ptr++] = dc_i2c_read_byte(i2c);
dc_i2c_next_read(i2c);
}
static void dc_i2c_set_irq(struct dc_i2c *i2c, int enable)
{
if (enable)
writeb_relaxed(1, i2c->regs + II_INTFLAG_CLEAR);
writeb_relaxed(!!enable, i2c->regs + II_INTENABLE);
}
static int dc_i2c_cmd_status(struct dc_i2c *i2c)
{
u8 cmd = readb_relaxed(i2c->regs + II_COMMAND);
return II_COMMAND_COMPLETION_STATUS(cmd);
}
static void dc_i2c_start_msg(struct dc_i2c *i2c, int first)
{
struct i2c_msg *msg = i2c->msg;
if (!(msg->flags & I2C_M_NOSTART)) {
i2c->state = STATE_START;
dc_i2c_cmd(i2c, first ? II_CMD_START : II_CMD_RESTART);
} else if (msg->flags & I2C_M_RD) {
i2c->state = STATE_READ;
dc_i2c_next_read(i2c);
} else {
i2c->state = STATE_WRITE;
dc_i2c_write_buf(i2c);
}
}
static irqreturn_t dc_i2c_irq(int irq, void *dev_id)
{
struct dc_i2c *i2c = dev_id;
int cmd_status = dc_i2c_cmd_status(i2c);
unsigned long flags;
u8 addr_cmd;
writeb_relaxed(1, i2c->regs + II_INTFLAG_CLEAR);
spin_lock_irqsave(&i2c->lock, flags);
if (cmd_status == II_CMD_STATUS_ACK_BAD
|| cmd_status == II_CMD_STATUS_ABORT) {
i2c->error = -EIO;
complete(&i2c->done);
goto out;
}
switch (i2c->state) {
case STATE_START:
addr_cmd = dc_i2c_addr_cmd(i2c->msg);
dc_i2c_write_byte(i2c, addr_cmd);
i2c->state = STATE_ADDR;
break;
case STATE_ADDR:
if (i2c->msg->flags & I2C_M_RD) {
dc_i2c_next_read(i2c);
i2c->state = STATE_READ;
break;
}
i2c->state = STATE_WRITE;
/* fall through */
case STATE_WRITE:
if (i2c->msgbuf_ptr < i2c->msg->len)
dc_i2c_write_buf(i2c);
else
dc_i2c_stop(i2c);
break;
case STATE_READ:
if (i2c->msgbuf_ptr < i2c->msg->len)
dc_i2c_read_buf(i2c);
else
dc_i2c_stop(i2c);
break;
case STATE_STOP:
i2c->state = STATE_IDLE;
complete(&i2c->done);
break;
}
out:
spin_unlock_irqrestore(&i2c->lock, flags);
return IRQ_HANDLED;
}
static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first,
int last)
{
unsigned long timeout = msecs_to_jiffies(TIMEOUT_MS);
unsigned long flags;
spin_lock_irqsave(&i2c->lock, flags);
i2c->msg = msg;
i2c->msgbuf_ptr = 0;
i2c->last = last;
i2c->error = 0;
reinit_completion(&i2c->done);
dc_i2c_set_irq(i2c, 1);
dc_i2c_start_msg(i2c, first);
spin_unlock_irqrestore(&i2c->lock, flags);
timeout = wait_for_completion_timeout(&i2c->done, timeout);
dc_i2c_set_irq(i2c, 0);
if (timeout == 0) {
i2c->state = STATE_IDLE;
return -ETIMEDOUT;
}
if (i2c->error)
return i2c->error;
return 0;
}
static int dc_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct dc_i2c *i2c = adap->algo_data;
int i, ret;
for (i = 0; i < num; i++) {
ret = dc_i2c_xfer_msg(i2c, &msgs[i], i == 0, i == num - 1);
if (ret)
return ret;
}
return num;
}
static int dc_i2c_init_hw(struct dc_i2c *i2c)
{
unsigned long clk_rate = clk_get_rate(i2c->clk);
unsigned int clocktime;
writeb_relaxed(II_CONTROL_LOCAL_RESET, i2c->regs + II_CONTROL);
udelay(100);
writeb_relaxed(0, i2c->regs + II_CONTROL);
udelay(100);
clocktime = DIV_ROUND_UP(clk_rate, 64 * i2c->frequency);
if (clocktime < 1 || clocktime > 0xff) {
dev_err(i2c->dev, "can't set bus speed of %u Hz\n",
i2c->frequency);
return -EINVAL;
}
writeb_relaxed(clocktime - 1, i2c->regs + II_CLOCKTIME);
return 0;
}
static u32 dc_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
}
static const struct i2c_algorithm dc_i2c_algorithm = {
.master_xfer = dc_i2c_xfer,
.functionality = dc_i2c_func,
};
static int dc_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dc_i2c *i2c;
struct resource *r;
int ret = 0, irq;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct dc_i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
&i2c->frequency))
i2c->frequency = DEFAULT_FREQ;
i2c->dev = &pdev->dev;
platform_set_drvdata(pdev, i2c);
spin_lock_init(&i2c->lock);
init_completion(&i2c->done);
i2c->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c->clk))
return PTR_ERR(i2c->clk);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c->regs = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, dc_i2c_irq, 0,
dev_name(&pdev->dev), i2c);
if (ret < 0)
return ret;
strlcpy(i2c->adap.name, "Conexant Digicolor I2C adapter",
sizeof(i2c->adap.name));
i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &dc_i2c_algorithm;
i2c->adap.dev.parent = &pdev->dev;
i2c->adap.dev.of_node = np;
i2c->adap.algo_data = i2c;
ret = dc_i2c_init_hw(i2c);
if (ret)
return ret;
ret = clk_prepare_enable(i2c->clk);
if (ret < 0)
return ret;
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
clk_unprepare(i2c->clk);
return ret;
}
return 0;
}
static int dc_i2c_remove(struct platform_device *pdev)
{
struct dc_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
clk_disable_unprepare(i2c->clk);
return 0;
}
static const struct of_device_id dc_i2c_match[] = {
{ .compatible = "cnxt,cx92755-i2c" },
{ },
};
static struct platform_driver dc_i2c_driver = {
.probe = dc_i2c_probe,
.remove = dc_i2c_remove,
.driver = {
.name = "digicolor-i2c",
.of_match_table = dc_i2c_match,
},
};
module_platform_driver(dc_i2c_driver);
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Conexant Digicolor I2C master driver");
MODULE_LICENSE("GPL v2");
...@@ -144,7 +144,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter, ...@@ -144,7 +144,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter,
{ {
struct dln2_i2c *dln2 = i2c_get_adapdata(adapter); struct dln2_i2c *dln2 = i2c_get_adapdata(adapter);
struct i2c_msg *pmsg; struct i2c_msg *pmsg;
struct device *dev = &dln2->adapter.dev;
int i; int i;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
...@@ -152,11 +151,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter, ...@@ -152,11 +151,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter,
pmsg = &msgs[i]; pmsg = &msgs[i];
if (pmsg->len > DLN2_I2C_MAX_XFER_SIZE) {
dev_warn(dev, "maximum transfer size exceeded\n");
return -EOPNOTSUPP;
}
if (pmsg->flags & I2C_M_RD) { if (pmsg->flags & I2C_M_RD) {
ret = dln2_i2c_read(dln2, pmsg->addr, pmsg->buf, ret = dln2_i2c_read(dln2, pmsg->addr, pmsg->buf,
pmsg->len); pmsg->len);
...@@ -187,6 +181,11 @@ static const struct i2c_algorithm dln2_i2c_usb_algorithm = { ...@@ -187,6 +181,11 @@ static const struct i2c_algorithm dln2_i2c_usb_algorithm = {
.functionality = dln2_i2c_func, .functionality = dln2_i2c_func,
}; };
static struct i2c_adapter_quirks dln2_i2c_quirks = {
.max_read_len = DLN2_I2C_MAX_XFER_SIZE,
.max_write_len = DLN2_I2C_MAX_XFER_SIZE,
};
static int dln2_i2c_probe(struct platform_device *pdev) static int dln2_i2c_probe(struct platform_device *pdev)
{ {
int ret; int ret;
...@@ -209,7 +208,9 @@ static int dln2_i2c_probe(struct platform_device *pdev) ...@@ -209,7 +208,9 @@ static int dln2_i2c_probe(struct platform_device *pdev)
dln2->adapter.owner = THIS_MODULE; dln2->adapter.owner = THIS_MODULE;
dln2->adapter.class = I2C_CLASS_HWMON; dln2->adapter.class = I2C_CLASS_HWMON;
dln2->adapter.algo = &dln2_i2c_usb_algorithm; dln2->adapter.algo = &dln2_i2c_usb_algorithm;
dln2->adapter.quirks = &dln2_i2c_quirks;
dln2->adapter.dev.parent = dev; dln2->adapter.dev.parent = dev;
dln2->adapter.dev.of_node = dev->of_node;
i2c_set_adapdata(&dln2->adapter, dln2); i2c_set_adapdata(&dln2->adapter, dln2);
snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d", snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d",
"dln2-i2c", dev_name(pdev->dev.parent), dln2->port); "dln2-i2c", dev_name(pdev->dev.parent), dln2->port);
......
...@@ -223,8 +223,6 @@ struct i801_priv { ...@@ -223,8 +223,6 @@ struct i801_priv {
#endif #endif
}; };
static struct pci_driver i801_driver;
#define FEATURE_SMBUS_PEC (1 << 0) #define FEATURE_SMBUS_PEC (1 << 0)
#define FEATURE_BLOCK_BUFFER (1 << 1) #define FEATURE_BLOCK_BUFFER (1 << 1)
#define FEATURE_BLOCK_PROC (1 << 2) #define FEATURE_BLOCK_PROC (1 << 2)
...@@ -1140,7 +1138,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1140,7 +1138,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
int err, i; int err, i;
struct i801_priv *priv; struct i801_priv *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
...@@ -1182,34 +1180,35 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1182,34 +1180,35 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
} }
priv->features &= ~disable_features; priv->features &= ~disable_features;
err = pci_enable_device(dev); err = pcim_enable_device(dev);
if (err) { if (err) {
dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
err); err);
goto exit; return err;
} }
pcim_pin_device(dev);
/* Determine the address of the SMBus area */ /* Determine the address of the SMBus area */
priv->smba = pci_resource_start(dev, SMBBAR); priv->smba = pci_resource_start(dev, SMBBAR);
if (!priv->smba) { if (!priv->smba) {
dev_err(&dev->dev, "SMBus base address uninitialized, " dev_err(&dev->dev,
"upgrade BIOS\n"); "SMBus base address uninitialized, upgrade BIOS\n");
err = -ENODEV; return -ENODEV;
goto exit;
} }
err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
if (err) { if (err) {
err = -ENODEV; return -ENODEV;
goto exit;
} }
err = pci_request_region(dev, SMBBAR, i801_driver.name); err = pcim_iomap_regions(dev, 1 << SMBBAR,
dev_driver_string(&dev->dev));
if (err) { if (err) {
dev_err(&dev->dev, "Failed to request SMBus region " dev_err(&dev->dev,
"0x%lx-0x%Lx\n", priv->smba, "Failed to request SMBus region 0x%lx-0x%Lx\n",
priv->smba,
(unsigned long long)pci_resource_end(dev, SMBBAR)); (unsigned long long)pci_resource_end(dev, SMBBAR));
goto exit; return err;
} }
pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp); pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
...@@ -1254,8 +1253,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1254,8 +1253,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (priv->features & FEATURE_IRQ) { if (priv->features & FEATURE_IRQ) {
init_waitqueue_head(&priv->waitq); init_waitqueue_head(&priv->waitq);
err = request_irq(dev->irq, i801_isr, IRQF_SHARED, err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
i801_driver.name, priv); IRQF_SHARED,
dev_driver_string(&dev->dev), priv);
if (err) { if (err) {
dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
dev->irq, err); dev->irq, err);
...@@ -1276,7 +1276,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1276,7 +1276,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
err = i2c_add_adapter(&priv->adapter); err = i2c_add_adapter(&priv->adapter);
if (err) { if (err) {
dev_err(&dev->dev, "Failed to add SMBus adapter\n"); dev_err(&dev->dev, "Failed to add SMBus adapter\n");
goto exit_free_irq; return err;
} }
i801_probe_optional_slaves(priv); i801_probe_optional_slaves(priv);
...@@ -1286,14 +1286,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1286,14 +1286,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
pci_set_drvdata(dev, priv); pci_set_drvdata(dev, priv);
return 0; return 0;
exit_free_irq:
if (priv->features & FEATURE_IRQ)
free_irq(dev->irq, priv);
pci_release_region(dev, SMBBAR);
exit:
kfree(priv);
return err;
} }
static void i801_remove(struct pci_dev *dev) static void i801_remove(struct pci_dev *dev)
...@@ -1304,11 +1296,6 @@ static void i801_remove(struct pci_dev *dev) ...@@ -1304,11 +1296,6 @@ static void i801_remove(struct pci_dev *dev)
i2c_del_adapter(&priv->adapter); i2c_del_adapter(&priv->adapter);
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
if (priv->features & FEATURE_IRQ)
free_irq(dev->irq, priv);
pci_release_region(dev, SMBBAR);
kfree(priv);
/* /*
* do not call pci_disable_device(dev) since it can cause hard hangs on * do not call pci_disable_device(dev) since it can cause hard hangs on
* some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
...@@ -1330,7 +1317,7 @@ static int i801_resume(struct pci_dev *dev) ...@@ -1330,7 +1317,7 @@ static int i801_resume(struct pci_dev *dev)
{ {
pci_set_power_state(dev, PCI_D0); pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev); pci_restore_state(dev);
return pci_enable_device(dev); return 0;
} }
#else #else
#define i801_suspend NULL #define i801_suspend NULL
......
...@@ -988,15 +988,16 @@ static irqreturn_t img_i2c_isr(int irq, void *dev_id) ...@@ -988,15 +988,16 @@ static irqreturn_t img_i2c_isr(int irq, void *dev_id)
static int img_i2c_reset_bus(struct img_i2c *i2c) static int img_i2c_reset_bus(struct img_i2c *i2c)
{ {
unsigned long flags; unsigned long flags;
int ret; unsigned long time_left;
spin_lock_irqsave(&i2c->lock, flags); spin_lock_irqsave(&i2c->lock, flags);
reinit_completion(&i2c->msg_complete); reinit_completion(&i2c->msg_complete);
img_i2c_reset_start(i2c); img_i2c_reset_start(i2c);
spin_unlock_irqrestore(&i2c->lock, flags); spin_unlock_irqrestore(&i2c->lock, flags);
ret = wait_for_completion_timeout(&i2c->msg_complete, IMG_I2C_TIMEOUT); time_left = wait_for_completion_timeout(&i2c->msg_complete,
if (ret == 0) IMG_I2C_TIMEOUT);
if (time_left == 0)
return -ETIMEDOUT; return -ETIMEDOUT;
return 0; return 0;
} }
...@@ -1007,6 +1008,7 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -1007,6 +1008,7 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
struct img_i2c *i2c = i2c_get_adapdata(adap); struct img_i2c *i2c = i2c_get_adapdata(adap);
bool atomic = false; bool atomic = false;
int i, ret; int i, ret;
unsigned long time_left;
if (i2c->mode == MODE_SUSPEND) { if (i2c->mode == MODE_SUSPEND) {
WARN(1, "refusing to service transaction in suspended state\n"); WARN(1, "refusing to service transaction in suspended state\n");
...@@ -1068,11 +1070,11 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -1068,11 +1070,11 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
img_i2c_write(i2c); img_i2c_write(i2c);
spin_unlock_irqrestore(&i2c->lock, flags); spin_unlock_irqrestore(&i2c->lock, flags);
ret = wait_for_completion_timeout(&i2c->msg_complete, time_left = wait_for_completion_timeout(&i2c->msg_complete,
IMG_I2C_TIMEOUT); IMG_I2C_TIMEOUT);
del_timer_sync(&i2c->check_timer); del_timer_sync(&i2c->check_timer);
if (ret == 0) { if (time_left == 0) {
dev_err(adap->dev.parent, "i2c transfer timed out\n"); dev_err(adap->dev.parent, "i2c transfer timed out\n");
i2c->msg_status = -ETIMEDOUT; i2c->msg_status = -ETIMEDOUT;
break; break;
......
...@@ -601,6 +601,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, ...@@ -601,6 +601,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
struct i2c_msg *msgs) struct i2c_msg *msgs)
{ {
int result; int result;
unsigned long time_left;
unsigned int temp = 0; unsigned int temp = 0;
unsigned long orig_jiffies = jiffies; unsigned long orig_jiffies = jiffies;
struct imx_i2c_dma *dma = i2c_imx->dma; struct imx_i2c_dma *dma = i2c_imx->dma;
...@@ -624,10 +625,10 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, ...@@ -624,10 +625,10 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
*/ */
imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR); imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR);
reinit_completion(&i2c_imx->dma->cmd_complete); reinit_completion(&i2c_imx->dma->cmd_complete);
result = wait_for_completion_timeout( time_left = wait_for_completion_timeout(
&i2c_imx->dma->cmd_complete, &i2c_imx->dma->cmd_complete,
msecs_to_jiffies(DMA_TIMEOUT)); msecs_to_jiffies(DMA_TIMEOUT));
if (result == 0) { if (time_left == 0) {
dmaengine_terminate_all(dma->chan_using); dmaengine_terminate_all(dma->chan_using);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -663,6 +664,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, ...@@ -663,6 +664,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
struct i2c_msg *msgs, bool is_lastmsg) struct i2c_msg *msgs, bool is_lastmsg)
{ {
int result; int result;
unsigned long time_left;
unsigned int temp; unsigned int temp;
unsigned long orig_jiffies = jiffies; unsigned long orig_jiffies = jiffies;
struct imx_i2c_dma *dma = i2c_imx->dma; struct imx_i2c_dma *dma = i2c_imx->dma;
...@@ -682,10 +684,10 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, ...@@ -682,10 +684,10 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
return result; return result;
reinit_completion(&i2c_imx->dma->cmd_complete); reinit_completion(&i2c_imx->dma->cmd_complete);
result = wait_for_completion_timeout( time_left = wait_for_completion_timeout(
&i2c_imx->dma->cmd_complete, &i2c_imx->dma->cmd_complete,
msecs_to_jiffies(DMA_TIMEOUT)); msecs_to_jiffies(DMA_TIMEOUT));
if (result == 0) { if (time_left == 0) {
dmaengine_terminate_all(dma->chan_using); dmaengine_terminate_all(dma->chan_using);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
......
...@@ -380,6 +380,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, ...@@ -380,6 +380,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
int size, union i2c_smbus_data *data) int size, union i2c_smbus_data *data)
{ {
int ret; int ret;
unsigned long time_left;
dma_addr_t dma_addr = 0; /* address of the data buffer */ dma_addr_t dma_addr = 0; /* address of the data buffer */
u8 dma_size = 0; u8 dma_size = 0;
enum dma_data_direction dma_direction = 0; enum dma_data_direction dma_direction = 0;
...@@ -578,13 +579,13 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, ...@@ -578,13 +579,13 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
ismt_submit_desc(priv); ismt_submit_desc(priv);
/* Now we wait for interrupt completion, 1s */ /* Now we wait for interrupt completion, 1s */
ret = wait_for_completion_timeout(&priv->cmp, HZ*1); time_left = wait_for_completion_timeout(&priv->cmp, HZ*1);
/* unmap the data buffer */ /* unmap the data buffer */
if (dma_size != 0) if (dma_size != 0)
dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction); dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction);
if (unlikely(!ret)) { if (unlikely(!time_left)) {
dev_err(dev, "completion wait timed out\n"); dev_err(dev, "completion wait timed out\n");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
goto out; goto out;
......
此差异已折叠。
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/mpc52xx.h> #include <asm/mpc52xx.h>
#include <asm/mpc85xx.h>
#include <sysdev/fsl_soc.h> #include <sysdev/fsl_soc.h>
#define DRV_NAME "mpc-i2c" #define DRV_NAME "mpc-i2c"
...@@ -95,8 +96,9 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) ...@@ -95,8 +96,9 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
i2c->interrupt = readb(i2c->base + MPC_I2C_SR); i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR); writeb(0, i2c->base + MPC_I2C_SR);
wake_up(&i2c->queue); wake_up(&i2c->queue);
}
return IRQ_HANDLED; return IRQ_HANDLED;
}
return IRQ_NONE;
} }
/* Sometimes 9th clock pulse isn't generated, and slave doesn't release /* Sometimes 9th clock pulse isn't generated, and slave doesn't release
...@@ -346,6 +348,33 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void) ...@@ -346,6 +348,33 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
return val; return val;
} }
static u32 mpc_i2c_get_prescaler_8xxx(void)
{
/* mpc83xx and mpc82xx all have prescaler 1 */
u32 prescaler = 1;
/* mpc85xx */
if (pvr_version_is(PVR_VER_E500V1) || pvr_version_is(PVR_VER_E500V2)
|| pvr_version_is(PVR_VER_E500MC)
|| pvr_version_is(PVR_VER_E5500)
|| pvr_version_is(PVR_VER_E6500)) {
unsigned int svr = mfspr(SPRN_SVR);
if ((SVR_SOC_VER(svr) == SVR_8540)
|| (SVR_SOC_VER(svr) == SVR_8541)
|| (SVR_SOC_VER(svr) == SVR_8560)
|| (SVR_SOC_VER(svr) == SVR_8555)
|| (SVR_SOC_VER(svr) == SVR_8610))
/* the above 85xx SoCs have prescaler 1 */
prescaler = 1;
else
/* all the other 85xx have prescaler 2 */
prescaler = 2;
}
return prescaler;
}
static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
u32 prescaler, u32 *real_clk) u32 prescaler, u32 *real_clk)
{ {
...@@ -363,7 +392,7 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, ...@@ -363,7 +392,7 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2; prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
if (!prescaler) if (!prescaler)
prescaler = 1; prescaler = mpc_i2c_get_prescaler_8xxx();
divider = fsl_get_sys_freq() / clock / prescaler; divider = fsl_get_sys_freq() / clock / prescaler;
......
...@@ -568,6 +568,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -568,6 +568,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
int ret; int ret;
int flags; int flags;
int use_pio = 0; int use_pio = 0;
unsigned long time_left;
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
...@@ -599,9 +600,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -599,9 +600,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (ret) if (ret)
return ret; return ret;
ret = wait_for_completion_timeout(&i2c->cmd_complete, time_left = wait_for_completion_timeout(&i2c->cmd_complete,
msecs_to_jiffies(1000)); msecs_to_jiffies(1000));
if (ret == 0) if (!time_left)
goto timeout; goto timeout;
ret = i2c->cmd_err; ret = i2c->cmd_err;
......
...@@ -446,9 +446,9 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) ...@@ -446,9 +446,9 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
*/ */
static int read_i2c(struct nmk_i2c_dev *dev, u16 flags) static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
{ {
u32 status = 0; int status = 0;
u32 mcr, irq_mask; u32 mcr, irq_mask;
int timeout; unsigned long timeout;
mcr = load_i2c_mcr_reg(dev, flags); mcr = load_i2c_mcr_reg(dev, flags);
writel(mcr, dev->virtbase + I2C_MCR); writel(mcr, dev->virtbase + I2C_MCR);
...@@ -517,7 +517,7 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags) ...@@ -517,7 +517,7 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
{ {
u32 status = 0; u32 status = 0;
u32 mcr, irq_mask; u32 mcr, irq_mask;
int timeout; unsigned long timeout;
mcr = load_i2c_mcr_reg(dev, flags); mcr = load_i2c_mcr_reg(dev, flags);
......
...@@ -104,18 +104,8 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -104,18 +104,8 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf)); req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf));
break; break;
case 2: case 2:
/* For two messages, we basically support only simple req.type = (msgs[1].flags & I2C_M_RD) ?
* smbus transactions of a write plus a read. We might OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE;
* want to allow also two writes but we'd have to bounce
* the data into a single buffer.
*/
if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD))
return -EOPNOTSUPP;
if (msgs[0].len > 4)
return -EOPNOTSUPP;
if (msgs[0].addr != msgs[1].addr)
return -EOPNOTSUPP;
req.type = OPAL_I2C_SM_READ;
req.addr = cpu_to_be16(msgs[0].addr); req.addr = cpu_to_be16(msgs[0].addr);
req.subaddr_sz = msgs[0].len; req.subaddr_sz = msgs[0].len;
for (i = 0; i < msgs[0].len; i++) for (i = 0; i < msgs[0].len; i++)
...@@ -210,6 +200,15 @@ static const struct i2c_algorithm i2c_opal_algo = { ...@@ -210,6 +200,15 @@ static const struct i2c_algorithm i2c_opal_algo = {
.functionality = i2c_opal_func, .functionality = i2c_opal_func,
}; };
/*
* For two messages, we basically support simple smbus transactions of a
* write-then-anything.
*/
static struct i2c_adapter_quirks i2c_opal_quirks = {
.flags = I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | I2C_AQ_COMB_SAME_ADDR,
.max_comb_1st_msg_len = 4,
};
static int i2c_opal_probe(struct platform_device *pdev) static int i2c_opal_probe(struct platform_device *pdev)
{ {
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
...@@ -232,6 +231,7 @@ static int i2c_opal_probe(struct platform_device *pdev) ...@@ -232,6 +231,7 @@ static int i2c_opal_probe(struct platform_device *pdev)
adapter->algo = &i2c_opal_algo; adapter->algo = &i2c_opal_algo;
adapter->algo_data = (void *)(unsigned long)opal_id; adapter->algo_data = (void *)(unsigned long)opal_id;
adapter->quirks = &i2c_opal_quirks;
adapter->dev.parent = &pdev->dev; adapter->dev.parent = &pdev->dev;
adapter->dev.of_node = of_node_get(pdev->dev.of_node); adapter->dev.of_node = of_node_get(pdev->dev.of_node);
pname = of_get_property(pdev->dev.of_node, "ibm,port-name", NULL); pname = of_get_property(pdev->dev.of_node, "ibm,port-name", NULL);
......
...@@ -456,14 +456,6 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd( ...@@ -456,14 +456,6 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
return -EINVAL; return -EINVAL;
} }
if (cmd->read_len > MSP_MAX_BYTES_PER_RW ||
cmd->write_len > MSP_MAX_BYTES_PER_RW) {
dev_err(&pmcmsptwi_adapter.dev,
"%s: Cannot transfer more than %d bytes\n",
__func__, MSP_MAX_BYTES_PER_RW);
return -EINVAL;
}
mutex_lock(&data->lock); mutex_lock(&data->lock);
dev_dbg(&pmcmsptwi_adapter.dev, dev_dbg(&pmcmsptwi_adapter.dev,
"Setting address to 0x%04x\n", cmd->addr); "Setting address to 0x%04x\n", cmd->addr);
...@@ -520,25 +512,14 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, ...@@ -520,25 +512,14 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
struct pmcmsptwi_cfg oldcfg, newcfg; struct pmcmsptwi_cfg oldcfg, newcfg;
int ret; int ret;
if (num > 2) { if (num == 2) {
dev_dbg(&adap->dev, "%d messages unsupported\n", num);
return -EINVAL;
} else if (num == 2) {
/* Check for a dual write-then-read command */
struct i2c_msg *nextmsg = msg + 1; struct i2c_msg *nextmsg = msg + 1;
if (!(msg->flags & I2C_M_RD) &&
(nextmsg->flags & I2C_M_RD) &&
msg->addr == nextmsg->addr) {
cmd.type = MSP_TWI_CMD_WRITE_READ; cmd.type = MSP_TWI_CMD_WRITE_READ;
cmd.write_len = msg->len; cmd.write_len = msg->len;
cmd.write_data = msg->buf; cmd.write_data = msg->buf;
cmd.read_len = nextmsg->len; cmd.read_len = nextmsg->len;
cmd.read_data = nextmsg->buf; cmd.read_data = nextmsg->buf;
} else {
dev_dbg(&adap->dev,
"Non write-read dual messages unsupported\n");
return -EINVAL;
}
} else if (msg->flags & I2C_M_RD) { } else if (msg->flags & I2C_M_RD) {
cmd.type = MSP_TWI_CMD_READ; cmd.type = MSP_TWI_CMD_READ;
cmd.read_len = msg->len; cmd.read_len = msg->len;
...@@ -598,6 +579,14 @@ static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter) ...@@ -598,6 +579,14 @@ static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL; I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL;
} }
static struct i2c_adapter_quirks pmcmsptwi_i2c_quirks = {
.flags = I2C_AQ_COMB_WRITE_THEN_READ,
.max_write_len = MSP_MAX_BYTES_PER_RW,
.max_read_len = MSP_MAX_BYTES_PER_RW,
.max_comb_1st_msg_len = MSP_MAX_BYTES_PER_RW,
.max_comb_2nd_msg_len = MSP_MAX_BYTES_PER_RW,
};
/* -- Initialization -- */ /* -- Initialization -- */
static struct i2c_algorithm pmcmsptwi_algo = { static struct i2c_algorithm pmcmsptwi_algo = {
...@@ -609,6 +598,7 @@ static struct i2c_adapter pmcmsptwi_adapter = { ...@@ -609,6 +598,7 @@ static struct i2c_adapter pmcmsptwi_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &pmcmsptwi_algo, .algo = &pmcmsptwi_algo,
.quirks = &pmcmsptwi_i2c_quirks,
.name = DRV_NAME, .name = DRV_NAME,
}; };
......
...@@ -153,12 +153,6 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap, ...@@ -153,12 +153,6 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
int read; int read;
int addrdir; int addrdir;
if (num != 1) {
dev_err(&adap->dev,
"Multi-message I2C transactions not supported\n");
return -EOPNOTSUPP;
}
if (msgs->flags & I2C_M_TEN) if (msgs->flags & I2C_M_TEN)
return -EINVAL; return -EINVAL;
read = (msgs->flags & I2C_M_RD) != 0; read = (msgs->flags & I2C_M_RD) != 0;
...@@ -205,6 +199,9 @@ static const struct i2c_algorithm i2c_powermac_algorithm = { ...@@ -205,6 +199,9 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
.functionality = i2c_powermac_func, .functionality = i2c_powermac_func,
}; };
static struct i2c_adapter_quirks i2c_powermac_quirks = {
.max_num_msgs = 1,
};
static int i2c_powermac_remove(struct platform_device *dev) static int i2c_powermac_remove(struct platform_device *dev)
{ {
...@@ -434,6 +431,7 @@ static int i2c_powermac_probe(struct platform_device *dev) ...@@ -434,6 +431,7 @@ static int i2c_powermac_probe(struct platform_device *dev)
platform_set_drvdata(dev, adapter); platform_set_drvdata(dev, adapter);
adapter->algo = &i2c_powermac_algorithm; adapter->algo = &i2c_powermac_algorithm;
adapter->quirks = &i2c_powermac_quirks;
i2c_set_adapdata(adapter, bus); i2c_set_adapdata(adapter, bus);
adapter->dev.parent = &dev->dev; adapter->dev.parent = &dev->dev;
......
...@@ -412,17 +412,6 @@ static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) ...@@ -412,17 +412,6 @@ static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
unsigned long left; unsigned long left;
int ret; int ret;
/*
* The QUP block will issue a NACK and STOP on the bus when reaching
* the end of the read, the length of the read is specified as one byte
* which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
*/
if (msg->len > QUP_READ_LIMIT) {
dev_err(qup->dev, "HW not capable of reads over %d bytes\n",
QUP_READ_LIMIT);
return -EINVAL;
}
qup->msg = msg; qup->msg = msg;
qup->pos = 0; qup->pos = 0;
...@@ -534,6 +523,15 @@ static const struct i2c_algorithm qup_i2c_algo = { ...@@ -534,6 +523,15 @@ static const struct i2c_algorithm qup_i2c_algo = {
.functionality = qup_i2c_func, .functionality = qup_i2c_func,
}; };
/*
* The QUP block will issue a NACK and STOP on the bus when reaching
* the end of the read, the length of the read is specified as one byte
* which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
*/
static struct i2c_adapter_quirks qup_i2c_quirks = {
.max_read_len = QUP_READ_LIMIT,
};
static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup) static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup)
{ {
clk_prepare_enable(qup->clk); clk_prepare_enable(qup->clk);
...@@ -670,6 +668,7 @@ static int qup_i2c_probe(struct platform_device *pdev) ...@@ -670,6 +668,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(&qup->adap, qup); i2c_set_adapdata(&qup->adap, qup);
qup->adap.algo = &qup_i2c_algo; qup->adap.algo = &qup_i2c_algo;
qup->adap.quirks = &qup_i2c_quirks;
qup->adap.dev.parent = qup->dev; qup->adap.dev.parent = qup->dev;
qup->adap.dev.of_node = pdev->dev.of_node; qup->adap.dev.of_node = pdev->dev.of_node;
strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name)); strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
......
...@@ -382,11 +382,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) ...@@ -382,11 +382,11 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
if (ssr_filtered & SAR) { if (ssr_filtered & SAR) {
/* read or write request */ /* read or write request */
if (ssr_raw & STM) { if (ssr_raw & STM) {
i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_START, &value); i2c_slave_event(priv->slave, I2C_SLAVE_READ_REQUESTED, &value);
rcar_i2c_write(priv, ICRXTX, value); rcar_i2c_write(priv, ICRXTX, value);
rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR); rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
} else { } else {
i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_START, &value); i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
rcar_i2c_read(priv, ICRXTX); /* dummy read */ rcar_i2c_read(priv, ICRXTX); /* dummy read */
rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR); rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
} }
...@@ -406,17 +406,15 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) ...@@ -406,17 +406,15 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
int ret; int ret;
value = rcar_i2c_read(priv, ICRXTX); value = rcar_i2c_read(priv, ICRXTX);
ret = i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_END, &value); ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
/* Send NACK in case of error */ /* Send NACK in case of error */
rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0)); rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0));
i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_START, &value);
rcar_i2c_write(priv, ICSSR, ~SDR & 0xff); rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
} }
/* master wants to read from us */ /* master wants to read from us */
if (ssr_filtered & SDE) { if (ssr_filtered & SDE) {
i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_END, &value); i2c_slave_event(priv->slave, I2C_SLAVE_READ_PROCESSED, &value);
i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_START, &value);
rcar_i2c_write(priv, ICRXTX, value); rcar_i2c_write(priv, ICRXTX, value);
rcar_i2c_write(priv, ICSSR, ~SDE & 0xff); rcar_i2c_write(priv, ICSSR, ~SDE & 0xff);
} }
......
...@@ -532,7 +532,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -532,7 +532,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
{ {
u32 packet_header; u32 packet_header;
u32 int_mask; u32 int_mask;
int ret; unsigned long time_left;
tegra_i2c_flush_fifos(i2c_dev); tegra_i2c_flush_fifos(i2c_dev);
...@@ -585,18 +585,20 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -585,18 +585,20 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n", dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
i2c_readl(i2c_dev, I2C_INT_MASK)); i2c_readl(i2c_dev, I2C_INT_MASK));
ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT); time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
TEGRA_I2C_TIMEOUT);
tegra_i2c_mask_irq(i2c_dev, int_mask); tegra_i2c_mask_irq(i2c_dev, int_mask);
if (ret == 0) { if (time_left == 0) {
dev_err(i2c_dev->dev, "i2c transfer timed out\n"); dev_err(i2c_dev->dev, "i2c transfer timed out\n");
tegra_i2c_init(i2c_dev); tegra_i2c_init(i2c_dev);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
dev_dbg(i2c_dev->dev, "transfer complete: %d %d %d\n", dev_dbg(i2c_dev->dev, "transfer complete: %lu %d %d\n",
ret, completion_done(&i2c_dev->msg_complete), i2c_dev->msg_err); time_left, completion_done(&i2c_dev->msg_complete),
i2c_dev->msg_err);
if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
return 0; return 0;
......
...@@ -288,10 +288,6 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs, ...@@ -288,10 +288,6 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs,
i, pmsg->flags & I2C_M_RD ? "read" : "write", i, pmsg->flags & I2C_M_RD ? "read" : "write",
pmsg->flags, pmsg->len, pmsg->addr); pmsg->flags, pmsg->len, pmsg->addr);
/* msgs longer than 2048 bytes are not supported by adapter */
if (pmsg->len > 2048)
return -EINVAL;
mutex_lock(&vb->lock); mutex_lock(&vb->lock);
/* directly send the message */ /* directly send the message */
if (pmsg->flags & I2C_M_RD) { if (pmsg->flags & I2C_M_RD) {
...@@ -358,6 +354,11 @@ static const struct i2c_algorithm vprbrd_algorithm = { ...@@ -358,6 +354,11 @@ static const struct i2c_algorithm vprbrd_algorithm = {
.functionality = vprbrd_i2c_func, .functionality = vprbrd_i2c_func,
}; };
static struct i2c_adapter_quirks vprbrd_quirks = {
.max_read_len = 2048,
.max_write_len = 2048,
};
static int vprbrd_i2c_probe(struct platform_device *pdev) static int vprbrd_i2c_probe(struct platform_device *pdev)
{ {
struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent); struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
...@@ -373,6 +374,7 @@ static int vprbrd_i2c_probe(struct platform_device *pdev) ...@@ -373,6 +374,7 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
vb_i2c->i2c.owner = THIS_MODULE; vb_i2c->i2c.owner = THIS_MODULE;
vb_i2c->i2c.class = I2C_CLASS_HWMON; vb_i2c->i2c.class = I2C_CLASS_HWMON;
vb_i2c->i2c.algo = &vprbrd_algorithm; vb_i2c->i2c.algo = &vprbrd_algorithm;
vb_i2c->i2c.quirks = &vprbrd_quirks;
vb_i2c->i2c.algo_data = vb; vb_i2c->i2c.algo_data = vb;
/* save the param in usb capabable memory */ /* save the param in usb capabable memory */
vb_i2c->bus_freq_param = i2c_bus_param; vb_i2c->bus_freq_param = i2c_bus_param;
......
...@@ -128,7 +128,8 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, ...@@ -128,7 +128,8 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
{ {
struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
u16 val, tcr_val; u16 val, tcr_val;
int ret, wait_result; int ret;
unsigned long wait_result;
int xfer_len = 0; int xfer_len = 0;
if (!(pmsg->flags & I2C_M_NOSTART)) { if (!(pmsg->flags & I2C_M_NOSTART)) {
...@@ -177,7 +178,7 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, ...@@ -177,7 +178,7 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
while (xfer_len < pmsg->len) { while (xfer_len < pmsg->len) {
wait_result = wait_for_completion_timeout(&i2c_dev->complete, wait_result = wait_for_completion_timeout(&i2c_dev->complete,
500 * HZ / 1000); msecs_to_jiffies(500));
if (wait_result == 0) if (wait_result == 0)
return -ETIMEDOUT; return -ETIMEDOUT;
...@@ -218,7 +219,8 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, ...@@ -218,7 +219,8 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
{ {
struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
u16 val, tcr_val; u16 val, tcr_val;
int ret, wait_result; int ret;
unsigned long wait_result;
u32 xfer_len = 0; u32 xfer_len = 0;
if (!(pmsg->flags & I2C_M_NOSTART)) { if (!(pmsg->flags & I2C_M_NOSTART)) {
...@@ -266,7 +268,7 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, ...@@ -266,7 +268,7 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
while (xfer_len < pmsg->len) { while (xfer_len < pmsg->len) {
wait_result = wait_for_completion_timeout(&i2c_dev->complete, wait_result = wait_for_completion_timeout(&i2c_dev->complete,
500 * HZ / 1000); msecs_to_jiffies(500));
if (!wait_result) if (!wait_result)
return -ETIMEDOUT; return -ETIMEDOUT;
......
/*
* Copyright (c) 2003-2015 Broadcom Corporation
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/completion.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#define XLP9XX_I2C_DIV 0x0
#define XLP9XX_I2C_CTRL 0x1
#define XLP9XX_I2C_CMD 0x2
#define XLP9XX_I2C_STATUS 0x3
#define XLP9XX_I2C_MTXFIFO 0x4
#define XLP9XX_I2C_MRXFIFO 0x5
#define XLP9XX_I2C_MFIFOCTRL 0x6
#define XLP9XX_I2C_STXFIFO 0x7
#define XLP9XX_I2C_SRXFIFO 0x8
#define XLP9XX_I2C_SFIFOCTRL 0x9
#define XLP9XX_I2C_SLAVEADDR 0xA
#define XLP9XX_I2C_OWNADDR 0xB
#define XLP9XX_I2C_FIFOWCNT 0xC
#define XLP9XX_I2C_INTEN 0xD
#define XLP9XX_I2C_INTST 0xE
#define XLP9XX_I2C_WAITCNT 0xF
#define XLP9XX_I2C_TIMEOUT 0X10
#define XLP9XX_I2C_GENCALLADDR 0x11
#define XLP9XX_I2C_CMD_START BIT(7)
#define XLP9XX_I2C_CMD_STOP BIT(6)
#define XLP9XX_I2C_CMD_READ BIT(5)
#define XLP9XX_I2C_CMD_WRITE BIT(4)
#define XLP9XX_I2C_CMD_ACK BIT(3)
#define XLP9XX_I2C_CTRL_MCTLEN_SHIFT 16
#define XLP9XX_I2C_CTRL_MCTLEN_MASK 0xffff0000
#define XLP9XX_I2C_CTRL_RST BIT(8)
#define XLP9XX_I2C_CTRL_EN BIT(6)
#define XLP9XX_I2C_CTRL_MASTER BIT(4)
#define XLP9XX_I2C_CTRL_FIFORD BIT(1)
#define XLP9XX_I2C_CTRL_ADDMODE BIT(0)
#define XLP9XX_I2C_INTEN_NACKADDR BIT(25)
#define XLP9XX_I2C_INTEN_SADDR BIT(13)
#define XLP9XX_I2C_INTEN_DATADONE BIT(12)
#define XLP9XX_I2C_INTEN_ARLOST BIT(11)
#define XLP9XX_I2C_INTEN_MFIFOFULL BIT(4)
#define XLP9XX_I2C_INTEN_MFIFOEMTY BIT(3)
#define XLP9XX_I2C_INTEN_MFIFOHI BIT(2)
#define XLP9XX_I2C_INTEN_BUSERR BIT(0)
#define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT 8
#define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT 0
#define XLP9XX_I2C_MFIFOCTRL_RST BIT(16)
#define XLP9XX_I2C_SLAVEADDR_RW BIT(0)
#define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT 1
#define XLP9XX_I2C_IP_CLK_FREQ 133000000UL
#define XLP9XX_I2C_DEFAULT_FREQ 100000
#define XLP9XX_I2C_HIGH_FREQ 400000
#define XLP9XX_I2C_FIFO_SIZE 0x80U
#define XLP9XX_I2C_TIMEOUT_MS 1000
#define XLP9XX_I2C_FIFO_WCNT_MASK 0xff
#define XLP9XX_I2C_STATUS_ERRMASK (XLP9XX_I2C_INTEN_ARLOST | \
XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR)
struct xlp9xx_i2c_dev {
struct device *dev;
struct i2c_adapter adapter;
struct completion msg_complete;
int irq;
bool msg_read;
u32 __iomem *base;
u32 msg_buf_remaining;
u32 msg_len;
u32 clk_hz;
u32 msg_err;
u8 *msg_buf;
};
static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv,
unsigned long reg, u32 val)
{
writel(val, priv->base + reg);
}
static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv,
unsigned long reg)
{
return readl(priv->base + reg);
}
static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
{
u32 inten;
inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask;
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
}
static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
{
u32 inten;
inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask;
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
}
static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv)
{
u32 thres;
thres = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT);
}
static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
{
u32 len, i;
u8 *buf = priv->msg_buf;
len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
for (i = 0; i < len; i++)
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, buf[i]);
priv->msg_buf_remaining -= len;
priv->msg_buf += len;
}
static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
{
u32 len, i;
u8 *buf = priv->msg_buf;
len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
XLP9XX_I2C_FIFO_WCNT_MASK;
len = min(priv->msg_buf_remaining, len);
for (i = 0; i < len; i++, buf++)
*buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
priv->msg_buf_remaining -= len;
priv->msg_buf = buf;
if (priv->msg_buf_remaining)
xlp9xx_i2c_update_rx_fifo_thres(priv);
}
static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id)
{
struct xlp9xx_i2c_dev *priv = dev_id;
u32 status;
status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST);
if (status == 0)
return IRQ_NONE;
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, status);
if (status & XLP9XX_I2C_STATUS_ERRMASK) {
priv->msg_err = status;
goto xfer_done;
}
/* SADDR ACK for SMBUS_QUICK */
if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0))
goto xfer_done;
if (!priv->msg_read) {
if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) {
/* TX FIFO got empty, fill it up again */
if (priv->msg_buf_remaining)
xlp9xx_i2c_fill_tx_fifo(priv);
else
xlp9xx_i2c_mask_irq(priv,
XLP9XX_I2C_INTEN_MFIFOEMTY);
}
} else {
if (status & (XLP9XX_I2C_INTEN_DATADONE |
XLP9XX_I2C_INTEN_MFIFOHI)) {
/* data is in FIFO, read it */
if (priv->msg_buf_remaining)
xlp9xx_i2c_drain_rx_fifo(priv);
}
}
/* Transfer complete */
if (status & XLP9XX_I2C_INTEN_DATADONE)
goto xfer_done;
return IRQ_HANDLED;
xfer_done:
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
complete(&priv->msg_complete);
return IRQ_HANDLED;
}
static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv)
{
u32 prescale;
/*
* The controller uses 5 * SCL clock internally.
* So prescale value should be divided by 5.
*/
prescale = DIV_ROUND_UP(XLP9XX_I2C_IP_CLK_FREQ, priv->clk_hz);
prescale = ((prescale - 8) / 5) - 1;
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN |
XLP9XX_I2C_CTRL_MASTER);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, prescale);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
return 0;
}
static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
int last_msg)
{
unsigned long timeleft;
u32 intr_mask, cmd, val;
priv->msg_buf = msg->buf;
priv->msg_buf_remaining = priv->msg_len = msg->len;
priv->msg_err = 0;
priv->msg_read = (msg->flags & I2C_M_RD);
reinit_completion(&priv->msg_complete);
/* Reset FIFO */
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
XLP9XX_I2C_MFIFOCTRL_RST);
/* set FIFO threshold if reading */
if (priv->msg_read)
xlp9xx_i2c_update_rx_fifo_thres(priv);
/* set slave addr */
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR,
(msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) |
(priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0));
/* Build control word for transfer */
val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
if (!priv->msg_read)
val &= ~XLP9XX_I2C_CTRL_FIFORD;
else
val |= XLP9XX_I2C_CTRL_FIFORD; /* read */
if (msg->flags & I2C_M_TEN)
val |= XLP9XX_I2C_CTRL_ADDMODE; /* 10-bit address mode*/
else
val &= ~XLP9XX_I2C_CTRL_ADDMODE;
/* set data length to be transferred */
val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
(msg->len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
/* fill fifo during tx */
if (!priv->msg_read)
xlp9xx_i2c_fill_tx_fifo(priv);
/* set interrupt mask */
intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR |
XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE);
if (priv->msg_read) {
intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI;
if (msg->len == 0)
intr_mask |= XLP9XX_I2C_INTEN_SADDR;
} else {
if (msg->len == 0)
intr_mask |= XLP9XX_I2C_INTEN_SADDR;
else
intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY;
}
xlp9xx_i2c_unmask_irq(priv, intr_mask);
/* set cmd reg */
cmd = XLP9XX_I2C_CMD_START;
cmd |= (priv->msg_read ? XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE);
if (last_msg)
cmd |= XLP9XX_I2C_CMD_STOP;
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, cmd);
timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS);
timeleft = wait_for_completion_timeout(&priv->msg_complete, timeleft);
if (priv->msg_err) {
dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err);
if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR)
xlp9xx_i2c_init(priv);
return -EIO;
}
if (timeleft == 0) {
dev_dbg(priv->dev, "i2c transfer timed out!\n");
xlp9xx_i2c_init(priv);
return -ETIMEDOUT;
}
return 0;
}
static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num)
{
int i, ret;
struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap);
for (i = 0; i < num; i++) {
ret = xlp9xx_i2c_xfer_msg(priv, &msgs[i], i == num - 1);
if (ret != 0)
return ret;
}
return num;
}
static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C |
I2C_FUNC_10BIT_ADDR;
}
static struct i2c_algorithm xlp9xx_i2c_algo = {
.master_xfer = xlp9xx_i2c_xfer,
.functionality = xlp9xx_i2c_functionality,
};
static int xlp9xx_i2c_get_frequency(struct platform_device *pdev,
struct xlp9xx_i2c_dev *priv)
{
struct device_node *np = pdev->dev.of_node;
u32 freq;
int err;
err = of_property_read_u32(np, "clock-frequency", &freq);
if (err) {
freq = XLP9XX_I2C_DEFAULT_FREQ;
dev_dbg(&pdev->dev, "using default frequency %u\n", freq);
} else if (freq == 0 || freq > XLP9XX_I2C_HIGH_FREQ) {
dev_warn(&pdev->dev, "invalid frequency %u, using default\n",
freq);
freq = XLP9XX_I2C_DEFAULT_FREQ;
}
priv->clk_hz = freq;
return 0;
}
static int xlp9xx_i2c_probe(struct platform_device *pdev)
{
struct xlp9xx_i2c_dev *priv;
struct resource *res;
int err = 0;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->irq = platform_get_irq(pdev, 0);
if (priv->irq <= 0) {
dev_err(&pdev->dev, "invalid irq!\n");
return priv->irq;
}
xlp9xx_i2c_get_frequency(pdev, priv);
xlp9xx_i2c_init(priv);
err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0,
pdev->name, priv);
if (err) {
dev_err(&pdev->dev, "IRQ request failed!\n");
return err;
}
init_completion(&priv->msg_complete);
priv->adapter.dev.parent = &pdev->dev;
priv->adapter.algo = &xlp9xx_i2c_algo;
priv->adapter.dev.of_node = pdev->dev.of_node;
priv->dev = &pdev->dev;
snprintf(priv->adapter.name, sizeof(priv->adapter.name), "xlp9xx-i2c");
i2c_set_adapdata(&priv->adapter, priv);
err = i2c_add_adapter(&priv->adapter);
if (err) {
dev_err(&pdev->dev, "failed to add I2C adapter!\n");
return err;
}
platform_set_drvdata(pdev, priv);
dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);
return 0;
}
static int xlp9xx_i2c_remove(struct platform_device *pdev)
{
struct xlp9xx_i2c_dev *priv;
priv = platform_get_drvdata(pdev);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
synchronize_irq(priv->irq);
i2c_del_adapter(&priv->adapter);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0);
return 0;
}
static const struct of_device_id xlp9xx_i2c_of_match[] = {
{ .compatible = "netlogic,xlp980-i2c", },
{ /* sentinel */ },
};
static struct platform_driver xlp9xx_i2c_driver = {
.probe = xlp9xx_i2c_probe,
.remove = xlp9xx_i2c_remove,
.driver = {
.name = "xlp9xx-i2c",
.of_match_table = xlp9xx_i2c_of_match,
},
};
module_platform_driver(xlp9xx_i2c_driver);
MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>");
MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver");
MODULE_LICENSE("GPL v2");
...@@ -561,7 +561,7 @@ static int i2c_generic_recovery(struct i2c_adapter *adap) ...@@ -561,7 +561,7 @@ static int i2c_generic_recovery(struct i2c_adapter *adap)
int i = 0, val = 1, ret = 0; int i = 0, val = 1, ret = 0;
if (bri->prepare_recovery) if (bri->prepare_recovery)
bri->prepare_recovery(bri); bri->prepare_recovery(adap);
/* /*
* By this time SCL is high, as we need to give 9 falling-rising edges * By this time SCL is high, as we need to give 9 falling-rising edges
...@@ -586,7 +586,7 @@ static int i2c_generic_recovery(struct i2c_adapter *adap) ...@@ -586,7 +586,7 @@ static int i2c_generic_recovery(struct i2c_adapter *adap)
} }
if (bri->unprepare_recovery) if (bri->unprepare_recovery)
bri->unprepare_recovery(bri); bri->unprepare_recovery(adap);
return ret; return ret;
} }
...@@ -1875,6 +1875,13 @@ static int __init i2c_init(void) ...@@ -1875,6 +1875,13 @@ static int __init i2c_init(void)
{ {
int retval; int retval;
retval = of_alias_get_highest_id("i2c");
down_write(&__i2c_board_lock);
if (retval >= __i2c_first_dynamic_bus_num)
__i2c_first_dynamic_bus_num = retval + 1;
up_write(&__i2c_board_lock);
retval = bus_register(&i2c_bus_type); retval = bus_register(&i2c_bus_type);
if (retval) if (retval)
return retval; return retval;
...@@ -1926,6 +1933,65 @@ module_exit(i2c_exit); ...@@ -1926,6 +1933,65 @@ module_exit(i2c_exit);
* ---------------------------------------------------- * ----------------------------------------------------
*/ */
/* Check if val is exceeding the quirk IFF quirk is non 0 */
#define i2c_quirk_exceeded(val, quirk) ((quirk) && ((val) > (quirk)))
static int i2c_quirk_error(struct i2c_adapter *adap, struct i2c_msg *msg, char *err_msg)
{
dev_err_ratelimited(&adap->dev, "adapter quirk: %s (addr 0x%04x, size %u, %s)\n",
err_msg, msg->addr, msg->len,
msg->flags & I2C_M_RD ? "read" : "write");
return -EOPNOTSUPP;
}
static int i2c_check_for_quirks(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
const struct i2c_adapter_quirks *q = adap->quirks;
int max_num = q->max_num_msgs, i;
bool do_len_check = true;
if (q->flags & I2C_AQ_COMB) {
max_num = 2;
/* special checks for combined messages */
if (num == 2) {
if (q->flags & I2C_AQ_COMB_WRITE_FIRST && msgs[0].flags & I2C_M_RD)
return i2c_quirk_error(adap, &msgs[0], "1st comb msg must be write");
if (q->flags & I2C_AQ_COMB_READ_SECOND && !(msgs[1].flags & I2C_M_RD))
return i2c_quirk_error(adap, &msgs[1], "2nd comb msg must be read");
if (q->flags & I2C_AQ_COMB_SAME_ADDR && msgs[0].addr != msgs[1].addr)
return i2c_quirk_error(adap, &msgs[0], "comb msg only to same addr");
if (i2c_quirk_exceeded(msgs[0].len, q->max_comb_1st_msg_len))
return i2c_quirk_error(adap, &msgs[0], "msg too long");
if (i2c_quirk_exceeded(msgs[1].len, q->max_comb_2nd_msg_len))
return i2c_quirk_error(adap, &msgs[1], "msg too long");
do_len_check = false;
}
}
if (i2c_quirk_exceeded(num, max_num))
return i2c_quirk_error(adap, &msgs[0], "too many messages");
for (i = 0; i < num; i++) {
u16 len = msgs[i].len;
if (msgs[i].flags & I2C_M_RD) {
if (do_len_check && i2c_quirk_exceeded(len, q->max_read_len))
return i2c_quirk_error(adap, &msgs[i], "msg too long");
} else {
if (do_len_check && i2c_quirk_exceeded(len, q->max_write_len))
return i2c_quirk_error(adap, &msgs[i], "msg too long");
}
}
return 0;
}
/** /**
* __i2c_transfer - unlocked flavor of i2c_transfer * __i2c_transfer - unlocked flavor of i2c_transfer
* @adap: Handle to I2C bus * @adap: Handle to I2C bus
...@@ -1943,6 +2009,9 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1943,6 +2009,9 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
unsigned long orig_jiffies; unsigned long orig_jiffies;
int ret, try; int ret, try;
if (adap->quirks && i2c_check_for_quirks(adap, msgs, num))
return -EOPNOTSUPP;
/* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets /* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
* enabled. This is an efficient way of keeping the for-loop from * enabled. This is an efficient way of keeping the for-loop from
* being executed when not needed. * being executed when not needed.
......
...@@ -36,7 +36,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, ...@@ -36,7 +36,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
struct eeprom_data *eeprom = i2c_get_clientdata(client); struct eeprom_data *eeprom = i2c_get_clientdata(client);
switch (event) { switch (event) {
case I2C_SLAVE_REQ_WRITE_END: case I2C_SLAVE_WRITE_RECEIVED:
if (eeprom->first_write) { if (eeprom->first_write) {
eeprom->buffer_idx = *val; eeprom->buffer_idx = *val;
eeprom->first_write = false; eeprom->first_write = false;
...@@ -47,17 +47,23 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, ...@@ -47,17 +47,23 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
} }
break; break;
case I2C_SLAVE_REQ_READ_START: case I2C_SLAVE_READ_PROCESSED:
/* The previous byte made it to the bus, get next one */
eeprom->buffer_idx++;
/* fallthrough */
case I2C_SLAVE_READ_REQUESTED:
spin_lock(&eeprom->buffer_lock); spin_lock(&eeprom->buffer_lock);
*val = eeprom->buffer[eeprom->buffer_idx]; *val = eeprom->buffer[eeprom->buffer_idx];
spin_unlock(&eeprom->buffer_lock); spin_unlock(&eeprom->buffer_lock);
break; /*
* Do not increment buffer_idx here, because we don't know if
case I2C_SLAVE_REQ_READ_END: * this byte will be actually used. Read Linux I2C slave docs
eeprom->buffer_idx++; * for details.
*/
break; break;
case I2C_SLAVE_STOP: case I2C_SLAVE_STOP:
case I2C_SLAVE_WRITE_REQUESTED:
eeprom->first_write = true; eeprom->first_write = true;
break; break;
......
...@@ -76,10 +76,9 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, ...@@ -76,10 +76,9 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
return -ENODEV; return -ENODEV;
} }
adapter = of_find_i2c_adapter_by_node(adapter_np); adapter = of_find_i2c_adapter_by_node(adapter_np);
if (!adapter) { if (!adapter)
dev_err(&pdev->dev, "Cannot find parent bus\n");
return -EPROBE_DEFER; return -EPROBE_DEFER;
}
mux->data.parent = i2c_adapter_id(adapter); mux->data.parent = i2c_adapter_id(adapter);
put_device(&adapter->dev); put_device(&adapter->dev);
...@@ -177,11 +176,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev) ...@@ -177,11 +176,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
} }
parent = i2c_get_adapter(mux->data.parent); parent = i2c_get_adapter(mux->data.parent);
if (!parent) { if (!parent)
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
mux->data.parent);
return -EPROBE_DEFER; return -EPROBE_DEFER;
}
mux->parent = parent; mux->parent = parent;
mux->gpio_base = gpio_base; mux->gpio_base = gpio_base;
......
...@@ -204,9 +204,9 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -204,9 +204,9 @@ static int pca954x_probe(struct i2c_client *client,
i2c_set_clientdata(client, data); i2c_set_clientdata(client, data);
/* Get the mux out of reset if a reset GPIO is specified. */ /* Get the mux out of reset if a reset GPIO is specified. */
gpio = devm_gpiod_get(&client->dev, "reset"); gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW);
if (!IS_ERR(gpio)) if (IS_ERR(gpio))
gpiod_direction_output(gpio, 0); return PTR_ERR(gpio);
/* Write the mux register at addr to verify /* Write the mux register at addr to verify
* that the mux is in fact present. This also * that the mux is in fact present. This also
......
...@@ -1960,6 +1960,32 @@ int of_alias_get_id(struct device_node *np, const char *stem) ...@@ -1960,6 +1960,32 @@ int of_alias_get_id(struct device_node *np, const char *stem)
} }
EXPORT_SYMBOL_GPL(of_alias_get_id); EXPORT_SYMBOL_GPL(of_alias_get_id);
/**
* of_alias_get_highest_id - Get highest alias id for the given stem
* @stem: Alias stem to be examined
*
* The function travels the lookup table to get the highest alias id for the
* given alias stem. It returns the alias id if found.
*/
int of_alias_get_highest_id(const char *stem)
{
struct alias_prop *app;
int id = -ENODEV;
mutex_lock(&of_mutex);
list_for_each_entry(app, &aliases_lookup, link) {
if (strcmp(app->stem, stem) != 0)
continue;
if (app->id > id)
id = app->id;
}
mutex_unlock(&of_mutex);
return id;
}
EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
u32 *pu) u32 *pu)
{ {
......
...@@ -253,10 +253,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) ...@@ -253,10 +253,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
#if IS_ENABLED(CONFIG_I2C_SLAVE) #if IS_ENABLED(CONFIG_I2C_SLAVE)
enum i2c_slave_event { enum i2c_slave_event {
I2C_SLAVE_REQ_READ_START, I2C_SLAVE_READ_REQUESTED,
I2C_SLAVE_REQ_READ_END, I2C_SLAVE_WRITE_REQUESTED,
I2C_SLAVE_REQ_WRITE_START, I2C_SLAVE_READ_PROCESSED,
I2C_SLAVE_REQ_WRITE_END, I2C_SLAVE_WRITE_RECEIVED,
I2C_SLAVE_STOP, I2C_SLAVE_STOP,
}; };
...@@ -435,8 +435,8 @@ struct i2c_bus_recovery_info { ...@@ -435,8 +435,8 @@ struct i2c_bus_recovery_info {
void (*set_scl)(struct i2c_adapter *, int val); void (*set_scl)(struct i2c_adapter *, int val);
int (*get_sda)(struct i2c_adapter *); int (*get_sda)(struct i2c_adapter *);
void (*prepare_recovery)(struct i2c_bus_recovery_info *bri); void (*prepare_recovery)(struct i2c_adapter *);
void (*unprepare_recovery)(struct i2c_bus_recovery_info *bri); void (*unprepare_recovery)(struct i2c_adapter *);
/* gpio recovery */ /* gpio recovery */
int scl_gpio; int scl_gpio;
...@@ -449,6 +449,48 @@ int i2c_recover_bus(struct i2c_adapter *adap); ...@@ -449,6 +449,48 @@ int i2c_recover_bus(struct i2c_adapter *adap);
int i2c_generic_gpio_recovery(struct i2c_adapter *adap); int i2c_generic_gpio_recovery(struct i2c_adapter *adap);
int i2c_generic_scl_recovery(struct i2c_adapter *adap); int i2c_generic_scl_recovery(struct i2c_adapter *adap);
/**
* struct i2c_adapter_quirks - describe flaws of an i2c adapter
* @flags: see I2C_AQ_* for possible flags and read below
* @max_num_msgs: maximum number of messages per transfer
* @max_write_len: maximum length of a write message
* @max_read_len: maximum length of a read message
* @max_comb_1st_msg_len: maximum length of the first msg in a combined message
* @max_comb_2nd_msg_len: maximum length of the second msg in a combined message
*
* Note about combined messages: Some I2C controllers can only send one message
* per transfer, plus something called combined message or write-then-read.
* This is (usually) a small write message followed by a read message and
* barely enough to access register based devices like EEPROMs. There is a flag
* to support this mode. It implies max_num_msg = 2 and does the length checks
* with max_comb_*_len because combined message mode usually has its own
* limitations. Because of HW implementations, some controllers can actually do
* write-then-anything or other variants. To support that, write-then-read has
* been broken out into smaller bits like write-first and read-second which can
* be combined as needed.
*/
struct i2c_adapter_quirks {
u64 flags;
int max_num_msgs;
u16 max_write_len;
u16 max_read_len;
u16 max_comb_1st_msg_len;
u16 max_comb_2nd_msg_len;
};
/* enforce max_num_msgs = 2 and use max_comb_*_len for length checks */
#define I2C_AQ_COMB BIT(0)
/* first combined message must be write */
#define I2C_AQ_COMB_WRITE_FIRST BIT(1)
/* second combined message must be read */
#define I2C_AQ_COMB_READ_SECOND BIT(2)
/* both combined messages must have the same target address */
#define I2C_AQ_COMB_SAME_ADDR BIT(3)
/* convenience macro for typical write-then read case */
#define I2C_AQ_COMB_WRITE_THEN_READ (I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | \
I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR)
/* /*
* i2c_adapter is the structure used to identify a physical i2c bus along * i2c_adapter is the structure used to identify a physical i2c bus along
* with the access algorithms necessary to access it. * with the access algorithms necessary to access it.
...@@ -474,6 +516,7 @@ struct i2c_adapter { ...@@ -474,6 +516,7 @@ struct i2c_adapter {
struct list_head userspace_clients; struct list_head userspace_clients;
struct i2c_bus_recovery_info *bus_recovery_info; struct i2c_bus_recovery_info *bus_recovery_info;
const struct i2c_adapter_quirks *quirks;
}; };
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
......
...@@ -332,6 +332,7 @@ extern int of_count_phandle_with_args(const struct device_node *np, ...@@ -332,6 +332,7 @@ extern int of_count_phandle_with_args(const struct device_node *np,
extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
extern int of_alias_get_id(struct device_node *np, const char *stem); extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_highest_id(const char *stem);
extern int of_machine_is_compatible(const char *compat); extern int of_machine_is_compatible(const char *compat);
...@@ -594,6 +595,11 @@ static inline int of_alias_get_id(struct device_node *np, const char *stem) ...@@ -594,6 +595,11 @@ static inline int of_alias_get_id(struct device_node *np, const char *stem)
return -ENOSYS; return -ENOSYS;
} }
static inline int of_alias_get_highest_id(const char *stem)
{
return -ENOSYS;
}
static inline int of_machine_is_compatible(const char *compat) static inline int of_machine_is_compatible(const char *compat)
{ {
return 0; return 0;
......
...@@ -18,6 +18,7 @@ struct davinci_i2c_platform_data { ...@@ -18,6 +18,7 @@ struct davinci_i2c_platform_data {
unsigned int bus_delay; /* post-transaction delay (usec) */ unsigned int bus_delay; /* post-transaction delay (usec) */
unsigned int sda_pin; /* GPIO pin ID to use for SDA */ unsigned int sda_pin; /* GPIO pin ID to use for SDA */
unsigned int scl_pin; /* GPIO pin ID to use for SCL */ unsigned int scl_pin; /* GPIO pin ID to use for SCL */
bool has_pfunc; /*chip has a ICPFUNC register */
}; };
/* for board setup code */ /* for board setup code */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册