提交 9bca19a0 编写于 作者: L Linus Torvalds

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

Pull i2c updates from Wolfram Sang:

 - mainly feature additions to drivers (stm32f7, qup, xlp9xx, mlxcpld, ...)

 - conversion to use the i2c_8bit_addr_from_msg macro consistently

 - move includes to platform_data

 - core updates to allow the (still in review) I3C subsystem to connect

 - and the regular share of smaller driver updates

* 'i2c/for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (68 commits)
  i2c: qup: fix building without CONFIG_ACPI
  i2c: tegra: Remove suspend-resume
  i2c: imx-lpi2c: Switch to SPDX identifier
  i2c: mxs: Switch to SPDX identifier
  i2c: busses: make use of i2c_8bit_addr_from_msg
  i2c: algos: make use of i2c_8bit_addr_from_msg
  i2c: rcar: document R8A77980 bindings
  i2c: qup: Add command-line parameter to override SCL frequency
  i2c: qup: Correct duty cycle for FM and FM+
  i2c: qup: Add support for Fast Mode Plus
  i2c: qup: add probe path for Centriq ACPI devices
  i2c: robotfuzz-osif: drop pointless test
  i2c: robotfuzz-osif: remove pointless local variable
  i2c: rk3x: Don't print visible virtual mapping MMIO address
  i2c: opal: don't check number of messages in the driver
  i2c: ibm_iic: don't check number of messages in the driver
  i2c: imx: Switch to SPDX identifier
  i2c: mux: pca954x: merge calls to of_match_device and of_device_get_match_data
  i2c: mux: demux-pinctrl: use proper parent device for demux adapter
  i2c: mux: improve error message for failed symlink
  ...
...@@ -24,7 +24,7 @@ Recommended properties : ...@@ -24,7 +24,7 @@ Recommended properties :
- 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 - ti,has-pfunc: boolean; if defined, it indicates that SoC supports PFUNC
registers. PFUNC registers allow to switch I2C pins to function as registers. PFUNC registers allow to switch I2C pins to function as
GPIOs, so they can by toggled manually. GPIOs, so they can be toggled manually.
Example (enbw_cmc board): Example (enbw_cmc board):
i2c@1c22000 { i2c@1c22000 {
......
...@@ -15,6 +15,7 @@ Required properties: ...@@ -15,6 +15,7 @@ Required properties:
"renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC. "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC.
"renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC. "renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC.
"renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC. "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
"renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC.
"renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC. "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC.
"renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device.
"renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible
......
...@@ -8,9 +8,7 @@ Required properties: ...@@ -8,9 +8,7 @@ Required properties:
(b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c.
(c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used
inside HDMIPHY block found on several samsung SoCs inside HDMIPHY block found on several samsung SoCs
(d) "samsung, exynos5440-i2c", for s3c2440-like i2c used (d) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as
on EXYNOS5440 which does not need GPIO configuration.
(e) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as
a host to SATA PHY controller on an internal bus. a host to SATA PHY controller on an internal bus.
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
......
...@@ -20,6 +20,10 @@ The next transaction types are supported: ...@@ -20,6 +20,10 @@ The next transaction types are supported:
- Write Byte/Block. - Write Byte/Block.
Registers: Registers:
CPBLTY 0x0 - capability reg.
Bits [6:5] - transaction length. b01 - 72B is supported,
36B in other case.
Bit 7 - SMBus block read support.
CTRL 0x1 - control reg. CTRL 0x1 - control reg.
Resets all the registers. Resets all the registers.
HALF_CYC 0x4 - cycle reg. HALF_CYC 0x4 - cycle reg.
......
...@@ -18,7 +18,7 @@ Usage ...@@ -18,7 +18,7 @@ Usage
i2c-ocores uses the platform bus, so you need to provide a struct i2c-ocores uses the platform bus, so you need to provide a struct
platform_device with the base address and interrupt number. The platform_device with the base address and interrupt number. The
dev.platform_data of the device should also point to a struct dev.platform_data of the device should also point to a struct
ocores_i2c_platform_data (see linux/i2c-ocores.h) describing the ocores_i2c_platform_data (see linux/platform_data/i2c-ocores.h) describing the
distance between registers and the input clock speed. distance between registers and the input clock speed.
There is also a possibility to attach a list of i2c_board_info which There is also a possibility to attach a list of i2c_board_info which
the i2c-ocores driver will add to the bus upon creation. the i2c-ocores driver will add to the bus upon creation.
......
...@@ -30,12 +30,12 @@ i2c-mux-gpio uses the platform bus, so you need to provide a struct ...@@ -30,12 +30,12 @@ i2c-mux-gpio uses the platform bus, so you need to provide a struct
platform_device with the platform_data pointing to a struct platform_device with the platform_data pointing to a struct
i2c_mux_gpio_platform_data with the I2C adapter number of the master i2c_mux_gpio_platform_data with the I2C adapter number of the master
bus, the number of bus segments to create and the GPIO pins used bus, the number of bus segments to create and the GPIO pins used
to control it. See include/linux/i2c-mux-gpio.h for details. to control it. See include/linux/platform_data/i2c-mux-gpio.h for details.
E.G. something like this for a MUX providing 4 bus segments E.G. something like this for a MUX providing 4 bus segments
controlled through 3 GPIO pins: controlled through 3 GPIO pins:
#include <linux/i2c-mux-gpio.h> #include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
static const unsigned myboard_gpiomux_gpios[] = { static const unsigned myboard_gpiomux_gpios[] = {
......
...@@ -5953,14 +5953,14 @@ GENERIC GPIO I2C DRIVER ...@@ -5953,14 +5953,14 @@ GENERIC GPIO I2C DRIVER
M: Haavard Skinnemoen <hskinnemoen@gmail.com> M: Haavard Skinnemoen <hskinnemoen@gmail.com>
S: Supported S: Supported
F: drivers/i2c/busses/i2c-gpio.c F: drivers/i2c/busses/i2c-gpio.c
F: include/linux/i2c-gpio.h F: include/linux/platform_data/i2c-gpio.h
GENERIC GPIO I2C MULTIPLEXER DRIVER GENERIC GPIO I2C MULTIPLEXER DRIVER
M: Peter Korsgaard <peter.korsgaard@barco.com> M: Peter Korsgaard <peter.korsgaard@barco.com>
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
S: Supported S: Supported
F: drivers/i2c/muxes/i2c-mux-gpio.c F: drivers/i2c/muxes/i2c-mux-gpio.c
F: include/linux/i2c-mux-gpio.h F: include/linux/platform_data/i2c-mux-gpio.h
F: Documentation/i2c/muxes/i2c-mux-gpio F: Documentation/i2c/muxes/i2c-mux-gpio
GENERIC HDLC (WAN) DRIVERS GENERIC HDLC (WAN) DRIVERS
...@@ -10392,7 +10392,7 @@ F: arch/arm/mach-omap1/ ...@@ -10392,7 +10392,7 @@ F: arch/arm/mach-omap1/
F: arch/arm/plat-omap/ F: arch/arm/plat-omap/
F: arch/arm/configs/omap1_defconfig F: arch/arm/configs/omap1_defconfig
F: drivers/i2c/busses/i2c-omap.c F: drivers/i2c/busses/i2c-omap.c
F: include/linux/i2c-omap.h F: include/linux/platform_data/i2c-omap.h
OMAP2+ SUPPORT OMAP2+ SUPPORT
M: Tony Lindgren <tony@atomide.com> M: Tony Lindgren <tony@atomide.com>
...@@ -10424,7 +10424,7 @@ F: drivers/regulator/tps65218-regulator.c ...@@ -10424,7 +10424,7 @@ F: drivers/regulator/tps65218-regulator.c
F: drivers/regulator/tps65910-regulator.c F: drivers/regulator/tps65910-regulator.c
F: drivers/regulator/twl-regulator.c F: drivers/regulator/twl-regulator.c
F: drivers/regulator/twl6030-regulator.c F: drivers/regulator/twl6030-regulator.c
F: include/linux/i2c-omap.h F: include/linux/platform_data/i2c-omap.h
ONION OMEGA2+ BOARD ONION OMEGA2+ BOARD
M: Harvey Hunt <harveyhuntnexus@gmail.com> M: Harvey Hunt <harveyhuntnexus@gmail.com>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/platform_data/pca953x.h> #include <linux/platform_data/pca953x.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/htcpld.h> #include <linux/htcpld.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define __ARCH_ARM_MACH_OMAP1_COMMON_H #define __ARCH_ARM_MACH_OMAP1_COMMON_H
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <asm/exception.h> #include <asm/exception.h>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <mach/mux.h> #include <mach/mux.h>
#include "soc.h" #include "soc.h"
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mfd/twl.h> #include <linux/mfd/twl.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/irqchip/irq-omap-intc.h> #include <linux/irqchip/irq-omap-intc.h>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* XXX these should be marked initdata for multi-OMAP kernels * XXX these should be marked initdata for multi-OMAP kernels
*/ */
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/omap-dma.h> #include <linux/omap-dma.h>
#include "omap_hwmod.h" #include "omap_hwmod.h"
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* XXX these should be marked initdata for multi-OMAP kernels * XXX these should be marked initdata for multi-OMAP kernels
*/ */
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/hsmmc-omap.h>
#include <linux/omap-dma.h> #include <linux/omap-dma.h>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include "omap_hwmod.h" #include "omap_hwmod.h"
#include "omap_hwmod_common_data.h" #include "omap_hwmod_common_data.h"
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* XXX these should be marked initdata for multi-OMAP kernels * XXX these should be marked initdata for multi-OMAP kernels
*/ */
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/power/smartreflex.h> #include <linux/power/smartreflex.h>
#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/hsmmc-omap.h>
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/hsmmc-omap.h>
#include <linux/power/smartreflex.h> #include <linux/power/smartreflex.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/omap-dma.h> #include <linux/omap-dma.h>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/hsmmc-omap.h>
#include <linux/power/smartreflex.h> #include <linux/power/smartreflex.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/omap-dma.h> #include <linux/omap-dma.h>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/hsmmc-omap.h>
#include <linux/power/smartreflex.h> #include <linux/power/smartreflex.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/omap-dma.h> #include <linux/omap-dma.h>
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/wm97xx.h> #include <linux/wm97xx.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h> #include <linux/usb/gpio_vbus.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/platform_data/i2c-pxa.h> #include <linux/platform_data/i2c-pxa.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include "generic.h" #include "generic.h"
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/idle.h> #include <asm/idle.h>
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-pca-platform.h> #include <linux/platform_data/i2c-pca-platform.h>
#include <linux/i2c-algo-pca.h> #include <linux/i2c-algo-pca.h>
#include <linux/usb/r8a66597.h> #include <linux/usb/r8a66597.h>
#include <linux/sh_intc.h> #include <linux/sh_intc.h>
......
...@@ -519,9 +519,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ...@@ -519,9 +519,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
} }
} }
} else { /* normal 7bit address */ } else { /* normal 7bit address */
addr = msg->addr << 1; addr = i2c_8bit_addr_from_msg(msg);
if (flags & I2C_M_RD)
addr |= 1;
if (flags & I2C_M_REV_DIR_ADDR) if (flags & I2C_M_REV_DIR_ADDR)
addr ^= 1; addr ^= 1;
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
......
...@@ -112,11 +112,8 @@ static int pca_address(struct i2c_algo_pca_data *adap, ...@@ -112,11 +112,8 @@ static int pca_address(struct i2c_algo_pca_data *adap,
struct i2c_msg *msg) struct i2c_msg *msg)
{ {
int sta = pca_get_con(adap); int sta = pca_get_con(adap);
int addr; int addr = i2c_8bit_addr_from_msg(msg);
addr = ((0x7f & msg->addr) << 1);
if (msg->flags & I2C_M_RD)
addr |= 1;
DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr); msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
......
...@@ -291,13 +291,9 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, ...@@ -291,13 +291,9 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
static int pcf_doAddress(struct i2c_algo_pcf_data *adap, static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
struct i2c_msg *msg) struct i2c_msg *msg)
{ {
unsigned short flags = msg->flags; unsigned char addr = i2c_8bit_addr_from_msg(msg);
unsigned char addr;
addr = msg->addr << 1; if (msg->flags & I2C_M_REV_DIR_ADDR)
if (flags & I2C_M_RD)
addr |= 1;
if (flags & I2C_M_REV_DIR_ADDR)
addr ^= 1; addr ^= 1;
i2c_outb(adap, addr); i2c_outb(adap, addr);
......
...@@ -943,6 +943,7 @@ config I2C_STM32F4 ...@@ -943,6 +943,7 @@ config I2C_STM32F4
config I2C_STM32F7 config I2C_STM32F7
tristate "STMicroelectronics STM32F7 I2C support" tristate "STMicroelectronics STM32F7 I2C support"
depends on ARCH_STM32 || COMPILE_TEST depends on ARCH_STM32 || COMPILE_TEST
select I2C_SLAVE
help help
Enable this option to add support for STM32 I2C controller embedded Enable this option to add support for STM32 I2C controller embedded
in STM32F7 SoCs. in STM32F7 SoCs.
......
...@@ -94,7 +94,8 @@ obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o ...@@ -94,7 +94,8 @@ obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o
obj-$(CONFIG_I2C_ST) += i2c-st.o obj-$(CONFIG_I2C_ST) += i2c-st.o
obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o
obj-$(CONFIG_I2C_STM32F7) += i2c-stm32f7.o i2c-stm32f7-drv-objs := i2c-stm32f7.o i2c-stm32.o
obj-$(CONFIG_I2C_STM32F7) += i2c-stm32f7-drv.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o
obj-$(CONFIG_I2C_SYNQUACER) += i2c-synquacer.o obj-$(CONFIG_I2C_SYNQUACER) += i2c-synquacer.o
......
...@@ -335,13 +335,12 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) ...@@ -335,13 +335,12 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus)
{ {
u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD; u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD;
struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; struct i2c_msg *msg = &bus->msgs[bus->msgs_index];
u8 slave_addr = msg->addr << 1; u8 slave_addr = i2c_8bit_addr_from_msg(msg);
bus->master_state = ASPEED_I2C_MASTER_START; bus->master_state = ASPEED_I2C_MASTER_START;
bus->buf_index = 0; bus->buf_index = 0;
if (msg->flags & I2C_M_RD) { if (msg->flags & I2C_M_RD) {
slave_addr |= 1;
command |= ASPEED_I2CD_M_RX_CMD; command |= ASPEED_I2CD_M_RX_CMD;
/* Need to let the hardware know to NACK after RX. */ /* Need to let the hardware know to NACK after RX. */
if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN)) if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN))
......
...@@ -518,8 +518,16 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id) ...@@ -518,8 +518,16 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
* the RXRDY interrupt first in order to not keep garbage data in the * the RXRDY interrupt first in order to not keep garbage data in the
* Receive Holding Register for the next transfer. * Receive Holding Register for the next transfer.
*/ */
if (irqstatus & AT91_TWI_RXRDY) if (irqstatus & AT91_TWI_RXRDY) {
at91_twi_read_next_byte(dev); /*
* Read all available bytes at once by polling RXRDY usable w/
* and w/o FIFO. With FIFO enabled we could also read RXFL and
* avoid polling RXRDY.
*/
do {
at91_twi_read_next_byte(dev);
} while (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY);
}
/* /*
* When a NACK condition is detected, the I2C controller sets the NACK, * When a NACK condition is detected, the I2C controller sets the NACK,
......
...@@ -351,13 +351,15 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -351,13 +351,15 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
* addr_2: addr[7:0] * addr_2: addr[7:0]
*/ */
addr_1 = 0xF0 | ((msg->addr >> 7) & 0x06); addr_1 = 0xF0 | ((msg->addr >> 7) & 0x06);
if (i2c_m_rd(msg))
addr_1 |= 1; /* Set the R/nW bit of the address */
addr_2 = msg->addr & 0xFF; addr_2 = msg->addr & 0xFF;
} else { } else {
/* 7-bit address /* 7-bit address
* addr_1: addr[6:0] | (R/nW) * addr_1: addr[6:0] | (R/nW)
* addr_2: dont care * addr_2: dont care
*/ */
addr_1 = (msg->addr << 1) & 0xFF; addr_1 = i2c_8bit_addr_from_msg(msg);
addr_2 = 0; addr_2 = 0;
} }
...@@ -365,7 +367,6 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) ...@@ -365,7 +367,6 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
/* I2C read transfer */ /* I2C read transfer */
rx_xfer = i2c_m_recv_len(msg) ? I2C_SMBUS_BLOCK_MAX : msg->len; rx_xfer = i2c_m_recv_len(msg) ? I2C_SMBUS_BLOCK_MAX : msg->len;
tx_xfer = 0; tx_xfer = 0;
addr_1 |= 1; /* Set the R/nW bit of the address */
} else { } else {
/* I2C write transfer */ /* I2C write transfer */
rx_xfer = 0; rx_xfer = 0;
...@@ -532,23 +533,23 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -532,23 +533,23 @@ static int axxia_i2c_probe(struct platform_device *pdev)
if (idev->bus_clk_rate == 0) if (idev->bus_clk_rate == 0)
idev->bus_clk_rate = 100000; /* default clock rate */ idev->bus_clk_rate = 100000; /* default clock rate */
ret = clk_prepare_enable(idev->i2c_clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
return ret;
}
ret = axxia_i2c_init(idev); ret = axxia_i2c_init(idev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to initialize\n"); dev_err(&pdev->dev, "failed to initialize\n");
return ret; goto error_disable_clk;
} }
ret = devm_request_irq(&pdev->dev, irq, axxia_i2c_isr, 0, ret = devm_request_irq(&pdev->dev, irq, axxia_i2c_isr, 0,
pdev->name, idev); pdev->name, idev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to claim IRQ%d\n", irq); dev_err(&pdev->dev, "failed to claim IRQ%d\n", irq);
return ret; goto error_disable_clk;
}
ret = clk_prepare_enable(idev->i2c_clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
return ret;
} }
i2c_set_adapdata(&idev->adapter, idev); i2c_set_adapdata(&idev->adapter, idev);
...@@ -563,12 +564,14 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -563,12 +564,14 @@ static int axxia_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, idev); platform_set_drvdata(pdev, idev);
ret = i2c_add_adapter(&idev->adapter); ret = i2c_add_adapter(&idev->adapter);
if (ret) { if (ret)
clk_disable_unprepare(idev->i2c_clk); goto error_disable_clk;
return ret;
}
return 0; return 0;
error_disable_clk:
clk_disable_unprepare(idev->i2c_clk);
return ret;
} }
static int axxia_i2c_remove(struct platform_device *pdev) static int axxia_i2c_remove(struct platform_device *pdev)
......
...@@ -149,18 +149,17 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) ...@@ -149,18 +149,17 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset; return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;
} }
void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) void __i2c_dw_disable(struct dw_i2c_dev *dev)
{
dw_writel(dev, enable, DW_IC_ENABLE);
}
void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
{ {
int timeout = 100; int timeout = 100;
do { do {
__i2c_dw_enable(dev, enable); __i2c_dw_disable_nowait(dev);
if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == enable) /*
* The enable status register may be unimplemented, but
* in that case this test reads zero and exits the loop.
*/
if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == 0)
return; return;
/* /*
...@@ -171,8 +170,7 @@ void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable) ...@@ -171,8 +170,7 @@ void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
usleep_range(25, 250); usleep_range(25, 250);
} while (timeout--); } while (timeout--);
dev_warn(dev->dev, "timeout in %sabling adapter\n", dev_warn(dev->dev, "timeout in disabling adapter\n");
enable ? "en" : "dis");
} }
unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
...@@ -277,7 +275,7 @@ u32 i2c_dw_func(struct i2c_adapter *adap) ...@@ -277,7 +275,7 @@ u32 i2c_dw_func(struct i2c_adapter *adap)
void i2c_dw_disable(struct dw_i2c_dev *dev) void i2c_dw_disable(struct dw_i2c_dev *dev)
{ {
/* Disable controller */ /* Disable controller */
__i2c_dw_enable_and_wait(dev, false); __i2c_dw_disable(dev);
/* Disable all interupts */ /* Disable all interupts */
dw_writel(dev, 0, DW_IC_INTR_MASK); dw_writel(dev, 0, DW_IC_INTR_MASK);
......
...@@ -297,8 +297,6 @@ u32 dw_readl(struct dw_i2c_dev *dev, int offset); ...@@ -297,8 +297,6 @@ u32 dw_readl(struct dw_i2c_dev *dev, int offset);
void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset); void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset); u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset); u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable);
void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable);
unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev); unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev);
int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare);
int i2c_dw_acquire_lock(struct dw_i2c_dev *dev); int i2c_dw_acquire_lock(struct dw_i2c_dev *dev);
...@@ -309,6 +307,18 @@ u32 i2c_dw_func(struct i2c_adapter *adap); ...@@ -309,6 +307,18 @@ u32 i2c_dw_func(struct i2c_adapter *adap);
void i2c_dw_disable(struct dw_i2c_dev *dev); void i2c_dw_disable(struct dw_i2c_dev *dev);
void i2c_dw_disable_int(struct dw_i2c_dev *dev); void i2c_dw_disable_int(struct dw_i2c_dev *dev);
static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
{
dw_writel(dev, 1, DW_IC_ENABLE);
}
static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
{
dw_writel(dev, 0, DW_IC_ENABLE);
}
void __i2c_dw_disable(struct dw_i2c_dev *dev);
extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev); extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev);
extern int i2c_dw_probe(struct dw_i2c_dev *dev); extern int i2c_dw_probe(struct dw_i2c_dev *dev);
#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE) #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE)
......
...@@ -81,7 +81,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev) ...@@ -81,7 +81,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
/* Disable the adapter */ /* Disable the adapter */
__i2c_dw_enable_and_wait(dev, false); __i2c_dw_disable(dev);
/* Set standard and fast speed deviders for high/low periods */ /* Set standard and fast speed deviders for high/low periods */
...@@ -180,7 +180,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) ...@@ -180,7 +180,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
u32 ic_con, ic_tar = 0; u32 ic_con, ic_tar = 0;
/* Disable the adapter */ /* Disable the adapter */
__i2c_dw_enable_and_wait(dev, false); __i2c_dw_disable(dev);
/* If the slave address is ten bit address, enable 10BITADDR */ /* If the slave address is ten bit address, enable 10BITADDR */
ic_con = dw_readl(dev, DW_IC_CON); ic_con = dw_readl(dev, DW_IC_CON);
...@@ -209,7 +209,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) ...@@ -209,7 +209,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
i2c_dw_disable_int(dev); i2c_dw_disable_int(dev);
/* Enable the adapter */ /* Enable the adapter */
__i2c_dw_enable(dev, true); __i2c_dw_enable(dev);
/* Dummy read to avoid the register getting stuck on Bay Trail */ /* Dummy read to avoid the register getting stuck on Bay Trail */
dw_readl(dev, DW_IC_ENABLE_STATUS); dw_readl(dev, DW_IC_ENABLE_STATUS);
...@@ -462,7 +462,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ...@@ -462,7 +462,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
* additional interrupts are a hardware bug or this driver doesn't * additional interrupts are a hardware bug or this driver doesn't
* handle them correctly yet. * handle them correctly yet.
*/ */
__i2c_dw_enable(dev, false); __i2c_dw_disable_nowait(dev);
if (dev->msg_err) { if (dev->msg_err) {
ret = dev->msg_err; ret = dev->msg_err;
......
...@@ -75,7 +75,7 @@ static int i2c_dw_init_slave(struct dw_i2c_dev *dev) ...@@ -75,7 +75,7 @@ static int i2c_dw_init_slave(struct dw_i2c_dev *dev)
comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
/* Disable the adapter. */ /* Disable the adapter. */
__i2c_dw_enable_and_wait(dev, false); __i2c_dw_disable(dev);
/* Configure SDA Hold Time if required. */ /* Configure SDA Hold Time if required. */
reg = dw_readl(dev, DW_IC_COMP_VERSION); reg = dw_readl(dev, DW_IC_COMP_VERSION);
...@@ -119,11 +119,11 @@ static int i2c_dw_reg_slave(struct i2c_client *slave) ...@@ -119,11 +119,11 @@ static int i2c_dw_reg_slave(struct i2c_client *slave)
* Set slave address in the IC_SAR register, * Set slave address in the IC_SAR register,
* the address to which the DW_apb_i2c responds. * the address to which the DW_apb_i2c responds.
*/ */
__i2c_dw_enable(dev, false); __i2c_dw_disable_nowait(dev);
dw_writel(dev, slave->addr, DW_IC_SAR); dw_writel(dev, slave->addr, DW_IC_SAR);
dev->slave = slave; dev->slave = slave;
__i2c_dw_enable(dev, true); __i2c_dw_enable(dev);
dev->cmd_err = 0; dev->cmd_err = 0;
dev->msg_write_idx = 0; dev->msg_write_idx = 0;
......
...@@ -360,11 +360,11 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, ...@@ -360,11 +360,11 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
if (ret < 0) if (ret < 0)
goto abort; goto abort;
} }
ret = diolan_i2c_put_byte_ack(dev,
i2c_8bit_addr_from_msg(pmsg));
if (ret < 0)
goto abort;
if (pmsg->flags & I2C_M_RD) { if (pmsg->flags & I2C_M_RD) {
ret =
diolan_i2c_put_byte_ack(dev, (pmsg->addr << 1) | 1);
if (ret < 0)
goto abort;
for (j = 0; j < pmsg->len; j++) { for (j = 0; j < pmsg->len; j++) {
u8 byte; u8 byte;
bool ack = j < pmsg->len - 1; bool ack = j < pmsg->len - 1;
...@@ -393,9 +393,6 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, ...@@ -393,9 +393,6 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
pmsg->buf[j] = byte; pmsg->buf[j] = byte;
} }
} else { } else {
ret = diolan_i2c_put_byte_ack(dev, pmsg->addr << 1);
if (ret < 0)
goto abort;
for (j = 0; j < pmsg->len; j++) { for (j = 0; j < pmsg->len; j++) {
ret = diolan_i2c_put_byte_ack(dev, ret = diolan_i2c_put_byte_ack(dev,
pmsg->buf[j]); pmsg->buf[j]);
......
...@@ -144,8 +144,7 @@ static void efm32_i2c_send_next_msg(struct efm32_i2c_ddata *ddata) ...@@ -144,8 +144,7 @@ static void efm32_i2c_send_next_msg(struct efm32_i2c_ddata *ddata)
struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg];
efm32_i2c_write32(ddata, REG_CMD, REG_CMD_START); efm32_i2c_write32(ddata, REG_CMD, REG_CMD_START);
efm32_i2c_write32(ddata, REG_TXDATA, cur_msg->addr << 1 | efm32_i2c_write32(ddata, REG_TXDATA, i2c_8bit_addr_from_msg(cur_msg));
(cur_msg->flags & I2C_M_RD ? 1 : 0));
} }
static void efm32_i2c_send_next_byte(struct efm32_i2c_ddata *ddata) static void efm32_i2c_send_next_byte(struct efm32_i2c_ddata *ddata)
......
...@@ -414,7 +414,7 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap, ...@@ -414,7 +414,7 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
iowrite32(addr_8_lsb, p + PCH_I2CDR); iowrite32(addr_8_lsb, p + PCH_I2CDR);
} else { } else {
/* set 7 bit slave address and R/W bit as 0 */ /* set 7 bit slave address and R/W bit as 0 */
iowrite32(addr << 1, p + PCH_I2CDR); iowrite32(i2c_8bit_addr_from_msg(msgs), p + PCH_I2CDR);
if (first) if (first)
pch_i2c_start(adap); pch_i2c_start(adap);
} }
...@@ -538,8 +538,7 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, ...@@ -538,8 +538,7 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR); iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
} else { } else {
/* 7 address bits + R/W bit */ /* 7 address bits + R/W bit */
addr = (((addr) << 1) | (I2C_RD)); iowrite32(i2c_8bit_addr_from_msg(msgs), p + PCH_I2CDR);
iowrite32(addr, p + PCH_I2CDR);
} }
/* check if it is the first message */ /* check if it is the first message */
......
...@@ -149,7 +149,7 @@ static int __em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -149,7 +149,7 @@ static int __em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
em_clear_set_bit(priv, 0, I2C_BIT_STT0, I2C_OFS_IICC0); em_clear_set_bit(priv, 0, I2C_BIT_STT0, I2C_OFS_IICC0);
/* Send slave address and R/W type */ /* Send slave address and R/W type */
writeb((msg->addr << 1) | read, priv->base + I2C_OFS_IIC0); writeb(i2c_8bit_addr_from_msg(msg), priv->base + I2C_OFS_IIC0);
/* Wait for transaction */ /* Wait for transaction */
status = em_i2c_wait_for_event(priv); status = em_i2c_wait_for_event(priv);
......
...@@ -707,7 +707,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, ...@@ -707,7 +707,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num) struct i2c_msg *msgs, int num)
{ {
struct exynos5_i2c *i2c = adap->algo_data; struct exynos5_i2c *i2c = adap->algo_data;
int i = 0, ret = 0, stop = 0; int i, ret;
if (i2c->suspended) { if (i2c->suspended) {
dev_err(i2c->dev, "HS-I2C is not initialized.\n"); dev_err(i2c->dev, "HS-I2C is not initialized.\n");
...@@ -718,30 +718,15 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, ...@@ -718,30 +718,15 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap,
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < num; i++, msgs++) { for (i = 0; i < num; ++i) {
stop = (i == num - 1); ret = exynos5_i2c_xfer_msg(i2c, msgs + i, i + 1 == num);
if (ret)
ret = exynos5_i2c_xfer_msg(i2c, msgs, stop); break;
if (ret < 0)
goto out;
}
if (i == num) {
ret = num;
} else {
/* Only one message, cannot access the device */
if (i == 1)
ret = -EREMOTEIO;
else
ret = i;
dev_warn(i2c->dev, "xfer message failed\n");
} }
out:
clk_disable(i2c->clk); clk_disable(i2c->clk);
return ret;
return ret ?: num;
} }
static u32 exynos5_i2c_func(struct i2c_adapter *adap) static u32 exynos5_i2c_func(struct i2c_adapter *adap)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
#define I2C_OVER_INTR BIT(0) #define I2C_OVER_INTR BIT(0)
#define HIX5I2C_MAX_FREQ 400000 /* 400k */ #define HIX5I2C_MAX_FREQ 400000 /* 400k */
#define HIX5I2C_READ_OPERATION 0x01
enum hix5hd2_i2c_state { enum hix5hd2_i2c_state {
HIX5I2C_STAT_RW_ERR = -1, HIX5I2C_STAT_RW_ERR = -1,
...@@ -311,12 +310,8 @@ static void hix5hd2_i2c_message_start(struct hix5hd2_i2c_priv *priv, int stop) ...@@ -311,12 +310,8 @@ static void hix5hd2_i2c_message_start(struct hix5hd2_i2c_priv *priv, int stop)
hix5hd2_i2c_clr_all_irq(priv); hix5hd2_i2c_clr_all_irq(priv);
hix5hd2_i2c_enable_irq(priv); hix5hd2_i2c_enable_irq(priv);
if (priv->msg->flags & I2C_M_RD) writel_relaxed(i2c_8bit_addr_from_msg(priv->msg),
writel_relaxed((priv->msg->addr << 1) | HIX5I2C_READ_OPERATION, priv->regs + HIX5I2C_TXR);
priv->regs + HIX5I2C_TXR);
else
writel_relaxed(priv->msg->addr << 1,
priv->regs + HIX5I2C_TXR);
writel_relaxed(I2C_WRITE | I2C_START, priv->regs + HIX5I2C_COM); writel_relaxed(I2C_WRITE | I2C_START, priv->regs + HIX5I2C_COM);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
...@@ -377,17 +372,7 @@ static int hix5hd2_i2c_xfer(struct i2c_adapter *adap, ...@@ -377,17 +372,7 @@ static int hix5hd2_i2c_xfer(struct i2c_adapter *adap,
goto out; goto out;
} }
if (i == num) { ret = num;
ret = num;
} else {
/* Only one message, cannot access the device */
if (i == 1)
ret = -EREMOTEIO;
else
ret = i;
dev_warn(priv->dev, "xfer message failed\n");
}
out: out:
pm_runtime_mark_last_busy(priv->dev); pm_runtime_mark_last_busy(priv->dev);
...@@ -471,7 +456,6 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev) ...@@ -471,7 +456,6 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
goto err_clk; goto err_clk;
} }
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_set_autosuspend_delay(priv->dev, MSEC_PER_SEC); pm_runtime_set_autosuspend_delay(priv->dev, MSEC_PER_SEC);
pm_runtime_use_autosuspend(priv->dev); pm_runtime_use_autosuspend(priv->dev);
pm_runtime_set_active(priv->dev); pm_runtime_set_active(priv->dev);
......
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI #if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c-mux-gpio.h> #include <linux/platform_data/i2c-mux-gpio.h>
#endif #endif
/* I801 SMBus address offsets */ /* I801 SMBus address offsets */
...@@ -1710,7 +1710,7 @@ static void i801_shutdown(struct pci_dev *dev) ...@@ -1710,7 +1710,7 @@ static void i801_shutdown(struct pci_dev *dev)
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int i801_suspend(struct device *dev) static int i801_suspend(struct device *dev)
{ {
struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_dev *pci_dev = to_pci_dev(dev);
...@@ -1731,8 +1731,7 @@ static int i801_resume(struct device *dev) ...@@ -1731,8 +1731,7 @@ static int i801_resume(struct device *dev)
} }
#endif #endif
static UNIVERSAL_DEV_PM_OPS(i801_pm_ops, i801_suspend, static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume);
i801_resume, NULL);
static struct pci_driver i801_driver = { static struct pci_driver i801_driver = {
.name = "i801_smbus", .name = "i801_smbus",
......
...@@ -561,9 +561,6 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -561,9 +561,6 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num); DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
if (!num)
return 0;
/* Check the sanity of the passed messages. /* Check the sanity of the passed messages.
* Uhh, generic i2c layer is more suitable place for such code... * Uhh, generic i2c layer is more suitable place for such code...
*/ */
......
// SPDX-License-Identifier: GPL-2.0+
/* /*
* This is i.MX low power i2c controller driver. * This is i.MX low power i2c controller driver.
* *
* Copyright 2016 Freescale Semiconductor, Inc. * Copyright 2016 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/ */
#include <linux/clk.h> #include <linux/clk.h>
...@@ -180,15 +170,13 @@ static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx, ...@@ -180,15 +170,13 @@ static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx,
struct i2c_msg *msgs) struct i2c_msg *msgs)
{ {
unsigned int temp; unsigned int temp;
u8 read;
temp = readl(lpi2c_imx->base + LPI2C_MCR); temp = readl(lpi2c_imx->base + LPI2C_MCR);
temp |= MCR_RRF | MCR_RTF; temp |= MCR_RRF | MCR_RTF;
writel(temp, lpi2c_imx->base + LPI2C_MCR); writel(temp, lpi2c_imx->base + LPI2C_MCR);
writel(0x7f00, lpi2c_imx->base + LPI2C_MSR); writel(0x7f00, lpi2c_imx->base + LPI2C_MSR);
read = msgs->flags & I2C_M_RD; temp = i2c_8bit_addr_from_msg(msgs) | (GEN_START << 8);
temp = (msgs->addr << 1 | read) | (GEN_START << 8);
writel(temp, lpi2c_imx->base + LPI2C_MTDR); writel(temp, lpi2c_imx->base + LPI2C_MTDR);
return lpi2c_imx_bus_busy(lpi2c_imx); return lpi2c_imx_bus_busy(lpi2c_imx);
......
// SPDX-License-Identifier: GPL-2.0+
/* /*
* Copyright (C) 2002 Motorola GSG-China * Copyright (C) 2002 Motorola GSG-China
* *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Author: * Author:
* Darius Augulis, Teltonika Inc. * Darius Augulis, Teltonika Inc.
* *
...@@ -630,7 +621,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, ...@@ -630,7 +621,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
* Write slave address. * Write slave address.
* The first byte must be transmitted by the CPU. * The first byte must be transmitted by the CPU.
*/ */
imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR); imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
reinit_completion(&i2c_imx->dma->cmd_complete); reinit_completion(&i2c_imx->dma->cmd_complete);
time_left = wait_for_completion_timeout( time_left = wait_for_completion_timeout(
&i2c_imx->dma->cmd_complete, &i2c_imx->dma->cmd_complete,
...@@ -760,10 +751,10 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) ...@@ -760,10 +751,10 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
int i, result; int i, result;
dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n", dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n",
__func__, msgs->addr << 1); __func__, i2c_8bit_addr_from_msg(msgs));
/* write slave address */ /* write slave address */
imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR); imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
result = i2c_imx_trx_complete(i2c_imx); result = i2c_imx_trx_complete(i2c_imx);
if (result) if (result)
return result; return result;
...@@ -796,10 +787,10 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo ...@@ -796,10 +787,10 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
dev_dbg(&i2c_imx->adapter.dev, dev_dbg(&i2c_imx->adapter.dev,
"<%s> write slave address: addr=0x%x\n", "<%s> write slave address: addr=0x%x\n",
__func__, (msgs->addr << 1) | 0x01); __func__, i2c_8bit_addr_from_msg(msgs));
/* write slave address */ /* write slave address */
imx_i2c_write_reg((msgs->addr << 1) | 0x01, i2c_imx, IMX_I2C_I2DR); imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
result = i2c_imx_trx_complete(i2c_imx); result = i2c_imx_trx_complete(i2c_imx);
if (result) if (result)
return result; return result;
......
...@@ -124,15 +124,14 @@ static int kempld_i2c_process(struct kempld_i2c_data *i2c) ...@@ -124,15 +124,14 @@ static int kempld_i2c_process(struct kempld_i2c_data *i2c)
/* 10 bit address? */ /* 10 bit address? */
if (i2c->msg->flags & I2C_M_TEN) { if (i2c->msg->flags & I2C_M_TEN) {
addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6);
/* Set read bit if necessary */
addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
i2c->state = STATE_ADDR10; i2c->state = STATE_ADDR10;
} else { } else {
addr = (i2c->msg->addr << 1); addr = i2c_8bit_addr_from_msg(i2c->msg);
i2c->state = STATE_START; i2c->state = STATE_START;
} }
/* Set read bit if necessary */
addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
kempld_write8(pld, KEMPLD_I2C_DATA, addr); kempld_write8(pld, KEMPLD_I2C_DATA, addr);
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START); kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START);
......
...@@ -45,13 +45,16 @@ ...@@ -45,13 +45,16 @@
#define MLXCPLD_I2C_VALID_FLAG (I2C_M_RECV_LEN | I2C_M_RD) #define MLXCPLD_I2C_VALID_FLAG (I2C_M_RECV_LEN | I2C_M_RD)
#define MLXCPLD_I2C_BUS_NUM 1 #define MLXCPLD_I2C_BUS_NUM 1
#define MLXCPLD_I2C_DATA_REG_SZ 36 #define MLXCPLD_I2C_DATA_REG_SZ 36
#define MLXCPLD_I2C_DATA_SZ_BIT BIT(5)
#define MLXCPLD_I2C_DATA_SZ_MASK GENMASK(6, 5)
#define MLXCPLD_I2C_SMBUS_BLK_BIT BIT(7)
#define MLXCPLD_I2C_MAX_ADDR_LEN 4 #define MLXCPLD_I2C_MAX_ADDR_LEN 4
#define MLXCPLD_I2C_RETR_NUM 2 #define MLXCPLD_I2C_RETR_NUM 2
#define MLXCPLD_I2C_XFER_TO 500000 /* usec */ #define MLXCPLD_I2C_XFER_TO 500000 /* usec */
#define MLXCPLD_I2C_POLL_TIME 2000 /* usec */ #define MLXCPLD_I2C_POLL_TIME 2000 /* usec */
/* LPC I2C registers */ /* LPC I2C registers */
#define MLXCPLD_LPCI2C_LPF_REG 0x0 #define MLXCPLD_LPCI2C_CPBLTY_REG 0x0
#define MLXCPLD_LPCI2C_CTRL_REG 0x1 #define MLXCPLD_LPCI2C_CTRL_REG 0x1
#define MLXCPLD_LPCI2C_HALF_CYC_REG 0x4 #define MLXCPLD_LPCI2C_HALF_CYC_REG 0x4
#define MLXCPLD_LPCI2C_I2C_HOLD_REG 0x5 #define MLXCPLD_LPCI2C_I2C_HOLD_REG 0x5
...@@ -83,6 +86,7 @@ struct mlxcpld_i2c_priv { ...@@ -83,6 +86,7 @@ struct mlxcpld_i2c_priv {
struct mutex lock; struct mutex lock;
struct mlxcpld_i2c_curr_xfer xfer; struct mlxcpld_i2c_curr_xfer xfer;
struct device *dev; struct device *dev;
bool smbus_block;
}; };
static void mlxcpld_i2c_lpc_write_buf(u8 *data, u8 len, u32 addr) static void mlxcpld_i2c_lpc_write_buf(u8 *data, u8 len, u32 addr)
...@@ -230,7 +234,7 @@ static void mlxcpld_i2c_set_transf_data(struct mlxcpld_i2c_priv *priv, ...@@ -230,7 +234,7 @@ static void mlxcpld_i2c_set_transf_data(struct mlxcpld_i2c_priv *priv,
* All upper layers currently are never use transfer with more than * All upper layers currently are never use transfer with more than
* 2 messages. Actually, it's also not so relevant in Mellanox systems * 2 messages. Actually, it's also not so relevant in Mellanox systems
* because of HW limitation. Max size of transfer is not more than 32 * because of HW limitation. Max size of transfer is not more than 32
* bytes in the current x86 LPCI2C bridge. * or 68 bytes in the current x86 LPCI2C bridge.
*/ */
priv->xfer.cmd = msgs[num - 1].flags & I2C_M_RD; priv->xfer.cmd = msgs[num - 1].flags & I2C_M_RD;
...@@ -295,7 +299,7 @@ static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv) ...@@ -295,7 +299,7 @@ static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv)
static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv) static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
{ {
int status, i, timeout = 0; int status, i, timeout = 0;
u8 datalen; u8 datalen, val;
do { do {
usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME); usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
...@@ -324,9 +328,22 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv) ...@@ -324,9 +328,22 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
* Actual read data len will be always the same as * Actual read data len will be always the same as
* requested len. 0xff (line pull-up) will be returned * requested len. 0xff (line pull-up) will be returned
* if slave has no data to return. Thus don't read * if slave has no data to return. Thus don't read
* MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD. * MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD. Only in case of
* SMBus block read transaction data len can be different,
* check this case.
*/ */
datalen = priv->xfer.data_len; mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_NUM_ADDR_REG, &val,
1);
if (priv->smbus_block && (val & MLXCPLD_I2C_SMBUS_BLK_BIT)) {
mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG,
&datalen, 1);
if (unlikely(datalen > (I2C_SMBUS_BLOCK_MAX + 1))) {
dev_err(priv->dev, "Incorrect smbus block read message len\n");
return -E2BIG;
}
} else {
datalen = priv->xfer.data_len;
}
mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_DATA_REG, mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_DATA_REG,
priv->xfer.msg[i].buf, datalen); priv->xfer.msg[i].buf, datalen);
...@@ -344,12 +361,20 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv) ...@@ -344,12 +361,20 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
static void mlxcpld_i2c_xfer_msg(struct mlxcpld_i2c_priv *priv) static void mlxcpld_i2c_xfer_msg(struct mlxcpld_i2c_priv *priv)
{ {
int i, len = 0; int i, len = 0;
u8 cmd; u8 cmd, val;
mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG, mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG,
&priv->xfer.data_len, 1); &priv->xfer.data_len, 1);
mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_ADDR_REG,
&priv->xfer.addr_width, 1); val = priv->xfer.addr_width;
/* Notify HW about SMBus block read transaction */
if (priv->smbus_block && priv->xfer.msg_num >= 2 &&
priv->xfer.msg[1].len == 1 &&
(priv->xfer.msg[1].flags & I2C_M_RECV_LEN) &&
(priv->xfer.msg[1].flags & I2C_M_RD))
val |= MLXCPLD_I2C_SMBUS_BLK_BIT;
mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_NUM_ADDR_REG, &val, 1);
for (i = 0; i < priv->xfer.msg_num; i++) { for (i = 0; i < priv->xfer.msg_num; i++) {
if ((priv->xfer.msg[i].flags & I2C_M_RD) != I2C_M_RD) { if ((priv->xfer.msg[i].flags & I2C_M_RD) != I2C_M_RD) {
...@@ -425,7 +450,14 @@ static int mlxcpld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -425,7 +450,14 @@ static int mlxcpld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
static u32 mlxcpld_i2c_func(struct i2c_adapter *adap) static u32 mlxcpld_i2c_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA; struct mlxcpld_i2c_priv *priv = i2c_get_adapdata(adap);
if (priv->smbus_block)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BLOCK_DATA;
else
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_I2C_BLOCK;
} }
static const struct i2c_algorithm mlxcpld_i2c_algo = { static const struct i2c_algorithm mlxcpld_i2c_algo = {
...@@ -440,6 +472,13 @@ static const struct i2c_adapter_quirks mlxcpld_i2c_quirks = { ...@@ -440,6 +472,13 @@ static const struct i2c_adapter_quirks mlxcpld_i2c_quirks = {
.max_comb_1st_msg_len = 4, .max_comb_1st_msg_len = 4,
}; };
static const struct i2c_adapter_quirks mlxcpld_i2c_quirks_ext = {
.flags = I2C_AQ_COMB_WRITE_THEN_READ,
.max_read_len = MLXCPLD_I2C_DATA_REG_SZ * 2 - MLXCPLD_I2C_MAX_ADDR_LEN,
.max_write_len = MLXCPLD_I2C_DATA_REG_SZ * 2,
.max_comb_1st_msg_len = 4,
};
static struct i2c_adapter mlxcpld_i2c_adapter = { static struct i2c_adapter mlxcpld_i2c_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "i2c-mlxcpld", .name = "i2c-mlxcpld",
...@@ -454,6 +493,7 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev) ...@@ -454,6 +493,7 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
{ {
struct mlxcpld_i2c_priv *priv; struct mlxcpld_i2c_priv *priv;
int err; int err;
u8 val;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -466,6 +506,16 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev) ...@@ -466,6 +506,16 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
/* Register with i2c layer */ /* Register with i2c layer */
mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO); mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO);
/* Read capability register */
mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_CPBLTY_REG, &val, 1);
/* Check support for extended transaction length */
if ((val & MLXCPLD_I2C_DATA_SZ_MASK) == MLXCPLD_I2C_DATA_SZ_BIT)
mlxcpld_i2c_adapter.quirks = &mlxcpld_i2c_quirks_ext;
/* Check support for smbus block transaction */
if (val & MLXCPLD_I2C_SMBUS_BLK_BIT)
priv->smbus_block = true;
if (pdev->id >= -1)
mlxcpld_i2c_adapter.nr = pdev->id;
priv->adap = mlxcpld_i2c_adapter; priv->adap = mlxcpld_i2c_adapter;
priv->adap.dev.parent = &pdev->dev; priv->adap.dev.parent = &pdev->dev;
priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR; priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
...@@ -734,7 +735,6 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c) ...@@ -734,7 +735,6 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c)
static int mtk_i2c_probe(struct platform_device *pdev) static int mtk_i2c_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id;
int ret = 0; int ret = 0;
struct mtk_i2c *i2c; struct mtk_i2c *i2c;
struct clk *clk; struct clk *clk;
...@@ -761,11 +761,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) ...@@ -761,11 +761,7 @@ static int mtk_i2c_probe(struct platform_device *pdev)
init_completion(&i2c->msg_complete); init_completion(&i2c->msg_complete);
of_id = of_match_node(mtk_i2c_of_match, pdev->dev.of_node); i2c->dev_comp = of_device_get_match_data(&pdev->dev);
if (!of_id)
return -EINVAL;
i2c->dev_comp = of_id->data;
i2c->adap.dev.of_node = pdev->dev.of_node; i2c->adap.dev.of_node = pdev->dev.of_node;
i2c->dev = &pdev->dev; i2c->dev = &pdev->dev;
i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.parent = &pdev->dev;
......
// SPDX-License-Identifier: GPL-2.0+
/* /*
* Freescale MXS I2C bus driver * Freescale MXS I2C bus driver
* *
...@@ -7,12 +8,6 @@ ...@@ -7,12 +8,6 @@
* based on a (non-working) driver which was: * based on a (non-working) driver which was:
* *
* Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/ */
#include <linux/slab.h> #include <linux/slab.h>
...@@ -180,9 +175,10 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap, ...@@ -180,9 +175,10 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc;
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap); struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
i2c->addr_data = i2c_8bit_addr_from_msg(msg);
if (msg->flags & I2C_M_RD) { if (msg->flags & I2C_M_RD) {
i2c->dma_read = true; i2c->dma_read = true;
i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_READ;
/* /*
* SELECT command. * SELECT command.
...@@ -240,7 +236,6 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap, ...@@ -240,7 +236,6 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
} }
} else { } else {
i2c->dma_read = false; i2c->dma_read = false;
i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_WRITE;
/* /*
* WRITE command. * WRITE command.
...@@ -371,7 +366,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ...@@ -371,7 +366,7 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
struct i2c_msg *msg, uint32_t flags) struct i2c_msg *msg, uint32_t flags)
{ {
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap); struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
uint32_t addr_data = msg->addr << 1; uint32_t addr_data = i2c_8bit_addr_from_msg(msg);
uint32_t data = 0; uint32_t data = 0;
int i, ret, xlen = 0, xmit = 0; int i, ret, xlen = 0, xmit = 0;
uint32_t start; uint32_t start;
...@@ -411,8 +406,6 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ...@@ -411,8 +406,6 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
*/ */
BUG_ON(msg->len > 4); BUG_ON(msg->len > 4);
addr_data |= I2C_SMBUS_READ;
/* SELECT command. */ /* SELECT command. */
mxs_i2c_pio_trigger_write_cmd(i2c, MXS_CMD_I2C_SELECT, mxs_i2c_pio_trigger_write_cmd(i2c, MXS_CMD_I2C_SELECT,
addr_data); addr_data);
...@@ -450,7 +443,6 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap, ...@@ -450,7 +443,6 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
* fast enough. It is possible to transfer arbitrary amount * fast enough. It is possible to transfer arbitrary amount
* of data using PIO write. * of data using PIO write.
*/ */
addr_data |= I2C_SMBUS_WRITE;
/* /*
* The LSB of data buffer is the first byte blasted across * The LSB of data buffer is the first byte blasted across
......
...@@ -1012,8 +1012,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -1012,8 +1012,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
goto err_no_mem; goto err_no_mem;
} }
pm_suspend_ignore_children(&adev->dev, true);
dev->clk = devm_clk_get(&adev->dev, NULL); dev->clk = devm_clk_get(&adev->dev, NULL);
if (IS_ERR(dev->clk)) { if (IS_ERR(dev->clk)) {
dev_err(&adev->dev, "could not get i2c clock\n"); dev_err(&adev->dev, "could not get i2c clock\n");
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/i2c-ocores.h> #include <linux/platform_data/i2c-ocores.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/log2.h> #include <linux/log2.h>
...@@ -222,10 +222,7 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -222,10 +222,7 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
i2c->nmsgs = num; i2c->nmsgs = num;
i2c->state = STATE_START; i2c->state = STATE_START;
oc_setreg(i2c, OCI2C_DATA, oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg));
(i2c->msg->addr << 1) |
((i2c->msg->flags & I2C_M_RD) ? 1:0));
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c-omap.h> #include <linux/platform_data/i2c-omap.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
......
...@@ -94,8 +94,6 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -94,8 +94,6 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
*/ */
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
switch(num) { switch(num) {
case 0:
return 0;
case 1: case 1:
req.type = (msgs[0].flags & I2C_M_RD) ? req.type = (msgs[0].flags & I2C_M_RD) ?
OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE; OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE;
...@@ -114,8 +112,6 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -114,8 +112,6 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
req.size = cpu_to_be32(msgs[1].len); req.size = cpu_to_be32(msgs[1].len);
req.buffer_ra = cpu_to_be64(__pa(msgs[1].buf)); req.buffer_ra = cpu_to_be64(__pa(msgs[1].buf));
break; break;
default:
return -EOPNOTSUPP;
} }
rc = i2c_opal_send_request(opal_id, &req); rc = i2c_opal_send_request(opal_id, &req);
......
...@@ -121,7 +121,7 @@ static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter, ...@@ -121,7 +121,7 @@ static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
read = msg->flags & I2C_M_RD ? 1 : 0; read = msg->flags & I2C_M_RD ? 1 : 0;
TXFIFO_WR(smbus, MTXFIFO_START | (msg->addr << 1) | read); TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg));
if (read) { if (read) {
TXFIFO_WR(smbus, msg->len | MTXFIFO_READ | TXFIFO_WR(smbus, msg->len | MTXFIFO_READ |
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c-algo-pca.h> #include <linux/i2c-algo-pca.h>
#include <linux/i2c-pca-platform.h> #include <linux/platform_data/i2c-pca-platform.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/io.h> #include <linux/io.h>
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c-pnx.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -29,6 +28,26 @@ ...@@ -29,6 +28,26 @@
#define I2C_PNX_SPEED_KHZ_DEFAULT 100 #define I2C_PNX_SPEED_KHZ_DEFAULT 100
#define I2C_PNX_REGION_SIZE 0x100 #define I2C_PNX_REGION_SIZE 0x100
struct i2c_pnx_mif {
int ret; /* Return value */
int mode; /* Interface mode */
struct completion complete; /* I/O completion */
struct timer_list timer; /* Timeout */
u8 * buf; /* Data buffer */
int len; /* Length of data buffer */
int order; /* RX Bytes to order via TX */
};
struct i2c_pnx_algo_data {
void __iomem *ioaddr;
struct i2c_pnx_mif mif;
int last;
struct clk *clk;
struct i2c_adapter adapter;
int irq;
u32 timeout;
};
enum { enum {
mstatus_tdi = 0x00000001, mstatus_tdi = 0x00000001,
mstatus_afi = 0x00000002, mstatus_afi = 0x00000002,
......
...@@ -136,8 +136,13 @@ ...@@ -136,8 +136,13 @@
*/ */
#define TOUT_MIN 2 #define TOUT_MIN 2
/* I2C Frequency Modes */
#define I2C_STANDARD_FREQ 100000
#define I2C_FAST_MODE_FREQ 400000
#define I2C_FAST_MODE_PLUS_FREQ 1000000
/* Default values. Use these if FW query fails */ /* Default values. Use these if FW query fails */
#define DEFAULT_CLK_FREQ 100000 #define DEFAULT_CLK_FREQ I2C_STANDARD_FREQ
#define DEFAULT_SRC_CLK 20000000 #define DEFAULT_SRC_CLK 20000000
/* /*
...@@ -150,6 +155,10 @@ ...@@ -150,6 +155,10 @@
/* TAG length for DATA READ in RX FIFO */ /* TAG length for DATA READ in RX FIFO */
#define READ_RX_TAGS_LEN 2 #define READ_RX_TAGS_LEN 2
static unsigned int scl_freq;
module_param_named(scl_freq, scl_freq, uint, 0444);
MODULE_PARM_DESC(scl_freq, "SCL frequency override");
/* /*
* count: no of blocks * count: no of blocks
* pos: current block number * pos: current block number
...@@ -453,7 +462,7 @@ static void qup_i2c_write_tx_fifo_v1(struct qup_i2c_dev *qup) ...@@ -453,7 +462,7 @@ static void qup_i2c_write_tx_fifo_v1(struct qup_i2c_dev *qup)
{ {
struct qup_i2c_block *blk = &qup->blk; struct qup_i2c_block *blk = &qup->blk;
struct i2c_msg *msg = qup->msg; struct i2c_msg *msg = qup->msg;
u32 addr = msg->addr << 1; u32 addr = i2c_8bit_addr_from_msg(msg);
u32 qup_tag; u32 qup_tag;
int idx; int idx;
u32 val; u32 val;
...@@ -1648,6 +1657,12 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup) ...@@ -1648,6 +1657,12 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup)
clk_disable_unprepare(qup->pclk); clk_disable_unprepare(qup->pclk);
} }
static const struct acpi_device_id qup_i2c_acpi_match[] = {
{ "QCOM8010"},
{ },
};
MODULE_DEVICE_TABLE(acpi, qup_i2c_acpi_match);
static int qup_i2c_probe(struct platform_device *pdev) static int qup_i2c_probe(struct platform_device *pdev)
{ {
static const int blk_sizes[] = {4, 16, 32}; static const int blk_sizes[] = {4, 16, 32};
...@@ -1669,10 +1684,15 @@ static int qup_i2c_probe(struct platform_device *pdev) ...@@ -1669,10 +1684,15 @@ static int qup_i2c_probe(struct platform_device *pdev)
init_completion(&qup->xfer); init_completion(&qup->xfer);
platform_set_drvdata(pdev, qup); platform_set_drvdata(pdev, qup);
ret = device_property_read_u32(qup->dev, "clock-frequency", &clk_freq); if (scl_freq) {
if (ret) { dev_notice(qup->dev, "Using override frequency of %u\n", scl_freq);
dev_notice(qup->dev, "using default clock-frequency %d", clk_freq = scl_freq;
DEFAULT_CLK_FREQ); } else {
ret = device_property_read_u32(qup->dev, "clock-frequency", &clk_freq);
if (ret) {
dev_notice(qup->dev, "using default clock-frequency %d",
DEFAULT_CLK_FREQ);
}
} }
if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) { if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
...@@ -1682,7 +1702,10 @@ static int qup_i2c_probe(struct platform_device *pdev) ...@@ -1682,7 +1702,10 @@ static int qup_i2c_probe(struct platform_device *pdev)
} else { } else {
qup->adap.algo = &qup_i2c_algo_v2; qup->adap.algo = &qup_i2c_algo_v2;
is_qup_v1 = false; is_qup_v1 = false;
ret = qup_i2c_req_dma(qup); if (acpi_match_device(qup_i2c_acpi_match, qup->dev))
goto nodma;
else
ret = qup_i2c_req_dma(qup);
if (ret == -EPROBE_DEFER) if (ret == -EPROBE_DEFER)
goto fail_dma; goto fail_dma;
...@@ -1734,8 +1757,8 @@ static int qup_i2c_probe(struct platform_device *pdev) ...@@ -1734,8 +1757,8 @@ static int qup_i2c_probe(struct platform_device *pdev)
} }
nodma: nodma:
/* We support frequencies up to FAST Mode (400KHz) */ /* We support frequencies up to FAST Mode Plus (1MHz) */
if (!clk_freq || clk_freq > 400000) { if (!clk_freq || clk_freq > I2C_FAST_MODE_PLUS_FREQ) {
dev_err(qup->dev, "clock frequency not supported %d\n", dev_err(qup->dev, "clock frequency not supported %d\n",
clk_freq); clk_freq);
return -EINVAL; return -EINVAL;
...@@ -1839,9 +1862,15 @@ static int qup_i2c_probe(struct platform_device *pdev) ...@@ -1839,9 +1862,15 @@ static int qup_i2c_probe(struct platform_device *pdev)
size = QUP_INPUT_FIFO_SIZE(io_mode); size = QUP_INPUT_FIFO_SIZE(io_mode);
qup->in_fifo_sz = qup->in_blk_sz * (2 << size); qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
hs_div = 3; hs_div = 3;
qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff); if (clk_freq <= I2C_STANDARD_FREQ) {
fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
} else {
/* 33%/66% duty cycle */
fs_div = ((src_clk_freq / clk_freq) - 6) * 2 / 3;
qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
}
/* /*
* Time it takes for a byte to be clocked out on the bus. * Time it takes for a byte to be clocked out on the bus.
...@@ -1959,14 +1988,6 @@ static const struct of_device_id qup_i2c_dt_match[] = { ...@@ -1959,14 +1988,6 @@ static const struct of_device_id qup_i2c_dt_match[] = {
}; };
MODULE_DEVICE_TABLE(of, qup_i2c_dt_match); MODULE_DEVICE_TABLE(of, qup_i2c_dt_match);
#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id qup_i2c_acpi_match[] = {
{ "QCOM8010"},
{ },
};
MODULE_DEVICE_TABLE(acpi, qup_i2c_acpi_match);
#endif
static struct platform_driver qup_i2c_driver = { static struct platform_driver qup_i2c_driver = {
.probe = qup_i2c_probe, .probe = qup_i2c_probe,
.remove = qup_i2c_remove, .remove = qup_i2c_remove,
......
...@@ -329,7 +329,7 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) ...@@ -329,7 +329,7 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
if (priv->msgs_left == 1) if (priv->msgs_left == 1)
priv->flags |= ID_LAST_MSG; priv->flags |= ID_LAST_MSG;
rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); rcar_i2c_write(priv, ICMAR, i2c_8bit_addr_from_msg(priv->msg));
/* /*
* We don't have a test case but the HW engineers say that the write order * We don't have a test case but the HW engineers say that the write order
* of ICMSR and ICMCR depends on whether we issue START or REP_START. Since * of ICMSR and ICMCR depends on whether we issue START or REP_START. Since
...@@ -542,6 +542,8 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) ...@@ -542,6 +542,8 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
* If next received data is the _LAST_, go to STOP phase. Might be * If next received data is the _LAST_, go to STOP phase. Might be
* overwritten by REP START when setting up a new msg. Not elegant * overwritten by REP START when setting up a new msg. Not elegant
* but the only stable sequence for REP START I have found so far. * but the only stable sequence for REP START I have found so far.
* If you want to change this code, make sure sending one transfer with
* four messages (WR-RD-WR-RD) works!
*/ */
if (priv->pos + 1 >= msg->len) if (priv->pos + 1 >= msg->len)
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
......
...@@ -167,15 +167,14 @@ static irqreturn_t riic_tdre_isr(int irq, void *data) ...@@ -167,15 +167,14 @@ static irqreturn_t riic_tdre_isr(int irq, void *data)
return IRQ_NONE; return IRQ_NONE;
if (riic->bytes_left == RIIC_INIT_MSG) { if (riic->bytes_left == RIIC_INIT_MSG) {
val = !!(riic->msg->flags & I2C_M_RD); if (riic->msg->flags & I2C_M_RD)
if (val)
/* On read, switch over to receive interrupt */ /* On read, switch over to receive interrupt */
riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER); riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER);
else else
/* On write, initialize length */ /* On write, initialize length */
riic->bytes_left = riic->msg->len; riic->bytes_left = riic->msg->len;
val |= (riic->msg->addr << 1); val = i2c_8bit_addr_from_msg(riic->msg);
} else { } else {
val = *riic->buf; val = *riic->buf;
riic->buf++; riic->buf++;
......
...@@ -1326,8 +1326,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev) ...@@ -1326,8 +1326,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_clk_notifier; goto err_clk_notifier;
dev_info(&pdev->dev, "Initialized RK3xxx I2C bus at %p\n", i2c->regs);
return 0; return 0;
err_clk_notifier: err_clk_notifier:
......
...@@ -62,27 +62,24 @@ static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, ...@@ -62,27 +62,24 @@ static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
{ {
struct osif_priv *priv = adapter->algo_data; struct osif_priv *priv = adapter->algo_data;
struct i2c_msg *pmsg; struct i2c_msg *pmsg;
int ret = 0; int ret;
int i, cmd; int i;
for (i = 0; ret >= 0 && i < num; i++) { for (i = 0; i < num; i++) {
pmsg = &msgs[i]; pmsg = &msgs[i];
if (pmsg->flags & I2C_M_RD) { if (pmsg->flags & I2C_M_RD) {
cmd = OSIFI2C_READ; ret = osif_usb_read(adapter, OSIFI2C_READ,
pmsg->flags, pmsg->addr,
ret = osif_usb_read(adapter, cmd, pmsg->flags, pmsg->buf, pmsg->len);
pmsg->addr, pmsg->buf,
pmsg->len);
if (ret != pmsg->len) { if (ret != pmsg->len) {
dev_err(&adapter->dev, "failure reading data\n"); dev_err(&adapter->dev, "failure reading data\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
} else { } else {
cmd = OSIFI2C_WRITE; ret = osif_usb_write(adapter, OSIFI2C_WRITE,
pmsg->flags, pmsg->addr,
ret = osif_usb_write(adapter, cmd, pmsg->flags, pmsg->buf, pmsg->len);
pmsg->addr, pmsg->buf, pmsg->len);
if (ret != pmsg->len) { if (ret != pmsg->len) {
dev_err(&adapter->dev, "failure writing data\n"); dev_err(&adapter->dev, "failure writing data\n");
return -EREMOTEIO; return -EREMOTEIO;
......
...@@ -154,8 +154,6 @@ static const struct of_device_id s3c24xx_i2c_match[] = { ...@@ -154,8 +154,6 @@ static const struct of_device_id s3c24xx_i2c_match[] = {
{ .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 }, { .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
{ .compatible = "samsung,s3c2440-hdmiphy-i2c", { .compatible = "samsung,s3c2440-hdmiphy-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) }, .data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
{ .compatible = "samsung,exynos5440-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_NO_GPIO) },
{ .compatible = "samsung,exynos5-sata-phy-i2c", { .compatible = "samsung,exynos5-sata-phy-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_POLL | QUIRK_NO_GPIO) }, .data = (void *)(QUIRK_S3C2440 | QUIRK_POLL | QUIRK_NO_GPIO) },
{}, {},
......
...@@ -899,17 +899,6 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) ...@@ -899,17 +899,6 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
if (resource_size(res) > 0x17) if (resource_size(res) > 0x17)
pd->flags |= IIC_FLAG_HAS_ICIC67; pd->flags |= IIC_FLAG_HAS_ICIC67;
/* Enable Runtime PM for this device.
*
* Also tell the Runtime PM core to ignore children
* for this device since it is valid for us to suspend
* this I2C master driver even though the slave devices
* on the I2C bus may not be suspended.
*
* The state of the I2C hardware bus is unaffected by
* the Runtime PM state.
*/
pm_suspend_ignore_children(&dev->dev, true);
pm_runtime_enable(&dev->dev); pm_runtime_enable(&dev->dev);
pm_runtime_get_sync(&dev->dev); pm_runtime_get_sync(&dev->dev);
......
/*
* i2c-stm32.c
*
* Copyright (C) M'boumba Cedric Madianga 2017
* Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
*
* License terms: GNU General Public License (GPL), version 2
*/
#include "i2c-stm32.h"
/* Functions for DMA support */
struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
dma_addr_t phy_addr,
u32 txdr_offset,
u32 rxdr_offset)
{
struct stm32_i2c_dma *dma;
struct dma_slave_config dma_sconfig;
int ret;
dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
if (!dma)
return NULL;
/* Request and configure I2C TX dma channel */
dma->chan_tx = dma_request_slave_channel(dev, "tx");
if (!dma->chan_tx) {
dev_dbg(dev, "can't request DMA tx channel\n");
ret = -EINVAL;
goto fail_al;
}
memset(&dma_sconfig, 0, sizeof(dma_sconfig));
dma_sconfig.dst_addr = phy_addr + txdr_offset;
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_sconfig.dst_maxburst = 1;
dma_sconfig.direction = DMA_MEM_TO_DEV;
ret = dmaengine_slave_config(dma->chan_tx, &dma_sconfig);
if (ret < 0) {
dev_err(dev, "can't configure tx channel\n");
goto fail_tx;
}
/* Request and configure I2C RX dma channel */
dma->chan_rx = dma_request_slave_channel(dev, "rx");
if (!dma->chan_rx) {
dev_err(dev, "can't request DMA rx channel\n");
ret = -EINVAL;
goto fail_tx;
}
memset(&dma_sconfig, 0, sizeof(dma_sconfig));
dma_sconfig.src_addr = phy_addr + rxdr_offset;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_sconfig.src_maxburst = 1;
dma_sconfig.direction = DMA_DEV_TO_MEM;
ret = dmaengine_slave_config(dma->chan_rx, &dma_sconfig);
if (ret < 0) {
dev_err(dev, "can't configure rx channel\n");
goto fail_rx;
}
init_completion(&dma->dma_complete);
dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
return dma;
fail_rx:
dma_release_channel(dma->chan_rx);
fail_tx:
dma_release_channel(dma->chan_tx);
fail_al:
devm_kfree(dev, dma);
dev_info(dev, "can't use DMA\n");
return NULL;
}
void stm32_i2c_dma_free(struct stm32_i2c_dma *dma)
{
dma->dma_buf = 0;
dma->dma_len = 0;
dma_release_channel(dma->chan_tx);
dma->chan_tx = NULL;
dma_release_channel(dma->chan_rx);
dma->chan_rx = NULL;
dma->chan_using = NULL;
}
int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
bool rd_wr, u32 len, u8 *buf,
dma_async_tx_callback callback,
void *dma_async_param)
{
struct dma_async_tx_descriptor *txdesc;
struct device *chan_dev;
int ret;
if (rd_wr) {
dma->chan_using = dma->chan_rx;
dma->dma_transfer_dir = DMA_DEV_TO_MEM;
dma->dma_data_dir = DMA_FROM_DEVICE;
} else {
dma->chan_using = dma->chan_tx;
dma->dma_transfer_dir = DMA_MEM_TO_DEV;
dma->dma_data_dir = DMA_TO_DEVICE;
}
dma->dma_len = len;
chan_dev = dma->chan_using->device->dev;
dma->dma_buf = dma_map_single(chan_dev, buf, dma->dma_len,
dma->dma_data_dir);
if (dma_mapping_error(chan_dev, dma->dma_buf)) {
dev_err(dev, "DMA mapping failed\n");
return -EINVAL;
}
txdesc = dmaengine_prep_slave_single(dma->chan_using, dma->dma_buf,
dma->dma_len,
dma->dma_transfer_dir,
DMA_PREP_INTERRUPT);
if (!txdesc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
ret = -EINVAL;
goto err;
}
reinit_completion(&dma->dma_complete);
txdesc->callback = callback;
txdesc->callback_param = dma_async_param;
ret = dma_submit_error(dmaengine_submit(txdesc));
if (ret < 0) {
dev_err(dev, "DMA submit failed\n");
goto err;
}
dma_async_issue_pending(dma->chan_using);
return 0;
err:
dma_unmap_single(chan_dev, dma->dma_buf, dma->dma_len,
dma->dma_data_dir);
return ret;
}
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
#ifndef _I2C_STM32_H #ifndef _I2C_STM32_H
#define _I2C_STM32_H #define _I2C_STM32_H
#include <linux/dma-direction.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
enum stm32_i2c_speed { enum stm32_i2c_speed {
STM32_I2C_SPEED_STANDARD, /* 100 kHz */ STM32_I2C_SPEED_STANDARD, /* 100 kHz */
STM32_I2C_SPEED_FAST, /* 400 kHz */ STM32_I2C_SPEED_FAST, /* 400 kHz */
...@@ -18,4 +22,37 @@ enum stm32_i2c_speed { ...@@ -18,4 +22,37 @@ enum stm32_i2c_speed {
STM32_I2C_SPEED_END, STM32_I2C_SPEED_END,
}; };
/**
* struct stm32_i2c_dma - DMA specific data
* @chan_tx: dma channel for TX transfer
* @chan_rx: dma channel for RX transfer
* @chan_using: dma channel used for the current transfer (TX or RX)
* @dma_buf: dma buffer
* @dma_len: dma buffer len
* @dma_transfer_dir: dma transfer direction indicator
* @dma_data_dir: dma transfer mode indicator
* @dma_complete: dma transfer completion
*/
struct stm32_i2c_dma {
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
struct dma_chan *chan_using;
dma_addr_t dma_buf;
unsigned int dma_len;
enum dma_transfer_direction dma_transfer_dir;
enum dma_data_direction dma_data_dir;
struct completion dma_complete;
};
struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
dma_addr_t phy_addr,
u32 txdr_offset, u32 rxdr_offset);
void stm32_i2c_dma_free(struct stm32_i2c_dma *dma);
int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
bool rd_wr, u32 len, u8 *buf,
dma_async_tx_callback callback,
void *dma_async_param);
#endif /* _I2C_STM32_H */ #endif /* _I2C_STM32_H */
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
/* STM32F7 I2C registers */ /* STM32F7 I2C registers */
#define STM32F7_I2C_CR1 0x00 #define STM32F7_I2C_CR1 0x00
#define STM32F7_I2C_CR2 0x04 #define STM32F7_I2C_CR2 0x04
#define STM32F7_I2C_OAR1 0x08
#define STM32F7_I2C_OAR2 0x0C
#define STM32F7_I2C_PECR 0x20
#define STM32F7_I2C_TIMINGR 0x10 #define STM32F7_I2C_TIMINGR 0x10
#define STM32F7_I2C_ISR 0x18 #define STM32F7_I2C_ISR 0x18
#define STM32F7_I2C_ICR 0x1C #define STM32F7_I2C_ICR 0x1C
...@@ -42,6 +45,10 @@ ...@@ -42,6 +45,10 @@
#define STM32F7_I2C_TXDR 0x28 #define STM32F7_I2C_TXDR 0x28
/* STM32F7 I2C control 1 */ /* STM32F7 I2C control 1 */
#define STM32F7_I2C_CR1_PECEN BIT(23)
#define STM32F7_I2C_CR1_SBC BIT(16)
#define STM32F7_I2C_CR1_RXDMAEN BIT(15)
#define STM32F7_I2C_CR1_TXDMAEN BIT(14)
#define STM32F7_I2C_CR1_ANFOFF BIT(12) #define STM32F7_I2C_CR1_ANFOFF BIT(12)
#define STM32F7_I2C_CR1_ERRIE BIT(7) #define STM32F7_I2C_CR1_ERRIE BIT(7)
#define STM32F7_I2C_CR1_TCIE BIT(6) #define STM32F7_I2C_CR1_TCIE BIT(6)
...@@ -57,34 +64,77 @@ ...@@ -57,34 +64,77 @@
| STM32F7_I2C_CR1_NACKIE \ | STM32F7_I2C_CR1_NACKIE \
| STM32F7_I2C_CR1_RXIE \ | STM32F7_I2C_CR1_RXIE \
| STM32F7_I2C_CR1_TXIE) | STM32F7_I2C_CR1_TXIE)
#define STM32F7_I2C_XFER_IRQ_MASK (STM32F7_I2C_CR1_TCIE \
| STM32F7_I2C_CR1_STOPIE \
| STM32F7_I2C_CR1_NACKIE \
| STM32F7_I2C_CR1_RXIE \
| STM32F7_I2C_CR1_TXIE)
/* STM32F7 I2C control 2 */ /* STM32F7 I2C control 2 */
#define STM32F7_I2C_CR2_PECBYTE BIT(26)
#define STM32F7_I2C_CR2_RELOAD BIT(24) #define STM32F7_I2C_CR2_RELOAD BIT(24)
#define STM32F7_I2C_CR2_NBYTES_MASK GENMASK(23, 16) #define STM32F7_I2C_CR2_NBYTES_MASK GENMASK(23, 16)
#define STM32F7_I2C_CR2_NBYTES(n) (((n) & 0xff) << 16) #define STM32F7_I2C_CR2_NBYTES(n) (((n) & 0xff) << 16)
#define STM32F7_I2C_CR2_NACK BIT(15) #define STM32F7_I2C_CR2_NACK BIT(15)
#define STM32F7_I2C_CR2_STOP BIT(14) #define STM32F7_I2C_CR2_STOP BIT(14)
#define STM32F7_I2C_CR2_START BIT(13) #define STM32F7_I2C_CR2_START BIT(13)
#define STM32F7_I2C_CR2_HEAD10R BIT(12)
#define STM32F7_I2C_CR2_ADD10 BIT(11)
#define STM32F7_I2C_CR2_RD_WRN BIT(10) #define STM32F7_I2C_CR2_RD_WRN BIT(10)
#define STM32F7_I2C_CR2_SADD10_MASK GENMASK(9, 0)
#define STM32F7_I2C_CR2_SADD10(n) (((n) & \
STM32F7_I2C_CR2_SADD10_MASK))
#define STM32F7_I2C_CR2_SADD7_MASK GENMASK(7, 1) #define STM32F7_I2C_CR2_SADD7_MASK GENMASK(7, 1)
#define STM32F7_I2C_CR2_SADD7(n) (((n) & 0x7f) << 1) #define STM32F7_I2C_CR2_SADD7(n) (((n) & 0x7f) << 1)
/* STM32F7 I2C Own Address 1 */
#define STM32F7_I2C_OAR1_OA1EN BIT(15)
#define STM32F7_I2C_OAR1_OA1MODE BIT(10)
#define STM32F7_I2C_OAR1_OA1_10_MASK GENMASK(9, 0)
#define STM32F7_I2C_OAR1_OA1_10(n) (((n) & \
STM32F7_I2C_OAR1_OA1_10_MASK))
#define STM32F7_I2C_OAR1_OA1_7_MASK GENMASK(7, 1)
#define STM32F7_I2C_OAR1_OA1_7(n) (((n) & 0x7f) << 1)
#define STM32F7_I2C_OAR1_MASK (STM32F7_I2C_OAR1_OA1_7_MASK \
| STM32F7_I2C_OAR1_OA1_10_MASK \
| STM32F7_I2C_OAR1_OA1EN \
| STM32F7_I2C_OAR1_OA1MODE)
/* STM32F7 I2C Own Address 2 */
#define STM32F7_I2C_OAR2_OA2EN BIT(15)
#define STM32F7_I2C_OAR2_OA2MSK_MASK GENMASK(10, 8)
#define STM32F7_I2C_OAR2_OA2MSK(n) (((n) & 0x7) << 8)
#define STM32F7_I2C_OAR2_OA2_7_MASK GENMASK(7, 1)
#define STM32F7_I2C_OAR2_OA2_7(n) (((n) & 0x7f) << 1)
#define STM32F7_I2C_OAR2_MASK (STM32F7_I2C_OAR2_OA2MSK_MASK \
| STM32F7_I2C_OAR2_OA2_7_MASK \
| STM32F7_I2C_OAR2_OA2EN)
/* STM32F7 I2C Interrupt Status */ /* STM32F7 I2C Interrupt Status */
#define STM32F7_I2C_ISR_ADDCODE_MASK GENMASK(23, 17)
#define STM32F7_I2C_ISR_ADDCODE_GET(n) \
(((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17)
#define STM32F7_I2C_ISR_DIR BIT(16)
#define STM32F7_I2C_ISR_BUSY BIT(15) #define STM32F7_I2C_ISR_BUSY BIT(15)
#define STM32F7_I2C_ISR_PECERR BIT(11)
#define STM32F7_I2C_ISR_ARLO BIT(9) #define STM32F7_I2C_ISR_ARLO BIT(9)
#define STM32F7_I2C_ISR_BERR BIT(8) #define STM32F7_I2C_ISR_BERR BIT(8)
#define STM32F7_I2C_ISR_TCR BIT(7) #define STM32F7_I2C_ISR_TCR BIT(7)
#define STM32F7_I2C_ISR_TC BIT(6) #define STM32F7_I2C_ISR_TC BIT(6)
#define STM32F7_I2C_ISR_STOPF BIT(5) #define STM32F7_I2C_ISR_STOPF BIT(5)
#define STM32F7_I2C_ISR_NACKF BIT(4) #define STM32F7_I2C_ISR_NACKF BIT(4)
#define STM32F7_I2C_ISR_ADDR BIT(3)
#define STM32F7_I2C_ISR_RXNE BIT(2) #define STM32F7_I2C_ISR_RXNE BIT(2)
#define STM32F7_I2C_ISR_TXIS BIT(1) #define STM32F7_I2C_ISR_TXIS BIT(1)
#define STM32F7_I2C_ISR_TXE BIT(0)
/* STM32F7 I2C Interrupt Clear */ /* STM32F7 I2C Interrupt Clear */
#define STM32F7_I2C_ICR_PECCF BIT(11)
#define STM32F7_I2C_ICR_ARLOCF BIT(9) #define STM32F7_I2C_ICR_ARLOCF BIT(9)
#define STM32F7_I2C_ICR_BERRCF BIT(8) #define STM32F7_I2C_ICR_BERRCF BIT(8)
#define STM32F7_I2C_ICR_STOPCF BIT(5) #define STM32F7_I2C_ICR_STOPCF BIT(5)
#define STM32F7_I2C_ICR_NACKCF BIT(4) #define STM32F7_I2C_ICR_NACKCF BIT(4)
#define STM32F7_I2C_ICR_ADDRCF BIT(3)
/* STM32F7 I2C Timing */ /* STM32F7 I2C Timing */
#define STM32F7_I2C_TIMINGR_PRESC(n) (((n) & 0xf) << 28) #define STM32F7_I2C_TIMINGR_PRESC(n) (((n) & 0xf) << 28)
...@@ -94,6 +144,8 @@ ...@@ -94,6 +144,8 @@
#define STM32F7_I2C_TIMINGR_SCLL(n) ((n) & 0xff) #define STM32F7_I2C_TIMINGR_SCLL(n) ((n) & 0xff)
#define STM32F7_I2C_MAX_LEN 0xff #define STM32F7_I2C_MAX_LEN 0xff
#define STM32F7_I2C_DMA_LEN_MIN 0x16
#define STM32F7_I2C_MAX_SLAVE 0x2
#define STM32F7_I2C_DNF_DEFAULT 0 #define STM32F7_I2C_DNF_DEFAULT 0
#define STM32F7_I2C_DNF_MAX 16 #define STM32F7_I2C_DNF_MAX 16
...@@ -159,11 +211,12 @@ struct stm32f7_i2c_setup { ...@@ -159,11 +211,12 @@ struct stm32f7_i2c_setup {
/** /**
* struct stm32f7_i2c_timings - private I2C output parameters * struct stm32f7_i2c_timings - private I2C output parameters
* @prec: Prescaler value * @node: List entry
* @presc: Prescaler value
* @scldel: Data setup time * @scldel: Data setup time
* @sdadel: Data hold time * @sdadel: Data hold time
* @sclh: SCL high period (master mode) * @sclh: SCL high period (master mode)
* @sclh: SCL low period (master mode) * @scll: SCL low period (master mode)
*/ */
struct stm32f7_i2c_timings { struct stm32f7_i2c_timings {
struct list_head node; struct list_head node;
...@@ -176,18 +229,30 @@ struct stm32f7_i2c_timings { ...@@ -176,18 +229,30 @@ struct stm32f7_i2c_timings {
/** /**
* struct stm32f7_i2c_msg - client specific data * struct stm32f7_i2c_msg - client specific data
* @addr: 8-bit slave addr, including r/w bit * @addr: 8-bit or 10-bit slave addr, including r/w bit
* @count: number of bytes to be transferred * @count: number of bytes to be transferred
* @buf: data buffer * @buf: data buffer
* @result: result of the transfer * @result: result of the transfer
* @stop: last I2C msg to be sent, i.e. STOP to be generated * @stop: last I2C msg to be sent, i.e. STOP to be generated
* @smbus: boolean to know if the I2C IP is used in SMBus mode
* @size: type of SMBus protocol
* @read_write: direction of SMBus protocol
* SMBus block read and SMBus block write - block read process call protocols
* @smbus_buf: buffer to be used for SMBus protocol transfer. It will
* contain a maximum of 32 bytes of data + byte command + byte count + PEC
* This buffer has to be 32-bit aligned to be compliant with memory address
* register in DMA mode.
*/ */
struct stm32f7_i2c_msg { struct stm32f7_i2c_msg {
u8 addr; u16 addr;
u32 count; u32 count;
u8 *buf; u8 *buf;
int result; int result;
bool stop; bool stop;
bool smbus;
int size;
char read_write;
u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4);
}; };
/** /**
...@@ -204,6 +269,13 @@ struct stm32f7_i2c_msg { ...@@ -204,6 +269,13 @@ struct stm32f7_i2c_msg {
* @f7_msg: customized i2c msg for driver usage * @f7_msg: customized i2c msg for driver usage
* @setup: I2C timing input setup * @setup: I2C timing input setup
* @timing: I2C computed timings * @timing: I2C computed timings
* @slave: list of slave devices registered on the I2C bus
* @slave_running: slave device currently used
* @slave_dir: transfer direction for the current slave device
* @master_mode: boolean to know in which mode the I2C is running (master or
* slave)
* @dma: dma data
* @use_dma: boolean to know if dma is used in the current transfer
*/ */
struct stm32f7_i2c_dev { struct stm32f7_i2c_dev {
struct i2c_adapter adap; struct i2c_adapter adap;
...@@ -218,6 +290,12 @@ struct stm32f7_i2c_dev { ...@@ -218,6 +290,12 @@ struct stm32f7_i2c_dev {
struct stm32f7_i2c_msg f7_msg; struct stm32f7_i2c_msg f7_msg;
struct stm32f7_i2c_setup setup; struct stm32f7_i2c_setup setup;
struct stm32f7_i2c_timings timing; struct stm32f7_i2c_timings timing;
struct i2c_client *slave[STM32F7_I2C_MAX_SLAVE];
struct i2c_client *slave_running;
u32 slave_dir;
bool master_mode;
struct stm32_i2c_dma *dma;
bool use_dma;
}; };
/** /**
...@@ -283,6 +361,11 @@ static inline void stm32f7_i2c_clr_bits(void __iomem *reg, u32 mask) ...@@ -283,6 +361,11 @@ static inline void stm32f7_i2c_clr_bits(void __iomem *reg, u32 mask)
writel_relaxed(readl_relaxed(reg) & ~mask, reg); writel_relaxed(readl_relaxed(reg) & ~mask, reg);
} }
static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask)
{
stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask);
}
static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
struct stm32f7_i2c_setup *setup, struct stm32f7_i2c_setup *setup,
struct stm32f7_i2c_timings *output) struct stm32f7_i2c_timings *output)
...@@ -524,6 +607,25 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev, ...@@ -524,6 +607,25 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
return 0; return 0;
} }
static void stm32f7_i2c_disable_dma_req(struct stm32f7_i2c_dev *i2c_dev)
{
void __iomem *base = i2c_dev->base;
u32 mask = STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN;
stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask);
}
static void stm32f7_i2c_dma_callback(void *arg)
{
struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
struct device *dev = dma->chan_using->device->dev;
stm32f7_i2c_disable_dma_req(i2c_dev);
dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir);
complete(&dma->dma_complete);
}
static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev) static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev)
{ {
struct stm32f7_i2c_timings *t = &i2c_dev->timing; struct stm32f7_i2c_timings *t = &i2c_dev->timing;
...@@ -567,6 +669,9 @@ static void stm32f7_i2c_read_rx_data(struct stm32f7_i2c_dev *i2c_dev) ...@@ -567,6 +669,9 @@ static void stm32f7_i2c_read_rx_data(struct stm32f7_i2c_dev *i2c_dev)
if (f7_msg->count) { if (f7_msg->count) {
*f7_msg->buf++ = readb_relaxed(base + STM32F7_I2C_RXDR); *f7_msg->buf++ = readb_relaxed(base + STM32F7_I2C_RXDR);
f7_msg->count--; f7_msg->count--;
} else {
/* Flush RX buffer has no data is expected */
readb_relaxed(base + STM32F7_I2C_RXDR);
} }
} }
...@@ -575,6 +680,9 @@ static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev) ...@@ -575,6 +680,9 @@ static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev)
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
u32 cr2; u32 cr2;
if (i2c_dev->use_dma)
f7_msg->count -= STM32F7_I2C_MAX_LEN;
cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2); cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
cr2 &= ~STM32F7_I2C_CR2_NBYTES_MASK; cr2 &= ~STM32F7_I2C_CR2_NBYTES_MASK;
...@@ -588,6 +696,43 @@ static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev) ...@@ -588,6 +696,43 @@ static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev)
writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2); writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
} }
static void stm32f7_i2c_smbus_reload(struct stm32f7_i2c_dev *i2c_dev)
{
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
u32 cr2;
u8 *val;
/*
* For I2C_SMBUS_BLOCK_DATA && I2C_SMBUS_BLOCK_PROC_CALL, the first
* data received inform us how many data will follow.
*/
stm32f7_i2c_read_rx_data(i2c_dev);
/*
* Update NBYTES with the value read to continue the transfer
*/
val = f7_msg->buf - sizeof(u8);
f7_msg->count = *val;
cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
}
static int stm32f7_i2c_release_bus(struct i2c_adapter *i2c_adap)
{
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
dev_info(i2c_dev->dev, "Trying to recover bus\n");
stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
STM32F7_I2C_CR1_PE);
stm32f7_i2c_hw_config(i2c_dev);
return 0;
}
static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev) static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev)
{ {
u32 status; u32 status;
...@@ -597,12 +742,18 @@ static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev) ...@@ -597,12 +742,18 @@ static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev)
status, status,
!(status & STM32F7_I2C_ISR_BUSY), !(status & STM32F7_I2C_ISR_BUSY),
10, 1000); 10, 1000);
if (!ret)
return 0;
dev_info(i2c_dev->dev, "bus busy\n");
ret = stm32f7_i2c_release_bus(&i2c_dev->adap);
if (ret) { if (ret) {
dev_dbg(i2c_dev->dev, "bus busy\n"); dev_err(i2c_dev->dev, "Failed to recover the bus (%d)\n", ret);
ret = -EBUSY; return ret;
} }
return ret; return -EBUSY;
} }
static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
...@@ -611,6 +762,7 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, ...@@ -611,6 +762,7 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
void __iomem *base = i2c_dev->base; void __iomem *base = i2c_dev->base;
u32 cr1, cr2; u32 cr1, cr2;
int ret;
f7_msg->addr = msg->addr; f7_msg->addr = msg->addr;
f7_msg->buf = msg->buf; f7_msg->buf = msg->buf;
...@@ -629,8 +781,15 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, ...@@ -629,8 +781,15 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
cr2 |= STM32F7_I2C_CR2_RD_WRN; cr2 |= STM32F7_I2C_CR2_RD_WRN;
/* Set slave address */ /* Set slave address */
cr2 &= ~STM32F7_I2C_CR2_SADD7_MASK; cr2 &= ~(STM32F7_I2C_CR2_HEAD10R | STM32F7_I2C_CR2_ADD10);
cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr); if (msg->flags & I2C_M_TEN) {
cr2 &= ~STM32F7_I2C_CR2_SADD10_MASK;
cr2 |= STM32F7_I2C_CR2_SADD10(f7_msg->addr);
cr2 |= STM32F7_I2C_CR2_ADD10;
} else {
cr2 &= ~STM32F7_I2C_CR2_SADD7_MASK;
cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr);
}
/* Set nb bytes to transfer and reload if needed */ /* Set nb bytes to transfer and reload if needed */
cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD); cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
...@@ -645,16 +804,286 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, ...@@ -645,16 +804,286 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE | cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE |
STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE; STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE;
/* Clear TX/RX interrupt */ /* Clear DMA req and TX/RX interrupt */
cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);
/* Configure DMA or enable RX/TX interrupt */
i2c_dev->use_dma = false;
if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN) {
ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
msg->flags & I2C_M_RD,
f7_msg->count, f7_msg->buf,
stm32f7_i2c_dma_callback,
i2c_dev);
if (!ret)
i2c_dev->use_dma = true;
else
dev_warn(i2c_dev->dev, "can't use DMA\n");
}
if (!i2c_dev->use_dma) {
if (msg->flags & I2C_M_RD)
cr1 |= STM32F7_I2C_CR1_RXIE;
else
cr1 |= STM32F7_I2C_CR1_TXIE;
} else {
if (msg->flags & I2C_M_RD)
cr1 |= STM32F7_I2C_CR1_RXDMAEN;
else
cr1 |= STM32F7_I2C_CR1_TXDMAEN;
}
/* Configure Start/Repeated Start */
cr2 |= STM32F7_I2C_CR2_START;
i2c_dev->master_mode = true;
/* Write configurations registers */
writel_relaxed(cr1, base + STM32F7_I2C_CR1);
writel_relaxed(cr2, base + STM32F7_I2C_CR2);
}
static int stm32f7_i2c_smbus_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
unsigned short flags, u8 command,
union i2c_smbus_data *data)
{
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct device *dev = i2c_dev->dev;
void __iomem *base = i2c_dev->base;
u32 cr1, cr2;
int i, ret;
f7_msg->result = 0;
reinit_completion(&i2c_dev->complete);
cr2 = readl_relaxed(base + STM32F7_I2C_CR2);
cr1 = readl_relaxed(base + STM32F7_I2C_CR1);
/* Set transfer direction */
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
if (f7_msg->read_write)
cr2 |= STM32F7_I2C_CR2_RD_WRN;
/* Set slave address */
cr2 &= ~(STM32F7_I2C_CR2_ADD10 | STM32F7_I2C_CR2_SADD7_MASK);
cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr);
f7_msg->smbus_buf[0] = command;
switch (f7_msg->size) {
case I2C_SMBUS_QUICK:
f7_msg->stop = true;
f7_msg->count = 0;
break;
case I2C_SMBUS_BYTE:
f7_msg->stop = true;
f7_msg->count = 1;
break;
case I2C_SMBUS_BYTE_DATA:
if (f7_msg->read_write) {
f7_msg->stop = false;
f7_msg->count = 1;
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
} else {
f7_msg->stop = true;
f7_msg->count = 2;
f7_msg->smbus_buf[1] = data->byte;
}
break;
case I2C_SMBUS_WORD_DATA:
if (f7_msg->read_write) {
f7_msg->stop = false;
f7_msg->count = 1;
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
} else {
f7_msg->stop = true;
f7_msg->count = 3;
f7_msg->smbus_buf[1] = data->word & 0xff;
f7_msg->smbus_buf[2] = data->word >> 8;
}
break;
case I2C_SMBUS_BLOCK_DATA:
if (f7_msg->read_write) {
f7_msg->stop = false;
f7_msg->count = 1;
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
} else {
f7_msg->stop = true;
if (data->block[0] > I2C_SMBUS_BLOCK_MAX ||
!data->block[0]) {
dev_err(dev, "Invalid block write size %d\n",
data->block[0]);
return -EINVAL;
}
f7_msg->count = data->block[0] + 2;
for (i = 1; i < f7_msg->count; i++)
f7_msg->smbus_buf[i] = data->block[i - 1];
}
break;
case I2C_SMBUS_PROC_CALL:
f7_msg->stop = false;
f7_msg->count = 3;
f7_msg->smbus_buf[1] = data->word & 0xff;
f7_msg->smbus_buf[2] = data->word >> 8;
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
f7_msg->read_write = I2C_SMBUS_READ;
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
f7_msg->stop = false;
if (data->block[0] > I2C_SMBUS_BLOCK_MAX - 1) {
dev_err(dev, "Invalid block write size %d\n",
data->block[0]);
return -EINVAL;
}
f7_msg->count = data->block[0] + 2;
for (i = 1; i < f7_msg->count; i++)
f7_msg->smbus_buf[i] = data->block[i - 1];
cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
f7_msg->read_write = I2C_SMBUS_READ;
break;
default:
dev_err(dev, "Unsupported smbus protocol %d\n", f7_msg->size);
return -EOPNOTSUPP;
}
f7_msg->buf = f7_msg->smbus_buf;
/* Configure PEC */
if ((flags & I2C_CLIENT_PEC) && f7_msg->size != I2C_SMBUS_QUICK) {
cr1 |= STM32F7_I2C_CR1_PECEN;
cr2 |= STM32F7_I2C_CR2_PECBYTE;
if (!f7_msg->read_write)
f7_msg->count++;
} else {
cr1 &= ~STM32F7_I2C_CR1_PECEN;
cr2 &= ~STM32F7_I2C_CR2_PECBYTE;
}
/* Set number of bytes to be transferred */
cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
/* Enable NACK, STOP, error and transfer complete interrupts */
cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE |
STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE;
/* Clear DMA req and TX/RX interrupt */
cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);
/* Configure DMA or enable RX/TX interrupt */
i2c_dev->use_dma = false;
if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN) {
ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
cr2 & STM32F7_I2C_CR2_RD_WRN,
f7_msg->count, f7_msg->buf,
stm32f7_i2c_dma_callback,
i2c_dev);
if (!ret)
i2c_dev->use_dma = true;
else
dev_warn(i2c_dev->dev, "can't use DMA\n");
}
if (!i2c_dev->use_dma) {
if (cr2 & STM32F7_I2C_CR2_RD_WRN)
cr1 |= STM32F7_I2C_CR1_RXIE;
else
cr1 |= STM32F7_I2C_CR1_TXIE;
} else {
if (cr2 & STM32F7_I2C_CR2_RD_WRN)
cr1 |= STM32F7_I2C_CR1_RXDMAEN;
else
cr1 |= STM32F7_I2C_CR1_TXDMAEN;
}
/* Set Start bit */
cr2 |= STM32F7_I2C_CR2_START;
i2c_dev->master_mode = true;
/* Write configurations registers */
writel_relaxed(cr1, base + STM32F7_I2C_CR1);
writel_relaxed(cr2, base + STM32F7_I2C_CR2);
return 0;
}
static void stm32f7_i2c_smbus_rep_start(struct stm32f7_i2c_dev *i2c_dev)
{
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
void __iomem *base = i2c_dev->base;
u32 cr1, cr2;
int ret;
cr2 = readl_relaxed(base + STM32F7_I2C_CR2);
cr1 = readl_relaxed(base + STM32F7_I2C_CR1);
/* Set transfer direction */
cr2 |= STM32F7_I2C_CR2_RD_WRN;
switch (f7_msg->size) {
case I2C_SMBUS_BYTE_DATA:
f7_msg->count = 1;
break;
case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL:
f7_msg->count = 2;
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_BLOCK_PROC_CALL:
f7_msg->count = 1;
cr2 |= STM32F7_I2C_CR2_RELOAD;
break;
}
f7_msg->buf = f7_msg->smbus_buf;
f7_msg->stop = true;
/* Add one byte for PEC if needed */
if (cr1 & STM32F7_I2C_CR1_PECEN)
f7_msg->count++;
/* Set number of bytes to be transferred */
cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK);
cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
/*
* Configure RX/TX interrupt:
*/
cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE); cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE);
cr1 |= STM32F7_I2C_CR1_RXIE;
/* Enable RX/TX interrupt according to msg direction */ /*
if (msg->flags & I2C_M_RD) * Configure DMA or enable RX/TX interrupt:
* For I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL we don't use
* dma as we don't know in advance how many data will be received
*/
cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);
i2c_dev->use_dma = false;
if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN &&
f7_msg->size != I2C_SMBUS_BLOCK_DATA &&
f7_msg->size != I2C_SMBUS_BLOCK_PROC_CALL) {
ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
cr2 & STM32F7_I2C_CR2_RD_WRN,
f7_msg->count, f7_msg->buf,
stm32f7_i2c_dma_callback,
i2c_dev);
if (!ret)
i2c_dev->use_dma = true;
else
dev_warn(i2c_dev->dev, "can't use DMA\n");
}
if (!i2c_dev->use_dma)
cr1 |= STM32F7_I2C_CR1_RXIE; cr1 |= STM32F7_I2C_CR1_RXIE;
else else
cr1 |= STM32F7_I2C_CR1_TXIE; cr1 |= STM32F7_I2C_CR1_RXDMAEN;
/* Configure Start/Repeated Start */ /* Configure Repeated Start */
cr2 |= STM32F7_I2C_CR2_START; cr2 |= STM32F7_I2C_CR2_START;
/* Write configurations registers */ /* Write configurations registers */
...@@ -662,9 +1091,278 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, ...@@ -662,9 +1091,278 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
writel_relaxed(cr2, base + STM32F7_I2C_CR2); writel_relaxed(cr2, base + STM32F7_I2C_CR2);
} }
static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask) static int stm32f7_i2c_smbus_check_pec(struct stm32f7_i2c_dev *i2c_dev)
{ {
stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask); struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
u8 count, internal_pec, received_pec;
internal_pec = readl_relaxed(i2c_dev->base + STM32F7_I2C_PECR);
switch (f7_msg->size) {
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
received_pec = f7_msg->smbus_buf[1];
break;
case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL:
received_pec = f7_msg->smbus_buf[2];
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_BLOCK_PROC_CALL:
count = f7_msg->smbus_buf[0];
received_pec = f7_msg->smbus_buf[count];
break;
default:
dev_err(i2c_dev->dev, "Unsupported smbus protocol for PEC\n");
return -EINVAL;
}
if (internal_pec != received_pec) {
dev_err(i2c_dev->dev, "Bad PEC 0x%02x vs. 0x%02x\n",
internal_pec, received_pec);
return -EBADMSG;
}
return 0;
}
static bool stm32f7_i2c_is_addr_match(struct i2c_client *slave, u32 addcode)
{
u32 addr;
if (!slave)
return false;
if (slave->flags & I2C_CLIENT_TEN) {
/*
* For 10-bit addr, addcode = 11110XY with
* X = Bit 9 of slave address
* Y = Bit 8 of slave address
*/
addr = slave->addr >> 8;
addr |= 0x78;
if (addr == addcode)
return true;
} else {
addr = slave->addr & 0x7f;
if (addr == addcode)
return true;
}
return false;
}
static void stm32f7_i2c_slave_start(struct stm32f7_i2c_dev *i2c_dev)
{
struct i2c_client *slave = i2c_dev->slave_running;
void __iomem *base = i2c_dev->base;
u32 mask;
u8 value = 0;
if (i2c_dev->slave_dir) {
/* Notify i2c slave that new read transfer is starting */
i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);
/*
* Disable slave TX config in case of I2C combined message
* (I2C Write followed by I2C Read)
*/
mask = STM32F7_I2C_CR2_RELOAD;
stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR2, mask);
mask = STM32F7_I2C_CR1_SBC | STM32F7_I2C_CR1_RXIE |
STM32F7_I2C_CR1_TCIE;
stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask);
/* Enable TX empty, STOP, NACK interrupts */
mask = STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE |
STM32F7_I2C_CR1_TXIE;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
} else {
/* Notify i2c slave that new write transfer is starting */
i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
/* Set reload mode to be able to ACK/NACK each received byte */
mask = STM32F7_I2C_CR2_RELOAD;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
/*
* Set STOP, NACK, RX empty and transfer complete interrupts.*
* Set Slave Byte Control to be able to ACK/NACK each data
* byte received
*/
mask = STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE |
STM32F7_I2C_CR1_SBC | STM32F7_I2C_CR1_RXIE |
STM32F7_I2C_CR1_TCIE;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
}
}
static void stm32f7_i2c_slave_addr(struct stm32f7_i2c_dev *i2c_dev)
{
void __iomem *base = i2c_dev->base;
u32 isr, addcode, dir, mask;
int i;
isr = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
addcode = STM32F7_I2C_ISR_ADDCODE_GET(isr);
dir = isr & STM32F7_I2C_ISR_DIR;
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
if (stm32f7_i2c_is_addr_match(i2c_dev->slave[i], addcode)) {
i2c_dev->slave_running = i2c_dev->slave[i];
i2c_dev->slave_dir = dir;
/* Start I2C slave processing */
stm32f7_i2c_slave_start(i2c_dev);
/* Clear ADDR flag */
mask = STM32F7_I2C_ICR_ADDRCF;
writel_relaxed(mask, base + STM32F7_I2C_ICR);
break;
}
}
}
static int stm32f7_i2c_get_slave_id(struct stm32f7_i2c_dev *i2c_dev,
struct i2c_client *slave, int *id)
{
int i;
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
if (i2c_dev->slave[i] == slave) {
*id = i;
return 0;
}
}
dev_err(i2c_dev->dev, "Slave 0x%x not registered\n", slave->addr);
return -ENODEV;
}
static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev,
struct i2c_client *slave, int *id)
{
struct device *dev = i2c_dev->dev;
int i;
/*
* slave[0] supports 7-bit and 10-bit slave address
* slave[1] supports 7-bit slave address only
*/
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
if (i == 1 && (slave->flags & I2C_CLIENT_PEC))
continue;
if (!i2c_dev->slave[i]) {
*id = i;
return 0;
}
}
dev_err(dev, "Slave 0x%x could not be registered\n", slave->addr);
return -EINVAL;
}
static bool stm32f7_i2c_is_slave_registered(struct stm32f7_i2c_dev *i2c_dev)
{
int i;
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
if (i2c_dev->slave[i])
return true;
}
return false;
}
static bool stm32f7_i2c_is_slave_busy(struct stm32f7_i2c_dev *i2c_dev)
{
int i, busy;
busy = 0;
for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
if (i2c_dev->slave[i])
busy++;
}
return i == busy;
}
static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev)
{
void __iomem *base = i2c_dev->base;
u32 cr2, status, mask;
u8 val;
int ret;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
/* Slave transmitter mode */
if (status & STM32F7_I2C_ISR_TXIS) {
i2c_slave_event(i2c_dev->slave_running,
I2C_SLAVE_READ_PROCESSED,
&val);
/* Write data byte */
writel_relaxed(val, base + STM32F7_I2C_TXDR);
}
/* Transfer Complete Reload for Slave receiver mode */
if (status & STM32F7_I2C_ISR_TCR || status & STM32F7_I2C_ISR_RXNE) {
/*
* Read data byte then set NBYTES to receive next byte or NACK
* the current received byte
*/
val = readb_relaxed(i2c_dev->base + STM32F7_I2C_RXDR);
ret = i2c_slave_event(i2c_dev->slave_running,
I2C_SLAVE_WRITE_RECEIVED,
&val);
if (!ret) {
cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
cr2 |= STM32F7_I2C_CR2_NBYTES(1);
writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
} else {
mask = STM32F7_I2C_CR2_NACK;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
}
}
/* NACK received */
if (status & STM32F7_I2C_ISR_NACKF) {
dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__);
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
}
/* STOP received */
if (status & STM32F7_I2C_ISR_STOPF) {
/* Disable interrupts */
stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_XFER_IRQ_MASK);
if (i2c_dev->slave_dir) {
/*
* Flush TX buffer in order to not used the byte in
* TXDR for the next transfer
*/
mask = STM32F7_I2C_ISR_TXE;
stm32f7_i2c_set_bits(base + STM32F7_I2C_ISR, mask);
}
/* Clear STOP flag */
writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);
/* Notify i2c slave that a STOP flag has been detected */
i2c_slave_event(i2c_dev->slave_running, I2C_SLAVE_STOP, &val);
i2c_dev->slave_running = NULL;
}
/* Address match received */
if (status & STM32F7_I2C_ISR_ADDR)
stm32f7_i2c_slave_addr(i2c_dev);
return IRQ_HANDLED;
} }
static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
...@@ -673,6 +1371,13 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) ...@@ -673,6 +1371,13 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
void __iomem *base = i2c_dev->base; void __iomem *base = i2c_dev->base;
u32 status, mask; u32 status, mask;
int ret = IRQ_HANDLED;
/* Check if the interrupt if for a slave device */
if (!i2c_dev->master_mode) {
ret = stm32f7_i2c_slave_isr_event(i2c_dev);
return ret;
}
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
...@@ -694,12 +1399,21 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) ...@@ -694,12 +1399,21 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
/* STOP detection flag */ /* STOP detection flag */
if (status & STM32F7_I2C_ISR_STOPF) { if (status & STM32F7_I2C_ISR_STOPF) {
/* Disable interrupts */ /* Disable interrupts */
stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); if (stm32f7_i2c_is_slave_registered(i2c_dev))
mask = STM32F7_I2C_XFER_IRQ_MASK;
else
mask = STM32F7_I2C_ALL_IRQ_MASK;
stm32f7_i2c_disable_irq(i2c_dev, mask);
/* Clear STOP flag */ /* Clear STOP flag */
writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);
complete(&i2c_dev->complete); if (i2c_dev->use_dma) {
ret = IRQ_WAKE_THREAD;
} else {
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
}
} }
/* Transfer complete */ /* Transfer complete */
...@@ -707,6 +1421,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) ...@@ -707,6 +1421,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
if (f7_msg->stop) { if (f7_msg->stop) {
mask = STM32F7_I2C_CR2_STOP; mask = STM32F7_I2C_CR2_STOP;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
} else if (i2c_dev->use_dma) {
ret = IRQ_WAKE_THREAD;
} else if (f7_msg->smbus) {
stm32f7_i2c_smbus_rep_start(i2c_dev);
} else { } else {
i2c_dev->msg_id++; i2c_dev->msg_id++;
i2c_dev->msg++; i2c_dev->msg++;
...@@ -714,13 +1432,50 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) ...@@ -714,13 +1432,50 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
} }
} }
if (status & STM32F7_I2C_ISR_TCR) {
if (f7_msg->smbus)
stm32f7_i2c_smbus_reload(i2c_dev);
else
stm32f7_i2c_reload(i2c_dev);
}
return ret;
}
static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
u32 status;
int ret;
/* /*
* Transfer Complete Reload: 255 data bytes have been transferred * Wait for dma transfer completion before sending next message or
* We have to prepare the I2C controller to transfer the remaining * notity the end of xfer to the client
* data.
*/ */
if (status & STM32F7_I2C_ISR_TCR) ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
stm32f7_i2c_reload(i2c_dev); if (!ret) {
dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_all(dma->chan_using);
f7_msg->result = -ETIMEDOUT;
}
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
if (status & STM32F7_I2C_ISR_TC) {
if (f7_msg->smbus) {
stm32f7_i2c_smbus_rep_start(i2c_dev);
} else {
i2c_dev->msg_id++;
i2c_dev->msg++;
stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg);
}
} else {
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -731,7 +1486,8 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) ...@@ -731,7 +1486,8 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
void __iomem *base = i2c_dev->base; void __iomem *base = i2c_dev->base;
struct device *dev = i2c_dev->dev; struct device *dev = i2c_dev->dev;
u32 status; struct stm32_i2c_dma *dma = i2c_dev->dma;
u32 mask, status;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
...@@ -739,6 +1495,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) ...@@ -739,6 +1495,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
if (status & STM32F7_I2C_ISR_BERR) { if (status & STM32F7_I2C_ISR_BERR) {
dev_err(dev, "<%s>: Bus error\n", __func__); dev_err(dev, "<%s>: Bus error\n", __func__);
writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR); writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR);
stm32f7_i2c_release_bus(&i2c_dev->adap);
f7_msg->result = -EIO; f7_msg->result = -EIO;
} }
...@@ -749,8 +1506,26 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) ...@@ -749,8 +1506,26 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
f7_msg->result = -EAGAIN; f7_msg->result = -EAGAIN;
} }
stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); if (status & STM32F7_I2C_ISR_PECERR) {
dev_err(dev, "<%s>: PEC error in reception\n", __func__);
writel_relaxed(STM32F7_I2C_ICR_PECCF, base + STM32F7_I2C_ICR);
f7_msg->result = -EINVAL;
}
/* Disable interrupts */
if (stm32f7_i2c_is_slave_registered(i2c_dev))
mask = STM32F7_I2C_XFER_IRQ_MASK;
else
mask = STM32F7_I2C_ALL_IRQ_MASK;
stm32f7_i2c_disable_irq(i2c_dev, mask);
/* Disable dma */
if (i2c_dev->use_dma) {
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_all(dma->chan_using);
}
i2c_dev->master_mode = false;
complete(&i2c_dev->complete); complete(&i2c_dev->complete);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -761,12 +1536,14 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -761,12 +1536,14 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
{ {
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap); struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
unsigned long time_left; unsigned long time_left;
int ret; int ret;
i2c_dev->msg = msgs; i2c_dev->msg = msgs;
i2c_dev->msg_num = num; i2c_dev->msg_num = num;
i2c_dev->msg_id = 0; i2c_dev->msg_id = 0;
f7_msg->smbus = false;
ret = clk_enable(i2c_dev->clk); ret = clk_enable(i2c_dev->clk);
if (ret) { if (ret) {
...@@ -787,6 +1564,8 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -787,6 +1564,8 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
if (!time_left) { if (!time_left) {
dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n",
i2c_dev->msg->addr); i2c_dev->msg->addr);
if (i2c_dev->use_dma)
dmaengine_terminate_all(dma->chan_using);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
...@@ -796,14 +1575,209 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -796,14 +1575,209 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
return (ret < 0) ? ret : num; return (ret < 0) ? ret : num;
} }
static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char read_write,
u8 command, int size,
union i2c_smbus_data *data)
{
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adapter);
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
struct device *dev = i2c_dev->dev;
unsigned long timeout;
int i, ret;
f7_msg->addr = addr;
f7_msg->size = size;
f7_msg->read_write = read_write;
f7_msg->smbus = true;
ret = clk_enable(i2c_dev->clk);
if (ret) {
dev_err(i2c_dev->dev, "Failed to enable clock\n");
return ret;
}
ret = stm32f7_i2c_wait_free_bus(i2c_dev);
if (ret)
goto clk_free;
ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data);
if (ret)
goto clk_free;
timeout = wait_for_completion_timeout(&i2c_dev->complete,
i2c_dev->adap.timeout);
ret = f7_msg->result;
if (ret)
goto clk_free;
if (!timeout) {
dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
if (i2c_dev->use_dma)
dmaengine_terminate_all(dma->chan_using);
ret = -ETIMEDOUT;
goto clk_free;
}
/* Check PEC */
if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) {
ret = stm32f7_i2c_smbus_check_pec(i2c_dev);
if (ret)
goto clk_free;
}
if (read_write && size != I2C_SMBUS_QUICK) {
switch (size) {
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
data->byte = f7_msg->smbus_buf[0];
break;
case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL:
data->word = f7_msg->smbus_buf[0] |
(f7_msg->smbus_buf[1] << 8);
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_BLOCK_PROC_CALL:
for (i = 0; i <= f7_msg->smbus_buf[0]; i++)
data->block[i] = f7_msg->smbus_buf[i];
break;
default:
dev_err(dev, "Unsupported smbus transaction\n");
ret = -EINVAL;
}
}
clk_free:
clk_disable(i2c_dev->clk);
return ret;
}
static int stm32f7_i2c_reg_slave(struct i2c_client *slave)
{
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(slave->adapter);
void __iomem *base = i2c_dev->base;
struct device *dev = i2c_dev->dev;
u32 oar1, oar2, mask;
int id, ret;
if (slave->flags & I2C_CLIENT_PEC) {
dev_err(dev, "SMBus PEC not supported in slave mode\n");
return -EINVAL;
}
if (stm32f7_i2c_is_slave_busy(i2c_dev)) {
dev_err(dev, "Too much slave registered\n");
return -EBUSY;
}
ret = stm32f7_i2c_get_free_slave_id(i2c_dev, slave, &id);
if (ret)
return ret;
if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) {
ret = clk_enable(i2c_dev->clk);
if (ret) {
dev_err(dev, "Failed to enable clock\n");
return ret;
}
}
if (id == 0) {
/* Configure Own Address 1 */
oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1);
oar1 &= ~STM32F7_I2C_OAR1_MASK;
if (slave->flags & I2C_CLIENT_TEN) {
oar1 |= STM32F7_I2C_OAR1_OA1_10(slave->addr);
oar1 |= STM32F7_I2C_OAR1_OA1MODE;
} else {
oar1 |= STM32F7_I2C_OAR1_OA1_7(slave->addr);
}
oar1 |= STM32F7_I2C_OAR1_OA1EN;
i2c_dev->slave[id] = slave;
writel_relaxed(oar1, i2c_dev->base + STM32F7_I2C_OAR1);
} else if (id == 1) {
/* Configure Own Address 2 */
oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2);
oar2 &= ~STM32F7_I2C_OAR2_MASK;
if (slave->flags & I2C_CLIENT_TEN) {
ret = -EOPNOTSUPP;
goto exit;
}
oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr);
oar2 |= STM32F7_I2C_OAR2_OA2EN;
i2c_dev->slave[id] = slave;
writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2);
} else {
ret = -ENODEV;
goto exit;
}
/* Enable ACK */
stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR2, STM32F7_I2C_CR2_NACK);
/* Enable Address match interrupt, error interrupt and enable I2C */
mask = STM32F7_I2C_CR1_ADDRIE | STM32F7_I2C_CR1_ERRIE |
STM32F7_I2C_CR1_PE;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
return 0;
exit:
if (!(stm32f7_i2c_is_slave_registered(i2c_dev)))
clk_disable(i2c_dev->clk);
return ret;
}
static int stm32f7_i2c_unreg_slave(struct i2c_client *slave)
{
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(slave->adapter);
void __iomem *base = i2c_dev->base;
u32 mask;
int id, ret;
ret = stm32f7_i2c_get_slave_id(i2c_dev, slave, &id);
if (ret)
return ret;
WARN_ON(!i2c_dev->slave[id]);
if (id == 0) {
mask = STM32F7_I2C_OAR1_OA1EN;
stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask);
} else {
mask = STM32F7_I2C_OAR2_OA2EN;
stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR2, mask);
}
i2c_dev->slave[id] = NULL;
if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) {
stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK);
clk_disable(i2c_dev->clk);
}
return 0;
}
static u32 stm32f7_i2c_func(struct i2c_adapter *adap) static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE |
I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_PEC;
} }
static struct i2c_algorithm stm32f7_i2c_algo = { static struct i2c_algorithm stm32f7_i2c_algo = {
.master_xfer = stm32f7_i2c_xfer, .master_xfer = stm32f7_i2c_xfer,
.smbus_xfer = stm32f7_i2c_smbus_xfer,
.functionality = stm32f7_i2c_func, .functionality = stm32f7_i2c_func,
.reg_slave = stm32f7_i2c_reg_slave,
.unreg_slave = stm32f7_i2c_unreg_slave,
}; };
static int stm32f7_i2c_probe(struct platform_device *pdev) static int stm32f7_i2c_probe(struct platform_device *pdev)
...@@ -815,6 +1789,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -815,6 +1789,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
u32 irq_error, irq_event, clk_rate, rise_time, fall_time; u32 irq_error, irq_event, clk_rate, rise_time, fall_time;
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct reset_control *rst; struct reset_control *rst;
dma_addr_t phy_addr;
int ret; int ret;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
...@@ -825,6 +1800,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -825,6 +1800,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c_dev->base)) if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base); return PTR_ERR(i2c_dev->base);
phy_addr = (dma_addr_t)res->start;
irq_event = irq_of_parse_and_map(np, 0); irq_event = irq_of_parse_and_map(np, 0);
if (!irq_event) { if (!irq_event) {
...@@ -871,8 +1847,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -871,8 +1847,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
i2c_dev->dev = &pdev->dev; i2c_dev->dev = &pdev->dev;
ret = devm_request_irq(&pdev->dev, irq_event, stm32f7_i2c_isr_event, 0, ret = devm_request_threaded_irq(&pdev->dev, irq_event,
pdev->name, i2c_dev); stm32f7_i2c_isr_event,
stm32f7_i2c_isr_event_thread,
IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to request irq event %i\n", dev_err(&pdev->dev, "Failed to request irq event %i\n",
irq_event); irq_event);
...@@ -924,6 +1903,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -924,6 +1903,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
init_completion(&i2c_dev->complete); init_completion(&i2c_dev->complete);
/* Init DMA config if supported */
i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr,
STM32F7_I2C_TXDR,
STM32F7_I2C_RXDR);
ret = i2c_add_adapter(adap); ret = i2c_add_adapter(adap);
if (ret) if (ret)
goto clk_free; goto clk_free;
...@@ -946,6 +1930,11 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) ...@@ -946,6 +1930,11 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
{ {
struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
if (i2c_dev->dma) {
stm32_i2c_dma_free(i2c_dev->dma);
i2c_dev->dma = NULL;
}
i2c_del_adapter(&i2c_dev->adap); i2c_del_adapter(&i2c_dev->adap);
clk_unprepare(i2c_dev->clk); clk_unprepare(i2c_dev->clk);
......
...@@ -602,20 +602,24 @@ static int stu300_send_address(struct stu300_dev *dev, ...@@ -602,20 +602,24 @@ static int stu300_send_address(struct stu300_dev *dev,
u32 val; u32 val;
int ret; int ret;
if (msg->flags & I2C_M_TEN) if (msg->flags & I2C_M_TEN) {
/* This is probably how 10 bit addresses look */ /* This is probably how 10 bit addresses look */
val = (0xf0 | (((u32) msg->addr & 0x300) >> 7)) & val = (0xf0 | (((u32) msg->addr & 0x300) >> 7)) &
I2C_DR_D_MASK; I2C_DR_D_MASK;
else if (msg->flags & I2C_M_RD)
val = ((msg->addr << 1) & I2C_DR_D_MASK); /* This is the direction bit */
val |= 0x01;
} else {
val = i2c_8bit_addr_from_msg(msg);
}
if (msg->flags & I2C_M_RD) { if (resend) {
/* This is the direction bit */ if (msg->flags & I2C_M_RD)
val |= 0x01;
if (resend)
dev_dbg(&dev->pdev->dev, "read resend\n"); dev_dbg(&dev->pdev->dev, "read resend\n");
} else if (resend) else
dev_dbg(&dev->pdev->dev, "write resend\n"); dev_dbg(&dev->pdev->dev, "write resend\n");
}
stu300_wr8(val, dev->virtbase + I2C_DR); stu300_wr8(val, dev->virtbase + I2C_DR);
/* For 10bit addressing, await 10bit request (EVENT 9) */ /* For 10bit addressing, await 10bit request (EVENT 9) */
......
...@@ -509,7 +509,7 @@ static int synquacer_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ...@@ -509,7 +509,7 @@ static int synquacer_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
dev_dbg(i2c->dev, "calculated timeout %d ms\n", i2c->timeout_ms); dev_dbg(i2c->dev, "calculated timeout %d ms\n", i2c->timeout_ms);
for (retry = 0; retry < adap->retries; retry++) { for (retry = 0; retry <= adap->retries; retry++) {
ret = synquacer_i2c_doxfer(i2c, msgs, num); ret = synquacer_i2c_doxfer(i2c, msgs, num);
if (ret != -EAGAIN) if (ret != -EAGAIN)
return ret; return ret;
......
...@@ -173,7 +173,6 @@ struct tegra_i2c_hw_feature { ...@@ -173,7 +173,6 @@ struct tegra_i2c_hw_feature {
* @msg_buf_remaining: size of unsent data in the message buffer * @msg_buf_remaining: size of unsent data in the message buffer
* @msg_read: identifies read transfers * @msg_read: identifies read transfers
* @bus_clk_rate: current i2c bus clock rate * @bus_clk_rate: current i2c bus clock rate
* @is_suspended: prevents i2c controller accesses after suspend is called
*/ */
struct tegra_i2c_dev { struct tegra_i2c_dev {
struct device *dev; struct device *dev;
...@@ -194,7 +193,6 @@ struct tegra_i2c_dev { ...@@ -194,7 +193,6 @@ struct tegra_i2c_dev {
int msg_read; int msg_read;
u32 bus_clk_rate; u32 bus_clk_rate;
u16 clk_divisor_non_hs_mode; u16 clk_divisor_non_hs_mode;
bool is_suspended;
bool is_multimaster_mode; bool is_multimaster_mode;
spinlock_t xfer_lock; spinlock_t xfer_lock;
}; };
...@@ -734,9 +732,6 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], ...@@ -734,9 +732,6 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
int i; int i;
int ret = 0; int ret = 0;
if (i2c_dev->is_suspended)
return -EBUSY;
ret = pm_runtime_get_sync(i2c_dev->dev); ret = pm_runtime_get_sync(i2c_dev->dev);
if (ret < 0) { if (ret < 0) {
dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret); dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret);
...@@ -1051,37 +1046,9 @@ static int tegra_i2c_remove(struct platform_device *pdev) ...@@ -1051,37 +1046,9 @@ static int tegra_i2c_remove(struct platform_device *pdev)
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int tegra_i2c_suspend(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
i2c_lock_adapter(&i2c_dev->adapter);
i2c_dev->is_suspended = true;
i2c_unlock_adapter(&i2c_dev->adapter);
return 0;
}
static int tegra_i2c_resume(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int ret;
i2c_lock_adapter(&i2c_dev->adapter);
ret = tegra_i2c_init(i2c_dev);
if (!ret)
i2c_dev->is_suspended = false;
i2c_unlock_adapter(&i2c_dev->adapter);
return ret;
}
static const struct dev_pm_ops tegra_i2c_pm = { static const struct dev_pm_ops tegra_i2c_pm = {
SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume, SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
NULL) NULL)
SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
}; };
#define TEGRA_I2C_PM (&tegra_i2c_pm) #define TEGRA_I2C_PM (&tegra_i2c_pm)
#else #else
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/i2c-xiic.h> #include <linux/platform_data/i2c-xiic.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -143,12 +143,6 @@ struct xiic_i2c { ...@@ -143,12 +143,6 @@ struct xiic_i2c {
#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS) #define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
/* The following constants are used with the following macros to specify the
* operation, a read or write operation.
*/
#define XIIC_READ_OPERATION 1
#define XIIC_WRITE_OPERATION 0
/* /*
* Tx Fifo upper bit masks. * Tx Fifo upper bit masks.
*/ */
...@@ -415,7 +409,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) ...@@ -415,7 +409,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
clr |= XIIC_INTR_RX_FULL_MASK; clr |= XIIC_INTR_RX_FULL_MASK;
if (!i2c->rx_msg) { if (!i2c->rx_msg) {
dev_dbg(i2c->adap.dev.parent, dev_dbg(i2c->adap.dev.parent,
"%s unexpexted RX IRQ\n", __func__); "%s unexpected RX IRQ\n", __func__);
xiic_clear_rx_fifo(i2c); xiic_clear_rx_fifo(i2c);
goto out; goto out;
} }
...@@ -470,7 +464,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) ...@@ -470,7 +464,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (!i2c->tx_msg) { if (!i2c->tx_msg) {
dev_dbg(i2c->adap.dev.parent, dev_dbg(i2c->adap.dev.parent,
"%s unexpexted TX IRQ\n", __func__); "%s unexpected TX IRQ\n", __func__);
goto out; goto out;
} }
...@@ -556,8 +550,7 @@ static void xiic_start_recv(struct xiic_i2c *i2c) ...@@ -556,8 +550,7 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
if (!(msg->flags & I2C_M_NOSTART)) if (!(msg->flags & I2C_M_NOSTART))
/* write the address */ /* write the address */
xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
(msg->addr << 1) | XIIC_READ_OPERATION | i2c_8bit_addr_from_msg(msg) | XIIC_TX_DYN_START_MASK);
XIIC_TX_DYN_START_MASK);
xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK); xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
...@@ -585,7 +578,7 @@ static void xiic_start_send(struct xiic_i2c *i2c) ...@@ -585,7 +578,7 @@ static void xiic_start_send(struct xiic_i2c *i2c)
if (!(msg->flags & I2C_M_NOSTART)) { if (!(msg->flags & I2C_M_NOSTART)) {
/* write the address */ /* write the address */
u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION | u16 data = i2c_8bit_addr_from_msg(msg) |
XIIC_TX_DYN_START_MASK; XIIC_TX_DYN_START_MASK;
if ((i2c->nmsgs == 1) && msg->len == 0) if ((i2c->nmsgs == 1) && msg->len == 0)
/* no data and last message -> add STOP */ /* no data and last message -> add STOP */
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -84,6 +85,8 @@ struct xlp9xx_i2c_dev { ...@@ -84,6 +85,8 @@ struct xlp9xx_i2c_dev {
struct device *dev; struct device *dev;
struct i2c_adapter adapter; struct i2c_adapter adapter;
struct completion msg_complete; struct completion msg_complete;
struct i2c_smbus_alert_setup alert_data;
struct i2c_client *ara;
int irq; int irq;
bool msg_read; bool msg_read;
bool len_recv; bool len_recv;
...@@ -155,9 +158,30 @@ static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv) ...@@ -155,9 +158,30 @@ static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
priv->msg_buf += len; priv->msg_buf += len;
} }
static void xlp9xx_i2c_update_rlen(struct xlp9xx_i2c_dev *priv)
{
u32 val, len;
/*
* Update receive length. Re-read len to get the latest value,
* and then add 4 to have a minimum value that can be safely
* written. This is to account for the byte read above, the
* transfer in progress and any delays in the register I/O
*/
val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
XLP9XX_I2C_FIFO_WCNT_MASK;
len = max_t(u32, priv->msg_len, len + 4);
if (len >= I2C_SMBUS_BLOCK_MAX + 2)
return;
val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
(len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
}
static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv) static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
{ {
u32 len, i, val; u32 len, i;
u8 rlen, *buf = priv->msg_buf; u8 rlen, *buf = priv->msg_buf;
len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) & len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
...@@ -167,21 +191,20 @@ static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv) ...@@ -167,21 +191,20 @@ static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
if (priv->len_recv) { if (priv->len_recv) {
/* read length byte */ /* read length byte */
rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO); rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
*buf++ = rlen; if (rlen > I2C_SMBUS_BLOCK_MAX || rlen == 0) {
len--; rlen = 0; /*abort transfer */
priv->msg_buf_remaining = 0;
if (priv->client_pec) priv->msg_len = 0;
++rlen; } else {
/* update remaining bytes and message length */ *buf++ = rlen;
priv->msg_buf_remaining = rlen; if (priv->client_pec)
priv->msg_len = rlen + 1; ++rlen; /* account for error check byte */
/* update remaining bytes and message length */
priv->msg_buf_remaining = rlen;
priv->msg_len = rlen + 1;
}
xlp9xx_i2c_update_rlen(priv);
priv->len_recv = false; priv->len_recv = false;
/* Update transfer length to read only actual data */
val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
((rlen + 1) << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
} else { } else {
len = min(priv->msg_buf_remaining, len); len = min(priv->msg_buf_remaining, len);
for (i = 0; i < len; i++, buf++) for (i = 0; i < len; i++, buf++)
...@@ -300,10 +323,6 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg, ...@@ -300,10 +323,6 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL, xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
XLP9XX_I2C_MFIFOCTRL_RST); XLP9XX_I2C_MFIFOCTRL_RST);
/* set FIFO threshold if reading */
if (priv->msg_read)
xlp9xx_i2c_update_rx_fifo_thres(priv);
/* set slave addr */ /* set slave addr */
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR, xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR,
(msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) | (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) |
...@@ -322,9 +341,13 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg, ...@@ -322,9 +341,13 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
val &= ~XLP9XX_I2C_CTRL_ADDMODE; val &= ~XLP9XX_I2C_CTRL_ADDMODE;
priv->len_recv = msg->flags & I2C_M_RECV_LEN; priv->len_recv = msg->flags & I2C_M_RECV_LEN;
len = priv->len_recv ? XLP9XX_I2C_FIFO_SIZE : msg->len; len = priv->len_recv ? I2C_SMBUS_BLOCK_MAX + 2 : msg->len;
priv->client_pec = msg->flags & I2C_CLIENT_PEC; priv->client_pec = msg->flags & I2C_CLIENT_PEC;
/* set FIFO threshold if reading */
if (priv->msg_read)
xlp9xx_i2c_update_rx_fifo_thres(priv);
/* set data length to be transferred */ /* set data length to be transferred */
val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) | val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
(len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT); (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
...@@ -378,8 +401,11 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg, ...@@ -378,8 +401,11 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
} }
/* update msg->len with actual received length */ /* update msg->len with actual received length */
if (msg->flags & I2C_M_RECV_LEN) if (msg->flags & I2C_M_RECV_LEN) {
if (!priv->msg_len)
return -EPROTO;
msg->len = priv->msg_len; msg->len = priv->msg_len;
}
return 0; return 0;
} }
...@@ -447,6 +473,19 @@ static int xlp9xx_i2c_get_frequency(struct platform_device *pdev, ...@@ -447,6 +473,19 @@ static int xlp9xx_i2c_get_frequency(struct platform_device *pdev,
return 0; return 0;
} }
static int xlp9xx_i2c_smbus_setup(struct xlp9xx_i2c_dev *priv,
struct platform_device *pdev)
{
if (!priv->alert_data.irq)
return -EINVAL;
priv->ara = i2c_setup_smbus_alert(&priv->adapter, &priv->alert_data);
if (!priv->ara)
return -ENODEV;
return 0;
}
static int xlp9xx_i2c_probe(struct platform_device *pdev) static int xlp9xx_i2c_probe(struct platform_device *pdev)
{ {
struct xlp9xx_i2c_dev *priv; struct xlp9xx_i2c_dev *priv;
...@@ -467,6 +506,10 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev) ...@@ -467,6 +506,10 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "invalid irq!\n"); dev_err(&pdev->dev, "invalid irq!\n");
return priv->irq; return priv->irq;
} }
/* SMBAlert irq */
priv->alert_data.irq = platform_get_irq(pdev, 1);
if (priv->alert_data.irq <= 0)
priv->alert_data.irq = 0;
xlp9xx_i2c_get_frequency(pdev, priv); xlp9xx_i2c_get_frequency(pdev, priv);
xlp9xx_i2c_init(priv); xlp9xx_i2c_init(priv);
...@@ -493,6 +536,10 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev) ...@@ -493,6 +536,10 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
if (err) if (err)
return err; return err;
err = xlp9xx_i2c_smbus_setup(priv, pdev);
if (err)
dev_dbg(&pdev->dev, "No active SMBus alert %d\n", err);
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr); dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);
......
...@@ -717,10 +717,6 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) ...@@ -717,10 +717,6 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
client->adapter = adap; client->adapter = adap;
client->dev.platform_data = info->platform_data; client->dev.platform_data = info->platform_data;
if (info->archdata)
client->dev.archdata = *info->archdata;
client->flags = info->flags; client->flags = info->flags;
client->addr = info->addr; client->addr = info->addr;
...@@ -746,7 +742,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) ...@@ -746,7 +742,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
client->dev.parent = &client->adapter->dev; client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type; client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type; client->dev.type = &i2c_client_type;
client->dev.of_node = info->of_node; client->dev.of_node = of_node_get(info->of_node);
client->dev.fwnode = info->fwnode; client->dev.fwnode = info->fwnode;
i2c_dev_set_name(adap, client, info); i2c_dev_set_name(adap, client, info);
...@@ -757,7 +753,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) ...@@ -757,7 +753,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
dev_err(&adap->dev, dev_err(&adap->dev,
"Failed to add properties to client %s: %d\n", "Failed to add properties to client %s: %d\n",
client->name, status); client->name, status);
goto out_err; goto out_err_put_of_node;
} }
} }
...@@ -773,6 +769,8 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) ...@@ -773,6 +769,8 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
out_free_props: out_free_props:
if (info->properties) if (info->properties)
device_remove_properties(&client->dev); device_remove_properties(&client->dev);
out_err_put_of_node:
of_node_put(info->of_node);
out_err: out_err:
dev_err(&adap->dev, dev_err(&adap->dev,
"Failed to register i2c client %s at 0x%02x (%d)\n", "Failed to register i2c client %s at 0x%02x (%d)\n",
......
...@@ -22,53 +22,64 @@ ...@@ -22,53 +22,64 @@
#include "i2c-core.h" #include "i2c-core.h"
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, int of_i2c_get_board_info(struct device *dev, struct device_node *node,
struct device_node *node) struct i2c_board_info *info)
{ {
struct i2c_client *client;
struct i2c_board_info info = {};
struct dev_archdata dev_ad = {};
u32 addr; u32 addr;
int ret; int ret;
dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); memset(info, 0, sizeof(*info));
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) {
dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n", dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);
node); return -EINVAL;
return ERR_PTR(-EINVAL);
} }
ret = of_property_read_u32(node, "reg", &addr); ret = of_property_read_u32(node, "reg", &addr);
if (ret) { if (ret) {
dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node); dev_err(dev, "of_i2c: invalid reg on %pOF\n", node);
return ERR_PTR(ret); return ret;
} }
if (addr & I2C_TEN_BIT_ADDRESS) { if (addr & I2C_TEN_BIT_ADDRESS) {
addr &= ~I2C_TEN_BIT_ADDRESS; addr &= ~I2C_TEN_BIT_ADDRESS;
info.flags |= I2C_CLIENT_TEN; info->flags |= I2C_CLIENT_TEN;
} }
if (addr & I2C_OWN_SLAVE_ADDRESS) { if (addr & I2C_OWN_SLAVE_ADDRESS) {
addr &= ~I2C_OWN_SLAVE_ADDRESS; addr &= ~I2C_OWN_SLAVE_ADDRESS;
info.flags |= I2C_CLIENT_SLAVE; info->flags |= I2C_CLIENT_SLAVE;
} }
info.addr = addr; info->addr = addr;
info.archdata = &dev_ad; info->of_node = node;
info.of_node = of_node_get(node);
if (of_property_read_bool(node, "host-notify")) if (of_property_read_bool(node, "host-notify"))
info.flags |= I2C_CLIENT_HOST_NOTIFY; info->flags |= I2C_CLIENT_HOST_NOTIFY;
if (of_get_property(node, "wakeup-source", NULL)) if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE; info->flags |= I2C_CLIENT_WAKE;
return 0;
}
EXPORT_SYMBOL_GPL(of_i2c_get_board_info);
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
struct device_node *node)
{
struct i2c_client *client;
struct i2c_board_info info;
int ret;
dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
ret = of_i2c_get_board_info(&adap->dev, node, &info);
if (ret)
return ERR_PTR(ret);
client = i2c_new_device(adap, &info); client = i2c_new_device(adap, &info);
if (!client) { if (!client) {
dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
of_node_put(node);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
return client; return client;
......
...@@ -466,6 +466,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, ...@@ -466,6 +466,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
status = i2c_transfer(adapter, msg, num); status = i2c_transfer(adapter, msg, num);
if (status < 0) if (status < 0)
return status; return status;
if (status != num)
return -EIO;
/* Check PEC if last message is a read */ /* Check PEC if last message is a read */
if (i && (msg[num-1].flags & I2C_M_RD)) { if (i && (msg[num-1].flags & I2C_M_RD)) {
......
...@@ -418,7 +418,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, ...@@ -418,7 +418,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id); snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id);
WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj, WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
symlink_name), symlink_name),
"can't create symlink for channel %u\n", chan_id); "can't create symlink to channel %u\n", chan_id);
dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
i2c_adapter_id(&priv->adap)); i2c_adapter_id(&priv->adap));
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
...@@ -105,7 +106,7 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne ...@@ -105,7 +106,7 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne
priv->cur_adap.owner = THIS_MODULE; priv->cur_adap.owner = THIS_MODULE;
priv->cur_adap.algo = &priv->algo; priv->cur_adap.algo = &priv->algo;
priv->cur_adap.algo_data = priv; priv->cur_adap.algo_data = priv;
priv->cur_adap.dev.parent = priv->dev; priv->cur_adap.dev.parent = &adap->dev;
priv->cur_adap.class = adap->class; priv->cur_adap.class = adap->class;
priv->cur_adap.retries = adap->retries; priv->cur_adap.retries = adap->retries;
priv->cur_adap.timeout = adap->timeout; priv->cur_adap.timeout = adap->timeout;
...@@ -254,6 +255,8 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) ...@@ -254,6 +255,8 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
pm_runtime_no_callbacks(&pdev->dev);
/* switch to first parent as active master */ /* switch to first parent as active master */
i2c_demux_activate_master(priv, 0); i2c_demux_activate_master(priv, 0);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-mux.h> #include <linux/i2c-mux.h>
#include <linux/i2c-mux-gpio.h> #include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -206,8 +206,7 @@ static const struct of_device_id ltc4306_of_match[] = { ...@@ -206,8 +206,7 @@ static const struct of_device_id ltc4306_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, ltc4306_of_match); MODULE_DEVICE_TABLE(of, ltc4306_of_match);
static int ltc4306_probe(struct i2c_client *client, static int ltc4306_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
const struct chip_desc *chip; const struct chip_desc *chip;
...@@ -221,7 +220,7 @@ static int ltc4306_probe(struct i2c_client *client, ...@@ -221,7 +220,7 @@ static int ltc4306_probe(struct i2c_client *client,
chip = of_device_get_match_data(&client->dev); chip = of_device_get_match_data(&client->dev);
if (!chip) if (!chip)
chip = &chips[id->driver_data]; chip = &chips[i2c_match_id(ltc4306_id, client)->driver_data];
idle_disc = device_property_read_bool(&client->dev, idle_disc = device_property_read_bool(&client->dev,
"i2c-mux-idle-disconnect"); "i2c-mux-idle-disconnect");
...@@ -310,7 +309,7 @@ static struct i2c_driver ltc4306_driver = { ...@@ -310,7 +309,7 @@ static struct i2c_driver ltc4306_driver = {
.name = "ltc4306", .name = "ltc4306",
.of_match_table = of_match_ptr(ltc4306_of_match), .of_match_table = of_match_ptr(ltc4306_of_match),
}, },
.probe = ltc4306_probe, .probe_new = ltc4306_probe,
.remove = ltc4306_remove, .remove = ltc4306_remove,
.id_table = ltc4306_id, .id_table = ltc4306_id,
}; };
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-mux.h> #include <linux/i2c-mux.h>
...@@ -373,7 +374,6 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -373,7 +374,6 @@ static int pca954x_probe(struct i2c_client *client,
int num, force, class; int num, force, class;
struct i2c_mux_core *muxc; struct i2c_mux_core *muxc;
struct pca954x *data; struct pca954x *data;
const struct of_device_id *match;
int ret; int ret;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
...@@ -389,15 +389,19 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -389,15 +389,19 @@ static int pca954x_probe(struct i2c_client *client,
i2c_set_clientdata(client, muxc); i2c_set_clientdata(client, muxc);
data->client = client; data->client = client;
/* Get the mux out of reset if a reset GPIO is specified. */ /* Reset the mux if a reset GPIO is specified. */
gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio)) if (IS_ERR(gpio))
return PTR_ERR(gpio); return PTR_ERR(gpio);
if (gpio) {
udelay(1);
gpiod_set_value_cansleep(gpio, 0);
/* Give the chip some time to recover. */
udelay(1);
}
match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev); data->chip = of_device_get_match_data(&client->dev);
if (match) if (!data->chip)
data->chip = of_device_get_match_data(&client->dev);
else
data->chip = &chips[id->driver_data]; data->chip = &chips[id->driver_data];
if (data->chip->id.manufacturer_id != I2C_DEVICE_ID_NONE) { if (data->chip->id.manufacturer_id != I2C_DEVICE_ID_NONE) {
......
...@@ -127,10 +127,8 @@ static int i2c_mux_reg_probe_dt(struct regmux *mux, ...@@ -127,10 +127,8 @@ static int i2c_mux_reg_probe_dt(struct regmux *mux,
values = devm_kcalloc(&pdev->dev, values = devm_kcalloc(&pdev->dev,
mux->data.n_values, sizeof(*mux->data.values), mux->data.n_values, sizeof(*mux->data.values),
GFP_KERNEL); GFP_KERNEL);
if (!values) { if (!values)
dev_err(&pdev->dev, "Cannot allocate values array");
return -ENOMEM; return -ENOMEM;
}
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
of_property_read_u32(child, "reg", values + i); of_property_read_u32(child, "reg", values + i);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/i2c-gpio.h> #include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include <linux/timb_gpio.h> #include <linux/timb_gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-ocores.h> #include <linux/platform_data/i2c-ocores.h>
#include <linux/i2c-xiic.h> #include <linux/platform_data/i2c-xiic.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/xilinx_spi.h> #include <linux/spi/xilinx_spi.h>
......
...@@ -532,6 +532,45 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata) ...@@ -532,6 +532,45 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata)
return 0; return 0;
} }
static void at24_remove_dummy_clients(struct at24_data *at24)
{
int i;
for (i = 1; i < at24->num_addresses; i++)
i2c_unregister_device(at24->client[i].client);
}
static int at24_make_dummy_client(struct at24_data *at24, unsigned int index,
struct regmap_config *regmap_config)
{
struct i2c_client *base_client, *dummy_client;
unsigned short int addr;
struct regmap *regmap;
struct device *dev;
base_client = at24->client[0].client;
dev = &base_client->dev;
addr = base_client->addr + index;
dummy_client = i2c_new_dummy(base_client->adapter,
base_client->addr + index);
if (!dummy_client) {
dev_err(dev, "address 0x%02x unavailable\n", addr);
return -EADDRINUSE;
}
regmap = devm_regmap_init_i2c(dummy_client, regmap_config);
if (IS_ERR(regmap)) {
i2c_unregister_device(dummy_client);
return PTR_ERR(regmap);
}
at24->client[index].client = dummy_client;
at24->client[index].regmap = regmap;
return 0;
}
static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
{ {
if (flags & AT24_FLAG_MAC) { if (flags & AT24_FLAG_MAC) {
...@@ -637,20 +676,10 @@ static int at24_probe(struct i2c_client *client) ...@@ -637,20 +676,10 @@ static int at24_probe(struct i2c_client *client)
/* use dummy devices for multiple-address chips */ /* use dummy devices for multiple-address chips */
for (i = 1; i < num_addresses; i++) { for (i = 1; i < num_addresses; i++) {
at24->client[i].client = i2c_new_dummy(client->adapter, err = at24_make_dummy_client(at24, i, &regmap_config);
client->addr + i); if (err) {
if (!at24->client[i].client) { at24_remove_dummy_clients(at24);
dev_err(dev, "address 0x%02x unavailable\n", return err;
client->addr + i);
err = -EADDRINUSE;
goto err_clients;
}
at24->client[i].regmap = devm_regmap_init_i2c(
at24->client[i].client,
&regmap_config);
if (IS_ERR(at24->client[i].regmap)) {
err = PTR_ERR(at24->client[i].regmap);
goto err_clients;
} }
} }
...@@ -685,7 +714,7 @@ static int at24_probe(struct i2c_client *client) ...@@ -685,7 +714,7 @@ static int at24_probe(struct i2c_client *client)
nvmem_config.word_size = 1; nvmem_config.word_size = 1;
nvmem_config.size = pdata.byte_len; nvmem_config.size = pdata.byte_len;
at24->nvmem = nvmem_register(&nvmem_config); at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
if (IS_ERR(at24->nvmem)) { if (IS_ERR(at24->nvmem)) {
err = PTR_ERR(at24->nvmem); err = PTR_ERR(at24->nvmem);
goto err_clients; goto err_clients;
...@@ -702,10 +731,7 @@ static int at24_probe(struct i2c_client *client) ...@@ -702,10 +731,7 @@ static int at24_probe(struct i2c_client *client)
return 0; return 0;
err_clients: err_clients:
for (i = 1; i < num_addresses; i++) at24_remove_dummy_clients(at24);
if (at24->client[i].client)
i2c_unregister_device(at24->client[i].client);
pm_runtime_disable(dev); pm_runtime_disable(dev);
return err; return err;
...@@ -714,15 +740,10 @@ static int at24_probe(struct i2c_client *client) ...@@ -714,15 +740,10 @@ static int at24_probe(struct i2c_client *client)
static int at24_remove(struct i2c_client *client) static int at24_remove(struct i2c_client *client)
{ {
struct at24_data *at24; struct at24_data *at24;
int i;
at24 = i2c_get_clientdata(client); at24 = i2c_get_clientdata(client);
nvmem_unregister(at24->nvmem); at24_remove_dummy_clients(at24);
for (i = 1; i < at24->num_addresses; i++)
i2c_unregister_device(at24->client[i].client);
pm_runtime_disable(&client->dev); pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev); pm_runtime_set_suspended(&client->dev);
......
/*
* Header file for I2C support on PNX010x/4008.
*
* Author: Dennis Kovalev <dkovalev@ru.mvista.com>
*
* 2004-2006 (c) MontaVista Software, Inc. 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.
*/
#ifndef __I2C_PNX_H__
#define __I2C_PNX_H__
struct platform_device;
struct clk;
struct i2c_pnx_mif {
int ret; /* Return value */
int mode; /* Interface mode */
struct completion complete; /* I/O completion */
struct timer_list timer; /* Timeout */
u8 * buf; /* Data buffer */
int len; /* Length of data buffer */
int order; /* RX Bytes to order via TX */
};
struct i2c_pnx_algo_data {
void __iomem *ioaddr;
struct i2c_pnx_mif mif;
int last;
struct clk *clk;
struct i2c_adapter adapter;
int irq;
u32 timeout;
};
#endif /* __I2C_PNX_H__ */
...@@ -394,7 +394,6 @@ static inline bool i2c_detect_slave_mode(struct device *dev) { return false; } ...@@ -394,7 +394,6 @@ static inline bool i2c_detect_slave_mode(struct device *dev) { return false; }
* @addr: stored in i2c_client.addr * @addr: stored in i2c_client.addr
* @dev_name: Overrides the default <busnr>-<addr> dev_name if set * @dev_name: Overrides the default <busnr>-<addr> dev_name if set
* @platform_data: stored in i2c_client.dev.platform_data * @platform_data: stored in i2c_client.dev.platform_data
* @archdata: copied into i2c_client.dev.archdata
* @of_node: pointer to OpenFirmware device node * @of_node: pointer to OpenFirmware device node
* @fwnode: device node supplied by the platform firmware * @fwnode: device node supplied by the platform firmware
* @properties: additional device properties for the device * @properties: additional device properties for the device
...@@ -419,7 +418,6 @@ struct i2c_board_info { ...@@ -419,7 +418,6 @@ struct i2c_board_info {
unsigned short addr; unsigned short addr;
const char *dev_name; const char *dev_name;
void *platform_data; void *platform_data;
struct dev_archdata *archdata;
struct device_node *of_node; struct device_node *of_node;
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
const struct property_entry *properties; const struct property_entry *properties;
...@@ -903,6 +901,9 @@ extern const struct of_device_id ...@@ -903,6 +901,9 @@ extern const struct of_device_id
*i2c_of_match_device(const struct of_device_id *matches, *i2c_of_match_device(const struct of_device_id *matches,
struct i2c_client *client); struct i2c_client *client);
int of_i2c_get_board_info(struct device *dev, struct device_node *node,
struct i2c_board_info *info);
#else #else
static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
...@@ -927,6 +928,13 @@ static inline const struct of_device_id ...@@ -927,6 +928,13 @@ static inline const struct of_device_id
return NULL; return NULL;
} }
static inline int of_i2c_get_board_info(struct device *dev,
struct device_node *node,
struct i2c_board_info *info)
{
return -ENOTSUPP;
}
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
#if IS_ENABLED(CONFIG_ACPI) #if IS_ENABLED(CONFIG_ACPI)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册