37
37
#include "adrv9001_bf.h"
38
38
#include "adi_adrv9001_hal.h"
39
39
#ifdef __KERNEL__
40
+ #include <linux/cleanup.h>
41
+ #include <linux/mutex.h>
40
42
#include <linux/string.h>
43
+
44
+ static DEFINE_MUTEX (dma_wr_lock );
41
45
#endif
42
46
43
47
/* Header files related to libraries */
@@ -103,8 +107,8 @@ const char* const adrv9001_error_table_CmdCtrlMboxCmdError[] =
103
107
"Command error"
104
108
};
105
109
106
- const char * const adrv9001_error_table_CmdError [] =
107
- {
110
+ const char * const adrv9001_error_table_CmdError [] =
111
+ {
108
112
"Error occurred during an Init Calibration. Check that no signal is being applied to the Rx ports. Check that "
109
113
"correct external LOs are applied, and synchronized, where appropriate" ,
110
114
"Error occurred during a Tracking Calibration. Disable tracking calibrations, reset and program. If enabled "
@@ -253,7 +257,7 @@ static __maybe_unused int32_t adrv9001_DmaMemReadByte(adi_adrv9001_Device_t *dev
253
257
}
254
258
255
259
regRead |= ADRV9001_DMA_CTL_LEGACY_MODE ;
256
-
260
+
257
261
/* bus size, 2'b00=byte; 2'b01=half-word; 2'b10=full-word; 2'b11=invalid */
258
262
/* core_bf.bus_size.write(bf_status, 2'b10); */
259
263
regRead |= ADRV9001_BF_ENCODE (0 , ADRV9001_DMA_CTL_BUS_SIZE_MASK , ADRV9001_DMA_CTL_BUS_SIZE_SHIFT );
@@ -325,7 +329,7 @@ static __maybe_unused int32_t adrv9001_DmaMemReadByte(adi_adrv9001_Device_t *dev
325
329
returnData [i + 1 ] = dataRead0 ;
326
330
ADRV9001_SPIREADBYTEDMA (device , "ARM_DMA_DATA_2" , ADRV9001_ADDR_ARM_DMA_DATA2 , & dataRead0 );
327
331
returnData [i + 2 ] = dataRead0 ;
328
-
332
+
329
333
/* 'single_instruction' has to be cleared before reading DMA_DATA3 and set back after */
330
334
ADI_EXPECT (adrv9001_NvsRegmapCore_SingleInstruction_Set , device , 0x0 );
331
335
ADRV9001_SPIREADBYTEDMA (device , "ARM_DMA_DATA_3" , ADRV9001_ADDR_ARM_DMA_DATA3 , & dataRead0 );
@@ -1042,7 +1046,7 @@ static void adrv9001_LoadSsiConfig(adi_adrv9001_Device_t *device, uint32_t *offs
1042
1046
cfgData [tempOffset ++ ] = (uint8_t )ssiConfig -> cmosClkInversionEn ;
1043
1047
1044
1048
cfgData [tempOffset ++ ] = (uint8_t )ssiConfig -> ddrEn ;
1045
-
1049
+
1046
1050
cfgData [tempOffset ++ ] = (uint8_t )ssiConfig -> rxMaskStrobeEn ;
1047
1051
1048
1052
/* 4 bytes of padding is needed for alignment */
@@ -1563,15 +1567,15 @@ typedef struct
1563
1567
duplexMode_e duplexMode;
1564
1568
uint8_t fhModeOn;
1565
1569
uint8_t reserved1[1u]; //< Reserved for future feature
1566
- uint8_t numDynamicProfile; // Number of Profile. =1 means only one profile and no switching
1570
+ uint8_t numDynamicProfile; // Number of Profile. =1 means only one profile and no switching
1567
1571
mcsMode_e mcsMode; // MCS mode selection: 0 - Disable, 1 - MCS Only, 2 - MCS + RFPLL phase sync
1568
- adcType_e adcTypeMonitor; // ADC type used in Monitor Mode
1569
- uint16_t pllLockTime_us; // Required lock time in microseconds for PLLs, based on ref_clk and loop bandwidth
1570
- pllModulus_t pllModuli; // PLL moduli
1571
- uint16_t pllPhaseSyncWait_us; // Worst case phase sync wait time in FH
1572
- mcsInf_e mcsInterfaceType; // 0-Disabled, 1-CMOS, 2-LVDS
1573
- uint8_t warmBootEnable; // Enable WarmBoot - Load initCal cefficients instead of running initCals
1574
- uint32_t reserved[1u]; // Reserved for future feature
1572
+ adcType_e adcTypeMonitor; // ADC type used in Monitor Mode
1573
+ uint16_t pllLockTime_us; // Required lock time in microseconds for PLLs, based on ref_clk and loop bandwidth
1574
+ pllModulus_t pllModuli; // PLL moduli
1575
+ uint16_t pllPhaseSyncWait_us; // Worst case phase sync wait time in FH
1576
+ mcsInf_e mcsInterfaceType; // 0-Disabled, 1-CMOS, 2-LVDS
1577
+ uint8_t warmBootEnable; // Enable WarmBoot - Load initCal cefficients instead of running initCals
1578
+ uint32_t reserved[1u]; // Reserved for future feature
1575
1579
} deviceSysConfig_t;
1576
1580
*/
1577
1581
static void adrv9001_DeviceSysConfigWrite (adi_adrv9001_Device_t * device , const adi_adrv9001_DeviceSysConfig_t * sysConfig , uint8_t cfgData [], uint32_t * offset )
@@ -1609,13 +1613,13 @@ static void adrv9001_DeviceSysConfigWrite(adi_adrv9001_Device_t *device, const a
1609
1613
{
1610
1614
adrv9001_LoadFourBytes (& tempOffset , cfgData , sysConfig -> pllModulus .dmModulus [i ]);
1611
1615
}
1612
-
1616
+
1613
1617
/* PLL phase sync wait time in us */
1614
1618
adrv9001_LoadTwoBytes (& tempOffset , cfgData , sysConfig -> pllPhaseSyncWait_us );
1615
1619
1616
1620
cfgData [tempOffset ++ ] = sysConfig -> mcsInterfaceType ;
1617
1621
cfgData [tempOffset ++ ] = sysConfig -> warmBootEnable ;
1618
-
1622
+
1619
1623
/* 4 bytes padding; Reserved for future use */
1620
1624
tempOffset += 4 ;
1621
1625
@@ -1994,7 +1998,7 @@ int32_t adrv9001_DmaMemWrite(adi_adrv9001_Device_t *device, uint32_t address, co
1994
1998
int32_t recoveryAction = ADI_COMMON_ACT_NO_ACTION ;
1995
1999
uint8_t singleInstruction = 0 ;
1996
2000
uint8_t spiMode = 0 ;
1997
-
2001
+
1998
2002
ADI_ENTRY_PTR_ARRAY_EXPECT (device , data , byteCount );
1999
2003
2000
2004
ADRV9001_DMAINFO ("ARM_MEM_WRITE" , armMemAddress , byteCount );
@@ -2015,7 +2019,7 @@ int32_t adrv9001_DmaMemWrite(adi_adrv9001_Device_t *device, uint32_t address, co
2015
2019
/* If Address is not on word boundary, Or ByteCount is not on Word boundary */
2016
2020
if (((armMemAddress & 0x00000003 ) > 0 ) || ((byteCount & 0x00000003 ) > 0 ))
2017
2021
{
2018
- if ((ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STANDARD_BYTES_252 == spiWriteMode ) ||
2022
+ if ((ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STANDARD_BYTES_252 == spiWriteMode ) ||
2019
2023
(ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STREAMING_BYTES_4 == spiWriteMode ))
2020
2024
{
2021
2025
ADI_ERROR_REPORT (& device -> common ,
@@ -2059,7 +2063,7 @@ int32_t adrv9001_DmaMemWrite(adi_adrv9001_Device_t *device, uint32_t address, co
2059
2063
2060
2064
/* setting up the DMA control register for a write */
2061
2065
ADRV9001_SPIWRITEBYTEDMA (device , "ARM_DMA_CTL" , ADRV9001_ADDR_ARM_DMA_CTL , regWrite );
2062
-
2066
+
2063
2067
/* Enable single instruction and disable SPI streaming mode by default.
2064
2068
* If ADRV9001 SPI streming mode is selected, then single instruction and single instruction are disbled */
2065
2069
ADI_EXPECT (adrv9001_NvsRegmapCore_SingleInstruction_Set , device , 0x1 );
@@ -2194,14 +2198,15 @@ int32_t adrv9001_DmaMemWriteFH(adi_adrv9001_Device_t *device, adi_adrv9001_FhHop
2194
2198
static uint8_t addrLsbArray [ADI_ADRV9001_FREQ_HOPPING_MAX_NUM_BYTES ];
2195
2199
static uint8_t dataArray [ADI_ADRV9001_FREQ_HOPPING_MAX_NUM_BYTES ];
2196
2200
2201
+ guard (mutex )(& dma_wr_lock );
2197
2202
memset (addrMsbArray , 0 , sizeof (addrMsbArray ));
2198
2203
memset (addrLsbArray , 0 , sizeof (addrLsbArray ));
2199
2204
memset (dataArray , 0 , sizeof (dataArray ));
2200
2205
#endif
2201
2206
2202
2207
ADI_ENTRY_PTR_ARRAY_EXPECT (device , numHopTableEntries , numHopTableEntriesByteCount );
2203
2208
ADI_ENTRY_PTR_ARRAY_EXPECT (device , hopTableBufferData , hopTableBufferDataByteCount );
2204
-
2209
+
2205
2210
/* Trigger appropriate SPI Interrupt upon table load */
2206
2211
if (hopSignal == ADI_ADRV9001_FH_HOP_SIGNAL_1 )
2207
2212
{
@@ -2217,7 +2222,7 @@ int32_t adrv9001_DmaMemWriteFH(adi_adrv9001_Device_t *device, adi_adrv9001_FhHop
2217
2222
}
2218
2223
2219
2224
ADRV9001_DMAINFO ("ARM_MEM_WRITE" , armMemAddress , byteCount );
2220
-
2225
+
2221
2226
regWrite &= ~ADRV9001_DMA_CTL_RD_WRB ;
2222
2227
regWrite |= ADRV9001_DMA_CTL_SYS_CODEB ;
2223
2228
regWrite |= ADRV9001_BF_ENCODE (2 , ADRV9001_DMA_CTL_BUS_SIZE_MASK , ADRV9001_DMA_CTL_BUS_SIZE_SHIFT );
@@ -2227,7 +2232,7 @@ int32_t adrv9001_DmaMemWriteFH(adi_adrv9001_Device_t *device, adi_adrv9001_FhHop
2227
2232
{
2228
2233
regWrite |= ADRV9001_DMA_CTL_AUTO_INCR ;
2229
2234
}
2230
-
2235
+
2231
2236
/* setting up the DMA control register for a write */
2232
2237
addrMsbArray [addrIndex ] = (uint8_t )(((ADRV9001_SPI_WRITE_POLARITY & 0x01 ) << 7 ) | ((ADRV9001_ADDR_ARM_DMA_CTL >> 8 ) & 0x7F ));
2233
2238
addrLsbArray [addrIndex ] = (uint8_t )ADRV9001_ADDR_ARM_DMA_CTL ;
@@ -2267,7 +2272,7 @@ int32_t adrv9001_DmaMemWriteFH(adi_adrv9001_Device_t *device, adi_adrv9001_FhHop
2267
2272
dataArray [addrIndex ] = numHopTableEntries [dataIndex ];
2268
2273
addrIndex ++ ;
2269
2274
}
2270
-
2275
+
2271
2276
addrMsbArray [addrIndex ] = (uint8_t )(((ADRV9001_SPI_WRITE_POLARITY & 0x01 ) << 7 ) | ((ADRV9001_ADDR_ARM_DMA_ADDR3 >> 8 ) & 0x7F ));
2272
2277
addrLsbArray [addrIndex ] = (uint8_t )ADRV9001_ADDR_ARM_DMA_ADDR3 ;
2273
2278
dataArray [addrIndex ] = (uint8_t )((hopTableBufferAddress ) >> ADRV9001_ADDR_ARM_DMA_ADDR3_BYTE_SHIFT );
@@ -2421,7 +2426,7 @@ int32_t adrv9001_DmaMemRead(adi_adrv9001_Device_t *device, uint32_t address, uin
2421
2426
returnData [i + 2 ] = dataRead ;
2422
2427
ADRV9001_SPIREADBYTEDMA (device , "ARM_DMA_DATA_1" , ADRV9001_ADDR_ARM_DMA_DATA1 , & dataRead );
2423
2428
returnData [i + 1 ] = dataRead ;
2424
-
2429
+
2425
2430
/* 'single_instruction' has to be cleared before reading DMA_DATA3 and set back after */
2426
2431
ADI_EXPECT (adrv9001_NvsRegmapCore_SingleInstruction_Set , device , 0x0 );
2427
2432
ADRV9001_SPIREADBYTEDMA (device , "ARM_DMA_DATA_0" , ADRV9001_ADDR_ARM_DMA_DATA0 , & dataRead );
@@ -2491,7 +2496,7 @@ int32_t adrv9001_FlexStreamProcessorMemWrite(adi_adrv9001_Device_t *device,
2491
2496
/* If Address is not on word boundary, Or ByteCount is not on Word boundary */
2492
2497
if (((flexSpAddress & 0x00000003 ) > 0 ) || ((byteCount & 0x00000003 ) > 0 ))
2493
2498
{
2494
- if ((ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STANDARD_BYTES_252 == spiWriteMode ) ||
2499
+ if ((ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STANDARD_BYTES_252 == spiWriteMode ) ||
2495
2500
(ADI_ADRV9001_ARM_SINGLE_SPI_WRITE_MODE_STREAMING_BYTES_4 == spiWriteMode ))
2496
2501
{
2497
2502
ADI_ERROR_REPORT (& device -> common ,
@@ -2526,7 +2531,7 @@ int32_t adrv9001_FlexStreamProcessorMemWrite(adi_adrv9001_Device_t *device,
2526
2531
2527
2532
/* setting up the flex SP DMA control register for a write */
2528
2533
ADRV9001_SPIWRITEBYTEDMA (device , "FLEX_SP_ARM_DMA_CTL" , ADRV9001_ADDR_FLEX_SP_ARM_DMA_CTL , regWrite );
2529
-
2534
+
2530
2535
/* Enable single instruction and disable SPI streaming mode by default.
2531
2536
* If ADRV9001 SPI streming mode is selected, then single instruction and single instruction are disbled */
2532
2537
ADI_EXPECT (adrv9001_NvsRegmapCore_SingleInstruction_Set , device , 0x1 );
@@ -2792,7 +2797,7 @@ static const char* adrv9001_CmdErrMsgGet(uint32_t errCode)
2792
2797
{
2793
2798
return adrv9001_error_table_CmdError [6 ];
2794
2799
}
2795
-
2800
+
2796
2801
return NULL ;
2797
2802
}
2798
2803
@@ -2849,7 +2854,7 @@ int32_t adrv9001_ArmCmdErrorHandler(adi_adrv9001_Device_t *device, uint32_t detE
2849
2854
2850
2855
ADI_EXPECT (adrv9001_ArmMailBoxErrCodeGet , device , & mailboxErrCode );
2851
2856
errorString = adrv9001_CmdErrMsgGet (mailboxErrCode );
2852
-
2857
+
2853
2858
ADI_ERROR_REPORT (& device -> common ,
2854
2859
ADI_ADRV9001_SRC_ARMCMD ,
2855
2860
mailboxErrCode ,
@@ -2951,7 +2956,7 @@ static uint32_t adrv9001_ArmProfileWrite_Validate(adi_adrv9001_Device_t *device,
2951
2956
ADI_ERROR_RETURN (device -> common .error .newAction );
2952
2957
}
2953
2958
}
2954
-
2959
+
2955
2960
/* Range check parameters in adi_adrv9001_TxSettings_t */
2956
2961
for (i = 0 ; i < ADI_ADRV9001_MAX_TXCHANNELS ; i ++ )
2957
2962
{
@@ -2967,7 +2972,7 @@ static uint32_t adrv9001_ArmProfileWrite_Validate(adi_adrv9001_Device_t *device,
2967
2972
ADI_RANGE_CHECK (device , init -> tx .txProfile [i ].txSsiConfig .ssiDataFormatSel , ADI_ADRV9001_SSI_FORMAT_2_BIT_SYMBOL_DATA , ADI_ADRV9001_SSI_FORMAT_22_BIT_I_Q_DATA_1_BIT_GAIN_CHANGE_8_BIT_GAIN_INDEX );
2968
2973
ADI_RANGE_CHECK (device , init -> tx .txProfile [i ].txSsiConfig .numLaneSel , ADI_ADRV9001_SSI_1_LANE , ADI_ADRV9001_SSI_4_LANE );
2969
2974
ADI_RANGE_CHECK (device , init -> tx .txProfile [i ].txSsiConfig .strobeType , ADI_ADRV9001_SSI_SHORT_STROBE , ADI_ADRV9001_SSI_LONG_STROBE );
2970
-
2975
+
2971
2976
if ((ADI_ADRV9001_SSI_TYPE_LVDS == init -> tx .txProfile [i ].txSsiConfig .ssiType ) &&
2972
2977
(false == init -> tx .txProfile [i ].txSsiConfig .ddrEn ) &&
2973
2978
(init -> tx .txProfile [i ].txInterfaceSampleRate_Hz > 30720000 ))
@@ -3144,7 +3149,7 @@ int32_t adrv9001_ArmProfileWrite(adi_adrv9001_Device_t *device, const adi_adrv90
3144
3149
cfgData [offset ++ ] = (uint8_t )(init -> clocks .armPowerSavingClkDiv - 1 );
3145
3150
3146
3151
cfgData [offset ++ ] = (uint8_t )init -> clocks .refClockOutEnable ;
3147
-
3152
+
3148
3153
cfgData [offset ++ ] = (uint8_t )init -> clocks .auxPllPower ;
3149
3154
cfgData [offset ++ ] = (uint8_t )init -> clocks .clkPllPower ;
3150
3155
@@ -3203,14 +3208,14 @@ int32_t adrv9001_ArmProfileWrite(adi_adrv9001_Device_t *device, const adi_adrv90
3203
3208
if (ADRV9001_BF_EQUAL (device -> devStateInfo .profilesValid , ADI_ADRV9001_TX_PROFILE_VALID ))
3204
3209
{
3205
3210
armChannels |= (init -> tx .txInitChannelMask & (ADI_ADRV9001_TX1 | ADI_ADRV9001_TX2 ));
3206
-
3211
+
3207
3212
/* Tx channels must have a valid and enabled ILB channel unless the signaling is Direct FM/FSK */
3208
3213
if (ADRV9001_BF_EQUAL (init -> tx .txInitChannelMask , ADI_ADRV9001_TX1 ) &&
3209
3214
(init -> tx .txProfile [0 ].outputSignaling != ADI_ADRV9001_TX_DIRECT_FM_FSK ))
3210
3215
{
3211
3216
armChannels |= (init -> rx .rxInitChannelMask & ADI_ADRV9001_ILB1 );
3212
3217
}
3213
-
3218
+
3214
3219
if (ADRV9001_BF_EQUAL (init -> tx .txInitChannelMask , ADI_ADRV9001_TX2 ) &&
3215
3220
(init -> tx .txProfile [1 ].outputSignaling != ADI_ADRV9001_TX_DIRECT_FM_FSK ))
3216
3221
{
@@ -3499,7 +3504,7 @@ int32_t adrv9001_DynamicProfile_Write(adi_adrv9001_Device_t *device,
3499
3504
int32_t recoveryAction = ADI_COMMON_ACT_NO_ACTION ;
3500
3505
uint32_t offset = 0 ;
3501
3506
uint8_t cfgData [ADRV9001_DYNAMIC_PROFILE_BLOB_SIZE ] = { 0 };
3502
-
3507
+
3503
3508
cfgData [offset ++ ] = dynamicProfile -> dynamicProfileIndex ;
3504
3509
cfgData [offset ++ ] = 0 ; // padding
3505
3510
cfgData [offset ++ ] = 0 ; // padding
0 commit comments