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

5
Last change on this file since d7c232f was 0cab067, checked in by Sebastian Huber <sebastian.huber@…>, on 03/23/18 at 14:54:12

bsps/powerpc: Move libcpu content to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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