Lines 43-55
__FBSDID("$FreeBSD$");
Link Here
|
43 |
* See ig4_var.h for locking semantics. |
43 |
* See ig4_var.h for locking semantics. |
44 |
*/ |
44 |
*/ |
45 |
|
45 |
|
|
|
46 |
#include "opt_acpi.h" |
47 |
|
46 |
#include <sys/param.h> |
48 |
#include <sys/param.h> |
47 |
#include <sys/systm.h> |
49 |
#include <sys/systm.h> |
48 |
#include <sys/kernel.h> |
50 |
#include <sys/kernel.h> |
49 |
#include <sys/module.h> |
51 |
#include <sys/module.h> |
50 |
#include <sys/errno.h> |
52 |
#include <sys/errno.h> |
|
|
53 |
#include <sys/kdb.h> |
51 |
#include <sys/lock.h> |
54 |
#include <sys/lock.h> |
52 |
#include <sys/mutex.h> |
55 |
#include <sys/mutex.h> |
|
|
56 |
#include <sys/proc.h> |
53 |
#include <sys/sx.h> |
57 |
#include <sys/sx.h> |
54 |
#include <sys/syslog.h> |
58 |
#include <sys/syslog.h> |
55 |
#include <sys/bus.h> |
59 |
#include <sys/bus.h> |
Lines 58-63
__FBSDID("$FreeBSD$");
Link Here
|
58 |
#include <machine/bus.h> |
62 |
#include <machine/bus.h> |
59 |
#include <sys/rman.h> |
63 |
#include <sys/rman.h> |
60 |
|
64 |
|
|
|
65 |
#ifdef DEV_ACPI |
66 |
#include <contrib/dev/acpica/include/acpi.h> |
67 |
#include <contrib/dev/acpica/include/accommon.h> |
68 |
#include <dev/acpica/acpivar.h> |
69 |
#endif |
70 |
|
61 |
#include <dev/pci/pcivar.h> |
71 |
#include <dev/pci/pcivar.h> |
62 |
#include <dev/pci/pcireg.h> |
72 |
#include <dev/pci/pcireg.h> |
63 |
#include <dev/iicbus/iicbus.h> |
73 |
#include <dev/iicbus/iicbus.h> |
Lines 70-76
__FBSDID("$FreeBSD$");
Link Here
|
70 |
#define TRANS_PCALL 2 |
80 |
#define TRANS_PCALL 2 |
71 |
#define TRANS_BLOCK 3 |
81 |
#define TRANS_BLOCK 3 |
72 |
|
82 |
|
73 |
static void ig4iic_start(void *xdev); |
83 |
#define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED() || \ |
|
|
84 |
sc->poll || sc->resume) |
85 |
|
86 |
/* |
87 |
* Clock register values calculation formulas and timings are snarfed from |
88 |
* Linux driver. |
89 |
* *S_SCL_HCNT = IC clock rate * (tHIGH + SDA falling time) - 3 |
90 |
* *S_SCL_LCNT = IC clock rate * (tLOW + SCL falling time) - 1 |
91 |
* SDA_TX_HOLD = IC clock rate * SDA hold time |
92 |
* All results are rounded to nearest. |
93 |
* |
94 |
* tLOW and tHIGH periods of the SCL clock are taken from I2C specification: |
95 |
* Speed mode STD FAST FAST+ HIGH |
96 |
* tHIGH 4.0 ns 0.6 ns 0.26 ns 0.06-0.12 ns |
97 |
* tLOW 4.7 ns 1.3 ns 0.5 ns 0.16-0.32 ns |
98 |
* |
99 |
* HIGH Speed mode tHIGH/tLOW values are depend on bus capacitance. |
100 |
*/ |
101 |
static const struct ig4_cfg ig4iic_configs[] = { |
102 |
[IG4_HASWELL] = { |
103 |
.bus_speed = IG4_CTL_SPEED_FAST, |
104 |
.ss_scl_hcnt = 432, |
105 |
.ss_scl_lcnt = 507, |
106 |
.fs_scl_hcnt = 110, |
107 |
.fs_scl_lcnt = 160, |
108 |
.sda_tx_hold = 9, |
109 |
.txfifo_depth = 32, |
110 |
.rxfifo_depth = 32, |
111 |
}, |
112 |
[IG4_ATOM] = { |
113 |
.bus_speed = IG4_CTL_SPEED_FAST, |
114 |
.ss_scl_hcnt = 512, |
115 |
.ss_scl_lcnt = 512, |
116 |
.fs_scl_hcnt = 85, |
117 |
.fs_scl_lcnt = 153, |
118 |
.sda_tx_hold = 6, |
119 |
.txfifo_depth = 32, |
120 |
.rxfifo_depth = 32, |
121 |
}, |
122 |
[IG4_SKYLAKE] = { |
123 |
/* |
124 |
* IC clock rate: 120 MHz |
125 |
* SDA hold time: 230 ns |
126 |
* SDA falling time: 300 ns |
127 |
* SCL falling time: 300 ns |
128 |
*/ |
129 |
.bus_speed = IG4_CTL_SPEED_FAST, |
130 |
.ss_scl_hcnt = 513, |
131 |
.ss_scl_lcnt = 599, |
132 |
.fs_scl_hcnt = 105, |
133 |
.fs_scl_lcnt = 191, |
134 |
.sda_tx_hold = 28, |
135 |
.txfifo_depth = 64, |
136 |
.rxfifo_depth = 64, |
137 |
}, |
138 |
[IG4_APL] = { |
139 |
/* |
140 |
* IC clock rate: 133 MHz |
141 |
* SDA hold time: 207 ns |
142 |
* SDA falling time: 171 ns |
143 |
* SCL falling time: 208 ns |
144 |
*/ |
145 |
.bus_speed = IG4_CTL_SPEED_FAST, |
146 |
.ss_scl_hcnt = 552, |
147 |
.ss_scl_lcnt = 652, |
148 |
.fs_scl_hcnt = 100, |
149 |
.fs_scl_lcnt = 200, |
150 |
.sda_tx_hold = 28, |
151 |
}, |
152 |
}; |
153 |
|
74 |
static void ig4iic_intr(void *cookie); |
154 |
static void ig4iic_intr(void *cookie); |
75 |
static void ig4iic_dump(ig4iic_softc_t *sc); |
155 |
static void ig4iic_dump(ig4iic_softc_t *sc); |
76 |
|
156 |
|
Lines 98-103
reg_read(ig4iic_softc_t *sc, uint32_t reg)
Link Here
|
98 |
return (value); |
178 |
return (value); |
99 |
} |
179 |
} |
100 |
|
180 |
|
|
|
181 |
static void |
182 |
set_intr_mask(ig4iic_softc_t *sc, uint32_t val) |
183 |
{ |
184 |
if (sc->intr_mask != val) { |
185 |
reg_write(sc, IG4_REG_INTR_MASK, val); |
186 |
sc->intr_mask = val; |
187 |
} |
188 |
} |
189 |
|
190 |
static int |
191 |
intrstat2iic(ig4iic_softc_t *sc, uint32_t val) |
192 |
{ |
193 |
uint32_t src; |
194 |
|
195 |
if (val & IG4_INTR_RX_UNDER) |
196 |
reg_read(sc, IG4_REG_CLR_RX_UNDER); |
197 |
if (val & IG4_INTR_RX_OVER) |
198 |
reg_read(sc, IG4_REG_CLR_RX_OVER); |
199 |
if (val & IG4_INTR_TX_OVER) |
200 |
reg_read(sc, IG4_REG_CLR_TX_OVER); |
201 |
|
202 |
if (val & IG4_INTR_TX_ABRT) { |
203 |
src = reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
204 |
reg_read(sc, IG4_REG_CLR_TX_ABORT); |
205 |
/* User-requested abort. Not really a error */ |
206 |
if (src & IG4_ABRTSRC_TRANSFER) |
207 |
return (IIC_ESTATUS); |
208 |
/* Master has lost arbitration */ |
209 |
if (src & IG4_ABRTSRC_ARBLOST) |
210 |
return (IIC_EBUSBSY); |
211 |
/* Did not receive an acknowledge from the remote slave */ |
212 |
if (src & (IG4_ABRTSRC_TXNOACK_ADDR7 | |
213 |
IG4_ABRTSRC_TXNOACK_ADDR10_1 | |
214 |
IG4_ABRTSRC_TXNOACK_ADDR10_2 | |
215 |
IG4_ABRTSRC_TXNOACK_DATA | |
216 |
IG4_ABRTSRC_GENCALL_NOACK)) |
217 |
return (IIC_ENOACK); |
218 |
/* Programming errors */ |
219 |
if (src & (IG4_ABRTSRC_GENCALL_READ | |
220 |
IG4_ABRTSRC_NORESTART_START | |
221 |
IG4_ABRTSRC_NORESTART_10)) |
222 |
return (IIC_ENOTSUPP); |
223 |
/* Other errors */ |
224 |
if (src & IG4_ABRTSRC_ACKED_START) |
225 |
return (IIC_EBUSERR); |
226 |
} |
227 |
/* |
228 |
* TX_OVER, RX_OVER and RX_UNDER are caused by wrong RX/TX FIFO depth |
229 |
* detection or driver's read/write pipelining errors. |
230 |
*/ |
231 |
if (val & (IG4_INTR_TX_OVER | IG4_INTR_RX_OVER)) |
232 |
return (IIC_EOVERFLOW); |
233 |
if (val & IG4_INTR_RX_UNDER) |
234 |
return (IIC_EUNDERFLOW); |
235 |
|
236 |
return (IIC_NOERR); |
237 |
} |
238 |
|
101 |
/* |
239 |
/* |
102 |
* Enable or disable the controller and wait for the controller to acknowledge |
240 |
* Enable or disable the controller and wait for the controller to acknowledge |
103 |
* the state change. |
241 |
* the state change. |
Lines 113-124
set_controller(ig4iic_softc_t *sc, uint32_t ctl)
Link Here
|
113 |
* When the controller is enabled, interrupt on STOP detect |
251 |
* When the controller is enabled, interrupt on STOP detect |
114 |
* or receive character ready and clear pending interrupts. |
252 |
* or receive character ready and clear pending interrupts. |
115 |
*/ |
253 |
*/ |
116 |
if (ctl & IG4_I2C_ENABLE) { |
254 |
set_intr_mask(sc, 0); |
117 |
reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | |
255 |
if (ctl & IG4_I2C_ENABLE) |
118 |
IG4_INTR_RX_FULL); |
|
|
119 |
reg_read(sc, IG4_REG_CLR_INTR); |
256 |
reg_read(sc, IG4_REG_CLR_INTR); |
120 |
} else |
|
|
121 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
122 |
|
257 |
|
123 |
reg_write(sc, IG4_REG_I2C_EN, ctl); |
258 |
reg_write(sc, IG4_REG_I2C_EN, ctl); |
124 |
error = IIC_ETIMEOUT; |
259 |
error = IIC_ETIMEOUT; |
Lines 129-147
set_controller(ig4iic_softc_t *sc, uint32_t ctl)
Link Here
|
129 |
error = 0; |
264 |
error = 0; |
130 |
break; |
265 |
break; |
131 |
} |
266 |
} |
132 |
if (cold) |
267 |
pause("i2cslv", 1); |
133 |
DELAY(1000); |
|
|
134 |
else |
135 |
mtx_sleep(sc, &sc->io_lock, 0, "i2cslv", 1); |
136 |
} |
268 |
} |
137 |
return (error); |
269 |
return (error); |
138 |
} |
270 |
} |
139 |
|
271 |
|
140 |
/* |
272 |
/* |
141 |
* Wait up to 25ms for the requested status using a 25uS polling loop. |
273 |
* Wait up to 25ms for the requested interrupt using a 25uS polling loop. |
142 |
*/ |
274 |
*/ |
143 |
static int |
275 |
static int |
144 |
wait_status(ig4iic_softc_t *sc, uint32_t status) |
276 |
wait_intr(ig4iic_softc_t *sc, uint32_t intr) |
145 |
{ |
277 |
{ |
146 |
uint32_t v; |
278 |
uint32_t v; |
147 |
int error; |
279 |
int error; |
Lines 151-162
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
151 |
|
283 |
|
152 |
error = IIC_ETIMEOUT; |
284 |
error = IIC_ETIMEOUT; |
153 |
|
285 |
|
154 |
for (;;) { |
286 |
while (error == IIC_ETIMEOUT) { |
155 |
/* |
287 |
/* |
156 |
* Check requested status |
288 |
* Check requested status |
157 |
*/ |
289 |
*/ |
158 |
v = reg_read(sc, IG4_REG_I2C_STA); |
290 |
v = reg_read(sc, IG4_REG_RAW_INTR_STAT); |
159 |
if (v & status) { |
291 |
error = intrstat2iic(sc, v & IG4_INTR_ERR_MASK); |
|
|
292 |
if (error) |
293 |
break; |
294 |
|
295 |
if (v & intr) { |
160 |
error = 0; |
296 |
error = 0; |
161 |
break; |
297 |
break; |
162 |
} |
298 |
} |
Lines 165-171
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
165 |
* When waiting for receive data break-out if the interrupt |
301 |
* When waiting for receive data break-out if the interrupt |
166 |
* loaded data into the FIFO. |
302 |
* loaded data into the FIFO. |
167 |
*/ |
303 |
*/ |
168 |
if (status & IG4_STATUS_RX_NOTEMPTY) { |
304 |
if (intr & IG4_INTR_RX_FULL) { |
169 |
if (sc->rpos != sc->rnext) { |
305 |
if (sc->rpos != sc->rnext) { |
170 |
error = 0; |
306 |
error = 0; |
171 |
break; |
307 |
break; |
Lines 177-183
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
177 |
* reset the timeout if we see a change in the transmit |
313 |
* reset the timeout if we see a change in the transmit |
178 |
* FIFO level as progress is being made. |
314 |
* FIFO level as progress is being made. |
179 |
*/ |
315 |
*/ |
180 |
if (status & IG4_STATUS_TX_EMPTY) { |
316 |
if (intr & (IG4_INTR_TX_EMPTY | IG4_INTR_STOP_DET)) { |
181 |
v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; |
317 |
v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; |
182 |
if (txlvl != v) { |
318 |
if (txlvl != v) { |
183 |
txlvl = v; |
319 |
txlvl = v; |
Lines 188-207
wait_status(ig4iic_softc_t *sc, uint32_t status)
Link Here
|
188 |
/* |
324 |
/* |
189 |
* Stop if we've run out of time. |
325 |
* Stop if we've run out of time. |
190 |
*/ |
326 |
*/ |
191 |
if (count_us >= limit_us) |
327 |
if (count_us >= limit_us) { |
|
|
328 |
error = IIC_ETIMEOUT; |
192 |
break; |
329 |
break; |
|
|
330 |
} |
193 |
|
331 |
|
194 |
/* |
332 |
/* |
195 |
* When waiting for receive data let the interrupt do its |
333 |
* When polling is not requested let the interrupt do its work. |
196 |
* work, otherwise poll with the lock held. |
|
|
197 |
*/ |
334 |
*/ |
198 |
if (status & IG4_STATUS_RX_NOTEMPTY) { |
335 |
if (!DO_POLL(sc)) { |
199 |
mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", |
336 |
mtx_lock(&sc->io_lock); |
|
|
337 |
sc->error = 0; |
338 |
set_intr_mask(sc, intr | IG4_INTR_ERR_MASK); |
339 |
error = mtx_sleep(sc, &sc->io_lock, 0, "i2cwait", |
200 |
(hz + 99) / 100); /* sleep up to 10ms */ |
340 |
(hz + 99) / 100); /* sleep up to 10ms */ |
|
|
341 |
if (error != 0) |
342 |
error = IIC_ETIMEOUT; |
343 |
else |
344 |
error = sc->error; |
345 |
set_intr_mask(sc, 0); |
346 |
mtx_unlock(&sc->io_lock); |
201 |
count_us += 10000; |
347 |
count_us += 10000; |
202 |
} else { |
348 |
} else { |
203 |
DELAY(25); |
349 |
DELAY(25); |
204 |
count_us += 25; |
350 |
count_us += 25; |
|
|
351 |
error = IIC_ETIMEOUT; |
205 |
} |
352 |
} |
206 |
} |
353 |
} |
207 |
|
354 |
|
Lines 250-271
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
Link Here
|
250 |
|
397 |
|
251 |
/* |
398 |
/* |
252 |
* Wait for TXFIFO to drain before disabling the controller. |
399 |
* Wait for TXFIFO to drain before disabling the controller. |
253 |
* |
|
|
254 |
* If a write message has not been completed it's really a |
255 |
* programming error, but for now in that case issue an extra |
256 |
* byte + STOP. |
257 |
* |
258 |
* If a read message has not been completed it's also a programming |
259 |
* error, for now just ignore it. |
260 |
*/ |
400 |
*/ |
261 |
wait_status(sc, IG4_STATUS_TX_NOTFULL); |
401 |
wait_intr(sc, IG4_INTR_TX_EMPTY); |
262 |
if (sc->write_started) { |
|
|
263 |
reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP); |
264 |
sc->write_started = 0; |
265 |
} |
266 |
if (sc->read_started) |
267 |
sc->read_started = 0; |
268 |
wait_status(sc, IG4_STATUS_TX_EMPTY); |
269 |
|
402 |
|
270 |
set_controller(sc, 0); |
403 |
set_controller(sc, 0); |
271 |
ctl = reg_read(sc, IG4_REG_CTL); |
404 |
ctl = reg_read(sc, IG4_REG_CTL); |
Lines 288-335
set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
Link Here
|
288 |
* IICBUS API FUNCTIONS |
421 |
* IICBUS API FUNCTIONS |
289 |
*/ |
422 |
*/ |
290 |
static int |
423 |
static int |
291 |
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave) |
424 |
ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave, bool repeated_start) |
292 |
{ |
425 |
{ |
293 |
set_slave_addr(sc, slave >> 1); |
426 |
set_slave_addr(sc, slave >> 1); |
|
|
427 |
|
428 |
if (!repeated_start) { |
429 |
/* |
430 |
* Clear any previous TX/RX FIFOs overflow/underflow bits |
431 |
* and I2C bus STOP condition. |
432 |
*/ |
433 |
reg_read(sc, IG4_REG_CLR_INTR); |
434 |
} |
435 |
|
294 |
return (0); |
436 |
return (0); |
295 |
} |
437 |
} |
296 |
|
438 |
|
|
|
439 |
static int |
440 |
ig4iic_xfer_abort(ig4iic_softc_t *sc) |
441 |
{ |
442 |
int error; |
443 |
|
444 |
/* Request send of STOP condition and flush of TX FIFO */ |
445 |
set_controller(sc, IG4_I2C_ABORT | IG4_I2C_ENABLE); |
446 |
/* |
447 |
* Wait for the TX_ABRT interrupt with ABRTSRC_TRANSFER |
448 |
* bit set in TX_ABRT_SOURCE register. |
449 |
*/ |
450 |
error = wait_intr(sc, IG4_INTR_STOP_DET); |
451 |
|
452 |
return (error == IIC_ESTATUS ? 0 : error); |
453 |
} |
454 |
|
455 |
/* |
456 |
* Amount of unread data before next burst to get better I2C bus utilization. |
457 |
* 2 bytes is enough in FAST mode. 8 bytes is better in FAST+ and HIGH modes. |
458 |
* Intel-recommended value is 16 for DMA transfers with 64-byte depth FIFOs. |
459 |
*/ |
460 |
#define IG4_FIFO_LOWAT 2 |
461 |
|
297 |
static int |
462 |
static int |
298 |
ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, |
463 |
ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, |
299 |
bool repeated_start, bool stop) |
464 |
bool repeated_start, bool stop) |
300 |
{ |
465 |
{ |
301 |
uint32_t cmd; |
466 |
uint32_t cmd; |
302 |
uint16_t i; |
467 |
int requested = 0; |
|
|
468 |
int received = 0; |
469 |
int burst, target, lowat = 0; |
303 |
int error; |
470 |
int error; |
304 |
|
471 |
|
305 |
if (len == 0) |
472 |
if (len == 0) |
306 |
return (0); |
473 |
return (0); |
307 |
|
474 |
|
308 |
cmd = IG4_DATA_COMMAND_RD; |
475 |
while (received < len) { |
309 |
cmd |= repeated_start ? IG4_DATA_RESTART : 0; |
476 |
burst = sc->cfg.txfifo_depth - |
310 |
cmd |= stop && len == 1 ? IG4_DATA_STOP : 0; |
477 |
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK); |
311 |
|
478 |
if (burst <= 0) { |
312 |
/* Issue request for the first byte (could be last as well). */ |
479 |
error = wait_intr(sc, IG4_INTR_TX_EMPTY); |
313 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
480 |
if (error) |
314 |
|
481 |
break; |
315 |
for (i = 0; i < len; i++) { |
482 |
burst = sc->cfg.txfifo_depth; |
316 |
/* |
483 |
} |
317 |
* Maintain a pipeline by queueing the allowance for the next |
484 |
/* Ensure we have enough free space in RXFIFO */ |
318 |
* read before waiting for the current read. |
485 |
burst = MIN(burst, sc->cfg.rxfifo_depth - lowat); |
319 |
*/ |
486 |
target = MIN(requested + burst, (int)len); |
320 |
cmd = IG4_DATA_COMMAND_RD; |
487 |
while (requested < target) { |
321 |
if (i < len - 1) { |
|
|
322 |
cmd = IG4_DATA_COMMAND_RD; |
488 |
cmd = IG4_DATA_COMMAND_RD; |
323 |
cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0; |
489 |
if (repeated_start && requested == 0) |
|
|
490 |
cmd |= IG4_DATA_RESTART; |
491 |
if (stop && requested == len - 1) |
492 |
cmd |= IG4_DATA_STOP; |
324 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
493 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
|
|
494 |
requested++; |
495 |
} |
496 |
/* Leave some data queued to maintain the hardware pipeline */ |
497 |
lowat = 0; |
498 |
if (requested != len && requested - received > IG4_FIFO_LOWAT) |
499 |
lowat = IG4_FIFO_LOWAT; |
500 |
/* After TXFLR fills up, clear it by reading available data */ |
501 |
while (received < requested - lowat) { |
502 |
error = wait_intr(sc, IG4_INTR_RX_FULL); |
503 |
if (error) |
504 |
goto out; |
505 |
buf[received++] = data_read(sc); |
325 |
} |
506 |
} |
326 |
error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY); |
|
|
327 |
if (error) |
328 |
break; |
329 |
buf[i] = data_read(sc); |
330 |
} |
507 |
} |
331 |
|
508 |
out: |
332 |
(void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
|
|
333 |
return (error); |
509 |
return (error); |
334 |
} |
510 |
} |
335 |
|
511 |
|
Lines 338-361
ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
Link Here
|
338 |
bool repeated_start, bool stop) |
514 |
bool repeated_start, bool stop) |
339 |
{ |
515 |
{ |
340 |
uint32_t cmd; |
516 |
uint32_t cmd; |
341 |
uint16_t i; |
517 |
int sent = 0; |
|
|
518 |
int burst, target; |
342 |
int error; |
519 |
int error; |
|
|
520 |
bool lowat_set = false; |
343 |
|
521 |
|
344 |
if (len == 0) |
522 |
if (len == 0) |
345 |
return (0); |
523 |
return (0); |
346 |
|
524 |
|
347 |
cmd = repeated_start ? IG4_DATA_RESTART : 0; |
525 |
while (sent < len) { |
348 |
for (i = 0; i < len; i++) { |
526 |
burst = sc->cfg.txfifo_depth - |
349 |
error = wait_status(sc, IG4_STATUS_TX_NOTFULL); |
527 |
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK); |
350 |
if (error) |
528 |
target = MIN(sent + burst, (int)len); |
351 |
break; |
529 |
/* Leave some data queued to maintain the hardware pipeline */ |
352 |
cmd |= buf[i]; |
530 |
if (sent == 0 && target != len) { |
353 |
cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0; |
531 |
lowat_set = true; |
354 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
532 |
reg_write(sc, IG4_REG_TX_TL, IG4_FIFO_LOWAT); |
355 |
cmd = 0; |
533 |
} |
|
|
534 |
while(sent < target) { |
535 |
cmd = buf[sent]; |
536 |
if (repeated_start && sent == 0) |
537 |
cmd |= IG4_DATA_RESTART; |
538 |
if (stop && sent == len - 1) |
539 |
cmd |= IG4_DATA_STOP; |
540 |
reg_write(sc, IG4_REG_DATA_CMD, cmd); |
541 |
sent++; |
542 |
} |
543 |
if (sent < len) { |
544 |
error = wait_intr(sc, IG4_INTR_TX_EMPTY); |
545 |
if (error) |
546 |
break; |
547 |
} |
356 |
} |
548 |
} |
|
|
549 |
if (lowat_set) |
550 |
reg_write(sc, IG4_REG_TX_TL, 0); |
357 |
|
551 |
|
358 |
(void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
|
|
359 |
return (error); |
552 |
return (error); |
360 |
} |
553 |
} |
361 |
|
554 |
|
Lines 369-374
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
369 |
int unit; |
562 |
int unit; |
370 |
bool rpstart; |
563 |
bool rpstart; |
371 |
bool stop; |
564 |
bool stop; |
|
|
565 |
bool allocated; |
372 |
|
566 |
|
373 |
/* |
567 |
/* |
374 |
* The hardware interface imposes limits on allowed I2C messages. |
568 |
* The hardware interface imposes limits on allowed I2C messages. |
Lines 429-436
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
429 |
return (IIC_ENOTSUPP); |
623 |
return (IIC_ENOTSUPP); |
430 |
} |
624 |
} |
431 |
|
625 |
|
432 |
sx_xlock(&sc->call_lock); |
626 |
/* Check if device is already allocated with iicbus_request_bus() */ |
433 |
mtx_lock(&sc->io_lock); |
627 |
allocated = sx_xlocked(&sc->call_lock) != 0; |
|
|
628 |
if (!allocated) |
629 |
sx_xlock(&sc->call_lock); |
434 |
|
630 |
|
435 |
/* Debugging - dump registers. */ |
631 |
/* Debugging - dump registers. */ |
436 |
if (ig4_dump) { |
632 |
if (ig4_dump) { |
Lines 461-467
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
461 |
error = 0; |
657 |
error = 0; |
462 |
for (i = 0; i < nmsgs; i++) { |
658 |
for (i = 0; i < nmsgs; i++) { |
463 |
if ((msgs[i].flags & IIC_M_NOSTART) == 0) { |
659 |
if ((msgs[i].flags & IIC_M_NOSTART) == 0) { |
464 |
error = ig4iic_xfer_start(sc, msgs[i].slave); |
660 |
error = ig4iic_xfer_start(sc, msgs[i].slave, rpstart); |
465 |
} else { |
661 |
} else { |
466 |
if (!sc->slave_valid || |
662 |
if (!sc->slave_valid || |
467 |
(msgs[i].slave >> 1) != sc->last_slave) { |
663 |
(msgs[i].slave >> 1) != sc->last_slave) { |
Lines 482-495
ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Link Here
|
482 |
else |
678 |
else |
483 |
error = ig4iic_write(sc, msgs[i].buf, msgs[i].len, |
679 |
error = ig4iic_write(sc, msgs[i].buf, msgs[i].len, |
484 |
rpstart, stop); |
680 |
rpstart, stop); |
485 |
if (error != 0) |
681 |
|
|
|
682 |
/* Wait for error or stop condition occurred on the I2C bus */ |
683 |
if (stop && error == 0) { |
684 |
error = wait_intr(sc, IG4_INTR_STOP_DET); |
685 |
if (error == 0) |
686 |
reg_read(sc, IG4_REG_CLR_INTR); |
687 |
} |
688 |
|
689 |
if (error != 0) { |
690 |
/* Send STOP condition if it's not done yet */ |
691 |
if ((reg_read(sc, IG4_REG_RAW_INTR_STAT) & |
692 |
(IG4_INTR_START_DET | IG4_INTR_STOP_DET)) |
693 |
== IG4_INTR_START_DET) |
694 |
ig4iic_xfer_abort(sc); |
695 |
reg_read(sc, IG4_REG_TX_ABRT_SOURCE); |
696 |
reg_read(sc, IG4_REG_CLR_INTR); |
486 |
break; |
697 |
break; |
|
|
698 |
} |
487 |
|
699 |
|
488 |
rpstart = !stop; |
700 |
rpstart = !stop; |
489 |
} |
701 |
} |
490 |
|
702 |
|
491 |
mtx_unlock(&sc->io_lock); |
703 |
if (!allocated) |
492 |
sx_unlock(&sc->call_lock); |
704 |
sx_unlock(&sc->call_lock); |
493 |
return (error); |
705 |
return (error); |
494 |
} |
706 |
} |
495 |
|
707 |
|
Lines 497-505
int
Link Here
|
497 |
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) |
709 |
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) |
498 |
{ |
710 |
{ |
499 |
ig4iic_softc_t *sc = device_get_softc(dev); |
711 |
ig4iic_softc_t *sc = device_get_softc(dev); |
|
|
712 |
bool allocated; |
500 |
|
713 |
|
501 |
sx_xlock(&sc->call_lock); |
714 |
allocated = sx_xlocked(&sc->call_lock) != 0; |
502 |
mtx_lock(&sc->io_lock); |
715 |
if (!allocated) |
|
|
716 |
sx_xlock(&sc->call_lock); |
503 |
|
717 |
|
504 |
/* TODO handle speed configuration? */ |
718 |
/* TODO handle speed configuration? */ |
505 |
if (oldaddr != NULL) |
719 |
if (oldaddr != NULL) |
Lines 508-529
ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
Link Here
|
508 |
if (addr == IIC_UNKNOWN) |
722 |
if (addr == IIC_UNKNOWN) |
509 |
sc->slave_valid = false; |
723 |
sc->slave_valid = false; |
510 |
|
724 |
|
511 |
mtx_unlock(&sc->io_lock); |
725 |
if (!allocated) |
512 |
sx_unlock(&sc->call_lock); |
726 |
sx_unlock(&sc->call_lock); |
513 |
return (0); |
727 |
return (0); |
514 |
} |
728 |
} |
515 |
|
729 |
|
516 |
/* |
|
|
517 |
* Called from ig4iic_pci_attach/detach() |
518 |
*/ |
519 |
int |
730 |
int |
520 |
ig4iic_attach(ig4iic_softc_t *sc) |
731 |
ig4iic_callback(device_t dev, int index, caddr_t data) |
521 |
{ |
732 |
{ |
|
|
733 |
ig4iic_softc_t *sc = device_get_softc(dev); |
734 |
int error = 0; |
735 |
int how; |
736 |
|
737 |
/* |
738 |
* Unfortunately, iicbus_request_bus() can return error code in both |
739 |
* formats, POSIX and IIC. Here we use EAGAIN instead of IIC_EBUSBSY |
740 |
* to match other possibly buggy iicbus_callback implementations. |
741 |
* As iicbus_poll() returns IIC_EBUSBSY, caller should check returned |
742 |
* value for both EAGAIN and IIC_EBUSBSY. Other error codes are POSIX. |
743 |
*/ |
744 |
switch (index) { |
745 |
case IIC_REQUEST_BUS: |
746 |
/* force polling if ig4iic is requested with IIC_DONTWAIT */ |
747 |
how = *(int *)data; |
748 |
if ((how & IIC_WAIT) == 0) { |
749 |
if (sx_try_xlock(&sc->call_lock) == 0) |
750 |
error = EWOULDBLOCK; |
751 |
else |
752 |
sc->poll = 1; |
753 |
} else |
754 |
sx_xlock(&sc->call_lock); |
755 |
break; |
756 |
|
757 |
case IIC_RELEASE_BUS: |
758 |
sc->poll = 0; |
759 |
sx_unlock(&sc->call_lock); |
760 |
break; |
761 |
|
762 |
default: |
763 |
error = EINVAL; |
764 |
} |
765 |
|
766 |
return (error); |
767 |
} |
768 |
|
769 |
#ifdef DEV_ACPI |
770 |
static int |
771 |
ig4iic_acpi_params(ig4iic_softc_t *sc, char *method, |
772 |
uint16_t *scl_hcnt, uint16_t *scl_lcnt, uint16_t *sda_tx_hold) |
773 |
{ |
774 |
ACPI_BUFFER buf; |
775 |
ACPI_HANDLE handle; |
776 |
ACPI_OBJECT *obj, *elems; |
522 |
int error; |
777 |
int error; |
|
|
778 |
|
779 |
handle = acpi_get_handle(sc->dev); |
780 |
if (handle == NULL) |
781 |
return (ENXIO); |
782 |
|
783 |
buf.Pointer = NULL; |
784 |
buf.Length = ACPI_ALLOCATE_BUFFER; |
785 |
|
786 |
if (ACPI_FAILURE(AcpiEvaluateObject(handle, method, NULL, &buf))) |
787 |
return (ENXIO); |
788 |
|
789 |
error = ENXIO; |
790 |
obj = (ACPI_OBJECT *)buf.Pointer; |
791 |
if (obj->Type == ACPI_TYPE_PACKAGE && obj->Package.Count == 3) { |
792 |
elems = obj->Package.Elements; |
793 |
*scl_hcnt = elems[0].Integer.Value & IG4_SCL_CLOCK_MASK; |
794 |
*scl_lcnt = elems[1].Integer.Value & IG4_SCL_CLOCK_MASK; |
795 |
*sda_tx_hold = elems[2].Integer.Value & IG4_SDA_TX_HOLD_MASK; |
796 |
error = 0; |
797 |
} |
798 |
|
799 |
AcpiOsFree(obj); |
800 |
|
801 |
return (error); |
802 |
} |
803 |
#endif /* DEV_ACPI */ |
804 |
|
805 |
static void |
806 |
ig4iic_get_config(ig4iic_softc_t *sc) |
807 |
{ |
808 |
const struct ig4_cfg *cfg; |
523 |
uint32_t v; |
809 |
uint32_t v; |
|
|
810 |
#ifdef DEV_ACPI |
811 |
uint16_t sda_tx_hold; |
812 |
#endif |
524 |
|
813 |
|
525 |
mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF); |
814 |
/* Fetch default hardware config from controller */ |
526 |
sx_init(&sc->call_lock, "IG4 call lock"); |
815 |
sc->cfg.version = reg_read(sc, IG4_REG_COMP_VER); |
|
|
816 |
sc->cfg.bus_speed = reg_read(sc, IG4_REG_CTL) & IG4_CTL_SPEED_MASK; |
817 |
sc->cfg.ss_scl_hcnt = |
818 |
reg_read(sc, IG4_REG_SS_SCL_HCNT) & IG4_SCL_CLOCK_MASK; |
819 |
sc->cfg.ss_scl_lcnt = |
820 |
reg_read(sc, IG4_REG_SS_SCL_LCNT) & IG4_SCL_CLOCK_MASK; |
821 |
sc->cfg.fs_scl_hcnt = |
822 |
reg_read(sc, IG4_REG_FS_SCL_HCNT) & IG4_SCL_CLOCK_MASK; |
823 |
sc->cfg.fs_scl_lcnt = |
824 |
reg_read(sc, IG4_REG_FS_SCL_LCNT) & IG4_SCL_CLOCK_MASK; |
825 |
sc->cfg.sda_tx_hold = |
826 |
reg_read(sc, IG4_REG_SDA_HOLD) & IG4_SDA_TX_HOLD_MASK; |
827 |
|
828 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
829 |
/* REG_COMP_PARAM1 register is not documented in Intel specs */ |
830 |
v = reg_read(sc, IG4_REG_COMP_PARAM1); |
831 |
if (IG4_PARAM1_TXFIFO_DEPTH(v) != 0) |
832 |
sc->cfg.txfifo_depth = IG4_PARAM1_TXFIFO_DEPTH(v); |
833 |
if (IG4_PARAM1_RXFIFO_DEPTH(v) != 0) |
834 |
sc->cfg.rxfifo_depth = IG4_PARAM1_RXFIFO_DEPTH(v); |
835 |
} else { |
836 |
/* |
837 |
* Hardware does not allow FIFO Threshold Levels value to be |
838 |
* set larger than the depth of the buffer. If an attempt is |
839 |
* made to do that, the actual value set will be the maximum |
840 |
* depth of the buffer. |
841 |
*/ |
842 |
v = reg_read(sc, IG4_REG_TX_TL); |
843 |
reg_write(sc, IG4_REG_TX_TL, v | IG4_FIFO_MASK); |
844 |
sc->cfg.txfifo_depth = |
845 |
(reg_read(sc, IG4_REG_TX_TL) & IG4_FIFO_MASK) + 1; |
846 |
reg_write(sc, IG4_REG_TX_TL, v); |
847 |
v = reg_read(sc, IG4_REG_RX_TL); |
848 |
reg_write(sc, IG4_REG_RX_TL, v | IG4_FIFO_MASK); |
849 |
sc->cfg.rxfifo_depth = |
850 |
(reg_read(sc, IG4_REG_RX_TL) & IG4_FIFO_MASK) + 1; |
851 |
reg_write(sc, IG4_REG_RX_TL, v); |
852 |
} |
853 |
|
854 |
/* Override hardware config with precalculated counter values */ |
855 |
if (sc->version < nitems(ig4iic_configs)) { |
856 |
cfg = &ig4iic_configs[sc->version]; |
857 |
if (cfg->bus_speed != 0) |
858 |
sc->cfg.bus_speed = cfg->bus_speed; |
859 |
if (cfg->ss_scl_hcnt != 0) |
860 |
sc->cfg.ss_scl_hcnt = cfg->ss_scl_hcnt; |
861 |
if (cfg->ss_scl_lcnt != 0) |
862 |
sc->cfg.ss_scl_lcnt = cfg->ss_scl_lcnt; |
863 |
if (cfg->fs_scl_hcnt != 0) |
864 |
sc->cfg.fs_scl_hcnt = cfg->fs_scl_hcnt; |
865 |
if (cfg->fs_scl_lcnt != 0) |
866 |
sc->cfg.fs_scl_lcnt = cfg->fs_scl_lcnt; |
867 |
if (cfg->sda_tx_hold != 0) |
868 |
sc->cfg.sda_tx_hold = cfg->sda_tx_hold; |
869 |
if (cfg->txfifo_depth != 0) |
870 |
sc->cfg.txfifo_depth = cfg->txfifo_depth; |
871 |
if (cfg->rxfifo_depth != 0) |
872 |
sc->cfg.rxfifo_depth = cfg->rxfifo_depth; |
873 |
} |
874 |
|
875 |
if (sc->cfg.bus_speed != IG4_CTL_SPEED_STD) |
876 |
sc->cfg.bus_speed = IG4_CTL_SPEED_FAST; |
877 |
|
878 |
#ifdef DEV_ACPI |
879 |
/* Evaluate SSCN and FMCN ACPI methods to fetch timings */ |
880 |
if (ig4iic_acpi_params(sc, "SSCN", |
881 |
&sc->cfg.ss_scl_hcnt, &sc->cfg.ss_scl_lcnt, &sda_tx_hold) == 0 && |
882 |
sc->cfg.bus_speed == IG4_CTL_SPEED_STD && |
883 |
sda_tx_hold != 0) |
884 |
sc->cfg.sda_tx_hold = sda_tx_hold; |
885 |
if (ig4iic_acpi_params(sc, "FMCN", |
886 |
&sc->cfg.fs_scl_hcnt, &sc->cfg.fs_scl_lcnt, &sda_tx_hold) == 0 && |
887 |
sc->cfg.bus_speed == IG4_CTL_SPEED_FAST && |
888 |
sda_tx_hold != 0) |
889 |
sc->cfg.sda_tx_hold = sda_tx_hold; |
890 |
#endif |
891 |
} |
892 |
|
893 |
static int |
894 |
ig4iic_set_config(ig4iic_softc_t *sc) |
895 |
{ |
896 |
uint32_t v; |
527 |
|
897 |
|
528 |
v = reg_read(sc, IG4_REG_DEVIDLE_CTRL); |
898 |
v = reg_read(sc, IG4_REG_DEVIDLE_CTRL); |
529 |
if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) { |
899 |
if (sc->version == IG4_SKYLAKE && (v & IG4_RESTORE_REQUIRED) ) { |
Lines 563-595
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
563 |
|
933 |
|
564 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
934 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
565 |
v = reg_read(sc, IG4_REG_COMP_VER); |
935 |
v = reg_read(sc, IG4_REG_COMP_VER); |
566 |
if (v < IG4_COMP_MIN_VER) { |
936 |
if (v < IG4_COMP_MIN_VER) |
567 |
error = ENXIO; |
937 |
return(ENXIO); |
568 |
goto done; |
|
|
569 |
} |
570 |
} |
938 |
} |
571 |
v = reg_read(sc, IG4_REG_SS_SCL_HCNT); |
|
|
572 |
v = reg_read(sc, IG4_REG_SS_SCL_LCNT); |
573 |
v = reg_read(sc, IG4_REG_FS_SCL_HCNT); |
574 |
v = reg_read(sc, IG4_REG_FS_SCL_LCNT); |
575 |
v = reg_read(sc, IG4_REG_SDA_HOLD); |
576 |
|
939 |
|
577 |
v = reg_read(sc, IG4_REG_SS_SCL_HCNT); |
940 |
if (set_controller(sc, 0)) { |
578 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, v); |
941 |
device_printf(sc->dev, "controller error during attach-1\n"); |
579 |
v = reg_read(sc, IG4_REG_SS_SCL_LCNT); |
942 |
return (ENXIO); |
580 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, v); |
943 |
} |
581 |
|
944 |
|
582 |
/* |
945 |
reg_read(sc, IG4_REG_CLR_INTR); |
583 |
* Program based on a 25000 Hz clock. This is a bit of a |
946 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
584 |
* hack (obviously). The defaults are 400 and 470 for standard |
947 |
sc->intr_mask = 0; |
585 |
* and 60 and 130 for fast. The defaults for standard fail |
948 |
|
586 |
* utterly (presumably cause an abort) because the clock time |
949 |
reg_write(sc, IG4_REG_SS_SCL_HCNT, sc->cfg.ss_scl_hcnt); |
587 |
* is ~18.8ms by default. This brings it down to ~4ms (for now). |
950 |
reg_write(sc, IG4_REG_SS_SCL_LCNT, sc->cfg.ss_scl_lcnt); |
588 |
*/ |
951 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, sc->cfg.fs_scl_hcnt); |
589 |
reg_write(sc, IG4_REG_SS_SCL_HCNT, 100); |
952 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, sc->cfg.fs_scl_lcnt); |
590 |
reg_write(sc, IG4_REG_SS_SCL_LCNT, 125); |
953 |
reg_write(sc, IG4_REG_SDA_HOLD, sc->cfg.sda_tx_hold); |
591 |
reg_write(sc, IG4_REG_FS_SCL_HCNT, 100); |
|
|
592 |
reg_write(sc, IG4_REG_FS_SCL_LCNT, 125); |
593 |
|
954 |
|
594 |
/* |
955 |
/* |
595 |
* Use a threshold of 1 so we get interrupted on each character, |
956 |
* Use a threshold of 1 so we get interrupted on each character, |
Lines 598-610
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
598 |
* |
959 |
* |
599 |
* See ig4_var.h for details on interrupt handler synchronization. |
960 |
* See ig4_var.h for details on interrupt handler synchronization. |
600 |
*/ |
961 |
*/ |
601 |
reg_write(sc, IG4_REG_RX_TL, 1); |
962 |
reg_write(sc, IG4_REG_RX_TL, 0); |
|
|
963 |
reg_write(sc, IG4_REG_TX_TL, 0); |
602 |
|
964 |
|
603 |
reg_write(sc, IG4_REG_CTL, |
965 |
reg_write(sc, IG4_REG_CTL, |
604 |
IG4_CTL_MASTER | |
966 |
IG4_CTL_MASTER | |
605 |
IG4_CTL_SLAVE_DISABLE | |
967 |
IG4_CTL_SLAVE_DISABLE | |
606 |
IG4_CTL_RESTARTEN | |
968 |
IG4_CTL_RESTARTEN | |
607 |
IG4_CTL_SPEED_STD); |
969 |
(sc->cfg.bus_speed & IG4_CTL_SPEED_MASK)); |
|
|
970 |
|
971 |
return (0); |
972 |
} |
973 |
|
974 |
/* |
975 |
* Called from ig4iic_pci_attach/detach() |
976 |
*/ |
977 |
int |
978 |
ig4iic_attach(ig4iic_softc_t *sc) |
979 |
{ |
980 |
int error; |
981 |
|
982 |
mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF); |
983 |
sx_init(&sc->call_lock, "IG4 call lock"); |
984 |
|
985 |
ig4iic_get_config(sc); |
986 |
|
987 |
error = ig4iic_set_config(sc); |
988 |
if (error) |
989 |
goto done; |
608 |
|
990 |
|
609 |
sc->iicbus = device_add_child(sc->dev, "iicbus", -1); |
991 |
sc->iicbus = device_add_child(sc->dev, "iicbus", -1); |
610 |
if (sc->iicbus == NULL) { |
992 |
if (sc->iicbus == NULL) { |
Lines 626-637
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
626 |
} |
1008 |
} |
627 |
#endif |
1009 |
#endif |
628 |
|
1010 |
|
629 |
mtx_lock(&sc->io_lock); |
1011 |
if (set_controller(sc, IG4_I2C_ENABLE)) { |
630 |
if (set_controller(sc, 0)) |
|
|
631 |
device_printf(sc->dev, "controller error during attach-1\n"); |
632 |
if (set_controller(sc, IG4_I2C_ENABLE)) |
633 |
device_printf(sc->dev, "controller error during attach-2\n"); |
1012 |
device_printf(sc->dev, "controller error during attach-2\n"); |
634 |
mtx_unlock(&sc->io_lock); |
1013 |
error = ENXIO; |
|
|
1014 |
goto done; |
1015 |
} |
1016 |
if (set_controller(sc, 0)) { |
1017 |
device_printf(sc->dev, "controller error during attach-3\n"); |
1018 |
error = ENXIO; |
1019 |
goto done; |
1020 |
} |
635 |
error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, |
1021 |
error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, |
636 |
NULL, ig4iic_intr, sc, &sc->intr_handle); |
1022 |
NULL, ig4iic_intr, sc, &sc->intr_handle); |
637 |
if (error) { |
1023 |
if (error) { |
Lines 639-676
ig4iic_attach(ig4iic_softc_t *sc)
Link Here
|
639 |
"Unable to setup irq: error %d\n", error); |
1025 |
"Unable to setup irq: error %d\n", error); |
640 |
} |
1026 |
} |
641 |
|
1027 |
|
642 |
sc->enum_hook.ich_func = ig4iic_start; |
|
|
643 |
sc->enum_hook.ich_arg = sc->dev; |
644 |
|
645 |
/* |
646 |
* We have to wait until interrupts are enabled. I2C read and write |
647 |
* only works if the interrupts are available. |
648 |
*/ |
649 |
if (config_intrhook_establish(&sc->enum_hook) != 0) |
650 |
error = ENOMEM; |
651 |
else |
652 |
error = 0; |
653 |
|
654 |
done: |
655 |
return (error); |
656 |
} |
657 |
|
658 |
void |
659 |
ig4iic_start(void *xdev) |
660 |
{ |
661 |
int error; |
662 |
ig4iic_softc_t *sc; |
663 |
device_t dev = (device_t)xdev; |
664 |
|
665 |
sc = device_get_softc(dev); |
666 |
|
667 |
config_intrhook_disestablish(&sc->enum_hook); |
668 |
|
669 |
error = bus_generic_attach(sc->dev); |
1028 |
error = bus_generic_attach(sc->dev); |
670 |
if (error) { |
1029 |
if (error) { |
671 |
device_printf(sc->dev, |
1030 |
device_printf(sc->dev, |
672 |
"failed to attach child: error %d\n", error); |
1031 |
"failed to attach child: error %d\n", error); |
673 |
} |
1032 |
} |
|
|
1033 |
|
1034 |
done: |
1035 |
return (error); |
674 |
} |
1036 |
} |
675 |
|
1037 |
|
676 |
int |
1038 |
int |
Lines 689-702
ig4iic_detach(ig4iic_softc_t *sc)
Link Here
|
689 |
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); |
1051 |
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); |
690 |
|
1052 |
|
691 |
sx_xlock(&sc->call_lock); |
1053 |
sx_xlock(&sc->call_lock); |
692 |
mtx_lock(&sc->io_lock); |
|
|
693 |
|
1054 |
|
694 |
sc->iicbus = NULL; |
1055 |
sc->iicbus = NULL; |
695 |
sc->intr_handle = NULL; |
1056 |
sc->intr_handle = NULL; |
696 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
1057 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
697 |
set_controller(sc, 0); |
1058 |
set_controller(sc, 0); |
698 |
|
1059 |
|
699 |
mtx_unlock(&sc->io_lock); |
|
|
700 |
sx_xunlock(&sc->call_lock); |
1060 |
sx_xunlock(&sc->call_lock); |
701 |
|
1061 |
|
702 |
mtx_destroy(&sc->io_lock); |
1062 |
mtx_destroy(&sc->io_lock); |
Lines 705-710
ig4iic_detach(ig4iic_softc_t *sc)
Link Here
|
705 |
return (0); |
1065 |
return (0); |
706 |
} |
1066 |
} |
707 |
|
1067 |
|
|
|
1068 |
int |
1069 |
ig4iic_suspend(ig4iic_softc_t *sc) |
1070 |
{ |
1071 |
int error; |
1072 |
|
1073 |
/* suspend all children */ |
1074 |
error = bus_generic_suspend(sc->dev); |
1075 |
|
1076 |
/* |
1077 |
* set IG4_DEVICE_IDLE and IG4_RESTORE_REQUIRED |
1078 |
* to place the device in the idle state, just to be safe |
1079 |
*/ |
1080 |
if (sc->version == IG4_SKYLAKE) { |
1081 |
sx_xlock(&sc->call_lock); |
1082 |
|
1083 |
reg_write(sc, IG4_REG_DEVIDLE_CTRL, |
1084 |
IG4_DEVICE_IDLE | IG4_RESTORE_REQUIRED); |
1085 |
|
1086 |
sx_xunlock(&sc->call_lock); |
1087 |
} |
1088 |
|
1089 |
return (error); |
1090 |
} |
1091 |
|
1092 |
int ig4iic_resume(ig4iic_softc_t *sc) |
1093 |
{ |
1094 |
int error; |
1095 |
|
1096 |
sx_xlock(&sc->call_lock); |
1097 |
/* Use polling as interrupts might not be available at this moment */ |
1098 |
sc->resume = true; |
1099 |
if (ig4iic_set_config(sc)) |
1100 |
device_printf(sc->dev, "controller error during resume\n"); |
1101 |
/* Force setting of the target address on the next transfer */ |
1102 |
sc->slave_valid = 0; |
1103 |
sx_xunlock(&sc->call_lock); |
1104 |
|
1105 |
error = bus_generic_resume(sc->dev); |
1106 |
|
1107 |
sx_xlock(&sc->call_lock); |
1108 |
sc->resume = false; |
1109 |
sx_xunlock(&sc->call_lock); |
1110 |
|
1111 |
return (error); |
1112 |
} |
1113 |
|
708 |
/* |
1114 |
/* |
709 |
* Interrupt Operation, see ig4_var.h for locking semantics. |
1115 |
* Interrupt Operation, see ig4_var.h for locking semantics. |
710 |
*/ |
1116 |
*/ |
Lines 715-743
ig4iic_intr(void *cookie)
Link Here
|
715 |
uint32_t status; |
1121 |
uint32_t status; |
716 |
|
1122 |
|
717 |
mtx_lock(&sc->io_lock); |
1123 |
mtx_lock(&sc->io_lock); |
718 |
/* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ |
1124 |
if (sc->intr_mask != 0) { |
719 |
reg_read(sc, IG4_REG_CLR_INTR); |
1125 |
status = reg_read(sc, IG4_REG_INTR_STAT); |
720 |
status = reg_read(sc, IG4_REG_I2C_STA); |
1126 |
set_intr_mask(sc, 0); |
721 |
while (status & IG4_STATUS_RX_NOTEMPTY) { |
1127 |
sc->error = intrstat2iic(sc, status); |
722 |
sc->rbuf[sc->rnext & IG4_RBUFMASK] = |
1128 |
if (status & IG4_INTR_RX_FULL) { |
723 |
(uint8_t)reg_read(sc, IG4_REG_DATA_CMD); |
1129 |
status = reg_read(sc, IG4_REG_I2C_STA); |
724 |
++sc->rnext; |
1130 |
while (status & IG4_STATUS_RX_NOTEMPTY) { |
725 |
status = reg_read(sc, IG4_REG_I2C_STA); |
1131 |
sc->rbuf[sc->rnext & IG4_RBUFMASK] = |
726 |
} |
1132 |
(uint8_t)reg_read(sc, IG4_REG_DATA_CMD); |
727 |
|
1133 |
++sc->rnext; |
728 |
/* |
1134 |
status = reg_read(sc, IG4_REG_I2C_STA); |
729 |
* Workaround to trigger pending interrupt if IG4_REG_INTR_STAT |
1135 |
} |
730 |
* is changed after clearing it |
|
|
731 |
*/ |
732 |
if (sc->access_intr_mask != 0) { |
733 |
status = reg_read(sc, IG4_REG_INTR_MASK); |
734 |
if (status != 0) { |
735 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
736 |
reg_write(sc, IG4_REG_INTR_MASK, status); |
737 |
} |
1136 |
} |
738 |
} |
|
|
739 |
|
1137 |
|
740 |
wakeup(sc); |
1138 |
wakeup(sc); |
|
|
1139 |
} else |
1140 |
reg_write(sc, IG4_REG_INTR_MASK, 0); |
741 |
mtx_unlock(&sc->io_lock); |
1141 |
mtx_unlock(&sc->io_lock); |
742 |
} |
1142 |
} |
743 |
|
1143 |
|
Lines 771-780
ig4iic_dump(ig4iic_softc_t *sc)
Link Here
|
771 |
REGDUMP(sc, IG4_REG_DMA_RDLR); |
1171 |
REGDUMP(sc, IG4_REG_DMA_RDLR); |
772 |
REGDUMP(sc, IG4_REG_SDA_SETUP); |
1172 |
REGDUMP(sc, IG4_REG_SDA_SETUP); |
773 |
REGDUMP(sc, IG4_REG_ENABLE_STATUS); |
1173 |
REGDUMP(sc, IG4_REG_ENABLE_STATUS); |
774 |
if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { |
1174 |
REGDUMP(sc, IG4_REG_COMP_PARAM1); |
775 |
REGDUMP(sc, IG4_REG_COMP_PARAM1); |
1175 |
REGDUMP(sc, IG4_REG_COMP_VER); |
776 |
REGDUMP(sc, IG4_REG_COMP_VER); |
|
|
777 |
} |
778 |
if (sc->version == IG4_ATOM) { |
1176 |
if (sc->version == IG4_ATOM) { |
779 |
REGDUMP(sc, IG4_REG_COMP_TYPE); |
1177 |
REGDUMP(sc, IG4_REG_COMP_TYPE); |
780 |
REGDUMP(sc, IG4_REG_CLK_PARMS); |
1178 |
REGDUMP(sc, IG4_REG_CLK_PARMS); |