Commit 278f1d07 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull i2c updates from Wolfram Sang:
 "Highlights from the I2C subsystem for 3.18:

   - new drivers for Axxia AM55xx, and Hisilicon hix5hd2 SoC.

   - designware driver gained AMD support, exynos gained exynos7 support

  The rest is usual driver stuff.  Hopefully no lowlights this time"

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: i801: Add Device IDs for Intel Sunrise Point PCH
  i2c: hix5hd2: add i2c controller driver
  i2c-imx: Disable the clock on probe failure
  i2c: designware: Add support for AMD I2C controller
  i2c: designware: Rework probe() to get clock a bit later
  i2c: designware: Default to fast mode in case of ACPI
  i2c: axxia: Add I2C driver for AXM55xx
  i2c: exynos: add support for HSI2C module on Exynos7
  i2c: mxs: detect No Slave Ack on SELECT in PIO mode
  i2c: cros_ec: Remove EC_I2C_FLAG_10BIT
  i2c: cros-ec-tunnel: Add of match table
  i2c: rcar: remove sign-compare flaw
  i2c: ismt: Use minimum descriptor size
  i2c: imx: Add arbitration lost check
  i2c: rk3x: Remove unlikely() annotations
  i2c: rcar: check for no IRQ in rcar_i2c_irq()
  i2c: rcar: make rcar_i2c_prepare_msg() *void*
  i2c: rcar: simplify check for last message
  i2c: designware: add support of platform data to set I2C mode
  i2c: designware: add support of I2C standard mode
parents d590c6cd 3e27a844
LSI Axxia I2C
Required properties :
- compatible : Must be "lsi,api2c"
- reg : Offset and length of the register set for the device
- interrupts : the interrupt specifier
- #address-cells : Must be <1>;
- #size-cells : Must be <0>;
- clock-names : Must contain "i2c".
- clocks: Must contain an entry for each name in clock-names. See the common
clock bindings.
Optional properties :
- clock-frequency : Desired I2C bus clock frequency in Hz. If not specified,
the default 100 kHz frequency will be used. As only Normal and Fast modes
are supported, possible values are 100000 and 400000.
Example :
i2c@02010084000 {
compatible = "lsi,api2c";
device_type = "i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x20 0x10084000 0x00 0x1000>;
interrupts = <0 19 4>;
clocks = <&clk_per>;
clock-names = "i2c";
clock-frequency = <400000>;
};
...@@ -12,6 +12,8 @@ Required properties: ...@@ -12,6 +12,8 @@ Required properties:
on Exynos5250 and Exynos5420 SoCs. on Exynos5250 and Exynos5420 SoCs.
-> "samsung,exynos5260-hsi2c", for i2c compatible with HSI2C available -> "samsung,exynos5260-hsi2c", for i2c compatible with HSI2C available
on Exynos5260 SoCs. on Exynos5260 SoCs.
-> "samsung,exynos7-hsi2c", for i2c compatible with HSI2C available
on Exynos7 SoCs.
- 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.
......
I2C for Hisilicon hix5hd2 chipset platform
Required properties:
- compatible: Must be "hisilicon,hix5hd2-i2c"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
- #address-cells = <1>;
- #size-cells = <0>;
- clocks: phandles to input clocks.
Optional properties:
- clock-frequency: Desired I2C bus frequency in Hz, otherwise defaults to 100000
- Child nodes conforming to i2c bus binding
Examples:
I2C0@f8b10000 {
compatible = "hisilicon,hix5hd2-i2c";
reg = <0xf8b10000 0x1000>;
interrupts = <0 38 4>;
clocks = <&clock HIX5HD2_I2C0_RST>;
#address-cells = <1>;
#size-cells = <0>;
}
...@@ -28,6 +28,7 @@ Supported adapters: ...@@ -28,6 +28,7 @@ Supported adapters:
* Intel Wildcat Point (PCH) * Intel Wildcat Point (PCH)
* Intel Wildcat Point-LP (PCH) * Intel Wildcat Point-LP (PCH)
* Intel BayTrail (SOC) * Intel BayTrail (SOC)
* Intel Sunrise Point-H (PCH)
Datasheets: Publicly available at the Intel website Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller On Intel Patsburg and later chipsets, both the normal host SMBus controller
......
...@@ -77,6 +77,16 @@ config I2C_AMD8111 ...@@ -77,6 +77,16 @@ config I2C_AMD8111
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-amd8111. will be called i2c-amd8111.
config I2C_HIX5HD2
tristate "Hix5hd2 high-speed I2C driver"
depends on ARCH_HIX5HD2
help
Say Y here to include support for high-speed I2C controller in the
Hisilicon based hix5hd2 SoCs.
This driver can also be built as a module. If so, the module
will be called i2c-hix5hd2.
config I2C_I801 config I2C_I801
tristate "Intel 82801 (ICH/PCH)" tristate "Intel 82801 (ICH/PCH)"
depends on PCI depends on PCI
...@@ -112,6 +122,7 @@ config I2C_I801 ...@@ -112,6 +122,7 @@ config I2C_I801
Wildcat Point (PCH) Wildcat Point (PCH)
Wildcat Point-LP (PCH) Wildcat Point-LP (PCH)
BayTrail (SOC) BayTrail (SOC)
Sunrise Point-H (PCH)
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-i801. will be called i2c-i801.
...@@ -337,6 +348,17 @@ config I2C_AU1550 ...@@ -337,6 +348,17 @@ config I2C_AU1550
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-au1550. will be called i2c-au1550.
config I2C_AXXIA
tristate "Axxia I2C controller"
depends on ARCH_AXXIA || COMPILE_TEST
default ARCH_AXXIA
help
Say yes if you want to support the I2C bus on Axxia platforms.
Please note that this controller is limited to transfers of maximum
255 bytes in length. Any attempt to to a larger transfer will return
an error.
config I2C_BCM2835 config I2C_BCM2835
tristate "Broadcom BCM2835 I2C controller" tristate "Broadcom BCM2835 I2C controller"
depends on ARCH_BCM2835 depends on ARCH_BCM2835
...@@ -423,6 +445,7 @@ config I2C_DESIGNWARE_CORE ...@@ -423,6 +445,7 @@ config I2C_DESIGNWARE_CORE
config I2C_DESIGNWARE_PLATFORM config I2C_DESIGNWARE_PLATFORM
tristate "Synopsys DesignWare Platform" tristate "Synopsys DesignWare Platform"
select I2C_DESIGNWARE_CORE select I2C_DESIGNWARE_CORE
depends on (ACPI && COMMON_CLK) || !ACPI
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
Synopsys DesignWare I2C adapter. Only master mode is supported. Synopsys DesignWare I2C adapter. Only master mode is supported.
...@@ -465,7 +488,7 @@ config I2C_EG20T ...@@ -465,7 +488,7 @@ config I2C_EG20T
config I2C_EXYNOS5 config I2C_EXYNOS5
tristate "Exynos5 high-speed I2C driver" tristate "Exynos5 high-speed I2C driver"
depends on ARCH_EXYNOS5 && OF depends on ARCH_EXYNOS && OF
default y default y
help help
High-speed I2C controller on Exynos5 based Samsung SoCs. High-speed I2C controller on Exynos5 based Samsung SoCs.
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
# Embedded system I2C/SMBus host controller drivers # Embedded system I2C/SMBus host controller drivers
obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_AXXIA) += i2c-axxia.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o
...@@ -47,6 +48,7 @@ obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o ...@@ -47,6 +48,7 @@ obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
......
This diff is collapsed.
...@@ -96,7 +96,7 @@ static int ec_i2c_construct_message(u8 *buf, const struct i2c_msg i2c_msgs[], ...@@ -96,7 +96,7 @@ static int ec_i2c_construct_message(u8 *buf, const struct i2c_msg i2c_msgs[],
msg->addr_flags = i2c_msg->addr; msg->addr_flags = i2c_msg->addr;
if (i2c_msg->flags & I2C_M_TEN) if (i2c_msg->flags & I2C_M_TEN)
msg->addr_flags |= EC_I2C_FLAG_10BIT; return -EINVAL;
if (i2c_msg->flags & I2C_M_RD) { if (i2c_msg->flags & I2C_M_RD) {
msg->addr_flags |= EC_I2C_FLAG_READ; msg->addr_flags |= EC_I2C_FLAG_READ;
...@@ -220,7 +220,9 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[], ...@@ -220,7 +220,9 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
} }
} }
ec_i2c_construct_message(request, i2c_msgs, num, bus_num); result = ec_i2c_construct_message(request, i2c_msgs, num, bus_num);
if (result)
goto exit;
msg.version = 0; msg.version = 0;
msg.command = EC_CMD_I2C_PASSTHRU; msg.command = EC_CMD_I2C_PASSTHRU;
...@@ -313,11 +315,20 @@ static int ec_i2c_remove(struct platform_device *dev) ...@@ -313,11 +315,20 @@ static int ec_i2c_remove(struct platform_device *dev)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id cros_ec_i2c_of_match[] = {
{ .compatible = "google,cros-ec-i2c-tunnel" },
{},
};
MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
#endif
static struct platform_driver ec_i2c_tunnel_driver = { static struct platform_driver ec_i2c_tunnel_driver = {
.probe = ec_i2c_probe, .probe = ec_i2c_probe,
.remove = ec_i2c_remove, .remove = ec_i2c_remove,
.driver = { .driver = {
.name = "cros-ec-i2c-tunnel", .name = "cros-ec-i2c-tunnel",
.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
}, },
}; };
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -41,6 +42,7 @@ ...@@ -41,6 +42,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/platform_data/i2c-designware.h>
#include "i2c-designware-core.h" #include "i2c-designware-core.h"
static struct i2c_algorithm i2c_dw_algo = { static struct i2c_algorithm i2c_dw_algo = {
...@@ -79,10 +81,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], ...@@ -79,10 +81,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
static int dw_i2c_acpi_configure(struct platform_device *pdev) static int dw_i2c_acpi_configure(struct platform_device *pdev)
{ {
struct dw_i2c_dev *dev = platform_get_drvdata(pdev); struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
bool fs_mode = dev->master_cfg & DW_IC_CON_SPEED_FAST; const struct acpi_device_id *id;
if (!ACPI_HANDLE(&pdev->dev))
return -ENODEV;
dev->adapter.nr = -1; dev->adapter.nr = -1;
dev->tx_fifo_depth = 32; dev->tx_fifo_depth = 32;
...@@ -92,14 +91,33 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) ...@@ -92,14 +91,33 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
* Try to get SDA hold time and *CNT values from an ACPI method if * Try to get SDA hold time and *CNT values from an ACPI method if
* it exists for both supported speed modes. * it exists for both supported speed modes.
*/ */
dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL);
fs_mode ? NULL : &dev->sda_hold_time);
dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
fs_mode ? &dev->sda_hold_time : NULL); &dev->sda_hold_time);
/*
* Provide a way for Designware I2C host controllers that are not
* based on Intel LPSS to specify their input clock frequency via
* id->driver_data.
*/
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
clk_register_fixed_rate(&pdev->dev, dev_name(&pdev->dev), NULL,
CLK_IS_ROOT, id->driver_data);
return 0; return 0;
} }
static void dw_i2c_acpi_unconfigure(struct platform_device *pdev)
{
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
const struct acpi_device_id *id;
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
clk_unregister(dev->clk);
}
static const struct acpi_device_id dw_i2c_acpi_match[] = { static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT33C2", 0 }, { "INT33C2", 0 },
{ "INT33C3", 0 }, { "INT33C3", 0 },
...@@ -107,6 +125,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { ...@@ -107,6 +125,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3433", 0 }, { "INT3433", 0 },
{ "80860F41", 0 }, { "80860F41", 0 },
{ "808622C1", 0 }, { "808622C1", 0 },
{ "AMD0010", 133 * 1000 * 1000 },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
...@@ -115,6 +134,7 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev) ...@@ -115,6 +134,7 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
{ {
return -ENODEV; return -ENODEV;
} }
static inline void dw_i2c_acpi_unconfigure(struct platform_device *pdev) { }
#endif #endif
static int dw_i2c_probe(struct platform_device *pdev) static int dw_i2c_probe(struct platform_device *pdev)
...@@ -122,7 +142,9 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -122,7 +142,9 @@ static int dw_i2c_probe(struct platform_device *pdev)
struct dw_i2c_dev *dev; struct dw_i2c_dev *dev;
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct resource *mem; struct resource *mem;
struct dw_i2c_platform_data *pdata;
int irq, r; int irq, r;
u32 clk_freq, ht = 0;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
...@@ -145,21 +167,14 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -145,21 +167,14 @@ static int dw_i2c_probe(struct platform_device *pdev)
dev->irq = irq; dev->irq = irq;
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
dev->clk = devm_clk_get(&pdev->dev, NULL); /* fast mode by default because of legacy reasons */
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; clk_freq = 400000;
if (IS_ERR(dev->clk))
return PTR_ERR(dev->clk);
clk_prepare_enable(dev->clk);
if (pdev->dev.of_node) {
u32 ht = 0;
u32 ic_clk = dev->get_clk_rate_khz(dev);
if (ACPI_COMPANION(&pdev->dev)) {
dw_i2c_acpi_configure(pdev);
} else if (pdev->dev.of_node) {
of_property_read_u32(pdev->dev.of_node, of_property_read_u32(pdev->dev.of_node,
"i2c-sda-hold-time-ns", &ht); "i2c-sda-hold-time-ns", &ht);
dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
1000000);
of_property_read_u32(pdev->dev.of_node, of_property_read_u32(pdev->dev.of_node,
"i2c-sda-falling-time-ns", "i2c-sda-falling-time-ns",
...@@ -167,6 +182,21 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -167,6 +182,21 @@ static int dw_i2c_probe(struct platform_device *pdev)
of_property_read_u32(pdev->dev.of_node, of_property_read_u32(pdev->dev.of_node,
"i2c-scl-falling-time-ns", "i2c-scl-falling-time-ns",
&dev->scl_falling_time); &dev->scl_falling_time);
of_property_read_u32(pdev->dev.of_node, "clock-frequency",
&clk_freq);
/* Only standard mode at 100kHz and fast mode at 400kHz
* are supported.
*/
if (clk_freq != 100000 && clk_freq != 400000) {
dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
return -EINVAL;
}
} else {
pdata = dev_get_platdata(&pdev->dev);
if (pdata)
clk_freq = pdata->i2c_scl_freq;
} }
dev->functionality = dev->functionality =
...@@ -176,12 +206,27 @@ static int dw_i2c_probe(struct platform_device *pdev) ...@@ -176,12 +206,27 @@ static int dw_i2c_probe(struct platform_device *pdev)
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK; I2C_FUNC_SMBUS_I2C_BLOCK;
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | if (clk_freq == 100000)
DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_STD;
else
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
/* Try first if we can configure the device from ACPI */ dev->clk = devm_clk_get(&pdev->dev, NULL);
r = dw_i2c_acpi_configure(pdev); dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
if (r) { if (IS_ERR(dev->clk))
return PTR_ERR(dev->clk);
clk_prepare_enable(dev->clk);
if (!dev->sda_hold_time && ht) {
u32 ic_clk = dev->get_clk_rate_khz(dev);
dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
1000000);
}
if (!dev->tx_fifo_depth) {
u32 param1 = i2c_dw_read_comp_param(dev); u32 param1 = i2c_dw_read_comp_param(dev);
dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1; dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
...@@ -237,6 +282,9 @@ static int dw_i2c_remove(struct platform_device *pdev) ...@@ -237,6 +282,9 @@ static int dw_i2c_remove(struct platform_device *pdev)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (ACPI_COMPANION(&pdev->dev))
dw_i2c_acpi_unconfigure(pdev);
return 0; return 0;
} }
......
...@@ -83,7 +83,6 @@ ...@@ -83,7 +83,6 @@
#define HSI2C_INT_TX_ALMOSTEMPTY_EN (1u << 0) #define HSI2C_INT_TX_ALMOSTEMPTY_EN (1u << 0)
#define HSI2C_INT_RX_ALMOSTFULL_EN (1u << 1) #define HSI2C_INT_RX_ALMOSTFULL_EN (1u << 1)
#define HSI2C_INT_TRAILING_EN (1u << 6) #define HSI2C_INT_TRAILING_EN (1u << 6)
#define HSI2C_INT_I2C_EN (1u << 9)
/* I2C_INT_STAT Register bits */ /* I2C_INT_STAT Register bits */
#define HSI2C_INT_TX_ALMOSTEMPTY (1u << 0) #define HSI2C_INT_TX_ALMOSTEMPTY (1u << 0)
...@@ -95,6 +94,17 @@ ...@@ -95,6 +94,17 @@
#define HSI2C_INT_TRAILING (1u << 6) #define HSI2C_INT_TRAILING (1u << 6)
#define HSI2C_INT_I2C (1u << 9) #define HSI2C_INT_I2C (1u << 9)
#define HSI2C_INT_TRANS_DONE (1u << 7)
#define HSI2C_INT_TRANS_ABORT (1u << 8)
#define HSI2C_INT_NO_DEV_ACK (1u << 9)
#define HSI2C_INT_NO_DEV (1u << 10)
#define HSI2C_INT_TIMEOUT (1u << 11)
#define HSI2C_INT_I2C_TRANS (HSI2C_INT_TRANS_DONE | \
HSI2C_INT_TRANS_ABORT | \
HSI2C_INT_NO_DEV_ACK | \
HSI2C_INT_NO_DEV | \
HSI2C_INT_TIMEOUT)
/* I2C_FIFO_STAT Register bits */ /* I2C_FIFO_STAT Register bits */
#define HSI2C_RX_FIFO_EMPTY (1u << 24) #define HSI2C_RX_FIFO_EMPTY (1u << 24)
#define HSI2C_RX_FIFO_FULL (1u << 23) #define HSI2C_RX_FIFO_FULL (1u << 23)
...@@ -143,6 +153,8 @@ ...@@ -143,6 +153,8 @@
#define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(1000)) #define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(1000))
#define HSI2C_EXYNOS7 BIT(0)
struct exynos5_i2c { struct exynos5_i2c {
struct i2c_adapter adap; struct i2c_adapter adap;
unsigned int suspended:1; unsigned int suspended:1;
...@@ -192,6 +204,7 @@ struct exynos5_i2c { ...@@ -192,6 +204,7 @@ struct exynos5_i2c {
*/ */
struct exynos_hsi2c_variant { struct exynos_hsi2c_variant {
unsigned int fifo_depth; unsigned int fifo_depth;
unsigned int hw;
}; };
static const struct exynos_hsi2c_variant exynos5250_hsi2c_data = { static const struct exynos_hsi2c_variant exynos5250_hsi2c_data = {
...@@ -202,6 +215,11 @@ static const struct exynos_hsi2c_variant exynos5260_hsi2c_data = { ...@@ -202,6 +215,11 @@ static const struct exynos_hsi2c_variant exynos5260_hsi2c_data = {
.fifo_depth = 16, .fifo_depth = 16,
}; };
static const struct exynos_hsi2c_variant exynos7_hsi2c_data = {
.fifo_depth = 16,
.hw = HSI2C_EXYNOS7,
};
static const struct of_device_id exynos5_i2c_match[] = { static const struct of_device_id exynos5_i2c_match[] = {
{ {
.compatible = "samsung,exynos5-hsi2c", .compatible = "samsung,exynos5-hsi2c",
...@@ -212,6 +230,9 @@ static const struct of_device_id exynos5_i2c_match[] = { ...@@ -212,6 +230,9 @@ static const struct of_device_id exynos5_i2c_match[] = {
}, { }, {
.compatible = "samsung,exynos5260-hsi2c", .compatible = "samsung,exynos5260-hsi2c",
.data = &exynos5260_hsi2c_data .data = &exynos5260_hsi2c_data
}, {
.compatible = "samsung,exynos7-hsi2c",
.data = &exynos7_hsi2c_data
}, {}, }, {},
}; };
MODULE_DEVICE_TABLE(of, exynos5_i2c_match); MODULE_DEVICE_TABLE(of, exynos5_i2c_match);
...@@ -256,13 +277,24 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode) ...@@ -256,13 +277,24 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
i2c->hs_clock : i2c->fs_clock; i2c->hs_clock : i2c->fs_clock;
/* /*
* In case of HSI2C controller in Exynos5 series
* FPCLK / FI2C = * FPCLK / FI2C =
* (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
*
* In case of HSI2C controllers in Exynos7 series
* FPCLK / FI2C =
* (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + FLT_CYCLE
*
* utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
* utemp1 = (TSCLK_L + TSCLK_H + 2) * utemp1 = (TSCLK_L + TSCLK_H + 2)
*/ */
t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7; t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; utemp0 = (clkin / op_clk) - 8;
if (i2c->variant->hw == HSI2C_EXYNOS7)
utemp0 -= t_ftl_cycle;
else
utemp0 -= 2 * t_ftl_cycle;
/* CLK_DIV max is 256 */ /* CLK_DIV max is 256 */
for (div = 0; div < 256; div++) { for (div = 0; div < 256; div++) {
...@@ -407,7 +439,28 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) ...@@ -407,7 +439,28 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
writel(int_status, i2c->regs + HSI2C_INT_STATUS); writel(int_status, i2c->regs + HSI2C_INT_STATUS);
/* handle interrupt related to the transfer status */ /* handle interrupt related to the transfer status */
if (int_status & HSI2C_INT_I2C) { if (i2c->variant->hw == HSI2C_EXYNOS7) {
if (int_status & HSI2C_INT_TRANS_DONE) {
i2c->trans_done = 1;
i2c->state = 0;
} else if (int_status & HSI2C_INT_TRANS_ABORT) {
dev_dbg(i2c->dev, "Deal with arbitration lose\n");
i2c->state = -EAGAIN;
goto stop;
} else if (int_status & HSI2C_INT_NO_DEV_ACK) {
dev_dbg(i2c->dev, "No ACK from device\n");
i2c->state = -ENXIO;
goto stop;
} else if (int_status & HSI2C_INT_NO_DEV) {
dev_dbg(i2c->dev, "No device\n");
i2c->state = -ENXIO;
goto stop;
} else if (int_status & HSI2C_INT_TIMEOUT) {
dev_dbg(i2c->dev, "Accessing device timed out\n");
i2c->state = -EAGAIN;
goto stop;
}
} else if (int_status & HSI2C_INT_I2C) {
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if (trans_status & HSI2C_NO_DEV_ACK) { if (trans_status & HSI2C_NO_DEV_ACK) {
dev_dbg(i2c->dev, "No ACK from device\n"); dev_dbg(i2c->dev, "No ACK from device\n");
...@@ -512,12 +565,17 @@ static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c) ...@@ -512,12 +565,17 @@ static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c)
static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
{ {
u32 i2c_ctl; u32 i2c_ctl;
u32 int_en = HSI2C_INT_I2C_EN; u32 int_en = 0;
u32 i2c_auto_conf = 0; u32 i2c_auto_conf = 0;
u32 fifo_ctl; u32 fifo_ctl;
unsigned long flags; unsigned long flags;
unsigned short trig_lvl; unsigned short trig_lvl;
if (i2c->variant->hw == HSI2C_EXYNOS7)
int_en |= HSI2C_INT_I2C_TRANS;
else
int_en |= HSI2C_INT_I2C;
i2c_ctl = readl(i2c->regs + HSI2C_CTL); i2c_ctl = readl(i2c->regs + HSI2C_CTL);
i2c_ctl &= ~(HSI2C_TXCHON | HSI2C_RXCHON); i2c_ctl &= ~(HSI2C_TXCHON | HSI2C_RXCHON);
fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN; fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN;
...@@ -724,12 +782,13 @@ static int exynos5_i2c_probe(struct platform_device *pdev) ...@@ -724,12 +782,13 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
goto err_clk; goto err_clk;
} }
/* Need to check the variant before setting up. */
i2c->variant = exynos5_i2c_get_variant(pdev);
ret = exynos5_hsi2c_clock_setup(i2c); ret = exynos5_hsi2c_clock_setup(i2c);
if (ret) if (ret)
goto err_clk; goto err_clk;
i2c->variant = exynos5_i2c_get_variant(pdev);
exynos5_i2c_reset(i2c); exynos5_i2c_reset(i2c);
ret = i2c_add_adapter(&i2c->adap); ret = i2c_add_adapter(&i2c->adap);
......
This diff is collapsed.
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
* Wildcat Point (PCH) 0x8ca2 32 hard yes yes yes * Wildcat Point (PCH) 0x8ca2 32 hard yes yes yes
* Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes * Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes
* BayTrail (SOC) 0x0f12 32 hard yes yes yes * BayTrail (SOC) 0x0f12 32 hard yes yes yes
* Sunrise Point-H (PCH) 0xa123 32 hard yes yes yes
* *
* Features supported by this driver: * Features supported by this driver:
* Software PEC no * Software PEC no
...@@ -184,6 +185,7 @@ ...@@ -184,6 +185,7 @@
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2 #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS 0xa123
struct i801_mux_config { struct i801_mux_config {
char *gpio_chip; char *gpio_chip;
...@@ -830,6 +832,7 @@ static const struct pci_device_id i801_ids[] = { ...@@ -830,6 +832,7 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) },
{ 0, } { 0, }
}; };
......
...@@ -268,6 +268,14 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) ...@@ -268,6 +268,14 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
while (1) { while (1) {
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
/* check for arbitration lost */
if (temp & I2SR_IAL) {
temp &= ~I2SR_IAL;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
return -EAGAIN;
}
if (for_busy && (temp & I2SR_IBB)) if (for_busy && (temp & I2SR_IBB))
break; break;
if (!for_busy && !(temp & I2SR_IBB)) if (!for_busy && !(temp & I2SR_IBB))
...@@ -702,7 +710,7 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -702,7 +710,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
pdev->name, i2c_imx); pdev->name, i2c_imx);
if (ret) { if (ret) {
dev_err(&pdev->dev, "can't claim irq %d\n", irq); dev_err(&pdev->dev, "can't claim irq %d\n", irq);
return ret; goto clk_disable;
} }
/* Init queue */ /* Init queue */
...@@ -727,7 +735,7 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -727,7 +735,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
ret = i2c_add_numbered_adapter(&i2c_imx->adapter); ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "registration failed\n"); dev_err(&pdev->dev, "registration failed\n");
return ret; goto clk_disable;
} }
/* Set up platform driver data */ /* Set up platform driver data */
...@@ -741,6 +749,10 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -741,6 +749,10 @@ static int i2c_imx_probe(struct platform_device *pdev)
dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
return 0; /* Return OK */ return 0; /* Return OK */
clk_disable:
clk_disable_unprepare(i2c_imx->clk);
return ret;
} }
static int i2c_imx_remove(struct platform_device *pdev) static int i2c_imx_remove(struct platform_device *pdev)
......
...@@ -81,7 +81,7 @@ ...@@ -81,7 +81,7 @@
#define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a
#define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15
#define ISMT_DESC_ENTRIES 32 /* number of descriptor entries */ #define ISMT_DESC_ENTRIES 2 /* number of descriptor entries */
#define ISMT_MAX_RETRIES 3 /* number of SMBus retries to attempt */ #define ISMT_MAX_RETRIES 3 /* number of SMBus retries to attempt */
/* Hardware Descriptor Constants - Control Field */ /* Hardware Descriptor Constants - Control Field */
......
...@@ -307,6 +307,9 @@ static int mxs_i2c_pio_wait_xfer_end(struct mxs_i2c_dev *i2c) ...@@ -307,6 +307,9 @@ static int mxs_i2c_pio_wait_xfer_end(struct mxs_i2c_dev *i2c)
unsigned long timeout = jiffies + msecs_to_jiffies(1000); unsigned long timeout = jiffies + msecs_to_jiffies(1000);
while (readl(i2c->regs + MXS_I2C_CTRL0) & MXS_I2C_CTRL0_RUN) { while (readl(i2c->regs + MXS_I2C_CTRL0) & MXS_I2C_CTRL0_RUN) {
if (readl(i2c->regs + MXS_I2C_CTRL1) &
MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ)
return -ENXIO;
if (time_after(jiffies, timeout)) if (time_after(jiffies, timeout))
return -ETIMEDOUT; return -ETIMEDOUT;
cond_resched(); cond_resched();
......
...@@ -195,7 +195,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, ...@@ -195,7 +195,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
*/ */
rate = clk_get_rate(priv->clk); rate = clk_get_rate(priv->clk);
cdf = rate / 20000000; cdf = rate / 20000000;
if (cdf >= 1 << cdf_width) { if (cdf >= 1U << cdf_width) {
dev_err(dev, "Input clock %lu too high\n", rate); dev_err(dev, "Input clock %lu too high\n", rate);
return -EIO; return -EIO;
} }
...@@ -245,7 +245,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, ...@@ -245,7 +245,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
return 0; return 0;
} }
static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
{ {
int read = !!rcar_i2c_is_recv(priv); int read = !!rcar_i2c_is_recv(priv);
...@@ -253,8 +253,6 @@ static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) ...@@ -253,8 +253,6 @@ static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
rcar_i2c_write(priv, ICMSR, 0); rcar_i2c_write(priv, ICMSR, 0);
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
return 0;
} }
/* /*
...@@ -365,6 +363,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) ...@@ -365,6 +363,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
static irqreturn_t rcar_i2c_irq(int irq, void *ptr) static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
{ {
struct rcar_i2c_priv *priv = ptr; struct rcar_i2c_priv *priv = ptr;
irqreturn_t result = IRQ_HANDLED;
u32 msr; u32 msr;
/*-------------- spin lock -----------------*/ /*-------------- spin lock -----------------*/
...@@ -374,6 +373,10 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) ...@@ -374,6 +373,10 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
/* Only handle interrupts that are currently enabled */ /* Only handle interrupts that are currently enabled */
msr &= rcar_i2c_read(priv, ICMIER); msr &= rcar_i2c_read(priv, ICMIER);
if (!msr) {
result = IRQ_NONE;
goto exit;
}
/* Arbitration lost */ /* Arbitration lost */
if (msr & MAL) { if (msr & MAL) {
...@@ -408,10 +411,11 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) ...@@ -408,10 +411,11 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
wake_up(&priv->wait); wake_up(&priv->wait);
} }
exit:
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
/*-------------- spin unlock -----------------*/ /*-------------- spin unlock -----------------*/
return IRQ_HANDLED; return result;
} }
static int rcar_i2c_master_xfer(struct i2c_adapter *adap, static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
...@@ -453,17 +457,14 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -453,17 +457,14 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
priv->msg = &msgs[i]; priv->msg = &msgs[i];
priv->pos = 0; priv->pos = 0;
priv->flags = 0; priv->flags = 0;
if (priv->msg == &msgs[num - 1]) if (i == num - 1)
rcar_i2c_flags_set(priv, ID_LAST_MSG); rcar_i2c_flags_set(priv, ID_LAST_MSG);
ret = rcar_i2c_prepare_msg(priv); rcar_i2c_prepare_msg(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
/*-------------- spin unlock -----------------*/ /*-------------- spin unlock -----------------*/
if (ret < 0)
break;
timeout = wait_event_timeout(priv->wait, timeout = wait_event_timeout(priv->wait,
rcar_i2c_flags_has(priv, ID_DONE), rcar_i2c_flags_has(priv, ID_DONE),
5 * HZ); 5 * HZ);
......
...@@ -208,7 +208,7 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) ...@@ -208,7 +208,7 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
* The hw can read up to 32 bytes at a time. If we need more than one * The hw can read up to 32 bytes at a time. If we need more than one
* chunk, send an ACK after the last byte of the current chunk. * chunk, send an ACK after the last byte of the current chunk.
*/ */
if (unlikely(len > 32)) { if (len > 32) {
len = 32; len = 32;
con &= ~REG_CON_LASTACK; con &= ~REG_CON_LASTACK;
} else { } else {
...@@ -403,7 +403,7 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) ...@@ -403,7 +403,7 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
} }
/* is there anything left to handle? */ /* is there anything left to handle? */
if (unlikely((ipd & REG_INT_ALL) == 0)) if ((ipd & REG_INT_ALL) == 0)
goto out; goto out;
switch (i2c->state) { switch (i2c->state) {
......
...@@ -1928,9 +1928,6 @@ struct ec_response_power_info { ...@@ -1928,9 +1928,6 @@ struct ec_response_power_info {
#define EC_CMD_I2C_PASSTHRU 0x9e #define EC_CMD_I2C_PASSTHRU 0x9e
/* Slave address is 10 (not 7) bit */
#define EC_I2C_FLAG_10BIT (1 << 16)
/* Read data; if not present, message is a write */ /* Read data; if not present, message is a write */
#define EC_I2C_FLAG_READ (1 << 15) #define EC_I2C_FLAG_READ (1 << 15)
......
/*
* Copyright(c) 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*/
#ifndef I2C_DESIGNWARE_H
#define I2C_DESIGNWARE_H
struct dw_i2c_platform_data {
unsigned int i2c_scl_freq;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment