Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:52

0001 /*
0002  * RTEMS generic MPC5200 BSP
0003  *
0004  * MBUS module (I2C bus) driver
0005  *
0006  * Adapted from:
0007  * MCF5206e MBUS module (I2C bus) driver
0008  */
0009 
0010 /*
0011  * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
0012  * Author: Victor V. Vengerov <vvv@oktet.ru>
0013  * Copyright (c) 2005 embedded brains GmbH & Co. KG
0014  *
0015  * The license and distribution terms for this file may be
0016  * found in the file LICENSE in this distribution or at
0017  * http://www.rtems.org/license/LICENSE.
0018  */
0019 
0020 #include "../i2c/mpc5200mbus.h"
0021 #include <bsp/mpc5200.h>
0022 #include <bsp/irq.h>
0023 #include <bsp/i2c.h>
0024 
0025 /* Events of I2C machine */
0026 typedef enum i2c_event {
0027     EVENT_NONE,      /* Spurious event */
0028     EVENT_TRANSFER,  /* Start new transfer */
0029     EVENT_NEXTMSG,   /* Start processing of next message in transfer */
0030     EVENT_ACK,       /* Sending finished with ACK */
0031     EVENT_NACK,      /* Sending finished with NACK */
0032     EVENT_TIMEOUT,   /* Timeout occured */
0033     EVENT_DATA_RECV, /* Data received */
0034     EVENT_ARB_LOST,  /* Arbitration lost */
0035     EVENT_SLAVE      /* Addressed as a slave */
0036 } i2c_event;
0037 
0038 /*** Auxillary primitives ***/
0039 
0040 /* Change state of finite state machine */
0041 #define next_state(bus,new_state) \
0042     do {                             \
0043         (bus)->state = (new_state);  \
0044     } while (0)
0045 
0046 /* Initiate start condition on the I2C bus */
0047 #define mpc5200mbus_start(bus) \
0048     do {                                                  \
0049         mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_MSTA;  \
0050     } while (0)
0051 
0052 /* Initiate stop condition on the I2C bus */
0053 #define mpc5200mbus_stop(bus) \
0054     do {                                                    \
0055         mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MSTA; \
0056     } while (0)
0057 
0058 /* Initiate repeat start condition on the I2C bus */
0059 #define mpc5200mbus_rstart(bus) \
0060     do {                                                    \
0061         mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_RSTA;  \
0062     } while (0)
0063 
0064 /* Send byte to the bus */
0065 #define mpc5200mbus_send(bus,byte) \
0066     do {                                      \
0067         mpc5200.i2c_regs[bus->bus_idx].mdr = (byte); \
0068     } while (0)
0069 
0070 /* Set transmit mode */
0071 #define mpc5200mbus_tx_mode(bus) \
0072     do {                                                     \
0073         mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_MTX;    \
0074     } while (0)
0075 
0076 /* Set receive mode */
0077 #define mpc5200mbus_rx_mode(bus) \
0078     do {                                                 \
0079         mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MTX;   \
0080         (void)mpc5200.i2c_regs[bus->bus_idx].mdr;                 \
0081     } while (0)
0082 
0083 
0084 /* Transmit acknowledge when byte received */
0085 #define mpc5200mbus_send_ack(bus) \
0086     do {                                                     \
0087          mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_TXAK;  \
0088     } while (0)
0089 
0090 /* DO NOT transmit acknowledge when byte received */
0091 #define mpc5200mbus_send_nack(bus) \
0092     do {                                                     \
0093         mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_TXAK;   \
0094     } while (0)
0095 
0096 #define mpc5200mbus_error(bus,err_status) \
0097     do {                                                       \
0098         do {                                                   \
0099            (bus)->cmsg->status = (err_status);                 \
0100            (bus)->cmsg++;                                      \
0101         } while (((bus)->cmsg - (bus)->msg < (bus)->nmsg) &&   \
0102                  ((bus)->cmsg->flags & I2C_MSG_ERRSKIP));      \
0103         bus->cmsg--;                                           \
0104     } while (0)
0105 
0106 /* mpc5200mbus_get_event --
0107  *     Read MBUS module status register, determine interrupt reason and
0108  *     return appropriate event.
0109  *
0110  * PARAMETERS:
0111  *     bus - pointer to MBUS module descriptor structure
0112  *
0113  * RETURNS:
0114  *     event code
0115  */
0116 static i2c_event
0117 mpc5200mbus_get_event(mpc5200mbus *bus)
0118 {
0119     i2c_event event;
0120     uint8_t   status, control;
0121     rtems_interrupt_level level;
0122     rtems_interrupt_disable(level);
0123     status = mpc5200.i2c_regs[bus->bus_idx].msr;
0124     control = mpc5200.i2c_regs[bus->bus_idx].mcr;
0125     if (status & MPC5200_I2C_MSR_MIF) /* Interrupt occured */
0126     {
0127         if (status & MPC5200_I2C_MSR_MAAS)
0128         {
0129             event = EVENT_SLAVE;
0130             mpc5200.i2c_regs[bus->bus_idx].mcr = control; /* To clear Addressed As Slave
0131                                                     condition */
0132         }
0133         else if (status & MPC5200_I2C_MSR_MAL) /* Arbitration lost */
0134         {
0135             mpc5200.i2c_regs[bus->bus_idx].msr = status & ~MPC5200_I2C_MSR_MAL;
0136             event = EVENT_ARB_LOST;
0137         }
0138         else if (control & MPC5200_I2C_MCR_MTX) /* Trasmit mode */
0139         {
0140             if (status & MPC5200_I2C_MSR_RXAK)
0141                 event = EVENT_NACK;
0142             else
0143                 event = EVENT_ACK;
0144         }
0145         else /* Received */
0146         {
0147             event = EVENT_DATA_RECV;
0148         }
0149 
0150         /* Clear interrupt condition */
0151         mpc5200.i2c_regs[bus->bus_idx].msr &= ~MPC5200_I2C_MSR_MIF;
0152     }
0153     else
0154     {
0155         event = EVENT_NONE;
0156     }
0157     rtems_interrupt_enable(level);
0158     return event;
0159 }
0160 
0161 static void
0162 mpc5200mbus_machine_error(mpc5200mbus *bus, i2c_event event)
0163 {
0164     return;
0165 }
0166 
0167 /* mpc5200mbus_machine --
0168  *     finite state machine for I2C bus protocol
0169  *
0170  * PARAMETERS:
0171  *     bus - pointer to ColdFire MBUS descriptor structure
0172  *     event - I2C event
0173  *
0174  * RETURNS:
0175  *     none
0176  */
0177 static void
0178 mpc5200mbus_machine(mpc5200mbus *bus, i2c_event event)
0179 {
0180     uint8_t   b;
0181     switch (bus->state)
0182     {
0183 
0184         case STATE_UNINITIALIZED:
0185       /* this should never happen. */
0186       mpc5200mbus_machine_error(bus, event);
0187       break;
0188         case STATE_IDLE:
0189             switch (event)
0190             {
0191                 case EVENT_NEXTMSG:  /* Start new message processing */
0192                     bus->cmsg++;
0193                     /* FALLTHRU */
0194 
0195                 case EVENT_TRANSFER: /* Initiate new transfer */
0196                     if (bus->cmsg - bus->msg >= bus->nmsg)
0197                     {
0198                         mpc5200mbus_stop(bus);
0199                         next_state(bus, STATE_IDLE);
0200                         bus->msg = bus->cmsg = NULL;
0201                         bus->nmsg = bus->byte = 0;
0202                         bus->done(bus->done_arg_ptr);
0203                         break;
0204                     }
0205 
0206                     /* Initiate START or REPEATED START condition on the bus */
0207                     if (event == EVENT_TRANSFER)
0208                     {
0209                         mpc5200mbus_start(bus);
0210                     }
0211                     else /* (event == EVENT_NEXTMSG) */
0212                     {
0213                         mpc5200mbus_rstart(bus);
0214                     }
0215 
0216                     bus->byte = 0;
0217                     mpc5200mbus_tx_mode(bus);
0218 
0219                     /* Initiate slave address sending */
0220                     if (bus->cmsg->flags & I2C_MSG_ADDR_10)
0221                     {
0222                         i2c_address a = bus->cmsg->addr;
0223                         b = 0xf0 | (((a >> 8) & 0x03) << 1);
0224                         if (bus->cmsg->flags & I2C_MSG_WR)
0225                         {
0226                             mpc5200mbus_send(bus, b);
0227                             next_state(bus, STATE_ADDR_1_W);
0228                         }
0229                         else
0230                         {
0231                             mpc5200mbus_send(bus, b | 1);
0232                             next_state(bus, STATE_ADDR_1_R);
0233                         }
0234                     }
0235                     else
0236                     {
0237                         b = (bus->cmsg->addr & ~0x01);
0238 
0239                         if (bus->cmsg->flags & I2C_MSG_WR)
0240                         {
0241                             next_state(bus, STATE_SENDING);
0242                         }
0243                         else
0244                         {
0245                             next_state(bus, STATE_ADDR_7);
0246                             b |= 1;
0247                         }
0248 
0249                         mpc5200mbus_send(bus, b);
0250                     }
0251                     break;
0252 
0253                 default:
0254                     mpc5200mbus_machine_error(bus, event);
0255                     break;
0256             }
0257             break;
0258 
0259         case STATE_ADDR_7:
0260             switch (event)
0261             {
0262                 case EVENT_ACK:
0263                     mpc5200mbus_rx_mode(bus);
0264                     if (bus->cmsg->len <= 1)
0265                         mpc5200mbus_send_nack(bus);
0266                     else
0267                         mpc5200mbus_send_ack(bus);
0268                     next_state(bus, STATE_RECEIVING);
0269                     break;
0270 
0271                 case EVENT_NACK:
0272                     mpc5200mbus_error(bus, I2C_NO_DEVICE);
0273                     next_state(bus, STATE_IDLE);
0274                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0275                     break;
0276 
0277                 case EVENT_ARB_LOST:
0278                     mpc5200mbus_error(bus, I2C_ARBITRATION_LOST);
0279                     next_state(bus, STATE_IDLE);
0280                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0281                     break;
0282 
0283                 default:
0284                     mpc5200mbus_machine_error(bus, event);
0285                     break;
0286             }
0287             break;
0288 
0289         case STATE_ADDR_1_R:
0290         case STATE_ADDR_1_W:
0291             switch (event)
0292             {
0293                 case EVENT_ACK:
0294                 {
0295                     uint8_t   b = (bus->cmsg->addr & 0xff);
0296                     mpc5200mbus_send(bus, b);
0297                     if (bus->state == STATE_ADDR_1_W)
0298                     {
0299                         next_state(bus, STATE_SENDING);
0300                     }
0301                     else
0302                     {
0303                         i2c_address a;
0304                         mpc5200mbus_rstart(bus);
0305                         mpc5200mbus_tx_mode(bus);
0306                         a = bus->cmsg->addr;
0307                         b = 0xf0 | (((a >> 8) & 0x03) << 1) | 1;
0308                         mpc5200mbus_send(bus, b);
0309                         next_state(bus, STATE_ADDR_7);
0310                     }
0311                     break;
0312                 }
0313 
0314                 case EVENT_NACK:
0315                     mpc5200mbus_error(bus, I2C_NO_DEVICE);
0316                     next_state(bus, STATE_IDLE);
0317                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0318                     break;
0319 
0320                 case EVENT_ARB_LOST:
0321                     mpc5200mbus_error(bus, I2C_ARBITRATION_LOST);
0322                     next_state(bus, STATE_IDLE);
0323                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0324                     break;
0325 
0326                 default:
0327                     mpc5200mbus_machine_error(bus, event);
0328                     break;
0329             }
0330             break;
0331 
0332         case STATE_SENDING:
0333             switch (event)
0334             {
0335                 case EVENT_ACK:
0336                     if (bus->byte == bus->cmsg->len)
0337                     {
0338                         next_state(bus, STATE_IDLE);
0339                         mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0340                     }
0341                     else
0342                     {
0343                         mpc5200mbus_send(bus, bus->cmsg->buf[bus->byte++]);
0344                         next_state(bus, STATE_SENDING);
0345                     }
0346                     break;
0347 
0348                 case EVENT_NACK:
0349                     if (bus->byte == 0)
0350                     {
0351                         mpc5200mbus_error(bus, I2C_NO_DEVICE);
0352                     }
0353                     else
0354                     {
0355                         mpc5200mbus_error(bus, I2C_NO_ACKNOWLEDGE);
0356                     }
0357                     next_state(bus, STATE_IDLE);
0358                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0359                     break;
0360 
0361                 case EVENT_ARB_LOST:
0362                     mpc5200mbus_error(bus, I2C_ARBITRATION_LOST);
0363                     next_state(bus, STATE_IDLE);
0364                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0365                     break;
0366 
0367                 default:
0368                     mpc5200mbus_machine_error(bus, event);
0369                     break;
0370 
0371             }
0372             break;
0373 
0374         case STATE_RECEIVING:
0375             switch (event)
0376             {
0377                 case EVENT_DATA_RECV:
0378                     if (bus->cmsg->len - bus->byte <= 2)
0379                     {
0380                         mpc5200mbus_send_nack(bus);
0381                         if (bus->cmsg->len - bus->byte <= 1)
0382                         {
0383                             if (bus->cmsg - bus->msg + 1 == bus->nmsg)
0384                                 mpc5200mbus_stop(bus);
0385                             else
0386                                 mpc5200mbus_rstart(bus);
0387                         }
0388                     }
0389                     else
0390                     {
0391                         mpc5200mbus_send_ack(bus);
0392                     }
0393                     bus->cmsg->buf[bus->byte++] = mpc5200.i2c_regs[bus->bus_idx].mdr;
0394                     if (bus->cmsg->len == bus->byte)
0395                     {
0396                         next_state(bus,STATE_IDLE);
0397                         mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0398                     }
0399                     else
0400                     {
0401                         next_state(bus,STATE_RECEIVING);
0402                     }
0403                     break;
0404 
0405                 case EVENT_ARB_LOST:
0406                     mpc5200mbus_error(bus, I2C_ARBITRATION_LOST);
0407                     next_state(bus, STATE_IDLE);
0408                     mpc5200mbus_machine(bus, EVENT_NEXTMSG);
0409                     break;
0410 
0411                 default:
0412                     mpc5200mbus_machine_error(bus, event);
0413                     break;
0414             }
0415             break;
0416     }
0417 }
0418 
0419 /* mpc5200mbus_interrupt_handler --
0420  *     MBUS module interrupt handler routine
0421  *
0422  * PARAMETERS:
0423  *     handle: pointer to mbus structure
0424  *
0425  * RETURNS:
0426  *     none
0427  */
0428 static void mpc5200mbus_interrupt_handler(rtems_irq_hdl_param handle)
0429 {
0430     i2c_event event;
0431     mpc5200mbus *bus = handle;
0432 
0433     event = mpc5200mbus_get_event(bus);
0434     /*
0435      * clear interrupt bit
0436      */
0437     mpc5200.i2c_regs[bus->bus_idx].msr &= ~MPC5200_I2C_MSR_MIF;
0438 
0439     mpc5200mbus_machine(bus, event);
0440 }
0441 
0442 /*
0443  * mpc5200_mbus_irq_enable
0444  *    enable irq for mbus
0445  */
0446 static void mpc5200mbus_irq_enable(const rtems_irq_connect_data* ptr)
0447 {
0448   int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx;
0449 
0450   mpc5200.i2c_regs[minor].mcr |= MPC5200_I2C_MCR_MIEN;
0451 }
0452 
0453 /*
0454  * mpc5200_mbus_irq_disable
0455  *    enable irq for mbus
0456  */
0457 static void mpc5200mbus_irq_disable(const rtems_irq_connect_data* ptr)
0458 {
0459   int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx;
0460 
0461   mpc5200.i2c_regs[minor].mcr &= ~MPC5200_I2C_MCR_MIEN;
0462 }
0463 
0464 /*
0465  * mpc5200_mbus_isOn
0466  *    check, whether irq is enabled
0467  */
0468 static int mpc5200mbus_irq_isOn(const rtems_irq_connect_data* ptr)
0469 {
0470   int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx;
0471 
0472   return (0 != (mpc5200.i2c_regs[minor].mcr & MPC5200_I2C_MCR_MIEN));
0473 }
0474 
0475 /* mpc5200mbus_poll --
0476  *     MBUS module poll routine; used to poll events when I2C driver
0477  *     operates in poll-driven mode.
0478  *
0479  * PARAMETERS:
0480  *     none
0481  *
0482  * RETURNS:
0483  *     none
0484  */
0485 void
0486 mpc5200mbus_poll(mpc5200mbus *bus)
0487 {
0488     i2c_event event;
0489     event = mpc5200mbus_get_event(bus);
0490     if (event != EVENT_NONE)
0491         mpc5200mbus_machine(bus, event);
0492 }
0493 
0494 /* mpc5200mbus_select_clock_divider --
0495  *     Select divider for system clock which is used for I2C bus clock
0496  *     generation. Not each divider can be selected for I2C bus; this
0497  *     function select nearest larger or equal divider.
0498  *
0499  * PARAMETERS:
0500  *     i2c_bus - pointer to the bus descriptor structure
0501  *     divider - system frequency divider for I2C serial clock.
0502  * RETURNS:
0503  *     RTEMS_SUCCESSFUL, if operation performed successfully, or
0504  *     RTEMS error code when failed.
0505  */
0506 rtems_status_code
0507 mpc5200mbus_select_clock_divider(mpc5200mbus *bus, int divider)
0508 {
0509     int i;
0510     int mbc;
0511     struct {
0512         int divider;
0513         int mbc;
0514     } dividers[] ={
0515         { 20,   0x20 }, { 22,   0x21 }, { 24,   0x22 }, { 26,   0x23 },
0516         { 28,   0x00 }, { 30,   0x01 }, { 32,   0x25 }, { 34,   0x02 },
0517         { 36,   0x26 }, { 40,   0x03 }, { 44,   0x04 }, { 48,   0x05 },
0518         { 56,   0x06 }, { 64,   0x2a }, { 68,   0x07 }, { 72,   0x2B },
0519         { 80,   0x08 }, { 88,   0x09 }, { 96,   0x2D }, { 104,  0x0A },
0520         { 112,  0x2E }, { 128,  0x0B }, { 144,  0x0C }, { 160,  0x0D },
0521         { 192,  0x0E }, { 224,  0x32 }, { 240,  0x0F }, { 256,  0x33 },
0522         { 288,  0x10 }, { 320,  0x11 }, { 384,  0x12 }, { 448,  0x36 },
0523         { 480,  0x13 }, { 512,  0x37 }, { 576,  0x14 }, { 640,  0x15 },
0524         { 768,  0x16 }, { 896,  0x3A }, { 960,  0x17 }, { 1024, 0x3B },
0525         { 1152, 0x18 }, { 1280, 0x19 }, { 1536, 0x1A }, { 1792, 0x3E },
0526         { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
0527         { 3072, 0x1E }, { 3840, 0x1F }
0528     };
0529 
0530     if (bus == NULL)
0531         return RTEMS_INVALID_ADDRESS;
0532 
0533     for (i = 0, mbc = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++)
0534     {
0535         mbc = dividers[i].mbc;
0536         if (dividers[i].divider >= divider)
0537         {
0538             break;
0539         }
0540     }
0541     mpc5200.i2c_regs[bus->bus_idx].mfdr = mbc;
0542     return RTEMS_SUCCESSFUL;
0543 }
0544 
0545 /* mpc5200mbus_initialize --
0546  *     Initialize MPC5200 MBUS I2C bus controller.
0547  *
0548  * PARAMETERS:
0549  *     i2c_bus - pointer to the bus descriptor structure
0550  *
0551  * RETURNS:
0552  *     RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed.
0553  */
0554 rtems_status_code
0555 mpc5200mbus_initialize(mpc5200mbus *i2c_bus)
0556 {
0557     rtems_interrupt_level level;
0558     rtems_status_code sc;
0559     rtems_irq_connect_data mbusIrqData;
0560 
0561     if (i2c_bus == NULL)
0562         return RTEMS_INVALID_ADDRESS;
0563 
0564     if (i2c_bus->state != STATE_UNINITIALIZED) /* Check if already initialized */
0565         return RTEMS_RESOURCE_IN_USE;
0566 
0567     i2c_bus->state = STATE_IDLE;
0568     i2c_bus->msg = NULL;
0569     i2c_bus->cmsg = NULL;
0570     i2c_bus->nmsg = 0;
0571     i2c_bus->byte = 0;
0572 
0573     /*
0574      * install interrupt handler
0575      */
0576     mbusIrqData.on     = mpc5200mbus_irq_enable;
0577     mbusIrqData.off    = mpc5200mbus_irq_disable;
0578     mbusIrqData.isOn   = mpc5200mbus_irq_isOn;
0579     mbusIrqData.handle = (rtems_irq_hdl_param)i2c_bus;
0580     mbusIrqData.hdl    = mpc5200mbus_interrupt_handler;
0581     switch(i2c_bus->bus_idx) {
0582     case 0:
0583       mbusIrqData.name   = BSP_SIU_IRQ_I2C1;
0584       break;
0585     case 1:
0586       mbusIrqData.name   = BSP_SIU_IRQ_I2C2;
0587       break;
0588     }
0589     if (!BSP_install_rtems_irq_handler (&mbusIrqData)) {
0590       sc = RTEMS_UNSATISFIED;
0591       return sc;
0592     }
0593 
0594     rtems_interrupt_disable(level);
0595 
0596     mpc5200.i2c_regs[i2c_bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MEN;
0597     mpc5200.i2c_regs[i2c_bus->bus_idx].msr = 0;
0598     mpc5200.i2c_regs[i2c_bus->bus_idx].mdr = 0x1F; /* Maximum possible divider is 3840 */
0599     mpc5200.i2c_regs[i2c_bus->bus_idx].mcr |= MPC5200_I2C_MCR_MEN;
0600 
0601     rtems_interrupt_enable(level);
0602 
0603     return RTEMS_SUCCESSFUL;
0604 }
0605 
0606 /* mpc5200mbus_i2c_transfer --
0607  *     Initiate multiple-messages transfer over I2C bus via ColdFire MBUS
0608  *     controller.
0609  *
0610  * PARAMETERS:
0611  *     bus - pointer to MBUS controller descriptor
0612  *     nmsg - number of messages
0613  *     msg - pointer to messages array
0614  *     done - function which is called when transfer is finished
0615  *     done_arg_ptr - arbitrary argument pointer passed to done funciton
0616  *
0617  * RETURNS:
0618  *     RTEMS_SUCCESSFUL if transfer initiated successfully, or error
0619  *     code when failed.
0620  */
0621 rtems_status_code
0622 mpc5200mbus_i2c_transfer(mpc5200mbus *bus, int nmsg, i2c_message *msg,
0623                      i2c_transfer_done done, void *done_arg_ptr)
0624 {
0625     if (bus->state == STATE_UNINITIALIZED)
0626         return RTEMS_NOT_CONFIGURED;
0627 
0628     bus->done = done;
0629     bus->done_arg_ptr = done_arg_ptr;
0630     bus->cmsg = bus->msg = msg;
0631     bus->nmsg = nmsg;
0632     bus->byte = 0;
0633     bus->state = STATE_IDLE;
0634     mpc5200mbus_machine(bus, EVENT_TRANSFER);
0635     return RTEMS_SUCCESSFUL;
0636 }
0637 
0638 
0639 /* mpc5200mbus_i2c_done --
0640  *     Close ColdFire MBUS I2C bus controller and release all resources.
0641  *
0642  * PARAMETERS:
0643  *     bus - pointer to MBUS controller descriptor
0644  *
0645  * RETURNS:
0646  *     RTEMS_SUCCESSFUL, if transfer initiated successfully, or error
0647  *     code when failed.
0648  */
0649 rtems_status_code
0650 mpc5200mbus_i2c_done(mpc5200mbus *i2c_bus)
0651 {
0652     rtems_status_code sc = RTEMS_SUCCESSFUL;
0653 
0654     if (i2c_bus->state == STATE_UNINITIALIZED)
0655         return RTEMS_NOT_CONFIGURED;
0656 
0657     mpc5200.i2c_regs[i2c_bus->bus_idx].mcr = 0;
0658 
0659     return sc;
0660 }