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

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 26.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * RTEMS support for MPC83xx
5 *
6 * This file contains the MPC83xx SPI driver.
7 * NOTE: it uses the same API as the I2C driver.
8 */
9
10/*
11 * Copyright (c) 2007 embedded brains GmbH & Co. KG
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <stdlib.h>
36#include <bsp.h>
37#include <bsp/irq.h>
38#include <mpc83xx/mpc83xx.h>
39#include <mpc83xx/mpc83xx_spidrv.h>
40#include <rtems/error.h>
41#include <rtems/bspIo.h>
42#include <errno.h>
43#include <rtems/libi2c.h>
44
45#undef DEBUG
46
47/*=========================================================================*\
48| Function:                                                                 |
49\*-------------------------------------------------------------------------*/
50static rtems_status_code mpc83xx_spi_baud_to_mode
51(
52/*-------------------------------------------------------------------------*\
53| Purpose:                                                                  |
54|   determine proper divider value                                          |
55+---------------------------------------------------------------------------+
56| Input Parameters:                                                         |
57\*-------------------------------------------------------------------------*/
58 uint32_t baudrate,                      /* desired baudrate               */
59 uint32_t base_frq,                      /* input frequency                */
60 uint32_t *spimode                       /* result value                   */
61)
62/*-------------------------------------------------------------------------*\
63| Return Value:                                                             |
64|    o = ok or error code                                                   |
65\*=========================================================================*/
66{
67  uint32_t divider;
68  uint32_t tmpmode = 0;
69  /*
70   * determine clock divider and DIV16 bit
71   */
72  divider = (base_frq+baudrate-1)/baudrate;
73  if (divider > 64) {
74    tmpmode = MPC83XX_SPIMODE_DIV16;
75    divider /= 16;
76  }
77  if ((divider <  1) ||
78      (divider > 64)) {
79    return RTEMS_INVALID_NUMBER;
80  }
81  else {
82    tmpmode |= MPC83XX_SPIMODE_PM(divider/4-1);
83  }
84  *spimode = tmpmode;
85  return RTEMS_SUCCESSFUL;
86}
87
88/*=========================================================================*\
89| Function:                                                                 |
90\*-------------------------------------------------------------------------*/
91static rtems_status_code mpc83xx_spi_char_mode
92(
93/*-------------------------------------------------------------------------*\
94| Purpose:                                                                  |
95|   determine proper value for character size                               |
96+---------------------------------------------------------------------------+
97| Input Parameters:                                                         |
98\*-------------------------------------------------------------------------*/
99 mpc83xx_spi_softc_t *softc_ptr,         /* handle                         */
100 uint32_t bits_per_char,                 /* bits per character             */
101 bool     lsb_first,                     /* TRUE: send LSB first           */
102 uint32_t *spimode                       /* result value                   */
103)
104/*-------------------------------------------------------------------------*\
105| Return Value:                                                             |
106|    o = ok or error code                                                   |
107\*=========================================================================*/
108{
109  uint32_t tmpmode;
110
111  if (bits_per_char == 32) {
112    tmpmode = 0;
113    softc_ptr->bytes_per_char = 4;
114    softc_ptr->bit_shift      = 0;
115  }
116  else {
117    if (lsb_first) {
118      /*
119       * non-reversed data (LSB first): 4..16 bits valid
120       * always aligned to bit 16 of data register
121       */
122      if ((bits_per_char >= 4) &&
123          (bits_per_char <= 16)) {
124        tmpmode = MPC83XX_SPIMODE_LEN( bits_per_char-1);
125        softc_ptr->bytes_per_char = (bits_per_char > 8) ? 2 : 1;
126        softc_ptr->bit_shift      = 16-bits_per_char;
127      }
128      else {
129        return RTEMS_INVALID_NUMBER;
130      }
131    }
132    else {
133      /*
134       * reversed data (MSB first): only 8/16/32 bits valid,
135       * always in lowest bits of data register
136       */
137      if (bits_per_char == 8) {
138        tmpmode = MPC83XX_SPIMODE_LEN(8-1);
139        softc_ptr->bytes_per_char = 1;
140        softc_ptr->bit_shift      = 0;
141      }
142      else if (bits_per_char == 16) {
143        tmpmode = MPC83XX_SPIMODE_LEN(16-1);
144        softc_ptr->bytes_per_char = 2;
145        softc_ptr->bit_shift      = 0;
146      }
147      else {
148        return RTEMS_INVALID_NUMBER;
149      }
150    }
151  }
152
153  *spimode = tmpmode;
154  return 0;
155}
156
157/*=========================================================================*\
158| Function:                                                                 |
159\*-------------------------------------------------------------------------*/
160static int mpc83xx_spi_wait
161(
162/*-------------------------------------------------------------------------*\
163| Purpose:                                                                  |
164|   wait for spi to become idle                                             |
165+---------------------------------------------------------------------------+
166| Input Parameters:                                                         |
167\*-------------------------------------------------------------------------*/
168 mpc83xx_spi_softc_t *softc_ptr,          /* handle              */
169 uint32_t             irq_mask,           /* irq mask to use     */
170 uint32_t             desired_status,     /* desired status word */
171 uint32_t             status_mask         /* status word mask    */
172)
173/*-------------------------------------------------------------------------*\
174| Return Value:                                                             |
175|    o = ok or error code                                                   |
176\*=========================================================================*/
177{
178  uint32_t act_status;
179  rtems_status_code rc;
180  uint32_t tout;
181
182#if defined(DEBUG)
183  printk("mpc83xx_spi_wait called... ");
184#endif
185  if (softc_ptr->initialized) {
186    /*
187     * allow interrupts, when receiver is not empty
188     */
189    softc_ptr->reg_ptr->spim = irq_mask;
190    rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100);
191    if (rc != RTEMS_SUCCESSFUL) {
192      return rc;
193    }
194  }
195  else {
196    tout = 0;
197    do {
198      if (tout++ > 1000000) {
199#if defined(DEBUG)
200        printk("... exit with RTEMS_TIMEOUT\r\n");
201#endif
202        return RTEMS_TIMEOUT;
203      }
204      /*
205       * wait for SPI to terminate
206       */
207    } while (!(softc_ptr->reg_ptr->spie & MPC83XX_SPIE_NE));
208  }
209
210  act_status = softc_ptr->reg_ptr->spie;
211  if ((act_status  & status_mask)!= desired_status) {
212#if defined(DEBUG)
213    printk("... exit with RTEMS_IO_ERROR,"
214           "act_status=0x%04x,mask=0x%04x,desired_status=0x%04x\r\n",
215           act_status,status_mask,desired_status);
216#endif
217    return RTEMS_IO_ERROR;
218  }
219#if defined(DEBUG)
220        printk("... exit OK\r\n");
221#endif
222  return RTEMS_SUCCESSFUL;
223}
224
225/*=========================================================================*\
226| Function:                                                                 |
227\*-------------------------------------------------------------------------*/
228static void mpc83xx_spi_irq_handler
229(
230/*-------------------------------------------------------------------------*\
231| Purpose:                                                                  |
232|   handle interrupts                                                       |
233+---------------------------------------------------------------------------+
234| Input Parameters:                                                         |
235\*-------------------------------------------------------------------------*/
236 rtems_irq_hdl_param handle     /* handle, is softc_ptr structure          */
237)
238/*-------------------------------------------------------------------------*\
239| Return Value:                                                             |
240|    <none>                                                                 |
241\*=========================================================================*/
242{
243  mpc83xx_spi_softc_t *softc_ptr = (mpc83xx_spi_softc_t *)handle;
244
245  /*
246   * disable interrupt mask
247   */
248  softc_ptr->reg_ptr->spim = 0;
249  if (softc_ptr->initialized) {
250    rtems_semaphore_release(softc_ptr->irq_sema_id);
251  }
252}
253
254/*=========================================================================*\
255| Function:                                                                 |
256\*-------------------------------------------------------------------------*/
257static void mpc83xx_spi_irq_on_off
258(
259/*-------------------------------------------------------------------------*\
260| Purpose:                                                                  |
261|   enable/disable interrupts (void, handled at different position)         |
262+---------------------------------------------------------------------------+
263| Input Parameters:                                                         |
264\*-------------------------------------------------------------------------*/
265 const
266 rtems_irq_connect_data *irq_conn_data   /* irq connect data                */
267)
268/*-------------------------------------------------------------------------*\
269| Return Value:                                                             |
270|    <none>                                                                 |
271\*=========================================================================*/
272{
273}
274
275
276/*=========================================================================*\
277| Function:                                                                 |
278\*-------------------------------------------------------------------------*/
279static int mpc83xx_spi_irq_isOn
280(
281/*-------------------------------------------------------------------------*\
282| Purpose:                                                                  |
283|   check state of interrupts, void, done differently                       |
284+---------------------------------------------------------------------------+
285| Input Parameters:                                                         |
286\*-------------------------------------------------------------------------*/
287 const
288 rtems_irq_connect_data *irq_conn_data  /* irq connect data                */
289)
290/*-------------------------------------------------------------------------*\
291| Return Value:                                                             |
292|    TRUE, if enabled                                                       |
293\*=========================================================================*/
294{
295  return (TRUE);
296}
297
298/*=========================================================================*\
299| Function:                                                                 |
300\*-------------------------------------------------------------------------*/
301static void mpc83xx_spi_install_irq_handler
302(
303/*-------------------------------------------------------------------------*\
304| Purpose:                                                                  |
305|   (un-)install the interrupt handler                                      |
306+---------------------------------------------------------------------------+
307| Input Parameters:                                                         |
308\*-------------------------------------------------------------------------*/
309 mpc83xx_spi_softc_t *softc_ptr,        /* ptr to control structure        */
310 int install                            /* TRUE: install, FALSE: remove    */
311)
312/*-------------------------------------------------------------------------*\
313| Return Value:                                                             |
314|    <none>                                                                 |
315\*=========================================================================*/
316{
317  rtems_status_code rc = RTEMS_SUCCESSFUL;
318
319  rtems_irq_connect_data irq_conn_data = {
320    softc_ptr->irq_number,
321    mpc83xx_spi_irq_handler,        /* rtems_irq_hdl           */
322    (rtems_irq_hdl_param)softc_ptr, /* (rtems_irq_hdl_param)   */
323    mpc83xx_spi_irq_on_off,         /* (rtems_irq_enable)      */
324    mpc83xx_spi_irq_on_off,         /* (rtems_irq_disable)     */
325    mpc83xx_spi_irq_isOn            /* (rtems_irq_is_enabled)  */
326  };
327
328  /*
329   * (un-)install handler for SPI device
330   */
331  if (install) {
332    /*
333     * create semaphore for IRQ synchronization
334     */
335    rc = rtems_semaphore_create(rtems_build_name('s','p','i','s'),
336                                0,
337                                RTEMS_FIFO
338                                | RTEMS_SIMPLE_BINARY_SEMAPHORE,
339                                0,
340                                &softc_ptr->irq_sema_id);
341    if (rc != RTEMS_SUCCESSFUL) {
342      rtems_panic("SPI: cannot create semaphore");
343    }
344    if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
345      rtems_panic("SPI: cannot install IRQ handler");
346    }
347  }
348  else {
349    if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) {
350      rtems_panic("SPI: cannot uninstall IRQ handler");
351    }
352    /*
353     * delete sync semaphore
354     */
355    if (softc_ptr->irq_sema_id != 0) {
356      rc = rtems_semaphore_delete(softc_ptr->irq_sema_id);
357      if (rc != RTEMS_SUCCESSFUL) {
358        rtems_panic("SPI: cannot delete semaphore");
359      }
360    }
361  }
362}
363
364/*=========================================================================*\
365| Function:                                                                 |
366\*-------------------------------------------------------------------------*/
367rtems_status_code mpc83xx_spi_init
368(
369/*-------------------------------------------------------------------------*\
370| Purpose:                                                                  |
371|   initialize the driver                                                   |
372+---------------------------------------------------------------------------+
373| Input Parameters:                                                         |
374\*-------------------------------------------------------------------------*/
375 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
376)
377/*-------------------------------------------------------------------------*\
378| Return Value:                                                             |
379|    o = ok or error code                                                   |
380\*=========================================================================*/
381{
382  mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc);
383#if defined(DEBUG)
384  printk("mpc83xx_spi_init called... ");
385#endif
386  /*
387   * init HW registers:
388   */
389  /*
390   * FIXME: set default mode in SPIM
391   */
392
393  /*
394   * init interrupt stuff
395   */
396  mpc83xx_spi_install_irq_handler(softc_ptr,TRUE);
397
398  /*
399   * mark, that we have initialized
400   */
401  softc_ptr->initialized = TRUE;
402#if defined(DEBUG)
403  printk("... exit OK\r\n");
404#endif
405  return RTEMS_SUCCESSFUL;
406}
407
408/*=========================================================================*\
409| Function:                                                                 |
410\*-------------------------------------------------------------------------*/
411int mpc83xx_spi_read_write_bytes
412(
413/*-------------------------------------------------------------------------*\
414| Purpose:                                                                  |
415|   transmit/receive some bytes from SPI device                             |
416+---------------------------------------------------------------------------+
417| Input Parameters:                                                         |
418\*-------------------------------------------------------------------------*/
419 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
420 unsigned char *rbuf,                    /* buffer to store bytes          */
421 const unsigned char *tbuf,              /* buffer to send  bytes          */
422 int len                                 /* number of bytes to transceive  */
423)
424/*-------------------------------------------------------------------------*\
425| Return Value:                                                             |
426|    number of bytes received or (negative) error code                      |
427\*=========================================================================*/
428{
429  mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc);
430  rtems_status_code rc;
431  int bc = 0;
432  int bytes_per_char = softc_ptr->bytes_per_char;
433  int bit_shift      = softc_ptr->bit_shift;
434  uint32_t spird_val;
435
436#if defined(DEBUG)
437  printk("mpc83xx_spi_read_write_bytes called... ");
438#endif
439
440  while (len > bytes_per_char-1) {
441    len -= bytes_per_char;
442    /*
443     * mark last byte in SPCOM
444     */
445#if defined(USE_LAST_BIT)
446    softc_ptr->reg_ptr->spcom = (len < bytes_per_char) ? MPC83XX_SPCOM_LST : 0;
447#else
448    softc_ptr->reg_ptr->spcom = 0;
449#endif
450    if (tbuf == NULL) {
451      /*
452       * perform idle char write to read byte
453       */
454      softc_ptr->reg_ptr->spitd = softc_ptr->idle_char << bit_shift;
455    }
456    else {
457      switch(bytes_per_char) {
458      case 1:
459        softc_ptr->reg_ptr->spitd = (*(uint8_t *)tbuf) << bit_shift;
460        break;
461      case 2:
462        softc_ptr->reg_ptr->spitd = (*(uint16_t *)tbuf) << bit_shift;
463        break;
464      case 4:
465        softc_ptr->reg_ptr->spitd = (*(uint32_t *)tbuf) << bit_shift;
466        break;
467      }
468      tbuf += softc_ptr->bytes_per_char;
469    }
470    /*
471     * wait 'til end of transfer
472     */
473#if defined(USE_LAST_BIT)
474    rc = mpc83xx_spi_wait(softc_ptr,
475                          ((len == 0)
476                           ? MPC83XX_SPIE_LT
477                           : MPC83XX_SPIE_NE),
478                          ((len == 0)
479                           ? MPC83XX_SPIE_LT
480                           : MPC83XX_SPIE_NF)
481                          | MPC83XX_SPIE_NE,
482                          MPC83XX_SPIE_LT
483                            | MPC83XX_SPIE_OV
484                          | MPC83XX_SPIE_UN
485                          | MPC83XX_SPIE_NE
486                          | MPC83XX_SPIE_NF);
487    if (len == 0) {
488      /*
489       * clear the "last transfer complete" event
490       */
491      softc_ptr->reg_ptr->spie = MPC83XX_SPIE_LT;
492    }
493#else
494    rc = mpc83xx_spi_wait(softc_ptr,
495                          MPC83XX_SPIE_NE,
496                          MPC83XX_SPIE_NF
497                          | MPC83XX_SPIE_NE,
498                          MPC83XX_SPIE_OV
499                          | MPC83XX_SPIE_UN
500                          | MPC83XX_SPIE_NE
501                          | MPC83XX_SPIE_NF);
502#endif
503    if (rc != RTEMS_SUCCESSFUL) {
504#if defined(DEBUG)
505      printk("... exit rc=%d\r\n",-rc);
506#endif
507      return -rc;
508    }
509    spird_val = softc_ptr->reg_ptr->spird;
510    if (rbuf != NULL) {
511      switch(bytes_per_char) {
512      case 1:
513         (*(uint8_t  *)rbuf) = spird_val >> bit_shift;
514        break;
515      case 2:
516         (*(uint16_t *)rbuf) = spird_val >> bit_shift;
517        break;
518      case 4:
519         (*(uint32_t *)rbuf) = spird_val >> bit_shift;
520        break;
521      }
522      rbuf += bytes_per_char;
523    }
524    bc += bytes_per_char;
525  }
526#if defined(DEBUG)
527  printk("... exit OK, rc=%d\r\n",bc);
528#endif
529  return bc;
530}
531
532/*=========================================================================*\
533| Function:                                                                 |
534\*-------------------------------------------------------------------------*/
535int mpc83xx_spi_read_bytes
536(
537/*-------------------------------------------------------------------------*\
538| Purpose:                                                                  |
539|   receive some bytes from SPI device                                      |
540+---------------------------------------------------------------------------+
541| Input Parameters:                                                         |
542\*-------------------------------------------------------------------------*/
543 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
544 unsigned char *buf,                     /* buffer to store bytes          */
545 int len                                 /* number of bytes to receive     */
546)
547/*-------------------------------------------------------------------------*\
548| Return Value:                                                             |
549|    number of bytes received or (negative) error code                      |
550\*=========================================================================*/
551{
552  return mpc83xx_spi_read_write_bytes(bh,buf,NULL,len);
553}
554
555/*=========================================================================*\
556| Function:                                                                 |
557\*-------------------------------------------------------------------------*/
558int mpc83xx_spi_write_bytes
559(
560/*-------------------------------------------------------------------------*\
561| Purpose:                                                                  |
562|   send some bytes to SPI device                                           |
563+---------------------------------------------------------------------------+
564| Input Parameters:                                                         |
565\*-------------------------------------------------------------------------*/
566 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
567 unsigned char *buf,                     /* buffer to send                 */
568 int len                                 /* number of bytes to send        */
569
570)
571/*-------------------------------------------------------------------------*\
572| Return Value:                                                             |
573|    number of bytes sent or (negative) error code                          |
574\*=========================================================================*/
575{
576  return mpc83xx_spi_read_write_bytes(bh,NULL,buf,len);
577}
578
579/*=========================================================================*\
580| Function:                                                                 |
581\*-------------------------------------------------------------------------*/
582rtems_status_code mpc83xx_spi_set_tfr_mode
583(
584/*-------------------------------------------------------------------------*\
585| Purpose:                                                                  |
586|   set SPI to desired baudrate/clock mode/character mode                   |
587+---------------------------------------------------------------------------+
588| Input Parameters:                                                         |
589\*-------------------------------------------------------------------------*/
590 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
591 const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info             */
592)
593/*-------------------------------------------------------------------------*\
594| Return Value:                                                             |
595|    rtems_status_code                                                      |
596\*=========================================================================*/
597{
598  mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc);
599  uint32_t spimode_baud,spimode;
600  rtems_status_code rc = RTEMS_SUCCESSFUL;
601
602  /* Set idle character */
603  softc_ptr->idle_char = tfr_mode->idle_char;
604
605  /*
606   * FIXME: set proper mode
607   */
608  if (rc == RTEMS_SUCCESSFUL) {
609    rc = mpc83xx_spi_baud_to_mode(tfr_mode->baudrate,
610                                  softc_ptr->base_frq,
611                                  &spimode_baud);
612  }
613  if (rc == RTEMS_SUCCESSFUL) {
614    rc = mpc83xx_spi_char_mode(softc_ptr,
615                               tfr_mode->bits_per_char,
616                               tfr_mode->lsb_first,
617                               &spimode);
618  }
619  if (rc == RTEMS_SUCCESSFUL) {
620    spimode |= spimode_baud;
621    spimode |= MPC83XX_SPIMODE_M_S; /* set master mode */
622    if (!tfr_mode->lsb_first) {
623      spimode |= MPC83XX_SPIMODE_REV;
624    }
625    if (tfr_mode->clock_inv) {
626      spimode |= MPC83XX_SPIMODE_CI;
627    }
628    if (tfr_mode->clock_phs) {
629      spimode |= MPC83XX_SPIMODE_CP;
630    }
631  }
632
633  if (rc == RTEMS_SUCCESSFUL) {
634    /*
635     * disable SPI
636     */
637    softc_ptr->reg_ptr->spmode &= ~MPC83XX_SPIMODE_EN;
638    /*
639     * set new mode and reenable SPI
640     */
641    softc_ptr->reg_ptr->spmode = spimode | MPC83XX_SPIMODE_EN;
642  }
643  return rc;
644}
645
646
647/*=========================================================================*\
648| Function:                                                                 |
649\*-------------------------------------------------------------------------*/
650int mpc83xx_spi_ioctl
651(
652/*-------------------------------------------------------------------------*\
653| Purpose:                                                                  |
654|   perform selected ioctl function for SPI                                 |
655+---------------------------------------------------------------------------+
656| Input Parameters:                                                         |
657\*-------------------------------------------------------------------------*/
658 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
659 int                 cmd,                /* ioctl command code             */
660 void               *arg                 /* additional argument array      */
661)
662/*-------------------------------------------------------------------------*\
663| Return Value:                                                             |
664|    rtems_status_code                                                      |
665\*=========================================================================*/
666{
667  int ret_val = -1;
668
669  switch(cmd) {
670  case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
671    ret_val =
672      -mpc83xx_spi_set_tfr_mode(bh,
673                                (const rtems_libi2c_tfr_mode_t *)arg);
674    break;
675  case RTEMS_LIBI2C_IOCTL_READ_WRITE:
676    ret_val =
677      mpc83xx_spi_read_write_bytes(bh,
678                                   ((rtems_libi2c_read_write_t *)arg)->rd_buf,
679                                   ((rtems_libi2c_read_write_t *)arg)->wr_buf,
680                                   ((rtems_libi2c_read_write_t *)arg)->byte_cnt);
681    break;
682  default:
683    ret_val = -RTEMS_NOT_DEFINED;
684    break;
685  }
686  return ret_val;
687}
688
689
690
Note: See TracBrowser for help on using the repository browser.