![]() |
|
|||
File indexing completed on 2025-05-11 08:23:53
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /* 0004 * RTEMS support for MPC83xx 0005 * 0006 * This file contains the MPC83xx SPI driver. 0007 * NOTE: it uses the same API as the I2C driver. 0008 */ 0009 0010 /* 0011 * Copyright (c) 2007 embedded brains GmbH & Co. KG 0012 * 0013 * Redistribution and use in source and binary forms, with or without 0014 * modification, are permitted provided that the following conditions 0015 * are met: 0016 * 1. Redistributions of source code must retain the above copyright 0017 * notice, this list of conditions and the following disclaimer. 0018 * 2. Redistributions in binary form must reproduce the above copyright 0019 * notice, this list of conditions and the following disclaimer in the 0020 * documentation and/or other materials provided with the distribution. 0021 * 0022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0025 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0026 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0027 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0028 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0029 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0030 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0031 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0032 * POSSIBILITY OF SUCH DAMAGE. 0033 */ 0034 0035 #include <stdlib.h> 0036 #include <bsp.h> 0037 #include <bsp/irq.h> 0038 #include <mpc83xx/mpc83xx.h> 0039 #include <mpc83xx/mpc83xx_spidrv.h> 0040 #include <rtems/error.h> 0041 #include <rtems/bspIo.h> 0042 #include <errno.h> 0043 #include <rtems/libi2c.h> 0044 0045 #undef DEBUG 0046 0047 /*=========================================================================*\ 0048 | Function: | 0049 \*-------------------------------------------------------------------------*/ 0050 static rtems_status_code mpc83xx_spi_baud_to_mode 0051 ( 0052 /*-------------------------------------------------------------------------*\ 0053 | Purpose: | 0054 | determine proper divider value | 0055 +---------------------------------------------------------------------------+ 0056 | Input Parameters: | 0057 \*-------------------------------------------------------------------------*/ 0058 uint32_t baudrate, /* desired baudrate */ 0059 uint32_t base_frq, /* input frequency */ 0060 uint32_t *spimode /* result value */ 0061 ) 0062 /*-------------------------------------------------------------------------*\ 0063 | Return Value: | 0064 | o = ok or error code | 0065 \*=========================================================================*/ 0066 { 0067 uint32_t divider; 0068 uint32_t tmpmode = 0; 0069 /* 0070 * determine clock divider and DIV16 bit 0071 */ 0072 divider = (base_frq+baudrate-1)/baudrate; 0073 if (divider > 64) { 0074 tmpmode = MPC83XX_SPIMODE_DIV16; 0075 divider /= 16; 0076 } 0077 if ((divider < 1) || 0078 (divider > 64)) { 0079 return RTEMS_INVALID_NUMBER; 0080 } 0081 else { 0082 tmpmode |= MPC83XX_SPIMODE_PM(divider/4-1); 0083 } 0084 *spimode = tmpmode; 0085 return RTEMS_SUCCESSFUL; 0086 } 0087 0088 /*=========================================================================*\ 0089 | Function: | 0090 \*-------------------------------------------------------------------------*/ 0091 static rtems_status_code mpc83xx_spi_char_mode 0092 ( 0093 /*-------------------------------------------------------------------------*\ 0094 | Purpose: | 0095 | determine proper value for character size | 0096 +---------------------------------------------------------------------------+ 0097 | Input Parameters: | 0098 \*-------------------------------------------------------------------------*/ 0099 mpc83xx_spi_softc_t *softc_ptr, /* handle */ 0100 uint32_t bits_per_char, /* bits per character */ 0101 bool lsb_first, /* TRUE: send LSB first */ 0102 uint32_t *spimode /* result value */ 0103 ) 0104 /*-------------------------------------------------------------------------*\ 0105 | Return Value: | 0106 | o = ok or error code | 0107 \*=========================================================================*/ 0108 { 0109 uint32_t tmpmode; 0110 0111 if (bits_per_char == 32) { 0112 tmpmode = 0; 0113 softc_ptr->bytes_per_char = 4; 0114 softc_ptr->bit_shift = 0; 0115 } 0116 else { 0117 if (lsb_first) { 0118 /* 0119 * non-reversed data (LSB first): 4..16 bits valid 0120 * always aligned to bit 16 of data register 0121 */ 0122 if ((bits_per_char >= 4) && 0123 (bits_per_char <= 16)) { 0124 tmpmode = MPC83XX_SPIMODE_LEN( bits_per_char-1); 0125 softc_ptr->bytes_per_char = (bits_per_char > 8) ? 2 : 1; 0126 softc_ptr->bit_shift = 16-bits_per_char; 0127 } 0128 else { 0129 return RTEMS_INVALID_NUMBER; 0130 } 0131 } 0132 else { 0133 /* 0134 * reversed data (MSB first): only 8/16/32 bits valid, 0135 * always in lowest bits of data register 0136 */ 0137 if (bits_per_char == 8) { 0138 tmpmode = MPC83XX_SPIMODE_LEN(8-1); 0139 softc_ptr->bytes_per_char = 1; 0140 softc_ptr->bit_shift = 0; 0141 } 0142 else if (bits_per_char == 16) { 0143 tmpmode = MPC83XX_SPIMODE_LEN(16-1); 0144 softc_ptr->bytes_per_char = 2; 0145 softc_ptr->bit_shift = 0; 0146 } 0147 else { 0148 return RTEMS_INVALID_NUMBER; 0149 } 0150 } 0151 } 0152 0153 *spimode = tmpmode; 0154 return 0; 0155 } 0156 0157 /*=========================================================================*\ 0158 | Function: | 0159 \*-------------------------------------------------------------------------*/ 0160 static int mpc83xx_spi_wait 0161 ( 0162 /*-------------------------------------------------------------------------*\ 0163 | Purpose: | 0164 | wait for spi to become idle | 0165 +---------------------------------------------------------------------------+ 0166 | Input Parameters: | 0167 \*-------------------------------------------------------------------------*/ 0168 mpc83xx_spi_softc_t *softc_ptr, /* handle */ 0169 uint32_t irq_mask, /* irq mask to use */ 0170 uint32_t desired_status, /* desired status word */ 0171 uint32_t status_mask /* status word mask */ 0172 ) 0173 /*-------------------------------------------------------------------------*\ 0174 | Return Value: | 0175 | o = ok or error code | 0176 \*=========================================================================*/ 0177 { 0178 uint32_t act_status; 0179 rtems_status_code rc; 0180 uint32_t tout; 0181 0182 #if defined(DEBUG) 0183 printk("mpc83xx_spi_wait called... "); 0184 #endif 0185 if (softc_ptr->initialized) { 0186 /* 0187 * allow interrupts, when receiver is not empty 0188 */ 0189 softc_ptr->reg_ptr->spim = irq_mask; 0190 rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100); 0191 if (rc != RTEMS_SUCCESSFUL) { 0192 return rc; 0193 } 0194 } 0195 else { 0196 tout = 0; 0197 do { 0198 if (tout++ > 1000000) { 0199 #if defined(DEBUG) 0200 printk("... exit with RTEMS_TIMEOUT\r\n"); 0201 #endif 0202 return RTEMS_TIMEOUT; 0203 } 0204 /* 0205 * wait for SPI to terminate 0206 */ 0207 } while (!(softc_ptr->reg_ptr->spie & MPC83XX_SPIE_NE)); 0208 } 0209 0210 act_status = softc_ptr->reg_ptr->spie; 0211 if ((act_status & status_mask)!= desired_status) { 0212 #if defined(DEBUG) 0213 printk("... exit with RTEMS_IO_ERROR," 0214 "act_status=0x%04x,mask=0x%04x,desired_status=0x%04x\r\n", 0215 act_status,status_mask,desired_status); 0216 #endif 0217 return RTEMS_IO_ERROR; 0218 } 0219 #if defined(DEBUG) 0220 printk("... exit OK\r\n"); 0221 #endif 0222 return RTEMS_SUCCESSFUL; 0223 } 0224 0225 /*=========================================================================*\ 0226 | Function: | 0227 \*-------------------------------------------------------------------------*/ 0228 static void mpc83xx_spi_irq_handler 0229 ( 0230 /*-------------------------------------------------------------------------*\ 0231 | Purpose: | 0232 | handle interrupts | 0233 +---------------------------------------------------------------------------+ 0234 | Input Parameters: | 0235 \*-------------------------------------------------------------------------*/ 0236 rtems_irq_hdl_param handle /* handle, is softc_ptr structure */ 0237 ) 0238 /*-------------------------------------------------------------------------*\ 0239 | Return Value: | 0240 | <none> | 0241 \*=========================================================================*/ 0242 { 0243 mpc83xx_spi_softc_t *softc_ptr = (mpc83xx_spi_softc_t *)handle; 0244 0245 /* 0246 * disable interrupt mask 0247 */ 0248 softc_ptr->reg_ptr->spim = 0; 0249 if (softc_ptr->initialized) { 0250 rtems_semaphore_release(softc_ptr->irq_sema_id); 0251 } 0252 } 0253 0254 /*=========================================================================*\ 0255 | Function: | 0256 \*-------------------------------------------------------------------------*/ 0257 static void mpc83xx_spi_irq_on_off 0258 ( 0259 /*-------------------------------------------------------------------------*\ 0260 | Purpose: | 0261 | enable/disable interrupts (void, handled at different position) | 0262 +---------------------------------------------------------------------------+ 0263 | Input Parameters: | 0264 \*-------------------------------------------------------------------------*/ 0265 const 0266 rtems_irq_connect_data *irq_conn_data /* irq connect data */ 0267 ) 0268 /*-------------------------------------------------------------------------*\ 0269 | Return Value: | 0270 | <none> | 0271 \*=========================================================================*/ 0272 { 0273 } 0274 0275 0276 /*=========================================================================*\ 0277 | Function: | 0278 \*-------------------------------------------------------------------------*/ 0279 static int mpc83xx_spi_irq_isOn 0280 ( 0281 /*-------------------------------------------------------------------------*\ 0282 | Purpose: | 0283 | check state of interrupts, void, done differently | 0284 +---------------------------------------------------------------------------+ 0285 | Input Parameters: | 0286 \*-------------------------------------------------------------------------*/ 0287 const 0288 rtems_irq_connect_data *irq_conn_data /* irq connect data */ 0289 ) 0290 /*-------------------------------------------------------------------------*\ 0291 | Return Value: | 0292 | TRUE, if enabled | 0293 \*=========================================================================*/ 0294 { 0295 return (TRUE); 0296 } 0297 0298 /*=========================================================================*\ 0299 | Function: | 0300 \*-------------------------------------------------------------------------*/ 0301 static void mpc83xx_spi_install_irq_handler 0302 ( 0303 /*-------------------------------------------------------------------------*\ 0304 | Purpose: | 0305 | (un-)install the interrupt handler | 0306 +---------------------------------------------------------------------------+ 0307 | Input Parameters: | 0308 \*-------------------------------------------------------------------------*/ 0309 mpc83xx_spi_softc_t *softc_ptr, /* ptr to control structure */ 0310 int install /* TRUE: install, FALSE: remove */ 0311 ) 0312 /*-------------------------------------------------------------------------*\ 0313 | Return Value: | 0314 | <none> | 0315 \*=========================================================================*/ 0316 { 0317 rtems_status_code rc = RTEMS_SUCCESSFUL; 0318 0319 rtems_irq_connect_data irq_conn_data = { 0320 softc_ptr->irq_number, 0321 mpc83xx_spi_irq_handler, /* rtems_irq_hdl */ 0322 (rtems_irq_hdl_param)softc_ptr, /* (rtems_irq_hdl_param) */ 0323 mpc83xx_spi_irq_on_off, /* (rtems_irq_enable) */ 0324 mpc83xx_spi_irq_on_off, /* (rtems_irq_disable) */ 0325 mpc83xx_spi_irq_isOn /* (rtems_irq_is_enabled) */ 0326 }; 0327 0328 /* 0329 * (un-)install handler for SPI device 0330 */ 0331 if (install) { 0332 /* 0333 * create semaphore for IRQ synchronization 0334 */ 0335 rc = rtems_semaphore_create(rtems_build_name('s','p','i','s'), 0336 0, 0337 RTEMS_FIFO 0338 | RTEMS_SIMPLE_BINARY_SEMAPHORE, 0339 0, 0340 &softc_ptr->irq_sema_id); 0341 if (rc != RTEMS_SUCCESSFUL) { 0342 rtems_panic("SPI: cannot create semaphore"); 0343 } 0344 if (!BSP_install_rtems_irq_handler (&irq_conn_data)) { 0345 rtems_panic("SPI: cannot install IRQ handler"); 0346 } 0347 } 0348 else { 0349 if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) { 0350 rtems_panic("SPI: cannot uninstall IRQ handler"); 0351 } 0352 /* 0353 * delete sync semaphore 0354 */ 0355 if (softc_ptr->irq_sema_id != 0) { 0356 rc = rtems_semaphore_delete(softc_ptr->irq_sema_id); 0357 if (rc != RTEMS_SUCCESSFUL) { 0358 rtems_panic("SPI: cannot delete semaphore"); 0359 } 0360 } 0361 } 0362 } 0363 0364 /*=========================================================================*\ 0365 | Function: | 0366 \*-------------------------------------------------------------------------*/ 0367 rtems_status_code mpc83xx_spi_init 0368 ( 0369 /*-------------------------------------------------------------------------*\ 0370 | Purpose: | 0371 | initialize the driver | 0372 +---------------------------------------------------------------------------+ 0373 | Input Parameters: | 0374 \*-------------------------------------------------------------------------*/ 0375 rtems_libi2c_bus_t *bh /* bus specifier structure */ 0376 ) 0377 /*-------------------------------------------------------------------------*\ 0378 | Return Value: | 0379 | o = ok or error code | 0380 \*=========================================================================*/ 0381 { 0382 mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc); 0383 #if defined(DEBUG) 0384 printk("mpc83xx_spi_init called... "); 0385 #endif 0386 /* 0387 * init HW registers: 0388 */ 0389 /* 0390 * FIXME: set default mode in SPIM 0391 */ 0392 0393 /* 0394 * init interrupt stuff 0395 */ 0396 mpc83xx_spi_install_irq_handler(softc_ptr,TRUE); 0397 0398 /* 0399 * mark, that we have initialized 0400 */ 0401 softc_ptr->initialized = TRUE; 0402 #if defined(DEBUG) 0403 printk("... exit OK\r\n"); 0404 #endif 0405 return RTEMS_SUCCESSFUL; 0406 } 0407 0408 /*=========================================================================*\ 0409 | Function: | 0410 \*-------------------------------------------------------------------------*/ 0411 int mpc83xx_spi_read_write_bytes 0412 ( 0413 /*-------------------------------------------------------------------------*\ 0414 | Purpose: | 0415 | transmit/receive some bytes from SPI device | 0416 +---------------------------------------------------------------------------+ 0417 | Input Parameters: | 0418 \*-------------------------------------------------------------------------*/ 0419 rtems_libi2c_bus_t *bh, /* bus specifier structure */ 0420 unsigned char *rbuf, /* buffer to store bytes */ 0421 const unsigned char *tbuf, /* buffer to send bytes */ 0422 int len /* number of bytes to transceive */ 0423 ) 0424 /*-------------------------------------------------------------------------*\ 0425 | Return Value: | 0426 | number of bytes received or (negative) error code | 0427 \*=========================================================================*/ 0428 { 0429 mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc); 0430 rtems_status_code rc; 0431 int bc = 0; 0432 int bytes_per_char = softc_ptr->bytes_per_char; 0433 int bit_shift = softc_ptr->bit_shift; 0434 uint32_t spird_val; 0435 0436 #if defined(DEBUG) 0437 printk("mpc83xx_spi_read_write_bytes called... "); 0438 #endif 0439 0440 while (len > bytes_per_char-1) { 0441 len -= bytes_per_char; 0442 /* 0443 * mark last byte in SPCOM 0444 */ 0445 #if defined(USE_LAST_BIT) 0446 softc_ptr->reg_ptr->spcom = (len < bytes_per_char) ? MPC83XX_SPCOM_LST : 0; 0447 #else 0448 softc_ptr->reg_ptr->spcom = 0; 0449 #endif 0450 if (tbuf == NULL) { 0451 /* 0452 * perform idle char write to read byte 0453 */ 0454 softc_ptr->reg_ptr->spitd = softc_ptr->idle_char << bit_shift; 0455 } 0456 else { 0457 switch(bytes_per_char) { 0458 case 1: 0459 softc_ptr->reg_ptr->spitd = (*(uint8_t *)tbuf) << bit_shift; 0460 break; 0461 case 2: 0462 softc_ptr->reg_ptr->spitd = (*(uint16_t *)tbuf) << bit_shift; 0463 break; 0464 case 4: 0465 softc_ptr->reg_ptr->spitd = (*(uint32_t *)tbuf) << bit_shift; 0466 break; 0467 } 0468 tbuf += softc_ptr->bytes_per_char; 0469 } 0470 /* 0471 * wait 'til end of transfer 0472 */ 0473 #if defined(USE_LAST_BIT) 0474 rc = mpc83xx_spi_wait(softc_ptr, 0475 ((len == 0) 0476 ? MPC83XX_SPIE_LT 0477 : MPC83XX_SPIE_NE), 0478 ((len == 0) 0479 ? MPC83XX_SPIE_LT 0480 : MPC83XX_SPIE_NF) 0481 | MPC83XX_SPIE_NE, 0482 MPC83XX_SPIE_LT 0483 | MPC83XX_SPIE_OV 0484 | MPC83XX_SPIE_UN 0485 | MPC83XX_SPIE_NE 0486 | MPC83XX_SPIE_NF); 0487 if (len == 0) { 0488 /* 0489 * clear the "last transfer complete" event 0490 */ 0491 softc_ptr->reg_ptr->spie = MPC83XX_SPIE_LT; 0492 } 0493 #else 0494 rc = mpc83xx_spi_wait(softc_ptr, 0495 MPC83XX_SPIE_NE, 0496 MPC83XX_SPIE_NF 0497 | MPC83XX_SPIE_NE, 0498 MPC83XX_SPIE_OV 0499 | MPC83XX_SPIE_UN 0500 | MPC83XX_SPIE_NE 0501 | MPC83XX_SPIE_NF); 0502 #endif 0503 if (rc != RTEMS_SUCCESSFUL) { 0504 #if defined(DEBUG) 0505 printk("... exit rc=%d\r\n",-rc); 0506 #endif 0507 return -rc; 0508 } 0509 spird_val = softc_ptr->reg_ptr->spird; 0510 if (rbuf != NULL) { 0511 switch(bytes_per_char) { 0512 case 1: 0513 (*(uint8_t *)rbuf) = spird_val >> bit_shift; 0514 break; 0515 case 2: 0516 (*(uint16_t *)rbuf) = spird_val >> bit_shift; 0517 break; 0518 case 4: 0519 (*(uint32_t *)rbuf) = spird_val >> bit_shift; 0520 break; 0521 } 0522 rbuf += bytes_per_char; 0523 } 0524 bc += bytes_per_char; 0525 } 0526 #if defined(DEBUG) 0527 printk("... exit OK, rc=%d\r\n",bc); 0528 #endif 0529 return bc; 0530 } 0531 0532 /*=========================================================================*\ 0533 | Function: | 0534 \*-------------------------------------------------------------------------*/ 0535 int mpc83xx_spi_read_bytes 0536 ( 0537 /*-------------------------------------------------------------------------*\ 0538 | Purpose: | 0539 | receive some bytes from SPI device | 0540 +---------------------------------------------------------------------------+ 0541 | Input Parameters: | 0542 \*-------------------------------------------------------------------------*/ 0543 rtems_libi2c_bus_t *bh, /* bus specifier structure */ 0544 unsigned char *buf, /* buffer to store bytes */ 0545 int len /* number of bytes to receive */ 0546 ) 0547 /*-------------------------------------------------------------------------*\ 0548 | Return Value: | 0549 | number of bytes received or (negative) error code | 0550 \*=========================================================================*/ 0551 { 0552 return mpc83xx_spi_read_write_bytes(bh,buf,NULL,len); 0553 } 0554 0555 /*=========================================================================*\ 0556 | Function: | 0557 \*-------------------------------------------------------------------------*/ 0558 int mpc83xx_spi_write_bytes 0559 ( 0560 /*-------------------------------------------------------------------------*\ 0561 | Purpose: | 0562 | send some bytes to SPI device | 0563 +---------------------------------------------------------------------------+ 0564 | Input Parameters: | 0565 \*-------------------------------------------------------------------------*/ 0566 rtems_libi2c_bus_t *bh, /* bus specifier structure */ 0567 unsigned char *buf, /* buffer to send */ 0568 int len /* number of bytes to send */ 0569 0570 ) 0571 /*-------------------------------------------------------------------------*\ 0572 | Return Value: | 0573 | number of bytes sent or (negative) error code | 0574 \*=========================================================================*/ 0575 { 0576 return mpc83xx_spi_read_write_bytes(bh,NULL,buf,len); 0577 } 0578 0579 /*=========================================================================*\ 0580 | Function: | 0581 \*-------------------------------------------------------------------------*/ 0582 rtems_status_code mpc83xx_spi_set_tfr_mode 0583 ( 0584 /*-------------------------------------------------------------------------*\ 0585 | Purpose: | 0586 | set SPI to desired baudrate/clock mode/character mode | 0587 +---------------------------------------------------------------------------+ 0588 | Input Parameters: | 0589 \*-------------------------------------------------------------------------*/ 0590 rtems_libi2c_bus_t *bh, /* bus specifier structure */ 0591 const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */ 0592 ) 0593 /*-------------------------------------------------------------------------*\ 0594 | Return Value: | 0595 | rtems_status_code | 0596 \*=========================================================================*/ 0597 { 0598 mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc); 0599 uint32_t spimode_baud,spimode; 0600 rtems_status_code rc = RTEMS_SUCCESSFUL; 0601 0602 /* Set idle character */ 0603 softc_ptr->idle_char = tfr_mode->idle_char; 0604 0605 /* 0606 * FIXME: set proper mode 0607 */ 0608 if (rc == RTEMS_SUCCESSFUL) { 0609 rc = mpc83xx_spi_baud_to_mode(tfr_mode->baudrate, 0610 softc_ptr->base_frq, 0611 &spimode_baud); 0612 } 0613 if (rc == RTEMS_SUCCESSFUL) { 0614 rc = mpc83xx_spi_char_mode(softc_ptr, 0615 tfr_mode->bits_per_char, 0616 tfr_mode->lsb_first, 0617 &spimode); 0618 } 0619 if (rc == RTEMS_SUCCESSFUL) { 0620 spimode |= spimode_baud; 0621 spimode |= MPC83XX_SPIMODE_M_S; /* set master mode */ 0622 if (!tfr_mode->lsb_first) { 0623 spimode |= MPC83XX_SPIMODE_REV; 0624 } 0625 if (tfr_mode->clock_inv) { 0626 spimode |= MPC83XX_SPIMODE_CI; 0627 } 0628 if (tfr_mode->clock_phs) { 0629 spimode |= MPC83XX_SPIMODE_CP; 0630 } 0631 } 0632 0633 if (rc == RTEMS_SUCCESSFUL) { 0634 /* 0635 * disable SPI 0636 */ 0637 softc_ptr->reg_ptr->spmode &= ~MPC83XX_SPIMODE_EN; 0638 /* 0639 * set new mode and reenable SPI 0640 */ 0641 softc_ptr->reg_ptr->spmode = spimode | MPC83XX_SPIMODE_EN; 0642 } 0643 return rc; 0644 } 0645 0646 0647 /*=========================================================================*\ 0648 | Function: | 0649 \*-------------------------------------------------------------------------*/ 0650 int mpc83xx_spi_ioctl 0651 ( 0652 /*-------------------------------------------------------------------------*\ 0653 | Purpose: | 0654 | perform selected ioctl function for SPI | 0655 +---------------------------------------------------------------------------+ 0656 | Input Parameters: | 0657 \*-------------------------------------------------------------------------*/ 0658 rtems_libi2c_bus_t *bh, /* bus specifier structure */ 0659 int cmd, /* ioctl command code */ 0660 void *arg /* additional argument array */ 0661 ) 0662 /*-------------------------------------------------------------------------*\ 0663 | Return Value: | 0664 | rtems_status_code | 0665 \*=========================================================================*/ 0666 { 0667 int ret_val = -1; 0668 0669 switch(cmd) { 0670 case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: 0671 ret_val = 0672 -mpc83xx_spi_set_tfr_mode(bh, 0673 (const rtems_libi2c_tfr_mode_t *)arg); 0674 break; 0675 case RTEMS_LIBI2C_IOCTL_READ_WRITE: 0676 ret_val = 0677 mpc83xx_spi_read_write_bytes(bh, 0678 ((rtems_libi2c_read_write_t *)arg)->rd_buf, 0679 ((rtems_libi2c_read_write_t *)arg)->wr_buf, 0680 ((rtems_libi2c_read_write_t *)arg)->byte_cnt); 0681 break; 0682 default: 0683 ret_val = -RTEMS_NOT_DEFINED; 0684 break; 0685 } 0686 return ret_val; 0687 } 0688 0689 0690
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |