diff options
| author | Wolfram Sang <wsa@sang-engineering.com> | 2013-12-20 13:08:50 -0500 |
|---|---|---|
| committer | Wolfram Sang <wsa@the-dreams.de> | 2014-01-02 09:56:52 -0500 |
| commit | 310c18a414504e42dbeb96263bc81ca865c7c3e5 (patch) | |
| tree | 632df5415bc4f96e8b75a7496ecbb9ee14f7054c | |
| parent | 802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff) | |
i2c: riic: add driver
Tested with a r7s72100 genmai board acessing an eeprom.
Signed-off-by: Wolfram Sang <wsa@sang-engineering.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-riic.txt | 29 | ||||
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-riic.c | 427 |
4 files changed, 467 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-riic.txt b/Documentation/devicetree/bindings/i2c/i2c-riic.txt new file mode 100644 index 000000000000..0bcc4716c319 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-riic.txt | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | Device tree configuration for Renesas RIIC driver | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : "renesas,riic-<soctype>". "renesas,riic-rz" as fallback | ||
| 5 | - reg : address start and address range size of device | ||
| 6 | - interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI) | ||
| 7 | - clock-frequency : frequency of bus clock in Hz | ||
| 8 | - #address-cells : should be <1> | ||
| 9 | - #size-cells : should be <0> | ||
| 10 | |||
| 11 | Pinctrl properties might be needed, too. See there. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | i2c0: i2c@fcfee000 { | ||
| 16 | compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; | ||
| 17 | reg = <0xfcfee000 0x44>; | ||
| 18 | interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, | ||
| 19 | <0 158 IRQ_TYPE_EDGE_RISING>, | ||
| 20 | <0 159 IRQ_TYPE_EDGE_RISING>, | ||
| 21 | <0 160 IRQ_TYPE_LEVEL_HIGH>, | ||
| 22 | <0 161 IRQ_TYPE_LEVEL_HIGH>, | ||
| 23 | <0 162 IRQ_TYPE_LEVEL_HIGH>, | ||
| 24 | <0 163 IRQ_TYPE_LEVEL_HIGH>, | ||
| 25 | <0 164 IRQ_TYPE_LEVEL_HIGH>; | ||
| 26 | clock-frequency = <100000>; | ||
| 27 | #address-cells = <1>; | ||
| 28 | #size-cells = <0>; | ||
| 29 | }; | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3b26129f6055..8e8332d5ac73 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -648,6 +648,16 @@ config I2C_PXA_SLAVE | |||
| 648 | is necessary for systems where the PXA may be a target on the | 648 | is necessary for systems where the PXA may be a target on the |
| 649 | I2C bus. | 649 | I2C bus. |
| 650 | 650 | ||
| 651 | config I2C_RIIC | ||
| 652 | tristate "Renesas RIIC adapter" | ||
| 653 | depends on ARCH_SHMOBILE || COMPILE_TEST | ||
| 654 | help | ||
| 655 | If you say yes to this option, support will be included for the | ||
| 656 | Renesas RIIC I2C interface. | ||
| 657 | |||
| 658 | This driver can also be built as a module. If so, the module | ||
| 659 | will be called i2c-riic. | ||
| 660 | |||
| 651 | config HAVE_S3C2410_I2C | 661 | config HAVE_S3C2410_I2C |
| 652 | bool | 662 | bool |
| 653 | help | 663 | help |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index c73eb0ea788e..dca041b1b99d 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
| @@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o | |||
| 63 | obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o | 63 | obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o |
| 64 | obj-$(CONFIG_I2C_PXA) += i2c-pxa.o | 64 | obj-$(CONFIG_I2C_PXA) += i2c-pxa.o |
| 65 | obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o | 65 | obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o |
| 66 | obj-$(CONFIG_I2C_RIIC) += i2c-riic.o | ||
| 66 | obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o | 67 | obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o |
| 67 | obj-$(CONFIG_I2C_S6000) += i2c-s6000.o | 68 | obj-$(CONFIG_I2C_S6000) += i2c-s6000.o |
| 68 | obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o | 69 | obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o |
diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c new file mode 100644 index 000000000000..9e1f8bacfb39 --- /dev/null +++ b/drivers/i2c/busses/i2c-riic.c | |||
| @@ -0,0 +1,427 @@ | |||
| 1 | /* | ||
| 2 | * Renesas RIIC driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com> | ||
| 5 | * Copyright (C) 2013 Renesas Solutions Corp. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This i2c core has a lot of interrupts, namely 8. We use their chaining as | ||
| 14 | * some kind of state machine. | ||
| 15 | * | ||
| 16 | * 1) The main xfer routine kicks off a transmission by putting the start bit | ||
| 17 | * (or repeated start) on the bus and enabling the transmit interrupt (TIE) | ||
| 18 | * since we need to send the slave address + RW bit in every case. | ||
| 19 | * | ||
| 20 | * 2) TIE sends slave address + RW bit and selects how to continue. | ||
| 21 | * | ||
| 22 | * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we | ||
| 23 | * are done, we switch over to the transmission done interrupt (TEIE) and mark | ||
| 24 | * the message as completed (includes sending STOP) there. | ||
| 25 | * | ||
| 26 | * 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is | ||
| 27 | * needed to start clocking, then we keep receiving until we are done. Note | ||
| 28 | * that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by | ||
| 29 | * writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a | ||
| 30 | * message to create the final NACK as sketched in the datasheet. This caused | ||
| 31 | * some subtle races (when byte n was processed and byte n+1 was already | ||
| 32 | * waiting), though, and I started with the safe approach. | ||
| 33 | * | ||
| 34 | * 4) If we got a NACK somewhere, we flag the error and stop the transmission | ||
| 35 | * via NAKIE. | ||
| 36 | * | ||
| 37 | * Also check the comments in the interrupt routines for some gory details. | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include <linux/clk.h> | ||
| 41 | #include <linux/completion.h> | ||
| 42 | #include <linux/err.h> | ||
| 43 | #include <linux/i2c.h> | ||
| 44 | #include <linux/interrupt.h> | ||
| 45 | #include <linux/io.h> | ||
| 46 | #include <linux/module.h> | ||
| 47 | #include <linux/of.h> | ||
| 48 | #include <linux/platform_device.h> | ||
| 49 | |||
| 50 | #define RIIC_ICCR1 0x00 | ||
| 51 | #define RIIC_ICCR2 0x04 | ||
| 52 | #define RIIC_ICMR1 0x08 | ||
| 53 | #define RIIC_ICMR3 0x10 | ||
| 54 | #define RIIC_ICSER 0x18 | ||
| 55 | #define RIIC_ICIER 0x1c | ||
| 56 | #define RIIC_ICSR2 0x24 | ||
| 57 | #define RIIC_ICBRL 0x34 | ||
| 58 | #define RIIC_ICBRH 0x38 | ||
| 59 | #define RIIC_ICDRT 0x3c | ||
| 60 | #define RIIC_ICDRR 0x40 | ||
| 61 | |||
| 62 | #define ICCR1_ICE 0x80 | ||
| 63 | #define ICCR1_IICRST 0x40 | ||
| 64 | #define ICCR1_SOWP 0x10 | ||
| 65 | |||
| 66 | #define ICCR2_BBSY 0x80 | ||
| 67 | #define ICCR2_SP 0x08 | ||
| 68 | #define ICCR2_RS 0x04 | ||
| 69 | #define ICCR2_ST 0x02 | ||
| 70 | |||
| 71 | #define ICMR1_CKS_MASK 0x70 | ||
| 72 | #define ICMR1_BCWP 0x08 | ||
| 73 | #define ICMR1_CKS(_x) ((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP) | ||
| 74 | |||
| 75 | #define ICMR3_RDRFS 0x20 | ||
| 76 | #define ICMR3_ACKWP 0x10 | ||
| 77 | #define ICMR3_ACKBT 0x08 | ||
| 78 | |||
| 79 | #define ICIER_TIE 0x80 | ||
| 80 | #define ICIER_TEIE 0x40 | ||
| 81 | #define ICIER_RIE 0x20 | ||
| 82 | #define ICIER_NAKIE 0x10 | ||
| 83 | |||
| 84 | #define ICSR2_NACKF 0x10 | ||
| 85 | |||
| 86 | /* ICBRx (@ PCLK 33MHz) */ | ||
| 87 | #define ICBR_RESERVED 0xe0 /* Should be 1 on writes */ | ||
| 88 | #define ICBRL_SP100K (19 | ICBR_RESERVED) | ||
| 89 | #define ICBRH_SP100K (16 | ICBR_RESERVED) | ||
| 90 | #define ICBRL_SP400K (21 | ICBR_RESERVED) | ||
| 91 | #define ICBRH_SP400K (9 | ICBR_RESERVED) | ||
| 92 | |||
| 93 | #define RIIC_INIT_MSG -1 | ||
| 94 | |||
| 95 | struct riic_dev { | ||
| 96 | void __iomem *base; | ||
| 97 | u8 *buf; | ||
| 98 | struct i2c_msg *msg; | ||
| 99 | int bytes_left; | ||
| 100 | int err; | ||
| 101 | int is_last; | ||
| 102 | struct completion msg_done; | ||
| 103 | struct i2c_adapter adapter; | ||
| 104 | struct clk *clk; | ||
| 105 | }; | ||
| 106 | |||
| 107 | struct riic_irq_desc { | ||
| 108 | int res_num; | ||
| 109 | irq_handler_t isr; | ||
| 110 | char *name; | ||
| 111 | }; | ||
| 112 | |||
| 113 | static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg) | ||
| 114 | { | ||
| 115 | writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg); | ||
| 116 | } | ||
| 117 | |||
| 118 | static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | ||
| 119 | { | ||
| 120 | struct riic_dev *riic = i2c_get_adapdata(adap); | ||
| 121 | unsigned long time_left; | ||
| 122 | int i, ret; | ||
| 123 | u8 start_bit; | ||
