source: rtems/bsps/powerpc/gen83xx/dev/mpc83xx_i2cdrv.c

Last change on this file was a11e1219, checked in by Christian Mauderer <christian.mauderer@…>, on 03/02/22 at 12:51:55

bsps/powerpc/gen83xx: Manual file header clean up

Updates #4625.

  • Property mode set to 100644
File size: 24.9 KB
Line 
1/*
2 * RTEMS support for MPC83xx
3 *
4 * This file contains the MPC83xx I2C driver.
5 */
6
7/*
8 * Copyright (c) 2007 embedded brains GmbH. All rights reserved.
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <stdlib.h>
16#include <bsp.h>
17#include <bsp/irq.h>
18#include <mpc83xx/mpc83xx_i2cdrv.h>
19#include <rtems/error.h>
20#include <rtems/bspIo.h>
21#include <errno.h>
22#include <rtems/libi2c.h>
23
24#undef DEBUG
25
26#if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
27  #define I2CCR_MEN  (1 << 7)   /* module enable */
28#elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
29  #define I2CCR_MDIS (1 << 7)   /* module disable */
30#endif
31#define I2CCR_MIEN (1 << 6)     /* module interrupt enable */
32#define I2CCR_MSTA (1 << 5)     /* 0->1 generates a start condiiton, 1->0 a stop */
33#define I2CCR_MTX  (1 << 4)     /* 0 = receive mode, 1 = transmit mode           */
34#define I2CCR_TXAK (1 << 3)     /* 0 = send ack 1 = send nak during receive      */
35#define I2CCR_RSTA (1 << 2)     /* 1 = send repeated start condition             */
36#define I2CCR_BCST (1 << 0)     /* 0 = disable 1 = enable broadcast accept       */
37
38#define I2CSR_MCF  (1 << 7)     /* data transfer (0=transfer in progres) */
39#define I2CSR_MAAS (1 << 6)     /* addessed as slave   */
40#define I2CSR_MBB  (1 << 5)     /* bus busy            */
41#define I2CSR_MAL  (1 << 4)     /* arbitration lost    */
42#define I2CSR_BCSTM (1 << 3)    /* broadcast match     */
43#define I2CSR_SRW  (1 << 2)     /* slave read/write    */
44#define I2CSR_MIF  (1 << 1)     /* module interrupt    */
45#define I2CSR_RXAK (1 << 0)     /* receive acknowledge */
46
47/*=========================================================================*\
48| Function:                                                                 |
49\*-------------------------------------------------------------------------*/
50static rtems_status_code mpc83xx_i2c_find_clock_divider
51(
52/*-------------------------------------------------------------------------*\
53| Purpose:                                                                  |
54|   determine proper divider value                                          |
55+---------------------------------------------------------------------------+
56| Input Parameters:                                                         |
57\*-------------------------------------------------------------------------*/
58 uint8_t *result,                        /* result value                   */
59 int divider                             /* requested divider              */
60)
61/*-------------------------------------------------------------------------*\
62| Return Value:                                                             |
63|    o = ok or error code                                                   |
64\*=========================================================================*/
65{
66  int i;
67  int fdr_val;
68  rtems_status_code sc = RTEMS_SUCCESSFUL;
69  struct {
70    int divider;
71    int fdr_val;
72  } dividers[] ={
73#if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
74    {  256,0x20 }, {  288,0x21 }, {  320,0x22 }, {  352,0x23 },
75    {  384,0x00 }, {  416,0x01 }, {  448,0x25 }, {  480,0x02 },
76    {  512,0x26 }, {  576,0x03 }, {  640,0x04 }, {  704,0x05 },
77    {  768,0x29 }, {  832,0x06 }, {  896,0x2a }, { 1024,0x07 },
78    { 1152,0x08 }, { 1280,0x09 }, { 1536,0x0A }, { 1792,0x2E },
79    { 1920,0x0B }, { 2048,0x2F }, { 2304,0x0C }, { 2560,0x0D },
80    { 3072,0x0E }, { 3584,0x32 }, { 3840,0x0F }, { 4096,0x33 },
81    { 4608,0x10 }, { 5120,0x11 }, { 6144,0x12 }, { 7168,0x36 },
82    { 7680,0x13 }, { 8192,0x37 }, { 9216,0x14 }, {10240,0x15 },
83    {12288,0x16 }, {14336,0x3A }, {15360,0x17 }, {16384,0x3B },
84    {18432,0x18 }, {20480,0x19 }, {24576,0x1A }, {28672,0x3E },
85    {30720,0x1B }, {32768,0x3F }, {36864,0x1C }, {40960,0x1D },
86    {49152,0x1E }, {61440,0x1F }
87#elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
88    { 768, 0x31 }
89#endif
90  };
91
92  if (divider <= 0) {
93    sc = RTEMS_INVALID_NUMBER;
94  }
95
96  if (sc == RTEMS_SUCCESSFUL) {
97    sc = RTEMS_INVALID_NUMBER;
98    for (i = 0, fdr_val = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) {
99      fdr_val = dividers[i].fdr_val;
100      if (dividers[i].divider >= divider)
101        {
102          sc = RTEMS_SUCCESSFUL;
103          *result = fdr_val;
104          break;
105        }
106    }
107  }
108  return sc;
109}
110
111/*=========================================================================*\
112| Function:                                                                 |
113\*-------------------------------------------------------------------------*/
114static int mpc83xx_i2c_wait
115(
116/*-------------------------------------------------------------------------*\
117| Purpose:                                                                  |
118|   wait for i2c to become idle                                             |
119+---------------------------------------------------------------------------+
120| Input Parameters:                                                         |
121\*-------------------------------------------------------------------------*/
122 mpc83xx_i2c_softc_t *softc_ptr,          /* handle              */
123 uint8_t              desired_status,     /* desired status word */
124 uint8_t              status_mask         /* status word mask    */
125)
126/*-------------------------------------------------------------------------*\
127| Return Value:                                                             |
128|    o = ok or error code                                                   |
129\*=========================================================================*/
130{
131  uint8_t act_status;
132  rtems_status_code rc;
133  uint32_t tout;
134
135#if defined(DEBUG)
136  printk("mpc83xx_i2c_wait called... ");
137#endif
138
139  if (softc_ptr->initialized) {
140    /*
141     * enable interrupt mask
142     */
143    softc_ptr->reg_ptr->i2ccr |= I2CCR_MIEN;
144    rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100);
145    if (rc != RTEMS_SUCCESSFUL) {
146      return rc;
147    }
148  }
149  else {
150    tout = 0;
151    do {
152      if (tout++ > 1000000) {
153#if defined(DEBUG)
154        printk("... exit with RTEMS_TIMEOUT\r\n");
155#endif
156        return RTEMS_TIMEOUT;
157      }
158    } while (!(softc_ptr->reg_ptr->i2csr & I2CSR_MIF));
159  }
160  softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MIEN;
161
162  act_status = softc_ptr->reg_ptr->i2csr;
163  if ((act_status  & status_mask) != desired_status) {
164#if defined(DEBUG)
165    printk("... exit with RTEMS_IO_ERROR\r\n");
166#endif
167    return RTEMS_IO_ERROR;
168  }
169#if defined(DEBUG)
170        printk("... exit OK\r\n");
171#endif
172  return RTEMS_SUCCESSFUL;
173}
174
175/*=========================================================================*\
176| Function:                                                                 |
177\*-------------------------------------------------------------------------*/
178static void mpc83xx_i2c_irq_handler
179(
180/*-------------------------------------------------------------------------*\
181| Purpose:                                                                  |
182|   handle interrupts                                                       |
183+---------------------------------------------------------------------------+
184| Input Parameters:                                                         |
185\*-------------------------------------------------------------------------*/
186 rtems_irq_hdl_param handle     /* handle, is softc_ptr structure          */
187)
188/*-------------------------------------------------------------------------*\
189| Return Value:                                                             |
190|    <none>                                                                 |
191\*=========================================================================*/
192{
193  mpc83xx_i2c_softc_t *softc_ptr = (mpc83xx_i2c_softc_t *)handle;
194
195  /*
196   * clear IRQ flag
197   */
198  #if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
199    softc_ptr->reg_ptr->i2csr &= ~I2CSR_MIF;
200  #elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
201    softc_ptr->reg_ptr->i2csr = I2CSR_MIF;
202  #endif
203
204  /*
205   * disable interrupt mask
206   */
207  softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MIEN;
208  if (softc_ptr->initialized) {
209    rtems_semaphore_release(softc_ptr->irq_sema_id);
210  }
211}
212
213/*=========================================================================*\
214| Function:                                                                 |
215\*-------------------------------------------------------------------------*/
216static void mpc83xx_i2c_irq_on_off
217(
218/*-------------------------------------------------------------------------*\
219| Purpose:                                                                  |
220|   enable/disable interrupts (void, handled at different position)         |
221+---------------------------------------------------------------------------+
222| Input Parameters:                                                         |
223\*-------------------------------------------------------------------------*/
224 const
225 rtems_irq_connect_data *irq_conn_data   /* irq connect data                */
226)
227/*-------------------------------------------------------------------------*\
228| Return Value:                                                             |
229|    <none>                                                                 |
230\*=========================================================================*/
231{
232}
233
234
235/*=========================================================================*\
236| Function:                                                                 |
237\*-------------------------------------------------------------------------*/
238static int mpc83xx_i2c_irq_isOn
239(
240/*-------------------------------------------------------------------------*\
241| Purpose:                                                                  |
242|   check state of interrupts, void, done differently                       |
243+---------------------------------------------------------------------------+
244| Input Parameters:                                                         |
245\*-------------------------------------------------------------------------*/
246 const
247 rtems_irq_connect_data *irq_conn_data  /* irq connect data                */
248)
249/*-------------------------------------------------------------------------*\
250| Return Value:                                                             |
251|    TRUE, if enabled                                                       |
252\*=========================================================================*/
253{
254  return (TRUE);
255}
256
257/*=========================================================================*\
258| Function:                                                                 |
259\*-------------------------------------------------------------------------*/
260static void mpc83xx_i2c_install_irq_handler
261(
262/*-------------------------------------------------------------------------*\
263| Purpose:                                                                  |
264|   (un-)install the interrupt handler                                      |
265+---------------------------------------------------------------------------+
266| Input Parameters:                                                         |
267\*-------------------------------------------------------------------------*/
268 mpc83xx_i2c_softc_t *softc_ptr,        /* ptr to control structure        */
269 int install                            /* TRUE: install, FALSE: remove    */
270)
271/*-------------------------------------------------------------------------*\
272| Return Value:                                                             |
273|    <none>                                                                 |
274\*=========================================================================*/
275{
276  rtems_status_code rc = RTEMS_SUCCESSFUL;
277
278  rtems_irq_connect_data irq_conn_data = {
279    softc_ptr->irq_number,
280    mpc83xx_i2c_irq_handler,           /* rtems_irq_hdl           */
281    (rtems_irq_hdl_param)softc_ptr,    /* (rtems_irq_hdl_param)   */
282    mpc83xx_i2c_irq_on_off,            /* (rtems_irq_enable)      */
283    mpc83xx_i2c_irq_on_off,            /* (rtems_irq_disable)     */
284    mpc83xx_i2c_irq_isOn               /* (rtems_irq_is_enabled)  */
285  };
286
287  /*
288   * (un-)install handler for I2C device
289   */
290  if (install) {
291    /*
292     * create semaphore for IRQ synchronization
293     */
294    rc = rtems_semaphore_create(rtems_build_name('i','2','c','s'),
295                                0,
296                                RTEMS_FIFO
297                                | RTEMS_SIMPLE_BINARY_SEMAPHORE,
298                                0,
299                                &softc_ptr->irq_sema_id);
300    if (rc != RTEMS_SUCCESSFUL) {
301      rtems_panic("I2C: cannot create semaphore");
302    }
303    if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
304      rtems_panic("I2C: cannot install IRQ handler");
305    }
306  }
307  else {
308    if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) {
309      rtems_panic("I2C: cannot uninstall IRQ handler");
310    }
311    /*
312     * delete sync semaphore
313     */
314    if (softc_ptr->irq_sema_id != 0) {
315      rc = rtems_semaphore_delete(softc_ptr->irq_sema_id);
316      if (rc != RTEMS_SUCCESSFUL) {
317        rtems_panic("I2C: cannot delete semaphore");
318      }
319    }
320  }
321}
322
323/*=========================================================================*\
324| Function:                                                                 |
325\*-------------------------------------------------------------------------*/
326static rtems_status_code mpc83xx_i2c_init
327(
328/*-------------------------------------------------------------------------*\
329| Purpose:                                                                  |
330|   initialize the driver                                                   |
331+---------------------------------------------------------------------------+
332| Input Parameters:                                                         |
333\*-------------------------------------------------------------------------*/
334 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
335)
336/*-------------------------------------------------------------------------*\
337| Return Value:                                                             |
338|    o = ok or error code                                                   |
339\*=========================================================================*/
340{
341  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
342  uint8_t fdr_val;
343  int errval;
344#if defined(DEBUG)
345  printk("mpc83xx_i2c_init called... ");
346#endif
347  /*
348   * init HW registers
349   */
350  /*
351   * init frequency divider to 100kHz
352   */
353  errval = mpc83xx_i2c_find_clock_divider(&fdr_val,
354                                          softc_ptr->base_frq/100000);
355  if (errval != 0) {
356    return errval;
357  }
358  softc_ptr->reg_ptr->i2cfdr = fdr_val;
359  /*
360   * init digital filter sampling rate
361   */
362  softc_ptr->reg_ptr->i2cdfsrr = 0x10 ; /* no special filtering needed */
363  /*
364   * set own slave address to broadcast (0x00)
365   */
366  softc_ptr->reg_ptr->i2cadr = 0x00 ;
367
368  /*
369   * set control register to module enable
370   */
371  #if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
372    softc_ptr->reg_ptr->i2ccr = I2CCR_MEN;
373  #elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
374    softc_ptr->reg_ptr->i2ccr = 0;
375  #endif
376
377  /*
378   * init interrupt stuff
379   */
380  mpc83xx_i2c_install_irq_handler(softc_ptr,TRUE);
381
382  /*
383   * mark, that we have initialized
384   */
385  softc_ptr->initialized = TRUE;
386#if defined(DEBUG)
387  printk("... exit OK\r\n");
388#endif
389  return RTEMS_SUCCESSFUL;
390}
391
392/*=========================================================================*\
393| Function:                                                                 |
394\*-------------------------------------------------------------------------*/
395static rtems_status_code mpc83xx_i2c_send_start
396(
397/*-------------------------------------------------------------------------*\
398| Purpose:                                                                  |
399|   send a start condition to bus                                           |
400+---------------------------------------------------------------------------+
401| Input Parameters:                                                         |
402\*-------------------------------------------------------------------------*/
403 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
404)
405/*-------------------------------------------------------------------------*\
406| Return Value:                                                             |
407|    o = ok or error code                                                   |
408\*=========================================================================*/
409{
410  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
411
412#if defined(DEBUG)
413  printk("mpc83xx_i2c_send_start called... ");
414#endif
415  if (0 != (softc_ptr->reg_ptr->i2ccr & I2CCR_MSTA)) {
416    /*
417     * already started, so send a "repeated start"
418     */
419    softc_ptr->reg_ptr->i2ccr |= I2CCR_RSTA;
420  }
421  else {
422    softc_ptr->reg_ptr->i2ccr |= I2CCR_MSTA;
423  }
424
425#if defined(DEBUG)
426  printk("... exit OK\r\n");
427#endif
428  return 0;
429}
430
431/*=========================================================================*\
432| Function:                                                                 |
433\*-------------------------------------------------------------------------*/
434static rtems_status_code mpc83xx_i2c_send_stop
435(
436/*-------------------------------------------------------------------------*\
437| Purpose:                                                                  |
438|   send a stop condition to bus                                            |
439+---------------------------------------------------------------------------+
440| Input Parameters:                                                         |
441\*-------------------------------------------------------------------------*/
442 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
443)
444/*-------------------------------------------------------------------------*\
445| Return Value:                                                             |
446|    o = ok or error code                                                   |
447\*=========================================================================*/
448{
449  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
450
451#if defined(DEBUG)
452  printk("mpc83xx_i2c_send_stop called... ");
453#endif
454  softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MSTA;
455  /*
456   * wait, 'til stop has been executed
457   */
458  while (0 != (softc_ptr->reg_ptr->i2csr & I2CSR_MBB)) {
459    rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
460  }
461#if defined(DEBUG)
462  printk("... exit OK\r\n");
463#endif
464  return 0;
465}
466
467/*=========================================================================*\
468| Function:                                                                 |
469\*-------------------------------------------------------------------------*/
470static rtems_status_code mpc83xx_i2c_send_addr
471(
472/*-------------------------------------------------------------------------*\
473| Purpose:                                                                  |
474|   address a slave device on the bus                                       |
475+---------------------------------------------------------------------------+
476| Input Parameters:                                                         |
477\*-------------------------------------------------------------------------*/
478 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
479 uint32_t addr,                          /* address to send on bus         */
480 int rw                                  /* 0=write,1=read                 */
481)
482/*-------------------------------------------------------------------------*\
483| Return Value:                                                             |
484|    o = ok or error code                                                   |
485\*=========================================================================*/
486{
487  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
488  uint8_t addr_byte;
489  rtems_status_code rc;
490
491#if defined(DEBUG)
492  printk("mpc83xx_i2c_send_addr called... ");
493#endif
494  softc_ptr->reg_ptr->i2ccr |= I2CCR_MTX;
495  /*
496   * determine, whether short or long address is needed, determine rd/wr
497   */
498  if (addr > 0x7f) {
499    addr_byte = (0xf0
500                 | ((addr >> 7) & 0x06)
501                 | ((rw) ? 1 : 0));
502    /*
503     * send first byte
504     */
505    softc_ptr->reg_ptr->i2cdr = addr_byte;
506    /*
507     * wait for successful transfer
508     */
509    rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | I2CSR_RXAK);
510    if (rc != RTEMS_SUCCESSFUL) {
511#if defined(DEBUG)
512      printk("... exit rc=%d\r\n",rc);
513#endif
514      return rc;
515    }
516  }
517  /*
518   * send (final) byte
519   */
520  addr_byte = ((addr << 1)
521               | ((rw) ? 1 : 0));
522
523  softc_ptr->reg_ptr->i2cdr = addr_byte;
524  /*
525   * wait for successful transfer
526   */
527  rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | I2CSR_RXAK);
528
529#if defined(DEBUG)
530  printk("... exit rc=%d\r\n",rc);
531#endif
532  return rc;
533}
534
535/*=========================================================================*\
536| Function:                                                                 |
537\*-------------------------------------------------------------------------*/
538static int mpc83xx_i2c_read_bytes
539(
540/*-------------------------------------------------------------------------*\
541| Purpose:                                                                  |
542|   receive some bytes from I2C device                                      |
543+---------------------------------------------------------------------------+
544| Input Parameters:                                                         |
545\*-------------------------------------------------------------------------*/
546 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
547 unsigned char *buf,                     /* buffer to store bytes          */
548 int len                                 /* number of bytes to receive     */
549)
550/*-------------------------------------------------------------------------*\
551| Return Value:                                                             |
552|    number of bytes received or (negative) error code                      |
553\*=========================================================================*/
554{
555  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
556  rtems_status_code rc;
557  unsigned char *p = buf;
558
559#if defined(DEBUG)
560  printk("mpc83xx_i2c_read_bytes called... ");
561#endif
562  softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MTX;
563  softc_ptr->reg_ptr->i2ccr &= ~I2CCR_TXAK;
564  /*
565   * FIXME: do we need to deactivate TXAK from the start,
566   * when only one byte is to be received?
567   */
568  /*
569   * we need a dummy transfer here to start the first read
570   */
571  softc_ptr->reg_ptr->i2cdr;
572
573  while (len-- > 0) {
574    if (len == 0) {
575      /*
576       * last byte is not acknowledged
577       */
578      softc_ptr->reg_ptr->i2ccr |= I2CCR_TXAK;
579    }
580    /*
581     * wait 'til end of transfer
582     */
583    rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF);
584    if (rc != RTEMS_SUCCESSFUL) {
585#if defined(DEBUG)
586      printk("... exit rc=%d\r\n",-rc);
587#endif
588      return -rc;
589    }
590    *p++ = softc_ptr->reg_ptr->i2cdr;
591
592  }
593
594 /*
595  * wait 'til end of last transfer
596  */
597  rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF);
598
599#if defined(DEBUG)
600  printk("... exit OK, rc=%d\r\n",p-buf);
601#endif
602  return p - buf;
603}
604
605/*=========================================================================*\
606| Function:                                                                 |
607\*-------------------------------------------------------------------------*/
608static int mpc83xx_i2c_write_bytes
609(
610/*-------------------------------------------------------------------------*\
611| Purpose:                                                                  |
612|   send some bytes to I2C device                                           |
613+---------------------------------------------------------------------------+
614| Input Parameters:                                                         |
615\*-------------------------------------------------------------------------*/
616 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
617 unsigned char *buf,                     /* buffer to send                 */
618 int len                                 /* number of bytes to send        */
619
620)
621/*-------------------------------------------------------------------------*\
622| Return Value:                                                             |
623|    number of bytes sent or (negative) error code                          |
624\*=========================================================================*/
625{
626  mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
627  rtems_status_code rc;
628  unsigned char *p = buf;
629
630#if defined(DEBUG)
631  printk("mpc83xx_i2c_write_bytes called... ");
632#endif
633  softc_ptr->reg_ptr->i2ccr =
634    (softc_ptr->reg_ptr->i2ccr & ~I2CCR_TXAK) | I2CCR_MTX;
635  while (len-- > 0) {
636    int rxack = len != 0 ? I2CSR_RXAK : 0;
637
638    softc_ptr->reg_ptr->i2cdr = *p++;
639    /*
640     * wait 'til end of transfer
641     */
642    rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | rxack);
643    if (rc != RTEMS_SUCCESSFUL) {
644#if defined(DEBUG)
645      printk("... exit rc=%d\r\n",-rc);
646#endif
647      return -rc;
648    }
649  }
650#if defined(DEBUG)
651  printk("... exit OK, rc=%d\r\n",p-buf);
652#endif
653  return p - buf;
654}
655
656rtems_libi2c_bus_ops_t mpc83xx_i2c_ops = {
657  .init = mpc83xx_i2c_init,
658  .send_start = mpc83xx_i2c_send_start,
659  .send_stop = mpc83xx_i2c_send_stop,
660  .send_addr = mpc83xx_i2c_send_addr,
661  .read_bytes = mpc83xx_i2c_read_bytes,
662  .write_bytes = mpc83xx_i2c_write_bytes,
663};
664
Note: See TracBrowser for help on using the repository browser.