aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/Kconfig13
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-sun6i-p2wi.c345
3 files changed, 359 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 759ee30dc63a..9f7d5859cf65 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -774,6 +774,19 @@ config I2C_STU300
774 This driver can also be built as a module. If so, the module 774 This driver can also be built as a module. If so, the module
775 will be called i2c-stu300. 775 will be called i2c-stu300.
776 776
777config I2C_SUN6I_P2WI
778 tristate "Allwinner sun6i internal P2WI controller"
779 depends on RESET_CONTROLLER
780 depends on MACH_SUN6I || COMPILE_TEST
781 help
782 If you say yes to this option, support will be included for the
783 P2WI (Push/Pull 2 Wire Interface) controller embedded in some sunxi
784 SOCs.
785 The P2WI looks like an SMBus controller (which supports only byte
786 accesses), except that it only supports one slave device.
787 This interface is used to connect to specific PMIC devices (like the
788 AXP221).
789
777config I2C_TEGRA 790config I2C_TEGRA
778 tristate "NVIDIA Tegra internal I2C controller" 791 tristate "NVIDIA Tegra internal I2C controller"
779 depends on ARCH_TEGRA 792 depends on ARCH_TEGRA
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 8ac83374cf7e..dd9a7f8e873f 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
75obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o 75obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
76obj-$(CONFIG_I2C_ST) += i2c-st.o 76obj-$(CONFIG_I2C_ST) += i2c-st.o
77obj-$(CONFIG_I2C_STU300) += i2c-stu300.o 77obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
78obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o
78obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o 79obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
79obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o 80obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
80obj-$(CONFIG_I2C_WMT) += i2c-wmt.o 81obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
new file mode 100644
index 000000000000..f1d3e6f1a409
--- /dev/null
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -0,0 +1,345 @@
1/*
2 * P2WI (Push-Pull Two Wire Interface) bus driver.
3 *
4 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * The P2WI controller looks like an SMBus controller which only supports byte
11 * data transfers. But, it differs from standard SMBus protocol on several
12 * aspects:
13 * - it supports only one slave device, and thus drop the address field
14 * - it adds a parity bit every 8bits of data
15 * - only one read access is required to read a byte (instead of a write
16 * followed by a read access in standard SMBus protocol)
17 * - there's no Ack bit after each byte transfer
18 *
19 * This means this bus cannot be used to interface with standard SMBus
20 * devices (the only known device to support this interface is the AXP221
21 * PMIC).
22 *
23 */
24#include <linux/clk.h>
25#include <linux/module.h>
26#include <linux/i2c.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/module.h>
30#include <linux/of.h>
31#include <linux/platform_device.h>
32#include <linux/reset.h>
33
34
35/* P2WI registers */
36#define P2WI_CTRL 0x0
37#define P2WI_CCR 0x4
38#define P2WI_INTE 0x8
39#define P2WI_INTS 0xc
40#define P2WI_DADDR0 0x10
41#define P2WI_DADDR1 0x14
42#define P2WI_DLEN 0x18
43#define P2WI_DATA0 0x1c
44#define P2WI_DATA1 0x20
45#define P2WI_LCR 0x24
46#define P2WI_PMCR 0x28
47
48/* CTRL fields */
49#define P2WI_CTRL_START_TRANS BIT(7)
50#define P2WI_CTRL_ABORT_TRANS BIT(6)
51#define P2WI_CTRL_GLOBAL_INT_ENB BIT(1)
52#define P2WI_CTRL_SOFT_RST BIT(0)
53
54/* CLK CTRL fields */
55#define P2WI_CCR_SDA_OUT_DELAY(v) (((v) & 0x7) << 8)
56#define P2WI_CCR_MAX_CLK_DIV 0xff
57#define P2WI_CCR_CLK_DIV(v) ((v) & P2WI_CCR_MAX_CLK_DIV)
58
59/* STATUS fields */
60#define P2WI_INTS_TRANS_ERR_ID(v) (((v) >> 8) & 0xff)
61#define P2WI_INTS_LOAD_BSY BIT(2)
62#define P2WI_INTS_TRANS_ERR BIT(1)
63#define P2WI_INTS_TRANS_OVER BIT(0)
64
65/* DATA LENGTH fields*/
66#define P2WI_DLEN_READ BIT(4)
67#define P2WI_DLEN_DATA_LENGTH(v) ((v - 1) & 0x7)
68
69/* LINE CTRL fields*/
70#define P2WI_LCR_SCL_STATE BIT(5)
71#define P2WI_LCR_SDA_STATE BIT(4)
72#define P2WI_LCR_SCL_CTL BIT(3)
73#define P2WI_LCR_SCL_CTL_EN BIT(2)
74#define P2WI_LCR_SDA_CTL BIT(1)
75#define P2WI_LCR_SDA_CTL_EN BIT(0)
76
77/* PMU MODE CTRL fields */
78#define P2WI_PMCR_PMU_INIT_SEND BIT(31)
79#define P2WI_PMCR_PMU_INIT_DATA(v) (((v) & 0xff) << 16)
80#define P2WI_PMCR_PMU_MODE_REG(v) (((v) & 0xff) << 8)
81#define P2WI_PMCR_PMU_DEV_ADDR(v) ((v) & 0xff)
82
83#define P2WI_MAX_FREQ 6000000
84
85struct p2wi {
86 struct i2c_adapter adapter;
87 struct completion complete;
88 unsigned int status;
89 void __iomem *regs;
90 struct clk *clk;
91 struct reset_control *rstc;
92 int slave_addr;
93};
94
95static irqreturn_t p2wi_interrupt(int irq, void *dev_id)
96{
97 struct p2wi *p2wi = dev_id;
98 unsigned long status;
99
100 status = readl(p2wi->regs + P2WI_INTS);
101 p2wi->status = status;
102
103 /* Clear interrupts */
104 status &= (P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR |
105 P2WI_INTS_TRANS_OVER);
106 writel(status, p2wi->regs + P2WI_INTS);
107
108 complete(&p2wi->complete);
109
110 return IRQ_HANDLED;
111}
112
113static u32 p2wi_functionality(struct i2c_adapter *adap)
114{
115 return I2C_FUNC_SMBUS_BYTE_DATA;
116}
117
118static int p2wi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
119 unsigned short flags, char read_write,
120 u8 command, int size, union i2c_smbus_data *data)
121{
122 struct p2wi *p2wi = i2c_get_adapdata(adap);
123 unsigned long dlen = P2WI_DLEN_DATA_LENGTH(1);
124
125 if (p2wi->slave_addr >= 0 && addr != p2wi->slave_addr) {
126 dev_err(&adap->dev, "invalid P2WI address\n");
127 return -EINVAL;
128 }
129
130 if (!data)
131 return -EINVAL;
132
133 writel(command, p2wi->regs + P2WI_DADDR0);
134
135 if (read_write == I2C_SMBUS_READ)
136 dlen |= P2WI_DLEN_READ;
137 else
138 writel(data->byte, p2wi->regs + P2WI_DATA0);
139
140 writel(dlen, p2wi->regs + P2WI_DLEN);
141
142 if (readl(p2wi->regs + P2WI_CTRL) & P2WI_CTRL_START_TRANS) {
143 dev_err(&adap->dev, "P2WI bus busy\n");
144 return -EBUSY;
145 }
146
147 reinit_completion(&p2wi->complete);
148
149 writel(P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR | P2WI_INTS_TRANS_OVER,
150 p2wi->regs + P2WI_INTE);
151
152 writel(P2WI_CTRL_START_TRANS | P2WI_CTRL_GLOBAL_INT_ENB,
153 p2wi->regs + P2WI_CTRL);
154
155 wait_for_completion(&p2wi->complete);
156