source: rtems/bsps/powerpc/gen83xx/spi/spi_init.c @ 276afd2b

5
Last change on this file since 276afd2b was 276afd2b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 07:48:52

bsps: Move SPI drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 12.8 KB
RevLine 
[d4d60360]1/*===============================================================*\
2| Project: RTEMS support for MPC83xx                              |
3+-----------------------------------------------------------------+
4|                    Copyright (c) 2007                           |
5|                    Embedded Brains GmbH                         |
6|                    Obere Lagerstr. 30                           |
7|                    D-82178 Puchheim                             |
8|                    Germany                                      |
9|                    rtems@embedded-brains.de                     |
10+-----------------------------------------------------------------+
11| The license and distribution terms for this file may be         |
12| found in the file LICENSE in this distribution or at            |
13|                                                                 |
[c499856]14| http://www.rtems.org/license/LICENSE.                           |
[d4d60360]15|                                                                 |
16+-----------------------------------------------------------------+
17| this file contains the low level MPC83xx SPI driver parameters  |
18| and board-specific functions                                    |
19\*===============================================================*/
[e570c313]20
21
[d4d60360]22#include <mpc83xx/mpc83xx_spidrv.h>
23#include <bsp/irq.h>
24#include <bsp.h>
[574fb67]25
[b5548e5]26#if defined(MPC83XX_BOARD_MPC8313ERDB)
[574fb67]27
28#include <libchip/spi-sd-card.h>
29
[b5548e5]30#elif defined(MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]31
[d4d60360]32#include <libchip/spi-flash-m25p40.h>
[574fb67]33
[b5548e5]34#elif defined(MPC83XX_BOARD_HSC_CM01)
[574fb67]35
[42bf1b9]36#include <libchip/spi-fram-fm25l256.h>
[574fb67]37
[42bf1b9]38#endif
[d4d60360]39
40/*=========================================================================*\
41| Board-specific adaptation functions                                       |
42\*=========================================================================*/
43
44/*=========================================================================*\
45| Function:                                                                 |
46\*-------------------------------------------------------------------------*/
47static rtems_status_code bsp_spi_sel_addr
48(
49/*-------------------------------------------------------------------------*\
50| Purpose:                                                                  |
51|   address a slave device on the bus                                       |
52+---------------------------------------------------------------------------+
53| Input Parameters:                                                         |
54\*-------------------------------------------------------------------------*/
55 rtems_libi2c_bus_t *bh,                 /* bus specifier structure        */
56 uint32_t addr,                          /* address to send on bus         */
57 int rw                                  /* 0=write,1=read                 */
58)
59/*-------------------------------------------------------------------------*\
60| Return Value:                                                             |
61|    o = ok or error code                                                   |
62\*=========================================================================*/
63{
[574fb67]64
[7a752161]65#if defined( MPC83XX_BOARD_MPC8313ERDB)
[574fb67]66
67  /* Check address */
68  if (addr > 0) {
69    return RTEMS_INVALID_NUMBER;
70  }
71
72  /* SCS (active low) */
73  mpc83xx.gpio [0].gpdat &= ~0x20000000;
74
[7a752161]75#elif defined( MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]76
[d4d60360]77  /*
78   * check device address for valid range
79   */
80  if (addr > 0) {
81    return RTEMS_INVALID_NUMBER;
82  }
83  /*
84   * select given device
85   * GPIO1[0] is nSEL_SPI for M25P40
86   * set it to be active/low
87   */
88  mpc83xx.gpio[0].gpdat &= ~(1 << (31- 0));
[574fb67]89
[7a752161]90#elif defined( MPC83XX_BOARD_HSC_CM01)
[574fb67]91
[d4d60360]92  /*
93   * check device address for valid range
94   */
95  if (addr > 7) {
96    return RTEMS_INVALID_NUMBER;
97  }
98  /*
99   * select given device
100   */
101  /*
102   * GPIO1[24] is SPI_A0
103   * GPIO1[25] is SPI_A1
104   * GPIO1[26] is SPI_A2
[ac7af4a]105   * set pins to address
[d4d60360]106   */
[ac7af4a]107  mpc83xx.gpio[0].gpdat =
[d4d60360]108    (mpc83xx.gpio[0].gpdat & ~(0x7  << (31-26)))
109    |                         (addr << (31-26));
110  /*
[ac7af4a]111   * GPIO1[27] is high-active strobe
[d4d60360]112   */
113  mpc83xx.gpio[0].gpdat |= (1 << (31- 27));
[574fb67]114
[d4d60360]115#endif
[574fb67]116
[d4d60360]117  return  RTEMS_SUCCESSFUL;
118}
119
120/*=========================================================================*\
121| Function:                                                                 |
122\*-------------------------------------------------------------------------*/
123static rtems_status_code bsp_spi_send_start_dummy
124(
125/*-------------------------------------------------------------------------*\
126| Purpose:                                                                  |
127|   dummy function, SPI has no start condition                              |
128+---------------------------------------------------------------------------+
129| Input Parameters:                                                         |
130\*-------------------------------------------------------------------------*/
131 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
132)
133/*-------------------------------------------------------------------------*\
134| Return Value:                                                             |
135|    o = ok or error code                                                   |
136\*=========================================================================*/
137{
[574fb67]138
[7a752161]139#if defined( MPC83XX_BOARD_MPC8313ERDB)
[574fb67]140
141  /* SCS (inactive high) */
142  mpc83xx.gpio [0].gpdat |= 0x20000000;
143
[7a752161]144#elif defined( MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]145
[d4d60360]146  /*
147   * GPIO1[0] is nSEL_SPI for M25P40
148   * set it to inactive/high
149   */
150  mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
[574fb67]151
[7a752161]152#elif defined( MPC83XX_BOARD_HSC_CM01)
[574fb67]153
[d4d60360]154  /*
[ac7af4a]155   * GPIO1[27] is high-active strobe
[d4d60360]156   * set it to inactive/ low
157   */
158  mpc83xx.gpio[0].gpdat &= ~(0x1 << (31-27));
[574fb67]159
[d4d60360]160#endif
[574fb67]161
[d4d60360]162  return 0;
163}
164
165/*=========================================================================*\
166| Function:                                                                 |
167\*-------------------------------------------------------------------------*/
168static rtems_status_code bsp_spi_send_stop
169(
170/*-------------------------------------------------------------------------*\
171| Purpose:                                                                  |
172|   deselect SPI                                                            |
173+---------------------------------------------------------------------------+
174| Input Parameters:                                                         |
175\*-------------------------------------------------------------------------*/
176 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
177)
178/*-------------------------------------------------------------------------*\
179| Return Value:                                                             |
180|    o = ok or error code                                                   |
181\*=========================================================================*/
182{
183#if defined(DEBUG)
184  printk("bsp_spi_send_stop called... ");
185#endif
[574fb67]186
[7a752161]187#if defined( MPC83XX_BOARD_MPC8313ERDB)
[574fb67]188
189  /* SCS (inactive high) */
190  mpc83xx.gpio [0].gpdat |= 0x20000000;
191
[7a752161]192#elif defined( MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]193
[d4d60360]194  /*
195   * deselect given device
196   * GPIO1[0] is nSEL_SPI for M25P40
197   * set it to be inactive/high
198   */
199  mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
[574fb67]200
[7a752161]201#elif defined( MPC83XX_BOARD_HSC_CM01)
[574fb67]202
[d4d60360]203  /*
204   * deselect device
[ac7af4a]205   * GPIO1[27] is high-active strobe
[d4d60360]206   */
207  mpc83xx.gpio[0].gpdat &= ~(1 << (31- 27));
[574fb67]208
[d4d60360]209#endif
[574fb67]210
[d4d60360]211#if defined(DEBUG)
212  printk("... exit OK\r\n");
213#endif
214  return 0;
215}
216
217/*=========================================================================*\
218| list of handlers                                                          |
219\*=========================================================================*/
220
221rtems_libi2c_bus_ops_t bsp_spi_ops = {
[574fb67]222  .init = mpc83xx_spi_init,
223  .send_start = bsp_spi_send_start_dummy,
224  .send_stop = bsp_spi_send_stop,
225  .send_addr = bsp_spi_sel_addr,
226  .read_bytes = mpc83xx_spi_read_bytes,
227  .write_bytes = mpc83xx_spi_write_bytes,
228  .ioctl = mpc83xx_spi_ioctl
[d4d60360]229};
230
231static mpc83xx_spi_desc_t bsp_spi_bus_desc = {
232  {/* public fields */
[574fb67]233    .ops = &bsp_spi_ops,
234    .size = sizeof(bsp_spi_bus_desc)
[d4d60360]235  },
236  { /* our private fields */
[574fb67]237    .reg_ptr =&mpc83xx.spi,
238    .initialized = FALSE,
239    .irq_number = BSP_IPIC_IRQ_SPI,
240    .base_frq = 0 /* filled in during init */
[d4d60360]241  }
242};
243
[7a752161]244#ifdef MPC83XX_BOARD_MPC8313ERDB
[574fb67]245
246#include <libchip/spi-sd-card.h>
247
[8a54204]248#define SD_CARD_NUMBER 1
249
250size_t sd_card_driver_table_size = SD_CARD_NUMBER;
251
252sd_card_driver_entry sd_card_driver_table [SD_CARD_NUMBER] = {
253  {
254    .device_name = "/dev/sd-card-a",
255    .bus = 0,
256    .transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
257    .command = SD_CARD_COMMAND_DEFAULT,
258    /* .response = whatever, */
259    .response_index = SD_CARD_COMMAND_SIZE,
260    .n_ac_max = SD_CARD_N_AC_MAX_DEFAULT,
261    .block_number = 0,
262    .block_size = 0,
263    .block_size_shift = 0,
264    .busy = true,
265    .verbose = true,
266    .schedule_if_busy = false
267  }
[574fb67]268};
269
[7a752161]270#endif /* MPC83XX_BOARD_MPC8313ERDB */
[574fb67]271
272
[d4d60360]273/*=========================================================================*\
274| initialization                                                            |
275\*=========================================================================*/
276
277/*=========================================================================*\
278| Function:                                                                 |
279\*-------------------------------------------------------------------------*/
280rtems_status_code bsp_register_spi
281(
282/*-------------------------------------------------------------------------*\
283| Purpose:                                                                  |
284|   register SPI bus and devices                                            |
285+---------------------------------------------------------------------------+
286| Input Parameters:                                                         |
287\*-------------------------------------------------------------------------*/
288 void                                    /* <none>                         */
289)
290/*-------------------------------------------------------------------------*\
291| Return Value:                                                             |
292|    0 or error code                                                        |
293\*=========================================================================*/
294{
[b5548e5]295  #if defined(MPC83XX_BOARD_MPC8313ERDB)
296    rtems_status_code sc = RTEMS_SUCCESSFUL;
297  #endif
[699c2be]298  unsigned spi_busno;
[b5548e5]299  int      ret_code;
[d4d60360]300
301  /*
302   * init I2C library (if not already done)
303   */
304  rtems_libi2c_initialize ();
305
306  /*
307   * init port pins used to address/select SPI devices
308   */
[574fb67]309
[b5548e5]310#if defined(MPC83XX_BOARD_MPC8313ERDB)
[574fb67]311
312  /*
313   * Configured as master (direct connection to SD card)
314   *
315   * GPIO[28] : SOUT
316   * GPIO[29] : SIN
317   * GPIO[30] : SCLK
318   * GPIO[02] : SCS (inactive high), GPIO[02] is normally connected to U43 at
319   * pin 15 of MC74LCX244DT.
320   */
321
322  /* Function */
323  mpc83xx.syscon.sicrl = (mpc83xx.syscon.sicrl & ~0x03fc0000) | 0x30000000;
324
325  /* Direction */
326  mpc83xx.gpio [0].gpdir = (mpc83xx.gpio [0].gpdir & ~0x0000000f) | 0x2000000b;
327
328  /* Data */
329  mpc83xx.gpio [0].gpdat |= 0x20000000;
330
331  /* Open Drain */
332  /* mpc83xx.gpio [0].gpdr  |= 0x0000000f; */
333
[b5548e5]334#elif defined(MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]335
[d4d60360]336  /*
337   * GPIO1[0] is nSEL_SPI for M25P40
338   * set it to be output, high
339   */
340  mpc83xx.gpio[0].gpdat |=  (1 << (31- 0));
341  mpc83xx.gpio[0].gpdir |=  (1 << (31- 0));
342  mpc83xx.gpio[0].gpdr  &= ~(1 << (31- 0));
[574fb67]343
[b5548e5]344#elif defined(MPC83XX_BOARD_HSC_CM01)
[574fb67]345
[d4d60360]346  /*
347   * GPIO1[24] is SPI_A0
348   * GPIO1[25] is SPI_A1
349   * GPIO1[26] is SPI_A2
[ac7af4a]350   * GPIO1[27] is high-active strobe
[d4d60360]351   * set pins to be output, low
352   */
353  mpc83xx.gpio[0].gpdat &= ~(0xf << (31-27));
354  mpc83xx.gpio[0].gpdir |=  (0xf << (31-27));
355  mpc83xx.gpio[0].gpdr  &= ~(0xf << (31-27));
[574fb67]356
[b5548e5]357#else
358
359  /*
360   * There is no SPI configuration information for this variant.
361   */
362  (void) spi_busno; /* avoid set but not used warning */
[d4d60360]363#endif
[574fb67]364
[42bf1b9]365  /*
366   * update base frequency in spi descriptor
367   */
368  bsp_spi_bus_desc.softc.base_frq = BSP_bus_frequency;
369
[d4d60360]370  /*
371   * register SPI bus
372   */
373  ret_code = rtems_libi2c_register_bus("/dev/spi",
374                                       &(bsp_spi_bus_desc.bus_desc));
375  if (ret_code < 0) {
376    return -ret_code;
377  }
[699c2be]378  spi_busno = (unsigned) ret_code;
[574fb67]379
[e81fe6d]380#if defined(MPC83XX_BOARD_MPC8313ERDB)
[574fb67]381
382  /* Register SD Card driver */
[8a54204]383  sd_card_driver_table [0].bus = spi_busno;
384  sc = sd_card_register();
385  if (sc != RTEMS_SUCCESSFUL) {
386    return sc;
387  }
[574fb67]388
[e81fe6d]389#elif defined(MPC83XX_BOARD_MPC8349EAMDS)
[574fb67]390
[d4d60360]391  /*
[42bf1b9]392   * register M25P40 Flash
[d4d60360]393   */
394  ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FLASH_DEVICE_NAME,
395                                       spi_flash_m25p40_rw_driver_descriptor,
396                                       spi_busno,0x00);
[7a752161]397#elif defined(MPC83XX_BOARD_HSC_CM01)
[574fb67]398
[42bf1b9]399  /*
400   * register FM25L256 FRAM
401   */
402  ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FRAM_DEVICE_NAME,
403                                       spi_fram_fm25l256_rw_driver_descriptor,
404                                       spi_busno,0x02);
[574fb67]405
406#endif
407
[42bf1b9]408  if (ret_code < 0) {
409    return -ret_code;
410  }
[574fb67]411
[d4d60360]412  /*
413   * FIXME: further drivers, when available
414   */
415  return 0;
416}
Note: See TracBrowser for help on using the repository browser.