Back to home page

LXR

 
 

    


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 low level MPC83xx SPI driver parameters
0007  * and board-specific functions.
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 <mpc83xx/mpc83xx_spidrv.h>
0036 #include <bsp/irq.h>
0037 #include <bsp.h>
0038 
0039 #if defined(MPC83XX_BOARD_MPC8313ERDB)
0040 
0041 #include <libchip/spi-sd-card.h>
0042 
0043 #elif defined(MPC83XX_BOARD_MPC8349EAMDS)
0044 
0045 #include <libchip/spi-flash-m25p40.h>
0046 
0047 #elif defined(MPC83XX_BOARD_HSC_CM01)
0048 
0049 #include <libchip/spi-fram-fm25l256.h>
0050 
0051 #endif
0052 
0053 /*=========================================================================*\
0054 | Board-specific adaptation functions                                       |
0055 \*=========================================================================*/
0056 
0057 /*=========================================================================*\
0058 | Function:                                                                 |
0059 \*-------------------------------------------------------------------------*/
0060 static rtems_status_code bsp_spi_sel_addr
0061 (
0062 /*-------------------------------------------------------------------------*\
0063 | Purpose:                                                                  |
0064 |   address a slave device on the bus                                       |
0065 +---------------------------------------------------------------------------+
0066 | Input Parameters:                                                         |
0067 \*-------------------------------------------------------------------------*/
0068  rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
0069  uint32_t addr,                          /* address to send on bus         */
0070  int rw                                  /* 0=write,1=read                 */
0071 )
0072 /*-------------------------------------------------------------------------*\
0073 | Return Value:                                                             |
0074 |    o = ok or error code                                                   |
0075 \*=========================================================================*/
0076 {
0077 
0078 #if defined( MPC83XX_BOARD_MPC8313ERDB)
0079 
0080   /* Check address */
0081   if (addr > 0) {
0082     return RTEMS_INVALID_NUMBER;
0083   }
0084 
0085   /* SCS (active low) */
0086   mpc83xx.gpio [0].gpdat &= ~0x20000000;
0087 
0088 #elif defined( MPC83XX_BOARD_MPC8349EAMDS)
0089 
0090   /*
0091    * check device address for valid range
0092    */
0093   if (addr > 0) {
0094     return RTEMS_INVALID_NUMBER;
0095   }
0096   /*
0097    * select given device
0098    * GPIO1[0] is nSEL_SPI for M25P40
0099    * set it to be active/low
0100    */
0101   mpc83xx.gpio[0].gpdat &= ~(1 << (31- 0));
0102 
0103 #elif defined( MPC83XX_BOARD_HSC_CM01)
0104 
0105   /*
0106    * check device address for valid range
0107    */
0108   if (addr > 7) {
0109     return RTEMS_INVALID_NUMBER;
0110   }
0111   /*
0112    * select given device
0113    */
0114   /*
0115    * GPIO1[24] is SPI_A0
0116    * GPIO1[25] is SPI_A1
0117    * GPIO1[26] is SPI_A2
0118    * set pins to address
0119    */
0120   mpc83xx.gpio[0].gpdat =
0121     (mpc83xx.gpio[0].gpdat & ~(0x7  << (31-26)))
0122     |                         (addr << (31-26));
0123   /*
0124    * GPIO1[27] is high-active strobe
0125    */
0126   mpc83xx.gpio[0].gpdat |= (1 << (31- 27));
0127 
0128 #endif
0129 
0130   return  RTEMS_SUCCESSFUL;
0131 }
0132 
0133 /*=========================================================================*\
0134 | Function:                                                                 |
0135 \*-------------------------------------------------------------------------*/
0136 static rtems_status_code bsp_spi_send_start_dummy
0137 (
0138 /*-------------------------------------------------------------------------*\
0139 | Purpose:                                                                  |
0140 |   dummy function, SPI has no start condition                              |
0141 +---------------------------------------------------------------------------+
0142 | Input Parameters:                                                         |
0143 \*-------------------------------------------------------------------------*/
0144  rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
0145 )
0146 /*-------------------------------------------------------------------------*\
0147 | Return Value:                                                             |
0148 |    o = ok or error code                                                   |
0149 \*=========================================================================*/
0150 {
0151 
0152 #if defined( MPC83XX_BOARD_MPC8313ERDB)
0153 
0154   /* SCS (inactive high) */
0155   mpc83xx.gpio [0].gpdat |= 0x20000000;
0156 
0157 #elif defined( MPC83XX_BOARD_MPC8349EAMDS)
0158 
0159   /*
0160    * GPIO1[0] is nSEL_SPI for M25P40
0161    * set it to inactive/high
0162    */
0163   mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
0164 
0165 #elif defined( MPC83XX_BOARD_HSC_CM01)
0166 
0167   /*
0168    * GPIO1[27] is high-active strobe
0169    * set it to inactive/ low
0170    */
0171   mpc83xx.gpio[0].gpdat &= ~(0x1 << (31-27));
0172 
0173 #endif
0174 
0175   return 0;
0176 }
0177 
0178 /*=========================================================================*\
0179 | Function:                                                                 |
0180 \*-------------------------------------------------------------------------*/
0181 static rtems_status_code bsp_spi_send_stop
0182 (
0183 /*-------------------------------------------------------------------------*\
0184 | Purpose:                                                                  |
0185 |   deselect SPI                                                            |
0186 +---------------------------------------------------------------------------+
0187 | Input Parameters:                                                         |
0188 \*-------------------------------------------------------------------------*/
0189  rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
0190 )
0191 /*-------------------------------------------------------------------------*\
0192 | Return Value:                                                             |
0193 |    o = ok or error code                                                   |
0194 \*=========================================================================*/
0195 {
0196 #if defined(DEBUG)
0197   printk("bsp_spi_send_stop called... ");
0198 #endif
0199 
0200 #if defined( MPC83XX_BOARD_MPC8313ERDB)
0201 
0202   /* SCS (inactive high) */
0203   mpc83xx.gpio [0].gpdat |= 0x20000000;
0204 
0205 #elif defined( MPC83XX_BOARD_MPC8349EAMDS)
0206 
0207   /*
0208    * deselect given device
0209    * GPIO1[0] is nSEL_SPI for M25P40
0210    * set it to be inactive/high
0211    */
0212   mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
0213 
0214 #elif defined( MPC83XX_BOARD_HSC_CM01)
0215 
0216   /*
0217    * deselect device
0218    * GPIO1[27] is high-active strobe
0219    */
0220   mpc83xx.gpio[0].gpdat &= ~(1 << (31- 27));
0221 
0222 #endif
0223 
0224 #if defined(DEBUG)
0225   printk("... exit OK\r\n");
0226 #endif
0227   return 0;
0228 }
0229 
0230 /*=========================================================================*\
0231 | list of handlers                                                          |
0232 \*=========================================================================*/
0233 
0234 rtems_libi2c_bus_ops_t bsp_spi_ops = {
0235   .init = mpc83xx_spi_init,
0236   .send_start = bsp_spi_send_start_dummy,
0237   .send_stop = bsp_spi_send_stop,
0238   .send_addr = bsp_spi_sel_addr,
0239   .read_bytes = mpc83xx_spi_read_bytes,
0240   .write_bytes = mpc83xx_spi_write_bytes,
0241   .ioctl = mpc83xx_spi_ioctl
0242 };
0243 
0244 static mpc83xx_spi_desc_t bsp_spi_bus_desc = {
0245   {/* public fields */
0246     .ops = &bsp_spi_ops,
0247     .size = sizeof(bsp_spi_bus_desc)
0248   },
0249   { /* our private fields */
0250     .reg_ptr =&mpc83xx.spi,
0251     .initialized = FALSE,
0252     .irq_number = BSP_IPIC_IRQ_SPI,
0253     .base_frq = 0 /* filled in during init */
0254   }
0255 };
0256 
0257 #ifdef MPC83XX_BOARD_MPC8313ERDB
0258 
0259 #include <libchip/spi-sd-card.h>
0260 
0261 #define SD_CARD_NUMBER 1
0262 
0263 size_t sd_card_driver_table_size = SD_CARD_NUMBER;
0264 
0265 sd_card_driver_entry sd_card_driver_table [SD_CARD_NUMBER] = {
0266   {
0267     .device_name = "/dev/sd-card-a",
0268     .bus = 0,
0269     .transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
0270     .command = SD_CARD_COMMAND_DEFAULT,
0271     /* .response = whatever, */
0272     .response_index = SD_CARD_COMMAND_SIZE,
0273     .n_ac_max = SD_CARD_N_AC_MAX_DEFAULT,
0274     .block_number = 0,
0275     .block_size = 0,
0276     .block_size_shift = 0,
0277     .busy = true,
0278     .verbose = true,
0279     .schedule_if_busy = false
0280   }
0281 };
0282 
0283 #endif /* MPC83XX_BOARD_MPC8313ERDB */
0284 
0285 
0286 /*=========================================================================*\
0287 | initialization                                                            |
0288 \*=========================================================================*/
0289 
0290 /*=========================================================================*\
0291 | Function:                                                                 |
0292 \*-------------------------------------------------------------------------*/
0293 rtems_status_code bsp_register_spi
0294 (
0295 /*-------------------------------------------------------------------------*\
0296 | Purpose:                                                                  |
0297 |   register SPI bus and devices                                            |
0298 +---------------------------------------------------------------------------+
0299 | Input Parameters:                                                         |
0300 \*-------------------------------------------------------------------------*/
0301  void                                    /* <none>                         */
0302 )
0303 /*-------------------------------------------------------------------------*\
0304 | Return Value:                                                             |
0305 |    0 or error code                                                        |
0306 \*=========================================================================*/
0307 {
0308   #if defined(MPC83XX_BOARD_MPC8313ERDB)
0309     rtems_status_code sc = RTEMS_SUCCESSFUL;
0310   #endif
0311   unsigned spi_busno;
0312   int      ret_code;
0313 
0314   /*
0315    * init I2C library (if not already done)
0316    */
0317   rtems_libi2c_initialize ();
0318 
0319   /*
0320    * init port pins used to address/select SPI devices
0321    */
0322 
0323 #if defined(MPC83XX_BOARD_MPC8313ERDB)
0324 
0325   /*
0326    * Configured as master (direct connection to SD card)
0327    *
0328    * GPIO[28] : SOUT
0329    * GPIO[29] : SIN
0330    * GPIO[30] : SCLK
0331    * GPIO[02] : SCS (inactive high), GPIO[02] is normally connected to U43 at
0332    * pin 15 of MC74LCX244DT.
0333    */
0334 
0335   /* Function */
0336   mpc83xx.syscon.sicrl = (mpc83xx.syscon.sicrl & ~0x03fc0000) | 0x30000000;
0337 
0338   /* Direction */
0339   mpc83xx.gpio [0].gpdir = (mpc83xx.gpio [0].gpdir & ~0x0000000f) | 0x2000000b;
0340 
0341   /* Data */
0342   mpc83xx.gpio [0].gpdat |= 0x20000000;
0343 
0344   /* Open Drain */
0345   /* mpc83xx.gpio [0].gpdr  |= 0x0000000f; */
0346 
0347 #elif defined(MPC83XX_BOARD_MPC8349EAMDS)
0348 
0349   /*
0350    * GPIO1[0] is nSEL_SPI for M25P40
0351    * set it to be output, high
0352    */
0353   mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
0354   mpc83xx.gpio[0].gpdir |=  (1 << (31- 0));
0355   mpc83xx.gpio[0].gpdr  &= ~(1 << (31- 0));
0356 
0357 #elif defined(MPC83XX_BOARD_HSC_CM01)
0358 
0359   /*
0360    * GPIO1[24] is SPI_A0
0361    * GPIO1[25] is SPI_A1
0362    * GPIO1[26] is SPI_A2
0363    * GPIO1[27] is high-active strobe
0364    * set pins to be output, low
0365    */
0366   mpc83xx.gpio[0].gpdat &= ~(0xf << (31-27));
0367   mpc83xx.gpio[0].gpdir |=  (0xf << (31-27));
0368   mpc83xx.gpio[0].gpdr  &= ~(0xf << (31-27));
0369 
0370 #else
0371 
0372   /*
0373    * There is no SPI configuration information for this variant.
0374    */
0375   (void) spi_busno; /* avoid set but not used warning */
0376 #endif
0377 
0378   /*
0379    * update base frequency in spi descriptor
0380    */
0381   bsp_spi_bus_desc.softc.base_frq = BSP_bus_frequency;
0382 
0383   /*
0384    * register SPI bus
0385    */
0386   ret_code = rtems_libi2c_register_bus("/dev/spi",
0387                        &(bsp_spi_bus_desc.bus_desc));
0388   if (ret_code < 0) {
0389     return -ret_code;
0390   }
0391   spi_busno = (unsigned) ret_code;
0392 
0393 #if defined(MPC83XX_BOARD_MPC8313ERDB)
0394 
0395   /* Register SD Card driver */
0396   sd_card_driver_table [0].bus = spi_busno;
0397   sc = sd_card_register();
0398   if (sc != RTEMS_SUCCESSFUL) {
0399     return sc;
0400   }
0401 
0402 #elif defined(MPC83XX_BOARD_MPC8349EAMDS)
0403 
0404   /*
0405    * register M25P40 Flash
0406    */
0407   ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FLASH_DEVICE_NAME,
0408                        spi_flash_m25p40_rw_driver_descriptor,
0409                        spi_busno,0x00);
0410 #elif defined(MPC83XX_BOARD_HSC_CM01)
0411 
0412   /*
0413    * register FM25L256 FRAM
0414    */
0415   ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FRAM_DEVICE_NAME,
0416                        spi_fram_fm25l256_rw_driver_descriptor,
0417                        spi_busno,0x02);
0418 
0419 #endif
0420 
0421   if (ret_code < 0) {
0422     return -ret_code;
0423   }
0424 
0425   /*
0426    * FIXME: further drivers, when available
0427    */
0428   return 0;
0429 }