1
0
Fork 0

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

Pull i2c changes from Wolfram Sang:
 - new drivers for exynos5, bcm kona, and st micro
 - bigger overhauls for drivers mxs and rcar
 - typical driver bugfixes, cleanups, improvements
 - got rid of the superfluous 'driver' member in i2c_client struct This
   touches a few drivers in other subsystems.  All acked.

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (38 commits)
  i2c: bcm-kona: fix error return code in bcm_kona_i2c_probe()
  i2c: i2c-eg20t: do not print error message in syslog if no ACK received
  i2c: bcm-kona: Introduce Broadcom I2C Driver
  i2c: cbus-gpio: Fix device tree binding
  i2c: wmt: add missing clk_disable_unprepare() on error
  i2c: designware: add new ACPI IDs
  i2c: i801: Add Device IDs for Intel Wildcat Point-LP PCH
  i2c: exynos5: Remove incorrect clk_disable_unprepare
  i2c: i2c-st: Add ST I2C controller
  i2c: exynos5: add High Speed I2C controller driver
  i2c: rcar: fixup rcar type naming
  i2c: scmi: remove some bogus NULL checks
  i2c: sh_mobile & rcar: Enable the driver on all ARM platforms
  i2c: sh_mobile: Convert to clk_prepare/unprepare
  i2c: mux: gpio: use reg value for i2c_add_mux_adapter
  i2c: mux: gpio: use gpio_set_value_cansleep()
  i2c: Include linux/of.h header
  i2c: mxs: Fix PIO mode on i.MX23
  i2c: mxs: Rework the PIO mode operation
  i2c: mxs: distinguish i.MX23 and i.MX28 based I2C controller
  ...
hifive-unleashed-5.1
Linus Torvalds 2013-11-18 15:50:07 -08:00
commit 13509c3a9d
66 changed files with 3109 additions and 242 deletions

View File

@ -0,0 +1,35 @@
Broadcom Kona Family I2C
=========================
This I2C controller is used in the following Broadcom SoCs:
BCM11130
BCM11140
BCM11351
BCM28145
BCM28155
Required Properties
-------------------
- compatible: "brcm,bcm11351-i2c", "brcm,kona-i2c"
- reg: Physical base address and length of controller registers
- interrupts: The interrupt number used by the controller
- clocks: clock specifier for the kona i2c external clock
- clock-frequency: The I2C bus frequency in Hz
- #address-cells: Should be <1>
- #size-cells: Should be <0>
Refer to clocks/clock-bindings.txt for generic clock consumer
properties.
Example:
i2c@3e016000 {
compatible = "brcm,bcm11351-i2c","brcm,kona-i2c";
reg = <0x3e016000 0x80>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bsc1_clk>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,44 @@
* Samsung's High Speed I2C controller
The Samsung's High Speed I2C controller is used to interface with I2C devices
at various speeds ranging from 100khz to 3.4Mhz.
Required properties:
- compatible: value should be.
-> "samsung,exynos5-hsi2c", for i2c compatible with exynos5 hsi2c.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
- #address-cells: always 1 (for i2c addresses)
- #size-cells: always 0
- Pinctrl:
- pinctrl-0: Pin control group to be used for this controller.
- pinctrl-names: Should contain only one value - "default".
Optional properties:
- clock-frequency: Desired operating frequency in Hz of the bus.
-> If not specified, the bus operates in fast-speed mode at
at 100khz.
-> If specified, the bus operates in high-speed mode only if the
clock-frequency is >= 1Mhz.
Example:
hsi2c@12ca0000 {
compatible = "samsung,exynos5-hsi2c";
reg = <0x12ca0000 0x100>;
interrupts = <56>;
clock-frequency = <100000>;
pinctrl-0 = <&i2c4_bus>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
s2mps11_pmic@66 {
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
};
};

View File

@ -0,0 +1,23 @@
I2C for R-Car platforms
Required properties:
- compatible: Must be one of
"renesas,i2c-rcar"
"renesas,i2c-r8a7778"
"renesas,i2c-r8a7779"
"renesas,i2c-r8a7790"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt specifier.
Optional properties:
- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this
propoerty indicates the default frequency 100 kHz.
Examples :
i2c0: i2c@e6500000 {
compatible = "renesas,i2c-rcar-h2";
reg = <0 0xe6500000 0 0x428>;
interrupts = <0 174 0x4>;
};

View File

@ -0,0 +1,41 @@
ST SSC binding, for I2C mode operation
Required properties :
- compatible : Must be "st,comms-ssc-i2c" or "st,comms-ssc4-i2c"
- reg : Offset and length of the register set for the device
- interrupts : the interrupt specifier
- clock-names: Must contain "ssc".
- clocks: Must contain an entry for each name in clock-names. See the common
clock bindings.
- A pinctrl state named "default" must be defined to set pins in mode of
operation for I2C transfer.
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.
- st,i2c-min-scl-pulse-width-us : The minimum valid SCL pulse width that is
allowed through the deglitch circuit. In units of us.
- st,i2c-min-sda-pulse-width-us : The minimum valid SDA pulse width that is
allowed through the deglitch circuit. In units of us.
- A pinctrl state named "idle" could be defined to set pins in idle state
when I2C instance is not performing a transfer.
- A pinctrl state named "sleep" could be defined to set pins in sleep state
when driver enters in suspend.
Example :
i2c0: i2c@fed40000 {
compatible = "st,comms-ssc4-i2c";
reg = <0xfed40000 0x110>;
interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&CLK_S_ICN_REG_0>;
clock-names = "ssc";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0_default>;
st,i2c-min-scl-pulse-width-us = <0>;
st,i2c-min-sda-pulse-width-us = <5>;
};

View File

@ -25,6 +25,7 @@ Supported adapters:
* Intel Avoton (SOC)
* Intel Wellsburg (PCH)
* Intel Coleto Creek (PCH)
* Intel Wildcat Point-LP (PCH)
Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller

View File

@ -1425,7 +1425,7 @@ M: Wolfram Sang <wsa@the-dreams.de>
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/misc/eeprom/at24.c
F: include/linux/i2c/at24.h
F: include/linux/platform_data/at24.h
ATA OVER ETHERNET (AOE) DRIVER
M: "Ed L. Cashin" <ecashin@coraid.com>

View File

@ -28,7 +28,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/at73c213.h>
#include <linux/clk.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>

View File

@ -27,7 +27,7 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/fb.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>

View File

@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/spi/spi.h>

View File

@ -18,7 +18,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/platform_data/pca953x.h>
#include <linux/input.h>
#include <linux/input/tps6507x-ts.h>

View File

@ -18,7 +18,7 @@
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/leds.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>

View File

@ -15,7 +15,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>

View File

@ -22,7 +22,7 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/i2c/pcf857x.h>
#include <media/tvp514x.h>

View File

@ -15,7 +15,7 @@
#include <linux/mtd/partitions.h>
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/etherdevice.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>

View File

@ -26,7 +26,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>

View File

@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>

View File

@ -23,7 +23,7 @@
#include <linux/smsc911x.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/irq.h>

View File

@ -18,7 +18,7 @@
*/
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/io.h>
#include <linux/mtd/plat-ram.h>
#include <linux/mtd/physmap.h>

View File

@ -24,7 +24,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>

View File

@ -29,7 +29,7 @@
#include <asm/mach/time.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/mfd/mc13xxx.h>
#include "common.h"

View File

@ -12,7 +12,7 @@
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/gpio.h>
#include <asm/mach/time.h>
#include <mach/kirkwood.h>

View File

@ -300,7 +300,7 @@ static struct omap_lcd_config osk_lcd_config __initdata = {
#ifdef CONFIG_OMAP_OSK_MISTRAL
#include <linux/input.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>

View File

@ -25,7 +25,7 @@
#include <linux/gpio.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>

View File

@ -20,7 +20,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/input.h>
#include <linux/err.h>
#include <linux/clk.h>

View File

@ -32,7 +32,7 @@
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/smsc911x.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/usb/phy.h>
#include <asm/mach-types.h>

View File

@ -27,7 +27,7 @@
#include <linux/i2c/pxa-i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/smc91x.h>
#include <linux/gpio.h>
#include <linux/leds.h>

View File

@ -24,7 +24,7 @@
#include <linux/io.h>
#include <linux/serial_core.h>
#include <linux/dm9000.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>

View File

@ -67,12 +67,12 @@ int drm_i2c_encoder_init(struct drm_device *dev,
goto fail;
}
if (!client->driver) {
if (!client->dev.driver) {
err = -ENODEV;
goto fail_unregister;
}
module = client->driver->driver.owner;
module = client->dev.driver->owner;
if (!try_module_get(module)) {
err = -ENODEV;
goto fail_unregister;
@ -80,7 +80,7 @@ int drm_i2c_encoder_init(struct drm_device *dev,
encoder->bus_priv = client;
encoder_drv = to_drm_i2c_encoder_driver(client->driver);
encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
err = encoder_drv->encoder_init(client, dev, encoder);
if (err)
@ -111,7 +111,7 @@ void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
{
struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
struct module *module = client->driver->driver.owner;
struct module *module = client->dev.driver->owner;
i2c_unregister_device(client);
encoder->bus_priv = NULL;

View File

@ -41,7 +41,8 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
if (!client)
return false;
if (!client->driver || client->driver->detect(client, info)) {
if (!client->dev.driver ||
to_i2c_driver(client->dev.driver)->detect(client, info)) {
i2c_unregister_device(client);
return false;
}

View File

@ -109,6 +109,7 @@ config I2C_I801
Avoton (SOC)
Wellsburg (PCH)
Coleto Creek (PCH)
Wildcat Point-LP (PCH)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
@ -345,6 +346,16 @@ config I2C_BCM2835
This support is also available as a module. If so, the module
will be called i2c-bcm2835.
config I2C_BCM_KONA
tristate "BCM Kona I2C adapter"
depends on ARCH_BCM_MOBILE
default y
help
If you say yes to this option, support will be included for the
I2C interface on the Broadcom Kona family of processors.
If you do not need KONA I2C inteface, say N.
config I2C_BLACKFIN_TWI
tristate "Blackfin TWI I2C support"
depends on BLACKFIN
@ -436,6 +447,13 @@ config I2C_EG20T
ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
config I2C_EXYNOS5
tristate "Exynos5 high-speed I2C driver"
depends on ARCH_EXYNOS5 && OF
help
Say Y here to include support for high-speed I2C controller in the
Exynos5 based Samsung SoCs.
config I2C_GPIO
tristate "GPIO-based bitbanging I2C"
depends on GPIOLIB
@ -665,7 +683,7 @@ config I2C_SH7760
config I2C_SH_MOBILE
tristate "SuperH Mobile I2C Controller"
depends on SUPERH || ARCH_SHMOBILE
depends on SUPERH || ARM || COMPILE_TEST
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Renesas SH-Mobile processor.
@ -695,6 +713,16 @@ config I2C_SIRF
This driver can also be built as a module. If so, the module
will be called i2c-sirf.
config I2C_ST
tristate "STMicroelectronics SSC I2C support"
depends on ARCH_STI
help
Enable this option to add support for STMicroelectronics SoCs
hardware SSC (Synchronous Serial Controller) as an I2C controller.
This driver can also be built as module. If so, the module
will be called i2c-st.
config I2C_STU300
tristate "ST Microelectronics DDC I2C interface"
depends on MACH_U300
@ -768,7 +796,7 @@ config I2C_XLR
config I2C_RCAR
tristate "Renesas R-Car I2C Controller"
depends on ARCH_SHMOBILE && I2C
depends on ARM || COMPILE_TEST
help
If you say yes to this option, support will be included for the
R-Car I2C controller.

View File

@ -42,6 +42,7 @@ i2c-designware-platform-objs := i2c-designware-platdrv.o
obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
i2c-designware-pci-objs := i2c-designware-pcidrv.o
obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
@ -68,6 +69,7 @@ obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
obj-$(CONFIG_I2C_ST) += i2c-st.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
@ -87,6 +89,7 @@ obj-$(CONFIG_I2C_VIPERBOARD) += i2c-viperboard.o
# Other I2C/SMBus bus drivers
obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o
obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o

View File

@ -0,0 +1,909 @@
/*
* Copyright (C) 2013 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/slab.h>
/* Hardware register offsets and field defintions */
#define CS_OFFSET 0x00000020
#define CS_ACK_SHIFT 3
#define CS_ACK_MASK 0x00000008
#define CS_ACK_CMD_GEN_START 0x00000000
#define CS_ACK_CMD_GEN_RESTART 0x00000001
#define CS_CMD_SHIFT 1
#define CS_CMD_CMD_NO_ACTION 0x00000000
#define CS_CMD_CMD_START_RESTART 0x00000001
#define CS_CMD_CMD_STOP 0x00000002
#define CS_EN_SHIFT 0
#define CS_EN_CMD_ENABLE_BSC 0x00000001
#define TIM_OFFSET 0x00000024
#define TIM_PRESCALE_SHIFT 6
#define TIM_P_SHIFT 3
#define TIM_NO_DIV_SHIFT 2
#define TIM_DIV_SHIFT 0
#define DAT_OFFSET 0x00000028
#define TOUT_OFFSET 0x0000002c
#define TXFCR_OFFSET 0x0000003c
#define TXFCR_FIFO_FLUSH_MASK 0x00000080
#define TXFCR_FIFO_EN_MASK 0x00000040
#define IER_OFFSET 0x00000044
#define IER_READ_COMPLETE_INT_MASK 0x00000010
#define IER_I2C_INT_EN_MASK 0x00000008
#define IER_FIFO_INT_EN_MASK 0x00000002
#define IER_NOACK_EN_MASK 0x00000001
#define ISR_OFFSET 0x00000048
#define ISR_RESERVED_MASK 0xffffff60
#define ISR_CMDBUSY_MASK 0x00000080
#define ISR_READ_COMPLETE_MASK 0x00000010
#define ISR_SES_DONE_MASK 0x00000008
#define ISR_ERR_MASK 0x00000004
#define ISR_TXFIFOEMPTY_MASK 0x00000002
#define ISR_NOACK_MASK 0x00000001
#define CLKEN_OFFSET 0x0000004C
#define CLKEN_AUTOSENSE_OFF_MASK 0x00000080
#define CLKEN_M_SHIFT 4
#define CLKEN_N_SHIFT 1
#define CLKEN_CLKEN_MASK 0x00000001
#define FIFO_STATUS_OFFSET 0x00000054
#define FIFO_STATUS_RXFIFO_EMPTY_MASK 0x00000004
#define FIFO_STATUS_TXFIFO_EMPTY_MASK 0x00000010
#define HSTIM_OFFSET 0x00000058
#define HSTIM_HS_MODE_MASK 0x00008000
#define HSTIM_HS_HOLD_SHIFT 10
#define HSTIM_HS_HIGH_PHASE_SHIFT 5
#define HSTIM_HS_SETUP_SHIFT 0
#define PADCTL_OFFSET 0x0000005c
#define PADCTL_PAD_OUT_EN_MASK 0x00000004
#define RXFCR_OFFSET 0x00000068
#define RXFCR_NACK_EN_SHIFT 7
#define RXFCR_READ_COUNT_SHIFT 0
#define RXFIFORDOUT_OFFSET 0x0000006c
/* Locally used constants */
#define MAX_RX_FIFO_SIZE 64U /* bytes */
#define MAX_TX_FIFO_SIZE 64U /* bytes */
#define STD_EXT_CLK_FREQ 13000000UL
#define HS_EXT_CLK_FREQ 104000000UL
#define MASTERCODE 0x08 /* Mastercodes are 0000_1xxxb */
#define I2C_TIMEOUT 100 /* msecs */
/* Operations that can be commanded to the controller */
enum bcm_kona_cmd_t {
BCM_CMD_NOACTION = 0,
BCM_CMD_START,
BCM_CMD_RESTART,
BCM_CMD_STOP,
};
enum bus_speed_index {
BCM_SPD_100K = 0,
BCM_SPD_400K,
BCM_SPD_1MHZ,
};
enum hs_bus_speed_index {
BCM_SPD_3P4MHZ = 0,
};
/* Internal divider settings for standard mode, fast mode and fast mode plus */
struct bus_speed_cfg {
uint8_t time_m; /* Number of cycles for setup time */
uint8_t time_n; /* Number of cycles for hold time */
uint8_t prescale; /* Prescale divider */
uint8_t time_p; /* Timing coefficient */
uint8_t no_div; /* Disable clock divider */
uint8_t time_div; /* Post-prescale divider */
};
/* Internal divider settings for high-speed mode */
struct hs_bus_speed_cfg {
uint8_t hs_hold; /* Number of clock cycles SCL stays low until
the end of bit period */
uint8_t hs_high_phase; /* Number of clock cycles SCL stays high
before it falls */
uint8_t hs_setup; /* Number of clock cycles SCL stays low
before it rises */
uint8_t prescale; /* Prescale divider */
uint8_t time_p; /* Timing coefficient */
uint8_t no_div; /* Disable clock divider */
uint8_t time_div; /* Post-prescale divider */
};
static const struct bus_speed_cfg std_cfg_table[] = {
[BCM_SPD_100K] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
[BCM_SPD_400K] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
[BCM_SPD_1MHZ] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
};
static const struct hs_bus_speed_cfg hs_cfg_table[] = {
[BCM_SPD_3P4MHZ] = {0x01, 0x08, 0x14, 0x00, 0x06, 0x01, 0x00},
};
struct bcm_kona_i2c_dev {
struct device *device;
void __iomem *base;
int irq;
struct clk *external_clk;
struct i2c_adapter adapter;
struct completion done;
const struct bus_speed_cfg *std_cfg;
const struct hs_bus_speed_cfg *hs_cfg;
};
static void bcm_kona_i2c_send_cmd_to_ctrl(struct bcm_kona_i2c_dev *dev,
enum bcm_kona_cmd_t cmd)
{
dev_dbg(dev->device, "%s, %d\n", __func__, cmd);
switch (cmd) {
case BCM_CMD_NOACTION:
writel((CS_CMD_CMD_NO_ACTION << CS_CMD_SHIFT) |
(CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT),
dev->base + CS_OFFSET);
break;
case BCM_CMD_START:
writel((CS_ACK_CMD_GEN_START << CS_ACK_SHIFT) |
(CS_CMD_CMD_START_RESTART << CS_CMD_SHIFT) |
(CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT),
dev->base + CS_OFFSET);
break;
case BCM_CMD_RESTART:
writel((CS_ACK_CMD_GEN_RESTART << CS_ACK_SHIFT) |
(CS_CMD_CMD_START_RESTART << CS_CMD_SHIFT) |
(CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT),
dev->base + CS_OFFSET);
break;
case BCM_CMD_STOP:
writel((CS_CMD_CMD_STOP << CS_CMD_SHIFT) |
(CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT),
dev->base + CS_OFFSET);
break;
default:
dev_err(dev->device, "Unknown command %d\n", cmd);
}
}
static void bcm_kona_i2c_enable_clock(struct bcm_kona_i2c_dev *dev)
{
writel(readl(dev->base + CLKEN_OFFSET) | CLKEN_CLKEN_MASK,
dev->base + CLKEN_OFFSET);
}
static void bcm_kona_i2c_disable_clock(struct bcm_kona_i2c_dev *dev)
{
writel(readl(dev->base + CLKEN_OFFSET) & ~CLKEN_CLKEN_MASK,
dev->base + CLKEN_OFFSET);
}
static irqreturn_t bcm_kona_i2c_isr(int irq, void *devid)
{
struct bcm_kona_i2c_dev *dev = devid;
uint32_t status = readl(dev->base + ISR_OFFSET);
if ((status & ~ISR_RESERVED_MASK) == 0)
return IRQ_NONE;
/* Must flush the TX FIFO when NAK detected */
if (status & ISR_NOACK_MASK)
writel(TXFCR_FIFO_FLUSH_MASK | TXFCR_FIFO_EN_MASK,
dev->base + TXFCR_OFFSET);
writel(status & ~ISR_RESERVED_MASK, dev->base + ISR_OFFSET);
complete_all(&dev->done);
return IRQ_HANDLED;
}
/* Wait for ISR_CMDBUSY_MASK to go low before writing to CS, DAT, or RCD */
static int bcm_kona_i2c_wait_if_busy(struct bcm_kona_i2c_dev *dev)
{
unsigned long timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT);
while (readl(dev->base + ISR_OFFSET) & ISR_CMDBUSY_MASK)
if (time_after(jiffies, timeout)) {
dev_err(dev->device, "CMDBUSY timeout\n");
return -ETIMEDOUT;
}
return 0;
}
/* Send command to I2C bus */
static int bcm_kona_send_i2c_cmd(struct bcm_kona_i2c_dev *dev,
enum bcm_kona_cmd_t cmd)
{
int rc;
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT);
/* Make sure the hardware is ready */
rc = bcm_kona_i2c_wait_if_busy(dev);
if (rc < 0)
return rc;
/* Unmask the session done interrupt */
writel(IER_I2C_INT_EN_MASK, dev->base + IER_OFFSET);
/* Mark as incomplete before sending the command */
reinit_completion(&dev->done);
/* Send the command */
bcm_kona_i2c_send_cmd_to_ctrl(dev, cmd);
/* Wait for transaction to finish or timeout */
time_left = wait_for_completion_timeout(&dev->done, time_left);
/* Mask all interrupts */
writel(0, dev->base + IER_OFFSET);
if (!time_left) {
dev_err(dev->device, "controller timed out\n");
rc = -ETIMEDOUT;
}
/* Clear command */
bcm_kona_i2c_send_cmd_to_ctrl(dev, BCM_CMD_NOACTION);
return rc;
}
/* Read a single RX FIFO worth of data from the i2c bus */
static int bcm_kona_i2c_read_fifo_single(struct bcm_kona_i2c_dev *dev,
uint8_t *buf, unsigned int len,
unsigned int last_byte_nak)
{
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT);
/* Mark as incomplete before starting the RX FIFO */
reinit_completion(&dev->done);
/* Unmask the read complete interrupt */
writel(IER_READ_COMPLETE_INT_MASK, dev->base + IER_OFFSET);
/* Start the RX FIFO */
writel((last_byte_nak << RXFCR_NACK_EN_SHIFT) |
(len << RXFCR_READ_COUNT_SHIFT),
dev->base + RXFCR_OFFSET);
/* Wait for FIFO read to complete */
time_left = wait_for_completion_timeout(&dev->done, time_left);
/* Mask all interrupts */
writel(0, dev->base + IER_OFFSET);
if (!time_left) {
dev_err(dev->device, "RX FIFO time out\n");
return -EREMOTEIO;
}
/* Read data from FIFO */
for (; len > 0; len--, buf++)
*buf = readl(dev->base + RXFIFORDOUT_OFFSET);
return 0;
}
/* Read any amount of data using the RX FIFO from the i2c bus */
static int bcm_kona_i2c_read_fifo(struct bcm_kona_i2c_dev *dev,
struct i2c_msg *msg)
{
unsigned int bytes_to_read = MAX_RX_FIFO_SIZE;
unsigned int last_byte_nak = 0;
unsigned int bytes_read = 0;
int rc;
uint8_t *tmp_buf = msg->buf;
while (bytes_read < msg->len) {
if (msg->len - bytes_read <= MAX_RX_FIFO_SIZE) {
last_byte_nak = 1; /* NAK last byte of transfer */
bytes_to_read = msg->len - bytes_read;
}
rc = bcm_kona_i2c_read_fifo_single(dev, tmp_buf, bytes_to_read,
last_byte_nak);
if (rc < 0)
return -EREMOTEIO;
bytes_read += bytes_to_read;
tmp_buf += bytes_to_read;
}
return 0;
}
/* Write a single byte of data to the i2c bus */
static int bcm_kona_i2c_write_byte(struct bcm_kona_i2c_dev *dev, uint8_t data,
unsigned int nak_expected)
{
int rc;
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT);
unsigned int nak_received;
/* Make sure the hardware is ready */
rc = bcm_kona_i2c_wait_if_busy(dev);
if (rc < 0)
return rc;
/* Clear pending session done interrupt */
writel(ISR_SES_DONE_MASK, dev->base + ISR_OFFSET);
/* Unmask the session done interrupt */
writel(IER_I2C_INT_EN_MASK, dev->base + IER_OFFSET);
/* Mark as incomplete before sending the data */
reinit_completion(&dev->done);
/* Send one byte of data */
writel(data, dev->base + DAT_OFFSET);
/* Wait for byte to be written */
time_left = wait_for_completion_timeout(&dev->done, time_left);
/* Mask all interrupts */
writel(0, dev->base + IER_OFFSET);
if (!time_left) {
dev_dbg(dev->device, "controller timed out\n");
return -ETIMEDOUT;
}
nak_received = readl(dev->base + CS_OFFSET) & CS_ACK_MASK ? 1 : 0;
if (nak_received ^ nak_expected) {
dev_dbg(dev->device, "unexpected NAK/ACK\n");
return -EREMOTEIO;
}
return 0;
}
/* Write a single TX FIFO worth of data to the i2c bus */
static int bcm_kona_i2c_write_fifo_single(struct bcm_kona_i2c_dev *dev,
uint8_t *buf, unsigned int len)
{
int k;
unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT);
unsigned int fifo_status;
/* Mark as incomplete before sending data to the TX FIFO */
reinit_completion(&dev->done);
/* Unmask the fifo empty and nak interrupt */
writel(IER_FIFO_INT_EN_MASK | IER_NOACK_EN_MASK,
dev->base + IER_OFFSET);
/* Disable IRQ to load a FIFO worth of data without interruption */
disable_irq(dev->irq);
/* Write data into FIFO */
for (k = 0; k < len; k++)
writel(buf[k], (dev->base + DAT_OFFSET));
/* Enable IRQ now that data has been loaded */
enable_irq(dev->irq);
/* Wait for FIFO to empty */
do {
time_left = wait_for_completion_timeout(&dev->done, time_left);
fifo_status = readl(dev->base + FIFO_STATUS_OFFSET);
} while (time_left && !(fifo_status & FIFO_STATUS_TXFIFO_EMPTY_MASK));
/* Mask all interrupts */
writel(0, dev->base + IER_OFFSET);
/* Check if there was a NAK */
if (readl(dev->base + CS_OFFSET) & CS_ACK_MASK) {
dev_err(dev->device, "unexpected NAK\n");
return -EREMOTEIO;
}
/* Check if a timeout occured */
if (!time_left) {
dev_err(dev->device, "completion timed out\n");
return -EREMOTEIO;
}
return 0;
}
/* Write any amount of data using TX FIFO to the i2c bus */
static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev,
struct i2c_msg *msg)
{
unsigned int bytes_to_write = MAX_TX_FIFO_SIZE;
unsigned int bytes_written = 0;
int rc;
uint8_t *tmp_buf = msg->buf;
while (bytes_written < msg->len) {
if (msg->len - bytes_written <= MAX_TX_FIFO_SIZE)
bytes_to_write = msg->len - bytes_written;
rc = bcm_kona_i2c_write_fifo_single(dev, tmp_buf,
bytes_to_write);
if (rc < 0)
return -EREMOTEIO;
bytes_written += bytes_to_write;
tmp_buf += bytes_to_write;
}
return 0;
}
/* Send i2c address */
static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev,
struct i2c_msg *msg)
{
unsigned char addr;
if (msg->flags & I2C_M_TEN) {
/* First byte is 11110XX0 where XX is upper 2 bits */
addr = 0xF0 | ((msg->addr & 0x300) >> 7);
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
/* Second byte is the remaining 8 bits */
addr = msg->addr & 0xFF;
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
if (msg->flags & I2C_M_RD) {
/* For read, send restart command */
if (bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART) < 0)
return -EREMOTEIO;
/* Then re-send the first byte with the read bit set */
addr = 0xF0 | ((msg->addr & 0x300) >> 7) | 0x01;
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
}
} else {
addr = msg->addr << 1;
if (msg->flags & I2C_M_RD)
addr |= 1;
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
}
return 0;
}
static void bcm_kona_i2c_enable_autosense(struct bcm_kona_i2c_dev *dev)
{
writel(readl(dev->base + CLKEN_OFFSET) & ~CLKEN_AUTOSENSE_OFF_MASK,
dev->base + CLKEN_OFFSET);
}
static void bcm_kona_i2c_config_timing(struct bcm_kona_i2c_dev *dev)
{
writel(readl(dev->base + HSTIM_OFFSET) & ~HSTIM_HS_MODE_MASK,
dev->base + HSTIM_OFFSET);
writel((dev->std_cfg->prescale << TIM_PRESCALE_SHIFT) |
(dev->std_cfg->time_p << TIM_P_SHIFT) |
(dev->std_cfg->no_div << TIM_NO_DIV_SHIFT) |
(dev->std_cfg->time_div << TIM_DIV_SHIFT),
dev->base + TIM_OFFSET);
writel((dev->std_cfg->time_m << CLKEN_M_SHIFT) |
(dev->std_cfg->time_n << CLKEN_N_SHIFT) |
CLKEN_CLKEN_MASK,
dev->base + CLKEN_OFFSET);
}
static void bcm_kona_i2c_config_timing_hs(struct bcm_kona_i2c_dev *dev)
{
writel((dev->hs_cfg->prescale << TIM_PRESCALE_SHIFT) |
(dev->hs_cfg->time_p << TIM_P_SHIFT) |
(dev->hs_cfg->no_div << TIM_NO_DIV_SHIFT) |
(dev->hs_cfg->time_div << TIM_DIV_SHIFT),
dev->base + TIM_OFFSET);
writel((dev->hs_cfg->hs_hold << HSTIM_HS_HOLD_SHIFT) |
(dev->hs_cfg->hs_high_phase << HSTIM_HS_HIGH_PHASE_SHIFT) |
(dev->hs_cfg->hs_setup << HSTIM_HS_SETUP_SHIFT),
dev->base + HSTIM_OFFSET);
writel(readl(dev->base + HSTIM_OFFSET) | HSTIM_HS_MODE_MASK,
dev->base + HSTIM_OFFSET);
}
static int bcm_kona_i2c_switch_to_hs(struct bcm_kona_i2c_dev *dev)
{
int rc;
/* Send mastercode at standard speed */
rc = bcm_kona_i2c_write_byte(dev, MASTERCODE, 1);
if (rc < 0) {
pr_err("High speed handshake failed\n");
return rc;
}
/* Configure external clock to higher frequency */
rc = clk_set_rate(dev->external_clk, HS_EXT_CLK_FREQ);
if (rc) {
dev_err(dev->device, "%s: clk_set_rate returned %d\n",
__func__, rc);
return rc;
}
/* Reconfigure internal dividers */
bcm_kona_i2c_config_timing_hs(dev);
/* Send a restart command */
rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART);
if (rc < 0)
dev_err(dev->device, "High speed restart command failed\n");
return rc;
}
static int bcm_kona_i2c_switch_to_std(struct bcm_kona_i2c_dev *dev)
{
int rc;
/* Reconfigure internal dividers */
bcm_kona_i2c_config_timing(dev);
/* Configure external clock to lower frequency */
rc = clk_set_rate(dev->external_clk, STD_EXT_CLK_FREQ);
if (rc) {
dev_err(dev->device, "%s: clk_set_rate returned %d\n",
__func__, rc);
}
return rc;
}
/* Master transfer function */
static int bcm_kona_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num)
{
struct bcm_kona_i2c_dev *dev = i2c_get_adapdata(adapter);
struct i2c_msg *pmsg;
int rc = 0;
int i;
rc = clk_prepare_enable(dev->external_clk);
if (rc) {
dev_err(dev->device, "%s: peri clock enable failed. err %d\n",
__func__, rc);
return rc;
}
/* Enable pad output */
writel(0, dev->base + PADCTL_OFFSET);
/* Enable internal clocks */
bcm_kona_i2c_enable_clock(dev);
/* Send start command */
rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_START);
if (rc < 0) {
dev_err(dev->device, "Start command failed rc = %d\n", rc);
goto xfer_disable_pad;
}
/* Switch to high speed if applicable */
if (dev->hs_cfg) {
rc = bcm_kona_i2c_switch_to_hs(dev);
if (rc < 0)
goto xfer_send_stop;
}
/* Loop through all messages */
for (i = 0; i < num; i++) {
pmsg = &msgs[i];
/* Send restart for subsequent messages */
if ((i != 0) && ((pmsg->flags & I2C_M_NOSTART) == 0)) {
rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART);
if (rc < 0) {
dev_err(dev->device,
"restart cmd failed rc = %d\n", rc);
goto xfer_send_stop;
}
}
/* Send slave address */
if (!(pmsg->flags & I2C_M_NOSTART)) {
rc = bcm_kona_i2c_do_addr(dev, pmsg);
if (rc < 0) {
dev_err(dev->device,
"NAK from addr %2.2x msg#%d rc = %d\n",
pmsg->addr, i, rc);
goto xfer_send_stop;
}
}
/* Perform data transfer */
if (pmsg->flags & I2C_M_RD) {
rc = bcm_kona_i2c_read_fifo(dev, pmsg);
if (rc < 0) {
dev_err(dev->device, "read failure\n");
goto xfer_send_stop;
}
} else {
rc = bcm_kona_i2c_write_fifo(dev, pmsg);
if (rc < 0) {
dev_err(dev->device, "write failure");
goto xfer_send_stop;
}
}
}
rc = num;
xfer_send_stop:
/* Send a STOP command */
bcm_kona_send_i2c_cmd(dev, BCM_CMD_STOP);
/* Return from high speed if applicable */
if (dev->hs_cfg) {
int hs_rc = bcm_kona_i2c_switch_to_std(dev);
if (hs_rc)
rc = hs_rc;
}
xfer_disable_pad:
/* Disable pad output */
writel(PADCTL_PAD_OUT_EN_MASK, dev->base + PADCTL_OFFSET);
/* Stop internal clock */
bcm_kona_i2c_disable_clock(dev);
clk_disable_unprepare(dev->external_clk);
return rc;
}
static uint32_t bcm_kona_i2c_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
I2C_FUNC_NOSTART;
}
static const struct i2c_algorithm bcm_algo = {
.master_xfer = bcm_kona_i2c_xfer,
.functionality = bcm_kona_i2c_functionality,
};
static int bcm_kona_i2c_assign_bus_speed(struct bcm_kona_i2c_dev *dev)
{
unsigned int bus_speed;
int ret = of_property_read_u32(dev->device->of_node, "clock-frequency",
&bus_speed);
if (ret < 0) {
dev_err(dev->device, "missing clock-frequency property\n");
return -ENODEV;
}
switch (bus_speed) {
case 100000:
dev->std_cfg = &std_cfg_table[BCM_SPD_100K];
break;
case 400000:
dev->std_cfg = &std_cfg_table[BCM_SPD_400K];
break;
case 1000000:
dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ];
break;
case 3400000:
/* Send mastercode at 100k */
dev->std_cfg = &std_cfg_table[BCM_SPD_100K];
dev->hs_cfg = &hs_cfg_table[BCM_SPD_3P4MHZ];
break;
default:
pr_err("%d hz bus speed not supported\n", bus_speed);
pr_err("Valid speeds are 100khz, 400khz, 1mhz, and 3.4mhz\n");
return -EINVAL;
}
return 0;
}
static int bcm_kona_i2c_probe(struct platform_device *pdev)
{
int rc = 0;
struct bcm_kona_i2c_dev *dev;
struct i2c_adapter *adap;
struct resource *iomem;
/* Allocate memory for private data structure */
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
platform_set_drvdata(pdev, dev);
dev->device = &pdev->dev;
init_completion(&dev->done);
/* Map hardware registers */
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(dev->device, iomem);
if (IS_ERR(dev->base))
return -ENOMEM;
/* Get and enable external clock */
dev->external_clk = devm_clk_get(dev->device, NULL);
if (IS_ERR(dev->external_clk)) {
dev_err(dev->device, "couldn't get clock\n");
return -ENODEV;
}
rc = clk_set_rate(dev->external_clk, STD_EXT_CLK_FREQ);
if (rc) {
dev_err(dev->device, "%s: clk_set_rate returned %d\n",
__func__, rc);
return rc;
}
rc = clk_prepare_enable(dev->external_clk);
if (rc) {
dev_err(dev->device, "couldn't enable clock\n");
return rc;
}
/* Parse bus speed */
rc = bcm_kona_i2c_assign_bus_speed(dev);
if (rc)
goto probe_disable_clk;
/* Enable internal clocks */
bcm_kona_i2c_enable_clock(dev);
/* Configure internal dividers */
bcm_kona_i2c_config_timing(dev);
/* Disable timeout */
writel(0, dev->base + TOUT_OFFSET);
/* Enable autosense */
bcm_kona_i2c_enable_autosense(dev);
/* Enable TX FIFO */
writel(TXFCR_FIFO_FLUSH_MASK | TXFCR_FIFO_EN_MASK,
dev->base + TXFCR_OFFSET);
/* Mask all interrupts */
writel(0, dev->base + IER_OFFSET);
/* Clear all pending interrupts */
writel(ISR_CMDBUSY_MASK |
ISR_READ_COMPLETE_MASK |
ISR_SES_DONE_MASK |
ISR_ERR_MASK |
ISR_TXFIFOEMPTY_MASK |
ISR_NOACK_MASK,
dev->base + ISR_OFFSET);
/* Get the interrupt number */
dev->irq = platform_get_irq(pdev, 0);
if (dev->irq < 0) {
dev_err(dev->device, "no irq resource\n");
rc = -ENODEV;
goto probe_disable_clk;
}
/* register the ISR handler */
rc = devm_request_irq(&pdev->dev, dev->irq, bcm_kona_i2c_isr,
IRQF_SHARED, pdev->name, dev);
if (rc) {
dev_err(dev->device, "failed to request irq %i\n", dev->irq);
goto probe_disable_clk;
}
/* Enable the controller but leave it idle */
bcm_kona_i2c_send_cmd_to_ctrl(dev, BCM_CMD_NOACTION);
/* Disable pad output */
writel(PADCTL_PAD_OUT_EN_MASK, dev->base + PADCTL_OFFSET);
/* Disable internal clock */
bcm_kona_i2c_disable_clock(dev);
/* Disable external clock */
clk_disable_unprepare(dev->external_clk);
/* Add the i2c adapter */
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
strlcpy(adap->name, "Broadcom I2C adapter", sizeof(adap->name));
adap->algo = &bcm_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
rc = i2c_add_adapter(adap);
if (rc) {
dev_err(dev->device, "failed to add adapter\n");
return rc;
}
dev_info(dev->device, "device registered successfully\n");
return 0;
probe_disable_clk:
bcm_kona_i2c_disable_clock(dev);
clk_disable_unprepare(dev->external_clk);
return rc;
}
static int bcm_kona_i2c_remove(struct platform_device *pdev)
{
struct bcm_kona_i2c_dev *dev = platform_get_drvdata(pdev);
i2c_del_adapter(&dev->adapter);
return 0;
}
static const struct of_device_id bcm_kona_i2c_of_match[] = {
{.compatible = "brcm,kona-i2c",},
{},
};
MODULE_DEVICE_TABLE(of, kona_i2c_of_match);
static struct platform_driver bcm_kona_i2c_driver = {
.driver = {
.name = "bcm-kona-i2c",
.owner = THIS_MODULE,
.of_match_table = bcm_kona_i2c_of_match,
},
.probe = bcm_kona_i2c_probe,
.remove = bcm_kona_i2c_remove,
};
module_platform_driver(bcm_kona_i2c_driver);
MODULE_AUTHOR("Tim Kryger <tkryger@broadcom.com>");
MODULE_DESCRIPTION("Broadcom Kona I2C Driver");
MODULE_LICENSE("GPL v2");

View File

@ -675,7 +675,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
p_adap->retries = 3;
rc = peripheral_request_list(
(unsigned short *)dev_get_platdata(&pdev->dev),
dev_get_platdata(&pdev->dev),
"i2c-bfin-twi");
if (rc) {
dev_err(&pdev->dev, "Can't setup pin mux!\n");
@ -723,7 +723,7 @@ out_error_add_adapter:
free_irq(iface->irq, iface);
out_error_req_irq:
out_error_no_irq:
peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev));
peripheral_free_list(dev_get_platdata(&pdev->dev));
out_error_pin_mux:
iounmap(iface->regs_base);
out_error_ioremap:
@ -739,7 +739,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
i2c_del_adapter(&(iface->adap));
free_irq(iface->irq, iface);
peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev));
peripheral_free_list(dev_get_platdata(&pdev->dev));
iounmap(iface->regs_base);
kfree(iface);

View File

@ -246,6 +246,7 @@ static int cbus_i2c_probe(struct platform_device *pdev)
adapter->owner = THIS_MODULE;
adapter->class = I2C_CLASS_HWMON;
adapter->dev.parent = &pdev->dev;
adapter->dev.of_node = pdev->dev.of_node;
adapter->nr = pdev->id;
adapter->timeout = HZ;
adapter->algo = &cbus_i2c_algo;
@ -289,6 +290,7 @@ static struct platform_driver cbus_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "i2c-cbus-gpio",
.of_match_table = of_match_ptr(i2c_cbus_dt_ids),
},
};
module_platform_driver(cbus_i2c_driver);

View File

@ -795,7 +795,7 @@ static struct platform_driver davinci_i2c_driver = {
.name = "i2c_davinci",
.owner = THIS_MODULE,
.pm = davinci_i2c_pm_ops,
.of_match_table = of_match_ptr(davinci_i2c_of_match),
.of_match_table = davinci_i2c_of_match,
},
};

View File

@ -103,6 +103,8 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT33C2", 0 },
{ "INT33C3", 0 },
{ "INT3432", 0 },
{ "INT3433", 0 },
{ "80860F41", 0 },
{ }
};

View File

@ -311,24 +311,6 @@ static void pch_i2c_start(struct i2c_algo_pch_data *adap)
pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
}
/**
* pch_i2c_getack() - to confirm ACK/NACK
* @adap: Pointer to struct i2c_algo_pch_data.
*/
static s32 pch_i2c_getack(struct i2c_algo_pch_data *adap)
{
u32 reg_val;
void __iomem *p = adap->pch_base_address;
reg_val = ioread32(p + PCH_I2CSR) & PCH_GETACK;
if (reg_val != 0) {
pch_err(adap, "return%d\n", -EPROTO);
return -EPROTO;
}
return 0;
}
/**
* pch_i2c_stop() - generate stop condition in normal mode.
* @adap: Pointer to struct i2c_algo_pch_data.
@ -344,6 +326,7 @@ static void pch_i2c_stop(struct i2c_algo_pch_data *adap)
static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)
{
long ret;
void __iomem *p = adap->pch_base_address;
ret = wait_event_timeout(pch_event,
(adap->pch_event_flag != 0), msecs_to_jiffies(1000));
@ -366,10 +349,9 @@ static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)
adap->pch_event_flag = 0;
if (pch_i2c_getack(adap)) {
pch_dbg(adap, "Receive NACK for slave address"
"setting\n");
return -EIO;
if (ioread32(p + PCH_I2CSR) & PCH_GETACK) {
pch_dbg(adap, "Receive NACK for slave address setting\n");
return -ENXIO;
}
return 0;

View File

@ -0,0 +1,769 @@
/**
* i2c-exynos5.c - Samsung Exynos5 I2C Controller Driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
/*
* HSI2C controller from Samsung supports 2 modes of operation
* 1. Auto mode: Where in master automatically controls the whole transaction
* 2. Manual mode: Software controls the transaction by issuing commands
* START, READ, WRITE, STOP, RESTART in I2C_MANUAL_CMD register.
*
* Operation mode can be selected by setting AUTO_MODE bit in I2C_CONF register
*
* Special bits are available for both modes of operation to set commands
* and for checking transfer status
*/
/* Register Map */
#define HSI2C_CTL 0x00
#define HSI2C_FIFO_CTL 0x04
#define HSI2C_TRAILIG_CTL 0x08
#define HSI2C_CLK_CTL 0x0C
#define HSI2C_CLK_SLOT 0x10
#define HSI2C_INT_ENABLE 0x20
#define HSI2C_INT_STATUS 0x24
#define HSI2C_ERR_STATUS 0x2C
#define HSI2C_FIFO_STATUS 0x30
#define HSI2C_TX_DATA 0x34
#define HSI2C_RX_DATA 0x38
#define HSI2C_CONF 0x40
#define HSI2C_AUTO_CONF 0x44
#define HSI2C_TIMEOUT 0x48
#define HSI2C_MANUAL_CMD 0x4C
#define HSI2C_TRANS_STATUS 0x50
#define HSI2C_TIMING_HS1 0x54
#define HSI2C_TIMING_HS2 0x58
#define HSI2C_TIMING_HS3 0x5C
#define HSI2C_TIMING_FS1 0x60
#define HSI2C_TIMING_FS2 0x64
#define HSI2C_TIMING_FS3 0x68
#define HSI2C_TIMING_SLA 0x6C
#define HSI2C_ADDR 0x70
/* I2C_CTL Register bits */
#define HSI2C_FUNC_MODE_I2C (1u << 0)
#define HSI2C_MASTER (1u << 3)
#define HSI2C_RXCHON (1u << 6)
#define HSI2C_TXCHON (1u << 7)
#define HSI2C_SW_RST (1u << 31)
/* I2C_FIFO_CTL Register bits */
#define HSI2C_RXFIFO_EN (1u << 0)
#define HSI2C_TXFIFO_EN (1u << 1)
#define HSI2C_RXFIFO_TRIGGER_LEVEL(x) ((x) << 4)
#define HSI2C_TXFIFO_TRIGGER_LEVEL(x) ((x) << 16)
/* As per user manual FIFO max depth is 64bytes */
#define HSI2C_FIFO_MAX 0x40
/* default trigger levels for Tx and Rx FIFOs */
#define HSI2C_DEF_TXFIFO_LVL (HSI2C_FIFO_MAX - 0x30)
#define HSI2C_DEF_RXFIFO_LVL (HSI2C_FIFO_MAX - 0x10)
/* I2C_TRAILING_CTL Register bits */
#define HSI2C_TRAILING_COUNT (0xf)
/* I2C_INT_EN Register bits */
#define HSI2C_INT_TX_ALMOSTEMPTY_EN (1u << 0)
#define HSI2C_INT_RX_ALMOSTFULL_EN (1u << 1)
#define HSI2C_INT_TRAILING_EN (1u << 6)
#define HSI2C_INT_I2C_EN (1u << 9)
/* I2C_INT_STAT Register bits */
#define HSI2C_INT_TX_ALMOSTEMPTY (1u << 0)
#define HSI2C_INT_RX_ALMOSTFULL (1u << 1)
#define HSI2C_INT_TX_UNDERRUN (1u << 2)
#define HSI2C_INT_TX_OVERRUN (1u << 3)
#define HSI2C_INT_RX_UNDERRUN (1u << 4)
#define HSI2C_INT_RX_OVERRUN (1u << 5)
#define HSI2C_INT_TRAILING (1u << 6)
#define HSI2C_INT_I2C (1u << 9)
/* I2C_FIFO_STAT Register bits */
#define HSI2C_RX_FIFO_EMPTY (1u << 24)
#define HSI2C_RX_FIFO_FULL (1u << 23)
#define HSI2C_RX_FIFO_LVL(x) ((x >> 16) & 0x7f)
#define HSI2C_TX_FIFO_EMPTY (1u << 8)
#define HSI2C_TX_FIFO_FULL (1u << 7)
#define HSI2C_TX_FIFO_LVL(x) ((x >> 0) & 0x7f)
/* I2C_CONF Register bits */
#define HSI2C_AUTO_MODE (1u << 31)
#define HSI2C_10BIT_ADDR_MODE (1u << 30)
#define HSI2C_HS_MODE (1u << 29)
/* I2C_AUTO_CONF Register bits */
#define HSI2C_READ_WRITE (1u << 16)
#define HSI2C_STOP_AFTER_TRANS (1u << 17)
#define HSI2C_MASTER_RUN (1u << 31)
/* I2C_TIMEOUT Register bits */
#define HSI2C_TIMEOUT_EN (1u << 31)
#define HSI2C_TIMEOUT_MASK 0xff
/* I2C_TRANS_STATUS register bits */
#define HSI2C_MASTER_BUSY (1u << 17)
#define HSI2C_SLAVE_BUSY (1u << 16)
#define HSI2C_TIMEOUT_AUTO (1u << 4)
#define HSI2C_NO_DEV (1u << 3)
#define HSI2C_NO_DEV_ACK (1u << 2)
#define HSI2C_TRANS_ABORT (1u << 1)
#define HSI2C_TRANS_DONE (1u << 0)
/* I2C_ADDR register bits */
#define HSI2C_SLV_ADDR_SLV(x) ((x & 0x3ff) << 0)
#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10)
#define HSI2C_MASTER_ID(x) ((x & 0xff) << 24)
#define MASTER_ID(x) ((x & 0x7) + 0x08)
/*
* Controller operating frequency, timing values for operation
* are calculated against this frequency
*/
#define HSI2C_HS_TX_CLOCK 1000000
#define HSI2C_FS_TX_CLOCK 100000
#define HSI2C_HIGH_SPD 1
#define HSI2C_FAST_SPD 0
#define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(1000))
struct exynos5_i2c {
struct i2c_adapter adap;
unsigned int suspended:1;
struct i2c_msg *msg;
struct completion msg_complete;
unsigned int msg_ptr;
unsigned int irq;
void __iomem *regs;
struct clk *clk;
struct device *dev;
int state;
spinlock_t lock; /* IRQ synchronization */
/*
* Since the TRANS_DONE bit is cleared on read, and we may read it
* either during an IRQ or after a transaction, keep track of its
* state here.
*/
int trans_done;
/* Controller operating frequency */
unsigned int fs_clock;
unsigned int hs_clock;
/*
* HSI2C Controller can operate in
* 1. High speed upto 3.4Mbps
* 2. Fast speed upto 1Mbps
*/
int speed_mode;
};
static const struct of_device_id exynos5_i2c_match[] = {
{ .compatible = "samsung,exynos5-hsi2c" },
{},
};
MODULE_DEVICE_TABLE(of, exynos5_i2c_match);
static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c *i2c)
{
writel(readl(i2c->regs + HSI2C_INT_STATUS),
i2c->regs + HSI2C_INT_STATUS);
}
/*
* exynos5_i2c_set_timing: updates the registers with appropriate
* timing values calculated
*
* Returns 0 on success, -EINVAL if the cycle length cannot
* be calculated.
*/
static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode)
{
u32 i2c_timing_s1;
u32 i2c_timing_s2;
u32 i2c_timing_s3;
u32 i2c_timing_sla;
unsigned int t_start_su, t_start_hd;
unsigned int t_stop_su;
unsigned int t_data_su, t_data_hd;
unsigned int t_scl_l, t_scl_h;
unsigned int t_sr_release;
unsigned int t_ftl_cycle;
unsigned int clkin = clk_get_rate(i2c->clk);
unsigned int div, utemp0 = 0, utemp1 = 0, clk_cycle;
unsigned int op_clk = (mode == HSI2C_HIGH_SPD) ?
i2c->hs_clock : i2c->fs_clock;
/*
* FPCLK / FI2C =
* (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
* utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
* utemp1 = (TSCLK_L + TSCLK_H + 2)
*/
t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;
/* CLK_DIV max is 256 */
for (div = 0; div < 256; div++) {
utemp1 = utemp0 / (div + 1);
/*
* SCL_L and SCL_H each has max value of 255
* Hence, For the clk_cycle to the have right value
* utemp1 has to be less then 512 and more than 4.
*/
if ((utemp1 < 512) && (utemp1 > 4)) {
clk_cycle = utemp1 - 2;
break;
} else if (div == 255) {
dev_warn(i2c->dev, "Failed to calculate divisor");
return -EINVAL;
}
}
t_scl_l = clk_cycle / 2;
t_scl_h = clk_cycle / 2;
t_start_su = t_scl_l;
t_start_hd = t_scl_l;
t_stop_su = t_scl_l;
t_data_su = t_scl_l / 2;
t_data_hd = t_scl_l / 2;
t_sr_release = clk_cycle;
i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
i2c_timing_s3 = div << 16 | t_sr_release << 0;
i2c_timing_sla = t_data_hd << 0;
dev_dbg(i2c->dev, "tSTART_SU: %X, tSTART_HD: %X, tSTOP_SU: %X\n",
t_start_su, t_start_hd, t_stop_su);
dev_dbg(i2c->dev, "tDATA_SU: %X, tSCL_L: %X, tSCL_H: %X\n",
t_data_su, t_scl_l, t_scl_h);
dev_dbg(i2c->dev, "nClkDiv: %X, tSR_RELEASE: %X\n",
div, t_sr_release);
dev_dbg(i2c->dev, "tDATA_HD: %X\n", t_data_hd);
if (mode == HSI2C_HIGH_SPD) {
writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_HS1);
writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_HS2);
writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_HS3);
} else {
writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_FS1);
writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_FS2);
writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_FS3);
}
writel(i2c_timing_sla, i2c->regs + HSI2C_TIMING_SLA);
return 0;
}
static int exynos5_hsi2c_clock_setup(struct exynos5_i2c *i2c)
{
/*
* Configure the Fast speed timing values
* Even the High Speed mode initially starts with Fast mode
*/
if (exynos5_i2c_set_timing(i2c, HSI2C_FAST_SPD)) {
dev_err(i2c->dev, "HSI2C FS Clock set up failed\n");
return -EINVAL;
}
/* configure the High speed timing values */
if (i2c->speed_mode == HSI2C_HIGH_SPD) {
if (exynos5_i2c_set_timing(i2c, HSI2C_HIGH_SPD)) {
dev_err(i2c->dev, "HSI2C HS Clock set up failed\n");
return -EINVAL;
}
}
return 0;
}
/*
* exynos5_i2c_init: configures the controller for I2C functionality
* Programs I2C controller for Master mode operation
*/
static void exynos5_i2c_init(struct exynos5_i2c *i2c)
{
u32 i2c_conf = readl(i2c->regs + HSI2C_CONF);
u32 i2c_timeout = readl(i2c->regs + HSI2C_TIMEOUT);
/* Clear to disable Timeout */
i2c_timeout &= ~HSI2C_TIMEOUT_EN;
writel(i2c_timeout, i2c->regs + HSI2C_TIMEOUT);
writel((HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
i2c->regs + HSI2C_CTL);
writel(HSI2C_TRAILING_COUNT, i2c->regs + HSI2C_TRAILIG_CTL);
if (i2c->speed_mode == HSI2C_HIGH_SPD) {
writel(HSI2C_MASTER_ID(MASTER_ID(i2c->adap.nr)),
i2c->regs + HSI2C_ADDR);
i2c_conf |= HSI2C_HS_MODE;
}
writel(i2c_conf | HSI2C_AUTO_MODE, i2c->regs + HSI2C_CONF);
}
static void exynos5_i2c_reset(struct exynos5_i2c *i2c)
{
u32 i2c_ctl;
/* Set and clear the bit for reset */
i2c_ctl = readl(i2c->regs + HSI2C_CTL);
i2c_ctl |= HSI2C_SW_RST;
writel(i2c_ctl, i2c->regs + HSI2C_CTL);
i2c_ctl = readl(i2c->regs + HSI2C_CTL);
i2c_ctl &= ~HSI2C_SW_RST;
writel(i2c_ctl, i2c->regs + HSI2C_CTL);
/* We don't expect calculations to fail during the run */
exynos5_hsi2c_clock_setup(i2c);
/* Initialize the configure registers */
exynos5_i2c_init(i2c);
}
/*
* exynos5_i2c_irq: top level IRQ servicing routine
*
* INT_STATUS registers gives the interrupt details. Further,
* FIFO_STATUS or TRANS_STATUS registers are to be check for detailed
* state of the bus.
*/
static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
{
struct exynos5_i2c *i2c = dev_id;
u32 fifo_level, int_status, fifo_status, trans_status;
unsigned char byte;
int len = 0;
i2c->state = -EINVAL;
spin_lock(&i2c->lock);
int_status = readl(i2c->regs + HSI2C_INT_STATUS);
writel(int_status, i2c->regs + HSI2C_INT_STATUS);
fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS);
/* handle interrupt related to the transfer status */
if (int_status & HSI2C_INT_I2C) {
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if (trans_status & HSI2C_NO_DEV_ACK) {
dev_dbg(i2c->dev, "No ACK from device\n");
i2c->state = -ENXIO;
goto stop;
} else if (trans_status & HSI2C_NO_DEV) {
dev_dbg(i2c->dev, "No device\n");
i2c->state = -ENXIO;
goto stop;
} else if (trans_status & HSI2C_TRANS_ABORT) {
dev_dbg(i2c->dev, "Deal with arbitration lose\n");
i2c->state = -EAGAIN;
goto stop;
} else if (trans_status & HSI2C_TIMEOUT_AUTO) {
dev_dbg(i2c->dev, "Accessing device timed out\n");
i2c->state = -EAGAIN;
goto stop;
} else if (trans_status & HSI2C_TRANS_DONE) {
i2c->trans_done = 1;
i2c->state = 0;
}
}
if ((i2c->msg->flags & I2C_M_RD) && (int_status &
(HSI2C_INT_TRAILING | HSI2C_INT_RX_ALMOSTFULL))) {
fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS);
fifo_level = HSI2C_RX_FIFO_LVL(fifo_status);
len = min(fifo_level, i2c->msg->len - i2c->msg_ptr);
while (len > 0) {
byte = (unsigned char)
readl(i2c->regs + HSI2C_RX_DATA);
i2c->msg->buf[i2c->msg_ptr++] = byte;
len--;
}
i2c->state = 0;
} else if (int_status & HSI2C_INT_TX_ALMOSTEMPTY) {
fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS);
fifo_level = HSI2C_TX_FIFO_LVL(fifo_status);
len = HSI2C_FIFO_MAX - fifo_level;
if (len > (i2c->msg->len - i2c->msg_ptr))
len = i2c->msg->len - i2c->msg_ptr;
while (len > 0) {
byte = i2c->msg->buf[i2c->msg_ptr++];
writel(byte, i2c->regs + HSI2C_TX_DATA);
len--;
}
i2c->state = 0;
}
stop:
if ((i2c->trans_done && (i2c->msg->len == i2c->msg_ptr)) ||
(i2c->state < 0)) {
writel(0, i2c->regs + HSI2C_INT_ENABLE);
exynos5_i2c_clr_pend_irq(i2c);
complete(&i2c->msg_complete);
}
spin_unlock(&i2c->lock);
return IRQ_HANDLED;
}
/*
* exynos5_i2c_wait_bus_idle
*
* Wait for the bus to go idle, indicated by the MASTER_BUSY bit being
* cleared.
*
* Returns -EBUSY if the bus cannot be bought to idle
*/
static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c)
{
unsigned long stop_time;
u32 trans_status;
/* wait for 100 milli seconds for the bus to be idle */
stop_time = jiffies + msecs_to_jiffies(100) + 1;
do {
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if (!(trans_status & HSI2C_MASTER_BUSY))
return 0;
usleep_range(50, 200);
} while (time_before(jiffies, stop_time));
return -EBUSY;
}
/*
* exynos5_i2c_message_start: Configures the bus and starts the xfer
* i2c: struct exynos5_i2c pointer for the current bus
* stop: Enables stop after transfer if set. Set for last transfer of
* in the list of messages.
*
* Configures the bus for read/write function
* Sets chip address to talk to, message length to be sent.
* Enables appropriate interrupts and sends start xfer command.
*/
static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
{
u32 i2c_ctl;
u32 int_en = HSI2C_INT_I2C_EN;
u32 i2c_auto_conf = 0;
u32 fifo_ctl;
unsigned long flags;
i2c_ctl = readl(i2c->regs + HSI2C_CTL);
i2c_ctl &= ~(HSI2C_TXCHON | HSI2C_RXCHON);
fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN;
if (i2c->msg->flags & I2C_M_RD) {
i2c_ctl |= HSI2C_RXCHON;
i2c_auto_conf = HSI2C_READ_WRITE;
fifo_ctl |= HSI2C_RXFIFO_TRIGGER_LEVEL(HSI2C_DEF_TXFIFO_LVL);
int_en |= (HSI2C_INT_RX_ALMOSTFULL_EN |
HSI2C_INT_TRAILING_EN);
} else {
i2c_ctl |= HSI2C_TXCHON;
fifo_ctl |= HSI2C_TXFIFO_TRIGGER_LEVEL(HSI2C_DEF_RXFIFO_LVL);
int_en |= HSI2C_INT_TX_ALMOSTEMPTY_EN;
}
writel(HSI2C_SLV_ADDR_MAS(i2c->msg->addr), i2c->regs + HSI2C_ADDR);
writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL);
writel(i2c_ctl, i2c->regs + HSI2C_CTL);
/*
* Enable interrupts before starting the transfer so that we don't
* miss any INT_I2C interrupts.
*/
spin_lock_irqsave(&i2c->lock, flags);
writel(int_en, i2c->regs + HSI2C_INT_ENABLE);
if (stop == 1)
i2c_auto_conf |= HSI2C_STOP_AFTER_TRANS;
i2c_auto_conf |= i2c->msg->len;
i2c_auto_conf |= HSI2C_MASTER_RUN;
writel(i2c_auto_conf, i2c->regs + HSI2C_AUTO_CONF);
spin_unlock_irqrestore(&i2c->lock, flags);
}
static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
struct i2c_msg *msgs, int stop)
{
unsigned long timeout;
int ret;
i2c->msg = msgs;
i2c->msg_ptr = 0;
i2c->trans_done = 0;
reinit_completion(&i2c->msg_complete);
exynos5_i2c_message_start(i2c, stop);
timeout = wait_for_completion_timeout(&i2c->msg_complete,
EXYNOS5_I2C_TIMEOUT);
if (timeout == 0)
ret = -ETIMEDOUT;
else
ret = i2c->state;
/*
* If this is the last message to be transfered (stop == 1)
* Then check if the bus can be brought back to idle.
*/
if (ret == 0 && stop)
ret = exynos5_i2c_wait_bus_idle(i2c);
if (ret < 0) {
exynos5_i2c_reset(i2c);
if (ret == -ETIMEDOUT)
dev_warn(i2c->dev, "%s timeout\n",
(msgs->flags & I2C_M_RD) ? "rx" : "tx");
}
/* Return the state as in interrupt routine */
return ret;
}
static int exynos5_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct exynos5_i2c *i2c = (struct exynos5_i2c *)adap->algo_data;
int i = 0, ret = 0, stop = 0;
if (i2c->suspended) {
dev_err(i2c->dev, "HS-I2C is not initialzed.\n");
return -EIO;
}
clk_prepare_enable(i2c->clk);
for (i = 0; i < num; i++, msgs++) {
stop = (i == num - 1);
ret = exynos5_i2c_xfer_msg(i2c, msgs, stop);
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_unprepare(i2c->clk);
return ret;
}
static u32 exynos5_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}
static const struct i2c_algorithm exynos5_i2c_algorithm = {
.master_xfer = exynos5_i2c_xfer,
.functionality = exynos5_i2c_func,
};
static int exynos5_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct exynos5_i2c *i2c;
struct resource *mem;
unsigned int op_clock;
int ret;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL);
if (!i2c) {
dev_err(&pdev->dev, "no memory for state\n");
return -ENOMEM;
}
if (of_property_read_u32(np, "clock-frequency", &op_clock)) {
i2c->speed_mode = HSI2C_FAST_SPD;
i2c->fs_clock = HSI2C_FS_TX_CLOCK;
} else {
if (op_clock >= HSI2C_HS_TX_CLOCK) {
i2c->speed_mode = HSI2C_HIGH_SPD;
i2c->fs_clock = HSI2C_FS_TX_CLOCK;
i2c->hs_clock = op_clock;
} else {
i2c->speed_mode = HSI2C_FAST_SPD;
i2c->fs_clock = op_clock;
}
}
strlcpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name));
i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &exynos5_i2c_algorithm;
i2c->adap.retries = 3;
i2c->dev = &pdev->dev;
i2c->clk = devm_clk_get(&pdev->dev, "hsi2c");
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
return -ENOENT;
}
clk_prepare_enable(i2c->clk);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(i2c->regs)) {
ret = PTR_ERR(i2c->regs);
goto err_clk;
}
i2c->adap.dev.of_node = np;
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &pdev->dev;
/* Clear pending interrupts from u-boot or misc causes */
exynos5_i2c_clr_pend_irq(i2c);
spin_lock_init(&i2c->lock);
init_completion(&i2c->msg_complete);
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find HS-I2C IRQ\n");
ret = -EINVAL;
goto err_clk;
}
ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
dev_name(&pdev->dev), i2c);
if (ret != 0) {
dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq);
goto err_clk;
}
ret = exynos5_hsi2c_clock_setup(i2c);
if (ret)
goto err_clk;
exynos5_i2c_init(i2c);
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto err_clk;
}
platform_set_drvdata(pdev, i2c);
err_clk:
clk_disable_unprepare(i2c->clk);
return ret;
}
static int exynos5_i2c_remove(struct platform_device *pdev)
{
struct exynos5_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
return 0;
}
static int exynos5_i2c_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct exynos5_i2c *i2c = platform_get_drvdata(pdev);
i2c->suspended = 1;
return 0;
}
static int exynos5_i2c_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct exynos5_i2c *i2c = platform_get_drvdata(pdev);
int ret = 0;
clk_prepare_enable(i2c->clk);
ret = exynos5_hsi2c_clock_setup(i2c);
if (ret) {
clk_disable_unprepare(i2c->clk);
return ret;
}
exynos5_i2c_init(i2c);
clk_disable_unprepare(i2c->clk);
i2c->suspended = 0;
return 0;
}
static SIMPLE_DEV_PM_OPS(exynos5_i2c_dev_pm_ops, exynos5_i2c_suspend_noirq,
exynos5_i2c_resume_noirq);
static struct platform_driver exynos5_i2c_driver = {
.probe = exynos5_i2c_probe,
.remove = exynos5_i2c_remove,
.driver = {
.owner = THIS_MODULE,
.name = "exynos5-hsi2c",
.pm = &exynos5_i2c_dev_pm_ops,
.of_match_table = exynos5_i2c_match,
},
};
module_platform_driver(exynos5_i2c_driver);
MODULE_DESCRIPTION("Exynos5 HS-I2C Bus driver");
MODULE_AUTHOR("Naveen Krishna Chatradhi, <ch.naveen@samsung.com>");
MODULE_AUTHOR("Taekgyun Ko, <taeggyun.ko@samsung.com>");
MODULE_LICENSE("GPL v2");

View File

@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
struct i2c_gpio_private_data {

View File

@ -59,6 +59,7 @@
Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
Coleto Creek (PCH) 0x23b0 32 hard yes yes yes
Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes
Features supported by this driver:
Software PEC no
@ -177,6 +178,7 @@
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2
struct i801_mux_config {
char *gpio_chip;
@ -819,6 +821,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) },
{ 0, }
};

View File

@ -911,7 +911,7 @@ static struct platform_driver mv64xxx_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
.of_match_table = of_match_ptr(mv64xxx_i2c_of_match_table),
.of_match_table = mv64xxx_i2c_of_match_table,
},
};

View File

@ -1,6 +1,7 @@
/*
* Freescale MXS I2C bus driver
*
* Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
* Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K.
*
* based on a (non-working) driver which was:
@ -34,10 +35,12 @@
#define MXS_I2C_CTRL0 (0x00)
#define MXS_I2C_CTRL0_SET (0x04)
#define MXS_I2C_CTRL0_CLR (0x08)
#define MXS_I2C_CTRL0_SFTRST 0x80000000
#define MXS_I2C_CTRL0_RUN 0x20000000
#define MXS_I2C_CTRL0_SEND_NAK_ON_LAST 0x02000000
#define MXS_I2C_CTRL0_PIO_MODE 0x01000000
#define MXS_I2C_CTRL0_RETAIN_CLOCK 0x00200000
#define MXS_I2C_CTRL0_POST_SEND_STOP 0x00100000
#define MXS_I2C_CTRL0_PRE_SEND_START 0x00080000
@ -64,13 +67,13 @@
#define MXS_I2C_CTRL1_SLAVE_IRQ 0x01
#define MXS_I2C_STAT (0x50)
#define MXS_I2C_STAT_GOT_A_NAK 0x10000000
#define MXS_I2C_STAT_BUS_BUSY 0x00000800
#define MXS_I2C_STAT_CLK_GEN_BUSY 0x00000400
#define MXS_I2C_DATA (0xa0)
#define MXS_I2C_DATA(i2c) ((i2c->dev_type == MXS_I2C_V1) ? 0x60 : 0xa0)
#define MXS_I2C_DEBUG0 (0xb0)
#define MXS_I2C_DEBUG0_CLR (0xb8)
#define MXS_I2C_DEBUG0_CLR(i2c) ((i2c->dev_type == MXS_I2C_V1) ? 0x78 : 0xb8)
#define MXS_I2C_DEBUG0_DMAREQ 0x80000000
@ -95,10 +98,17 @@
#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
MXS_I2C_CTRL0_MASTER_MODE)
enum mxs_i2c_devtype {
MXS_I2C_UNKNOWN = 0,
MXS_I2C_V1,
MXS_I2C_V2,
};
/**
* struct mxs_i2c_dev - per device, private MXS-I2C data
*
* @dev: driver model device node
* @dev_type: distinguish i.MX23/i.MX28 features
* @regs: IO registers pointer
* @cmd_complete: completion object for transaction wait
* @cmd_err: error code for last transaction
@ -106,6 +116,7 @@
*/
struct mxs_i2c_dev {
struct device *dev;
enum mxs_i2c_devtype dev_type;
void __iomem *regs;
struct completion cmd_complete;
int cmd_err;
@ -291,48 +302,11 @@ write_init_pio_fail:
return -EINVAL;
}
static int mxs_i2c_pio_wait_dmareq(struct mxs_i2c_dev *i2c)
static int mxs_i2c_pio_wait_xfer_end(struct mxs_i2c_dev *i2c)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
while (!(readl(i2c->regs + MXS_I2C_DEBUG0) &
MXS_I2C_DEBUG0_DMAREQ)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
}
return 0;
}
static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c, int last)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
/*
* We do not use interrupts in the PIO mode. Due to the
* maximum transfer length being 8 bytes in PIO mode, the
* overhead of interrupt would be too large and this would
* neglect the gain from using the PIO mode.
*/
while (!(readl(i2c->regs + MXS_I2C_CTRL1) &
MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
}
writel(MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ,
i2c->regs + MXS_I2C_CTRL1_CLR);
/*
* When ending a transfer with a stop, we have to wait for the bus to
* go idle before we report the transfer as completed. Otherwise the
* start of the next transfer may race with the end of the current one.
*/
while (last && (readl(i2c->regs + MXS_I2C_STAT) &
(MXS_I2C_STAT_BUS_BUSY | MXS_I2C_STAT_CLK_GEN_BUSY))) {
while (readl(i2c->regs + MXS_I2C_CTRL0) & MXS_I2C_CTRL0_RUN) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
@ -370,106 +344,215 @@ static void mxs_i2c_pio_trigger_cmd(struct mxs_i2c_dev *i2c, u32 cmd)
writel(reg, i2c->regs + MXS_I2C_CTRL0);
}
/*
* Start WRITE transaction on the I2C bus. By studying i.MX23 datasheet,
* CTRL0::PIO_MODE bit description clarifies the order in which the registers
* must be written during PIO mode operation. First, the CTRL0 register has
* to be programmed with all the necessary bits but the RUN bit. Then the
* payload has to be written into the DATA register. Finally, the transmission
* is executed by setting the RUN bit in CTRL0.
*/
static void mxs_i2c_pio_trigger_write_cmd(struct mxs_i2c_dev *i2c, u32 cmd,
u32 data)
{
writel(cmd, i2c->regs + MXS_I2C_CTRL0);
if (i2c->dev_type == MXS_I2C_V1)
writel(MXS_I2C_CTRL0_PIO_MODE, i2c->regs + MXS_I2C_CTRL0_SET);
writel(data, i2c->regs + MXS_I2C_DATA(i2c));
writel(MXS_I2C_CTRL0_RUN, i2c->regs + MXS_I2C_CTRL0_SET);
}
static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
struct i2c_msg *msg, uint32_t flags)
{
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
uint32_t addr_data = msg->addr << 1;
uint32_t data = 0;
int i, shifts_left, ret;
int i, ret, xlen = 0, xmit = 0;
uint32_t start;
/* Mute IRQs coming from this block. */
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_CLR);
/*
* MX23 idea:
* - Enable CTRL0::PIO_MODE (1 << 24)
* - Enable CTRL1::ACK_MODE (1 << 27)
*
* WARNING! The MX23 is broken in some way, even if it claims
* to support PIO, when we try to transfer any amount of data
* that is not aligned to 4 bytes, the DMA engine will have
* bits in DEBUG1::DMA_BYTES_ENABLES still set even after the
* transfer. This in turn will mess up the next transfer as
* the block it emit one byte write onto the bus terminated
* with a NAK+STOP. A possible workaround is to reset the IP
* block after every PIO transmission, which might just work.
*
* NOTE: The CTRL0::PIO_MODE description is important, since
* it outlines how the PIO mode is really supposed to work.
*/
if (msg->flags & I2C_M_RD) {
/*
* PIO READ transfer:
*
* This transfer MUST be limited to 4 bytes maximum. It is not
* possible to transfer more than four bytes via PIO, since we
* can not in any way make sure we can read the data from the
* DATA register fast enough. Besides, the RX FIFO is only four
* bytes deep, thus we can only really read up to four bytes at
* time. Finally, there is no bit indicating us that new data
* arrived at the FIFO and can thus be fetched from the DATA
* register.
*/
BUG_ON(msg->len > 4);
addr_data |= I2C_SMBUS_READ;
/* SELECT command. */
mxs_i2c_pio_trigger_cmd(i2c, MXS_CMD_I2C_SELECT);
mxs_i2c_pio_trigger_write_cmd(i2c, MXS_CMD_I2C_SELECT,
addr_data);
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(addr_data, i2c->regs + MXS_I2C_DATA);
writel(MXS_I2C_DEBUG0_DMAREQ, i2c->regs + MXS_I2C_DEBUG0_CLR);
ret = mxs_i2c_pio_wait_cplt(i2c, 0);
if (ret)
return ret;
if (mxs_i2c_pio_check_error_state(i2c))
ret = mxs_i2c_pio_wait_xfer_end(i2c);
if (ret) {
dev_err(i2c->dev,
"PIO: Failed to send SELECT command!\n");
goto cleanup;
}
/* READ command. */
mxs_i2c_pio_trigger_cmd(i2c,
MXS_CMD_I2C_READ | flags |
MXS_I2C_CTRL0_XFER_COUNT(msg->len));
ret = mxs_i2c_pio_wait_xfer_end(i2c);
if (ret) {
dev_err(i2c->dev,
"PIO: Failed to send SELECT command!\n");
goto cleanup;
}
data = readl(i2c->regs + MXS_I2C_DATA(i2c));
for (i = 0; i < msg->len; i++) {
if ((i & 3) == 0) {
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
data = readl(i2c->regs + MXS_I2C_DATA);
writel(MXS_I2C_DEBUG0_DMAREQ,
i2c->regs + MXS_I2C_DEBUG0_CLR);
}
msg->buf[i] = data & 0xff;
data >>= 8;
}
} else {
/*
* PIO WRITE transfer:
*
* The code below implements clock stretching to circumvent
* the possibility of kernel not being able to supply data
* fast enough. It is possible to transfer arbitrary amount
* of data using PIO write.
*/
addr_data |= I2C_SMBUS_WRITE;
/* WRITE command. */
mxs_i2c_pio_trigger_cmd(i2c,
MXS_CMD_I2C_WRITE | flags |
MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1));
/*
* The LSB of data buffer is the first byte blasted across
* the bus. Higher order bytes follow. Thus the following
* filling schematic.
*/
data = addr_data << 24;
/* Start the transfer with START condition. */
start = MXS_I2C_CTRL0_PRE_SEND_START;
/* If the transfer is long, use clock stretching. */
if (msg->len > 3)
start |= MXS_I2C_CTRL0_RETAIN_CLOCK;
for (i = 0; i < msg->len; i++) {
data >>= 8;
data |= (msg->buf[i] << 24);
if ((i & 3) == 2) {
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(data, i2c->regs + MXS_I2C_DATA);
writel(MXS_I2C_DEBUG0_DMAREQ,
i2c->regs + MXS_I2C_DEBUG0_CLR);
}
}
shifts_left = 24 - (i & 3) * 8;
if (shifts_left) {
data >>= shifts_left;
ret = mxs_i2c_pio_wait_dmareq(i2c);
if (ret)
return ret;
writel(data, i2c->regs + MXS_I2C_DATA);
xmit = 0;
/* This is the last transfer of the message. */
if (i + 1 == msg->len) {
/* Add optional STOP flag. */
start |= flags;
/* Remove RETAIN_CLOCK bit. */
start &= ~MXS_I2C_CTRL0_RETAIN_CLOCK;
xmit = 1;
}
/* Four bytes are ready in the "data" variable. */
if ((i & 3) == 2)
xmit = 1;
/* Nothing interesting happened, continue stuffing. */
if (!xmit)
continue;
/*
* Compute the size of the transfer and shift the
* data accordingly.
*
* i = (4k + 0) .... xlen = 2
* i = (4k + 1) .... xlen = 3
* i = (4k + 2) .... xlen = 4
* i = (4k + 3) .... xlen = 1
*/
if ((i % 4) == 3)
xlen = 1;
else
xlen = (i % 4) + 2;
data >>= (4 - xlen) * 8;
dev_dbg(i2c->dev,
"PIO: len=%i pos=%i total=%i [W%s%s%s]\n",
xlen, i, msg->len,
start & MXS_I2C_CTRL0_PRE_SEND_START ? "S" : "",
start & MXS_I2C_CTRL0_POST_SEND_STOP ? "E" : "",
start & MXS_I2C_CTRL0_RETAIN_CLOCK ? "C" : "");
writel(MXS_I2C_DEBUG0_DMAREQ,
i2c->regs + MXS_I2C_DEBUG0_CLR);
i2c->regs + MXS_I2C_DEBUG0_CLR(i2c));
mxs_i2c_pio_trigger_write_cmd(i2c,
start | MXS_I2C_CTRL0_MASTER_MODE |
MXS_I2C_CTRL0_DIRECTION |
MXS_I2C_CTRL0_XFER_COUNT(xlen), data);
/* The START condition is sent only once. */
start &= ~MXS_I2C_CTRL0_PRE_SEND_START;
/* Wait for the end of the transfer. */
ret = mxs_i2c_pio_wait_xfer_end(i2c);
if (ret) {
dev_err(i2c->dev,
"PIO: Failed to finish WRITE cmd!\n");
break;
}
/* Check NAK here. */
ret = readl(i2c->regs + MXS_I2C_STAT) &
MXS_I2C_STAT_GOT_A_NAK;
if (ret) {
ret = -ENXIO;
goto cleanup;
}
}
}
ret = mxs_i2c_pio_wait_cplt(i2c, flags & MXS_I2C_CTRL0_POST_SEND_STOP);
if (ret)
return ret;
/* make sure we capture any occurred error into cmd_err */
mxs_i2c_pio_check_error_state(i2c);
ret = mxs_i2c_pio_check_error_state(i2c);
cleanup:
/* Clear any dangling IRQs and re-enable interrupts. */
writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
return 0;
/* Clear the PIO_MODE on i.MX23 */
if (i2c->dev_type == MXS_I2C_V1)
writel(MXS_I2C_CTRL0_PIO_MODE, i2c->regs + MXS_I2C_CTRL0_CLR);
return ret;
}
/*
@ -479,8 +562,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
int stop)
{
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
int ret, err;
int ret;
int flags;
int use_pio = 0;
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
@ -491,19 +575,21 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
return -EINVAL;
/*
* The current boundary to select between PIO/DMA transfer method
* is set to 8 bytes, transfers shorter than 8 bytes are transfered
* using PIO mode while longer transfers use DMA. The 8 byte border is
* based on this empirical measurement and a lot of previous frobbing.
* The MX28 I2C IP block can only do PIO READ for transfer of to up
* 4 bytes of length. The write transfer is not limited as it can use
* clock stretching to avoid FIFO underruns.
*/
if ((msg->flags & I2C_M_RD) && (msg->len <= 4))
use_pio = 1;
if (!(msg->flags & I2C_M_RD) && (msg->len < 7))
use_pio = 1;
i2c->cmd_err = 0;
if (0) { /* disable PIO mode until a proper fix is made */
if (use_pio) {
ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
if (ret) {
err = mxs_i2c_reset(i2c);
if (err)
return err;
}
/* No need to reset the block if NAK was received. */
if (ret && (ret != -ENXIO))
mxs_i2c_reset(i2c);
} else {
reinit_completion(&i2c->cmd_complete);
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
@ -514,9 +600,11 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
msecs_to_jiffies(1000));
if (ret == 0)
goto timeout;
ret = i2c->cmd_err;
}
if (i2c->cmd_err == -ENXIO) {
if (ret == -ENXIO) {
/*
* If the transfer fails with a NAK from the slave the
* controller halts until it gets told to return to idle state.
@ -525,7 +613,19 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
i2c->regs + MXS_I2C_CTRL1_SET);
}
ret = i2c->cmd_err;
/*
* WARNING!
* The i.MX23 is strange. After each and every operation, it's I2C IP
* block must be reset, otherwise the IP block will misbehave. This can
* be observed on the bus by the block sending out one single byte onto
* the bus. In case such an error happens, bit 27 will be set in the
* DEBUG0 register. This bit is not documented in the i.MX23 datasheet
* and is marked as "TBD" instead. To reset this bit to a correct state,
* reset the whole block. Since the block reset does not take long, do
* reset the block after every transfer to play safe.
*/
if (i2c->dev_type == MXS_I2C_V1)
mxs_i2c_reset(i2c);
dev_dbg(i2c->dev, "Done with err=%d\n", ret);
@ -680,8 +780,28 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
return 0;
}
static struct platform_device_id mxs_i2c_devtype[] = {
{
.name = "imx23-i2c",
.driver_data = MXS_I2C_V1,
}, {
.name = "imx28-i2c",
.driver_data = MXS_I2C_V2,
}, { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mxs_i2c_devtype);
static const struct of_device_id mxs_i2c_dt_ids[] = {
{ .compatible = "fsl,imx23-i2c", .data = &mxs_i2c_devtype[0], },
{ .compatible = "fsl,imx28-i2c", .data = &mxs_i2c_devtype[1], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
static int mxs_i2c_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxs_i2c_dt_ids, &pdev->dev);
struct device *dev = &pdev->dev;
struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap;
@ -693,6 +813,11 @@ static int mxs_i2c_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
if (of_id) {
const struct platform_device_id *device_id = of_id->data;
i2c->dev_type = device_id->driver_data;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
@ -768,12 +893,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id mxs_i2c_dt_ids[] = {
{ .compatible = "fsl,imx28-i2c", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
static struct platform_driver mxs_i2c_driver = {
.driver = {
.name = DRIVER_NAME,
@ -796,6 +915,7 @@ static void __exit mxs_i2c_exit(void)
}
module_exit(mxs_i2c_exit);
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
MODULE_DESCRIPTION("MXS I2C Bus Driver");
MODULE_LICENSE("GPL");

View File

@ -23,6 +23,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/of.h>
#define I2C_PNX_TIMEOUT_DEFAULT 10 /* msec */
#define I2C_PNX_SPEED_KHZ_DEFAULT 100

View File

@ -33,6 +33,7 @@
#include <linux/i2c/i2c-rcar.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
@ -102,8 +103,8 @@ enum {
#define ID_NACK (1 << 4)
enum rcar_i2c_type {
I2C_RCAR_H1,
I2C_RCAR_H2,
I2C_RCAR_GEN1,
I2C_RCAR_GEN2,
};
struct rcar_i2c_priv {
@ -226,22 +227,23 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
u32 bus_speed,
struct device *dev)
{
struct clk *clkp = clk_get(NULL, "peripheral_clk");
struct clk *clkp = clk_get(dev, NULL);
u32 scgd, cdf;
u32 round, ick;
u32 scl;
u32 cdf_width;
unsigned long rate;
if (!clkp) {
dev_err(dev, "there is no peripheral_clk\n");
return -EIO;
if (IS_ERR(clkp)) {
dev_err(dev, "couldn't get clock\n");
return PTR_ERR(clkp);
}
switch (priv->devtype) {
case I2C_RCAR_H1:
case I2C_RCAR_GEN1:
cdf_width = 2;
break;
case I2C_RCAR_H2:
case I2C_RCAR_GEN2:
cdf_width = 3;
break;
default:
@ -264,15 +266,14 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
* clkp : peripheral_clk
* F[] : integer up-valuation
*/
for (cdf = 0; cdf < (1 << cdf_width); cdf++) {
ick = clk_get_rate(clkp) / (1 + cdf);
if (ick < 20000000)
goto ick_find;
rate = clk_get_rate(clkp);
cdf = rate / 20000000;
if (cdf >= 1 << cdf_width) {
dev_err(dev, "Input clock %lu too high\n", rate);
return -EIO;
}
dev_err(dev, "there is no best CDF\n");
return -EIO;
ick = rate / (cdf + 1);
ick_find:
/*
* it is impossible to calculate large scale
* number on u32. separate it
@ -290,6 +291,12 @@ ick_find:
*
* Calculation result (= SCL) should be less than
* bus_speed for hardware safety
*
* We could use something along the lines of
* div = ick / (bus_speed + 1) + 1;
* scgd = (div - 20 - round + 7) / 8;
* scl = ick / (20 + (scgd * 8) + round);
* (not fully verified) but that would get pretty involved
*/
for (scgd = 0; scgd < 0x40; scgd++) {
scl = ick / (20 + (scgd * 8) + round);
@ -306,7 +313,7 @@ scgd_find:
/*
* keep icccr value
*/
priv->icccr = (scgd << (cdf_width) | cdf);
priv->icccr = scgd << cdf_width | cdf;
return 0;
}
@ -632,6 +639,15 @@ static const struct i2c_algorithm rcar_i2c_algo = {
.functionality = rcar_i2c_func,
};
static const struct of_device_id rcar_i2c_dt_ids[] = {
{ .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
{},
};
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
static int rcar_i2c_probe(struct platform_device *pdev)
{
struct i2c_rcar_platform_data *pdata = dev_get_platdata(&pdev->dev);
@ -649,10 +665,15 @@ static int rcar_i2c_probe(struct platform_device *pdev)
}
bus_speed = 100000; /* default 100 kHz */
if (pdata && pdata->bus_speed)
ret = of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed);
if (ret < 0 && pdata && pdata->bus_speed)
bus_speed = pdata->bus_speed;
priv->devtype = platform_get_device_id(pdev)->driver_data;
if (pdev->dev.of_node)
priv->devtype = (long)of_match_device(rcar_i2c_dt_ids,
dev)->data;
else
priv->devtype = platform_get_device_id(pdev)->driver_data;
ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
if (ret < 0)
@ -673,6 +694,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->retries = 3;
adap->dev.parent = dev;
adap->dev.of_node = dev->of_node;
i2c_set_adapdata(adap, priv);
strlcpy(adap->name, pdev->name, sizeof(adap->name));
@ -709,9 +731,9 @@ static int rcar_i2c_remove(struct platform_device *pdev)
}
static struct platform_device_id rcar_i2c_id_table[] = {
{ "i2c-rcar", I2C_RCAR_H1 },
{ "i2c-rcar_h1", I2C_RCAR_H1 },
{ "i2c-rcar_h2", I2C_RCAR_H2 },
{ "i2c-rcar", I2C_RCAR_GEN1 },
{ "i2c-rcar_gen1", I2C_RCAR_GEN1 },
{ "i2c-rcar_gen2", I2C_RCAR_GEN2 },
{},
};
MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table);
@ -720,6 +742,7 @@ static struct platform_driver rcar_i2c_driver = {
.driver = {
.name = "i2c-rcar",
.owner = THIS_MODULE,
.of_match_table = rcar_i2c_dt_ids,
},
.probe = rcar_i2c_probe,
.remove = rcar_i2c_remove,

View File

@ -36,6 +36,7 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>

View File

@ -223,7 +223,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
goto out;
obj = pkg->package.elements + 1;
if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
if (obj->type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, "Invalid argument type"));
result = -EIO;
goto out;
@ -235,7 +235,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
case I2C_SMBUS_WORD_DATA:
if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
if (obj->type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, "Invalid argument type"));
result = -EIO;
goto out;
@ -246,7 +246,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
data->byte = obj->integer.value;
break;
case I2C_SMBUS_BLOCK_DATA:
if (obj == NULL || obj->type != ACPI_TYPE_BUFFER) {
if (obj->type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO, "Invalid argument type"));
result = -EIO;
goto out;

View File

@ -235,7 +235,7 @@ static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
int offset;
/* Get clock rate after clock is enabled */
clk_enable(pd->clk);
clk_prepare_enable(pd->clk);
i2c_clk_khz = clk_get_rate(pd->clk) / 1000;
i2c_clk_khz /= pd->clks_per_count;
@ -270,14 +270,14 @@ static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
pd->icic &= ~ICIC_ICCHB8;
out:
clk_disable(pd->clk);
clk_disable_unprepare(pd->clk);
}
static void activate_ch(struct sh_mobile_i2c_data *pd)
{
/* Wake up device and enable clock */
pm_runtime_get_sync(pd->dev);
clk_enable(pd->clk);
clk_prepare_enable(pd->clk);
/* Enable channel and configure rx ack */
iic_set_clr(pd, ICCR, ICCR_ICE, 0);
@ -300,7 +300,7 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd)
iic_set_clr(pd, ICCR, 0, ICCR_ICE);
/* Disable clock and mark device as idle */
clk_disable(pd->clk);
clk_disable_unprepare(pd->clk);
pm_runtime_put_sync(pd->dev);
}

View File

@ -0,0 +1,872 @@
/*
* Copyright (C) 2013 STMicroelectronics
*
* I2C master mode controller driver, used in STMicroelectronics devices.
*
* Author: Maxime Coquelin <maxime.coquelin@st.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
/* SSC registers */
#define SSC_BRG 0x000
#define SSC_TBUF 0x004
#define SSC_RBUF 0x008
#define SSC_CTL 0x00C
#define SSC_IEN 0x010
#define SSC_STA 0x014
#define SSC_I2C 0x018
#define SSC_SLAD 0x01C
#define SSC_REP_START_HOLD 0x020
#define SSC_START_HOLD 0x024
#define SSC_REP_START_SETUP 0x028
#define SSC_DATA_SETUP 0x02C
#define SSC_STOP_SETUP 0x030
#define SSC_BUS_FREE 0x034
#define SSC_TX_FSTAT 0x038
#define SSC_RX_FSTAT 0x03C
#define SSC_PRE_SCALER_BRG 0x040
#define SSC_CLR 0x080
#define SSC_NOISE_SUPP_WIDTH 0x100
#define SSC_PRSCALER 0x104
#define SSC_NOISE_SUPP_WIDTH_DATAOUT 0x108
#define SSC_PRSCALER_DATAOUT 0x10c
/* SSC Control */
#define SSC_CTL_DATA_WIDTH_9 0x8
#define SSC_CTL_DATA_WIDTH_MSK 0xf
#define SSC_CTL_BM 0xf
#define SSC_CTL_HB BIT(4)
#define SSC_CTL_PH BIT(5)
#define SSC_CTL_PO BIT(6)
#define SSC_CTL_SR BIT(7)
#define SSC_CTL_MS BIT(8)
#define SSC_CTL_EN BIT(9)
#define SSC_CTL_LPB BIT(10)
#define SSC_CTL_EN_TX_FIFO BIT(11)
#define SSC_CTL_EN_RX_FIFO BIT(12)
#define SSC_CTL_EN_CLST_RX BIT(13)
/* SSC Interrupt Enable */
#define SSC_IEN_RIEN BIT(0)
#define SSC_IEN_TIEN BIT(1)
#define SSC_IEN_TEEN BIT(2)
#define SSC_IEN_REEN BIT(3)
#define SSC_IEN_PEEN BIT(4)
#define SSC_IEN_AASEN BIT(6)
#define SSC_IEN_STOPEN BIT(7)
#define SSC_IEN_ARBLEN BIT(8)
#define SSC_IEN_NACKEN BIT(10)
#define SSC_IEN_REPSTRTEN BIT(11)
#define SSC_IEN_TX_FIFO_HALF BIT(12)
#define SSC_IEN_RX_FIFO_HALF_FULL BIT(14)
/* SSC Status */
#define SSC_STA_RIR BIT(0)
#define SSC_STA_TIR BIT(1)
#define SSC_STA_TE BIT(2)
#define SSC_STA_RE BIT(3)
#define SSC_STA_PE BIT(4)
#define SSC_STA_CLST BIT(5)
#define SSC_STA_AAS BIT(6)
#define SSC_STA_STOP BIT(7)
#define SSC_STA_ARBL BIT(8)
#define SSC_STA_BUSY BIT(9)
#define SSC_STA_NACK BIT(10)
#define SSC_STA_REPSTRT BIT(11)
#define SSC_STA_TX_FIFO_HALF BIT(12)
#define SSC_STA_TX_FIFO_FULL BIT(13)
#define SSC_STA_RX_FIFO_HALF BIT(14)
/* SSC I2C Control */
#define SSC_I2C_I2CM BIT(0)
#define SSC_I2C_STRTG BIT(1)
#define SSC_I2C_STOPG BIT(2)
#define SSC_I2C_ACKG BIT(3)
#define SSC_I2C_AD10 BIT(4)
#define SSC_I2C_TXENB BIT(5)
#define SSC_I2C_REPSTRTG BIT(11)
#define SSC_I2C_SLAVE_DISABLE BIT(12)
/* SSC Tx FIFO Status */
#define SSC_TX_FSTAT_STATUS 0x07
/* SSC Rx FIFO Status */
#define SSC_RX_FSTAT_STATUS 0x07
/* SSC Clear bit operation */
#define SSC_CLR_SSCAAS BIT(6)
#define SSC_CLR_SSCSTOP BIT(7)
#define SSC_CLR_SSCARBL BIT(8)
#define SSC_CLR_NACK BIT(10)
#define SSC_CLR_REPSTRT BIT(11)
/* SSC Clock Prescaler */
#define SSC_PRSC_VALUE 0x0f
#define SSC_TXFIFO_SIZE 0x8
#define SSC_RXFIFO_SIZE 0x8
enum st_i2c_mode {
I2C_MODE_STANDARD,
I2C_MODE_FAST,
I2C_MODE_END,
};
/**
* struct st_i2c_timings - per-Mode tuning parameters
* @rate: I2C bus rate
* @rep_start_hold: I2C repeated start hold time requirement
* @rep_start_setup: I2C repeated start set up time requirement
* @start_hold: I2C start hold time requirement
* @data_setup_time: I2C data set up time requirement
* @stop_setup_time: I2C stop set up time requirement
* @bus_free_time: I2C bus free time requirement
* @sda_pulse_min_limit: I2C SDA pulse mini width limit
*/
struct st_i2c_timings {
u32 rate;
u32 rep_start_hold;
u32 rep_start_setup;
u32 start_hold;
u32 data_setup_time;
u32 stop_setup_time;
u32 bus_free_time;
u32 sda_pulse_min_limit;
};
/**
* struct st_i2c_client - client specific data
* @addr: 8-bit slave addr, including r/w bit
* @count: number of bytes to be transfered
* @xfered: number of bytes already transferred
* @buf: data buffer
* @result: result of the transfer
* @stop: last I2C msg to be sent, i.e. STOP to be generated
*/
struct st_i2c_client {
u8 addr;
u32 count;
u32 xfered;
u8 *buf;
int result;
bool stop;
};
/**
* struct st_i2c_dev - private data of the controller
* @adap: I2C adapter for this controller
* @dev: device for this controller
* @base: virtual memory area
* @complete: completion of I2C message
* @irq: interrupt line for th controller
* @clk: hw ssc block clock
* @mode: I2C mode of the controller. Standard or Fast only supported
* @scl_min_width_us: SCL line minimum pulse width in us
* @sda_min_width_us: SDA line minimum pulse width in us
* @client: I2C transfert information
* @busy: I2C transfer on-going
*/
struct st_i2c_dev {
struct i2c_adapter adap;
struct device *dev;
void __iomem *base;
struct completion complete;
int irq;
struct clk *clk;
int mode;
u32 scl_min_width_us;
u32 sda_min_width_us;
struct st_i2c_client client;
bool busy;
};
static inline void st_i2c_set_bits(void __iomem *reg, u32 mask)
{
writel_relaxed(readl_relaxed(reg) | mask, reg);
}
static inline void st_i2c_clr_bits(void __iomem *reg, u32 mask)
{
writel_relaxed(readl_relaxed(reg) & ~mask, reg);
}
/* From I2C Specifications v0.5 */
static struct st_i2c_timings i2c_timings[] = {
[I2C_MODE_STANDARD] = {
.rate = 100000,
.rep_start_hold = 4000,
.rep_start_setup = 4700,
.start_hold = 4000,
.data_setup_time = 250,
.stop_setup_time = 4000,
.bus_free_time = 4700,
},
[I2C_MODE_FAST] = {
.rate = 400000,
.rep_start_hold = 600,
.rep_start_setup = 600,
.start_hold = 600,
.data_setup_time = 100,
.stop_setup_time = 600,
.bus_free_time = 1300,
},
};
static void st_i2c_flush_rx_fifo(struct st_i2c_dev *i2c_dev)
{
int count, i;
/*
* Counter only counts up to 7 but fifo size is 8...
* When fifo is full, counter is 0 and RIR bit of status register is
* set
*/
if (readl_relaxed(i2c_dev->base + SSC_STA) & SSC_STA_RIR)
count = SSC_RXFIFO_SIZE;
else
count = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT) &
SSC_RX_FSTAT_STATUS;
for (i = 0; i < count; i++)
readl_relaxed(i2c_dev->base + SSC_RBUF);
}
static void st_i2c_soft_reset(struct st_i2c_dev *i2c_dev)
{
/*
* FIFO needs to be emptied before reseting the IP,
* else the controller raises a BUSY error.
*/
st_i2c_flush_rx_fifo(i2c_dev);
st_i2c_set_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR);
st_i2c_clr_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR);
}
/**
* st_i2c_hw_config() - Prepare SSC block, calculate and apply tuning timings
* @i2c_dev: Controller's private data
*/
static void st_i2c_hw_config(struct st_i2c_dev *i2c_dev)
{
unsigned long rate;
u32 val, ns_per_clk;
struct st_i2c_timings *t = &i2c_timings[i2c_dev->mode];
st_i2c_soft_reset(i2c_dev);
val = SSC_CLR_REPSTRT | SSC_CLR_NACK | SSC_CLR_SSCARBL |
SSC_CLR_SSCAAS | SSC_CLR_SSCSTOP;
writel_relaxed(val, i2c_dev->base + SSC_CLR);
/* SSC Control register setup */
val = SSC_CTL_PO | SSC_CTL_PH | SSC_CTL_HB | SSC_CTL_DATA_WIDTH_9;
writel_relaxed(val, i2c_dev->base + SSC_CTL);
rate = clk_get_rate(i2c_dev->clk);
ns_per_clk = 1000000000 / rate;
/* Baudrate */
val = rate / (2 * t->rate);
writel_relaxed(val, i2c_dev->base + SSC_BRG);
/* Pre-scaler baudrate */
writel_relaxed(1, i2c_dev->base + SSC_PRE_SCALER_BRG);
/* Enable I2C mode */
writel_relaxed(SSC_I2C_I2CM, i2c_dev->base + SSC_I2C);
/* Repeated start hold time */
val = t->rep_start_hold / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_REP_START_HOLD);
/* Repeated start set up time */
val = t->rep_start_setup / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_REP_START_SETUP);
/* Start hold time */
val = t->start_hold / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_START_HOLD);
/* Data set up time */
val = t->data_setup_time / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_DATA_SETUP);
/* Stop set up time */
val = t->stop_setup_time / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_STOP_SETUP);
/* Bus free time */
val = t->bus_free_time / ns_per_clk;
writel_relaxed(val, i2c_dev->base + SSC_BUS_FREE);
/* Prescalers set up */
val = rate / 10000000;
writel_relaxed(val, i2c_dev->base + SSC_PRSCALER);
writel_relaxed(val, i2c_dev->base + SSC_PRSCALER_DATAOUT);
/* Noise suppression witdh */
val = i2c_dev->scl_min_width_us * rate / 100000000;
writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH);
/* Noise suppression max output data delay width */
val = i2c_dev->sda_min_width_us * rate / 100000000;
writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH_DATAOUT);
}
static int st_i2c_wait_free_bus(struct st_i2c_dev *i2c_dev)
{
u32 sta;
int i;
for (i = 0; i < 10; i++) {
sta = readl_relaxed(i2c_dev->base + SSC_STA);
if (!(sta & SSC_STA_BUSY))
return 0;
usleep_range(2000, 4000);
}
dev_err(i2c_dev->dev, "bus not free (status = 0x%08x)\n", sta);
return -EBUSY;
}
/**
* st_i2c_write_tx_fifo() - Write a byte in the Tx FIFO
* @i2c_dev: Controller's private data
* @byte: Data to write in the Tx FIFO
*/
static inline void st_i2c_write_tx_fifo(struct st_i2c_dev *i2c_dev, u8 byte)
{
u16 tbuf = byte << 1;
writel_relaxed(tbuf | 1, i2c_dev->base + SSC_TBUF);
}
/**
* st_i2c_wr_fill_tx_fifo() - Fill the Tx FIFO in write mode
* @i2c_dev: Controller's private data
*
* This functions fills the Tx FIFO with I2C transfert buffer when
* in write mode.
*/
static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev)
{
struct st_i2c_client *c = &i2c_dev->client;
u32 tx_fstat, sta;
int i;
sta = readl_relaxed(i2c_dev->base + SSC_STA);
if (sta & SSC_STA_TX_FIFO_FULL)
return;
tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT);
tx_fstat &= SSC_TX_FSTAT_STATUS;
if (c->count < (SSC_TXFIFO_SIZE - tx_fstat))
i = c->count;
else
i = SSC_TXFIFO_SIZE - tx_fstat;
for (; i > 0; i--, c->count--, c->buf++)
st_i2c_write_tx_fifo(i2c_dev, *c->buf);
}
/**
* st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode
* @i2c_dev: Controller's private data
*
* This functions fills the Tx FIFO with fixed pattern when
* in read mode to trigger clock.
*/
static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max)
{
struct st_i2c_client *c = &i2c_dev->client;
u32 tx_fstat, sta;
int i;
sta = readl_relaxed(i2c_dev->base + SSC_STA);
if (sta & SSC_STA_TX_FIFO_FULL)
return;
tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT);
tx_fstat &= SSC_TX_FSTAT_STATUS;
if (max < (SSC_TXFIFO_SIZE - tx_fstat))
i = max;
else
i = SSC_TXFIFO_SIZE - tx_fstat;
for (; i > 0; i--, c->xfered++)
st_i2c_write_tx_fifo(i2c_dev, 0xff);
}
static void st_i2c_read_rx_fifo(struct st_i2c_dev *i2c_dev)
{
struct st_i2c_client *c = &i2c_dev->client;
u32 i, sta;
u16 rbuf;
sta = readl_relaxed(i2c_dev->base + SSC_STA);
if (sta & SSC_STA_RIR) {
i = SSC_RXFIFO_SIZE;
} else {
i = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT);
i &= SSC_RX_FSTAT_STATUS;
}
for (; (i > 0) && (c->count > 0); i--, c->count--) {
rbuf = readl_relaxed(i2c_dev->base + SSC_RBUF) >> 1;
*c->buf++ = (u8)rbuf & 0xff;
}
if (i) {
dev_err(i2c_dev->dev, "Unexpected %d bytes in rx fifo\n", i);
st_i2c_flush_rx_fifo(i2c_dev);
}
}
/**
* st_i2c_terminate_xfer() - Send either STOP or REPSTART condition
* @i2c_dev: Controller's private data
*/
static void st_i2c_terminate_xfer(struct st_i2c_dev *i2c_dev)
{
struct st_i2c_client *c = &i2c_dev->client;
st_i2c_clr_bits(i2c_dev->base + SSC_IEN, SSC_IEN_TEEN);
st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);
if (c->stop) {
st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_STOPEN);
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
} else {
st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_REPSTRTEN);
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_REPSTRTG);
}
}
/**
* st_i2c_handle_write() - Handle FIFO empty interrupt in case of write
* @i2c_dev: Controller's private data
*/
static void st_i2c_handle_write(struct st_i2c_dev *i2c_dev)
{
struct st_i2c_client *c = &i2c_dev->client;
st_i2c_flush_rx_fifo(i2c_dev);
if (!c->count)
/* End of xfer, send stop or repstart */
st_i2c_terminate_xfer(i2c_dev);
else
st_i2c_wr_fill_tx_fifo(i2c_dev);
}
/**
* st_i2c_handle_write() - Handle FIFO enmpty interrupt in case of read
* @i2c_dev: Controller's private data
*/
static void st_i2c_handle_read(struct st_i2c_dev *i2c_dev)
{
struct st_i2c_client *c = &i2c_dev->client;
u32 ien;
/* Trash the address read back */
if (!c->xfered) {
readl_relaxed(i2c_dev->base + SSC_RBUF);
st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_TXENB);
} else {
st_i2c_read_rx_fifo(i2c_dev);
}
if (!c->count) {
/* End of xfer, send stop or repstart */
st_i2c_terminate_xfer(i2c_dev);
} else if (c->count == 1) {
/* Penultimate byte to xfer, disable ACK gen. */
st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_ACKG);
/* Last received byte is to be handled by NACK interrupt */
ien = SSC_IEN_NACKEN | SSC_IEN_ARBLEN;
writel_relaxed(ien, i2c_dev->base + SSC_IEN);
st_i2c_rd_fill_tx_fifo(i2c_dev, c->count);
} else {
st_i2c_rd_fill_tx_fifo(i2c_dev, c->count - 1);
}
}
/**
* st_i2c_isr() - Interrupt routine
* @irq: interrupt number
* @data: Controller's private data
*/
static irqreturn_t st_i2c_isr_thread(int irq, void *data)
{
struct st_i2c_dev *i2c_dev = data;
struct st_i2c_client *c = &i2c_dev->client;
u32 sta, ien;
int it;
ien = readl_relaxed(i2c_dev->base + SSC_IEN);
sta = readl_relaxed(i2c_dev->base + SSC_STA);
/* Use __fls() to check error bits first */
it = __fls(sta & ien);
if (it < 0) {
dev_dbg(i2c_dev->dev, "spurious it (sta=0x%04x, ien=0x%04x)\n",
sta, ien);
return IRQ_NONE;
}
switch (1 << it) {
case SSC_STA_TE:
if (c->addr & I2C_M_RD)
st_i2c_handle_read(i2c_dev);
else
st_i2c_handle_write(i2c_dev);
break;
case SSC_STA_STOP:
case SSC_STA_REPSTRT:
writel_relaxed(0, i2c_dev->base + SSC_IEN);
complete(&i2c_dev->complete);
break;
case SSC_STA_NACK:
writel_relaxed(SSC_CLR_NACK, i2c_dev->base + SSC_CLR);
/* Last received byte handled by NACK interrupt */
if ((c->addr & I2C_M_RD) && (c->count == 1) && (c->xfered)) {
st_i2c_handle_read(i2c_dev);
break;
}
it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN;
writel_relaxed(it, i2c_dev->base + SSC_IEN);
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
c->result = -EIO;
break;
case SSC_STA_ARBL:
writel_relaxed(SSC_CLR_SSCARBL, i2c_dev->base + SSC_CLR);
it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN;
writel_relaxed(it, i2c_dev->base + SSC_IEN);
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG);
c->result = -EIO;
break;
default:
dev_err(i2c_dev->dev,
"it %d unhandled (sta=0x%04x)\n", it, sta);
}
/*
* Read IEN register to ensure interrupt mask write is effective
* before re-enabling interrupt at GIC level, and thus avoid spurious
* interrupts.
*/
readl(i2c_dev->base + SSC_IEN);
return IRQ_HANDLED;
}
/**
* st_i2c_xfer_msg() - Transfer a single I2C message
* @i2c_dev: Controller's private data
* @msg: I2C message to transfer
* @is_first: first message of the sequence
* @is_last: last message of the sequence
*/
static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
bool is_first, bool is_last)
{
struct st_i2c_client *c = &i2c_dev->client;
u32 ctl, i2c, it;
unsigned long timeout;
int ret;
c->addr = (u8)(msg->addr << 1);
c->addr |= (msg->flags & I2C_M_RD);
c->buf = msg->buf;
c->count = msg->len;
c->xfered = 0;
c->result = 0;
c->stop = is_last;
reinit_completion(&i2c_dev->complete);
ctl = SSC_CTL_EN | SSC_CTL_MS | SSC_CTL_EN_RX_FIFO | SSC_CTL_EN_TX_FIFO;
st_i2c_set_bits(i2c_dev->base + SSC_CTL, ctl);
i2c = SSC_I2C_TXENB;
if (c->addr & I2C_M_RD)
i2c |= SSC_I2C_ACKG;
st_i2c_set_bits(i2c_dev->base + SSC_I2C, i2c);
/* Write slave address */
st_i2c_write_tx_fifo(i2c_dev, c->addr);
/* Pre-fill Tx fifo with data in case of write */
if (!(c->addr & I2C_M_RD))
st_i2c_wr_fill_tx_fifo(i2c_dev);
it = SSC_IEN_NACKEN | SSC_IEN_TEEN | SSC_IEN_ARBLEN;
writel_relaxed(it, i2c_dev->base + SSC_IEN);
if (is_first) {
ret = st_i2c_wait_free_bus(i2c_dev);
if (ret)
return ret;
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);
}
timeout = wait_for_completion_timeout(&i2c_dev->complete,
i2c_dev->adap.timeout);
ret = c->result;
if (!timeout) {
dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n",
c->addr);
ret = -ETIMEDOUT;
}
i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG;
st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c);
writel_relaxed(SSC_CLR_SSCSTOP | SSC_CLR_REPSTRT,
i2c_dev->base + SSC_CLR);
return ret;
}
/**
* st_i2c_xfer() - Transfer a single I2C message
* @i2c_adap: Adapter pointer to the controller
* @msgs: Pointer to data to be written.
* @num: Number of messages to be executed
*/
static int st_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msgs[], int num)
{
struct st_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
int ret, i;
i2c_dev->busy = true;
ret = clk_prepare_enable(i2c_dev->clk);
if (ret) {
dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n");
return ret;
}
pinctrl_pm_select_default_state(i2c_dev->dev);
st_i2c_hw_config(i2c_dev);
for (i = 0; (i < num) && !ret; i++)
ret = st_i2c_xfer_msg(i2c_dev, &msgs[i], i == 0, i == num - 1);
pinctrl_pm_select_idle_state(i2c_dev->dev);
clk_disable_unprepare(i2c_dev->clk);
i2c_dev->busy = false;
return (ret < 0) ? ret : i;
}
#ifdef CONFIG_PM_SLEEP
static int st_i2c_suspend(struct device *dev)
{
struct platform_device *pdev =
container_of(dev, struct platform_device, dev);
struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
if (i2c_dev->busy)
return -EBUSY;
pinctrl_pm_select_sleep_state(dev);
return 0;
}
static int st_i2c_resume(struct device *dev)
{
pinctrl_pm_select_default_state(dev);
/* Go in idle state if available */
pinctrl_pm_select_idle_state(dev);
return 0;
}
static SIMPLE_DEV_PM_OPS(st_i2c_pm, st_i2c_suspend, st_i2c_resume);
#define ST_I2C_PM (&st_i2c_pm)
#else
#define ST_I2C_PM NULL
#endif
static u32 st_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm st_i2c_algo = {
.master_xfer = st_i2c_xfer,
.functionality = st_i2c_func,
};
static int st_i2c_of_get_deglitch(struct device_node *np,
struct st_i2c_dev *i2c_dev)
{
int ret;
ret = of_property_read_u32(np, "st,i2c-min-scl-pulse-width-us",
&i2c_dev->scl_min_width_us);
if ((ret == -ENODATA) || (ret == -EOVERFLOW)) {
dev_err(i2c_dev->dev, "st,i2c-min-scl-pulse-width-us invalid\n");
return ret;
}
ret = of_property_read_u32(np, "st,i2c-min-sda-pulse-width-us",
&i2c_dev->sda_min_width_us);
if ((ret == -ENODATA) || (ret == -EOVERFLOW)) {
dev_err(i2c_dev->dev, "st,i2c-min-sda-pulse-width-us invalid\n");
return ret;
}
return 0;
}
static int st_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct st_i2c_dev *i2c_dev;
struct resource *res;
u32 clk_rate;
struct i2c_adapter *adap;
int ret;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base);
i2c_dev->irq = irq_of_parse_and_map(np, 0);
if (!i2c_dev->irq) {
dev_err(&pdev->dev, "IRQ missing or invalid\n");
return -EINVAL;
}
i2c_dev->clk = of_clk_get_by_name(np, "ssc");
if (IS_ERR(i2c_dev->clk)) {
dev_err(&pdev->dev, "Unable to request clock\n");
return PTR_ERR(i2c_dev->clk);
}
i2c_dev->mode = I2C_MODE_STANDARD;
ret = of_property_read_u32(np, "clock-frequency", &clk_rate);
if ((!ret) && (clk_rate == 400000))
i2c_dev->mode = I2C_MODE_FAST;
i2c_dev->dev = &pdev->dev;
ret = devm_request_threaded_irq(&pdev->dev, i2c_dev->irq,
NULL, st_i2c_isr_thread,
IRQF_ONESHOT, pdev->name, i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
return ret;
}
pinctrl_pm_select_default_state(i2c_dev->dev);
/* In case idle state available, select it */
pinctrl_pm_select_idle_state(i2c_dev->dev);
ret = st_i2c_of_get_deglitch(np, i2c_dev);
if (ret)
return ret;
adap = &i2c_dev->adap;
i2c_set_adapdata(adap, i2c_dev);
snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%x)", res->start);
adap->owner = THIS_MODULE;
adap->timeout = 2 * HZ;
adap->retries = 0;
adap->algo = &st_i2c_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
init_completion(&i2c_dev->complete);
ret = i2c_add_adapter(adap);
if (ret) {
dev_err(&pdev->dev, "Failed to add adapter\n");
return ret;
}
platform_set_drvdata(pdev, i2c_dev);
dev_info(i2c_dev->dev, "%s initialized\n", adap->name);
return 0;
}
static int st_i2c_remove(struct platform_device *pdev)
{
struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c_dev->adap);
return 0;
}
static struct of_device_id st_i2c_match[] = {
{ .compatible = "st,comms-ssc-i2c", },
{ .compatible = "st,comms-ssc4-i2c", },
{},
};
MODULE_DEVICE_TABLE(of, st_i2c_match);
static struct platform_driver st_i2c_driver = {
.driver = {
.name = "st-i2c",
.owner = THIS_MODULE,
.of_match_table = st_i2c_match,
.pm = ST_I2C_PM,
},
.probe = st_i2c_probe,
.remove = st_i2c_remove,
};
module_platform_driver(st_i2c_driver);
MODULE_AUTHOR("Maxime Coquelin <maxime.coquelin@st.com>");
MODULE_DESCRIPTION("STMicroelectronics I2C driver");
MODULE_LICENSE("GPL v2");

View File

@ -349,6 +349,7 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)
err = clk_set_rate(i2c_dev->clk, 20000000);
if (err) {
dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n");
clk_disable_unprepare(i2c_dev->clk);
return err;
}

View File

@ -40,6 +40,7 @@
#include <linux/i2c-xiic.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of.h>
#define DRIVER_NAME "xiic-i2c"
@ -702,7 +703,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
if (irq < 0)
goto resource_missing;
pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev);
pdata = dev_get_platdata(&pdev->dev);
i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
if (!i2c)

View File

@ -248,7 +248,7 @@ static int i2c_device_probe(struct device *dev)
driver = to_i2c_driver(dev->driver);
if (!driver->probe || !driver->id_table)
return -ENODEV;
client->driver = driver;
if (!device_can_wakeup(&client->dev))
device_init_wakeup(&client->dev,
client->flags & I2C_CLIENT_WAKE);
@ -257,7 +257,6 @@ static int i2c_device_probe(struct device *dev)
acpi_dev_pm_attach(&client->dev, true);
status = driver->probe(client, i2c_match_id(driver->id_table, client));
if (status) {
client->driver = NULL;
i2c_set_clientdata(client, NULL);
acpi_dev_pm_detach(&client->dev, true);
}
@ -281,10 +280,8 @@ static int i2c_device_remove(struct device *dev)
dev->driver = NULL;
status = 0;
}
if (status == 0) {
client->driver = NULL;
if (status == 0)
i2c_set_clientdata(client, NULL);
}
acpi_dev_pm_detach(&client->dev, true);
return status;
}
@ -1614,9 +1611,14 @@ static int i2c_cmd(struct device *dev, void *_arg)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_cmd_arg *arg = _arg;
struct i2c_driver *driver;
if (client && client->driver && client->driver->command)
client->driver->command(client, arg->cmd, arg->arg);
if (!client || !client->dev.driver)
return 0;
driver = to_i2c_driver(client->dev.driver);
if (driver->command)
driver->command(client, arg->cmd, arg->arg);
return 0;
}

View File

@ -102,8 +102,8 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
kfree(i2c_dev);
}
static ssize_t show_adapter_name(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt));
@ -111,7 +111,13 @@ static ssize_t show_adapter_name(struct device *dev,
return -ENODEV;
return sprintf(buf, "%s\n", i2c_dev->adap->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
static DEVICE_ATTR_RO(name);
static struct attribute *i2c_attrs[] = {
&dev_attr_name.attr,
NULL,
};
ATTRIBUTE_GROUPS(i2c);
/* ------------------------------------------------------------------------- */
@ -562,15 +568,10 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy)
res = PTR_ERR(i2c_dev->dev);
goto error;
}
res = device_create_file(i2c_dev->dev, &dev_attr_name);
if (res)
goto error_destroy;
pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
adap->name, adap->nr);
return 0;
error_destroy:
device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
error:
return_i2c_dev(i2c_dev);
return res;
@ -589,7 +590,6 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)
if (!i2c_dev) /* attach_adapter must have failed */
return 0;
device_remove_file(i2c_dev->dev, &dev_attr_name);
return_i2c_dev(i2c_dev);
device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
@ -637,6 +637,7 @@ static int __init i2c_dev_init(void)
res = PTR_ERR(i2c_dev_class);
goto out_unreg_chrdev;
}
i2c_dev_class->dev_groups = i2c_groups;
/* Keep track of adapters which will be added or removed later */
res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);

View File

@ -46,6 +46,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
{
struct i2c_client *client = i2c_verify_client(dev);
struct alert_data *data = addrp;
struct i2c_driver *driver;
if (!client || client->addr != data->addr)
return 0;
@ -54,12 +55,13 @@ static int smbus_do_alert(struct device *dev, void *addrp)
/*
* Drivers should either disable alerts, or provide at least
* a minimal handler. Lock so client->driver won't change.
* a minimal handler. Lock so the driver won't change.
*/
device_lock(dev);
if (client->driver) {
if (client->driver->alert)
client->driver->alert(client, data->flag);
if (client->dev.driver) {
driver = to_i2c_driver(client->dev.driver);
if (driver->alert)
driver->alert(client, data->flag);
else
dev_warn(&client->dev, "no driver alert()!\n");
} else

View File

@ -238,7 +238,7 @@ static struct platform_driver i2c_arbitrator_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "i2c-arb-gpio-challenge",
.of_match_table = of_match_ptr(i2c_arbitrator_of_match),
.of_match_table = i2c_arbitrator_of_match,
},
};

View File

@ -30,15 +30,15 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
int i;
for (i = 0; i < mux->data.n_gpios; i++)
gpio_set_value(mux->gpio_base + mux->data.gpios[i],
val & (1 << i));
gpio_set_value_cansleep(mux->gpio_base + mux->data.gpios[i],
val & (1 << i));
}
static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
{
struct gpiomux *mux = data;
i2c_mux_gpio_set(mux, mux->data.values[chan]);
i2c_mux_gpio_set(mux, chan);
return 0;
}
@ -228,7 +228,7 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;
mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
i, class,
mux->data.values[i], class,
i2c_mux_gpio_select, deselect);
if (!mux->adap[i]) {
ret = -ENODEV;
@ -283,7 +283,7 @@ static struct platform_driver i2c_mux_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "i2c-mux-gpio",
.of_match_table = of_match_ptr(i2c_mux_gpio_of_match),
.of_match_table = i2c_mux_gpio_of_match,
},
};

View File

@ -24,6 +24,7 @@
#include <linux/i2c-mux-pinctrl.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
struct i2c_mux_pinctrl {
struct device *dev;

View File

@ -1581,7 +1581,7 @@ static int s5c73m3_probe(struct i2c_client *client,
oif_sd = &state->oif_sd;
v4l2_subdev_init(sd, &s5c73m3_subdev_ops);
sd->owner = client->driver->driver.owner;
sd->owner = client->dev.driver->owner;
v4l2_set_subdevdata(sd, state);
strlcpy(sd->name, "S5C73M3", sizeof(sd->name));

View File

@ -411,8 +411,8 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd,
device_lock(&client->dev);
if (!client->driver ||
!try_module_get(client->driver->driver.owner)) {
if (!client->dev.driver ||
!try_module_get(client->dev.driver->owner)) {
ret = -EPROBE_DEFER;
v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n",
node->full_name);
@ -442,7 +442,7 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd,
fmd->num_sensors++;
mod_put:
module_put(client->driver->driver.owner);
module_put(client->dev.driver->owner);
dev_put:
device_unlock(&client->dev);
put_device(&client->dev);

View File

@ -43,7 +43,7 @@
#define UNSET (-1U)
#define PREFIX (t->i2c->driver->driver.name)
#define PREFIX (t->i2c->dev.driver->name)
/*
* Driver modprobe parameters
@ -452,7 +452,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
}
tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
c->adapter->name, c->driver->driver.name, c->addr << 1, type,
c->adapter->name, c->dev.driver->name, c->addr << 1, type,
t->mode_mask);
return;
@ -556,7 +556,7 @@ static void tuner_lookup(struct i2c_adapter *adap,
int mode_mask;
if (pos->i2c->adapter != adap ||
strcmp(pos->i2c->driver->driver.name, "tuner"))
strcmp(pos->i2c->dev.driver->name, "tuner"))
continue;
mode_mask = pos->mode_mask;

View File

@ -236,14 +236,14 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
v4l2_subdev_init(sd, ops);
sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
/* the owner is the same as the i2c_client's driver owner */
sd->owner = client->driver->driver.owner;
sd->owner = client->dev.driver->owner;
sd->dev = &client->dev;
/* i2c_client and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, client);
i2c_set_clientdata(client, sd);
/* initialize name */
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
client->driver->driver.name, i2c_adapter_id(client->adapter),
client->dev.driver->name, i2c_adapter_id(client->adapter),
client->addr);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
@ -274,11 +274,11 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
loaded. This delay-load mechanism doesn't work if other drivers
want to use the i2c device, so explicitly loading the module
is the best alternative. */
if (client == NULL || client->driver == NULL)
if (client == NULL || client->dev.driver == NULL)
goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */
if (!try_module_get(client->driver->driver.owner))
if (!try_module_get(client->dev.driver->owner))
goto error;
sd = i2c_get_clientdata(client);
@ -287,7 +287,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
if (v4l2_device_register_subdev(v4l2_dev, sd))
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
module_put(client->dev.driver->owner);
error:
/* If we have a client but no subdev, then something went wrong and

View File

@ -22,7 +22,7 @@
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
#include <linux/platform_data/at24.h>
/*
* I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.

View File

@ -205,7 +205,6 @@ struct i2c_driver {
* @name: Indicates the type of the device, usually a chip name that's
* generic enough to hide second-sourcing and compatible revisions.
* @adapter: manages the bus segment hosting this I2C device
* @driver: device's driver, hence pointer to access routines
* @dev: Driver model device node for the slave.
* @irq: indicates the IRQ generated by this device (if any)
* @detected: member of an i2c_driver.clients list or i2c-core's
@ -222,7 +221,6 @@ struct i2c_client {
/* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head detected;

View File

@ -28,7 +28,7 @@
*
* void get_mac_addr(struct memory_accessor *mem_acc, void *context)
* {
* u8 *mac_addr = ethernet_pdata->mac_addr;
* u8 *mac_addr = ethernet_pdata->mac_addr;
* off_t offset = context;
*
* // Read MAC addr from EEPROM

View File

@ -35,7 +35,7 @@
printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
#define v4l_client_printk(level, client, fmt, arg...) \
v4l_printk(level, (client)->driver->driver.name, (client)->adapter, \
v4l_printk(level, (client)->dev.driver->name, (client)->adapter, \
(client)->addr, fmt , ## arg)
#define v4l_err(client, fmt, arg...) \

View File

@ -65,7 +65,7 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
* already bound. If not it means binding failed, and then there
* is no point in keeping the device instantiated.
*/
if (!keywest_ctx->client->driver) {
if (!keywest_ctx->client->dev.driver) {
i2c_unregister_device(keywest_ctx->client);
keywest_ctx->client = NULL;
return -ENODEV;
@ -76,7 +76,7 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
* This is safe because i2c-core holds the core_lock mutex for us.
*/
list_add_tail(&keywest_ctx->client->detected,
&keywest_ctx->client->driver->clients);
&to_i2c_driver(keywest_ctx->client->dev.driver)->clients);
return 0;
}

View File

@ -215,7 +215,7 @@ static int imx_wm8962_probe(struct platform_device *pdev)
goto fail;
}
codec_dev = of_find_i2c_device_by_node(codec_np);
if (!codec_dev || !codec_dev->driver) {
if (!codec_dev || !codec_dev->dev.driver) {
dev_err(&pdev->dev, "failed to find codec platform device\n");
ret = -EINVAL;
goto fail;