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

Last change on this file since fe8b4b6c was fe8b4b6c, checked in by Joel Sherrill <joel@…>, on 07/11/22 at 22:28:07

bsps/powerpc/83xx: Change license to BSD-2

Updates #3053.

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