summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorVishwaroop <va@nvidia.com>2018-03-14 07:14:02 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-19 01:43:41 -0400
commitb8df3ffe3be5d85e0b9854818cc089998e08576f (patch)
tree90d1edfb97aa30016277ed4fbcdf626924b500d6 /drivers/i2c
parentb68f1b9eff898a7f521278bdaae067e50fc998c7 (diff)
i2c: tegra-slave: Removed depreciated slave driver
Removed depreciated T186 I2C slave driver. Bug 200368264 Change-Id: Ibedc81df3d0f0f57c7108d208ef5a26a07ecd193 Signed-off-by: Vishwaroop <va@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1675017 Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Venu Byravarasu <vbyravarasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig5
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-t18x-client.c236
-rw-r--r--drivers/i2c/busses/i2c-t18x-slave.c529
-rw-r--r--drivers/i2c/busses/i2c-t18x-slave.h128
-rw-r--r--drivers/i2c/busses/i2c-t18x-slv-common.h27
6 files changed, 0 insertions, 926 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d488b815c..1f93838c2 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -25,11 +25,6 @@ config I2C_BPMP_TEGRA
25 This driver is a downstream version and there is a newer variant 25 This driver is a downstream version and there is a newer variant
26 available in modern kernels. 26 available in modern kernels.
27 27
28config TEGRA_I2CSLV_T186
29 bool "Tegra i2c slave controller driver"
30 default y
31 help
32 Enable on-chip i2c slave controller.
33config I2C_TEGRA_CAMRTC 28config I2C_TEGRA_CAMRTC
34 bool "Tegra I2C Camera RTCPU driver" 29 bool "Tegra I2C Camera RTCPU driver"
35 depends on TEGRA_CAMERA_RTCPU 30 depends on TEGRA_CAMERA_RTCPU
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 15f3d1b2f..c3c28229d 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -2,7 +2,6 @@ obj-$(CONFIG_I2C_TEGRA_VI) += i2c-tegra-vi.o
2#CFLAGS_i2c-bpmp-tegra.o = -Werror 2#CFLAGS_i2c-bpmp-tegra.o = -Werror
3ccflags-y += -I$(srctree.nvidia)/include 3ccflags-y += -I$(srctree.nvidia)/include
4obj-$(CONFIG_I2C_BPMP_TEGRA) += i2c-bpmp-tegra.o 4obj-$(CONFIG_I2C_BPMP_TEGRA) += i2c-bpmp-tegra.o
5obj-$(CONFIG_TEGRA_I2CSLV_T186) += i2c-t18x-slave.o i2c-t18x-client.o
6obj-$(CONFIG_I2C_TEGRA_CAMRTC) += i2c-ivc-single.o i2c-ivc-multi.o i2c-rtcpu.o i2c-rtcpu-clk-config.o 5obj-$(CONFIG_I2C_TEGRA_CAMRTC) += i2c-ivc-single.o i2c-ivc-multi.o i2c-rtcpu.o i2c-rtcpu-clk-config.o
7 6
8ifdef CONFIG_ARCH_TEGRA_19x_SOC 7ifdef CONFIG_ARCH_TEGRA_19x_SOC
diff --git a/drivers/i2c/busses/i2c-t18x-client.c b/drivers/i2c/busses/i2c-t18x-client.c
deleted file mode 100644
index a01bc5f79..000000000
--- a/drivers/i2c/busses/i2c-t18x-client.c
+++ /dev/null
@@ -1,236 +0,0 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15/* #define DEBUG */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/completion.h>
23#include "i2c-t18x-slv-common.h"
24
25struct i2cslv_client {
26 unsigned long addr;
27
28 bool is_7bit_addr;
29
30 bool client_rx_in_prgrs;
31 bool client_tx_in_prgrs;
32
33 unsigned char *rx_buf;
34 unsigned char *tx_buf;
35
36 unsigned int rx_buf_len;
37 unsigned int rx_buf_pos;
38
39 unsigned int tx_buf_len;
40 unsigned int tx_buf_pos;
41 struct completion slave_rx_complete;
42
43 struct i2cslv_client_ops *i2c_clnt_ops;
44} *i2cslv_client;
45
46extern int i2cslv_register_client(struct i2cslv_client_ops *,
47 const unsigned long,
48 bool);
49
50extern void i2cslv_unregister_client(void);
51/* i2cslv_client_read - Controller driver use this callback to send data to
52 * client driver.
53 * This callback executes in interrupt context. DON'T include any sleepable
54 * functions.
55 */
56
57static void i2cslv_client_read(unsigned char wd)
58{
59
60 if (i2cslv_client->rx_buf_pos == MAX_BUFF_SIZE) {
61 pr_err("%s %x\n", __func__, wd);
62 pr_err("rx buffer full");
63 return;
64 }
65
66 i2cslv_client->rx_buf[i2cslv_client->rx_buf_pos++] = wd;
67
68 i2cslv_client->rx_buf_len++;
69
70 pr_debug("%s %x\n", __func__, wd);
71}
72
73/* i2cslv_client_read_end - Controller driver use this callback to pass read
74 * xfer end event to client driver.
75 * This callback executes in interrupt context. DON'T include any sleepable
76 * functions.
77 */
78
79static void i2cslv_client_read_end(void)
80{
81 pr_debug("%s\n", __func__);
82 i2cslv_client->rx_buf_pos = 0;
83 complete(&i2cslv_client->slave_rx_complete);
84}
85
86/* i2cslv_client_write - Controller driver use this callback to get data to
87 * client driver.
88 *
89 * If data is not available in tx buffer, This function returns 0xAA as dummy
90 * data. This callback executes in interrupt context. DON'T include any
91 * sleepable functions.
92 */
93static unsigned char i2cslv_client_write(void)
94{
95 unsigned char dummy_wr = 0xAA;
96 unsigned char udata;
97
98 pr_debug("%s\n", __func__);
99
100 if (i2cslv_client->tx_buf_pos > i2cslv_client->tx_buf_len) {
101 pr_err("tx buffer empty");
102 return dummy_wr;
103 }
104
105 udata = i2cslv_client->tx_buf[i2cslv_client->tx_buf_pos++];
106 return udata;
107}
108
109/* i2cslv_client_write_end - Controller driver use this callback to pass write
110 * xfer end event to client driver.
111 * This callback executes in interrupt context. DON'T include any sleepable
112 * functions.
113 */
114static void i2cslv_client_write_end(void)
115{
116 pr_debug("%s\n", __func__);
117
118 i2cslv_client->tx_buf_pos = 0;
119}
120
121static struct i2cslv_client_ops i2c_clnt_ops = {
122 .slv_sendbyte_to_client = i2cslv_client_read,
123 .slv_sendbyte_end_to_client = i2cslv_client_read_end,
124 .slv_getbyte_from_client = i2cslv_client_write,
125 .slv_getbyte_end_from_client = i2cslv_client_write_end,
126};
127
128inline int tegra_i2cslv_register(const unsigned long i2cslv_addr,
129 bool is_seven_bit)
130{
131 return i2cslv_register_client(&i2c_clnt_ops, i2cslv_addr, is_seven_bit);
132}
133EXPORT_SYMBOL(tegra_i2cslv_register);
134
135inline void tegra_i2cslv_unregister(void)
136{
137 i2cslv_unregister_client();
138}
139EXPORT_SYMBOL(tegra_i2cslv_unregister);
140
141/* tegra_i2cslv_write - To fill the client tx buffer.
142 *
143 * This function is used by the application, to fill the client tx buffer.
144 */
145int tegra_i2cslv_write(const char *wr, const unsigned int len)
146{
147 /* FIXME: Add multiple write support from application */
148 if (!wr || len > MAX_BUFF_SIZE)
149 return -EINVAL;
150
151 memcpy(i2cslv_client->tx_buf, wr, len);
152
153 i2cslv_client->tx_buf_len = len;
154
155 i2cslv_client->tx_buf_pos = 0;
156 return 0;
157}
158EXPORT_SYMBOL(tegra_i2cslv_write);
159
160/* tegra_i2cslv_read - To get the client rx buffer.
161 *
162 * This function is used by the application, to get the client rx buffer.
163 * This function waits for the current slave rx xfer completion.
164 */
165int tegra_i2cslv_read(char *rd, unsigned int len)
166{
167 long ret;
168 if (!rd || len > MAX_BUFF_SIZE)
169 return -EINVAL;
170
171 ret = wait_for_completion_interruptible_timeout(
172 &i2cslv_client->slave_rx_complete,
173 SLAVE_RX_TIMEOUT);
174
175 if (ret <= 0) {
176 pr_err("Timeout waiting for RX end of xfer\n");
177 return -EIO;
178 }
179
180 memcpy(rd, i2cslv_client->rx_buf, len);
181 reinit_completion(&i2cslv_client->slave_rx_complete);
182
183 return len;
184}
185EXPORT_SYMBOL(tegra_i2cslv_read);
186
187static int __init tegra_i2cslv_init_client(void)
188{
189 int ret = 0;
190
191 i2cslv_client = kzalloc(sizeof(*i2cslv_client), GFP_KERNEL);
192 if (!i2cslv_client)
193 return -ENOMEM;
194
195 i2cslv_client->rx_buf = kzalloc(MAX_BUFF_SIZE, GFP_KERNEL);
196 if (!(i2cslv_client->rx_buf))
197 goto err_enmm;
198
199 i2cslv_client->tx_buf = kzalloc(MAX_BUFF_SIZE, GFP_KERNEL);
200 if (!(i2cslv_client->tx_buf))
201 goto err_enmm;
202
203 i2cslv_client->rx_buf_len = 0;
204
205 i2cslv_client->rx_buf_pos = 0;
206
207 i2cslv_client->tx_buf_len = 0;
208
209 i2cslv_client->tx_buf_pos = 0;
210
211 init_completion(&i2cslv_client->slave_rx_complete);
212
213 return ret;
214err_enmm:
215 kfree(i2cslv_client->rx_buf);
216 kfree(i2cslv_client);
217
218 ret = -ENOMEM;
219 pr_err("i2cslv_client alloc error\n");
220 return ret;
221}
222
223static void __exit tegra_i2cslv_exit_client(void)
224{
225 pr_debug("%s\n", __func__);
226
227 kfree(i2cslv_client->rx_buf);
228 kfree(i2cslv_client->tx_buf);
229 kfree(i2cslv_client);
230}
231
232MODULE_AUTHOR("Ankit Gupta <guptaa@nvidia.com>");
233MODULE_DESCRIPTION("NVIDIA i2c slave client module");
234MODULE_LICENSE("GPL v2");
235late_initcall(tegra_i2cslv_init_client);
236module_exit(tegra_i2cslv_exit_client);
diff --git a/drivers/i2c/busses/i2c-t18x-slave.c b/drivers/i2c/busses/i2c-t18x-slave.c
deleted file mode 100644
index eb76fe37d..000000000
--- a/drivers/i2c/busses/i2c-t18x-slave.c
+++ /dev/null
@@ -1,529 +0,0 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/clk.h>
22#include <linux/reset.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/delay.h>
26#include <asm/io.h>
27#include "i2c-t18x-slv-common.h"
28#include "i2c-t18x-slave.h"
29
30static struct i2cslv_cntlr *i2cslv;
31
32#if defined(DEBUG)
33void debug_reg(void)
34{
35 dev_dbg(i2cslv->dev, "I2C_I2C_SL_INT_SOURCE_0 %X\n",
36 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_INT_SOURCE));
37 dev_dbg(i2cslv->dev, "I2C_INTERRUPT_STATUS_REGISTER_0 %X\n",
38 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_STATUS));
39 dev_dbg(i2cslv->dev, "I2C_I2C_SL_STATUS_0 %X\n",
40 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_STATUS));
41 dev_dbg(i2cslv->dev, "I2C_INT_SOURCE %X\n",
42 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_SOURCE));
43 dev_dbg(i2cslv->dev, "I2C_I2C_SL_CNFG_0 %X\n",
44 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_CNFG));
45 dev_dbg(i2cslv->dev, "I2C_SLV_ADDR1 %X\n",
46 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_ADDR1));
47 dev_dbg(i2cslv->dev, "I2C_INTERRUPT_MASK_REGISTER_0 %X\n",
48 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_MASK));
49 dev_dbg(i2cslv->dev, "I2C_I2C_SL_INT_MASK_0 %X\n",
50 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_INT_MASK));
51}
52EXPORT_SYMBOL(debug_reg);
53#endif
54
55/* i2cslv_load_config - To activate the i2c slave configuration
56 *
57 * After configuring I2C slave controller, To activate the configuration,
58 * We need to set I2C_CONFIG_LOAD_SLV bit in I2C_CONFIG_LOAD reg. Once the
59 * configuration is active, HW will clear the bit.
60 * This needs to call after doing all required slave registers configuration.
61 */
62static int i2cslv_load_config(void)
63{
64 int ret = 0;
65 unsigned long i2c_load_config_reg = 0;
66 int i2c_retries = I2C_RETRIES;
67
68 i2c_load_config_reg = tegra_i2cslv_readl(i2cslv, I2C_CONFIG_LOAD);
69 i2c_load_config_reg |= I2C_CONFIG_LOAD_SLV;
70
71 tegra_i2cslv_writel(i2cslv, i2c_load_config_reg, I2C_CONFIG_LOAD);
72
73 do {
74 if (tegra_i2cslv_readl(i2cslv, I2C_CONFIG_LOAD) &
75 I2C_CONFIG_LOAD_SLV)
76 continue;
77 else
78 break;
79 } while (--i2c_retries);
80
81 if (!i2c_retries) {
82 dev_err(i2cslv->dev, "ERR unable to load i2cslv config\n");
83 ret = -1;
84 }
85
86 return ret;
87}
88
89/* handle_slave_rx - To get the data byte fron bus and provide the data to
90 * client driver
91 * After receving master tx event, This function reads the data from bus and
92 * pass it to client driver for processing.
93 * In case of I2C_SLV_END_TRANS interrupt, It clears the interrupts and
94 * notifies the client driver.All this happens in interrupt context only.
95 */
96static void handle_slave_rx(const unsigned long i2c_int_src,
97 const unsigned long i2c_slv_src)
98{
99 unsigned char udata;
100
101 if (i2c_slv_src & I2C_SLV_END_TRANS) {
102 dev_dbg(i2cslv->dev, "End of Transfer\n");
103
104 /* clear the interrupts to release the SCL line */
105 tegra_i2cslv_writel(i2cslv, I2C_SLV_END_TRANS, I2C_SLV_STATUS);
106 tegra_i2cslv_writel(i2cslv, I2C_SLV_SL_IRQ, I2C_SLV_STATUS);
107 goto end_trnsfr;
108 }
109
110 udata = (unsigned char)tegra_i2cslv_readl(i2cslv, I2C_SLV_SLV_RCVD);
111 /* Send the received data to client driver */
112 tegra_i2cslv_sendbyte_to_client(i2cslv, udata);
113 /* clear the interrupt to release the SCL line */
114 tegra_i2cslv_writel(i2cslv, I2C_SLV_SL_IRQ, I2C_SLV_STATUS);
115
116 return;
117
118end_trnsfr:
119 i2cslv->slave_rx_in_progress = false;
120 tegra_i2cslv_sendbyte_end_to_client(i2cslv);
121}
122
123/* handle_slave_tx - To get the data byte fron client driver and send it to
124 * master over bus.
125 * After receving master rx event, This function reads the data from client
126 * driver and pass it to master driver.
127 * In case of I2C_SLV_END_TRANS interrupt, It clears the interrupts and
128 * notifies the client driver.All this happens in interrupt context only.
129 */
130
131static void handle_slave_tx(const unsigned long i2c_int_src,
132 const unsigned long i2c_slv_src)
133{
134 unsigned char udata;
135
136 if (i2c_slv_src & I2C_SLV_END_TRANS) {
137 dev_dbg(i2cslv->dev, "End of Transfer\n");
138
139 /* clear the interrupt to release the SCL line */
140 tegra_i2cslv_writel(i2cslv, I2C_SLV_END_TRANS, I2C_SLV_STATUS);
141 tegra_i2cslv_writel(i2cslv, I2C_SLV_SL_IRQ, I2C_SLV_STATUS);
142
143 goto end_trnsfr;
144 }
145
146 /* clear the interrupt to release the SCL line */
147 tegra_i2cslv_writel(i2cslv, I2C_SLV_SL_IRQ, I2C_SLV_STATUS);
148 /* Get the data byte fron client driver */
149 udata = tegra_i2cslv_getbyte_from_client(i2cslv);
150 tegra_i2cslv_writel(i2cslv, udata, I2C_SLV_SLV_RCVD);
151
152 return;
153
154end_trnsfr:
155 i2cslv->slave_tx_in_progress = false;
156 tegra_i2cslv_getbyte_end_from_client(i2cslv);
157}
158
159/* tegra_i2cslv_isr - Interrupt handler for slave controller
160 *
161 * This is the core part of slave driver. It maintain the state machine of
162 * i2c slave controller.
163 */
164static irqreturn_t tegra_i2cslv_isr(int irq, void *context_data)
165{
166 unsigned char udata;
167 unsigned long i2c_int_src = tegra_i2cslv_readl(i2cslv, I2C_INT_SOURCE);
168 unsigned long i2c_slv_int_src = tegra_i2cslv_readl(i2cslv,
169 I2C_SLV_INT_SOURCE);
170 unsigned long i2c_slv_sts = tegra_i2cslv_readl(i2cslv, I2C_SLV_STATUS);
171 unsigned long reg;
172
173#if defined(DEBUG)
174 debug_reg();
175#endif
176 /*
177 * Packet transfer error is seen at the end of transfer.
178 * It is not required by byte mode implementation and is
179 * most valid in case of fifo mode. As suggested by HW team
180 * we should clear it when it occurs.
181 */
182 if (unlikely(i2c_int_src & I2C_INT_PACKET_XFER_ERR)) {
183 dev_dbg(i2cslv->dev, " Packet Transfer error\n");
184 tegra_i2cslv_writel(i2cslv, I2C_INT_PACKET_XFER_ERR,
185 I2C_INT_STATUS);
186 if (!(I2C_SLV_SL_IRQ & i2c_slv_sts))
187 return IRQ_HANDLED;
188 }
189
190 if (unlikely(i2c_int_src & I2C_INT_SLV_WR2RD_INT)) {
191
192 dev_dbg(i2cslv->dev, "Master WR2RD\n");
193
194 /* Master send repeatedstart condition and changed the xfer
195 * direction from write to read. In response, Slave will change
196 * its direction fron rx to tx, if Rx xfer is in progress.
197 */
198 if (unlikely(WARN_ON(!i2cslv->slave_rx_in_progress))) {
199 /* Master is misbehaving. */
200 dev_err(i2cslv->dev,
201 "Got WR2RD while slave rx not in progress\n");
202 goto err;
203 }
204
205 if (i2cslv->slave_rx_in_progress) {
206 i2cslv->slave_rx_in_progress = false;
207 tegra_i2cslv_sendbyte_end_to_client(i2cslv);
208
209 udata = tegra_i2cslv_getbyte_from_client(i2cslv);
210 i2cslv->slave_tx_in_progress = true;
211 tegra_i2cslv_writel(i2cslv, udata, I2C_SLV_SLV_RCVD);
212 }
213
214 /* Clearing the bit. If Slave Rx xfer is not in progress
215 * we can ignore this interrupt.
216 */
217 tegra_i2cslv_writel(i2cslv, I2C_INT_SLV_WR2RD_INT,
218 I2C_INT_STATUS);
219 /* FIXME: What if SL_IRQ is set here */
220 return IRQ_HANDLED;
221 }
222
223 /*
224 * ERR: if tx is in progress and RNW = 0.
225 * ERR: if tx is in progress and we receive a new transfer.
226 * FIXME: Add more cases for wr2wr and rd2rd xfer.
227 */
228 if (unlikely(WARN_ON((i2cslv->slave_tx_in_progress
229 && (!(i2c_slv_sts & I2C_SLV_STATUS_RNW)))
230 || (i2cslv->slave_tx_in_progress
231 && (i2c_slv_sts & I2C_SLV_RCVD))))) {
232 dev_err(i2cslv->dev, "error in transfer\n");
233 goto err;
234 }
235
236 /* Check for the SL_IRQ */
237 if (unlikely(WARN_ON(!(i2c_slv_int_src & I2C_SLV_SL_IRQ)))) {
238 dev_err(i2cslv->dev, "SL_IRQ is not set\n");
239 goto err;
240 }
241
242 if (i2cslv->slave_tx_in_progress)
243 handle_slave_tx(i2c_int_src, i2c_slv_int_src);
244 else if (i2cslv->slave_rx_in_progress &&
245 !(i2c_slv_int_src & I2C_SLV_RCVD))
246 /* In case of master wr2rd xfer, I2C_SLV_RCVD new xfer bit check
247 * is required to identify the xfer direction change.
248 */
249 handle_slave_rx(i2c_int_src, i2c_slv_int_src);
250
251 /*
252 * The RCVD bit marks the start of transfer.
253 * The RCVD register contains the received address.
254 * The RNW bit is used to determine the direction of transaction.
255 */
256 if (i2c_slv_int_src & I2C_SLV_RCVD) {
257 tegra_i2cslv_writel(i2cslv, I2C_SLV_RCVD, I2C_SLV_STATUS);
258 tegra_i2cslv_writel(i2cslv, I2C_SLV_SL_IRQ, I2C_SLV_STATUS);
259
260 /* In case of WR2RD, Return from here. Controller will
261 * then generate WR2RD interrupt. Write the data to SLV_RCVD
262 * while handling WR2RD interrupt.
263 */
264 if (i2cslv->slave_rx_in_progress)
265 return IRQ_HANDLED;
266
267 /* if RNW, master issued read. */
268 if (i2c_slv_sts & I2C_SLV_STATUS_RNW) {
269 i2cslv->slave_rx_in_progress = false;
270 i2cslv->slave_tx_in_progress = true;
271 udata = tegra_i2cslv_getbyte_from_client(i2cslv);
272 tegra_i2cslv_writel(i2cslv, udata, I2C_SLV_SLV_RCVD);
273 } else {
274 i2cslv->slave_rx_in_progress = true;
275 i2cslv->slave_tx_in_progress = false;
276 }
277 }
278
279 return IRQ_HANDLED;
280
281err:
282 dev_err(i2cslv->dev, "I2C_I2C_SL_INT_SOURCE_0 %X\n",
283 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_INT_SOURCE));
284 dev_err(i2cslv->dev, "I2C_INTERRUPT_STATUS_REGISTER_0 %X\n",
285 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_STATUS));
286 dev_err(i2cslv->dev, "I2C_I2C_SL_STATUS_0 %X\n",
287 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_STATUS));
288 dev_err(i2cslv->dev, "I2C_INT_SOURCE %X\n",
289 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_SOURCE));
290 dev_err(i2cslv->dev, "I2C_I2C_SL_CNFG_0 %X\n",
291 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_CNFG));
292 dev_err(i2cslv->dev, "I2C_SLV_ADDR1 %X\n",
293 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_ADDR1));
294 dev_err(i2cslv->dev, "I2C_INTERRUPT_MASK_REGISTER_0 %X\n",
295 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_INT_MASK));
296 dev_err(i2cslv->dev, "I2C_I2C_SL_INT_MASK_0 %X\n",
297 (unsigned int)tegra_i2cslv_readl(i2cslv, I2C_SLV_INT_MASK));
298
299 /* Reset the internal state of controller and fifo. This will not
300 * reset the registers configuration
301 */
302 reg = tegra_i2cslv_readl(i2cslv, I2C_SLV_RESET_CNTRL);
303 reg |= I2C_SLV_SOFT_RESET;
304 tegra_i2cslv_writel(i2cslv, reg, I2C_SLV_RESET_CNTRL);
305 udelay(2);
306 /* Clear it for normal operation */
307 reg &= ~(I2C_SLV_SOFT_RESET);
308 tegra_i2cslv_writel(i2cslv, reg, I2C_SLV_RESET_CNTRL);
309
310 return IRQ_HANDLED;
311}
312
313/* i2cslv_init_config - To set the default configuration.
314 */
315static void i2cslv_init_config(void)
316{
317 unsigned long reg = 0;
318
319 reg = tegra_i2cslv_readl(i2cslv, I2C_SLV_RESET_CNTRL);
320 reg &= ~(I2C_SLV_SOFT_RESET);
321 tegra_i2cslv_writel(i2cslv, reg, I2C_SLV_RESET_CNTRL);
322
323 tegra_i2cslv_writel(i2cslv, I2C_REG_RESET, I2C_FIFO_CONTROL);
324 tegra_i2cslv_writel(i2cslv, I2C_REG_RESET, I2C_INTERRUPT_SET_REGISTER);
325 tegra_i2cslv_writel(i2cslv, I2C_REG_RESET, I2C_CLKEN_OVERRIDE);
326 tegra_i2cslv_writel(i2cslv, I2C_REG_RESET, I2C_TLOW_SEXT);
327 tegra_i2cslv_writel(i2cslv, I2C_REG_RESET, I2C_SL_INT_SET);
328 tegra_i2cslv_writel(i2cslv, I2C_SL_DELAY_COUNT_RESET,
329 I2C_SL_DELAY_COUNT);
330}
331
332static int i2cslv_init_cntlr(const unsigned long i2cslv_addr, bool is_seven_bit)
333{
334 int ret = 0;
335 unsigned long reg = 0;
336
337 i2cslv->div_clk = devm_clk_get(i2cslv->dev, "div-clk");
338 if (IS_ERR(i2cslv->div_clk)) {
339 dev_err(i2cslv->dev, "missing controller clock");
340 return PTR_ERR(i2cslv->div_clk);
341 }
342
343 ret = clk_prepare_enable(i2cslv->div_clk);
344 if (ret < 0) {
345 dev_err(i2cslv->dev, "Enabling div clk failed, err %d\n", ret);
346 return ret;
347 }
348
349 i2cslv->rstc = devm_reset_control_get(i2cslv->dev, "i2c");
350 if (IS_ERR(i2cslv->rstc)) {
351 ret = PTR_ERR(i2cslv->rstc);
352 dev_err(i2cslv->dev, "Reset control is not found: %d\n", ret);
353 return ret;
354 }
355
356 /* set the default values */
357 i2cslv_init_config();
358
359 /* set the slave address and address mode */
360 if (is_seven_bit) {
361 tegra_i2cslv_writel(i2cslv, i2cslv_addr & I2C_7BIT_ADDR_MASK,
362 I2C_SLV_ADDR1);
363
364 /* program ADDR2 register for 7 bit. */
365 reg = tegra_i2cslv_readl(i2cslv, I2C_SLV_ADDR2);
366 reg &= ~(I2C_SLV_ADDR2_MASK);
367 tegra_i2cslv_writel(i2cslv, reg, I2C_SLV_ADDR2);
368 } else {
369 dev_err(i2cslv->dev, "10 bit address not supported\n");
370 return -EINVAL;
371 }
372
373 /* Unmask I2C_INT_PACKET_XFER_ERR Just to clear it */
374 tegra_i2cslv_writel(i2cslv, (I2C_INT_SLV_WR2RD_INT |
375 I2C_INT_PACKET_XFER_ERR), I2C_INT_MASK);
376
377 tegra_i2cslv_writel(i2cslv, (I2C_SLV_END_TRANS | I2C_SLV_SL_IRQ |
378 I2C_SLV_RCVD), I2C_SLV_INT_MASK);
379
380 reg = tegra_i2cslv_readl(i2cslv, I2C_SLV_CNFG);
381 reg |= (I2C_SLV_CNFG_NEW_SL | I2C_SLV_CNFG_ENABLE_SL);
382 tegra_i2cslv_writel(i2cslv, reg, I2C_SLV_CNFG);
383
384 ret = i2cslv_load_config();
385
386 i2cslv->slave_rx_in_progress = false;
387 i2cslv->slave_tx_in_progress = false;
388
389 return ret;
390}
391
392int i2cslv_register_client(struct i2cslv_client_ops *i2c_ops,
393 const unsigned long i2cslv_addr, bool is_seven_bit)
394{
395 int ret = 0;
396
397 if (i2cslv->is_cntlr_intlzd) {
398 dev_info(i2cslv->dev, "controller already initialized\n");
399 return -EAGAIN;
400 }
401
402 if (!i2c_ops) {
403 dev_err(i2cslv->dev, "i2c ops == NULL\n");
404 return -EINVAL;
405 }
406
407 if (!(i2c_ops->slv_sendbyte_to_client) ||
408 !(i2c_ops->slv_getbyte_from_client) ||
409 !(i2c_ops->slv_sendbyte_end_to_client) ||
410 !(i2c_ops->slv_getbyte_end_from_client)) {
411 dev_err(i2cslv->dev, "i2c ops incomplete\n");
412 return -EINVAL;
413 }
414
415 i2cslv->i2c_clnt_ops = i2c_ops;
416
417 ret = i2cslv_init_cntlr(i2cslv_addr, is_seven_bit);
418 if (ret < 0) {
419 dev_err(i2cslv->dev, "i2c ops == NULL\n");
420 return -EAGAIN;
421 }
422
423 i2cslv->is_cntlr_intlzd = true;
424
425 return ret;
426}
427EXPORT_SYMBOL(i2cslv_register_client);
428
429void i2cslv_unregister_client(void)
430{
431 tegra_i2cslv_writel(i2cslv, 0, I2C_INT_MASK);
432 tegra_i2cslv_writel(i2cslv, 0, I2C_SLV_INT_MASK);
433
434 i2cslv->is_cntlr_intlzd = false;
435
436 i2cslv->i2c_clnt_ops = NULL;
437}
438EXPORT_SYMBOL(i2cslv_unregister_client);
439
440static int tegra_i2cslv_probe(struct platform_device *pdev)
441{
442 int ret = 0;
443
444 i2cslv = devm_kzalloc(&pdev->dev, sizeof(*i2cslv), GFP_KERNEL);
445 if (!i2cslv)
446 return -ENOMEM;
447
448 i2cslv->dev = &pdev->dev;
449
450 i2cslv->iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
451 if (!i2cslv->iomem) {
452 dev_err(&pdev->dev, "No IO memory resource\n");
453 ret = -ENODEV;
454 goto err_enmm;
455 }
456
457 i2cslv->base = devm_ioremap_resource(i2cslv->dev, i2cslv->iomem);
458 if (!i2cslv->base) {
459 dev_err(&pdev->dev,
460 "Cannot request memregion/iomap dma address\n");
461 ret = -EADDRNOTAVAIL;
462 goto err_adrnvld;
463 }
464
465 i2cslv->irq = platform_get_irq(pdev, 0);
466
467 ret = request_threaded_irq(i2cslv->irq, NULL,
468 tegra_i2cslv_isr, IRQF_ONESHOT,
469 dev_name(&pdev->dev), i2cslv);
470 if (ret < 0) {
471 dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
472 i2cslv->irq);
473 goto err_free_i2cslv;
474 }
475
476 i2cslv->is_cntlr_intlzd = false;
477
478 return ret;
479
480err_free_i2cslv:
481
482err_adrnvld:
483 release_mem_region(i2cslv->iomem->start, resource_size(i2cslv->iomem));
484err_enmm:
485 put_device(&pdev->dev);
486 return ret;
487}
488
489static int tegra_i2cslv_remove(struct platform_device *pdev)
490{
491 struct i2cslv_cntlr *i2cslv = platform_get_drvdata(pdev);
492
493 clk_disable_unprepare(i2cslv->div_clk);
494 reset_control_put(i2cslv->rstc);
495 return 0;
496}
497
498static struct of_device_id tegra_i2cslv_of_match[] = {
499 {.compatible = "nvidia,tegra-i2cslv-t186",},
500 {}
501};
502
503MODULE_DEVICE_TABLE(of, tegra_i2cslv_of_match);
504
505static struct platform_driver tegra_i2cslv_driver = {
506 .probe = tegra_i2cslv_probe,
507 .remove = tegra_i2cslv_remove,
508 .driver = {
509 .name = "tegra-i2cslv-t186",
510 .owner = THIS_MODULE,
511 .of_match_table = of_match_ptr(tegra_i2cslv_of_match),
512 },
513};
514
515static int __init tegra_i2cslv_init_driver(void)
516{
517 return platform_driver_register(&tegra_i2cslv_driver);
518}
519
520static void __exit tegra_i2cslv_exit_driver(void)
521{
522 platform_driver_unregister(&tegra_i2cslv_driver);
523}
524
525MODULE_AUTHOR("Ankit Gupta <guptaa@nvidia.com>");
526MODULE_DESCRIPTION("NVIDIA Tegra186 i2c slave driver");
527MODULE_LICENSE("GPL v2");
528module_init(tegra_i2cslv_init_driver);
529module_exit(tegra_i2cslv_exit_driver);
diff --git a/drivers/i2c/busses/i2c-t18x-slave.h b/drivers/i2c/busses/i2c-t18x-slave.h
deleted file mode 100644
index d3436e247..000000000
--- a/drivers/i2c/busses/i2c-t18x-slave.h
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef __I2C_T18X_SLAVE_H__
16#define __I2C_T18X_SLAVE_H__
17
18#define I2C_SLV_CNFG 0X20
19
20#define I2C_SLV_CNFG_ENABLE_SL (1<<3)
21#define I2C_SLV_CNFG_NEW_SL (1<<2)
22
23#define I2C_CONFIG_LOAD 0x8c
24#define I2C_CONFIG_LOAD_SLV (1<<1)
25#define I2C_TIMEOUT_CONFIG_LOAD (1<<2)
26
27#define I2C_FIFO_CONTROL 0x5c
28#define I2C_INTERRUPT_SET_REGISTER 0x74
29#define I2C_CLKEN_OVERRIDE 0x90
30#define I2C_DEBUG_CONTROL 0xa4
31#define I2C_TLOW_SEXT 0x34
32#define I2C_SL_INT_SET 0x48
33#define I2C_SL_DELAY_COUNT 0x3c
34#define I2C_SL_DELAY_COUNT_RESET 0x1e
35
36#define I2C_SLV_ADDR1 0x02c
37#define I2C_SLV_ADDR2 0x030
38
39#define I2C_SLV_RESET_CNTRL 0xac
40#define I2C_SLV_SOFT_RESET (1<<0)
41
42/* Interrupt Handeling */
43#define I2C_INT_MASK 0x064
44#define I2C_INT_STATUS 0x068
45#define I2C_INT_SOURCE 0x70
46
47#define I2C_INT_SLV_WR2RD_INT (1<<26)
48#define I2C_INT_PACKET_XFER_ERR (1<<25)
49
50#define I2C_SLV_STATUS 0x28
51#define I2C_SLV_INT_MASK 0x40
52#define I2C_SLV_INT_SOURCE 0x44
53
54#define I2C_SLV_END_TRANS (1<<4)
55#define I2C_SLV_SL_IRQ (1<<3)
56#define I2C_SLV_RCVD (1<<2)
57#define I2C_SLV_STATUS_RNW (1<<1)
58
59#define I2C_SLV_SLV_RCVD 0x24
60
61#define I2C_RETRIES 2000
62#define I2C_REG_RESET 0x0
63
64#define I2C_SLV_ADDR2_MASK 0x1FFFF
65#define I2C_7BIT_ADDR_MASK 0x7F
66#define I2C_10BIT_ADDR_MASK 0x3FF
67
68struct i2cslv_cntlr {
69 struct device *dev;
70 struct clk *clk;
71 struct reset_control *rstc;
72 struct clk *div_clk;
73 struct resource *iomem;
74 int irq;
75 void __iomem *base;
76 bool is_cntlr_intlzd;
77 bool slave_rx_in_progress;
78 bool slave_tx_in_progress;
79 bool is_7bit_addr;
80 /* No of bytes rcvd / trnsfrd after err */
81 struct i2cslv_client_ops *i2c_clnt_ops;
82};
83
84static inline unsigned long tegra_i2cslv_readl(struct i2cslv_cntlr *i2cslv,
85 unsigned long reg)
86{
87 return readl(i2cslv->base + reg);
88}
89
90static inline void tegra_i2cslv_writel(struct i2cslv_cntlr *i2cslv,
91 unsigned long val, unsigned long reg)
92{
93 writel(val, i2cslv->base + reg);
94}
95
96static inline void tegra_i2cslv_sendbyte_to_client(struct i2cslv_cntlr *i2cslv,
97 unsigned char wd)
98{
99 if (i2cslv->i2c_clnt_ops &&
100 i2cslv->i2c_clnt_ops->slv_sendbyte_to_client)
101 i2cslv->i2c_clnt_ops->slv_sendbyte_to_client(wd);
102}
103
104static inline unsigned char tegra_i2cslv_getbyte_from_client(struct i2cslv_cntlr
105 *i2cslv)
106{
107 if (i2cslv->i2c_clnt_ops &&
108 i2cslv->i2c_clnt_ops->slv_getbyte_from_client)
109 return i2cslv->i2c_clnt_ops->slv_getbyte_from_client();
110 return 0;
111}
112
113static inline void tegra_i2cslv_sendbyte_end_to_client(
114 struct i2cslv_cntlr *i2cslv)
115{
116 if (i2cslv->i2c_clnt_ops &&
117 i2cslv->i2c_clnt_ops->slv_sendbyte_end_to_client)
118 i2cslv->i2c_clnt_ops->slv_sendbyte_end_to_client();
119}
120
121static inline void tegra_i2cslv_getbyte_end_from_client(
122 struct i2cslv_cntlr *i2cslv)
123{
124 if (i2cslv->i2c_clnt_ops &&
125 i2cslv->i2c_clnt_ops->slv_getbyte_end_from_client)
126 i2cslv->i2c_clnt_ops->slv_getbyte_end_from_client();
127}
128#endif /* __I2C_T18X_SLAVE_H__ */
diff --git a/drivers/i2c/busses/i2c-t18x-slv-common.h b/drivers/i2c/busses/i2c-t18x-slv-common.h
deleted file mode 100644
index 4539d6aac..000000000
--- a/drivers/i2c/busses/i2c-t18x-slv-common.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef __I2C_T18X_SLV_COMMON_H__
16#define __I2C_T18X_SLV_COMMON_H__
17
18#define MAX_BUFF_SIZE 4096
19#define SLAVE_RX_TIMEOUT (msecs_to_jiffies(1000))
20
21struct i2cslv_client_ops {
22 void (*slv_sendbyte_to_client)(unsigned char);
23 unsigned char (*slv_getbyte_from_client)(void);
24 void (*slv_sendbyte_end_to_client)(void);
25 void (*slv_getbyte_end_from_client)(void);
26};
27#endif /* __I2C_T18X_SLV_COMMON_H__ */