blob: bb91b88ebb3b77e8cdbfc5a4801b860e377d5c92 [file] [log] [blame]
Angel Pons5f249e62020-04-04 18:51:01 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Angel Pons5f249e62020-04-04 18:51:01 +02002
David Hendricks8cbd5692017-12-01 20:49:48 -08003/*
David Hendricks8cbd5692017-12-01 20:49:48 -08004 * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5 */
Angel Pons5f249e62020-04-04 18:51:01 +02006
David Hendricks8cbd5692017-12-01 20:49:48 -08007#include <console/console.h>
8#include <soc/twsi.h>
9#include <soc/clock.h>
10#include <device/i2c.h>
11#include <device/i2c_simple.h>
David Hendricks8cbd5692017-12-01 20:49:48 -080012#include <delay.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020013#include <device/mmio.h>
David Hendricks8cbd5692017-12-01 20:49:48 -080014#include <soc/addressmap.h>
15
16#define TWSI_THP 24
17
18#define TWSI_SW_TWSI 0x1000
19#define TWSI_TWSI_SW 0x1008
20#define TWSI_INT 0x1010
21#define TWSI_SW_TWSI_EXT 0x1018
22
23union twsx_sw_twsi {
24 u64 u;
25 struct {
26 u64 data:32;
27 u64 eop_ia:3;
28 u64 ia:5;
29 u64 addr:10;
30 u64 scr:2;
31 u64 size:3;
32 u64 sovr:1;
33 u64 r:1;
34 u64 op:4;
35 u64 eia:1;
36 u64 slonly:1;
37 u64 v:1;
38 } s;
39};
40
41union twsx_sw_twsi_ext {
42 u64 u;
43 struct {
44 u64 data:32;
45 u64 ia:8;
46 u64 :24;
47 } s;
48};
49
50union twsx_int {
51 u64 u;
52 struct {
53 u64 st_int:1; /** TWSX_SW_TWSI register update int */
54 u64 ts_int:1; /** TWSX_TWSI_SW register update int */
55 u64 core_int:1; /** TWSI core interrupt, ignored for HLC */
56 u64 :5; /** Reserved */
57 u64 sda_ovr:1; /** SDA testing override */
58 u64 scl_ovr:1; /** SCL testing override */
59 u64 sda:1; /** SDA signal */
60 u64 scl:1; /** SCL signal */
61 u64 :52; /** Reserved */
62 } s;
63};
64
65enum {
66 TWSI_OP_WRITE = 0,
67 TWSI_OP_READ = 1,
68};
69
70enum {
71 TWSI_EOP_SLAVE_ADDR = 0,
72 TWSI_EOP_CLK_CTL = 3,
73 TWSI_SW_EOP_IA = 6,
74};
75
76enum {
77 TWSI_SLAVEADD = 0,
78 TWSI_DATA = 1,
79 TWSI_CTL = 2,
80 TWSI_CLKCTL = 3,
81 TWSI_STAT = 3,
82 TWSI_SLAVEADD_EXT = 4,
83 TWSI_RST = 7,
84};
85
86enum {
87 TWSI_CTL_AAK = (1 << 2),
88 TWSI_CTL_IFLG = (1 << 3),
89 TWSI_CTL_STP = (1 << 4),
90 TWSI_CTL_STA = (1 << 5),
91 TWSI_CTL_ENAB = (1 << 6),
92 TWSI_CTL_CE = (1 << 7),
93};
94
95enum {
96 /** Bus error */
97 TWSI_STAT_BUS_ERROR = 0x00,
98 /** Start condition transmitted */
99 TWSI_STAT_START = 0x08,
100 /** Repeat start condition transmitted */
101 TWSI_STAT_RSTART = 0x10,
102 /** Address + write bit transmitted, ACK received */
103 TWSI_STAT_TXADDR_ACK = 0x18,
104 /** Address + write bit transmitted, /ACK received */
105 TWSI_STAT_TXADDR_NAK = 0x20,
106 /** Data byte transmitted in master mode, ACK received */
107 TWSI_STAT_TXDATA_ACK = 0x28,
108 /** Data byte transmitted in master mode, ACK received */
109 TWSI_STAT_TXDATA_NAK = 0x30,
110 /** Arbitration lost in address or data byte */
111 TWSI_STAT_TX_ARB_LOST = 0x38,
112 /** Address + read bit transmitted, ACK received */
113 TWSI_STAT_RXADDR_ACK = 0x40,
114 /** Address + read bit transmitted, /ACK received */
115 TWSI_STAT_RXADDR_NAK = 0x48,
116 /** Data byte received in master mode, ACK transmitted */
117 TWSI_STAT_RXDATA_ACK_SENT = 0x50,
118 /** Data byte received, NACK transmitted */
119 TWSI_STAT_RXDATA_NAK_SENT = 0x58,
120 /** Slave address received, sent ACK */
121 TWSI_STAT_SLAVE_RXADDR_ACK = 0x60,
122 /**
123 * Arbitration lost in address as master, slave address + write bit
124 * received, ACK transmitted
125 */
126 TWSI_STAT_TX_ACK_ARB_LOST = 0x68,
127 /** General call address received, ACK transmitted */
128 TWSI_STAT_RX_GEN_ADDR_ACK = 0x70,
129 /**
130 * Arbitration lost in address as master, general call address
131 * received, ACK transmitted
132 */
133 TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78,
134 /** Data byte received after slave address received, ACK transmitted */
135 TWSI_STAT_SLAVE_RXDATA_ACK = 0x80,
136 /** Data byte received after slave address received, /ACK transmitted */
137 TWSI_STAT_SLAVE_RXDATA_NAK = 0x88,
138 /**
139 * Data byte received after general call address received, ACK
140 * transmitted
141 */
142 TWSI_STAT_GEN_RXADDR_ACK = 0x90,
143 /**
144 * Data byte received after general call address received, /ACK
145 * transmitted
146 */
147 TWSI_STAT_GEN_RXADDR_NAK = 0x98,
148 /** STOP or repeated START condition received in slave mode */
149 TWSI_STAT_STOP_MULTI_START = 0xA0,
150 /** Slave address + read bit received, ACK transmitted */
151 TWSI_STAT_SLAVE_RXADDR2_ACK = 0xA8,
152 /**
153 * Arbitration lost in address as master, slave address + read bit
154 * received, ACK transmitted
155 */
156 TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xB0,
157 /** Data byte transmitted in slave mode, ACK received */
158 TWSI_STAT_SLAVE_TXDATA_ACK = 0xB8,
159 /** Data byte transmitted in slave mode, /ACK received */
160 TWSI_STAT_SLAVE_TXDATA_NAK = 0xC0,
161 /** Last byte transmitted in slave mode, ACK received */
162 TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xC8,
163 /** Second address byte + write bit transmitted, ACK received */
164 TWSI_STAT_TXADDR2DATA_ACK = 0xD0,
165 /** Second address byte + write bit transmitted, /ACK received */
166 TWSI_STAT_TXADDR2DATA_NAK = 0xD8,
167 /** No relevant status information */
168 TWSI_STAT_IDLE = 0xF8
169};
170
171/**
172 * Returns true if we lost arbitration
173 *
174 * @param code status code
175 * @param final_read true if this is the final read operation
176 *
177 * @return true if arbitration has been lost, false if it hasn't been lost.
178 */
179static int twsi_i2c_lost_arb(u8 code, int final_read)
180{
181 switch (code) {
182 /* Arbitration lost */
183 case TWSI_STAT_TX_ARB_LOST:
184 case TWSI_STAT_TX_ACK_ARB_LOST:
185 case TWSI_STAT_RX_GEN_ADDR_ARB_LOST:
186 case TWSI_STAT_RXDATA_ACK_ARB_LOST:
187 return -1;
188
189 /* Being addressed as slave, should back off and listen */
190 case TWSI_STAT_SLAVE_RXADDR_ACK:
191 case TWSI_STAT_RX_GEN_ADDR_ACK:
192 case TWSI_STAT_GEN_RXADDR_ACK:
193 case TWSI_STAT_GEN_RXADDR_NAK:
194 return -1;
195
196 /* Core busy as slave */
197 case TWSI_STAT_SLAVE_RXDATA_ACK:
198 case TWSI_STAT_SLAVE_RXDATA_NAK:
199 case TWSI_STAT_STOP_MULTI_START:
200 case TWSI_STAT_SLAVE_RXADDR2_ACK:
201 case TWSI_STAT_SLAVE_TXDATA_ACK:
202 case TWSI_STAT_SLAVE_TXDATA_NAK:
203 case TWSI_STAT_SLAVE_TXDATA_END_ACK:
204 return -1;
205
206 /* Ack allowed on pre-terminal bytes only */
207 case TWSI_STAT_RXDATA_ACK_SENT:
208 if (!final_read)
209 return 0;
210 return -1;
211
212 /* NAK allowed on terminal byte only */
213 case TWSI_STAT_RXDATA_NAK_SENT:
214 if (!final_read)
215 return 0;
216 return -1;
217
218 case TWSI_STAT_TXDATA_NAK:
219 case TWSI_STAT_TXADDR_NAK:
220 case TWSI_STAT_RXADDR_NAK:
221 case TWSI_STAT_TXADDR2DATA_NAK:
222 return -1;
223 }
224 return 0;
225}
226
227#define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F)
228
229/**
230 * Writes to the MIO_TWS(0..5)_SW_TWSI register
231 *
232 * @param baseaddr Base address of i2c registers
233 * @param sw_twsi value to write
234 *
235 * @return 0 for success, otherwise error
236 */
237static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
238{
239 unsigned long timeout = 500000;
240
241 sw_twsi.s.r = 0;
242 sw_twsi.s.v = 1;
243
244 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
245 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
246 do {
247 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
248 timeout--;
249 } while (sw_twsi.s.v != 0 && timeout > 0);
250
251 if (sw_twsi.s.v)
252 printk(BIOS_ERR, "%s: timed out\n", __func__);
253 return sw_twsi.u;
254}
255
256/**
257 * Reads the MIO_TWS(0..5)_SW_TWSI register
258 *
259 * @param baseaddr Base address of i2c registers
260 * @param sw_twsi value for eia and op, etc. to read
261 *
262 * @return value of the register
263 */
264static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
265{
266 unsigned long timeout = 500000;
267 sw_twsi.s.r = 1;
268 sw_twsi.s.v = 1;
269
270 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
271 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
272
273 do {
274 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
275 timeout--;
276 } while (sw_twsi.s.v != 0 && timeout > 0);
277
278 if (sw_twsi.s.v)
279 printk(BIOS_ERR, "%s: Error writing 0x%llx\n", __func__,
280 sw_twsi.u);
281
282 printk(BIOS_SPEW, "%s: Returning 0x%llx\n", __func__, sw_twsi.u);
283 return sw_twsi.u;
284}
285
286/**
287 * Write control register
288 *
289 * @param baseaddr Base address for i2c registers
290 * @param data data to write
291 */
292static void twsi_write_ctl(void *baseaddr, const u8 data)
293{
294 union twsx_sw_twsi twsi_sw;
295
296 printk(BIOS_SPEW, "%s(%p, 0x%x)\n", __func__, baseaddr, data);
297 twsi_sw.u = 0;
298
299 twsi_sw.s.op = TWSI_SW_EOP_IA;
300 twsi_sw.s.eop_ia = TWSI_CTL;
301 twsi_sw.s.data = data;
302
303 twsi_write_sw(baseaddr, twsi_sw);
304}
305
306/**
307 * Reads the TWSI Control Register
308 *
309 * @param[in] baseaddr Base address for i2c
310 *
311 * @return 8-bit TWSI control register
312 */
313static u32 twsi_read_ctl(void *baseaddr)
314{
315 union twsx_sw_twsi sw_twsi;
316
317 sw_twsi.u = 0;
318 sw_twsi.s.op = TWSI_SW_EOP_IA;
319 sw_twsi.s.eop_ia = TWSI_CTL;
320
321 sw_twsi.u = twsi_read_sw(baseaddr, sw_twsi);
322 printk(BIOS_SPEW, "%s(%p): 0x%x\n", __func__, baseaddr, sw_twsi.s.data);
323 return sw_twsi.s.data;
324}
325
326/**
327 * Read i2c status register
328 *
329 * @param baseaddr Base address of i2c registers
330 *
331 * @return value of status register
332 */
333static u8 twsi_read_status(void *baseaddr)
334{
335 union twsx_sw_twsi twsi_sw;
336
337 twsi_sw.u = 0;
338 twsi_sw.s.op = TWSI_SW_EOP_IA;
339 twsi_sw.s.eop_ia = TWSI_STAT;
340
341 return twsi_read_sw(baseaddr, twsi_sw);
342}
343
344/**
345 * Waits for an i2c operation to complete
346 *
347 * @param baseaddr Base address of registers
348 *
349 * @return 0 for success, 1 if timeout
350 */
351static int twsi_wait(void *baseaddr)
352{
353 unsigned long timeout = 500000;
354 u8 twsi_ctl;
355
356 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
357 do {
358 twsi_ctl = twsi_read_ctl(baseaddr);
359 twsi_ctl &= TWSI_CTL_IFLG;
360 timeout--;
361 } while (!twsi_ctl && timeout > 0);
362
363 printk(BIOS_SPEW, " return: %u\n", !twsi_ctl);
364 return !twsi_ctl;
365}
366
367/**
368 * Sends an i2c stop condition
369 *
370 * @param baseaddr register base address
371 *
372 * @return 0 for success, -1 if error
373 */
374static int twsi_stop(void *baseaddr)
375{
376 u8 stat;
377 twsi_write_ctl(baseaddr, TWSI_CTL_STP | TWSI_CTL_ENAB);
378
379 stat = twsi_read_status(baseaddr);
380 if (stat != TWSI_STAT_IDLE) {
381 printk(BIOS_ERR, "%s: Bad status on bus@%p\n", __func__,
382 baseaddr);
383 return -1;
384 }
385 return 0;
386}
387
388/**
389 * Manually clear the I2C bus and send a stop
390 */
391static void twsi_unblock(void *baseaddr)
392{
393 int i;
394 union twsx_int int_reg;
395
396 int_reg.u = 0;
397 for (i = 0; i < 9; i++) {
398 int_reg.s.scl_ovr = 0;
399 write64(baseaddr + TWSI_INT, int_reg.u);
400 udelay(5);
401 int_reg.s.scl_ovr = 1;
402 write64(baseaddr + TWSI_INT, int_reg.u);
403 udelay(5);
404 }
405 int_reg.s.sda_ovr = 1;
406 write64(baseaddr + TWSI_INT, int_reg.u);
407 udelay(5);
408 int_reg.s.scl_ovr = 0;
409 write64(baseaddr + TWSI_INT, int_reg.u);
410 udelay(5);
411 int_reg.u = 0;
412 write64(baseaddr + TWSI_INT, int_reg.u);
413 udelay(5);
414}
415
416/**
417 * Unsticks the i2c bus
418 *
419 * @param baseaddr base address of registers
420 */
421static int twsi_start_unstick(void *baseaddr)
422{
423 twsi_stop(baseaddr);
424
425 twsi_unblock(baseaddr);
426
427 return 0;
428}
429
430/**
431 * Sends an i2c start condition
432 *
433 * @param baseaddr base address of registers
434 *
435 * @return 0 for success, otherwise error
436 */
437static int twsi_start(void *baseaddr)
438{
439 int result;
440 u8 stat;
441
442 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
443 twsi_write_ctl(baseaddr, TWSI_CTL_STA | TWSI_CTL_ENAB);
444 result = twsi_wait(baseaddr);
445 if (result) {
446 stat = twsi_read_status(baseaddr);
447 printk(BIOS_SPEW, "%s: result: 0x%x, status: 0x%x\n", __func__,
448 result, stat);
449 switch (stat) {
450 case TWSI_STAT_START:
451 case TWSI_STAT_RSTART:
452 return 0;
453 case TWSI_STAT_RXADDR_ACK:
454 default:
455 return twsi_start_unstick(baseaddr);
456 }
457 }
458 printk(BIOS_SPEW, "%s: success\n", __func__);
459 return 0;
460}
461
462/**
463 * Writes data to the i2c bus
464 *
465 * @param baseraddr register base address
466 * @param slave_addr address of slave to write to
467 * @param buffer Pointer to buffer to write
468 * @param length Number of bytes in buffer to write
469 *
470 * @return 0 for success, otherwise error
471 */
472static int twsi_write_data(void *baseaddr, const u8 slave_addr,
473 const u8 *buffer, const unsigned int length)
474{
475 union twsx_sw_twsi twsi_sw;
476 unsigned int curr = 0;
477 int result;
478
479 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, 0x%x)\n", __func__, baseaddr,
480 slave_addr, buffer, length);
481 result = twsi_start(baseaddr);
482 if (result) {
483 printk(BIOS_ERR, "%s: Could not start BUS transaction\n",
484 __func__);
485 return -1;
486 }
487
488 result = twsi_wait(baseaddr);
489 if (result) {
490 printk(BIOS_ERR, "%s: wait failed\n", __func__);
491 return result;
492 }
493
494 twsi_sw.u = 0;
495 twsi_sw.s.op = TWSI_SW_EOP_IA;
496 twsi_sw.s.eop_ia = TWSI_DATA;
497 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_WRITE;
498
499 twsi_write_sw(baseaddr, twsi_sw);
500 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
501
502 printk(BIOS_SPEW, "%s: Waiting\n", __func__);
503 result = twsi_wait(baseaddr);
504 if (result) {
505 printk(BIOS_ERR, "%s: Timed out writing slave address 0x%x\n",
506 __func__, slave_addr);
507 return result;
508 }
509 result = twsi_read_status(baseaddr);
510 if ((result = twsi_read_status(baseaddr)) != TWSI_STAT_TXADDR_ACK) {
511 twsi_stop(baseaddr);
512 return twsi_i2c_lost_arb(result, 0);
513 }
514
515 while (curr < length) {
516 twsi_sw.u = 0;
517 twsi_sw.s.op = TWSI_SW_EOP_IA;
518 twsi_sw.s.eop_ia = TWSI_DATA;
519 twsi_sw.s.data = buffer[curr++];
520
521 twsi_write_sw(baseaddr, twsi_sw);
522 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
523
524 result = twsi_wait(baseaddr);
525 if (result) {
526 printk(BIOS_ERR, "%s: Timed out writing data to 0x%x\n",
527 __func__, slave_addr);
528 return result;
529 }
530 }
531
532 printk(BIOS_SPEW, "%s: Stopping\n", __func__);
533 return twsi_stop(baseaddr);
534}
535
536/**
537 * Performs a read transaction on the i2c bus
538 *
539 * @param baseaddr Base address of twsi registers
540 * @param slave_addr i2c bus address to read from
541 * @param buffer buffer to read into
542 * @param length number of bytes to read
543 *
544 * @return 0 for success, otherwise error
545 */
546static int twsi_read_data(void *baseaddr, const u8 slave_addr,
547 u8 *buffer, const unsigned int length)
548{
549 union twsx_sw_twsi twsi_sw;
550 unsigned int curr = 0;
551 int result;
552
553 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, %u)\n", __func__, baseaddr,
554 slave_addr, buffer, length);
555 result = twsi_start(baseaddr);
556 if (result) {
557 printk(BIOS_ERR, "%s: start failed\n", __func__);
558 return result;
559 }
560
561 result = twsi_wait(baseaddr);
562 if (result) {
563 printk(BIOS_ERR, "%s: wait failed\n", __func__);
564 return result;
565 }
566
567 twsi_sw.u = 0;
568
569 twsi_sw.s.op = TWSI_SW_EOP_IA;
570 twsi_sw.s.eop_ia = TWSI_DATA;
571
572 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_READ;
573
574 twsi_write_sw(baseaddr, twsi_sw);
575 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
576
577 result = twsi_wait(baseaddr);
578 if (result) {
579 printk(BIOS_ERR, "%s: waiting for sending addr failed\n", __func__);
580 return result;
581 }
582
583 result = twsi_read_status(baseaddr);
584 if (result != TWSI_STAT_RXADDR_ACK) {
585 twsi_stop(baseaddr);
586 return twsi_i2c_lost_arb(result, 0);
587 }
588
589 while (curr < length) {
590 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB |
591 ((curr < length - 1) ? TWSI_CTL_AAK : 0));
592
593 result = twsi_wait(baseaddr);
594 if (result) {
595 printk(BIOS_ERR, "%s: waiting for data failed\n",
596 __func__);
597 return result;
598 }
599
600 twsi_sw.u = twsi_read_sw(baseaddr, twsi_sw);
601 buffer[curr++] = twsi_sw.s.data;
602 }
603
604 twsi_stop(baseaddr);
605
606 return 0;
607}
608
609static int twsi_set_speed(void *baseaddr, const unsigned int speed)
610{
611 u64 io_clock_hz;
612 int n_div;
613 int m_div;
614 union twsx_sw_twsi sw_twsi;
615
616 io_clock_hz = thunderx_get_io_clock();
617
618 /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the
619 * clocks M divider based on the SCLK.
620 * TWSI freq = (core freq) / (20 x (M+1) x (thp+1) x 2^N)
621 * M = ((core freq) / (20 x (TWSI freq) x (thp+1) x 2^N)) - 1
622 */
623 for (n_div = 0; n_div < 8; n_div++) {
624 m_div = io_clock_hz / (20 * speed * (TWSI_THP + 1));
625 m_div /= 1 << n_div;
626 m_div -= 1;
627 if (m_div < 16)
628 break;
629 }
630 if (m_div >= 16)
631 return -1;
632
633 sw_twsi.u = 0;
634 sw_twsi.s.v = 1;
635 sw_twsi.s.op = 0x6; /* See EOP field */
636 sw_twsi.s.r = 0; /* Select CLKCTL when R = 0 */
637 sw_twsi.s.eop_ia = 3; /* R=0 selects CLKCTL, R=1 selects STAT */
638 sw_twsi.s.data = ((m_div & 0xf) << 3) | ((n_div & 0x7) << 0);
639
640 twsi_write_sw(baseaddr, sw_twsi);
641 return 0;
642}
643
644int twsi_init(unsigned int bus, enum i2c_speed hz)
645{
646 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
647 if (!baseaddr)
648 return -1;
649
650 if (twsi_set_speed(baseaddr, hz) < 0)
651 return -1;
652
653 /* Enable TWSI, HLC disable, STOP, NAK */
654 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
655
656 return 0;
657}
658
Martin Roth57e89092019-10-23 21:45:23 -0600659int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
David Hendricks8cbd5692017-12-01 20:49:48 -0800660 int seg_count)
661{
662 int result;
663 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
664 if (!baseaddr)
665 return -1;
666
667 printk(BIOS_SPEW, "%s: %d messages\n", __func__, seg_count);
668 for (; seg_count > 0; seg_count--, segments++) {
669 if (segments->flags & I2C_M_RD) {
670 result = twsi_read_data(baseaddr, segments->slave,
671 segments->buf, segments->len);
672 } else {
673 result = twsi_write_data(baseaddr, segments->slave,
674 segments->buf, segments->len);
675 }
676 if (result) {
677 printk(BIOS_ERR, "%s: error transmitting data\n",
678 __func__);
679 return -1;
680 }
681 }
682
683 return 0;
684}