blob: 8e38a24ec3fcc5d56487c8b3a15d75e22f09ed3c [file] [log] [blame]
Sagar Dharia7c927c02016-11-23 11:51:43 -07001/*
2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
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/clk.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/i2c.h>
19#include <linux/interrupt.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/platform_device.h>
24#include <linux/qcom-geni-se.h>
25
26#define SE_I2C_TX_TRANS_LEN (0x26C)
27#define SE_I2C_RX_TRANS_LEN (0x270)
28#define SE_I2C_SCL_COUNTERS (0x278)
29
30#define SE_I2C_ERR (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |\
31 M_GP_IRQ_1_EN | M_GP_IRQ_3_EN | M_GP_IRQ_4_EN)
32#define SE_I2C_ABORT (1U << 1)
33/* M_CMD OP codes for I2C */
34#define I2C_WRITE (0x1)
35#define I2C_READ (0x2)
36#define I2C_WRITE_READ (0x3)
37#define I2C_ADDR_ONLY (0x4)
38#define I2C_BUS_CLEAR (0x6)
39#define I2C_STOP_ON_BUS (0x7)
40/* M_CMD params for I2C */
41#define PRE_CMD_DELAY (BIT(0))
42#define TIMESTAMP_BEFORE (BIT(1))
43#define STOP_STRETCH (BIT(2))
44#define TIMESTAMP_AFTER (BIT(3))
45#define POST_COMMAND_DELAY (BIT(4))
46#define IGNORE_ADD_NACK (BIT(6))
47#define READ_FINISHED_WITH_ACK (BIT(7))
48#define BYPASS_ADDR_PHASE (BIT(8))
49#define SLV_ADDR_MSK (GENMASK(15, 9))
50#define SLV_ADDR_SHFT (9)
51
52struct geni_i2c_dev {
53 struct device *dev;
54 void __iomem *base;
55 int irq;
56 int err;
57 struct i2c_adapter adap;
58 struct completion xfer;
59 struct i2c_msg *cur;
60 int cur_wr;
61 int cur_rd;
62};
63
64static inline void qcom_geni_i2c_conf(void __iomem *base, int dfs, int div)
65{
66 geni_write_reg(dfs, base, SE_GENI_CLK_SEL);
67 geni_write_reg((div << 4) | 1, base, GENI_SER_M_CLK_CFG);
68 geni_write_reg(((5 << 20) | (0xC << 10) | 0x18),
69 base, SE_I2C_SCL_COUNTERS);
70 /*
71 * Ensure Clk config completes before return.
72 */
73 mb();
74}
75
76static irqreturn_t geni_i2c_irq(int irq, void *dev)
77{
78 struct geni_i2c_dev *gi2c = dev;
79 int i, j;
80 u32 m_stat = readl_relaxed(gi2c->base + SE_GENI_M_IRQ_STATUS);
81 u32 tx_stat = readl_relaxed(gi2c->base + SE_GENI_TX_FIFO_STATUS);
82 u32 rx_stat = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
83 struct i2c_msg *cur = gi2c->cur;
84
85 dev_dbg(gi2c->dev,
86 "got i2c irq:%d, stat:0x%x, tx stat:0x%x, rx stat:0x%x\n",
87 irq, m_stat, tx_stat, rx_stat);
88 if (!cur || m_stat & SE_I2C_ERR) {
89 dev_err(gi2c->dev, "i2c txn err");
90 writel_relaxed(0, (gi2c->base + SE_GENI_TX_WATERMARK_REG));
91 gi2c->err = -EIO;
92 goto irqret;
93 }
94 if (((m_stat & M_RX_FIFO_WATERMARK_EN) ||
95 (m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) {
96 u32 rxcnt = rx_stat & RX_FIFO_WC_MSK;
97
98 for (j = 0; j < rxcnt; j++) {
99 u32 temp;
100 int p;
101
102 temp = readl_relaxed(gi2c->base + SE_GENI_RX_FIFOn);
103 for (i = gi2c->cur_rd, p = 0; (i < cur->len && p < 4);
104 i++, p++)
105 cur->buf[i] = (u8) ((temp >> (p * 8)) & 0xff);
106 gi2c->cur_rd = i;
107 if (gi2c->cur_rd == cur->len) {
108 dev_dbg(gi2c->dev, "i:%d,read 0x%x\n", i, temp);
109 break;
110 }
111 dev_dbg(gi2c->dev, "i: %d, read 0x%x\n", i, temp);
112 }
113 } else if ((m_stat & M_TX_FIFO_WATERMARK_EN) &&
114 !(cur->flags & I2C_M_RD)) {
115 for (j = 0; j < 0x1f; j++) {
116 u32 temp = 0;
117 int p;
118
119 for (i = gi2c->cur_wr, p = 0; (i < cur->len && p < 4);
120 i++, p++)
121 temp |= (((u32)(cur->buf[i]) << (p * 8)));
122 writel_relaxed(temp, gi2c->base + SE_GENI_TX_FIFOn);
123 gi2c->cur_wr = i;
124 dev_dbg(gi2c->dev, "i:%d,wrote 0x%x\n", i, temp);
125 if (gi2c->cur_wr == cur->len) {
126 dev_dbg(gi2c->dev, "i2c bytes done writing\n");
127 writel_relaxed(0,
128 (gi2c->base + SE_GENI_TX_WATERMARK_REG));
129 break;
130 }
131 }
132 }
133irqret:
134 writel_relaxed(m_stat, gi2c->base + SE_GENI_M_IRQ_CLEAR);
135 /* Ensure all writes are done before returning from ISR. */
136 wmb();
137 /* if this is err with done-bit not set, handle that thr' timeout. */
138 if (m_stat & M_CMD_DONE_EN) {
139 dev_dbg(gi2c->dev, "i2c irq: err:%d, stat:0x%x\n",
140 gi2c->err, m_stat);
141 complete(&gi2c->xfer);
142 }
143 return IRQ_HANDLED;
144}
145
146static int geni_i2c_xfer(struct i2c_adapter *adap,
147 struct i2c_msg msgs[],
148 int num)
149{
150 struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap);
151 int i, ret = 0, timeout = 0;
152
153 gi2c->err = 0;
154 gi2c->cur = &msgs[0];
155 reinit_completion(&gi2c->xfer);
156 enable_irq(gi2c->irq);
157 qcom_geni_i2c_conf(gi2c->base, 0, 2);
158 se_config_packing(gi2c->base, 8, 4, true);
159 dev_dbg(gi2c->dev, "i2c xfer:num:%d, msgs:len:%d,flg:%d\n",
160 num, msgs[0].len, msgs[0].flags);
161 for (i = 0; i < num; i++) {
162 int stretch = (i < (num - 1));
163 u32 m_param = 0;
164 u32 m_cmd = 0;
165
166 m_param |= (stretch ? STOP_STRETCH : ~(STOP_STRETCH));
167 m_param |= ((msgs[i].addr & 0x7F) << SLV_ADDR_SHFT);
168
169 gi2c->cur = &msgs[i];
170 if (msgs[i].flags & I2C_M_RD) {
171 dev_dbg(gi2c->dev,
172 "READ,n:%d,i:%d len:%d, stretch:%d\n",
173 num, i, msgs[i].len, stretch);
174 geni_write_reg(msgs[i].len,
175 gi2c->base, SE_I2C_RX_TRANS_LEN);
176 m_cmd = I2C_READ;
177 geni_setup_m_cmd(gi2c->base, m_cmd, m_param);
178 } else {
179 dev_dbg(gi2c->dev,
180 "WRITE:n:%d,i%d len:%d, stretch:%d\n",
181 num, i, msgs[i].len, stretch);
182 geni_write_reg(msgs[i].len, gi2c->base,
183 SE_I2C_TX_TRANS_LEN);
184 m_cmd = I2C_WRITE;
185 geni_setup_m_cmd(gi2c->base, m_cmd, m_param);
186 /* Get FIFO IRQ */
187 geni_write_reg(1, gi2c->base, SE_GENI_TX_WATERMARK_REG);
188 }
189 /* Ensure FIFO write go through before waiting for Done evet */
190 mb();
191 timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
192 if (!timeout) {
193 dev_err(gi2c->dev, "Timed out\n");
194 gi2c->err = -ETIMEDOUT;
195 gi2c->cur = NULL;
196 geni_abort_m_cmd(gi2c->base);
197 timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
198 }
199 gi2c->cur_wr = 0;
200 gi2c->cur_rd = 0;
201 if (gi2c->err) {
202 dev_err(gi2c->dev, "i2c error :%d\n", gi2c->err);
203 ret = gi2c->err;
204 break;
205 }
206 }
207 if (ret == 0)
208 ret = i;
209 disable_irq(gi2c->irq);
210 gi2c->cur = NULL;
211 gi2c->err = 0;
212 dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret);
213 return ret;
214}
215
216static u32 geni_i2c_func(struct i2c_adapter *adap)
217{
218 return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
219}
220
221static const struct i2c_algorithm geni_i2c_algo = {
222 .master_xfer = geni_i2c_xfer,
223 .functionality = geni_i2c_func,
224};
225
226static int geni_i2c_probe(struct platform_device *pdev)
227{
228 struct geni_i2c_dev *gi2c;
229 struct resource *res;
230 int ret;
231
232 gi2c = devm_kzalloc(&pdev->dev, sizeof(*gi2c), GFP_KERNEL);
233 if (!gi2c)
234 return -ENOMEM;
235
236 gi2c->dev = &pdev->dev;
237
238 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
239 if (!res)
240 return -EINVAL;
241
242 gi2c->base = devm_ioremap_resource(gi2c->dev, res);
243 if (IS_ERR(gi2c->base))
244 return PTR_ERR(gi2c->base);
245
246 gi2c->irq = platform_get_irq(pdev, 0);
247 if (gi2c->irq < 0) {
248 dev_err(gi2c->dev, "IRQ error for i2c-geni\n");
249 return gi2c->irq;
250 }
251
252 gi2c->adap.algo = &geni_i2c_algo;
253 init_completion(&gi2c->xfer);
254 platform_set_drvdata(pdev, gi2c);
255 ret = devm_request_irq(gi2c->dev, gi2c->irq, geni_i2c_irq,
256 IRQF_TRIGGER_HIGH, "i2c_geni", gi2c);
257 if (ret) {
258 dev_err(gi2c->dev, "Request_irq failed:%d: err:%d\n",
259 gi2c->irq, ret);
260 return ret;
261 }
262 disable_irq(gi2c->irq);
263 i2c_set_adapdata(&gi2c->adap, gi2c);
264 gi2c->adap.dev.parent = gi2c->dev;
265 gi2c->adap.dev.of_node = pdev->dev.of_node;
266
267 strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
268
269 i2c_add_adapter(&gi2c->adap);
270 geni_se_init(gi2c->base, FIFO_MODE, 0xF, 0x10);
271
272 return 0;
273}
274
275static int geni_i2c_remove(struct platform_device *pdev)
276{
277 struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
278
279 disable_irq(gi2c->irq);
280 i2c_del_adapter(&gi2c->adap);
281 return 0;
282}
283
284#ifdef CONFIG_PM_SLEEP
285static int geni_i2c_suspend(struct device *device)
286{
287 return 0;
288}
289
290static int geni_i2c_resume(struct device *device)
291{
292 return 0;
293}
294#endif
295
296static const struct dev_pm_ops geni_i2c_pm_ops = {
297 SET_SYSTEM_SLEEP_PM_OPS(
298 geni_i2c_suspend,
299 geni_i2c_resume)
300};
301
302static const struct of_device_id geni_i2c_dt_match[] = {
303 { .compatible = "qcom,i2c-geni" },
304 {}
305};
306MODULE_DEVICE_TABLE(of, geni_i2c_dt_match);
307
308static struct platform_driver geni_i2c_driver = {
309 .probe = geni_i2c_probe,
310 .remove = geni_i2c_remove,
311 .driver = {
312 .name = "i2c_geni",
313 .pm = &geni_i2c_pm_ops,
314 .of_match_table = geni_i2c_dt_match,
315 },
316};
317
318module_platform_driver(geni_i2c_driver);
319
320MODULE_LICENSE("GPL v2");
321MODULE_ALIAS("platform:i2c_geni");