1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * netup_unidvb_i2c.c |
4 | * |
5 | * Internal I2C bus driver for NetUP Universal Dual DVB-CI |
6 | * |
7 | * Copyright (C) 2014 NetUP Inc. |
8 | * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru> |
9 | * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru> |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> |
15 | #include <linux/delay.h> |
16 | #include "netup_unidvb.h" |
17 | |
18 | #define NETUP_I2C_BUS0_ADDR 0x4800 |
19 | #define NETUP_I2C_BUS1_ADDR 0x4840 |
20 | #define NETUP_I2C_TIMEOUT 1000 |
21 | |
22 | /* twi_ctrl0_stat reg bits */ |
23 | #define TWI_IRQEN_COMPL 0x1 |
24 | #define TWI_IRQEN_ANACK 0x2 |
25 | #define TWI_IRQEN_DNACK 0x4 |
26 | #define TWI_IRQ_COMPL (TWI_IRQEN_COMPL << 8) |
27 | #define TWI_IRQ_ANACK (TWI_IRQEN_ANACK << 8) |
28 | #define TWI_IRQ_DNACK (TWI_IRQEN_DNACK << 8) |
29 | #define TWI_IRQ_TX 0x800 |
30 | #define TWI_IRQ_RX 0x1000 |
31 | #define TWI_IRQEN (TWI_IRQEN_COMPL | TWI_IRQEN_ANACK | TWI_IRQEN_DNACK) |
32 | /* twi_addr_ctrl1 reg bits*/ |
33 | #define TWI_TRANSFER 0x100 |
34 | #define TWI_NOSTOP 0x200 |
35 | #define TWI_SOFT_RESET 0x2000 |
36 | /* twi_clkdiv reg value */ |
37 | #define TWI_CLKDIV 156 |
38 | /* fifo_stat_ctrl reg bits */ |
39 | #define FIFO_IRQEN 0x8000 |
40 | #define FIFO_RESET 0x4000 |
41 | /* FIFO size */ |
42 | #define FIFO_SIZE 16 |
43 | |
44 | struct netup_i2c_fifo_regs { |
45 | union { |
46 | __u8 data8; |
47 | __le16 data16; |
48 | __le32 data32; |
49 | }; |
50 | __u8 padding[4]; |
51 | __le16 stat_ctrl; |
52 | } __packed __aligned(1); |
53 | |
54 | struct netup_i2c_regs { |
55 | __le16 clkdiv; |
56 | __le16 twi_ctrl0_stat; |
57 | __le16 twi_addr_ctrl1; |
58 | __le16 length; |
59 | __u8 padding1[8]; |
60 | struct netup_i2c_fifo_regs tx_fifo; |
61 | __u8 padding2[6]; |
62 | struct netup_i2c_fifo_regs rx_fifo; |
63 | } __packed __aligned(1); |
64 | |
65 | irqreturn_t netup_i2c_interrupt(struct netup_i2c *i2c) |
66 | { |
67 | u16 reg, tmp; |
68 | unsigned long flags; |
69 | irqreturn_t iret = IRQ_HANDLED; |
70 | |
71 | spin_lock_irqsave(&i2c->lock, flags); |
72 | reg = readw(addr: &i2c->regs->twi_ctrl0_stat); |
73 | writew(val: reg & ~TWI_IRQEN, addr: &i2c->regs->twi_ctrl0_stat); |
74 | dev_dbg(i2c->adap.dev.parent, |
75 | "%s(): twi_ctrl0_state 0x%x\n" , __func__, reg); |
76 | if ((reg & TWI_IRQEN_COMPL) != 0 && (reg & TWI_IRQ_COMPL)) { |
77 | dev_dbg(i2c->adap.dev.parent, |
78 | "%s(): TWI_IRQEN_COMPL\n" , __func__); |
79 | i2c->state = STATE_DONE; |
80 | goto irq_ok; |
81 | } |
82 | if ((reg & TWI_IRQEN_ANACK) != 0 && (reg & TWI_IRQ_ANACK)) { |
83 | dev_dbg(i2c->adap.dev.parent, |
84 | "%s(): TWI_IRQEN_ANACK\n" , __func__); |
85 | i2c->state = STATE_ERROR; |
86 | goto irq_ok; |
87 | } |
88 | if ((reg & TWI_IRQEN_DNACK) != 0 && (reg & TWI_IRQ_DNACK)) { |
89 | dev_dbg(i2c->adap.dev.parent, |
90 | "%s(): TWI_IRQEN_DNACK\n" , __func__); |
91 | i2c->state = STATE_ERROR; |
92 | goto irq_ok; |
93 | } |
94 | if ((reg & TWI_IRQ_RX) != 0) { |
95 | tmp = readw(addr: &i2c->regs->rx_fifo.stat_ctrl); |
96 | writew(val: tmp & ~FIFO_IRQEN, addr: &i2c->regs->rx_fifo.stat_ctrl); |
97 | i2c->state = STATE_WANT_READ; |
98 | dev_dbg(i2c->adap.dev.parent, |
99 | "%s(): want read\n" , __func__); |
100 | goto irq_ok; |
101 | } |
102 | if ((reg & TWI_IRQ_TX) != 0) { |
103 | tmp = readw(addr: &i2c->regs->tx_fifo.stat_ctrl); |
104 | writew(val: tmp & ~FIFO_IRQEN, addr: &i2c->regs->tx_fifo.stat_ctrl); |
105 | i2c->state = STATE_WANT_WRITE; |
106 | dev_dbg(i2c->adap.dev.parent, |
107 | "%s(): want write\n" , __func__); |
108 | goto irq_ok; |
109 | } |
110 | dev_warn(&i2c->adap.dev, "%s(): not mine interrupt\n" , __func__); |
111 | iret = IRQ_NONE; |
112 | irq_ok: |
113 | spin_unlock_irqrestore(lock: &i2c->lock, flags); |
114 | if (iret == IRQ_HANDLED) |
115 | wake_up(&i2c->wq); |
116 | return iret; |
117 | } |
118 | |
119 | static void netup_i2c_reset(struct netup_i2c *i2c) |
120 | { |
121 | dev_dbg(i2c->adap.dev.parent, "%s()\n" , __func__); |
122 | i2c->state = STATE_DONE; |
123 | writew(TWI_SOFT_RESET, addr: &i2c->regs->twi_addr_ctrl1); |
124 | writew(TWI_CLKDIV, addr: &i2c->regs->clkdiv); |
125 | writew(FIFO_RESET, addr: &i2c->regs->tx_fifo.stat_ctrl); |
126 | writew(FIFO_RESET, addr: &i2c->regs->rx_fifo.stat_ctrl); |
127 | writew(val: 0x800, addr: &i2c->regs->tx_fifo.stat_ctrl); |
128 | writew(val: 0x800, addr: &i2c->regs->rx_fifo.stat_ctrl); |
129 | } |
130 | |
131 | static void netup_i2c_fifo_tx(struct netup_i2c *i2c) |
132 | { |
133 | u8 data; |
134 | u32 fifo_space = FIFO_SIZE - |
135 | (readw(addr: &i2c->regs->tx_fifo.stat_ctrl) & 0x3f); |
136 | u32 msg_length = i2c->msg->len - i2c->xmit_size; |
137 | |
138 | msg_length = (msg_length < fifo_space ? msg_length : fifo_space); |
139 | while (msg_length--) { |
140 | data = i2c->msg->buf[i2c->xmit_size++]; |
141 | writeb(val: data, addr: &i2c->regs->tx_fifo.data8); |
142 | dev_dbg(i2c->adap.dev.parent, |
143 | "%s(): write 0x%02x\n" , __func__, data); |
144 | } |
145 | if (i2c->xmit_size < i2c->msg->len) { |
146 | dev_dbg(i2c->adap.dev.parent, |
147 | "%s(): TX IRQ enabled\n" , __func__); |
148 | writew(readw(addr: &i2c->regs->tx_fifo.stat_ctrl) | FIFO_IRQEN, |
149 | addr: &i2c->regs->tx_fifo.stat_ctrl); |
150 | } |
151 | } |
152 | |
153 | static void netup_i2c_fifo_rx(struct netup_i2c *i2c) |
154 | { |
155 | u8 data; |
156 | u32 fifo_size = readw(addr: &i2c->regs->rx_fifo.stat_ctrl) & 0x3f; |
157 | |
158 | dev_dbg(i2c->adap.dev.parent, |
159 | "%s(): RX fifo size %d\n" , __func__, fifo_size); |
160 | while (fifo_size--) { |
161 | data = readb(addr: &i2c->regs->rx_fifo.data8); |
162 | if ((i2c->msg->flags & I2C_M_RD) != 0 && |
163 | i2c->xmit_size < i2c->msg->len) { |
164 | i2c->msg->buf[i2c->xmit_size++] = data; |
165 | dev_dbg(i2c->adap.dev.parent, |
166 | "%s(): read 0x%02x\n" , __func__, data); |
167 | } |
168 | } |
169 | if (i2c->xmit_size < i2c->msg->len) { |
170 | dev_dbg(i2c->adap.dev.parent, |
171 | "%s(): RX IRQ enabled\n" , __func__); |
172 | writew(readw(addr: &i2c->regs->rx_fifo.stat_ctrl) | FIFO_IRQEN, |
173 | addr: &i2c->regs->rx_fifo.stat_ctrl); |
174 | } |
175 | } |
176 | |
177 | static void netup_i2c_start_xfer(struct netup_i2c *i2c) |
178 | { |
179 | u16 rdflag = ((i2c->msg->flags & I2C_M_RD) ? 1 : 0); |
180 | u16 reg = readw(addr: &i2c->regs->twi_ctrl0_stat); |
181 | |
182 | writew(TWI_IRQEN | reg, addr: &i2c->regs->twi_ctrl0_stat); |
183 | writew(val: i2c->msg->len, addr: &i2c->regs->length); |
184 | writew(TWI_TRANSFER | (i2c->msg->addr << 1) | rdflag, |
185 | addr: &i2c->regs->twi_addr_ctrl1); |
186 | dev_dbg(i2c->adap.dev.parent, |
187 | "%s(): length %d twi_addr_ctrl1 0x%x twi_ctrl0_stat 0x%x\n" , |
188 | __func__, readw(&i2c->regs->length), |
189 | readw(&i2c->regs->twi_addr_ctrl1), |
190 | readw(&i2c->regs->twi_ctrl0_stat)); |
191 | i2c->state = STATE_WAIT; |
192 | i2c->xmit_size = 0; |
193 | if (!rdflag) |
194 | netup_i2c_fifo_tx(i2c); |
195 | else |
196 | writew(FIFO_IRQEN | readw(addr: &i2c->regs->rx_fifo.stat_ctrl), |
197 | addr: &i2c->regs->rx_fifo.stat_ctrl); |
198 | } |
199 | |
200 | static int netup_i2c_xfer(struct i2c_adapter *adap, |
201 | struct i2c_msg *msgs, int num) |
202 | { |
203 | unsigned long flags; |
204 | int i, trans_done, res = num; |
205 | struct netup_i2c *i2c = i2c_get_adapdata(adap); |
206 | u16 reg; |
207 | |
208 | spin_lock_irqsave(&i2c->lock, flags); |
209 | if (i2c->state != STATE_DONE) { |
210 | dev_dbg(i2c->adap.dev.parent, |
211 | "%s(): i2c->state == %d, resetting I2C\n" , |
212 | __func__, i2c->state); |
213 | netup_i2c_reset(i2c); |
214 | } |
215 | dev_dbg(i2c->adap.dev.parent, "%s() num %d\n" , __func__, num); |
216 | for (i = 0; i < num; i++) { |
217 | i2c->msg = &msgs[i]; |
218 | netup_i2c_start_xfer(i2c); |
219 | trans_done = 0; |
220 | while (!trans_done) { |
221 | spin_unlock_irqrestore(lock: &i2c->lock, flags); |
222 | if (wait_event_timeout(i2c->wq, |
223 | i2c->state != STATE_WAIT, |
224 | msecs_to_jiffies(NETUP_I2C_TIMEOUT))) { |
225 | spin_lock_irqsave(&i2c->lock, flags); |
226 | switch (i2c->state) { |
227 | case STATE_WANT_READ: |
228 | netup_i2c_fifo_rx(i2c); |
229 | break; |
230 | case STATE_WANT_WRITE: |
231 | netup_i2c_fifo_tx(i2c); |
232 | break; |
233 | case STATE_DONE: |
234 | if ((i2c->msg->flags & I2C_M_RD) != 0 && |
235 | i2c->xmit_size != i2c->msg->len) |
236 | netup_i2c_fifo_rx(i2c); |
237 | dev_dbg(i2c->adap.dev.parent, |
238 | "%s(): msg %d OK\n" , |
239 | __func__, i); |
240 | trans_done = 1; |
241 | break; |
242 | case STATE_ERROR: |
243 | res = -EIO; |
244 | dev_dbg(i2c->adap.dev.parent, |
245 | "%s(): error state\n" , |
246 | __func__); |
247 | goto done; |
248 | default: |
249 | dev_dbg(i2c->adap.dev.parent, |
250 | "%s(): invalid state %d\n" , |
251 | __func__, i2c->state); |
252 | res = -EINVAL; |
253 | goto done; |
254 | } |
255 | if (!trans_done) { |
256 | i2c->state = STATE_WAIT; |
257 | reg = readw( |
258 | addr: &i2c->regs->twi_ctrl0_stat); |
259 | writew(TWI_IRQEN | reg, |
260 | addr: &i2c->regs->twi_ctrl0_stat); |
261 | } |
262 | spin_unlock_irqrestore(lock: &i2c->lock, flags); |
263 | } else { |
264 | spin_lock_irqsave(&i2c->lock, flags); |
265 | dev_dbg(i2c->adap.dev.parent, |
266 | "%s(): wait timeout\n" , __func__); |
267 | res = -ETIMEDOUT; |
268 | goto done; |
269 | } |
270 | spin_lock_irqsave(&i2c->lock, flags); |
271 | } |
272 | } |
273 | done: |
274 | spin_unlock_irqrestore(lock: &i2c->lock, flags); |
275 | dev_dbg(i2c->adap.dev.parent, "%s(): result %d\n" , __func__, res); |
276 | return res; |
277 | } |
278 | |
279 | static u32 netup_i2c_func(struct i2c_adapter *adap) |
280 | { |
281 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
282 | } |
283 | |
284 | static const struct i2c_algorithm netup_i2c_algorithm = { |
285 | .master_xfer = netup_i2c_xfer, |
286 | .functionality = netup_i2c_func, |
287 | }; |
288 | |
289 | static const struct i2c_adapter netup_i2c_adapter = { |
290 | .owner = THIS_MODULE, |
291 | .name = NETUP_UNIDVB_NAME, |
292 | .class = I2C_CLASS_HWMON, |
293 | .algo = &netup_i2c_algorithm, |
294 | }; |
295 | |
296 | static int netup_i2c_init(struct netup_unidvb_dev *ndev, int bus_num) |
297 | { |
298 | int ret; |
299 | struct netup_i2c *i2c; |
300 | |
301 | if (bus_num < 0 || bus_num > 1) { |
302 | dev_err(&ndev->pci_dev->dev, |
303 | "%s(): invalid bus_num %d\n" , __func__, bus_num); |
304 | return -EINVAL; |
305 | } |
306 | i2c = &ndev->i2c[bus_num]; |
307 | spin_lock_init(&i2c->lock); |
308 | init_waitqueue_head(&i2c->wq); |
309 | i2c->regs = (struct netup_i2c_regs __iomem *)(ndev->bmmio0 + |
310 | (bus_num == 0 ? NETUP_I2C_BUS0_ADDR : NETUP_I2C_BUS1_ADDR)); |
311 | netup_i2c_reset(i2c); |
312 | i2c->adap = netup_i2c_adapter; |
313 | i2c->adap.dev.parent = &ndev->pci_dev->dev; |
314 | i2c_set_adapdata(adap: &i2c->adap, data: i2c); |
315 | ret = i2c_add_adapter(adap: &i2c->adap); |
316 | if (ret) |
317 | return ret; |
318 | dev_info(&ndev->pci_dev->dev, |
319 | "%s(): registered I2C bus %d at 0x%x\n" , |
320 | __func__, |
321 | bus_num, (bus_num == 0 ? |
322 | NETUP_I2C_BUS0_ADDR : |
323 | NETUP_I2C_BUS1_ADDR)); |
324 | return 0; |
325 | } |
326 | |
327 | static void netup_i2c_remove(struct netup_unidvb_dev *ndev, int bus_num) |
328 | { |
329 | struct netup_i2c *i2c; |
330 | |
331 | if (bus_num < 0 || bus_num > 1) { |
332 | dev_err(&ndev->pci_dev->dev, |
333 | "%s(): invalid bus number %d\n" , __func__, bus_num); |
334 | return; |
335 | } |
336 | i2c = &ndev->i2c[bus_num]; |
337 | netup_i2c_reset(i2c); |
338 | /* remove adapter */ |
339 | i2c_del_adapter(adap: &i2c->adap); |
340 | dev_info(&ndev->pci_dev->dev, |
341 | "netup_i2c_remove: unregistered I2C bus %d\n" , bus_num); |
342 | } |
343 | |
344 | int netup_i2c_register(struct netup_unidvb_dev *ndev) |
345 | { |
346 | int ret; |
347 | |
348 | ret = netup_i2c_init(ndev, bus_num: 0); |
349 | if (ret) |
350 | return ret; |
351 | ret = netup_i2c_init(ndev, bus_num: 1); |
352 | if (ret) { |
353 | netup_i2c_remove(ndev, bus_num: 0); |
354 | return ret; |
355 | } |
356 | return 0; |
357 | } |
358 | |
359 | void netup_i2c_unregister(struct netup_unidvb_dev *ndev) |
360 | { |
361 | netup_i2c_remove(ndev, bus_num: 0); |
362 | netup_i2c_remove(ndev, bus_num: 1); |
363 | } |
364 | |
365 | |