source: svn/trunk/newcon3bcm2_21bu/nexus/modules/spi/7552/src/nexus_spi.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 11.9 KB
Line 
1/***************************************************************************
2 *     (c)2007-2010 Broadcom Corporation
3 *
4 *  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 *  and may only be used, duplicated, modified or distributed pursuant to the terms and
6 *  conditions of a separate, written license agreement executed between you and Broadcom
7 *  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 *  no license (express or implied), right to use, or waiver of any kind with respect to the
9 *  Software, and Broadcom expressly reserves all rights in and to the Software and all
10 *  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 *  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 *  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13 *
14 *  Except as expressly set forth in the Authorized License,
15 *
16 *  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 *  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 *  and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *
20 *  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 *  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 *  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 *  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 *  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 *  USE OR PERFORMANCE OF THE SOFTWARE.
28 *
29 *  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 *  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 *  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 *  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 *  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 *  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 *  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 *  ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: nexus_spi.c $
39 * $brcm_Revision: 16 $
40 * $brcm_Date: 11/12/10 3:31p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/spi/7400/src/nexus_spi.c $
47 *
48 * 16   11/12/10 3:31p gmohile
49 * SW7408-145 : Fix 7408 support
50 *
51 * 15   11/3/10 1:39p jhaberf
52 * SW35125-1: Added 35125 DTV chip support
53 *
54 * 14   6/9/10 2:48p jhaberf
55 * SW35230-67: integrated latest nexus SPI support for the 35230
56 *
57 * 13   5/19/10 5:20p jhaberf
58 * SW35230-67: Added bHeap and bufferSize structure members for 35230
59 *
60 * 12   5/13/10 4:32p jhaberf
61 * SW35230-67: Added nexus spi changes for 35230 DTV chip
62 *
63 * 11   1/7/10 11:33a jhaberf
64 * SW35230-1: Added some #fidef's in order to get module building for
65 *  35230 DTV chip
66 *
67 * 10   1/6/10 11:33a mphillip
68 * SW3548-2660: Merge interrupt vs. polling mode changes to main
69 *
70 * SW3548-2660/2   1/6/10 11:29a mphillip
71 * SW3548-2660: Rename variable exposing interrupt vs. polling mode for
72 *  transfers
73 *
74 * SW3548-2660/1   1/5/10 6:06p mphillip
75 * SW3548-2660: Add a user setting to enable polling for transfers
76 *
77 * 9   11/11/09 11:53a erickson
78 * SW7405-3362: add dtl and rdsclk fields to NEXUS_SpiSettings
79 *
80 * 8   1/26/09 12:05p erickson
81 * PR51468: global variable naming convention
82 *
83 * 7   1/26/09 11:07a erickson
84 * PR51468: global variable naming convention
85 *
86 * 6   11/20/08 8:27a ahulse
87 * PR49515: If set, override default settings with user set settings
88 *
89 * 5   8/18/08 10:28a katrep
90 * PR45674: Compiler warnings in DEBUG=n builds
91 *
92 * 4   4/11/08 9:53a erickson
93 * PR41246: convert BDBG_OBJECT_UNSET to BDBG_OBJECT_DESTROY if freeing
94 *  memory
95 *
96 * 3   3/31/08 12:32p erickson
97 * PR41073: check result of malloc and fail graciously
98 *
99 * 2   1/25/08 2:29p erickson
100 * PR39016: implemented Read,Write,SetSettings
101 *
102 * 1   1/18/08 2:21p jgarrett
103 * PR 38808: Merging to main branch
104 *
105 * Nexus_Devel/3   11/21/07 11:12a erickson
106 * PR37423: update
107 *
108 * Nexus_Devel/2   11/20/07 2:23p erickson
109 * PR37423: simplify module init
110 *
111 * Nexus_Devel/1   11/20/07 1:28p erickson
112 * PR37423: added uart, gpio, spi modules
113 *
114 **************************************************************************/
115#include "nexus_spi_module.h"
116#include "bspi.h"
117#include "breg_spi.h"
118#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
119#include "bchp_pcu.h"
120#include "bchp_tvm.h"
121#elif (BCHP_CHIP==7408)
122#include "bchp_hif_mspi.h"
123#else
124#include "bchp_mspi.h"
125#endif /*BCHP_CHIP==35230*/
126#include "priv/nexus_core.h"
127
128BDBG_MODULE(nexus_spi);
129
130#ifndef BCHP_MSPI_SPCR0_MSB_CPOL_MASK
131#define BCHP_MSPI_SPCR0_MSB_CPOL_MASK BCHP_HIF_MSPI_SPCR0_MSB_CPOL_MASK
132#define BCHP_MSPI_SPCR0_MSB_CPHA_MASK BCHP_HIF_MSPI_SPCR0_MSB_CPHA_MASK
133#endif
134
135NEXUS_ModuleHandle g_NEXUS_spiModule;
136struct {
137    NEXUS_SpiModuleSettings settings;
138    BSPI_Handle spi;
139} g_NEXUS_spi;
140
141/****************************************
142* Module functions
143***************/
144
145void NEXUS_SpiModule_GetDefaultSettings(NEXUS_SpiModuleSettings *pSettings)
146{
147    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
148}
149
150NEXUS_ModuleHandle NEXUS_SpiModule_Init(const NEXUS_SpiModuleSettings *pSettings)
151{
152    BSPI_Settings spiSettings;
153    BERR_Code rc;
154
155    BDBG_ASSERT(!g_NEXUS_spiModule);
156    g_NEXUS_spiModule = NEXUS_Module_Create("spi", NULL);
157    if (pSettings) {
158        g_NEXUS_spi.settings = *pSettings;
159    }
160    else {
161        NEXUS_SpiModule_GetDefaultSettings(&g_NEXUS_spi.settings);
162    }
163
164    BSPI_GetDefaultSettings(&spiSettings, g_pCoreHandles->chp);
165    rc = BSPI_Open(&g_NEXUS_spi.spi, g_pCoreHandles->chp, g_pCoreHandles->reg, g_pCoreHandles->bint, &spiSettings);
166    if (rc) {rc=BERR_TRACE(NEXUS_UNKNOWN); return NULL;}
167
168    return g_NEXUS_spiModule;
169}
170
171void NEXUS_SpiModule_Uninit()
172{
173    BSPI_Close(g_NEXUS_spi.spi);
174    NEXUS_Module_Destroy(g_NEXUS_spiModule);
175    g_NEXUS_spiModule = NULL;
176}
177
178/****************************************
179* API functions
180***************/
181
182BDBG_OBJECT_ID(NEXUS_Spi);
183
184struct NEXUS_Spi {
185    BDBG_OBJECT(NEXUS_Spi)
186    BSPI_ChannelHandle spiChannel;
187    BREG_SPI_Handle spiReg;
188    NEXUS_SpiSettings settings;
189};
190
191void NEXUS_Spi_GetDefaultSettings(NEXUS_SpiSettings *pSettings)
192{
193    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
194    pSettings->txLeadingCapFalling = true;
195    pSettings->clockActiveLow = true;
196    pSettings->interruptMode = true;
197#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
198    pSettings->interruptMode = false;
199    pSettings->pcs = NEXUS_SpiPeripheralChipSelect_e0;      /* default to first SS line */
200    pSettings->xferDMAMode = false;
201        pSettings->hHeap = NULL;
202        pSettings->bufferSize = 0;
203#endif
204}
205
206NEXUS_SpiHandle NEXUS_Spi_Open(unsigned index, const NEXUS_SpiSettings *pSettings)
207{
208    BSPI_ChannelSettings channelSettings;
209    NEXUS_SpiHandle spi;
210    BERR_Code rc;
211    unsigned totalChannels;
212    NEXUS_SpiSettings defaultSettings;
213
214    if (!pSettings) {
215        NEXUS_Spi_GetDefaultSettings(&defaultSettings);
216        pSettings = &defaultSettings;
217    }
218
219    BSPI_GetTotalChannels(g_NEXUS_spi.spi, &totalChannels);
220    if (index >= totalChannels) {
221        BDBG_ERR(("invalid Spi[%d]", index));
222        return NULL;
223    }
224
225    spi = BKNI_Malloc(sizeof(*spi));
226    if (!spi) {
227        rc=BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY);
228        return NULL;
229    }
230    BKNI_Memset(spi, 0, sizeof(*spi));
231    BDBG_OBJECT_SET(spi, NEXUS_Spi);
232
233    BSPI_GetChannelDefaultSettings(g_NEXUS_spi.spi, index, &channelSettings);
234
235    if ( pSettings->baud )
236        channelSettings.baud                   = pSettings->baud;
237    if ( pSettings->bitsPerTransfer )
238        channelSettings.bitsPerTxfr            = pSettings->bitsPerTransfer;
239    if ( pSettings->lastByteContinueEnable )
240        channelSettings.lastByteContinueEnable = pSettings->lastByteContinueEnable;
241    if ( pSettings->useUserDtlAndDsclk )
242        channelSettings.useUserDtlAndDsclk     = pSettings->useUserDtlAndDsclk;
243
244    channelSettings.intMode                    = pSettings->interruptMode;
245#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
246    if ( pSettings->pcs )
247        channelSettings.pcs                    = pSettings->pcs;
248    channelSettings.xferDMAMode                = pSettings->xferDMAMode;
249
250        if(pSettings->hHeap != NULL)
251        {
252            channelSettings.hHeap                      = NEXUS_Heap_GetMemHandle(pSettings->hHeap);
253        }
254        channelSettings.bufferSize                 = pSettings->bufferSize;
255#endif
256
257    rc = BSPI_OpenChannel(g_NEXUS_spi.spi, &spi->spiChannel, index, &channelSettings);
258    if (rc) {rc=BERR_TRACE(rc); goto error;}
259
260    rc = BSPI_CreateSpiRegHandle(spi->spiChannel, &spi->spiReg);
261    if (rc) {rc=BERR_TRACE(rc); goto error;}
262
263    rc = NEXUS_Spi_SetSettings(spi, pSettings);
264    if (rc) {rc=BERR_TRACE(rc); goto error;}
265
266    return spi;
267error:
268    NEXUS_Spi_Close(spi);
269    return NULL;
270}
271
272void NEXUS_Spi_Close(NEXUS_SpiHandle spi)
273{
274    BDBG_OBJECT_ASSERT(spi, NEXUS_Spi);
275
276    if (spi->spiReg) {
277        BSPI_CloseSpiRegHandle(spi->spiReg);
278    }
279    if (spi->spiChannel) {
280        BSPI_CloseChannel(spi->spiChannel);
281    }
282
283    BDBG_OBJECT_DESTROY(spi, NEXUS_Spi);
284    BKNI_Free(spi);
285}
286
287void NEXUS_Spi_GetSettings(NEXUS_SpiHandle spi, NEXUS_SpiSettings *pSettings)
288{
289    BDBG_OBJECT_ASSERT(spi, NEXUS_Spi);
290    *pSettings = spi->settings;
291}
292
293NEXUS_Error NEXUS_Spi_SetSettings(NEXUS_SpiHandle spi, const NEXUS_SpiSettings *pSettings)
294{
295    uint8_t clkConfig;
296    BERR_Code rc;
297
298    BDBG_OBJECT_ASSERT(spi, NEXUS_Spi);
299
300    BSPI_GetClkConfig(spi->spiChannel, &clkConfig);
301#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
302    /* TODO - 35230 SPI register manipulations here */
303    if (pSettings->clockActiveLow)
304        clkConfig |= 0x4;
305    else
306        clkConfig &= ~(0x4);
307
308    if (pSettings->txLeadingCapFalling)
309        clkConfig |= 0x1;
310    else
311        clkConfig &= ~(0x1);
312
313        if (pSettings->rxLeading)
314                clkConfig |= 0x2;
315        else
316                clkConfig &= ~(0x2);
317#else
318    if (pSettings->clockActiveLow)
319        clkConfig |= BCHP_MSPI_SPCR0_MSB_CPOL_MASK; /* if 1, then 0 is active */
320    else
321        clkConfig &= ~BCHP_MSPI_SPCR0_MSB_CPOL_MASK; /* if 0, then 1 is active */
322    if (pSettings->txLeadingCapFalling)
323        clkConfig |= BCHP_MSPI_SPCR0_MSB_CPHA_MASK;
324    else
325        clkConfig &= ~BCHP_MSPI_SPCR0_MSB_CPHA_MASK;
326#endif/*BCHP_CHIP==35230*/
327
328    rc = BSPI_SetClkConfig(spi->spiChannel, clkConfig);
329    if (rc) return BERR_TRACE(rc);
330
331    rc = BSPI_SetDTLConfig(spi->spiChannel, pSettings->dtl);
332    if (rc) return BERR_TRACE(rc);
333
334#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
335    /* nothing to do */
336#else
337    rc = BSPI_SetRDSCLKConfig(spi->spiChannel, pSettings->rdsclk);
338    if (rc) return BERR_TRACE(rc);
339#endif
340
341#if ((BCHP_CHIP==35125) || (BCHP_CHIP==35230) || (BCHP_CHIP==35330))
342    /* set the SPI transfer mode, either DMA or regular RxTx register */
343    rc = BSPI_SetDMAMode(spi->spiChannel, pSettings->xferDMAMode);
344    if (rc) return BERR_TRACE(rc);
345
346    /* set the slave select */
347    rc = BSPI_SetPCS(spi->spiChannel, pSettings->pcs);
348    if (rc) return BERR_TRACE(rc);
349#endif
350
351    spi->settings = *pSettings;
352    return 0;
353}
354
355NEXUS_Error NEXUS_Spi_Write(NEXUS_SpiHandle spi, const uint8_t *pWriteData,
356    size_t length)
357{
358    BERR_Code rc;
359    BDBG_OBJECT_ASSERT(spi, NEXUS_Spi);
360    rc = BREG_SPI_Write(spi->spiReg, pWriteData, length);
361    if (rc) return BERR_TRACE(rc);
362    return 0;
363}
364
365NEXUS_Error NEXUS_Spi_Read(NEXUS_SpiHandle spi, const uint8_t *pWriteData,
366    uint8_t *pReadData, size_t length)
367{
368    BERR_Code rc;
369    BDBG_OBJECT_ASSERT(spi, NEXUS_Spi);
370    rc = BREG_SPI_Read(spi->spiReg, pWriteData, pReadData, length);
371    if (rc) return BERR_TRACE(rc);
372    return 0;
373}
Note: See TracBrowser for help on using the repository browser.