diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-15 20:49:46 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-15 20:49:46 -0400 |
| commit | bbe05e543bfeab1c37127f38b7e575db916fbc6c (patch) | |
| tree | 30c8f1dc6465e6a5b31f51f4468cd7e7114dcde3 | |
| parent | 9db59599ae502b38b27cff6462273f84acd59927 (diff) | |
| parent | aeb068c57214858b638d5ee627bb4a831f98771e (diff) | |
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull more i2c updates from Wolfram Sang:
"I2C has two more new drivers: Altera FPGA and STM32F7"
* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
i2c: i2c-stm32f7: add driver
i2c: i2c-stm32f4: use generic definition of speed enum
dt-bindings: i2c-stm32: Document the STM32F7 I2C bindings
i2c: altera: Add Altera I2C Controller driver
dt-bindings: i2c: Add Altera I2C Controller
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-altera.txt | 39 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-stm32.txt | 29 | ||||
| -rw-r--r-- | MAINTAINERS | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 20 | ||||
| -rw-r--r-- | drivers/i2c/busses/Makefile | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-altera.c | 511 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32.h | 20 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f4.c | 18 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f7.c | 972 |
9 files changed, 1602 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-altera.txt b/Documentation/devicetree/bindings/i2c/i2c-altera.txt new file mode 100644 index 000000000000..767664f448ec --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-altera.txt | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | * Altera I2C Controller | ||
| 2 | * This is Altera's synthesizable logic block I2C Controller for use | ||
| 3 | * in Altera's FPGAs. | ||
| 4 | |||
| 5 | Required properties : | ||
| 6 | - compatible : should be "altr,softip-i2c-v1.0" | ||
| 7 | - reg : Offset and length of the register set for the device | ||
| 8 | - interrupts : <IRQ> where IRQ is the interrupt number. | ||
| 9 | - clocks : phandle to input clock. | ||
| 10 | - #address-cells = <1>; | ||
| 11 | - #size-cells = <0>; | ||
| 12 | |||
| 13 | Recommended properties : | ||
| 14 | - clock-frequency : desired I2C bus clock frequency in Hz. | ||
| 15 | |||
| 16 | Optional properties : | ||
| 17 | - fifo-size : Size of the RX and TX FIFOs in bytes. | ||
| 18 | - Child nodes conforming to i2c bus binding | ||
| 19 | |||
| 20 | Example : | ||
| 21 | |||
| 22 | i2c@100080000 { | ||
| 23 | compatible = "altr,softip-i2c-v1.0"; | ||
| 24 | reg = <0x00000001 0x00080000 0x00000040>; | ||
| 25 | interrupt-parent = <&intc>; | ||
| 26 | interrupts = <0 43 4>; | ||
| 27 | clocks = <&clk_0>; | ||
| 28 | clock-frequency = <100000>; | ||
| 29 | #address-cells = <1>; | ||
| 30 | #size-cells = <0>; | ||
| 31 | fifo-size = <4>; | ||
| 32 | |||
| 33 | eeprom@51 { | ||
| 34 | compatible = "atmel,24c32"; | ||
| 35 | reg = <0x51>; | ||
| 36 | pagesize = <32>; | ||
| 37 | }; | ||
| 38 | }; | ||
| 39 | |||
diff --git a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt index 78eaf7b718ed..3b5489966634 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | * I2C controller embedded in STMicroelectronics STM32 I2C platform | 1 | * I2C controller embedded in STMicroelectronics STM32 I2C platform |
| 2 | 2 | ||
| 3 | Required properties : | 3 | Required properties : |
| 4 | - compatible : Must be "st,stm32f4-i2c" | 4 | - compatible : Must be one of the following |
| 5 | - "st,stm32f4-i2c" | ||
| 6 | - "st,stm32f7-i2c" | ||
| 5 | - reg : Offset and length of the register set for the device | 7 | - reg : Offset and length of the register set for the device |
| 6 | - interrupts : Must contain the interrupt id for I2C event and then the | 8 | - interrupts : Must contain the interrupt id for I2C event and then the |
| 7 | interrupt id for I2C error. | 9 | interrupt id for I2C error. |
| @@ -14,8 +16,16 @@ Required properties : | |||
| 14 | 16 | ||
| 15 | Optional properties : | 17 | Optional properties : |
| 16 | - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, | 18 | - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, |
| 17 | the default 100 kHz frequency will be used. As only Normal and Fast modes | 19 | the default 100 kHz frequency will be used. |
| 18 | are supported, possible values are 100000 and 400000. | 20 | For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are |
| 21 | 100000 and 400000. | ||
| 22 | For STM32F7 SoC, Standard-mode, Fast-mode and Fast-mode Plus are supported, | ||
| 23 | possible values are 100000, 400000 and 1000000. | ||
| 24 | - i2c-scl-rising-time-ns : Only for STM32F7, I2C SCL Rising time for the board | ||
| 25 | (default: 25) | ||
| 26 | - i2c-scl-falling-time-ns : Only for STM32F7, I2C SCL Falling time for the board | ||
| 27 | (default: 10) | ||
| 28 | I2C Timings are derived from these 2 values | ||
| 19 | 29 | ||
| 20 | Example : | 30 | Example : |
| 21 | 31 | ||
| @@ -31,3 +41,16 @@ Example : | |||
| 31 | pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; | 41 | pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; |
| 32 | pinctrl-names = "default"; | 42 | pinctrl-names = "default"; |
| 33 | }; | 43 | }; |
| 44 | |||
| 45 | i2c@40005400 { | ||
| 46 | compatible = "st,stm32f7-i2c"; | ||
| 47 | #address-cells = <1>; | ||
| 48 | #size-cells = <0>; | ||
| 49 | reg = <0x40005400 0x400>; | ||
| 50 | interrupts = <31>, | ||
| 51 | <32>; | ||
| 52 | resets = <&rcc STM32F7_APB1_RESET(I2C1)>; | ||
| 53 | clocks = <&rcc 1 CLK_I2C1>; | ||
| 54 | pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; | ||
| 55 | pinctrl-names = "default"; | ||
| 56 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 209306019483..4b914dd27bae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -644,6 +644,11 @@ ALPS PS/2 TOUCHPAD DRIVER | |||
| 644 | R: Pali Rohár <pali.rohar@gmail.com> | 644 | R: Pali Rohár <pali.rohar@gmail.com> |
| 645 | F: drivers/input/mouse/alps.* | 645 | F: drivers/input/mouse/alps.* |
| 646 | 646 | ||
| 647 | ALTERA I2C CONTROLLER DRIVER | ||
| 648 | M: Thor Thayer <thor.thayer@linux.intel.com> | ||
| 649 | S: Maintained | ||
| 650 | F: drivers/i2c/busses/i2c-altera.c | ||
| 651 | |||
| 647 | ALTERA MAILBOX DRIVER | 652 | ALTERA MAILBOX DRIVER |
| 648 | M: Ley Foon Tan <lftan@altera.com> | 653 | M: Ley Foon Tan <lftan@altera.com> |
| 649 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) | 654 | L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index edc0cfb6fc1a..c06dce2c1da7 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -336,6 +336,16 @@ config I2C_POWERMAC | |||
| 336 | 336 | ||
| 337 | comment "I2C system bus drivers (mostly embedded / system-on-chip)" | 337 | comment "I2C system bus drivers (mostly embedded / system-on-chip)" |
| 338 | 338 | ||
| 339 | config I2C_ALTERA | ||
| 340 | tristate "Altera Soft IP I2C" | ||
| 341 | depends on (ARCH_SOCFPGA || NIOS2) && OF | ||
| 342 | help | ||
| 343 | If you say yes to this option, support will be included for the | ||
| 344 | Altera Soft IP I2C interfaces on SoCFPGA and Nios2 architectures. | ||
| 345 | |||
| 346 | This driver can also be built as a module. If so, the module | ||
| 347 | will be called i2c-altera. | ||
| 348 | |||
| 339 | config I2C_ASPEED | 349 | config I2C_ASPEED |
| 340 | tristate "Aspeed I2C Controller" | 350 | tristate "Aspeed I2C Controller" |
| 341 | depends on ARCH_ASPEED || COMPILE_TEST | 351 | depends on ARCH_ASPEED || COMPILE_TEST |
| @@ -935,6 +945,16 @@ config I2C_STM32F4 | |||
| 935 | This driver can also be built as module. If so, the module | 945 | This driver can also be built as module. If so, the module |
| 936 | will be called i2c-stm32f4. | 946 | will be called i2c-stm32f4. |
| 937 | 947 | ||
| 948 | config I2C_STM32F7 | ||
| 949 | tristate "STMicroelectronics STM32F7 I2C support" | ||
| 950 | depends on ARCH_STM32 || COMPILE_TEST | ||
| 951 | help | ||
| 952 | Enable this option to add support for STM32 I2C controller embedded | ||
| 953 | in STM32F7 SoCs. | ||
| 954 | |||
| 955 | This driver can also be built as module. If so, the module | ||
| 956 | will be called i2c-stm32f7. | ||
| 957 | |||
| 938 | config I2C_STU300 | 958 | config I2C_STU300 |
| 939 | tristate "ST Microelectronics DDC I2C interface" | 959 | tristate "ST Microelectronics DDC I2C interface" |
| 940 | depends on MACH_U300 | 960 | depends on MACH_U300 |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 562daf738048..47f3ac9a695a 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
| @@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o | |||
| 30 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o | 30 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o |
| 31 | 31 | ||
| 32 | # Embedded system I2C/SMBus host controller drivers | 32 | # Embedded system I2C/SMBus host controller drivers |
| 33 | obj-$(CONFIG_I2C_ALTERA) += i2c-altera.o | ||
| 33 | obj-$(CONFIG_I2C_ASPEED) += i2c-aspeed.o | 34 | obj-$(CONFIG_I2C_ASPEED) += i2c-aspeed.o |
| 34 | obj-$(CONFIG_I2C_AT91) += i2c-at91.o | 35 | obj-$(CONFIG_I2C_AT91) += i2c-at91.o |
| 35 | obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | 36 | obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o |
| @@ -93,6 +94,7 @@ obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o | |||
| 93 | obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o | 94 | obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o |
| 94 | obj-$(CONFIG_I2C_ST) += i2c-st.o | 95 | obj-$(CONFIG_I2C_ST) += i2c-st.o |
| 95 | obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o | 96 | obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o |
| 97 | obj-$(CONFIG_I2C_STM32F7) += i2c-stm32f7.o | ||
| 96 | obj-$(CONFIG_I2C_STU300) += i2c-stu300.o | 98 | obj-$(CONFIG_I2C_STU300) += i2c-stu300.o |
| 97 | obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o | 99 | obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o |
| 98 | obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o | 100 | obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o |
diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c new file mode 100644 index 000000000000..f5e1941e65b5 --- /dev/null +++ b/drivers/i2c/busses/i2c-altera.c | |||
| @@ -0,0 +1,511 @@ | |||
| 1 | /* | ||
| 2 | * Copyright Intel Corporation (C) 2017. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | * | ||
| 16 | * Based on the i2c-axxia.c driver. | ||
| 17 | */ | ||
| 18 | #include <linux/clk.h> | ||
| 19 | #include <linux/clkdev.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/iopoll.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | |||
| 29 | #define ALTR_I2C_TFR_CMD 0x00 /* Transfer Command register */ | ||
| 30 | #define ALTR_I2C_TFR_CMD_STA BIT(9) /* send START before byte */ | ||
| 31 | #define ALTR_I2C_TFR_CMD_STO BIT(8) /* send STOP after byte */ | ||
| 32 | #define ALTR_I2C_TFR_CMD_RW_D BIT(0) /* Direction of transfer */ | ||
| 33 | #define ALTR_I2C_RX_DATA 0x04 /* RX data FIFO register */ | ||
| 34 | #define ALTR_I2C_CTRL 0x08 /* Control register */ | ||
| 35 | #define ALTR_I2C_CTRL_RXT_SHFT 4 /* RX FIFO Threshold */ | ||
| 36 | #define ALTR_I2C_CTRL_TCT_SHFT 2 /* TFER CMD FIFO Threshold */ | ||
| 37 | #define ALTR_I2C_CTRL_BSPEED BIT(1) /* Bus Speed (1=Fast) */ | ||
| 38 | #define ALTR_I2C_CTRL_EN BIT(0) /* Enable Core (1=Enable) */ | ||
| 39 | #define ALTR_I2C_ISER 0x0C /* Interrupt Status Enable register */ | ||
| 40 | #define ALTR_I2C_ISER_RXOF_EN BIT(4) /* Enable RX OVERFLOW IRQ */ | ||
| 41 | #define ALTR_I2C_ISER_ARB_EN BIT(3) /* Enable ARB LOST IRQ */ | ||
| 42 | #define ALTR_I2C_ISER_NACK_EN BIT(2) /* Enable NACK DET IRQ */ | ||
| 43 | #define ALTR_I2C_ISER_RXRDY_EN BIT(1) /* Enable RX Ready IRQ */ | ||
| 44 | #define ALTR_I2C_ISER_TXRDY_EN BIT(0) /* Enable TX Ready IRQ */ | ||
| 45 | #define ALTR_I2C_ISR 0x10 /* Interrupt Status register */ | ||
| 46 | #define ALTR_I2C_ISR_RXOF BIT(4) /* RX OVERFLOW IRQ */ | ||
| 47 | #define ALTR_I2C_ISR_ARB BIT(3) /* ARB LOST IRQ */ | ||
| 48 | #define ALTR_I2C_ISR_NACK BIT(2) /* NACK DET IRQ */ | ||
| 49 | #define ALTR_I2C_ISR_RXRDY BIT(1) /* RX Ready IRQ */ | ||
| 50 | #define ALTR_I2C_ISR_TXRDY BIT(0) /* TX Ready IRQ */ | ||
| 51 | #define ALTR_I2C_STATUS 0x14 /* Status register */ | ||
| 52 | #define ALTR_I2C_STAT_CORE BIT(0) /* Core Status (0=idle) */ | ||
| 53 | #define ALTR_I2C_TC_FIFO_LVL 0x18 /* Transfer FIFO LVL register */ | ||
| 54 | #define ALTR_I2C_RX_FIFO_LVL 0x1C /* Receive FIFO LVL register */ | ||
| 55 | #define ALTR_I2C_SCL_LOW 0x20 /* SCL low count register */ | ||
| 56 | #define ALTR_I2C_SCL_HIGH 0x24 /* SCL high count register */ | ||
| 57 | #define ALTR_I2C_SDA_HOLD 0x28 /* SDA hold count register */ | ||
| 58 | |||
| 59 | #define ALTR_I2C_ALL_IRQ (ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | \ | ||
| 60 | ALTR_I2C_ISR_NACK | ALTR_I2C_ISR_RXRDY | \ | ||
| 61 | ALTR_I2C_ISR_TXRDY) | ||
| 62 | |||
| 63 | #define ALTR_I2C_THRESHOLD 0 /* IRQ Threshold at 1 element */ | ||
| 64 | #define ALTR_I2C_DFLT_FIFO_SZ 4 | ||
| 65 | #define ALTR_I2C_TIMEOUT 100000 /* 100ms */ | ||
| 66 | #define ALTR_I2C_XFER_TIMEOUT (msecs_to_jiffies(250)) | ||
| 67 | |||
| 68 | /** | ||
| 69 | * altr_i2c_dev - I2C device context | ||
| 70 | * @base: pointer to register struct | ||
| 71 | * @msg: pointer to current message | ||
| 72 | * @msg_len: number of bytes transferred in msg | ||
| 73 | * @msg_err: error code for completed message | ||
| 74 | * @msg_complete: xfer completion object | ||
| 75 | * @dev: device reference | ||
| 76 | * @adapter: core i2c abstraction | ||
| 77 | * @i2c_clk: clock reference for i2c input clock | ||
| 78 | * @bus_clk_rate: current i2c bus clock rate | ||
| 79 | * @buf: ptr to msg buffer for easier use. | ||
| 80 | * @fifo_size: size of the FIFO passed in. | ||
| 81 | * @isr_mask: cached copy of local ISR enables. | ||
| 82 | * @isr_status: cached copy of local ISR status. | ||
| 83 | * @lock: spinlock for IRQ synchronization. | ||
| 84 | */ | ||
| 85 | struct altr_i2c_dev { | ||
| 86 | void __iomem *base; | ||
| 87 | struct i2c_msg *msg; | ||
| 88 | size_t msg_len; | ||
| 89 | int msg_err; | ||
| 90 | struct completion msg_complete; | ||
| 91 | struct device *dev; | ||
| 92 | struct i2c_adapter adapter; | ||
| 93 | struct clk *i2c_clk; | ||
| 94 | u32 bus_clk_rate; | ||
| 95 | u8 *buf; | ||
| 96 | u32 fifo_size; | ||
| 97 | u32 isr_mask; | ||
| 98 | u32 isr_status; | ||
| 99 | spinlock_t lock; /* IRQ synchronization */ | ||
| 100 | }; | ||
| 101 | |||
| 102 | static void | ||
| 103 | altr_i2c_int_enable(struct altr_i2c_dev *idev, u32 mask, bool enable) | ||
| 104 | { | ||
| 105 | unsigned long flags; | ||
| 106 | u32 int_en; | ||
| 107 | |||
| 108 | spin_lock_irqsave(&idev->lock, flags); | ||
| 109 | |||
| 110 | int_en = readl(idev->base + ALTR_I2C_ISER); | ||
| 111 | if (enable) | ||
| 112 | idev->isr_mask = int_en | mask; | ||
| 113 | else | ||
| 114 | idev->isr_mask = int_en & ~mask; | ||
| 115 | |||
| 116 | writel(idev->isr_mask, idev->base + ALTR_I2C_ISER); | ||
| 117 | |||
| 118 | spin_unlock_irqrestore(&idev->lock, flags); | ||
| 119 | } | ||
| 120 | |||
| 121 | static void altr_i2c_int_clear(struct altr_i2c_dev *idev, u32 mask) | ||
| 122 | { | ||
| 123 | u32 int_en = readl(idev->base + ALTR_I2C_ISR); | ||
| 124 | |||
| 125 | writel(int_en | mask, idev->base + ALTR_I2C_ISR); | ||
| 126 | } | ||
| 127 | |||
| 128 | static void altr_i2c_core_disable(struct altr_i2c_dev *idev) | ||
| 129 | { | ||
| 130 | u32 tmp = readl(idev->base + ALTR_I2C_CTRL); | ||
| 131 | |||
| 132 | writel(tmp & ~ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void altr_i2c_core_enable(struct altr_i2c_dev *idev) | ||
| 136 | { | ||
| 137 | u32 tmp = readl(idev->base + ALTR_I2C_CTRL); | ||
| 138 | |||
| 139 | writel(tmp | ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void altr_i2c_reset(struct altr_i2c_dev *idev) | ||
| 143 | { | ||
| 144 | altr_i2c_core_disable(idev); | ||
| 145 | altr_i2c_core_enable(idev); | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void altr_i2c_stop(struct altr_i2c_dev *idev) | ||
| 149 | { | ||
| 150 | writel(ALTR_I2C_TFR_CMD_STO, idev->base + ALTR_I2C_TFR_CMD); | ||
| 151 | } | ||
| 152 | |||
| 153 | static void altr_i2c_init(struct altr_i2c_dev *idev) | ||
| 154 | { | ||
| 155 | u32 divisor = clk_get_rate(idev->i2c_clk) / idev->bus_clk_rate; | ||
| 156 | u32 clk_mhz = clk_get_rate(idev->i2c_clk) / 1000000; | ||
| 157 | u32 tmp = (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_RXT_SHFT) | | ||
| 158 | (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_TCT_SHFT); | ||
| 159 | u32 t_high, t_low; | ||
| 160 | |||
| 161 | if (idev->bus_clk_rate <= 100000) { | ||
| 162 | tmp &= ~ALTR_I2C_CTRL_BSPEED; | ||
| 163 | /* Standard mode SCL 50/50 */ | ||
| 164 | t_high = divisor * 1 / 2; | ||
| 165 | t_low = divisor * 1 / 2; | ||
| 166 | } else { | ||
| 167 | tmp |= ALTR_I2C_CTRL_BSPEED; | ||
| 168 | /* Fast mode SCL 33/66 */ | ||
| 169 | t_high = divisor * 1 / 3; | ||
| 170 | t_low = divisor * 2 / 3; | ||
| 171 | } | ||
| 172 | writel(tmp, idev->base + ALTR_I2C_CTRL); | ||
| 173 | |||
| 174 | dev_dbg(idev->dev, "rate=%uHz per_clk=%uMHz -> ratio=1:%u\n", | ||
| 175 | idev->bus_clk_rate, clk_mhz, divisor); | ||
| 176 | |||
| 177 | /* Reset controller */ | ||
| 178 | altr_i2c_reset(idev); | ||
| 179 | |||
| 180 | /* SCL High Time */ | ||
| 181 | writel(t_high, idev->base + ALTR_I2C_SCL_HIGH); | ||
| 182 | /* SCL Low Time */ | ||
| 183 | writel(t_low, idev->base + ALTR_I2C_SCL_LOW); | ||
| 184 | /* SDA Hold Time, 300ns */ | ||
| 185 | writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD); | ||
| 186 | |||
| 187 | /* Mask all master interrupt bits */ | ||
| 188 | altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | * altr_i2c_transfer - On the last byte to be transmitted, send | ||
| 193 | * a Stop bit on the last byte. | ||
| 194 | */ | ||
| 195 | static void altr_i2c_transfer(struct altr_i2c_dev *idev, u32 data) | ||
| 196 | { | ||
| 197 | /* On the last byte to be transmitted, send STOP */ | ||
| 198 | if (idev->msg_len == 1) | ||
| 199 | data |= ALTR_I2C_TFR_CMD_STO; | ||
| 200 | if (idev->msg_len > 0) | ||
| 201 | writel(data, idev->base + ALTR_I2C_TFR_CMD); | ||
| 202 | } | ||
| 203 | |||
| 204 | /** | ||
| 205 | * altr_i2c_empty_rx_fifo - Fetch data from RX FIFO until end of | ||
| 206 | * transfer. Send a Stop bit on the last byte. | ||
| 207 | */ | ||
| 208 | static void altr_i2c_empty_rx_fifo(struct altr_i2c_dev *idev) | ||
| 209 | { | ||
| 210 | size_t rx_fifo_avail = readl(idev->base + ALTR_I2C_RX_FIFO_LVL); | ||
| 211 | int bytes_to_transfer = min(rx_fifo_avail, idev->msg_len); | ||
| 212 | |||
| 213 | while (bytes_to_transfer-- > 0) { | ||
| 214 | *idev->buf++ = readl(idev->base + ALTR_I2C_RX_DATA); | ||
| 215 | idev->msg_len--; | ||
| 216 | altr_i2c_transfer(idev, 0); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * altr_i2c_fill_tx_fifo - Fill TX FIFO from current message buffer. | ||
| 222 | * @return: Number of bytes left to transfer. | ||
| 223 | */ | ||
| 224 | static int altr_i2c_fill_tx_fifo(struct altr_i2c_dev *idev) | ||
| 225 | { | ||
| 226 | size_t tx_fifo_avail = idev->fifo_size - readl(idev->base + | ||
| 227 | ALTR_I2C_TC_FIFO_LVL); | ||
| 228 | int bytes_to_transfer = min(tx_fifo_avail, idev->msg_len); | ||
| 229 | int ret = idev->msg_len - bytes_to_transfer; | ||
| 230 | |||
| 231 | while (bytes_to_transfer-- > 0) { | ||
| 232 | altr_i2c_transfer(idev, *idev->buf++); | ||
| 233 | idev->msg_len--; | ||
| 234 | } | ||
| 235 | |||
| 236 | return ret; | ||
| 237 | } | ||
| 238 | |||
| 239 | static irqreturn_t altr_i2c_isr_quick(int irq, void *_dev) | ||
| 240 | { | ||
| 241 | struct altr_i2c_dev *idev = _dev; | ||
| 242 | irqreturn_t ret = IRQ_HANDLED; | ||
| 243 | |||
| 244 | /* Read IRQ status but only interested in Enabled IRQs. */ | ||
| 245 | idev->isr_status = readl(idev->base + ALTR_I2C_ISR) & idev->isr_mask; | ||
| 246 | if (idev->isr_status) | ||
| 247 | ret = IRQ_WAKE_THREAD; | ||
| 248 | |||
| 249 | return ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | static irqreturn_t altr_i2c_isr(int irq, void *_dev) | ||
| 253 | { | ||
| 254 | int ret; | ||
| 255 | bool read, finish = false; | ||
| 256 | struct altr_i2c_dev *idev = _dev; | ||
| 257 | u32 status = idev->isr_status; | ||
| 258 | |||
| 259 | if (!idev->msg) { | ||
| 260 | dev_warn(idev->dev, "unexpected interrupt\n"); | ||
| 261 | altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ); | ||
| 262 | return IRQ_HANDLED; | ||
| 263 | } | ||
| 264 | read = (idev->msg->flags & I2C_M_RD) != 0; | ||
| 265 | |||
| 266 | /* handle Lost Arbitration */ | ||
| 267 | if (unlikely(status & ALTR_I2C_ISR_ARB)) { | ||
| 268 | altr_i2c_int_clear(idev, ALTR_I2C_ISR_ARB); | ||
| 269 | idev->msg_err = -EAGAIN; | ||
| 270 | finish = true; | ||
| 271 | } else if (unlikely(status & ALTR_I2C_ISR_NACK)) { | ||
| 272 | dev_dbg(idev->dev, "Could not get ACK\n"); | ||
| 273 | idev->msg_err = -ENXIO; | ||
| 274 | altr_i2c_int_clear(idev, ALTR_I2C_ISR_NACK); | ||
| 275 | altr_i2c_stop(idev); | ||
| 276 | finish = true; | ||
| 277 | } else if (read && unlikely(status & ALTR_I2C_ISR_RXOF)) { | ||
| 278 | /* handle RX FIFO Overflow */ | ||
| 279 | altr_i2c_empty_rx_fifo(idev); | ||
| 280 | altr_i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY); | ||
| 281 | altr_i2c_stop(idev); | ||
| 282 | dev_err(idev->dev, "RX FIFO Overflow\n"); | ||
| 283 | finish = true; | ||
| 284 | } else if (read && (status & ALTR_I2C_ISR_RXRDY)) { | ||
| 285 | /* RX FIFO needs service? */ | ||
| 286 | altr_i2c_empty_rx_fifo(idev); | ||
| 287 | altr_i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY); | ||
| 288 | if (!idev->msg_len) | ||
| 289 | finish = true; | ||
| 290 | } else if (!read && (status & ALTR_I2C_ISR_TXRDY)) { | ||
| 291 | /* TX FIFO needs service? */ | ||
| 292 | altr_i2c_int_clear(idev, ALTR_I2C_ISR_TXRDY); | ||
| 293 | if (idev->msg_len > 0) | ||
| 294 | altr_i2c_fill_tx_fifo(idev); | ||
| 295 | else | ||
| 296 | finish = true; | ||
| 297 | } else { | ||
| 298 | dev_warn(idev->dev, "Unexpected interrupt: 0x%x\n", status); | ||
| 299 | altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ); | ||
| 300 | } | ||
| 301 | |||
| 302 | if (finish) { | ||
| 303 | /* Wait for the Core to finish */ | ||
| 304 | ret = readl_poll_timeout_atomic(idev->base + ALTR_I2C_STATUS, | ||
| 305 | status, | ||
| 306 | !(status & ALTR_I2C_STAT_CORE), | ||
| 307 | 1, ALTR_I2C_TIMEOUT); | ||
| 308 | if (ret) | ||
| 309 | dev_err(idev->dev, "message timeout\n"); | ||
| 310 | altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); | ||
| 311 | altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ); | ||
| 312 | complete(&idev->msg_complete); | ||
| 313 | dev_dbg(idev->dev, "Message Complete\n"); | ||
| 314 | } | ||
| 315 | |||
| 316 | return IRQ_HANDLED; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg) | ||
| 320 | { | ||
| 321 | u32 imask = ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | ALTR_I2C_ISR_NACK; | ||
| 322 | unsigned long time_left; | ||
| 323 | u32 value; | ||
| 324 | u8 addr = i2c_8bit_addr_from_msg(msg); | ||
| 325 | |||
| 326 | idev->msg = msg; | ||
| 327 | idev->msg_len = msg->len; | ||
| 328 | idev->buf = msg->buf; | ||
| 329 | idev->msg_err = 0; | ||
| 330 | reinit_completion(&idev->msg_complete); | ||
| 331 | altr_i2c_core_enable(idev); | ||
| 332 | |||
| 333 | /* Make sure RX FIFO is empty */ | ||
| 334 | do { | ||
| 335 | readl(idev->base + ALTR_I2C_RX_DATA); | ||
| 336 | } while (readl(idev->base + ALTR_I2C_RX_FIFO_LVL)); | ||
| 337 | |||
| 338 | writel(ALTR_I2C_TFR_CMD_STA | addr, idev->base + ALTR_I2C_TFR_CMD); | ||
| 339 | |||
| 340 | if ((msg->flags & I2C_M_RD) != 0) { | ||
| 341 | imask |= ALTR_I2C_ISER_RXOF_EN | ALTR_I2C_ISER_RXRDY_EN; | ||
| 342 | altr_i2c_int_enable(idev, imask, true); | ||
| 343 | /* write the first byte to start the RX */ | ||
| 344 | altr_i2c_transfer(idev, 0); | ||
| 345 | } else { | ||
| 346 | imask |= ALTR_I2C_ISR_TXRDY; | ||
| 347 | altr_i2c_int_enable(idev, imask, true); | ||
| 348 | altr_i2c_fill_tx_fifo(idev); | ||
| 349 | } | ||
| 350 | |||
| 351 | time_left = wait_for_completion_timeout(&idev->msg_complete, | ||
| 352 | ALTR_I2C_XFER_TIMEOUT); | ||
| 353 | altr_i2c_int_enable(idev, imask, false); | ||
| 354 | |||
| 355 | value = readl(idev->base + ALTR_I2C_STATUS) & ALTR_I2C_STAT_CORE; | ||
| 356 | if (value) | ||
| 357 | dev_err(idev->dev, "Core Status not IDLE...\n"); | ||
| 358 | |||
| 359 | if (time_left == 0) { | ||
| 360 | idev->msg_err = -ETIMEDOUT; | ||
| 361 | dev_dbg(idev->dev, "Transaction timed out.\n"); | ||
| 362 | } | ||
| 363 | |||
| 364 | altr_i2c_core_disable(idev); | ||
| 365 | |||
| 366 | return idev->msg_err; | ||
| 367 | } | ||
| 368 | |||
| 369 | static int | ||
| 370 | altr_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
| 371 | { | ||
| 372 | struct altr_i2c_dev *idev = i2c_get_adapdata(adap); | ||
| 373 | int i, ret; | ||
| 374 | |||
| 375 | for (i = 0; i < num; i++) { | ||
| 376 | ret = altr_i2c_xfer_msg(idev, msgs++); | ||
| 377 | if (ret) | ||
| 378 | return ret; | ||
| 379 | } | ||
| 380 | return num; | ||
| 381 | } | ||
| 382 | |||
| 383 | static u32 altr_i2c_func(struct i2c_adapter *adap) | ||
| 384 | { | ||
| 385 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
| 386 | } | ||
| 387 | |||
| 388 | static const struct i2c_algorithm altr_i2c_algo = { | ||
| 389 | .master_xfer = altr_i2c_xfer, | ||
| 390 | .functionality = altr_i2c_func, | ||
| 391 | }; | ||
| 392 | |||
| 393 | static int altr_i2c_probe(struct platform_device *pdev) | ||
| 394 | { | ||
| 395 | struct altr_i2c_dev *idev = NULL; | ||
| 396 | struct resource *res; | ||
| 397 | int irq, ret; | ||
| 398 | u32 val; | ||
| 399 | |||
| 400 | idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); | ||
| 401 | if (!idev) | ||
| 402 | return -ENOMEM; | ||
| 403 | |||
| 404 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 405 | idev->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 406 | if (IS_ERR(idev->base)) | ||
| 407 | return PTR_ERR(idev->base); | ||
| 408 | |||
| 409 | irq = platform_get_irq(pdev, 0); | ||
| 410 | if (irq < 0) { | ||
| 411 | dev_err(&pdev->dev, "missing interrupt resource\n"); | ||
| 412 | return irq; | ||
| 413 | } | ||
| 414 | |||
| 415 | idev->i2c_clk = devm_clk_get(&pdev->dev, NULL); | ||
| 416 | if (IS_ERR(idev->i2c_clk)) { | ||
| 417 | dev_err(&pdev->dev, "missing clock\n"); | ||
| 418 | return PTR_ERR(idev->i2c_clk); | ||
| 419 | } | ||
| 420 | |||
| 421 | idev->dev = &pdev->dev; | ||
| 422 | init_completion(&idev->msg_complete); | ||
| 423 | spin_lock_init(&idev->lock); | ||
| 424 | |||
| 425 | val = device_property_read_u32(idev->dev, "fifo-size", | ||
| 426 | &idev->fifo_size); | ||
| 427 | if (val) { | ||
| 428 | dev_err(&pdev->dev, "FIFO size set to default of %d\n", | ||
| 429 | ALTR_I2C_DFLT_FIFO_SZ); | ||
| 430 | idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ; | ||
| 431 | } | ||
| 432 | |||
| 433 | val = device_property_read_u32(idev->dev, "clock-frequency", | ||
| 434 | &idev->bus_clk_rate); | ||
| 435 | if (val) { | ||
| 436 | dev_err(&pdev->dev, "Default to 100kHz\n"); | ||
| 437 | idev->bus_clk_rate = 100000; /* default clock rate */ | ||
| 438 | } | ||
| 439 | |||
| 440 | if (idev->bus_clk_rate > 400000) { | ||
| 441 | dev_err(&pdev->dev, "invalid clock-frequency %d\n", | ||
| 442 | idev->bus_clk_rate); | ||
| 443 | return -EINVAL; | ||
| 444 | } | ||
| 445 | |||
| 446 | ret = devm_request_threaded_irq(&pdev->dev, irq, altr_i2c_isr_quick, | ||
| 447 | altr_i2c_isr, IRQF_ONESHOT, | ||
| 448 | pdev->name, idev); | ||
| 449 | if (ret) { | ||
| 450 | dev_err(&pdev->dev, "failed to claim IRQ %d\n", irq); | ||
| 451 | return ret; | ||
| 452 | } | ||
| 453 | |||
| 454 | ret = clk_prepare_enable(idev->i2c_clk); | ||
| 455 | if (ret) { | ||
| 456 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 457 | return ret; | ||
| 458 | } | ||
| 459 | |||
| 460 | altr_i2c_init(idev); | ||
| 461 | |||
| 462 | i2c_set_adapdata(&idev->adapter, idev); | ||
| 463 | strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name)); | ||
| 464 | idev->adapter.owner = THIS_MODULE; | ||
| 465 | idev->adapter.algo = &altr_i2c_algo; | ||
| 466 | idev->adapter.dev.parent = &pdev->dev; | ||
| 467 | idev->adapter.dev.of_node = pdev->dev.of_node; | ||
| 468 | |||
| 469 | platform_set_drvdata(pdev, idev); | ||
| 470 | |||
| 471 | ret = i2c_add_adapter(&idev->adapter); | ||
| 472 | if (ret) { | ||
| 473 | clk_disable_unprepare(idev->i2c_clk); | ||
| 474 | return ret; | ||
| 475 | } | ||
| 476 | dev_info(&pdev->dev, "Altera SoftIP I2C Probe Complete\n"); | ||
| 477 | |||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | |||
| 481 | static int altr_i2c_remove(struct platform_device *pdev) | ||
| 482 | { | ||
| 483 | struct altr_i2c_dev *idev = platform_get_drvdata(pdev); | ||
| 484 | |||
| 485 | clk_disable_unprepare(idev->i2c_clk); | ||
| 486 | i2c_del_adapter(&idev->adapter); | ||
| 487 | |||
| 488 | return 0; | ||
| 489 | } | ||
| 490 | |||
| 491 | /* Match table for of_platform binding */ | ||
| 492 | static const struct of_device_id altr_i2c_of_match[] = { | ||
| 493 | { .compatible = "altr,softip-i2c-v1.0" }, | ||
| 494 | {}, | ||
| 495 | }; | ||
| 496 | MODULE_DEVICE_TABLE(of, altr_i2c_of_match); | ||
| 497 | |||
| 498 | static struct platform_driver altr_i2c_driver = { | ||
| 499 | .probe = altr_i2c_probe, | ||
| 500 | .remove = altr_i2c_remove, | ||
| 501 | .driver = { | ||
| 502 | .name = "altera-i2c", | ||
| 503 | .of_match_table = altr_i2c_of_match, | ||
| 504 | }, | ||
| 505 | }; | ||
| 506 | |||
| 507 | module_platform_driver(altr_i2c_driver); | ||
| 508 | |||
| 509 | MODULE_DESCRIPTION("Altera Soft IP I2C bus driver"); | ||
| 510 | MODULE_AUTHOR("Thor Thayer <thor.thayer@linux.intel.com>"); | ||
| 511 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/i2c/busses/i2c-stm32.h b/drivers/i2c/busses/i2c-stm32.h new file mode 100644 index 000000000000..dab51761f8c5 --- /dev/null +++ b/drivers/i2c/busses/i2c-stm32.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * i2c-stm32.h | ||
| 3 | * | ||
| 4 | * Copyright (C) M'boumba Cedric Madianga 2017 | ||
| 5 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> | ||
| 6 | * | ||
| 7 | * License terms: GNU General Public License (GPL), version 2 | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef _I2C_STM32_H | ||
| 11 | #define _I2C_STM32_H | ||
| 12 | |||
| 13 | enum stm32_i2c_speed { | ||
| 14 | STM32_I2C_SPEED_STANDARD, /* 100 kHz */ | ||
| 15 | STM32_I2C_SPEED_FAST, /* 400 kHz */ | ||
| 16 | STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */ | ||
| 17 | STM32_I2C_SPEED_END, | ||
| 18 | }; | ||
| 19 | |||
| 20 | #endif /* _I2C_STM32_H */ | ||
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c index aceb6f788564..4ec108496f15 100644 --- a/drivers/i2c/busses/i2c-stm32f4.c +++ b/drivers/i2c/busses/i2c-stm32f4.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/reset.h> | 28 | #include <linux/reset.h> |
| 29 | 29 | ||
| 30 | #include "i2c-stm32.h" | ||
| 31 | |||
| 30 | /* STM32F4 I2C offset registers */ | 32 | /* STM32F4 I2C offset registers */ |
| 31 | #define STM32F4_I2C_CR1 0x00 | 33 | #define STM32F4_I2C_CR1 0x00 |
| 32 | #define STM32F4_I2C_CR2 0x04 | 34 | #define STM32F4_I2C_CR2 0x04 |
| @@ -90,12 +92,6 @@ | |||
| 90 | #define STM32F4_I2C_MAX_FREQ 46U | 92 | #define STM32F4_I2C_MAX_FREQ 46U |
| 91 | #define HZ_TO_MHZ 1000000 | 93 | #define HZ_TO_MHZ 1000000 |
| 92 | 94 | ||
| 93 | enum stm32f4_i2c_speed { | ||
| 94 | STM32F4_I2C_SPEED_STANDARD, /* 100 kHz */ | ||
| 95 | STM32F4_I2C_SPEED_FAST, /* 400 kHz */ | ||
| 96 | STM32F4_I2C_SPEED_END, | ||
| 97 | }; | ||
| 98 | |||
| 99 | /** | 95 | /** |
| 100 | * struct stm32f4_i2c_msg - client specific data | 96 | * struct stm32f4_i2c_msg - client specific data |
| 101 | * @addr: 8-bit slave addr, including r/w bit | 97 | * @addr: 8-bit slave addr, including r/w bit |
| @@ -159,7 +155,7 @@ static int stm32f4_i2c_set_periph_clk_freq(struct stm32f4_i2c_dev *i2c_dev) | |||
| 159 | i2c_dev->parent_rate = clk_get_rate(i2c_dev->clk); | 155 | i2c_dev->parent_rate = clk_get_rate(i2c_dev->clk); |
| 160 | freq = DIV_ROUND_UP(i2c_dev->parent_rate, HZ_TO_MHZ); | 156 | freq = DIV_ROUND_UP(i2c_dev->parent_rate, HZ_TO_MHZ); |
| 161 | 157 | ||
| 162 | if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) { | 158 | if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) { |
| 163 | /* | 159 | /* |
| 164 | * To reach 100 kHz, the parent clk frequency should be between | 160 | * To reach 100 kHz, the parent clk frequency should be between |
| 165 | * a minimum value of 2 MHz and a maximum value of 46 MHz due | 161 | * a minimum value of 2 MHz and a maximum value of 46 MHz due |
| @@ -216,7 +212,7 @@ static void stm32f4_i2c_set_rise_time(struct stm32f4_i2c_dev *i2c_dev) | |||
| 216 | * is not higher than 46 MHz . As a result trise is at most 4 bits wide | 212 | * is not higher than 46 MHz . As a result trise is at most 4 bits wide |
| 217 | * and so fits into the TRISE bits [5:0]. | 213 | * and so fits into the TRISE bits [5:0]. |
| 218 | */ | 214 | */ |
| 219 | if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) | 215 | if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) |
| 220 | trise = freq + 1; | 216 | trise = freq + 1; |
| 221 | else | 217 | else |
| 222 | trise = freq * 3 / 10 + 1; | 218 | trise = freq * 3 / 10 + 1; |
| @@ -230,7 +226,7 @@ static void stm32f4_i2c_set_speed_mode(struct stm32f4_i2c_dev *i2c_dev) | |||
| 230 | u32 val; | 226 | u32 val; |
| 231 | u32 ccr = 0; | 227 | u32 ccr = 0; |
| 232 | 228 | ||
| 233 | if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) { | 229 | if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) { |
| 234 | /* | 230 | /* |
| 235 | * In standard mode: | 231 | * In standard mode: |
| 236 | * t_scl_high = t_scl_low = CCR * I2C parent clk period | 232 | * t_scl_high = t_scl_low = CCR * I2C parent clk period |
| @@ -808,10 +804,10 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) | |||
| 808 | udelay(2); | 804 | udelay(2); |
| 809 | reset_control_deassert(rst); | 805 | reset_control_deassert(rst); |
| 810 | 806 | ||
| 811 | i2c_dev->speed = STM32F4_I2C_SPEED_STANDARD; | 807 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; |
| 812 | ret = of_property_read_u32(np, "clock-frequency", &clk_rate); | 808 | ret = of_property_read_u32(np, "clock-frequency", &clk_rate); |
| 813 | if (!ret && clk_rate >= 400000) | 809 | if (!ret && clk_rate >= 400000) |
| 814 | i2c_dev->speed = STM32F4_I2C_SPEED_FAST; | 810 | i2c_dev->speed = STM32_I2C_SPEED_FAST; |
| 815 | 811 | ||
| 816 | i2c_dev->dev = &pdev->dev; | 812 | i2c_dev->dev = &pdev->dev; |
| 817 | 813 | ||
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c new file mode 100644 index 000000000000..47c67b0ca896 --- /dev/null +++ b/drivers/i2c/busses/i2c-stm32f7.c | |||
| @@ -0,0 +1,972 @@ | |||
| 1 | /* | ||
| 2 | * Driver for STMicroelectronics STM32F7 I2C controller | ||
| 3 | * | ||
| 4 | * This I2C controller is described in the STM32F75xxx and STM32F74xxx Soc | ||
| 5 | * reference manual. | ||
| 6 | * Please see below a link to the documentation: | ||
| 7 | * http://www.st.com/resource/en/reference_manual/dm00124865.pdf | ||
| 8 | * | ||
| 9 | * Copyright (C) M'boumba Cedric Madianga 2017 | ||
| 10 | * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> | ||
| 11 | * | ||
| 12 | * This driver is based on i2c-stm32f4.c | ||
| 13 | * | ||
| 14 | * License terms: GNU General Public License (GPL), version 2 | ||
| 15 | */ | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/i2c.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/iopoll.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/of.h> | ||
| 25 | #include <linux/of_address.h> | ||
| 26 | #include <linux/of_irq.h> | ||
| 27 | #include <linux/of_platform.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | #include <linux/reset.h> | ||
| 30 | #include <linux/slab.h> | ||
| 31 | |||
| 32 | #include "i2c-stm32.h" | ||
| 33 | |||
| 34 | /* STM32F7 I2C registers */ | ||
| 35 | #define STM32F7_I2C_CR1 0x00 | ||
| 36 | #define STM32F7_I2C_CR2 0x04 | ||
| 37 | #define STM32F7_I2C_TIMINGR 0x10 | ||
| 38 | #define STM32F7_I2C_ISR 0x18 | ||
| 39 | #define STM32F7_I2C_ICR 0x1C | ||
| 40 | #define STM32F7_I2C_RXDR 0x24 | ||
| 41 | #define STM32F7_I2C_TXDR 0x28 | ||
| 42 | |||
| 43 | /* STM32F7 I2C control 1 */ | ||
| 44 | #define STM32F7_I2C_CR1_ANFOFF BIT(12) | ||
| 45 | #define STM32F7_I2C_CR1_ERRIE BIT(7) | ||
| 46 | #define STM32F7_I2C_CR1_TCIE BIT(6) | ||
| 47 | #define STM32F7_I2C_CR1_STOPIE BIT(5) | ||
| 48 | #define STM32F7_I2C_CR1_NACKIE BIT(4) | ||
| 49 | #define STM32F7_I2C_CR1_ADDRIE BIT(3) | ||
| 50 | #define STM32F7_I2C_CR1_RXIE BIT(2) | ||
| 51 | #define STM32F7_I2C_CR1_TXIE BIT(1) | ||
| 52 | #define STM32F7_I2C_CR1_PE BIT(0) | ||
| 53 | #define STM32F7_I2C_ALL_IRQ_MASK (STM32F7_I2C_CR1_ERRIE \ | ||
| 54 | | STM32F7_I2C_CR1_TCIE \ | ||
| 55 | | STM32F7_I2C_CR1_STOPIE \ | ||
| 56 | | STM32F7_I2C_CR1_NACKIE \ | ||
| 57 | | STM32F7_I2C_CR1_RXIE \ | ||
| 58 | | STM32F7_I2C_CR1_TXIE) | ||
| 59 | |||
| 60 | /* STM32F7 I2C control 2 */ | ||
| 61 | #define STM32F7_I2C_CR2_RELOAD BIT(24) | ||
| 62 | #define STM32F7_I2C_CR2_NBYTES_MASK GENMASK(23, 16) | ||
| 63 | #define STM32F7_I2C_CR2_NBYTES(n) (((n) & 0xff) << 16) | ||
| 64 | #define STM32F7_I2C_CR2_NACK BIT(15) | ||
| 65 | #define STM32F7_I2C_CR2_STOP BIT(14) | ||
| 66 | #define STM32F7_I2C_CR2_START BIT(13) | ||
| 67 | #define STM32F7_I2C_CR2_RD_WRN BIT(10) | ||
| 68 | #define STM32F7_I2C_CR2_SADD7_MASK GENMASK(7, 1) | ||
| 69 | #define STM32F7_I2C_CR2_SADD7(n) (((n) & 0x7f) << 1) | ||
| 70 | |||
| 71 | /* STM32F7 I2C Interrupt Status */ | ||
| 72 | #define STM32F7_I2C_ISR_BUSY BIT(15) | ||
| 73 | #define STM32F7_I2C_ISR_ARLO BIT(9) | ||
| 74 | #define STM32F7_I2C_ISR_BERR BIT(8) | ||
| 75 | #define STM32F7_I2C_ISR_TCR BIT(7) | ||
| 76 | #define STM32F7_I2C_ISR_TC BIT(6) | ||
| 77 | #define STM32F7_I2C_ISR_STOPF BIT(5) | ||
| 78 | #define STM32F7_I2C_ISR_NACKF BIT(4) | ||
| 79 | #define STM32F7_I2C_ISR_RXNE BIT(2) | ||
| 80 | #define STM32F7_I2C_ISR_TXIS BIT(1) | ||
| 81 | |||
| 82 | /* STM32F7 I2C Interrupt Clear */ | ||
| 83 | #define STM32F7_I2C_ICR_ARLOCF BIT(9) | ||
| 84 | #define STM32F7_I2C_ICR_BERRCF BIT(8) | ||
| 85 | #define STM32F7_I2C_ICR_STOPCF BIT(5) | ||
| 86 | #define STM32F7_I2C_ICR_NACKCF BIT(4) | ||
| 87 | |||
| 88 | /* STM32F7 I2C Timing */ | ||
| 89 | #define STM32F7_I2C_TIMINGR_PRESC(n) (((n) & 0xf) << 28) | ||
| 90 | #define STM32F7_I2C_TIMINGR_SCLDEL(n) (((n) & 0xf) << 20) | ||
| 91 | #define STM32F7_I2C_TIMINGR_SDADEL(n) (((n) & 0xf) << 16) | ||
| 92 | #define STM32F7_I2C_TIMINGR_SCLH(n) (((n) & 0xff) << 8) | ||
| 93 | #define STM32F7_I2C_TIMINGR_SCLL(n) ((n) & 0xff) | ||
| 94 | |||
| 95 | #define STM32F7_I2C_MAX_LEN 0xff | ||
| 96 | |||
| 97 | #define STM32F7_I2C_DNF_DEFAULT 0 | ||
| 98 | #define STM32F7_I2C_DNF_MAX 16 | ||
| 99 | |||
| 100 | #define STM32F7_I2C_ANALOG_FILTER_ENABLE 1 | ||
| 101 | #define STM32F7_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */ | ||
| 102 | #define STM32F7_I2C_ANALOG_FILTER_DELAY_MAX 260 /* ns */ | ||
| 103 | |||
| 104 | #define STM32F7_I2C_RISE_TIME_DEFAULT 25 /* ns */ | ||
| 105 | #define STM32F7_I2C_FALL_TIME_DEFAULT 10 /* ns */ | ||
| 106 | |||
| 107 | #define STM32F7_PRESC_MAX BIT(4) | ||
| 108 | #define STM32F7_SCLDEL_MAX BIT(4) | ||
| 109 | #define STM32F7_SDADEL_MAX BIT(4) | ||
| 110 | #define STM32F7_SCLH_MAX BIT(8) | ||
| 111 | #define STM32F7_SCLL_MAX BIT(8) | ||
| 112 | |||
| 113 | /** | ||
| 114 | * struct stm32f7_i2c_spec - private i2c specification timing | ||
| 115 | * @rate: I2C bus speed (Hz) | ||
| 116 | * @rate_min: 80% of I2C bus speed (Hz) | ||
| 117 | * @rate_max: 100% of I2C bus speed (Hz) | ||
| 118 | * @fall_max: Max fall time of both SDA and SCL signals (ns) | ||
| 119 | * @rise_max: Max rise time of both SDA and SCL signals (ns) | ||
| 120 | * @hddat_min: Min data hold time (ns) | ||
| 121 | * @vddat_max: Max data valid time (ns) | ||
| 122 | * @sudat_min: Min data setup time (ns) | ||
| 123 | * @l_min: Min low period of the SCL clock (ns) | ||
| 124 | * @h_min: Min high period of the SCL clock (ns) | ||
| 125 | */ | ||
| 126 | struct stm32f7_i2c_spec { | ||
| 127 | u32 rate; | ||
| 128 | u32 rate_min; | ||
| 129 | u32 rate_max; | ||
| 130 | u32 fall_max; | ||
| 131 | u32 rise_max; | ||
| 132 | u32 hddat_min; | ||
| 133 | u32 vddat_max; | ||
| 134 | u32 sudat_min; | ||
| 135 | u32 l_min; | ||
| 136 | u32 h_min; | ||
| 137 | }; | ||
| 138 | |||
| 139 | /** | ||
| 140 | * struct stm32f7_i2c_setup - private I2C timing setup parameters | ||
| 141 | * @speed: I2C speed mode (standard, Fast Plus) | ||
| 142 | * @speed_freq: I2C speed frequency (Hz) | ||
| 143 | * @clock_src: I2C clock source frequency (Hz) | ||
| 144 | * @rise_time: Rise time (ns) | ||
| 145 | * @fall_time: Fall time (ns) | ||
| 146 | * @dnf: Digital filter coefficient (0-16) | ||
| 147 | * @analog_filter: Analog filter delay (On/Off) | ||
| 148 | */ | ||
| 149 | struct stm32f7_i2c_setup { | ||
| 150 | enum stm32_i2c_speed speed; | ||
| 151 | u32 speed_freq; | ||
| 152 | u32 clock_src; | ||
| 153 | u32 rise_time; | ||
| 154 | u32 fall_time; | ||
| 155 | u8 dnf; | ||
| 156 | bool analog_filter; | ||
| 157 | }; | ||
| 158 | |||
| 159 | /** | ||
| 160 | * struct stm32f7_i2c_timings - private I2C output parameters | ||
| 161 | * @prec: Prescaler value | ||
| 162 | * @scldel: Data setup time | ||
| 163 | * @sdadel: Data hold time | ||
| 164 | * @sclh: SCL high period (master mode) | ||
| 165 | * @sclh: SCL low period (master mode) | ||
| 166 | */ | ||
| 167 | struct stm32f7_i2c_timings { | ||
| 168 | struct list_head node; | ||
| 169 | u8 presc; | ||
| 170 | u8 scldel; | ||
| 171 | u8 sdadel; | ||
| 172 | u8 sclh; | ||
| 173 | u8 scll; | ||
| 174 | }; | ||
| 175 | |||
| 176 | /** | ||
| 177 | * struct stm32f7_i2c_msg - client specific data | ||
| 178 | * @addr: 8-bit slave addr, including r/w bit | ||
| 179 | * @count: number of bytes to be transferred | ||
| 180 | * @buf: data buffer | ||
| 181 | * @result: result of the transfer | ||
| 182 | * @stop: last I2C msg to be sent, i.e. STOP to be generated | ||
| 183 | */ | ||
| 184 | struct stm32f7_i2c_msg { | ||
| 185 | u8 addr; | ||
| 186 | u32 count; | ||
| 187 | u8 *buf; | ||
| 188 | int result; | ||
| 189 | bool stop; | ||
| 190 | }; | ||
| 191 | |||
| 192 | /** | ||
| 193 | * struct stm32f7_i2c_dev - private data of the controller | ||
| 194 | * @adap: I2C adapter for this controller | ||
| 195 | * @dev: device for this controller | ||
| 196 | * @base: virtual memory area | ||
| 197 | * @complete: completion of I2C message | ||
| 198 | * @clk: hw i2c clock | ||
| 199 | * @speed: I2C clock frequency of the controller. Standard, Fast or Fast+ | ||
| 200 | * @msg: Pointer to data to be written | ||
| 201 | * @msg_num: number of I2C messages to be executed | ||
| 202 | * @msg_id: message identifiant | ||
| 203 | * @f7_msg: customized i2c msg for driver usage | ||
| 204 | * @setup: I2C timing input setup | ||
| 205 | * @timing: I2C computed timings | ||
| 206 | */ | ||
| 207 | struct stm32f7_i2c_dev { | ||
| 208 | struct i2c_adapter adap; | ||
| 209 | struct device *dev; | ||
| 210 | void __iomem *base; | ||
| 211 | struct completion complete; | ||
| 212 | struct clk *clk; | ||
| 213 | int speed; | ||
| 214 | struct i2c_msg *msg; | ||
| 215 | unsigned int msg_num; | ||
| 216 | unsigned int msg_id; | ||
| 217 | struct stm32f7_i2c_msg f7_msg; | ||
| 218 | struct stm32f7_i2c_setup *setup; | ||
| 219 | struct stm32f7_i2c_timings timing; | ||
| 220 | }; | ||
| 221 | |||
| 222 | /** | ||
| 223 | * All these values are coming from I2C Specification, Version 6.0, 4th of | ||
| 224 | * April 2014. | ||
| 225 | * | ||
| 226 | * Table10. Characteristics of the SDA and SCL bus lines for Standard, Fast, | ||
| 227 | * and Fast-mode Plus I2C-bus devices | ||
| 228 | */ | ||
| 229 | static struct stm32f7_i2c_spec i2c_specs[] = { | ||
| 230 | [STM32_I2C_SPEED_STANDARD] = { | ||
| 231 | .rate = 100000, | ||
| 232 | .rate_min = 80000, | ||
| 233 | .rate_max = 100000, | ||
| 234 | .fall_max = 300, | ||
| 235 | .rise_max = 1000, | ||
| 236 | .hddat_min = 0, | ||
| 237 | .vddat_max = 3450, | ||
| 238 | .sudat_min = 250, | ||
| 239 | .l_min = 4700, | ||
| 240 | .h_min = 4000, | ||
| 241 | }, | ||
| 242 | [STM32_I2C_SPEED_FAST] = { | ||
| 243 | .rate = 400000, | ||
| 244 | .rate_min = 320000, | ||
| 245 | .rate_max = 400000, | ||
| 246 | .fall_max = 300, | ||
| 247 | .rise_max = 300, | ||
| 248 | .hddat_min = 0, | ||
| 249 | .vddat_max = 900, | ||
| 250 | .sudat_min = 100, | ||
| 251 | .l_min = 1300, | ||
| 252 | .h_min = 600, | ||
| 253 | }, | ||
| 254 | [STM32_I2C_SPEED_FAST_PLUS] = { | ||
| 255 | .rate = 1000000, | ||
| 256 | .rate_min = 800000, | ||
| 257 | .rate_max = 1000000, | ||
| 258 | .fall_max = 100, | ||
| 259 | .rise_max = 120, | ||
| 260 | .hddat_min = 0, | ||
| 261 | .vddat_max = 450, | ||
| 262 | .sudat_min = 50, | ||
| 263 | .l_min = 500, | ||
| 264 | .h_min = 260, | ||
| 265 | }, | ||
| 266 | }; | ||
| 267 | |||
| 268 | struct stm32f7_i2c_setup stm32f7_setup = { | ||
| 269 | .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT, | ||
| 270 | .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, | ||
| 271 | .dnf = STM32F7_I2C_DNF_DEFAULT, | ||
| 272 | .analog_filter = STM32F7_I2C_ANALOG_FILTER_ENABLE, | ||
| 273 | }; | ||
| 274 | |||
| 275 | static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask) | ||
| 276 | { | ||
| 277 | writel_relaxed(readl_relaxed(reg) | mask, reg); | ||
| 278 | } | ||
| 279 | |||
| 280 | static inline void stm32f7_i2c_clr_bits(void __iomem *reg, u32 mask) | ||
| 281 | { | ||
| 282 | writel_relaxed(readl_relaxed(reg) & ~mask, reg); | ||
| 283 | } | ||
| 284 | |||
| 285 | static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, | ||
| 286 | struct stm32f7_i2c_setup *setup, | ||
| 287 | struct stm32f7_i2c_timings *output) | ||
| 288 | { | ||
| 289 | u32 p_prev = STM32F7_PRESC_MAX; | ||
| 290 | u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, | ||
| 291 | setup->clock_src); | ||
| 292 | u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC, | ||
| 293 | setup->speed_freq); | ||
| 294 | u32 clk_error_prev = i2cbus; | ||
| 295 | u32 tsync; | ||
| 296 | u32 af_delay_min, af_delay_max; | ||
| 297 | u32 dnf_delay; | ||
| 298 | u32 clk_min, clk_max; | ||
| 299 | int sdadel_min, sdadel_max; | ||
| 300 | int scldel_min; | ||
| 301 | struct stm32f7_i2c_timings *v, *_v, *s; | ||
| 302 | struct list_head solutions; | ||
| 303 | u16 p, l, a, h; | ||
| 304 | int ret = 0; | ||
| 305 | |||
| 306 | if (setup->speed >= STM32_I2C_SPEED_END) { | ||
| 307 | dev_err(i2c_dev->dev, "speed out of bound {%d/%d}\n", | ||
| 308 | setup->speed, STM32_I2C_SPEED_END - 1); | ||
| 309 | return -EINVAL; | ||
| 310 | } | ||
| 311 | |||
| 312 | if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || | ||
| 313 | (setup->fall_time > i2c_specs[setup->speed].fall_max)) { | ||
| 314 | dev_err(i2c_dev->dev, | ||
| 315 | "timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", | ||
| 316 | setup->rise_time, i2c_specs[setup->speed].rise_max, | ||
| 317 | setup->fall_time, i2c_specs[setup->speed].fall_max); | ||
| 318 | return -EINVAL; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (setup->dnf > STM32F7_I2C_DNF_MAX) { | ||
| 322 | dev_err(i2c_dev->dev, | ||
| 323 | "DNF out of bound %d/%d\n", | ||
| 324 | setup->dnf, STM32F7_I2C_DNF_MAX); | ||
| 325 | return -EINVAL; | ||
| 326 | } | ||
| 327 | |||
| 328 | if (setup->speed_freq > i2c_specs[setup->speed].rate) { | ||
| 329 | dev_err(i2c_dev->dev, "ERROR: Freq {%d/%d}\n", | ||
| 330 | setup->speed_freq, i2c_specs[setup->speed].rate); | ||
| 331 | return -EINVAL; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* Analog and Digital Filters */ | ||
| 335 | af_delay_min = | ||
| 336 | (setup->analog_filter ? | ||
| 337 | STM32F7_I2C_ANALOG_FILTER_DELAY_MIN : 0); | ||
| 338 | af_delay_max = | ||
| 339 | (setup->analog_filter ? | ||
| 340 | STM32F7_I2C_ANALOG_FILTER_DELAY_MAX : 0); | ||
| 341 | dnf_delay = setup->dnf * i2cclk; | ||
| 342 | |||
| 343 | sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min - | ||
| 344 | af_delay_min - (setup->dnf + 3) * i2cclk; | ||
| 345 | |||
| 346 | sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - | ||
| 347 | af_delay_max - (setup->dnf + 4) * i2cclk; | ||
| 348 | |||
| 349 | scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min; | ||
| 350 | |||
| 351 | if (sdadel_min < 0) | ||
| 352 | sdadel_min = 0; | ||
| 353 | if (sdadel_max < 0) | ||
| 354 | sdadel_max = 0; | ||
| 355 | |||
| 356 | dev_dbg(i2c_dev->dev, "SDADEL(min/max): %i/%i, SCLDEL(Min): %i\n", | ||
| 357 | sdadel_min, sdadel_max, scldel_min); | ||
| 358 | |||
| 359 | INIT_LIST_HEAD(&solutions); | ||
| 360 | /* Compute possible values for PRESC, SCLDEL and SDADEL */ | ||
| 361 | for (p = 0; p < STM32F7_PRESC_MAX; p++) { | ||
| 362 | for (l = 0; l < STM32F7_SCLDEL_MAX; l++) { | ||
| 363 | u32 scldel = (l + 1) * (p + 1) * i2cclk; | ||
| 364 | |||
| 365 | if (scldel < scldel_min) | ||
| 366 | continue; | ||
| 367 | |||
| 368 | for (a = 0; a < STM32F7_SDADEL_MAX; a++) { | ||
| 369 | u32 sdadel = (a * (p + 1) + 1) * i2cclk; | ||
| 370 | |||
| 371 | if (((sdadel >= sdadel_min) && | ||
| 372 | (sdadel <= sdadel_max)) && | ||
| 373 | (p != p_prev)) { | ||
| 374 | v = kmalloc(sizeof(*v), GFP_KERNEL); | ||
| 375 | if (!v) { | ||
| 376 | ret = -ENOMEM; | ||
| 377 | goto exit; | ||
| 378 | } | ||
| 379 | |||
| 380 | v->presc = p; | ||
| 381 | v->scldel = l; | ||
| 382 | v->sdadel = a; | ||
| 383 | p_prev = p; | ||
| 384 | |||
| 385 | list_add_tail(&v->node, | ||
| 386 | &solutions); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | if (list_empty(&solutions)) { | ||
| 393 | dev_err(i2c_dev->dev, "no Prescaler solution\n"); | ||
| 394 | ret = -EPERM; | ||
| 395 | goto exit; | ||
| 396 | } | ||
| 397 | |||
| 398 | tsync = af_delay_min + dnf_delay + (2 * i2cclk); | ||
| 399 | s = NULL; | ||
| 400 | clk_max = NSEC_PER_SEC / i2c_specs[setup->speed].rate_min; | ||
| 401 | clk_min = NSEC_PER_SEC / i2c_specs[setup->speed].rate_max; | ||
| 402 | |||
| 403 | /* | ||
| 404 | * Among Prescaler possibilities discovered above figures out SCL Low | ||
| 405 | * and High Period. Provided: | ||
| 406 | * - SCL Low Period has to be higher than SCL Clock Low Period | ||
| 407 | * defined by I2C Specification. I2C Clock has to be lower than | ||
| 408 | * (SCL Low Period - Analog/Digital filters) / 4. | ||
| 409 | * - SCL High Period has to be lower than SCL Clock High Period | ||
| 410 | * defined by I2C Specification | ||
| 411 | * - I2C Clock has to be lower than SCL High Period | ||
| 412 | */ | ||
| 413 | list_for_each_entry(v, &solutions, node) { | ||
| 414 | u32 prescaler = (v->presc + 1) * i2cclk; | ||
| 415 | |||
| 416 | for (l = 0; l < STM32F7_SCLL_MAX; l++) { | ||
| 417 | u32 tscl_l = (l + 1) * prescaler + tsync; | ||
| 418 | |||
| 419 | if ((tscl_l < i2c_specs[setup->speed].l_min) || | ||
| 420 | (i2cclk >= | ||
| 421 | ((tscl_l - af_delay_min - dnf_delay) / 4))) { | ||
| 422 | continue; | ||
| 423 | } | ||
| 424 | |||
| 425 | for (h = 0; h < STM32F7_SCLH_MAX; h++) { | ||
| 426 | u32 tscl_h = (h + 1) * prescaler + tsync; | ||
| 427 | u32 tscl = tscl_l + tscl_h + | ||
| 428 | setup->rise_time + setup->fall_time; | ||
| 429 | |||
| 430 | if ((tscl >= clk_min) && (tscl <= clk_max) && | ||
| 431 | (tscl_h >= i2c_specs[setup->speed].h_min) && | ||
| 432 | (i2cclk < tscl_h)) { | ||
| 433 | int clk_error = tscl - i2cbus; | ||
| 434 | |||
| 435 | if (clk_error < 0) | ||
| 436 | clk_error = -clk_error; | ||
| 437 | |||
| 438 | if (clk_error < clk_error_prev) { | ||
| 439 | clk_error_prev = clk_error; | ||
| 440 | v->scll = l; | ||
| 441 | v->sclh = h; | ||
| 442 | s = v; | ||
| 443 | } | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | if (!s) { | ||
| 450 | dev_err(i2c_dev->dev, "no solution at all\n"); | ||
| 451 | ret = -EPERM; | ||
| 452 | goto exit; | ||
| 453 | } | ||
| 454 | |||
| 455 | output->presc = s->presc; | ||
| 456 | output->scldel = s->scldel; | ||
| 457 | output->sdadel = s->sdadel; | ||
| 458 | output->scll = s->scll; | ||
| 459 | output->sclh = s->sclh; | ||
| 460 | |||
| 461 | dev_dbg(i2c_dev->dev, | ||
| 462 | "Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n", | ||
| 463 | output->presc, | ||
| 464 | output->scldel, output->sdadel, | ||
| 465 | output->scll, output->sclh); | ||
| 466 | |||
| 467 | exit: | ||
| 468 | /* Release list and memory */ | ||
| 469 | list_for_each_entry_safe(v, _v, &solutions, node) { | ||
| 470 | list_del(&v->node); | ||
| 471 | kfree(v); | ||
| 472 | } | ||
| 473 | |||
| 474 | return ret; | ||
| 475 | } | ||
| 476 | |||
| 477 | static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev, | ||
| 478 | struct stm32f7_i2c_setup *setup) | ||
| 479 | { | ||
| 480 | int ret = 0; | ||
| 481 | |||
| 482 | setup->speed = i2c_dev->speed; | ||
| 483 | setup->speed_freq = i2c_specs[setup->speed].rate; | ||
| 484 | setup->clock_src = clk_get_rate(i2c_dev->clk); | ||
| 485 | |||
| 486 | if (!setup->clock_src) { | ||
| 487 | dev_err(i2c_dev->dev, "clock rate is 0\n"); | ||
| 488 | return -EINVAL; | ||
| 489 | } | ||
| 490 | |||
| 491 | do { | ||
| 492 | ret = stm32f7_i2c_compute_timing(i2c_dev, setup, | ||
| 493 | &i2c_dev->timing); | ||
| 494 | if (ret) { | ||
| 495 | dev_err(i2c_dev->dev, | ||
| 496 | "failed to compute I2C timings.\n"); | ||
| 497 | if (i2c_dev->speed > STM32_I2C_SPEED_STANDARD) { | ||
| 498 | i2c_dev->speed--; | ||
| 499 | setup->speed = i2c_dev->speed; | ||
| 500 | setup->speed_freq = | ||
| 501 | i2c_specs[setup->speed].rate; | ||
| 502 | dev_warn(i2c_dev->dev, | ||
| 503 | "downgrade I2C Speed Freq to (%i)\n", | ||
| 504 | i2c_specs[setup->speed].rate); | ||
| 505 | } else { | ||
| 506 | break; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | } while (ret); | ||
| 510 | |||
| 511 | if (ret) { | ||
| 512 | dev_err(i2c_dev->dev, "Impossible to compute I2C timings.\n"); | ||
| 513 | return ret; | ||
| 514 | } | ||
| 515 | |||
| 516 | dev_dbg(i2c_dev->dev, "I2C Speed(%i), Freq(%i), Clk Source(%i)\n", | ||
| 517 | setup->speed, setup->speed_freq, setup->clock_src); | ||
| 518 | dev_dbg(i2c_dev->dev, "I2C Rise(%i) and Fall(%i) Time\n", | ||
| 519 | setup->rise_time, setup->fall_time); | ||
| 520 | dev_dbg(i2c_dev->dev, "I2C Analog Filter(%s), DNF(%i)\n", | ||
| 521 | (setup->analog_filter ? "On" : "Off"), setup->dnf); | ||
| 522 | |||
| 523 | return 0; | ||
| 524 | } | ||
| 525 | |||
| 526 | static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev) | ||
| 527 | { | ||
| 528 | struct stm32f7_i2c_timings *t = &i2c_dev->timing; | ||
| 529 | u32 timing = 0; | ||
| 530 | |||
| 531 | /* Timing settings */ | ||
| 532 | timing |= STM32F7_I2C_TIMINGR_PRESC(t->presc); | ||
| 533 | timing |= STM32F7_I2C_TIMINGR_SCLDEL(t->scldel); | ||
| 534 | timing |= STM32F7_I2C_TIMINGR_SDADEL(t->sdadel); | ||
| 535 | timing |= STM32F7_I2C_TIMINGR_SCLH(t->sclh); | ||
| 536 | timing |= STM32F7_I2C_TIMINGR_SCLL(t->scll); | ||
| 537 | writel_relaxed(timing, i2c_dev->base + STM32F7_I2C_TIMINGR); | ||
| 538 | |||
| 539 | /* Enable I2C */ | ||
| 540 | if (i2c_dev->setup->analog_filter) | ||
| 541 | stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, | ||
| 542 | STM32F7_I2C_CR1_ANFOFF); | ||
| 543 | else | ||
| 544 | stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, | ||
| 545 | STM32F7_I2C_CR1_ANFOFF); | ||
| 546 | stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, | ||
| 547 | STM32F7_I2C_CR1_PE); | ||
| 548 | } | ||
| 549 | |||
| 550 | static void stm32f7_i2c_write_tx_data(struct stm32f7_i2c_dev *i2c_dev) | ||
| 551 | { | ||
| 552 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 553 | void __iomem *base = i2c_dev->base; | ||
| 554 | |||
| 555 | if (f7_msg->count) { | ||
| 556 | writeb_relaxed(*f7_msg->buf++, base + STM32F7_I2C_TXDR); | ||
| 557 | f7_msg->count--; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | |||
| 561 | static void stm32f7_i2c_read_rx_data(struct stm32f7_i2c_dev *i2c_dev) | ||
| 562 | { | ||
| 563 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 564 | void __iomem *base = i2c_dev->base; | ||
| 565 | |||
| 566 | if (f7_msg->count) { | ||
| 567 | *f7_msg->buf++ = readb_relaxed(base + STM32F7_I2C_RXDR); | ||
| 568 | f7_msg->count--; | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev) | ||
| 573 | { | ||
| 574 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 575 | u32 cr2; | ||
| 576 | |||
| 577 | cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2); | ||
| 578 | |||
| 579 | cr2 &= ~STM32F7_I2C_CR2_NBYTES_MASK; | ||
| 580 | if (f7_msg->count > STM32F7_I2C_MAX_LEN) { | ||
| 581 | cr2 |= STM32F7_I2C_CR2_NBYTES(STM32F7_I2C_MAX_LEN); | ||
| 582 | } else { | ||
| 583 | cr2 &= ~STM32F7_I2C_CR2_RELOAD; | ||
| 584 | cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count); | ||
| 585 | } | ||
| 586 | |||
| 587 | writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2); | ||
| 588 | } | ||
| 589 | |||
| 590 | static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev) | ||
| 591 | { | ||
| 592 | u32 status; | ||
| 593 | int ret; | ||
| 594 | |||
| 595 | ret = readl_relaxed_poll_timeout(i2c_dev->base + STM32F7_I2C_ISR, | ||
| 596 | status, | ||
| 597 | !(status & STM32F7_I2C_ISR_BUSY), | ||
| 598 | 10, 1000); | ||
| 599 | if (ret) { | ||
| 600 | dev_dbg(i2c_dev->dev, "bus busy\n"); | ||
| 601 | ret = -EBUSY; | ||
| 602 | } | ||
| 603 | |||
| 604 | return ret; | ||
| 605 | } | ||
| 606 | |||
| 607 | static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, | ||
| 608 | struct i2c_msg *msg) | ||
| 609 | { | ||
| 610 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 611 | void __iomem *base = i2c_dev->base; | ||
| 612 | u32 cr1, cr2; | ||
| 613 | |||
| 614 | f7_msg->addr = msg->addr; | ||
| 615 | f7_msg->buf = msg->buf; | ||
| 616 | f7_msg->count = msg->len; | ||
| 617 | f7_msg->result = 0; | ||
| 618 | f7_msg->stop = (i2c_dev->msg_id >= i2c_dev->msg_num - 1); | ||
| 619 | |||
| 620 | reinit_completion(&i2c_dev->complete); | ||
| 621 | |||
| 622 | cr1 = readl_relaxed(base + STM32F7_I2C_CR1); | ||
| 623 | cr2 = readl_relaxed(base + STM32F7_I2C_CR2); | ||
| 624 | |||
| 625 | /* Set transfer direction */ | ||
| 626 | cr2 &= ~STM32F7_I2C_CR2_RD_WRN; | ||
| 627 | if (msg->flags & I2C_M_RD) | ||
| 628 | cr2 |= STM32F7_I2C_CR2_RD_WRN; | ||
| 629 | |||
| 630 | /* Set slave address */ | ||
| 631 | cr2 &= ~STM32F7_I2C_CR2_SADD7_MASK; | ||
| 632 | cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr); | ||
| 633 | |||
| 634 | /* Set nb bytes to transfer and reload if needed */ | ||
| 635 | cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD); | ||
| 636 | if (f7_msg->count > STM32F7_I2C_MAX_LEN) { | ||
| 637 | cr2 |= STM32F7_I2C_CR2_NBYTES(STM32F7_I2C_MAX_LEN); | ||
| 638 | cr2 |= STM32F7_I2C_CR2_RELOAD; | ||
| 639 | } else { | ||
| 640 | cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count); | ||
| 641 | } | ||
| 642 | |||
| 643 | /* Enable NACK, STOP, error and transfer complete interrupts */ | ||
| 644 | cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE | | ||
| 645 | STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE; | ||
| 646 | |||
| 647 | /* Clear TX/RX interrupt */ | ||
| 648 | cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE); | ||
| 649 | |||
| 650 | /* Enable RX/TX interrupt according to msg direction */ | ||
| 651 | if (msg->flags & I2C_M_RD) | ||
| 652 | cr1 |= STM32F7_I2C_CR1_RXIE; | ||
| 653 | else | ||
| 654 | cr1 |= STM32F7_I2C_CR1_TXIE; | ||
| 655 | |||
| 656 | /* Configure Start/Repeated Start */ | ||
| 657 | cr2 |= STM32F7_I2C_CR2_START; | ||
| 658 | |||
| 659 | /* Write configurations registers */ | ||
| 660 | writel_relaxed(cr1, base + STM32F7_I2C_CR1); | ||
| 661 | writel_relaxed(cr2, base + STM32F7_I2C_CR2); | ||
| 662 | } | ||
| 663 | |||
| 664 | static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask) | ||
| 665 | { | ||
| 666 | stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask); | ||
| 667 | } | ||
| 668 | |||
| 669 | static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) | ||
| 670 | { | ||
| 671 | struct stm32f7_i2c_dev *i2c_dev = data; | ||
| 672 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 673 | void __iomem *base = i2c_dev->base; | ||
| 674 | u32 status, mask; | ||
| 675 | |||
| 676 | status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); | ||
| 677 | |||
| 678 | /* Tx empty */ | ||
| 679 | if (status & STM32F7_I2C_ISR_TXIS) | ||
| 680 | stm32f7_i2c_write_tx_data(i2c_dev); | ||
| 681 | |||
| 682 | /* RX not empty */ | ||
| 683 | if (status & STM32F7_I2C_ISR_RXNE) | ||
| 684 | stm32f7_i2c_read_rx_data(i2c_dev); | ||
| 685 | |||
| 686 | /* NACK received */ | ||
| 687 | if (status & STM32F7_I2C_ISR_NACKF) { | ||
| 688 | dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__); | ||
| 689 | writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); | ||
| 690 | f7_msg->result = -ENXIO; | ||
| 691 | } | ||
| 692 | |||
| 693 | /* STOP detection flag */ | ||
| 694 | if (status & STM32F7_I2C_ISR_STOPF) { | ||
| 695 | /* Disable interrupts */ | ||
| 696 | stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); | ||
| 697 | |||
| 698 | /* Clear STOP flag */ | ||
| 699 | writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); | ||
| 700 | |||
| 701 | complete(&i2c_dev->complete); | ||
| 702 | } | ||
| 703 | |||
| 704 | /* Transfer complete */ | ||
| 705 | if (status & STM32F7_I2C_ISR_TC) { | ||
| 706 | if (f7_msg->stop) { | ||
| 707 | mask = STM32F7_I2C_CR2_STOP; | ||
| 708 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); | ||
| 709 | } else { | ||
| 710 | i2c_dev->msg_id++; | ||
| 711 | i2c_dev->msg++; | ||
| 712 | stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 716 | /* | ||
| 717 | * Transfer Complete Reload: 255 data bytes have been transferred | ||
| 718 | * We have to prepare the I2C controller to transfer the remaining | ||
| 719 | * data. | ||
| 720 | */ | ||
| 721 | if (status & STM32F7_I2C_ISR_TCR) | ||
| 722 | stm32f7_i2c_reload(i2c_dev); | ||
| 723 | |||
| 724 | return IRQ_HANDLED; | ||
| 725 | } | ||
| 726 | |||
| 727 | static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) | ||
| 728 | { | ||
| 729 | struct stm32f7_i2c_dev *i2c_dev = data; | ||
| 730 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 731 | void __iomem *base = i2c_dev->base; | ||
| 732 | struct device *dev = i2c_dev->dev; | ||
| 733 | u32 status; | ||
| 734 | |||
| 735 | status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); | ||
| 736 | |||
| 737 | /* Bus error */ | ||
| 738 | if (status & STM32F7_I2C_ISR_BERR) { | ||
| 739 | dev_err(dev, "<%s>: Bus error\n", __func__); | ||
| 740 | writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR); | ||
| 741 | f7_msg->result = -EIO; | ||
| 742 | } | ||
| 743 | |||
| 744 | /* Arbitration loss */ | ||
| 745 | if (status & STM32F7_I2C_ISR_ARLO) { | ||
| 746 | dev_dbg(dev, "<%s>: Arbitration loss\n", __func__); | ||
| 747 | writel_relaxed(STM32F7_I2C_ICR_ARLOCF, base + STM32F7_I2C_ICR); | ||
| 748 | f7_msg->result = -EAGAIN; | ||
| 749 | } | ||
| 750 | |||
| 751 | stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); | ||
| 752 | |||
| 753 | complete(&i2c_dev->complete); | ||
| 754 | |||
| 755 | return IRQ_HANDLED; | ||
| 756 | } | ||
| 757 | |||
| 758 | static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
| 759 | struct i2c_msg msgs[], int num) | ||
| 760 | { | ||
| 761 | struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap); | ||
| 762 | struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; | ||
| 763 | unsigned long time_left; | ||
| 764 | int ret; | ||
| 765 | |||
| 766 | i2c_dev->msg = msgs; | ||
| 767 | i2c_dev->msg_num = num; | ||
| 768 | i2c_dev->msg_id = 0; | ||
| 769 | |||
| 770 | ret = clk_enable(i2c_dev->clk); | ||
| 771 | if (ret) { | ||
| 772 | dev_err(i2c_dev->dev, "Failed to enable clock\n"); | ||
| 773 | return ret; | ||
| 774 | } | ||
| 775 | |||
| 776 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); | ||
| 777 | if (ret) | ||
| 778 | goto clk_free; | ||
| 779 | |||
| 780 | stm32f7_i2c_xfer_msg(i2c_dev, msgs); | ||
| 781 | |||
| 782 | time_left = wait_for_completion_timeout(&i2c_dev->complete, | ||
| 783 | i2c_dev->adap.timeout); | ||
| 784 | ret = f7_msg->result; | ||
| 785 | |||
| 786 | if (!time_left) { | ||
| 787 | dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", | ||
| 788 | i2c_dev->msg->addr); | ||
| 789 | ret = -ETIMEDOUT; | ||
| 790 | } | ||
| 791 | |||
| 792 | clk_free: | ||
| 793 | clk_disable(i2c_dev->clk); | ||
| 794 | |||
| 795 | return (ret < 0) ? ret : num; | ||
| 796 | } | ||
| 797 | |||
| 798 | static u32 stm32f7_i2c_func(struct i2c_adapter *adap) | ||
| 799 | { | ||
| 800 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
| 801 | } | ||
| 802 | |||
| 803 | static struct i2c_algorithm stm32f7_i2c_algo = { | ||
| 804 | .master_xfer = stm32f7_i2c_xfer, | ||
| 805 | .functionality = stm32f7_i2c_func, | ||
| 806 | }; | ||
| 807 | |||
| 808 | static int stm32f7_i2c_probe(struct platform_device *pdev) | ||
| 809 | { | ||
| 810 | struct device_node *np = pdev->dev.of_node; | ||
| 811 | struct stm32f7_i2c_dev *i2c_dev; | ||
| 812 | const struct stm32f7_i2c_setup *setup; | ||
| 813 | struct resource *res; | ||
| 814 | u32 irq_error, irq_event, clk_rate, rise_time, fall_time; | ||
| 815 | struct i2c_adapter *adap; | ||
| 816 | struct reset_control *rst; | ||
| 817 | int ret; | ||
| 818 | |||
| 819 | i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); | ||
| 820 | if (!i2c_dev) | ||
| 821 | return -ENOMEM; | ||
| 822 | |||
| 823 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 824 | i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 825 | if (IS_ERR(i2c_dev->base)) | ||
| 826 | return PTR_ERR(i2c_dev->base); | ||
| 827 | |||
| 828 | irq_event = irq_of_parse_and_map(np, 0); | ||
| 829 | if (!irq_event) { | ||
| 830 | dev_err(&pdev->dev, "IRQ event missing or invalid\n"); | ||
| 831 | return -EINVAL; | ||
| 832 | } | ||
| 833 | |||
| 834 | irq_error = irq_of_parse_and_map(np, 1); | ||
| 835 | if (!irq_error) { | ||
| 836 | dev_err(&pdev->dev, "IRQ error missing or invalid\n"); | ||
| 837 | return -EINVAL; | ||
| 838 | } | ||
| 839 | |||
| 840 | i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 841 | if (IS_ERR(i2c_dev->clk)) { | ||
| 842 | dev_err(&pdev->dev, "Error: Missing controller clock\n"); | ||
| 843 | return PTR_ERR(i2c_dev->clk); | ||
| 844 | } | ||
| 845 | ret = clk_prepare_enable(i2c_dev->clk); | ||
| 846 | if (ret) { | ||
| 847 | dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); | ||
| 848 | return ret; | ||
| 849 | } | ||
| 850 | |||
| 851 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; | ||
| 852 | ret = device_property_read_u32(&pdev->dev, "clock-frequency", | ||
| 853 | &clk_rate); | ||
| 854 | if (!ret && clk_rate >= 1000000) | ||
| 855 | i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; | ||
| 856 | else if (!ret && clk_rate >= 400000) | ||
| 857 | i2c_dev->speed = STM32_I2C_SPEED_FAST; | ||
| 858 | else if (!ret && clk_rate >= 100000) | ||
| 859 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; | ||
| 860 | |||
| 861 | rst = devm_reset_control_get(&pdev->dev, NULL); | ||
| 862 | if (IS_ERR(rst)) { | ||
| 863 | dev_err(&pdev->dev, "Error: Missing controller reset\n"); | ||
| 864 | ret = PTR_ERR(rst); | ||
| 865 | goto clk_free; | ||
| 866 | } | ||
| 867 | reset_control_assert(rst); | ||
| 868 | udelay(2); | ||
| 869 | reset_control_deassert(rst); | ||
| 870 | |||
| 871 | i2c_dev->dev = &pdev->dev; | ||
| 872 | |||
| 873 | ret = devm_request_irq(&pdev->dev, irq_event, stm32f7_i2c_isr_event, 0, | ||
| 874 | pdev->name, i2c_dev); | ||
| 875 | if (ret) { | ||
| 876 | dev_err(&pdev->dev, "Failed to request irq event %i\n", | ||
| 877 | irq_event); | ||
| 878 | goto clk_free; | ||
| 879 | } | ||
| 880 | |||
| 881 | ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, | ||
| 882 | pdev->name, i2c_dev); | ||
| 883 | if (ret) { | ||
| 884 | dev_err(&pdev->dev, "Failed to request irq error %i\n", | ||
| 885 | irq_error); | ||
| 886 | goto clk_free; | ||
| 887 | } | ||
| 888 | |||
| 889 | setup = of_device_get_match_data(&pdev->dev); | ||
| 890 | i2c_dev->setup->rise_time = setup->rise_time; | ||
| 891 | i2c_dev->setup->fall_time = setup->fall_time; | ||
| 892 | i2c_dev->setup->dnf = setup->dnf; | ||
| 893 | i2c_dev->setup->analog_filter = setup->analog_filter; | ||
| 894 | |||
| 895 | ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", | ||
| 896 | &rise_time); | ||
| 897 | if (!ret) | ||
| 898 | i2c_dev->setup->rise_time = rise_time; | ||
| 899 | |||
| 900 | ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", | ||
| 901 | &fall_time); | ||
| 902 | if (!ret) | ||
| 903 | i2c_dev->setup->fall_time = fall_time; | ||
| 904 | |||
| 905 | ret = stm32f7_i2c_setup_timing(i2c_dev, i2c_dev->setup); | ||
| 906 | if (ret) | ||
| 907 | goto clk_free; | ||
| 908 | |||
| 909 | stm32f7_i2c_hw_config(i2c_dev); | ||
| 910 | |||
| 911 | adap = &i2c_dev->adap; | ||
| 912 | i2c_set_adapdata(adap, i2c_dev); | ||
| 913 | snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", | ||
| 914 | &res->start); | ||
| 915 | adap->owner = THIS_MODULE; | ||
| 916 | adap->timeout = 2 * HZ; | ||
| 917 | adap->retries = 3; | ||
| 918 | adap->algo = &stm32f7_i2c_algo; | ||
| 919 | adap->dev.parent = &pdev->dev; | ||
| 920 | adap->dev.of_node = pdev->dev.of_node; | ||
| 921 | |||
| 922 | init_completion(&i2c_dev->complete); | ||
| 923 | |||
| 924 | ret = i2c_add_adapter(adap); | ||
| 925 | if (ret) | ||
| 926 | goto clk_free; | ||
| 927 | |||
| 928 | platform_set_drvdata(pdev, i2c_dev); | ||
| 929 | |||
| 930 | clk_disable(i2c_dev->clk); | ||
| 931 | |||
| 932 | dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); | ||
| 933 | |||
| 934 | return 0; | ||
| 935 | |||
| 936 | clk_free: | ||
| 937 | clk_disable_unprepare(i2c_dev->clk); | ||
| 938 | |||
| 939 | return ret; | ||
| 940 | } | ||
| 941 | |||
| 942 | static int stm32f7_i2c_remove(struct platform_device *pdev) | ||
| 943 | { | ||
| 944 | struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); | ||
| 945 | |||
| 946 | i2c_del_adapter(&i2c_dev->adap); | ||
| 947 | |||
| 948 | clk_unprepare(i2c_dev->clk); | ||
| 949 | |||
| 950 | return 0; | ||
| 951 | } | ||
| 952 | |||
| 953 | static const struct of_device_id stm32f7_i2c_match[] = { | ||
| 954 | { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, | ||
| 955 | {}, | ||
| 956 | }; | ||
| 957 | MODULE_DEVICE_TABLE(of, stm32f7_i2c_match); | ||
| 958 | |||
| 959 | static struct platform_driver stm32f7_i2c_driver = { | ||
| 960 | .driver = { | ||
| 961 | .name = "stm32f7-i2c", | ||
| 962 | .of_match_table = stm32f7_i2c_match, | ||
| 963 | }, | ||
| 964 | .probe = stm32f7_i2c_probe, | ||
| 965 | .remove = stm32f7_i2c_remove, | ||
| 966 | }; | ||
| 967 | |||
| 968 | module_platform_driver(stm32f7_i2c_driver); | ||
| 969 | |||
| 970 | MODULE_AUTHOR("M'boumba Cedric Madianga <cedric.madianga@gmail.com>"); | ||
| 971 | MODULE_DESCRIPTION("STMicroelectronics STM32F7 I2C driver"); | ||
| 972 | MODULE_LICENSE("GPL v2"); | ||
