Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC ADC 100M 14b 4cha
Commits
05bbebf8
Commit
05bbebf8
authored
Sep 07, 2021
by
Federico Vaga
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/v6.0.0.rc1'
parents
2f6f18d7
8ce74dac
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
789 additions
and
361 deletions
+789
-361
.gitlab-ci.yml
.gitlab-ci.yml
+7
-0
CHANGELOG.rst
CHANGELOG.rst
+20
-0
index.rst
doc/gateware/index.rst
+6
-3
driver.rst
doc/software/driver.rst
+4
-4
fmc_adc_100Ms_csr.cheby
hdl/cheby/fmc_adc_100Ms_csr.cheby
+2
-4
fmc_adc_100Ms_csr.vhd
hdl/cheby/fmc_adc_100Ms_csr.vhd
+7
-5
ltc2174_2l16b_receiver.vhd
hdl/platform/xilinx/spartan6/ltc2174_2l16b_receiver.vhd
+205
-57
fmc_adc_100Ms_core.vhd
hdl/rtl/fmc_adc_100Ms_core.vhd
+23
-10
fmc_adc_mezzanine.vhd
hdl/rtl/fmc_adc_mezzanine.vhd
+5
-2
fmc_adc_100Ms_csr.v
hdl/testbench/include/fmc_adc_100Ms_csr.v
+2
-2
svec_ref_fmc_adc_100Ms.vhd
hdl/top/svec_ref_design/svec_ref_fmc_adc_100Ms.vhd
+2
-1
Kbuild
software/kernel/Kbuild
+4
-0
fa-calibration.c
software/kernel/fa-calibration.c
+71
-47
fa-core.c
software/kernel/fa-core.c
+144
-23
fa-debug.c
software/kernel/fa-debug.c
+24
-33
fa-dma.c
software/kernel/fa-dma.c
+36
-52
fa-zio-drv.c
software/kernel/fa-zio-drv.c
+36
-34
fa-zio-trg.c
software/kernel/fa-zio-trg.c
+4
-6
fmc-adc-100m14b4ch-spec-core.c
software/kernel/fmc-adc-100m14b4ch-spec-core.c
+18
-6
fmc-adc-100m14b4ch-svec-core.c
software/kernel/fmc-adc-100m14b4ch-svec-core.c
+34
-16
fmc-adc-100m14b4cha-private.h
software/kernel/fmc-adc-100m14b4cha-private.h
+27
-7
fmc-adc-100m14b4cha.h
software/kernel/fmc-adc-100m14b4cha.h
+11
-0
fmc-adc-100m14b4cha.h
software/kernel/platform_data/fmc-adc-100m14b4cha.h
+1
-2
spi.c
software/kernel/spi.c
+5
-2
Makefile
software/tools/Makefile
+4
-0
fau-acq-time.c
software/tools/fau-acq-time.c
+6
-5
fau-calibration.c
software/tools/fau-calibration.c
+49
-27
fau-trg-config.c
software/tools/fau-trg-config.c
+32
-13
No files found.
.gitlab-ci.yml
View file @
05bbebf8
...
@@ -26,6 +26,13 @@ cppcheck:
...
@@ -26,6 +26,13 @@ cppcheck:
script
:
script
:
-
make -C software cppcheck
-
make -C software cppcheck
flawfinder
:
stage
:
static-analysis
image
:
name
:
gitlab-registry.cern.ch/coht/common-containers/static-analysis:latest
script
:
-
make -C software/tools flawfinder
documentation
:
documentation
:
stage
:
build
stage
:
build
image
:
image
:
...
...
CHANGELOG.rst
View file @
05bbebf8
...
@@ -6,6 +6,26 @@
...
@@ -6,6 +6,26 @@
Changelog
Changelog
=========
=========
6.0.0 - 2021-09-07
==================
Added
-----
- hdl: configurable auto byte swap in hardware, useful for SVEC to reduce software complexity
- hdl,sw: DMA data is always little-endian
- sw: software version validation against FPGA version
- bld: flawfinder check on software tools
Changed
-------
- sw: offsets are not anymore in uV but they are just raw values
Fixed
-----
- sw: security fixes detected by flawfinder
- sw: fixes detected by checkpatch.pl
- sw: style fixes detected by checkpatch.pl
- sw: improve compatibility with newer ( > 3.10) Linux kernel versions
5.0.4 - 2021-07-09
5.0.4 - 2021-07-09
==================
==================
Fixed
Fixed
...
...
doc/gateware/index.rst
View file @
05bbebf8
...
@@ -377,7 +377,7 @@ Mezzanine 1-wire Master
...
@@ -377,7 +377,7 @@ Mezzanine 1-wire Master
~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
.. note::
.. note::
FIXME talk about the themometer core in general-cores
FIXME talk about the the
r
mometer core in general-cores
Mezzanine I2C Master
Mezzanine I2C Master
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
...
@@ -470,8 +470,8 @@ register enables the sampling clock (Si570 chip), and the other
...
@@ -470,8 +470,8 @@ register enables the sampling clock (Si570 chip), and the other
internal components. Also, in order to use the input offset DACs, the
internal components. Also, in order to use the input offset DACs, the
``OFFSET_DAC_CLR_N`` field must be set to one.
``OFFSET_DAC_CLR_N`` field must be set to one.
The field ``
MAN_BITSLIP`` allows to ’manually’ control the ADC data
The field ``
SERDES_CALIB`` allows to ’manually’ restart the timing
alignment in the de-serialiser. The fields ``TRIG_LED`` and
calibration and
alignment in the de-serialiser. The fields ``TRIG_LED`` and
``ACQ_LED`` allows to control the FMC front panel LEDs. Those four
``ACQ_LED`` allows to control the FMC front panel LEDs. Those four
fields are for test purpose only and must stay zero in normal
fields are for test purpose only and must stay zero in normal
operation.
operation.
...
@@ -1047,6 +1047,9 @@ state.
...
@@ -1047,6 +1047,9 @@ state.
The start of an acquisition is prohibited if either the number of
The start of an acquisition is prohibited if either the number of
shots or the number of post-trigger samples is equal to zero.
shots or the number of post-trigger samples is equal to zero.
.. note::
Acquired data are always stored to be read in little endian.
Single-shot Mode
Single-shot Mode
----------------
----------------
...
...
doc/software/driver.rst
View file @
05bbebf8
...
@@ -195,16 +195,16 @@ chN-50ohm-term
...
@@ -195,16 +195,16 @@ chN-50ohm-term
turn on the termination resistor. Default is 0.
turn on the termination resistor. Default is 0.
chN-offset
chN-offset
The user offset is an integer value in the range [-5
000000,5000000], and
The user offset is an integer value in the range [-5
.000V, +4.999V]. It
it represents microvolts. The offset represents the center-scale
follows the DAC data format, so the range is describe by 16bits from 0x0000
of conversion for the input channel.
Internally, a DAC is used to
(-5.000V) to 0xFFFF (+4.999V).
Internally, a DAC is used to
generate the requested voltage, which is then subtracted from the
generate the requested voltage, which is then subtracted from the
input signal. DAC values are corrected according to the
input signal. DAC values are corrected according to the
calibration values retrieved from the FMC EEPROM. For this reason,
calibration values retrieved from the FMC EEPROM. For this reason,
the offset may saturate at values less than +/- 5V.
the offset may saturate at values less than +/- 5V.
chN-offset-zero
chN-offset-zero
The necessary offset to to bring the signal to 0 in
microv
olts (it must be
The necessary offset to to bring the signal to 0 in
V
olts (it must be
withing the range of chN-offset).
withing the range of chN-offset).
chN-vref
chN-vref
...
...
hdl/cheby/fmc_adc_100Ms_csr.cheby
View file @
05bbebf8
...
@@ -41,11 +41,9 @@ memory-map:
...
@@ -41,11 +41,9 @@ memory-map:
range: 3
range: 3
description: Offset DACs clear (active low)
description: Offset DACs clear (active low)
- field:
- field:
name:
man_bitslip
name:
serdes_calib
range: 4
range: 4
description: Manual serdes bitslip (ignore on read)
description: Initial serdes calibration
x-hdl:
type: wire
- field:
- field:
name: trig_led
name: trig_led
range: 6
range: 6
...
...
hdl/cheby/fmc_adc_100Ms_csr.vhd
View file @
05bbebf8
...
@@ -15,7 +15,7 @@ package fmc_adc_100ms_csr_pkg is
...
@@ -15,7 +15,7 @@ package fmc_adc_100ms_csr_pkg is
ctl_fsm_cmd
:
std_logic_vector
(
1
downto
0
);
ctl_fsm_cmd
:
std_logic_vector
(
1
downto
0
);
ctl_fmc_clk_oe
:
std_logic
;
ctl_fmc_clk_oe
:
std_logic
;
ctl_offset_dac_clr_n
:
std_logic
;
ctl_offset_dac_clr_n
:
std_logic
;
ctl_
man_bitslip
:
std_logic
;
ctl_
serdes_calib
:
std_logic
;
ctl_trig_led
:
std_logic
;
ctl_trig_led
:
std_logic
;
ctl_acq_led
:
std_logic
;
ctl_acq_led
:
std_logic
;
ctl_clear_trig_stat
:
std_logic
;
ctl_clear_trig_stat
:
std_logic
;
...
@@ -47,7 +47,6 @@ package fmc_adc_100ms_csr_pkg is
...
@@ -47,7 +47,6 @@ package fmc_adc_100ms_csr_pkg is
type
t_fmc_adc_100ms_csr_slave_out
is
record
type
t_fmc_adc_100ms_csr_slave_out
is
record
ctl_fsm_cmd
:
std_logic_vector
(
1
downto
0
);
ctl_fsm_cmd
:
std_logic_vector
(
1
downto
0
);
ctl_man_bitslip
:
std_logic
;
ctl_clear_trig_stat
:
std_logic
;
ctl_clear_trig_stat
:
std_logic
;
ctl_calib_apply
:
std_logic
;
ctl_calib_apply
:
std_logic
;
sta_fsm
:
std_logic_vector
(
2
downto
0
);
sta_fsm
:
std_logic_vector
(
2
downto
0
);
...
@@ -120,6 +119,7 @@ architecture syn of fmc_adc_100ms_csr is
...
@@ -120,6 +119,7 @@ architecture syn of fmc_adc_100ms_csr is
signal
wb_wip
:
std_logic
;
signal
wb_wip
:
std_logic
;
signal
ctl_fmc_clk_oe_reg
:
std_logic
;
signal
ctl_fmc_clk_oe_reg
:
std_logic
;
signal
ctl_offset_dac_clr_n_reg
:
std_logic
;
signal
ctl_offset_dac_clr_n_reg
:
std_logic
;
signal
ctl_serdes_calib_reg
:
std_logic
;
signal
ctl_trig_led_reg
:
std_logic
;
signal
ctl_trig_led_reg
:
std_logic
;
signal
ctl_acq_led_reg
:
std_logic
;
signal
ctl_acq_led_reg
:
std_logic
;
signal
ctl_wreq
:
std_logic
;
signal
ctl_wreq
:
std_logic
;
...
@@ -250,7 +250,7 @@ begin
...
@@ -250,7 +250,7 @@ begin
fmc_adc_100ms_csr_o
.
ctl_fsm_cmd
<=
wr_dat_d0
(
1
downto
0
);
fmc_adc_100ms_csr_o
.
ctl_fsm_cmd
<=
wr_dat_d0
(
1
downto
0
);
fmc_adc_100ms_csr_o
.
ctl_fmc_clk_oe
<=
ctl_fmc_clk_oe_reg
;
fmc_adc_100ms_csr_o
.
ctl_fmc_clk_oe
<=
ctl_fmc_clk_oe_reg
;
fmc_adc_100ms_csr_o
.
ctl_offset_dac_clr_n
<=
ctl_offset_dac_clr_n_reg
;
fmc_adc_100ms_csr_o
.
ctl_offset_dac_clr_n
<=
ctl_offset_dac_clr_n_reg
;
fmc_adc_100ms_csr_o
.
ctl_
man_bitslip
<=
wr_dat_d0
(
4
)
;
fmc_adc_100ms_csr_o
.
ctl_
serdes_calib
<=
ctl_serdes_calib_reg
;
fmc_adc_100ms_csr_o
.
ctl_trig_led
<=
ctl_trig_led_reg
;
fmc_adc_100ms_csr_o
.
ctl_trig_led
<=
ctl_trig_led_reg
;
fmc_adc_100ms_csr_o
.
ctl_acq_led
<=
ctl_acq_led_reg
;
fmc_adc_100ms_csr_o
.
ctl_acq_led
<=
ctl_acq_led_reg
;
fmc_adc_100ms_csr_o
.
ctl_clear_trig_stat
<=
wr_dat_d0
(
8
);
fmc_adc_100ms_csr_o
.
ctl_clear_trig_stat
<=
wr_dat_d0
(
8
);
...
@@ -260,6 +260,7 @@ begin
...
@@ -260,6 +260,7 @@ begin
if
rst_n_i
=
'0'
then
if
rst_n_i
=
'0'
then
ctl_fmc_clk_oe_reg
<=
'0'
;
ctl_fmc_clk_oe_reg
<=
'0'
;
ctl_offset_dac_clr_n_reg
<=
'0'
;
ctl_offset_dac_clr_n_reg
<=
'0'
;
ctl_serdes_calib_reg
<=
'0'
;
ctl_trig_led_reg
<=
'0'
;
ctl_trig_led_reg
<=
'0'
;
ctl_acq_led_reg
<=
'0'
;
ctl_acq_led_reg
<=
'0'
;
ctl_wack
<=
'0'
;
ctl_wack
<=
'0'
;
...
@@ -267,6 +268,7 @@ begin
...
@@ -267,6 +268,7 @@ begin
if
ctl_wreq
=
'1'
then
if
ctl_wreq
=
'1'
then
ctl_fmc_clk_oe_reg
<=
wr_dat_d0
(
2
);
ctl_fmc_clk_oe_reg
<=
wr_dat_d0
(
2
);
ctl_offset_dac_clr_n_reg
<=
wr_dat_d0
(
3
);
ctl_offset_dac_clr_n_reg
<=
wr_dat_d0
(
3
);
ctl_serdes_calib_reg
<=
wr_dat_d0
(
4
);
ctl_trig_led_reg
<=
wr_dat_d0
(
6
);
ctl_trig_led_reg
<=
wr_dat_d0
(
6
);
ctl_acq_led_reg
<=
wr_dat_d0
(
7
);
ctl_acq_led_reg
<=
wr_dat_d0
(
7
);
end
if
;
end
if
;
...
@@ -624,7 +626,7 @@ begin
...
@@ -624,7 +626,7 @@ begin
end
process
;
end
process
;
-- Process for read requests.
-- Process for read requests.
process
(
rd_adr_d0
,
rd_req_d0
,
fmc_adc_100ms_csr_i
.
ctl_fsm_cmd
,
ctl_fmc_clk_oe_reg
,
ctl_offset_dac_clr_n_reg
,
fmc_adc_100ms_csr_i
.
ctl_man_bitslip
,
ctl_trig_led_reg
,
ctl_acq_led_reg
,
fmc_adc_100ms_csr_i
.
ctl_clear_trig_stat
,
fmc_adc_100ms_csr_i
.
ctl_calib_apply
,
fmc_adc_100ms_csr_i
.
sta_fsm
,
fmc_adc_100ms_csr_i
.
sta_serdes_pll
,
fmc_adc_100ms_csr_i
.
sta_serdes_synced
,
fmc_adc_100ms_csr_i
.
sta_acq_cfg
,
fmc_adc_100ms_csr_i
.
sta_fmc_nr
,
fmc_adc_100ms_csr_i
.
sta_calib_busy
,
fmc_adc_100ms_csr_i
.
trig_stat_ext
,
fmc_adc_100ms_csr_i
.
trig_stat_sw
,
fmc_adc_100ms_csr_i
.
trig_stat_time
,
fmc_adc_100ms_csr_i
.
trig_stat_ch1
,
fmc_adc_100ms_csr_i
.
trig_stat_ch2
,
fmc_adc_100ms_csr_i
.
trig_stat_ch3
,
fmc_adc_100ms_csr_i
.
trig_stat_ch4
,
trig_en_ext_reg
,
fmc_adc_100ms_csr_i
.
trig_en_sw
,
trig_en_time_reg
,
fmc_adc_100ms_csr_i
.
trig_en_aux_time
,
trig_en_ch1_reg
,
trig_en_ch2_reg
,
trig_en_ch3_reg
,
trig_en_ch4_reg
,
trig_pol_ext_reg
,
trig_pol_ch1_reg
,
trig_pol_ch2_reg
,
trig_pol_ch3_reg
,
trig_pol_ch4_reg
,
ext_trig_dly_reg
,
shots_nbr_reg
,
fmc_adc_100ms_csr_i
.
shots_remain
,
fmc_adc_100ms_csr_i
.
multi_depth
,
fmc_adc_100ms_csr_i
.
trig_pos
,
fmc_adc_100ms_csr_i
.
fs_freq
,
downsample_reg
,
pre_samples_reg
,
post_samples_reg
,
fmc_adc_100ms_csr_i
.
samples_cnt
,
fmc_adc_ch1_i
.
dat
,
fmc_adc_ch1_rack
,
fmc_adc_ch2_i
.
dat
,
fmc_adc_ch2_rack
,
fmc_adc_ch3_i
.
dat
,
fmc_adc_ch3_rack
,
fmc_adc_ch4_i
.
dat
,
fmc_adc_ch4_rack
)
begin
process
(
rd_adr_d0
,
rd_req_d0
,
fmc_adc_100ms_csr_i
.
ctl_fsm_cmd
,
ctl_fmc_clk_oe_reg
,
ctl_offset_dac_clr_n_reg
,
ctl_serdes_calib_reg
,
ctl_trig_led_reg
,
ctl_acq_led_reg
,
fmc_adc_100ms_csr_i
.
ctl_clear_trig_stat
,
fmc_adc_100ms_csr_i
.
ctl_calib_apply
,
fmc_adc_100ms_csr_i
.
sta_fsm
,
fmc_adc_100ms_csr_i
.
sta_serdes_pll
,
fmc_adc_100ms_csr_i
.
sta_serdes_synced
,
fmc_adc_100ms_csr_i
.
sta_acq_cfg
,
fmc_adc_100ms_csr_i
.
sta_fmc_nr
,
fmc_adc_100ms_csr_i
.
sta_calib_busy
,
fmc_adc_100ms_csr_i
.
trig_stat_ext
,
fmc_adc_100ms_csr_i
.
trig_stat_sw
,
fmc_adc_100ms_csr_i
.
trig_stat_time
,
fmc_adc_100ms_csr_i
.
trig_stat_ch1
,
fmc_adc_100ms_csr_i
.
trig_stat_ch2
,
fmc_adc_100ms_csr_i
.
trig_stat_ch3
,
fmc_adc_100ms_csr_i
.
trig_stat_ch4
,
trig_en_ext_reg
,
fmc_adc_100ms_csr_i
.
trig_en_sw
,
trig_en_time_reg
,
fmc_adc_100ms_csr_i
.
trig_en_aux_time
,
trig_en_ch1_reg
,
trig_en_ch2_reg
,
trig_en_ch3_reg
,
trig_en_ch4_reg
,
trig_pol_ext_reg
,
trig_pol_ch1_reg
,
trig_pol_ch2_reg
,
trig_pol_ch3_reg
,
trig_pol_ch4_reg
,
ext_trig_dly_reg
,
shots_nbr_reg
,
fmc_adc_100ms_csr_i
.
shots_remain
,
fmc_adc_100ms_csr_i
.
multi_depth
,
fmc_adc_100ms_csr_i
.
trig_pos
,
fmc_adc_100ms_csr_i
.
fs_freq
,
downsample_reg
,
pre_samples_reg
,
post_samples_reg
,
fmc_adc_100ms_csr_i
.
samples_cnt
,
fmc_adc_ch1_i
.
dat
,
fmc_adc_ch1_rack
,
fmc_adc_ch2_i
.
dat
,
fmc_adc_ch2_rack
,
fmc_adc_ch3_i
.
dat
,
fmc_adc_ch3_rack
,
fmc_adc_ch4_i
.
dat
,
fmc_adc_ch4_rack
)
begin
-- By default ack read requests
-- By default ack read requests
rd_dat_d0
<=
(
others
=>
'X'
);
rd_dat_d0
<=
(
others
=>
'X'
);
fmc_adc_ch1_re
<=
'0'
;
fmc_adc_ch1_re
<=
'0'
;
...
@@ -640,7 +642,7 @@ begin
...
@@ -640,7 +642,7 @@ begin
rd_dat_d0
(
1
downto
0
)
<=
fmc_adc_100ms_csr_i
.
ctl_fsm_cmd
;
rd_dat_d0
(
1
downto
0
)
<=
fmc_adc_100ms_csr_i
.
ctl_fsm_cmd
;
rd_dat_d0
(
2
)
<=
ctl_fmc_clk_oe_reg
;
rd_dat_d0
(
2
)
<=
ctl_fmc_clk_oe_reg
;
rd_dat_d0
(
3
)
<=
ctl_offset_dac_clr_n_reg
;
rd_dat_d0
(
3
)
<=
ctl_offset_dac_clr_n_reg
;
rd_dat_d0
(
4
)
<=
fmc_adc_100ms_csr_i
.
ctl_man_bitslip
;
rd_dat_d0
(
4
)
<=
ctl_serdes_calib_reg
;
rd_dat_d0
(
5
)
<=
'0'
;
rd_dat_d0
(
5
)
<=
'0'
;
rd_dat_d0
(
6
)
<=
ctl_trig_led_reg
;
rd_dat_d0
(
6
)
<=
ctl_trig_led_reg
;
rd_dat_d0
(
7
)
<=
ctl_acq_led_reg
;
rd_dat_d0
(
7
)
<=
ctl_acq_led_reg
;
...
...
hdl/platform/xilinx/spartan6/ltc2174_2l16b_receiver.vhd
View file @
05bbebf8
This diff is collapsed.
Click to expand it.
hdl/rtl/fmc_adc_100Ms_core.vhd
View file @
05bbebf8
...
@@ -40,6 +40,8 @@ entity fmc_adc_100Ms_core is
...
@@ -40,6 +40,8 @@ entity fmc_adc_100Ms_core is
g_TRIG_DELAY_SW
:
natural
:
=
9
;
g_TRIG_DELAY_SW
:
natural
:
=
9
;
-- FMC-ADC identification number
-- FMC-ADC identification number
g_FMC_ADC_NR
:
natural
:
=
0
;
g_FMC_ADC_NR
:
natural
:
=
0
;
-- Data endianness. If set, swap memory data byte
g_BYTE_SWAP
:
boolean
:
=
false
;
-- WB interface configuration
-- WB interface configuration
g_WB_CSR_MODE
:
t_wishbone_interface_mode
:
=
PIPELINED
;
g_WB_CSR_MODE
:
t_wishbone_interface_mode
:
=
PIPELINED
;
g_WB_CSR_GRANULARITY
:
t_wishbone_address_granularity
:
=
BYTE
);
g_WB_CSR_GRANULARITY
:
t_wishbone_address_granularity
:
=
BYTE
);
...
@@ -71,7 +73,7 @@ entity fmc_adc_100Ms_core is
...
@@ -71,7 +73,7 @@ entity fmc_adc_100Ms_core is
acq_stop_p_o
:
out
std_logic
;
acq_stop_p_o
:
out
std_logic
;
acq_end_p_o
:
out
std_logic
;
acq_end_p_o
:
out
std_logic
;
-- Trigger time-tag inputs
-- Trigger time-tag inputs
(sys_clk_i)
trigger_tag_i
:
in
t_timetag
;
trigger_tag_i
:
in
t_timetag
;
time_trig_i
:
in
std_logic
;
time_trig_i
:
in
std_logic
;
aux_time_trig_i
:
in
std_logic
;
aux_time_trig_i
:
in
std_logic
;
...
@@ -151,8 +153,7 @@ architecture rtl of fmc_adc_100Ms_core is
...
@@ -151,8 +153,7 @@ architecture rtl of fmc_adc_100Ms_core is
-- SerDes
-- SerDes
signal
serdes_out_data
:
std_logic_vector
(
63
downto
0
);
signal
serdes_out_data
:
std_logic_vector
(
63
downto
0
);
signal
serdes_out_data_synced
:
std_logic_vector
(
63
downto
0
);
signal
serdes_out_data_synced
:
std_logic_vector
(
63
downto
0
);
signal
serdes_man_bitslip
:
std_logic
;
signal
serdes_calib_sync
:
std_logic
;
signal
serdes_man_bitslip_sync
:
std_logic
;
signal
serdes_locked
:
std_logic
;
signal
serdes_locked
:
std_logic
;
signal
serdes_locked_sync
:
std_logic
;
signal
serdes_locked_sync
:
std_logic
;
signal
serdes_synced
:
std_logic
;
signal
serdes_synced
:
std_logic
;
...
@@ -293,6 +294,7 @@ architecture rtl of fmc_adc_100Ms_core is
...
@@ -293,6 +294,7 @@ architecture rtl of fmc_adc_100Ms_core is
-- Wishbone to DDR flowcontrol FIFO
-- Wishbone to DDR flowcontrol FIFO
signal
wb_ddr_fifo_din
:
std_logic_vector
(
64
downto
0
);
signal
wb_ddr_fifo_din
:
std_logic_vector
(
64
downto
0
);
signal
wb_ddr_fifo_dout
:
std_logic_vector
(
64
downto
0
);
signal
wb_ddr_fifo_dout
:
std_logic_vector
(
64
downto
0
);
signal
wb_ddr_fifo_dout2
:
std_logic_vector
(
63
downto
0
);
signal
wb_ddr_fifo_empty
:
std_logic
;
signal
wb_ddr_fifo_empty
:
std_logic
;
signal
wb_ddr_fifo_full
:
std_logic
;
signal
wb_ddr_fifo_full
:
std_logic
;
signal
wb_ddr_fifo_wr
:
std_logic
;
signal
wb_ddr_fifo_wr
:
std_logic
;
...
@@ -427,8 +429,8 @@ begin
...
@@ -427,8 +429,8 @@ begin
port
map
(
port
map
(
clk_i
=>
fs_clk
,
clk_i
=>
fs_clk
,
rst_n_a_i
=>
'1'
,
rst_n_a_i
=>
'1'
,
d_i
=>
serdes_man_bitslip
,
d_i
=>
csr_regout
.
ctl_serdes_calib
,
q_o
=>
serdes_
man_bitslip
_sync
);
q_o
=>
serdes_
calib
_sync
);
cmp_adc_serdes
:
entity
work
.
ltc2174_2l16b_receiver
cmp_adc_serdes
:
entity
work
.
ltc2174_2l16b_receiver
generic
map
(
generic
map
(
...
@@ -443,7 +445,7 @@ begin
...
@@ -443,7 +445,7 @@ begin
adc_outb_p_i
=>
adc_outb_p_i
,
adc_outb_p_i
=>
adc_outb_p_i
,
adc_outb_n_i
=>
adc_outb_n_i
,
adc_outb_n_i
=>
adc_outb_n_i
,
serdes_arst_i
=>
serdes_arst
,
serdes_arst_i
=>
serdes_arst
,
serdes_
bslip_i
=>
serdes_man_bitslip
_sync
,
serdes_
calib_i
=>
serdes_calib
_sync
,
serdes_locked_o
=>
serdes_locked
,
serdes_locked_o
=>
serdes_locked
,
serdes_synced_o
=>
serdes_synced
,
serdes_synced_o
=>
serdes_synced
,
adc_data_o
=>
serdes_out_data
,
adc_data_o
=>
serdes_out_data
,
...
@@ -484,7 +486,6 @@ begin
...
@@ -484,7 +486,6 @@ begin
fmc_adc_ch4_o
=>
wb_channel_in
(
4
));
fmc_adc_ch4_o
=>
wb_channel_in
(
4
));
csr_regin
.
ctl_fsm_cmd
<=
fsm_cmd
;
csr_regin
.
ctl_fsm_cmd
<=
fsm_cmd
;
csr_regin
.
ctl_man_bitslip
<=
serdes_man_bitslip
;
csr_regin
.
ctl_clear_trig_stat
<=
trig_storage_clear
;
csr_regin
.
ctl_clear_trig_stat
<=
trig_storage_clear
;
csr_regin
.
ctl_calib_apply
<=
sync_calib_apply
;
csr_regin
.
ctl_calib_apply
<=
sync_calib_apply
;
...
@@ -530,12 +531,10 @@ begin
...
@@ -530,12 +531,10 @@ begin
if
rising_edge
(
sys_clk_i
)
then
if
rising_edge
(
sys_clk_i
)
then
if
ctl_reg_wr
=
'1'
then
if
ctl_reg_wr
=
'1'
then
fsm_cmd
<=
csr_regout
.
ctl_fsm_cmd
;
fsm_cmd
<=
csr_regout
.
ctl_fsm_cmd
;
serdes_man_bitslip
<=
csr_regout
.
ctl_man_bitslip
;
trig_storage_clear
<=
csr_regout
.
ctl_clear_trig_stat
;
trig_storage_clear
<=
csr_regout
.
ctl_clear_trig_stat
;
sync_calib_apply
<=
csr_regout
.
ctl_calib_apply
;
sync_calib_apply
<=
csr_regout
.
ctl_calib_apply
;
else
else
fsm_cmd
<=
(
others
=>
'0'
);
fsm_cmd
<=
(
others
=>
'0'
);
serdes_man_bitslip
<=
'0'
;
trig_storage_clear
<=
'0'
;
trig_storage_clear
<=
'0'
;
sync_calib_apply
<=
'0'
;
sync_calib_apply
<=
'0'
;
end
if
;
end
if
;
...
@@ -1633,6 +1632,20 @@ begin
...
@@ -1633,6 +1632,20 @@ begin
-- Convert to 32-bit word addressing for Wishbone
-- Convert to 32-bit word addressing for Wishbone
wb_ddr_skidpad_adr_in
<=
std_logic_vector
(
ram_addr_cnt
);
wb_ddr_skidpad_adr_in
<=
std_logic_vector
(
ram_addr_cnt
);
gen_no_byte_swap
:
if
not
g_BYTE_SWAP
generate
wb_ddr_fifo_dout2
<=
wb_ddr_fifo_dout
(
63
downto
0
);
end
generate
;
gen_byte_swap
:
if
g_BYTE_SWAP
generate
wb_ddr_fifo_dout2
(
63
downto
32
)
<=
(
wb_ddr_fifo_dout
(
39
downto
32
)
&
wb_ddr_fifo_dout
(
47
downto
40
)
&
wb_ddr_fifo_dout
(
55
downto
48
)
&
wb_ddr_fifo_dout
(
63
downto
56
));
wb_ddr_fifo_dout2
(
31
downto
0
)
<=
(
wb_ddr_fifo_dout
(
7
downto
0
)
&
wb_ddr_fifo_dout
(
15
downto
8
)
&
wb_ddr_fifo_dout
(
23
downto
16
)
&
wb_ddr_fifo_dout
(
31
downto
24
));
end
generate
;
inst_skidpad
:
entity
work
.
wb_skidpad2
inst_skidpad
:
entity
work
.
wb_skidpad2
generic
map
(
generic
map
(
g_adrbits
=>
ram_addr_cnt
'length
,
g_adrbits
=>
ram_addr_cnt
'length
,
...
@@ -1644,7 +1657,7 @@ begin
...
@@ -1644,7 +1657,7 @@ begin
stb_i
=>
wb_ddr_skidpad_stb_in
,
stb_i
=>
wb_ddr_skidpad_stb_in
,
adr_i
=>
wb_ddr_skidpad_adr_in
,
adr_i
=>
wb_ddr_skidpad_adr_in
,
dat_i
=>
wb_ddr_fifo_dout
(
63
downto
0
)
,
dat_i
=>
wb_ddr_fifo_dout
2
,
sel_i
=>
(
others
=>
'1'
),
sel_i
=>
(
others
=>
'1'
),
we_i
=>
'1'
,
we_i
=>
'1'
,
stall_o
=>
wb_ddr_skidpad_stall
,
stall_o
=>
wb_ddr_skidpad_stall
,
...
...
hdl/rtl/fmc_adc_mezzanine.vhd
View file @
05bbebf8
...
@@ -41,6 +41,8 @@ entity fmc_adc_mezzanine is
...
@@ -41,6 +41,8 @@ entity fmc_adc_mezzanine is
g_TAG_ADJUST
:
natural
:
=
27
;
g_TAG_ADJUST
:
natural
:
=
27
;
-- FMC-ADC identification number
-- FMC-ADC identification number
g_FMC_ADC_NR
:
natural
:
=
0
;
g_FMC_ADC_NR
:
natural
:
=
0
;
-- Data endianness. If set, swap memory data byte
g_BYTE_SWAP
:
boolean
:
=
false
;
-- WB interface configuration
-- WB interface configuration
g_WB_MODE
:
t_wishbone_interface_mode
:
=
PIPELINED
;
g_WB_MODE
:
t_wishbone_interface_mode
:
=
PIPELINED
;
g_WB_GRANULARITY
:
t_wishbone_address_granularity
:
=
BYTE
);
g_WB_GRANULARITY
:
t_wishbone_address_granularity
:
=
BYTE
);
...
@@ -67,11 +69,11 @@ entity fmc_adc_mezzanine is
...
@@ -67,11 +69,11 @@ entity fmc_adc_mezzanine is
acq_cfg_ok_o
:
out
std_logic
;
acq_cfg_ok_o
:
out
std_logic
;
-- Auxiliary trigger input wishbone interface
-- Auxiliary trigger input wishbone interface
wb_trigin_slave_i
:
in
t_wishbone_slave_in
;
wb_trigin_slave_i
:
in
t_wishbone_slave_in
:
=
c_DUMMY_WB_SLAVE_IN
;
wb_trigin_slave_o
:
out
t_wishbone_slave_out
;
wb_trigin_slave_o
:
out
t_wishbone_slave_out
;
-- Trigout wishbone interface
-- Trigout wishbone interface
wb_trigout_slave_i
:
in
t_wishbone_slave_in
;
wb_trigout_slave_i
:
in
t_wishbone_slave_in
:
=
c_DUMMY_WB_SLAVE_IN
;
wb_trigout_slave_o
:
out
t_wishbone_slave_out
;
wb_trigout_slave_o
:
out
t_wishbone_slave_out
;
-- FMC interface
-- FMC interface
...
@@ -309,6 +311,7 @@ begin
...
@@ -309,6 +311,7 @@ begin
g_TRIG_DELAY_EXT
=>
g_TRIG_DELAY_EXT
,
g_TRIG_DELAY_EXT
=>
g_TRIG_DELAY_EXT
,
g_TRIG_DELAY_SW
=>
g_TRIG_DELAY_SW
,
g_TRIG_DELAY_SW
=>
g_TRIG_DELAY_SW
,
g_FMC_ADC_NR
=>
g_FMC_ADC_NR
,
g_FMC_ADC_NR
=>
g_FMC_ADC_NR
,
g_BYTE_SWAP
=>
g_BYTE_SWAP
,
g_WB_CSR_MODE
=>
PIPELINED
,
g_WB_CSR_MODE
=>
PIPELINED
,
g_WB_CSR_GRANULARITY
=>
BYTE
)
g_WB_CSR_GRANULARITY
=>
BYTE
)
port
map
(
port
map
(
...
...
hdl/testbench/include/fmc_adc_100Ms_csr.v
View file @
05bbebf8
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
`define
FMC_ADC_100MS_CSR_CTL_FMC_CLK_OE
'
h4
`define
FMC_ADC_100MS_CSR_CTL_FMC_CLK_OE
'
h4
`define
FMC_ADC_100MS_CSR_CTL_OFFSET_DAC_CLR_N_OFFSET 3
`define
FMC_ADC_100MS_CSR_CTL_OFFSET_DAC_CLR_N_OFFSET 3
`define
FMC_ADC_100MS_CSR_CTL_OFFSET_DAC_CLR_N
'
h8
`define
FMC_ADC_100MS_CSR_CTL_OFFSET_DAC_CLR_N
'
h8
`define
FMC_ADC_100MS_CSR_CTL_
MAN_BITSLIP
_OFFSET 4
`define
FMC_ADC_100MS_CSR_CTL_
SERDES_CALIB
_OFFSET 4
`define
FMC_ADC_100MS_CSR_CTL_
MAN_BITSLIP
'
h10
`define
FMC_ADC_100MS_CSR_CTL_
SERDES_CALIB
'
h10
`define
FMC_ADC_100MS_CSR_CTL_TRIG_LED_OFFSET 6
`define
FMC_ADC_100MS_CSR_CTL_TRIG_LED_OFFSET 6
`define
FMC_ADC_100MS_CSR_CTL_TRIG_LED
'
h40
`define
FMC_ADC_100MS_CSR_CTL_TRIG_LED
'
h40
`define
FMC_ADC_100MS_CSR_CTL_ACQ_LED_OFFSET 7
`define
FMC_ADC_100MS_CSR_CTL_ACQ_LED_OFFSET 7
...
...
hdl/top/svec_ref_design/svec_ref_fmc_adc_100Ms.vhd
View file @
05bbebf8
...
@@ -531,10 +531,11 @@ begin -- architecture arch
...
@@ -531,10 +531,11 @@ begin -- architecture arch
d_i
=>
fmc_irq
(
I
),
d_i
=>
fmc_irq
(
I
),
q_o
=>
irq_vector
(
I
));
q_o
=>
irq_vector
(
I
));
cmp_fmc_adc_mezzanine
:
fmc_adc_mezzanine
cmp_fmc_adc_mezzanine
:
entity
work
.
fmc_adc_mezzanine
generic
map
(
generic
map
(
g_MULTISHOT_RAM_SIZE
=>
g_MULTISHOT_RAM_SIZE
,
g_MULTISHOT_RAM_SIZE
=>
g_MULTISHOT_RAM_SIZE
,
g_SPARTAN6_USE_PLL
=>
TRUE
,
g_SPARTAN6_USE_PLL
=>
TRUE
,
g_BYTE_SWAP
=>
TRUE
,
g_FMC_ADC_NR
=>
I
,
g_FMC_ADC_NR
=>
I
,
g_WB_MODE
=>
PIPELINED
,
g_WB_MODE
=>
PIPELINED
,
g_WB_GRANULARITY
=>
BYTE
)
g_WB_GRANULARITY
=>
BYTE
)
...
...
software/kernel/Kbuild
View file @
05bbebf8
...
@@ -8,12 +8,16 @@ VMEBUS_EXTRA_SYMBOLS-$(CONFIG_FMC_ADC_SVEC) := $(VMEBUS_ABS)/driver/Module.symve
...
@@ -8,12 +8,16 @@ VMEBUS_EXTRA_SYMBOLS-$(CONFIG_FMC_ADC_SVEC) := $(VMEBUS_ABS)/driver/Module.symve
ZIO_VERSION = $(shell cd $(ZIO_ABS); git describe --always --dirty --long --tags)
ZIO_VERSION = $(shell cd $(ZIO_ABS); git describe --always --dirty --long --tags)
VERSION = $(shell cd $(src); git describe --always --dirty --long --tags)
VERSION = $(shell cd $(src); git describe --always --dirty --long --tags)
VER_MAJ := $(shell echo $(subst v,,$(VERSION)) | cut -d '.' -f 1)
VER_MIN := $(shell echo $(subst v,,$(VERSION)) | cut -d '.' -f 2)
FA_VERSION_BLD := $(shell printf "0x%02x%02x0000" $(VER_MAJ) $(VER_MIN))
KBUILD_EXTRA_SYMBOLS += $(ZIO_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(ZIO_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(FMC_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(FMC_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(VMEBUS_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(VMEBUS_EXTRA_SYMBOLS-y)
ccflags-y = -DVERSION=\"$(VERSION)\"
ccflags-y = -DVERSION=\"$(VERSION)\"
ccflags-y += -DFA_VERSION_BLD=$(FA_VERSION_BLD)
ccflags-y += -DCONFIG_FMC_ADC_SVEC
ccflags-y += -DCONFIG_FMC_ADC_SVEC
ccflags-y += -I$(src)
ccflags-y += -I$(src)
ccflags-y += -I$(ZIO_ABS)/include
ccflags-y += -I$(ZIO_ABS)/include
...
...
software/kernel/fa-calibration.c
View file @
05bbebf8
// SPDX-FileCopyrightText: 2020 CERN (home.cern)
//
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 CERN (home.cern)
/*
/*
* EEPROM calibration block retreival code for fa-dev
* EEPROM calibration block retreival code for fa-dev
...
@@ -16,10 +15,10 @@
...
@@ -16,10 +15,10 @@
#include <linux/jiffies.h>
#include <linux/jiffies.h>
#include "fmc-adc-100m14b4cha-private.h"
#include "fmc-adc-100m14b4cha-private.h"
static
int
fa_calib_temp_period
=
0
;
static
int
fa_calib_temp_period
;
module_param_named
(
temp_calib_period
,
fa_calib_temp_period
,
int
,
0444
);
module_param_named
(
temp_calib_period
,
fa_calib_temp_period
,
int
,
0444
);
static
int
fa_calib_temp
=
0
;
static
int
fa_calib_temp
;
module_param_named
(
temp_calib
,
fa_calib_temp
,
int
,
0444
);
module_param_named
(
temp_calib
,
fa_calib_temp
,
int
,
0444
);
/* This identity calibration is used as default */
/* This identity calibration is used as default */
...
@@ -48,7 +47,7 @@ static int fa_calib_apply(struct fa_dev *fa)
...
@@ -48,7 +47,7 @@ static int fa_calib_apply(struct fa_dev *fa)
return
-
EBUSY
;
return
-
EBUSY
;
}
}
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_CTL_CALIB_APPLY
],
1
);
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_CTL_CALIB_APPLY
],
1
);
ndelay
(
100
);
ndelay
(
100
);
if
(
fa_calib_is_busy
(
fa
))
{
if
(
fa_calib_is_busy
(
fa
))
{
dev_err
(
&
fa
->
pdev
->
dev
,
dev_err
(
&
fa
->
pdev
->
dev
,
"%s Calibration value applied but still 'busy'
\n
"
,
"%s Calibration value applied but still 'busy'
\n
"
,
...
@@ -134,7 +133,7 @@ static const int64_t gain_dac_error_slope_fix[] = {
...
@@ -134,7 +133,7 @@ static const int64_t gain_dac_error_slope_fix[] = {
static
int
fa_calib_dac_gain_fix
(
int
range
,
uint32_t
gain_c
,
static
int
fa_calib_dac_gain_fix
(
int
range
,
uint32_t
gain_c
,
int32_t
delta_temp
)
int32_t
delta_temp
)
{
{
int64_t
error
;
int64_t
error
;
error
=
gain_dac_error_slope_fix
[
range
]
*
delta_temp
;
error
=
gain_dac_error_slope_fix
[
range
]
*
delta_temp
;
error
/=
0x2000
;
/* see comment above for gain_dac_error_slope_fix */
error
/=
0x2000
;
/* see comment above for gain_dac_error_slope_fix */
...
@@ -148,7 +147,7 @@ static bool fa_calib_is_compensation_on(struct fa_dev *fa)
...
@@ -148,7 +147,7 @@ static bool fa_calib_is_compensation_on(struct fa_dev *fa)
if
(
unlikely
((
fa
->
flags
&
FA_DEV_F_PATTERN_DATA
)))
if
(
unlikely
((
fa
->
flags
&
FA_DEV_F_PATTERN_DATA
)))
return
false
;
return
false
;
if
(
unlikely
(
fa_calib_temp
))
if
(
unlikely
(
fa_calib_temp
))
return
true
;
return
true
;
return
false
;
return
false
;
...
@@ -208,47 +207,52 @@ static int fa_dac_offset_set(struct fa_dev *fa, unsigned int chan,
...
@@ -208,47 +207,52 @@ static int fa_dac_offset_set(struct fa_dev *fa, unsigned int chan,
return
fa_spi_xfer
(
fa
,
FA_SPI_SS_DAC
(
chan
),
16
,
val
,
NULL
);
return
fa_spi_xfer
(
fa
,
FA_SPI_SS_DAC
(
chan
),
16
,
val
,
NULL
);
}
}
static
int64_t
fa_dac_offset_raw_get
(
int32_t
offset
)
static
uint16_t
fa_dac_offset_raw_calibrate
(
struct
fa_dev
*
fa
,
uint16_t
raw_offset
,
int
gain
,
int
offset
)
{
{
int32_t
signed_offset
=
raw_offset
-
0x8000
;
int64_t
hwval
;
int64_t
hwval
;
hwval
=
offset
*
0x8000LL
/
5000000
;
hwval
=
((
signed_offset
+
offset
)
*
gain
)
>>
15
;
/* signed */
if
(
hwval
==
0x8000
)
hwval
+=
0x8000
;
/* offset binary */
hwval
=
0x7fff
;
/* -32768 .. 32767 */
dev_dbg
(
&
fa
->
pdev
->
dev
,
return
hwval
;
"Final DAC calibrated value: (0x%08x + 0x%08x) * 0x%08x = 0x%08llx
\n
"
,
}
signed_offset
,
offset
,
gain
,
hwval
);
static
int64_t
fa_dac_offset_raw_calibrate
(
int32_t
raw_offset
,
int
gain
,
int
offset
)
{
int64_t
hwval
;
hwval
=
((
raw_offset
+
offset
)
*
gain
)
>>
15
;
/* signed */
/* Saturate */
hwval
+=
0x8000
;
/* offset binary */
if
(
hwval
<
0
)
{
if
(
hwval
<
0
)
hwval
=
0
;
hwval
=
0
;
if
(
hwval
>
0xffff
)
dev_warn
(
&
fa
->
pdev
->
dev
,
"Final DAC calibrated value: lower saturation, set 0x%04llx"
,
hwval
);
}
if
(
hwval
>
0xffff
)
{
hwval
=
0xffff
;
hwval
=
0xffff
;
dev_warn
(
&
fa
->
pdev
->
dev
,
"Final DAC calibrated value: lower saturation, set 0x%04llx"
,
hwval
);
}
return
hwval
;
return
hwval
;
}
}
static
int
fa_dac_offset_get
(
struct
fa_dev
*
fa
,
unsigned
int
chan
)
static
int
fa_dac_offset_get
(
struct
fa_dev
*
fa
,
unsigned
int
chan
,
uint16_t
*
offset
)
{
{
int32_t
off_uv
=
fa
->
user_offset
[
chan
]
+
fa
->
zero_offset
[
chan
];
int32_t
user
=
fa
->
user_offset
[
chan
];
int32_t
zero
=
fa
->
zero_offset
[
chan
];
int32_t
__offset
=
(
user
+
zero
)
-
0x8000
;
/* Bring back to DAC format */
if
(
WARN
(
off_uv
<
DAC_SAT_LOW
,
if
(
__offset
&
~
DAC_VAL_MASK
)
{
"DAC lower saturation %d < %d
\n
"
,
dev_err
(
&
fa
->
pdev
->
dev
,
off_uv
,
DAC_SAT_LOW
))
{
"DAC offset value overflows 16bits. {user: 0x%04x, zero: 0x%04x, sum: 0x%08x}
\n
"
,
off_uv
=
DAC_SAT_LOW
;
user
,
zero
,
__offset
);
}
return
-
EINVAL
;
if
(
WARN
(
off_uv
>
DAC_SAT_UP
,
"DAC upper saturation %d > %d
\n
"
,
off_uv
,
DAC_SAT_UP
))
{
off_uv
=
DAC_SAT_UP
;
}
}
return
off_uv
;
*
offset
=
__offset
;
return
0
;
}
}
/**
/**
...
@@ -262,12 +266,16 @@ static int fa_dac_offset_get(struct fa_dev *fa, unsigned int chan)
...
@@ -262,12 +266,16 @@ static int fa_dac_offset_get(struct fa_dev *fa, unsigned int chan)
int
fa_calib_dac_config_chan
(
struct
fa_dev
*
fa
,
unsigned
int
chan
,
int
fa_calib_dac_config_chan
(
struct
fa_dev
*
fa
,
unsigned
int
chan
,
int32_t
temperature
,
unsigned
int
flags
)
int32_t
temperature
,
unsigned
int
flags
)
{
{
int32_t
off_uv
=
fa_dac_offset_get
(
fa
,
chan
);
uint16_t
value
;
int32_t
off_uv_raw
=
fa_dac_offset_raw_get
(
off_uv
);
int
range
=
fa
->
range
[
chan
];
int
range
=
fa
->
range
[
chan
];
struct
fa_calib_stanza
*
cal
=
&
fa
->
calib
.
dac
[
range
];
struct
fa_calib_stanza
*
cal
=
&
fa
->
calib
.
dac
[
range
];
int
gain
;
int
gain
;
int
hwval
;
int
hwval
;
int
err
;
err
=
fa_dac_offset_get
(
fa
,
chan
,
&
value
);
if
(
err
)
return
err
;
if
(
fa_calib_is_compensation_on
(
fa
))
{
if
(
fa_calib_is_compensation_on
(
fa
))
{
int32_t
delta_temp
;
int32_t
delta_temp
;
...
@@ -287,10 +295,10 @@ int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan,
...
@@ -287,10 +295,10 @@ int fa_calib_dac_config_chan(struct fa_dev *fa, unsigned int chan,
__func__
,
chan
,
range
,
gain
,
cal
->
offset
[
chan
]);
__func__
,
chan
,
range
,
gain
,
cal
->
offset
[
chan
]);
}
}
hwval
=
fa_dac_offset_raw_calibrate
(
off_uv_raw
,
gain
,
hwval
=
fa_dac_offset_raw_calibrate
(
fa
,
value
,
gain
,
cal
->
offset
[
chan
]);
cal
->
offset
[
chan
]);
return
fa_dac_offset_set
(
fa
,
chan
,
hwval
);
return
fa_dac_offset_set
(
fa
,
chan
,
hwval
);
}
}
void
fa_calib_config_chan
(
struct
fa_dev
*
fa
,
unsigned
int
chan
,
void
fa_calib_config_chan
(
struct
fa_dev
*
fa
,
unsigned
int
chan
,
...
@@ -311,6 +319,14 @@ void fa_calib_config(struct fa_dev *fa)
...
@@ -311,6 +319,14 @@ void fa_calib_config(struct fa_dev *fa)
fa_calib_config_chan
(
fa
,
i
,
temperature
,
0
);
fa_calib_config_chan
(
fa
,
i
,
temperature
,
0
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
}
}
static
void
__fa_calib_gain_update
(
struct
fa_dev
*
fa
)
{
fa_calib_config
(
fa
);
mod_timer
(
&
fa
->
calib_timer
,
jiffies
+
HZ
*
fa_calib_temp_period
);
}
/**
/**
* Periodically update gain calibration values
* Periodically update gain calibration values
* @fa: FMC ADC device
* @fa: FMC ADC device
...
@@ -320,14 +336,17 @@ void fa_calib_config(struct fa_dev *fa)
...
@@ -320,14 +336,17 @@ void fa_calib_config(struct fa_dev *fa)
* linear behavior with respect to the temperature.
* linear behavior with respect to the temperature.
*
*
*/
*/
#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
static
void
fa_calib_gain_update
(
struct
timer_list
*
timer
)
{
__fa_calib_gain_update
(
from_timer
(
fa
,
timer
,
calib_timer
));
}
#else
static
void
fa_calib_gain_update
(
unsigned
long
arg
)
static
void
fa_calib_gain_update
(
unsigned
long
arg
)
{
{
struct
fa_dev
*
fa
=
(
void
*
)
arg
;
__fa_calib_gain_update
((
void
*
)
arg
);
fa_calib_config
(
fa
);
mod_timer
(
&
fa
->
calib_timer
,
jiffies
+
HZ
*
fa_calib_temp_period
);
}
}
#endif
/* Actual verification code */
/* Actual verification code */
static
int
fa_verify_calib_stanza
(
struct
device
*
msgdev
,
char
*
name
,
int
r
,
static
int
fa_verify_calib_stanza
(
struct
device
*
msgdev
,
char
*
name
,
int
r
,
struct
fa_calib_stanza
*
cal
)
struct
fa_calib_stanza
*
cal
)
...
@@ -493,14 +512,19 @@ int fa_calib_init(struct fa_dev *fa)
...
@@ -493,14 +512,19 @@ int fa_calib_init(struct fa_dev *fa)
fa_calib_write
(
fa
,
&
calib
);
fa_calib_write
(
fa
,
&
calib
);
/* First calibration.
/* First calibration.
The board has just been reset by the carrier before calling this
* The board has just been reset by the carrier before calling this
driver and reading the temperature read needs at least 350ms */
* driver and reading the temperature read needs at least 350ms
*/
msleep
(
400
);
msleep
(
400
);
fa_calib_config
(
fa
);
fa_calib_config
(
fa
);
/* Prepare the timely recalibration */
/* Prepare the timely recalibration */
if
(
fa_calib_is_compensation_on
(
fa
)
&&
fa_calib_temp_period
)
{
if
(
fa_calib_is_compensation_on
(
fa
)
&&
fa_calib_temp_period
)
{
#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
timer_setup
(
&
fa
->
calib_timer
,
fa_calib_gain_update
,
0
);
#else
setup_timer
(
&
fa
->
calib_timer
,
fa_calib_gain_update
,
(
unsigned
long
)
fa
);
setup_timer
(
&
fa
->
calib_timer
,
fa_calib_gain_update
,
(
unsigned
long
)
fa
);
#endif
mod_timer
(
&
fa
->
calib_timer
,
mod_timer
(
&
fa
->
calib_timer
,
jiffies
+
HZ
*
fa_calib_temp_period
);
jiffies
+
HZ
*
fa_calib_temp_period
);
}
}
...
...
software/kernel/fa-core.c
View file @
05bbebf8
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <linux/mod_devicetable.h>
#include <linux/mod_devicetable.h>
#include <uapi/linux/ipmi/fru.h>
#include <uapi/linux/ipmi/fru.h>
#include <linux/fmc.h>
#include <linux/fmc.h>
#include <linux/io.h>
#include "fmc-adc-100m14b4cha-private.h"
#include "fmc-adc-100m14b4cha-private.h"
#include <platform_data/fmc-adc-100m14b4cha.h>
#include <platform_data/fmc-adc-100m14b4cha.h>
...
@@ -19,6 +20,12 @@
...
@@ -19,6 +20,12 @@
static
int
fa_enable_test_data_fpga
;
static
int
fa_enable_test_data_fpga
;
module_param_named
(
enable_test_data_fpga
,
fa_enable_test_data_fpga
,
int
,
0444
);
module_param_named
(
enable_test_data_fpga
,
fa_enable_test_data_fpga
,
int
,
0444
);
static
int
version_ignore
;
module_param
(
version_ignore
,
int
,
0644
);
MODULE_PARM_DESC
(
version_ignore
,
"Ignore the version declared in the FPGA and force the driver to load all components (default 0)"
);
#define FA_EEPROM_TYPE "at24c64"
#define FA_EEPROM_TYPE "at24c64"
...
@@ -36,6 +43,29 @@ static const int zfad_hw_range[] = {
...
@@ -36,6 +43,29 @@ static const int zfad_hw_range[] = {
struct
workqueue_struct
*
fa_workqueue
;
struct
workqueue_struct
*
fa_workqueue
;
static
int
fa_sg_alloc_table_from_pages
(
struct
sg_table
*
sgt
,
struct
page
**
pages
,
unsigned
int
n_pages
,
unsigned
int
offset
,
unsigned
long
size
,
unsigned
int
max_segment
,
gfp_t
gfp_mask
)
{
#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
struct
scatterlist
*
sg
;
sg
=
__sg_alloc_table_from_pages
(
sgt
,
pages
,
n_pages
,
offset
,
size
,
max_segment
,
NULL
,
0
,
gfp_mask
);
if
(
IS_ERR
(
sg
))
return
PTR_ERR
(
sg
);
else
return
0
;
#else
return
__sg_alloc_table_from_pages
(
sgt
,
pages
,
n_pages
,
offset
,
size
,
max_segment
,
gfp_mask
);
#endif
}
/**
/**
* Enable/Disable Data Output Randomizer
* Enable/Disable Data Output Randomizer
* @fa: the adc descriptor
* @fa: the adc descriptor
...
@@ -46,17 +76,20 @@ int fa_adc_output_randomizer_set(struct fa_dev *fa, bool enable)
...
@@ -46,17 +76,20 @@ int fa_adc_output_randomizer_set(struct fa_dev *fa, bool enable)
uint32_t
tx
,
rx
;
uint32_t
tx
,
rx
;
int
err
;
int
err
;
tx
=
0x8000
;
/* Read register A1 */
tx
=
0x8000
;
tx
|=
(
1
<<
8
);
tx
|=
(
1
<<
8
);
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
/* Set or clear RAND bit */
if
(
enable
)
if
(
enable
)
rx
|=
BIT
(
6
);
rx
|=
BIT
(
6
);
else
else
rx
&=
~
BIT
(
6
);
rx
&=
~
BIT
(
6
);
/* Write back A1 */
tx
=
0x0000
;
tx
=
0x0000
;
tx
|=
(
1
<<
8
);
tx
|=
(
1
<<
8
);
tx
|=
(
rx
&
0xFF
);
tx
|=
(
rx
&
0xFF
);
...
@@ -76,7 +109,8 @@ bool fa_adc_is_output_randomizer(struct fa_dev *fa)
...
@@ -76,7 +109,8 @@ bool fa_adc_is_output_randomizer(struct fa_dev *fa)
uint32_t
tx
,
rx
;
uint32_t
tx
,
rx
;
int
err
;
int
err
;
tx
=
0x8000
;
/* Read register A1 */
tx
=
0x8000
;
tx
|=
(
1
<<
8
);
tx
|=
(
1
<<
8
);
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
if
(
err
)
if
(
err
)
...
@@ -127,13 +161,13 @@ int fa_trigger_software(struct fa_dev *fa)
...
@@ -127,13 +161,13 @@ int fa_trigger_software(struct fa_dev *fa)
return
-
EPERM
;
return
-
EPERM
;
}
}
/* Fire if nsamples!=0 */
/* Fire if nsamples!=0 */
if
(
!
ti
->
nsamples
)
{
if
(
!
ti
->
nsamples
)
{
dev_info
(
&
fa
->
pdev
->
dev
,
"pre + post = 0: cannot acquire
\n
"
);
dev_info
(
&
fa
->
pdev
->
dev
,
"pre + post = 0: cannot acquire
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/*
/*
* We can do a software trigger if the FSM is not in
* We can do a software trigger if the FSM is not in
* the WAIT trigger status. Wait for it.
* the WAIT trigger status. Wait for it.
* Remember that: timeout is in us, a sample takes 10ns
* Remember that: timeout is in us, a sample takes 10ns
...
@@ -347,7 +381,7 @@ err:
...
@@ -347,7 +381,7 @@ err:
* @enable 0 to disable, 1 to enable
* @enable 0 to disable, 1 to enable
*/
*/
int
fa_adc_data_pattern_get
(
struct
fa_dev
*
fa
,
uint16_t
*
pattern
,
int
fa_adc_data_pattern_get
(
struct
fa_dev
*
fa
,
uint16_t
*
pattern
,
unsigned
int
*
enable
)
unsigned
int
*
enable
)
{
{
uint32_t
tx
,
rx
;
uint32_t
tx
,
rx
;
int
err
;
int
err
;
...
@@ -443,8 +477,7 @@ int zfad_fsm_command(struct fa_dev *fa, uint32_t command)
...
@@ -443,8 +477,7 @@ int zfad_fsm_command(struct fa_dev *fa, uint32_t command)
if
(
command
==
FA100M14B4C_CMD_START
)
{
if
(
command
==
FA100M14B4C_CMD_START
)
{
if
(
!
fa_adc_is_serdes_ready
(
fa
))
{
if
(
!
fa_adc_is_serdes_ready
(
fa
))
{
dev_err
(
fa
->
msgdev
,
dev_err
(
fa
->
msgdev
,
"Cannot start acquisition: "
"Cannot start acquisition: SerDes PLL not locked or synchronized (0x%08x)
\n
"
,
"SerDes PLL not locked or synchronized (0x%08x)
\n
"
,
fa_ioread
(
fa
,
fa
->
fa_adc_csr_base
+
ADC_CSR_STA_REG_OFFSET
));
fa_ioread
(
fa
,
fa
->
fa_adc_csr_base
+
ADC_CSR_STA_REG_OFFSET
));
return
-
EBUSY
;
return
-
EBUSY
;
}
}
...
@@ -459,8 +492,8 @@ int zfad_fsm_command(struct fa_dev *fa, uint32_t command)
...
@@ -459,8 +492,8 @@ int zfad_fsm_command(struct fa_dev *fa, uint32_t command)
* from zfat_arm_trigger() or zfad_input_cset()
* from zfat_arm_trigger() or zfad_input_cset()
*/
*/
if
(
!
(
cset
->
ti
->
flags
&
ZIO_TI_ARMED
))
{
if
(
!
(
cset
->
ti
->
flags
&
ZIO_TI_ARMED
))
{
dev_info
(
fa
->
msgdev
,
"Cannot start acquisition: "
dev_info
(
fa
->
msgdev
,
"
Trigger refuses to arm
\n
"
);
"Cannot start acquisition:
Trigger refuses to arm
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -484,7 +517,11 @@ static void fa_init_timetag(struct fa_dev *fa)
...
@@ -484,7 +517,11 @@ static void fa_init_timetag(struct fa_dev *fa)
{
{
unsigned
long
seconds
;
unsigned
long
seconds
;
#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE
seconds
=
ktime_get_real_seconds
();
#else
seconds
=
get_seconds
();
seconds
=
get_seconds
();
#endif
fa_writel
(
fa
,
fa
->
fa_utc_base
,
&
zfad_regs
[
ZFA_UTC_SECONDS_U
],
fa_writel
(
fa
,
fa
->
fa_utc_base
,
&
zfad_regs
[
ZFA_UTC_SECONDS_U
],
(
seconds
>>
32
)
&
0xFFFFFFFF
);
(
seconds
>>
32
)
&
0xFFFFFFFF
);
fa_writel
(
fa
,
fa
->
fa_utc_base
,
&
zfad_regs
[
ZFA_UTC_SECONDS_L
],
fa_writel
(
fa
,
fa
->
fa_utc_base
,
&
zfad_regs
[
ZFA_UTC_SECONDS_L
],
...
@@ -517,12 +554,8 @@ static int __fa_init(struct fa_dev *fa)
...
@@ -517,12 +554,8 @@ static int __fa_init(struct fa_dev *fa)
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_CTL_FMS_CMD
],
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_CTL_FMS_CMD
],
FA100M14B4C_CMD_STOP
);
FA100M14B4C_CMD_STOP
);
/* Initialize channels to use 1V range */
/* Initialize channels to use 1V range */
for
(
i
=
0
;
i
<
4
;
++
i
)
{
for
(
i
=
0
;
i
<
FA100M14B4C_NCHAN
;
++
i
)
fa_adc_range_set
(
fa
,
&
zdev
->
cset
->
chan
[
i
],
FA100M14B4C_RANGE_1V
);
fa_adc_range_set
(
fa
,
&
zdev
->
cset
->
chan
[
i
],
FA100M14B4C_RANGE_1V
);
/* reset channel offset */
fa
->
user_offset
[
i
]
=
0
;
fa
->
zero_offset
[
i
]
=
0
;
}
/* Set decimation to minimum */
/* Set decimation to minimum */
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_SR_UNDER
],
1
);
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_SR_UNDER
],
1
);
...
@@ -554,12 +587,11 @@ static int __fa_init(struct fa_dev *fa)
...
@@ -554,12 +587,11 @@ static int __fa_init(struct fa_dev *fa)
/* This structure lists the various subsystems */
/* This structure lists the various subsystems */
struct
fa_modlist
{
struct
fa_modlist
{
char
*
name
;
char
*
name
;
int
(
*
init
)(
struct
fa_dev
*
);
int
(
*
init
)(
struct
fa_dev
*
fa
);
void
(
*
exit
)(
struct
fa_dev
*
);
void
(
*
exit
)(
struct
fa_dev
*
fa
);
};
};
static
struct
fa_modlist
mods
[]
=
{
static
struct
fa_modlist
mods
[]
=
{
{
"spi"
,
fa_spi_init
,
fa_spi_exit
},
{
"zio"
,
fa_zio_init
,
fa_zio_exit
},
{
"zio"
,
fa_zio_init
,
fa_zio_exit
},
{
"debug"
,
fa_debug_init
,
fa_debug_exit
},
{
"debug"
,
fa_debug_init
,
fa_debug_exit
},
{
"calibration"
,
fa_calib_init
,
fa_calib_exit
},
{
"calibration"
,
fa_calib_init
,
fa_calib_exit
},
...
@@ -645,19 +677,85 @@ static void fa_sg_alloc_table_init(struct fa_dev *fa)
...
@@ -645,19 +677,85 @@ static void fa_sg_alloc_table_init(struct fa_dev *fa)
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_NOSQUASH_SCATTERLIST
))
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_NOSQUASH_SCATTERLIST
))
fa
->
sg_alloc_table_from_pages
=
sg_alloc_table_from_pages_no_squash
;
fa
->
sg_alloc_table_from_pages
=
sg_alloc_table_from_pages_no_squash
;
else
else
fa
->
sg_alloc_table_from_pages
=
_
_sg_alloc_table_from_pages
;
fa
->
sg_alloc_table_from_pages
=
fa
_sg_alloc_table_from_pages
;
}
}
static
struct
fmc_adc_platform_data
fmc_adc_pdata_default
=
{
static
struct
fmc_adc_platform_data
fmc_adc_pdata_default
=
{
.
flags
=
0
,
.
flags
=
0
,
.
vme_reg_offset
=
0
,
.
vme_reg_offset
=
0
,
.
vme_dma_offset
=
0
,
.
vme_dma_offset
=
0
,
.
calib_trig_time
=
0
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
.
calib_trig_internal
=
0
,
};
};
static
int
fa_metadata_get
(
struct
fa_dev
*
fa
)
{
struct
resource
*
r
;
void
*
mem
;
int
i
;
r
=
platform_get_resource
(
fa
->
pdev
,
IORESOURCE_MEM
,
ADC_MEM_META
);
if
(
r
==
NULL
)
{
dev_err
(
&
fa
->
pdev
->
dev
,
"Can't inspect ADC device metadata: missing resource
\n
"
);
return
-
ENODEV
;
}
mem
=
ioremap
(
r
->
start
,
resource_size
(
r
));
if
(
!
mem
)
{
dev_err
(
&
fa
->
pdev
->
dev
,
"Can't inspect ADC device metadata: failed to map
\n
"
);
return
-
ENODEV
;
}
/* Dump meta*/
for
(
i
=
0
;
i
<
sizeof
(
fa
->
meta
)
/
4
;
++
i
)
((
uint32_t
*
)
&
fa
->
meta
)[
i
]
=
fa_ioread
(
fa
,
mem
+
(
i
*
4
));
iounmap
(
mem
);
return
0
;
}
static
bool
fa_is_fpga_version_valid
(
uint32_t
expected
,
uint32_t
found
)
{
if
(
version_ignore
)
return
true
;
if
(
FA_VERSION_MAJ
(
found
)
!=
FA_VERSION_MAJ
(
expected
))
return
false
;
if
(
FA_VERSION_MIN
(
found
)
<
FA_VERSION_MIN
(
expected
))
return
false
;
return
true
;
}
static
bool
fa_is_fpga_valid
(
struct
fa_dev
*
fa
)
{
if
(
fa
->
meta
.
vendor
!=
FA_META_VENDOR_ID
)
{
dev_err
(
&
fa
->
pdev
->
dev
,
"Unknow vendor ID: %08x
\n
"
,
fa
->
meta
.
vendor
);
return
false
;
}
switch
(
fa
->
meta
.
device
)
{
case
FA_META_DEVICE_ID_SVEC_DBL_ADC
:
break
;
case
FA_META_DEVICE_ID_SPEC
:
break
;
default:
dev_err
(
&
fa
->
pdev
->
dev
,
"Unknow device ID: %08x
\n
"
,
fa
->
meta
.
device
);
return
false
;
}
if
(
!
fa_is_fpga_version_valid
(
FA_VERSION_DRV
,
fa
->
meta
.
version
))
{
dev_err
(
&
fa
->
pdev
->
dev
,
"Invalid version: %08x, expected: %08x
\n
"
,
fa
->
meta
.
version
,
FA_VERSION_DRV
);
return
false
;
}
return
true
;
}
/* probe and remove are called by fa-spec.c */
/* probe and remove are called by fa-spec.c */
int
fa_probe
(
struct
platform_device
*
pdev
)
int
fa_probe
(
struct
platform_device
*
pdev
)
{
{
...
@@ -720,7 +818,7 @@ int fa_probe(struct platform_device *pdev)
...
@@ -720,7 +818,7 @@ int fa_probe(struct platform_device *pdev)
}
}
}
}
if
(
!
fa_fmc_slot_is_valid
(
fa
))
if
(
!
fa_fmc_slot_is_valid
(
fa
))
goto
out_fmc_err
;
goto
out_fmc_err
;
err
=
sysfs_create_link
(
&
fa
->
pdev
->
dev
.
kobj
,
&
fa
->
slot
->
dev
.
kobj
,
err
=
sysfs_create_link
(
&
fa
->
pdev
->
dev
.
kobj
,
&
fa
->
slot
->
dev
.
kobj
,
...
@@ -731,18 +829,34 @@ int fa_probe(struct platform_device *pdev)
...
@@ -731,18 +829,34 @@ int fa_probe(struct platform_device *pdev)
goto
err_fmc_link
;
goto
err_fmc_link
;
}
}
err
=
fa_metadata_get
(
fa
);
if
(
err
)
goto
out_meta
;
if
(
!
fa_is_fpga_valid
(
fa
))
goto
out_valid
;
err
=
fa_dma_request_channel
(
fa
);
err
=
fa_dma_request_channel
(
fa
);
if
(
err
)
if
(
err
)
goto
out_dma
;
goto
out_dma
;
fa_clock_enable
(
fa
);
fa_clock_enable
(
fa
);
err
=
fa_spi_init
(
fa
);
if
(
err
)
goto
out_spi
;
err
=
fa_adc_wait_serdes_ready
(
fa
,
msecs_to_jiffies
(
10
));
err
=
fa_adc_wait_serdes_ready
(
fa
,
msecs_to_jiffies
(
10
));
if
(
err
)
{
if
(
err
)
{
dev_err
(
&
fa
->
pdev
->
dev
,
"The SERDES did not syncronize
\n
"
);
dev_err
(
&
fa
->
pdev
->
dev
,
"The SERDES did not syncronize
\n
"
);
goto
out_serdes
;
goto
out_serdes
;
}
}
/* reset channel offset before calibration */
for
(
i
=
0
;
i
<
FA100M14B4C_NCHAN
;
++
i
)
{
fa
->
user_offset
[
i
]
=
0x8000
;
fa
->
zero_offset
[
i
]
=
0x8000
;
}
/* init all subsystems */
/* init all subsystems */
for
(
i
=
0
,
m
=
mods
;
i
<
ARRAY_SIZE
(
mods
);
i
++
,
m
++
)
{
for
(
i
=
0
,
m
=
mods
;
i
<
ARRAY_SIZE
(
mods
);
i
++
,
m
++
)
{
dev_dbg
(
fa
->
msgdev
,
"Calling init for
\"
%s
\"\n
"
,
m
->
name
);
dev_dbg
(
fa
->
msgdev
,
"Calling init for
\"
%s
\"\n
"
,
m
->
name
);
...
@@ -771,9 +885,13 @@ out:
...
@@ -771,9 +885,13 @@ out:
m
->
exit
(
fa
);
m
->
exit
(
fa
);
iounmap
(
fa
->
fa_top_level
);
iounmap
(
fa
->
fa_top_level
);
out_serdes:
out_serdes:
fa_spi_exit
(
fa
);
out_spi:
fa_clock_disable
(
fa
);
fa_clock_disable
(
fa
);
fa_dma_release_channel
(
fa
);
fa_dma_release_channel
(
fa
);
out_dma:
out_dma:
out_valid:
out_meta:
sysfs_remove_link
(
&
fa
->
pdev
->
dev
.
kobj
,
dev_name
(
&
fa
->
slot
->
dev
));
sysfs_remove_link
(
&
fa
->
pdev
->
dev
.
kobj
,
dev_name
(
&
fa
->
slot
->
dev
));
err_fmc_link:
err_fmc_link:
out_fmc_err:
out_fmc_err:
...
@@ -799,9 +917,12 @@ int fa_remove(struct platform_device *pdev)
...
@@ -799,9 +917,12 @@ int fa_remove(struct platform_device *pdev)
while
(
--
i
>=
0
)
{
while
(
--
i
>=
0
)
{
struct
fa_modlist
*
m
=
mods
+
i
;
struct
fa_modlist
*
m
=
mods
+
i
;
if
(
m
->
exit
)
if
(
m
->
exit
)
m
->
exit
(
fa
);
m
->
exit
(
fa
);
}
}
fa_spi_exit
(
fa
);
fa_clock_disable
(
fa
);
fa_clock_disable
(
fa
);
fa_dma_release_channel
(
fa
);
fa_dma_release_channel
(
fa
);
...
@@ -836,14 +957,14 @@ static int fa_init(void)
...
@@ -836,14 +957,14 @@ static int fa_init(void)
{
{
int
ret
;
int
ret
;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)
#if KERNEL_VERSION(3, 15, 0) > LINUX_VERSION_CODE
fa_workqueue
=
alloc_workqueue
(
fa_dev_drv
.
driver
.
name
,
fa_workqueue
=
alloc_workqueue
(
fa_dev_drv
.
driver
.
name
,
WQ_NON_REENTRANT
|
WQ_UNBOUND
|
WQ_NON_REENTRANT
|
WQ_UNBOUND
|
WQ_MEM_RECLAIM
,
1
);
WQ_MEM_RECLAIM
,
1
);
#else
#else
fa_workqueue
=
alloc_workqueue
(
fa_dev_drv
.
driver
.
name
,
fa_workqueue
=
alloc_workqueue
(
fa_dev_drv
.
driver
.
name
,
WQ_UNBOUND
|
WQ_MEM_RECLAIM
,
1
);
WQ_UNBOUND
|
WQ_MEM_RECLAIM
,
1
);
#endif
#endif
if
(
fa_workqueue
==
NULL
)
if
(
fa_workqueue
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
...
software/kernel/fa-debug.c
View file @
05bbebf8
...
@@ -9,22 +9,22 @@
...
@@ -9,22 +9,22 @@
#include "fmc-adc-100m14b4cha-private.h"
#include "fmc-adc-100m14b4cha-private.h"
#define FA_DBG_REG32_CH(_n) \
#define FA_DBG_REG32_CH(_n) \
{.name = "ADC-CSR:ch"#_n"_ctl", .offset = ADC_CSR_OFF + 0x080 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_ctl", .offset = ADC_CSR_OFF + 0x080 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_sta", .offset = ADC_CSR_OFF + 0x084 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_sta", .offset = ADC_CSR_OFF + 0x084 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_cal_nb", .offset = ADC_CSR_OFF + 0x088 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_cal_nb", .offset = ADC_CSR_OFF + 0x088 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_sat", .offset = ADC_CSR_OFF + 0x08C + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_sat", .offset = ADC_CSR_OFF + 0x08C + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_trig_thres", .offset = ADC_CSR_OFF + 0x090 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_trig_thres", .offset = ADC_CSR_OFF + 0x090 + ((_n - 1) * 0x40)},
\
{.name = "ADC-CSR:ch"#_n"_trig_dly", .offset = ADC_CSR_OFF + 0x094 + ((_n - 1) * 0x40)}
{.name = "ADC-CSR:ch"#_n"_trig_dly", .offset = ADC_CSR_OFF + 0x094 + ((_n - 1) * 0x40)}
#define FA_DBG_REG32_TIM(_name, _off)
\
#define FA_DBG_REG32_TIM(_name, _off) \
{ \
{
\
.name = "TIME-TAG:"#_name"_seconds_upper",
\
.name = "TIME-TAG:"#_name"_seconds_upper", \
.offset = ADC_UTC_OFF + _off \
.offset = ADC_UTC_OFF + _off \
}, { \
}, {
\
.name = "TIME-TAG:"#_name"_seconds_lower",
\
.name = "TIME-TAG:"#_name"_seconds_lower", \
.offset = ADC_UTC_OFF + _off + 0x4, \
.offset = ADC_UTC_OFF + _off + 0x4, \
}, { \
}, {
\
.name = "TIME-TAG:"#_name"_coarse",
\
.name = "TIME-TAG:"#_name"_coarse", \
.offset = ADC_UTC_OFF + _off + 0x8, \
.offset = ADC_UTC_OFF + _off + 0x8, \
}
}
...
@@ -139,8 +139,8 @@ static void fa_regdump_seq_read_spi(struct fa_dev *fa, struct seq_file *s)
...
@@ -139,8 +139,8 @@ static void fa_regdump_seq_read_spi(struct fa_dev *fa, struct seq_file *s)
{
{
int
i
;
int
i
;
seq_p
rintf
(
s
,
"ADC SPI registers
\n
"
);
seq_p
uts
(
s
,
"ADC SPI registers
\n
"
);
seq_p
rintf
(
s
,
"Address Data
\n
"
);
seq_p
uts
(
s
,
"Address Data
\n
"
);
for
(
i
=
0
;
i
<
5
;
++
i
)
{
for
(
i
=
0
;
i
<
5
;
++
i
)
{
uint32_t
tx
,
rx
;
uint32_t
tx
,
rx
;
int
err
;
int
err
;
...
@@ -149,11 +149,9 @@ static void fa_regdump_seq_read_spi(struct fa_dev *fa, struct seq_file *s)
...
@@ -149,11 +149,9 @@ static void fa_regdump_seq_read_spi(struct fa_dev *fa, struct seq_file *s)
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
err
=
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
tx
,
&
rx
);
rx
&=
0xFF
;
/* the value is 8bit */
rx
&=
0xFF
;
/* the value is 8bit */
if
(
err
)
if
(
err
)
seq_printf
(
s
,
"A%d %02xh read failure!
\n
"
,
seq_printf
(
s
,
"A%d %02xh read failure!
\n
"
,
i
,
i
);
i
,
i
);
else
else
seq_printf
(
s
,
"A%d %02xh 0x%02x
\n
"
,
seq_printf
(
s
,
"A%d %02xh 0x%02x
\n
"
,
i
,
i
,
rx
);
i
,
i
,
rx
);
}
}
}
}
...
@@ -183,7 +181,7 @@ static const struct file_operations fa_regdump_ops = {
...
@@ -183,7 +181,7 @@ static const struct file_operations fa_regdump_ops = {
static
ssize_t
fa_trg_sw_write
(
struct
file
*
file
,
const
char
__user
*
buf
,
static
ssize_t
fa_trg_sw_write
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
size_t
count
,
loff_t
*
ppos
)
{
{
struct
fa_dev
*
fa
=
file
->
private_data
;
struct
fa_dev
*
fa
=
file
->
private_data
;
int
err
;
int
err
;
...
@@ -212,7 +210,7 @@ static int fa_data_pattern_adc_write(struct fa_dev *fa, const char __user *buf,
...
@@ -212,7 +210,7 @@ static int fa_data_pattern_adc_write(struct fa_dev *fa, const char __user *buf,
if
(
err
)
if
(
err
)
return
-
EFAULT
;
return
-
EFAULT
;
if
((
count
==
1
||
count
==
2
)
&&
buf_l
[
0
]
==
'0'
)
{
if
((
count
==
1
||
count
==
2
)
&&
buf_l
[
0
]
==
'0'
)
{
err
=
fa_adc_data_pattern_set
(
fa
,
0
,
0
);
err
=
fa_adc_data_pattern_set
(
fa
,
0
,
0
);
fa_calib_init
(
fa
);
fa_calib_init
(
fa
);
return
err
;
return
err
;
...
@@ -249,10 +247,10 @@ static ssize_t fa_data_pattern_write(struct file *file, const char __user *buf,
...
@@ -249,10 +247,10 @@ static ssize_t fa_data_pattern_write(struct file *file, const char __user *buf,
err
=
fa_data_pattern_adc_write
(
fa
,
buf
+
4
,
count
-
4
);
err
=
fa_data_pattern_adc_write
(
fa
,
buf
+
4
,
count
-
4
);
return
err
?
err
:
count
;
return
err
?
err
:
count
;
}
else
{
dev_err
(
&
fa
->
pdev
->
dev
,
"Unknown command
\"
%s
\"\n
"
,
buf_l
);
return
-
EINVAL
;
}
}
dev_err
(
&
fa
->
pdev
->
dev
,
"Unknown command
\"
%s
\"\n
"
,
buf_l
);
return
-
EINVAL
;
}
}
static
ssize_t
fa_data_pattern_read
(
struct
file
*
file
,
char
__user
*
buf
,
static
ssize_t
fa_data_pattern_read
(
struct
file
*
file
,
char
__user
*
buf
,
...
@@ -264,10 +262,10 @@ static ssize_t fa_data_pattern_read(struct file *file, char __user *buf,
...
@@ -264,10 +262,10 @@ static ssize_t fa_data_pattern_read(struct file *file, char __user *buf,
unsigned
int
enable
;
unsigned
int
enable
;
int
err
;
int
err
;
if
(
*
ppos
>
0
)
if
(
*
ppos
>
0
)
return
0
;
return
0
;
err
=
fa_adc_data_pattern_get
(
fa
,
&
pattern
,
&
enable
);
err
=
fa_adc_data_pattern_get
(
fa
,
&
pattern
,
&
enable
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
snprintf
(
buf_l
,
FA_ADC_DATA_PATTERN_CMD_SIZE
,
"adc %u 0x%02x
\n
"
,
snprintf
(
buf_l
,
FA_ADC_DATA_PATTERN_CMD_SIZE
,
"adc %u 0x%02x
\n
"
,
...
@@ -301,14 +299,7 @@ int fa_debug_init(struct fa_dev *fa)
...
@@ -301,14 +299,7 @@ int fa_debug_init(struct fa_dev *fa)
fa
->
dbg_reg32
.
regs
=
fa_debugfs_reg32
;
fa
->
dbg_reg32
.
regs
=
fa_debugfs_reg32
;
fa
->
dbg_reg32
.
nregs
=
ARRAY_SIZE
(
fa_debugfs_reg32
);
fa
->
dbg_reg32
.
nregs
=
ARRAY_SIZE
(
fa_debugfs_reg32
);
fa
->
dbg_reg32
.
base
=
fa
->
fa_top_level
;
fa
->
dbg_reg32
.
base
=
fa
->
fa_top_level
;
fa
->
dbg_reg
=
debugfs_create_regset32
(
"regs"
,
0444
,
fa
->
dbg_dir
,
debugfs_create_regset32
(
"regs"
,
0444
,
fa
->
dbg_dir
,
&
fa
->
dbg_reg32
);
&
fa
->
dbg_reg32
);
if
(
IS_ERR_OR_NULL
(
fa
->
dbg_reg
))
{
err
=
PTR_ERR
(
fa
->
dbg_reg
);
dev_warn
(
&
fa
->
pdev
->
dev
,
"Cannot create debugfs file
\"
regs
\"
(%d)
\n
"
,
err
);
}
fa
->
dbg_reg_spi
=
debugfs_create_file
(
"spi-regs"
,
0444
,
fa
->
dbg_reg_spi
=
debugfs_create_file
(
"spi-regs"
,
0444
,
fa
->
dbg_dir
,
fa
,
fa
->
dbg_dir
,
fa
,
...
...
software/kernel/fa-dma.c
View file @
05bbebf8
...
@@ -4,53 +4,43 @@
...
@@ -4,53 +4,43 @@
* Author: Federico Vaga <federico.vaga@cern.ch>
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/types.h>
#ifdef CONFIG_FMC_ADC_SVEC
#ifdef CONFIG_FMC_ADC_SVEC
#include "vmebus.h"
#include "vmebus.h"
#endif
#endif
#include "fmc-adc-100m14b4cha-private.h"
#include "fmc-adc-100m14b4cha-private.h"
/* Endianess */
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 0
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1
#endif
static
void
zfad_dma_done
(
struct
zio_cset
*
cset
);
static
void
zfad_dma_done
(
struct
zio_cset
*
cset
);
static
int
__get_endian
(
void
)
{
int
i
=
1
;
char
*
p
=
(
char
*
)
&
i
;
if
(
p
[
0
]
==
1
)
return
LITTLE_ENDIAN
;
else
return
BIG_ENDIAN
;
}
/**
/**
* Fix endianess from big to host endianess (32bit)
* Fix endianness from little to host endianess (32bit)
* @byte_lenght: number of bytes to fix (32bit aligned)
* @buffer: buffer to fix
*
* Data coming from the ADC IP-CORE are little-endian, so on big endian CPUs
* we have to swap the byte order.
*/
*/
static
void
__endianness
(
unsigned
int
byte_length
,
void
*
buffer
)
#ifdef __BIG_ENDIAN
static
void
fix_endianness
(
unsigned
int
byte_length
,
void
*
buffer
)
{
{
/* CPU may be little endian, VME is big endian */
/* swap samples and trig timetag all seen as 32bits words */
if
(
__get_endian
()
==
LITTLE_ENDIAN
)
{
int
i
;
/* swap samples and trig timetag all seen as 32bits words */
int
size
=
byte_length
/
4
;
int
i
;
uint32_t
*
ptr
=
buffer
;
int
size
=
byte_length
/
4
;
uint32_t
*
ptr
=
buffer
;
for
(
i
=
0
;
i
<
size
;
++
i
,
++
ptr
)
for
(
i
=
0
;
i
<
size
;
++
i
,
++
ptr
)
*
ptr
=
__be32_to_cpu
(
*
ptr
);
le32_to_cpus
(
ptr
);
}
}
}
#else
static
void
fix_endianness
(
unsigned
int
byte_length
,
void
*
buffer
)
{
}
#endif
struct
zfad_timetag
{
struct
zfad_timetag
{
uint32_t
sec_low
;
uint32_t
sec_low
;
...
@@ -76,7 +66,7 @@ static bool fa_dmaengine_filter_svec(struct dma_chan *dchan, void *arg)
...
@@ -76,7 +66,7 @@ static bool fa_dmaengine_filter_svec(struct dma_chan *dchan, void *arg)
struct
fa_dev
*
fa
=
arg
;
struct
fa_dev
*
fa
=
arg
;
struct
device
*
device_ref
;
struct
device
*
device_ref
;
device_ref
=
fa
->
pdev
->
dev
.
parent
->
parent
->
parent
->
parent
->
parent
->
parent
;
device_ref
=
fa
->
pdev
->
dev
.
parent
->
parent
->
parent
->
parent
->
parent
->
parent
;
return
(
dchan
->
device
->
dev
==
device_ref
);
return
(
dchan
->
device
->
dev
==
device_ref
);
}
}
...
@@ -87,7 +77,7 @@ int fa_dma_request_channel(struct fa_dev *fa)
...
@@ -87,7 +77,7 @@ int fa_dma_request_channel(struct fa_dev *fa)
struct
resource
*
r
;
struct
resource
*
r
;
int
dma_dev_id
;
int
dma_dev_id
;
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
return
0
;
return
0
;
r
=
platform_get_resource
(
fa
->
pdev
,
IORESOURCE_DMA
,
ADC_DMA
);
r
=
platform_get_resource
(
fa
->
pdev
,
IORESOURCE_DMA
,
ADC_DMA
);
...
@@ -189,7 +179,7 @@ static uint32_t fa_ddr_offset_multi(struct fa_dev *fa, uint32_t shot_n)
...
@@ -189,7 +179,7 @@ static uint32_t fa_ddr_offset_multi(struct fa_dev *fa, uint32_t shot_n)
struct
zio_cset
*
cset
=
fa
->
zdev
->
cset
;
struct
zio_cset
*
cset
=
fa
->
zdev
->
cset
;
uint32_t
off
;
uint32_t
off
;
off
=
cset
->
interleave
->
current_ctrl
->
ssize
*
cset
->
ti
->
nsamples
;
off
=
cset
->
interleave
->
current_ctrl
->
ssize
*
cset
->
ti
->
nsamples
;
off
+=
FA_TRIG_TIMETAG_BYTES
;
off
+=
FA_TRIG_TIMETAG_BYTES
;
off
*=
shot_n
;
off
*=
shot_n
;
...
@@ -200,11 +190,10 @@ static uint32_t fa_ddr_offset(struct fa_dev *fa, uint32_t shot_n)
...
@@ -200,11 +190,10 @@ static uint32_t fa_ddr_offset(struct fa_dev *fa, uint32_t shot_n)
{
{
WARN
(
fa
->
n_shots
==
1
&&
shot_n
!=
0
,
WARN
(
fa
->
n_shots
==
1
&&
shot_n
!=
0
,
"Inconsistent shot number %d
\n
"
,
shot_n
);
"Inconsistent shot number %d
\n
"
,
shot_n
);
if
(
fa
->
n_shots
==
1
)
{
if
(
fa
->
n_shots
==
1
)
return
fa_ddr_offset_single
(
fa
);
return
fa_ddr_offset_single
(
fa
);
}
else
{
else
return
fa_ddr_offset_multi
(
fa
,
shot_n
);
return
fa_ddr_offset_multi
(
fa
,
shot_n
);
}
}
}
static
unsigned
int
zfad_block_n_pages
(
struct
zio_block
*
block
)
static
unsigned
int
zfad_block_n_pages
(
struct
zio_block
*
block
)
...
@@ -320,12 +309,7 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages,
...
@@ -320,12 +309,7 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages,
static
void
zfad_dma_context_exit_svec
(
struct
zio_cset
*
cset
,
static
void
zfad_dma_context_exit_svec
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
struct
zfad_block
*
zfad_block
)
{
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
kfree
(
zfad_block
->
dma_ctx
);
kfree
(
zfad_block
->
dma_ctx
);
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_DATA_NO_SWAP
))
return
;
__endianness
(
zfad_block
->
block
->
datalen
,
zfad_block
->
block
->
data
);
}
}
static
void
zfad_dma_context_exit
(
struct
zio_cset
*
cset
,
static
void
zfad_dma_context_exit
(
struct
zio_cset
*
cset
,
...
@@ -333,6 +317,7 @@ static void zfad_dma_context_exit(struct zio_cset *cset,
...
@@ -333,6 +317,7 @@ static void zfad_dma_context_exit(struct zio_cset *cset,
{
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
fix_endianness
(
zfad_block
->
block
->
datalen
,
zfad_block
->
block
->
data
);
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
zfad_dma_context_exit_svec
(
cset
,
zfad_block
);
zfad_dma_context_exit_svec
(
cset
,
zfad_block
);
}
}
...
@@ -546,7 +531,7 @@ static int fa_svec_ddr_window_set(struct fa_dev *fa, unsigned int offset)
...
@@ -546,7 +531,7 @@ static int fa_svec_ddr_window_set(struct fa_dev *fa, unsigned int offset)
return
-
ENODEV
;
return
-
ENODEV
;
fa_iowrite
(
fa
,
offset
,
addr
);
fa_iowrite
(
fa
,
offset
,
addr
);
return
0
;
return
0
;
}
}
static
int
fa_dmaengine_slave_config
(
struct
fa_dev
*
fa
,
static
int
fa_dmaengine_slave_config
(
struct
fa_dev
*
fa
,
...
@@ -582,7 +567,7 @@ static int fa_dma_shot_wait_svec(struct fa_dev *fa,
...
@@ -582,7 +567,7 @@ static int fa_dma_shot_wait_svec(struct fa_dev *fa,
{
{
int
err
;
int
err
;
if
(
fa
->
n_shots
==
1
)
if
(
fa
->
n_shots
==
1
)
return
0
;
return
0
;
err
=
wait_for_completion_interruptible_timeout
(
&
zfad_block
->
shot_done
,
err
=
wait_for_completion_interruptible_timeout
(
&
zfad_block
->
shot_done
,
...
@@ -596,7 +581,7 @@ static int fa_dma_shot_wait_svec(struct fa_dev *fa,
...
@@ -596,7 +581,7 @@ static int fa_dma_shot_wait_svec(struct fa_dev *fa,
return
-
EINVAL
;
return
-
EINVAL
;
}
}
return
0
;
return
0
;
}
}
static
int
fa_dma_start_svec
(
struct
zio_cset
*
cset
)
static
int
fa_dma_start_svec
(
struct
zio_cset
*
cset
)
...
@@ -698,12 +683,11 @@ static int zfad_dma_start(struct zio_cset *cset)
...
@@ -698,12 +683,11 @@ static int zfad_dma_start(struct zio_cset *cset)
err
=
fa_fsm_wait_state
(
fa
,
FA100M14B4C_STATE_IDLE
,
10
);
err
=
fa_fsm_wait_state
(
fa
,
FA100M14B4C_STATE_IDLE
,
10
);
if
(
err
)
{
if
(
err
)
{
dev_warn
(
&
fa
->
pdev
->
dev
,
dev_warn
(
&
fa
->
pdev
->
dev
,
"Can't start DMA on the last acquisition, "
"Can't start DMA on the last acquisition, State Machine is not IDLE
\n
"
);
"State Machine is not IDLE
\n
"
);
return
err
;
return
err
;
}
}
dev_dbg
(
&
fa
->
pdev
->
dev
,
dev_dbg
(
&
fa
->
pdev
->
dev
,
"Start DMA transfer for %i shots of %i samples
\n
"
,
"Start DMA transfer for %i shots of %i samples
\n
"
,
fa
->
n_shots
,
cset
->
ti
->
nsamples
);
fa
->
n_shots
,
cset
->
ti
->
nsamples
);
...
@@ -712,14 +696,14 @@ static int zfad_dma_start(struct zio_cset *cset)
...
@@ -712,14 +696,14 @@ static int zfad_dma_start(struct zio_cset *cset)
* different DMA transfers required for multi-shots
* different DMA transfers required for multi-shots
*/
*/
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SRC
],
0
);
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SRC
],
0
);
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
err
=
fa_dma_start_svec
(
cset
);
err
=
fa_dma_start_svec
(
cset
);
else
else
err
=
fa_dma_start_spec
(
cset
);
err
=
fa_dma_start_spec
(
cset
);
if
(
err
)
if
(
err
)
goto
err_start
;
goto
err_start
;
return
0
;
return
0
;
err_start:
err_start:
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SRC
],
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SRC
],
...
@@ -774,7 +758,7 @@ static void zfad_block_ctrl_attr_update(struct zio_block *block,
...
@@ -774,7 +758,7 @@ static void zfad_block_ctrl_attr_update(struct zio_block *block,
struct
zio_control
*
ctrl
=
zio_get_ctrl
(
block
);
struct
zio_control
*
ctrl
=
zio_get_ctrl
(
block
);
uint32_t
*
ext_val
=
ctrl
->
attr_channel
.
ext_val
;
uint32_t
*
ext_val
=
ctrl
->
attr_channel
.
ext_val
;
ext_val
[
FA100M14B4C_TATTR_STA
]
=
timetag
->
status
;
ext_val
[
FA100M14B4C_TATTR_STA
]
=
timetag
->
status
;
ctrl
->
seq_num
=
seq_num
;
ctrl
->
seq_num
=
seq_num
;
}
}
...
...
software/kernel/fa-zio-drv.c
View file @
05bbebf8
...
@@ -44,15 +44,15 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
...
@@ -44,15 +44,15 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
*/
*/
ZIO_ATTR_EXT
(
"undersample"
,
ZIO_RW_PERM
,
ZFAT_SR_UNDER
,
1
),
ZIO_ATTR_EXT
(
"undersample"
,
ZIO_RW_PERM
,
ZFAT_SR_UNDER
,
1
),
ZIO_ATTR_EXT
(
"ch0-offset"
,
ZIO_RW_PERM
,
ZFA_CH1_OFFSET
,
0
),
ZIO_ATTR_EXT
(
"ch0-offset"
,
ZIO_RW_PERM
,
ZFA_CH1_OFFSET
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch1-offset"
,
ZIO_RW_PERM
,
ZFA_CH2_OFFSET
,
0
),
ZIO_ATTR_EXT
(
"ch1-offset"
,
ZIO_RW_PERM
,
ZFA_CH2_OFFSET
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch2-offset"
,
ZIO_RW_PERM
,
ZFA_CH3_OFFSET
,
0
),
ZIO_ATTR_EXT
(
"ch2-offset"
,
ZIO_RW_PERM
,
ZFA_CH3_OFFSET
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch3-offset"
,
ZIO_RW_PERM
,
ZFA_CH4_OFFSET
,
0
),
ZIO_ATTR_EXT
(
"ch3-offset"
,
ZIO_RW_PERM
,
ZFA_CH4_OFFSET
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch0-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH1_OFFSET_ZERO
,
0
),
ZIO_ATTR_EXT
(
"ch0-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH1_OFFSET_ZERO
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch1-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH2_OFFSET_ZERO
,
0
),
ZIO_ATTR_EXT
(
"ch1-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH2_OFFSET_ZERO
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch2-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH3_OFFSET_ZERO
,
0
),
ZIO_ATTR_EXT
(
"ch2-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH3_OFFSET_ZERO
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch3-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH4_OFFSET_ZERO
,
0
),
ZIO_ATTR_EXT
(
"ch3-offset-zero"
,
ZIO_RW_PERM
,
ZFA_SW_CH4_OFFSET_ZERO
,
0
x8000
),
ZIO_ATTR_EXT
(
"ch0-vref"
,
ZIO_RW_PERM
,
ZFA_CH1_CTL_RANGE
,
0
),
ZIO_ATTR_EXT
(
"ch0-vref"
,
ZIO_RW_PERM
,
ZFA_CH1_CTL_RANGE
,
0
),
ZIO_ATTR_EXT
(
"ch1-vref"
,
ZIO_RW_PERM
,
ZFA_CH2_CTL_RANGE
,
0
),
ZIO_ATTR_EXT
(
"ch1-vref"
,
ZIO_RW_PERM
,
ZFA_CH2_CTL_RANGE
,
0
),
...
@@ -104,7 +104,7 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
...
@@ -104,7 +104,7 @@ static struct zio_attribute zfad_cset_ext_zattr[] = {
* 4: POST_TRIG
* 4: POST_TRIG
* 5: DECR_SHOT
* 5: DECR_SHOT
* 7: Illegal
* 7: Illegal
*
*
/
*/
ZIO_PARAM_EXT
(
"fsm-state"
,
ZIO_RO_PERM
,
ZFA_STA_FSM
,
0
),
ZIO_PARAM_EXT
(
"fsm-state"
,
ZIO_RO_PERM
,
ZFA_STA_FSM
,
0
),
/* last acquisition end time stamp */
/* last acquisition end time stamp */
ZIO_PARAM_EXT
(
"tstamp-acq-end-su"
,
ZIO_RO_PERM
,
ZIO_PARAM_EXT
(
"tstamp-acq-end-su"
,
ZIO_RO_PERM
,
...
@@ -160,12 +160,6 @@ int zfad_convert_user_range(uint32_t user_val)
...
@@ -160,12 +160,6 @@ int zfad_convert_user_range(uint32_t user_val)
return
zfad_convert_hw_range
(
user_val
);
return
zfad_convert_hw_range
(
user_val
);
}
}
static
bool
fa_is_dac_offset_valid
(
int32_t
user
,
int32_t
zero
)
{
int32_t
offset
=
user
+
zero
;
return
(
offset
>=
DAC_SAT_LOW
&&
offset
<=
DAC_SAT_UP
);
}
/*
/*
* zfad_conf_set
* zfad_conf_set
*
*
...
@@ -209,15 +203,17 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
...
@@ -209,15 +203,17 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
/*fallthrough*/
/*fallthrough*/
case
ZFA_SW_CH4_OFFSET_ZERO
:
case
ZFA_SW_CH4_OFFSET_ZERO
:
i
--
;
i
--
;
chan
=
to_zio_cset
(
dev
)
->
chan
+
i
;
if
(
usr_val
&
0xFFFF0000
)
{
if
(
!
fa_is_dac_offset_valid
(
fa
->
user_offset
[
chan
->
index
],
dev_err
(
dev
,
usr_val
))
"Offset must be a 16bit unsigned value (0x%08x)
\n
"
,
usr_val
);
return
-
EINVAL
;
return
-
EINVAL
;
}
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
fa
->
zero_offset
[
i
]
=
usr_val
;
fa
->
zero_offset
[
i
]
=
usr_val
;
fa_calib_dac_config_chan
(
fa
,
i
,
0
,
FA_CALIB_FLAG_READ_TEMP
);
err
=
fa_calib_dac_config_chan
(
fa
,
i
,
0
,
FA_CALIB_FLAG_READ_TEMP
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
return
0
;
return
err
;
case
ZFA_CHx_SAT
:
case
ZFA_CHx_SAT
:
/* TODO when TLV */
/* TODO when TLV */
break
;
break
;
...
@@ -244,18 +240,27 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
...
@@ -244,18 +240,27 @@ static int zfad_conf_set(struct device *dev, struct zio_attribute *zattr,
/*fallthrough*/
/*fallthrough*/
case
ZFA_CH4_OFFSET
:
case
ZFA_CH4_OFFSET
:
i
--
;
i
--
;
chan
=
to_zio_cset
(
dev
)
->
chan
+
i
;
if
(
usr_val
&
0xFFFF0000
)
{
if
(
!
fa_is_dac_offset_valid
(
usr_val
,
dev_err
(
dev
,
fa
->
zero_offset
[
chan
->
index
]))
"Offset must be a 16bit unsigned value (0x%08x)
\n
"
,
usr_val
);
return
-
EINVAL
;
return
-
EINVAL
;
}
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
fa
->
user_offset
[
chan
->
index
]
=
usr_val
;
fa
->
user_offset
[
i
]
=
usr_val
;
err
=
fa_calib_dac_config_chan
(
fa
,
i
,
0
,
err
=
fa_calib_dac_config_chan
(
fa
,
i
,
0
,
FA_CALIB_FLAG_READ_TEMP
);
FA_CALIB_FLAG_READ_TEMP
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_unlock
(
&
fa
->
zdev
->
cset
->
lock
);
return
err
;
return
err
;
case
ZFA_CHx_OFFSET
:
case
ZFA_CHx_OFFSET
:
chan
=
to_zio_chan
(
dev
);
chan
=
to_zio_chan
(
dev
);
if
(
usr_val
&
0xFFFF0000
)
{
dev_err
(
dev
,
"Offset must be a 16bit unsigned value (0x%08x)
\n
"
,
usr_val
);
return
-
EINVAL
;
}
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
spin_lock
(
&
fa
->
zdev
->
cset
->
lock
);
fa
->
user_offset
[
chan
->
index
]
=
usr_val
;
fa
->
user_offset
[
chan
->
index
]
=
usr_val
;
err
=
fa_calib_dac_config_chan
(
fa
,
chan
->
index
,
0
,
err
=
fa_calib_dac_config_chan
(
fa
,
chan
->
index
,
0
,
...
@@ -425,18 +430,16 @@ static inline int zfat_overflow_detection(struct zio_ti *ti)
...
@@ -425,18 +430,16 @@ static inline int zfat_overflow_detection(struct zio_ti *ti)
nsamples
=
ti_zattr
[
ZIO_ATTR_TRIG_PRE_SAMP
].
value
+
nsamples
=
ti_zattr
[
ZIO_ATTR_TRIG_PRE_SAMP
].
value
+
ti_zattr
[
ZIO_ATTR_TRIG_POST_SAMP
].
value
;
ti_zattr
[
ZIO_ATTR_TRIG_POST_SAMP
].
value
;
shot_size
=
((
nsamples
+
2
)
*
ti
->
cset
->
ssize
)
*
FA100M14B4C_NCHAN
;
shot_size
=
((
nsamples
+
2
)
*
ti
->
cset
->
ssize
)
*
FA100M14B4C_NCHAN
;
if
(
(
shot_size
*
nshot_t
)
>
FA100M14B4C_MAX_ACQ_BYTE
)
{
if
(
(
shot_size
*
nshot_t
)
>
FA100M14B4C_MAX_ACQ_BYTE
)
{
dev_err
(
fa
->
msgdev
,
"Cannot acquire, dev memory overflow
\n
"
);
dev_err
(
fa
->
msgdev
,
"Cannot acquire, dev memory overflow
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
/* in case of multi shot, each shot cannot exceed the dpram size */
/* in case of multi shot, each shot cannot exceed the dpram size */
if
(
(
nshot_t
>
1
)
&&
if
((
nshot_t
>
1
)
&&
(
nsamples
>
fa
->
mshot_max_samples
))
{
(
nsamples
>
fa
->
mshot_max_samples
)
)
{
dev_err
(
fa
->
msgdev
,
dev_err
(
fa
->
msgdev
,
"Cannot acquire such amount of samples "
"Cannot acquire such amount of samples (req: %d , max: %d) in multi shot mode. dev memory overflow
\n
"
,
"(req: %d , max: %d) in multi shot mode."
nsamples
,
fa
->
mshot_max_samples
);
"dev memory overflow
\n
"
,
nsamples
,
fa
->
mshot_max_samples
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
return
0
;
return
0
;
...
@@ -634,9 +637,8 @@ static struct zio_driver fa_zdrv = {
...
@@ -634,9 +637,8 @@ static struct zio_driver fa_zdrv = {
.
remove
=
zfad_zio_remove
,
.
remove
=
zfad_zio_remove
,
/* Take the version from ZIO git sub-module */
/* Take the version from ZIO git sub-module */
.
min_version
=
ZIO_VERSION
(
__ZIO_MIN_MAJOR_VERSION
,
.
min_version
=
ZIO_VERSION
(
__ZIO_MIN_MAJOR_VERSION
,
__ZIO_MIN_MINOR_VERSION
,
__ZIO_MIN_MINOR_VERSION
,
0
),
/* Change it if you use new features from
0
),
a specific patch */
};
};
...
...
software/kernel/fa-zio-trg.c
View file @
05bbebf8
...
@@ -297,8 +297,7 @@ static int zfat_data_done(struct zio_cset *cset)
...
@@ -297,8 +297,7 @@ static int zfat_data_done(struct zio_cset *cset)
i
+
1
,
fa
->
n_shots
);
i
+
1
,
fa
->
n_shots
);
zio_buffer_store_block
(
bi
,
zfad_block
[
i
].
block
);
zio_buffer_store_block
(
bi
,
zfad_block
[
i
].
block
);
}
else
{
/* Free un-filled blocks */
}
else
{
/* Free un-filled blocks */
dev_dbg
(
fa
->
msgdev
,
"Free un-acquired block %d/%d "
dev_dbg
(
fa
->
msgdev
,
"Free un-acquired block %d/%d (received %d shots)
\n
"
,
"(received %d shots)
\n
"
,
i
+
1
,
fa
->
n_shots
,
fa
->
n_fires
);
i
+
1
,
fa
->
n_shots
,
fa
->
n_fires
);
zio_buffer_free_block
(
bi
,
zfad_block
[
i
].
block
);
zio_buffer_free_block
(
bi
,
zfad_block
[
i
].
block
);
}
}
...
@@ -383,8 +382,7 @@ static int zfat_arm_trigger(struct zio_ti *ti)
...
@@ -383,8 +382,7 @@ static int zfat_arm_trigger(struct zio_ti *ti)
if
(
size
%
4
)
{
if
(
size
%
4
)
{
/* should never happen: increase the size accordling */
/* should never happen: increase the size accordling */
dev_warn
(
fa
->
msgdev
,
dev_warn
(
fa
->
msgdev
,
"zio data block size should 32bit word aligned."
"zio data block size should 32bit word aligned. original size:%d was increased by %d bytes
\n
"
,
"original size:%d was increased by %d bytes
\n
"
,
size
,
size
%
4
);
size
,
size
%
4
);
size
+=
size
%
4
;
size
+=
size
%
4
;
}
}
...
@@ -496,8 +494,8 @@ int fa_trig_init(void)
...
@@ -496,8 +494,8 @@ int fa_trig_init(void)
err
=
zio_register_trig
(
&
zfat_type
,
"adc-100m14b"
);
err
=
zio_register_trig
(
&
zfat_type
,
"adc-100m14b"
);
if
(
err
)
if
(
err
)
pr_err
(
"%s: Cannot register ZIO trigger type
"
pr_err
(
"%s: Cannot register ZIO trigger type
\"
adc-100m14b
\"
(error %i)
\n
"
,
"
\"
adc-100m14b
\"
(error %i)
\n
"
,
KBUILD_MODNAME
,
err
);
KBUILD_MODNAME
,
err
);
return
err
;
return
err
;
}
}
...
...
software/kernel/fmc-adc-100m14b4ch-spec-core.c
View file @
05bbebf8
...
@@ -12,6 +12,8 @@
...
@@ -12,6 +12,8 @@
#include "platform_data/fmc-adc-100m14b4cha.h"
#include "platform_data/fmc-adc-100m14b4cha.h"
enum
fa_spec_dev_offsets
{
enum
fa_spec_dev_offsets
{
FA_SPEC_DBL_ADC_META_START
=
0x00000000
,
FA_SPEC_DBL_ADC_META_END
=
0x00000040
,
FA_SPEC_ADC_MEM_START
=
0x000002000
,
FA_SPEC_ADC_MEM_START
=
0x000002000
,
FA_SPEC_ADC_MEM_END
=
0x000003FFF
,
FA_SPEC_ADC_MEM_END
=
0x000003FFF
,
};
};
...
@@ -23,7 +25,8 @@ static const struct fmc_adc_platform_data fmc_adc_pdata = {
...
@@ -23,7 +25,8 @@ static const struct fmc_adc_platform_data fmc_adc_pdata = {
.
calib_trig_internal
=
0
,
.
calib_trig_internal
=
0
,
};
};
static
int
fa_spec_probe
(
struct
platform_device
*
pdev
)
{
static
int
fa_spec_probe
(
struct
platform_device
*
pdev
)
{
static
struct
resource
fa_spec_fdt_res
[]
=
{
static
struct
resource
fa_spec_fdt_res
[]
=
{
{
{
.
name
=
"fmc-adc-mem"
,
.
name
=
"fmc-adc-mem"
,
...
@@ -36,7 +39,14 @@ static int fa_spec_probe(struct platform_device *pdev) {
...
@@ -36,7 +39,14 @@ static int fa_spec_probe(struct platform_device *pdev) {
{
{
.
name
=
"fmc-adc-irq"
,
.
name
=
"fmc-adc-irq"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
}};
},
{
.
name
=
"fmc-adc-meta"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
FA_SPEC_DBL_ADC_META_START
,
.
end
=
FA_SPEC_DBL_ADC_META_END
,
},
};
struct
platform_device_info
pdevinfo
=
{
struct
platform_device_info
pdevinfo
=
{
.
parent
=
&
pdev
->
dev
,
.
parent
=
&
pdev
->
dev
,
.
name
=
"fmc-adc-100m"
,
.
name
=
"fmc-adc-100m"
,
...
@@ -93,6 +103,8 @@ static int fa_spec_probe(struct platform_device *pdev) {
...
@@ -93,6 +103,8 @@ static int fa_spec_probe(struct platform_device *pdev) {
fa_spec_fdt_res
[
0
].
end
=
rmem
->
start
+
FA_SPEC_ADC_MEM_END
;
fa_spec_fdt_res
[
0
].
end
=
rmem
->
start
+
FA_SPEC_ADC_MEM_END
;
fa_spec_fdt_res
[
1
].
start
=
dma_dev_chan
;
fa_spec_fdt_res
[
1
].
start
=
dma_dev_chan
;
fa_spec_fdt_res
[
2
].
start
=
irq
;
fa_spec_fdt_res
[
2
].
start
=
irq
;
fa_spec_fdt_res
[
3
].
start
=
rmem
->
start
+
FA_SPEC_DBL_ADC_META_START
;
fa_spec_fdt_res
[
3
].
end
=
rmem
->
start
+
FA_SPEC_DBL_ADC_META_END
;
pdev_child
=
platform_device_register_full
(
&
pdevinfo
);
pdev_child
=
platform_device_register_full
(
&
pdevinfo
);
if
(
IS_ERR
(
pdev_child
))
if
(
IS_ERR
(
pdev_child
))
...
@@ -101,7 +113,8 @@ static int fa_spec_probe(struct platform_device *pdev) {
...
@@ -101,7 +113,8 @@ static int fa_spec_probe(struct platform_device *pdev) {
return
0
;
return
0
;
}
}
static
int
fa_spec_remove
(
struct
platform_device
*
pdev
)
{
static
int
fa_spec_remove
(
struct
platform_device
*
pdev
)
{
struct
platform_device
*
pdev_child
=
platform_get_drvdata
(
pdev
);
struct
platform_device
*
pdev_child
=
platform_get_drvdata
(
pdev
);
platform_device_unregister
(
pdev_child
);
platform_device_unregister
(
pdev_child
);
...
@@ -133,11 +146,10 @@ static const struct platform_device_id fa_spec_id_table[] = {
...
@@ -133,11 +146,10 @@ static const struct platform_device_id fa_spec_id_table[] = {
};
};
static
struct
platform_driver
fa_spec_driver
=
{
static
struct
platform_driver
fa_spec_driver
=
{
.
driver
=
.
driver
=
{
{
.
name
=
"fmc-adc-100m-spec"
,
.
name
=
"fmc-adc-100m-spec"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
},
},
.
id_table
=
fa_spec_id_table
,
.
id_table
=
fa_spec_id_table
,
.
probe
=
fa_spec_probe
,
.
probe
=
fa_spec_probe
,
.
remove
=
fa_spec_remove
,
.
remove
=
fa_spec_remove
,
...
...
software/kernel/fmc-adc-100m14b4ch-svec-core.c
View file @
05bbebf8
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/core.h>
#include <linux/fmc.h>
#include <linux/fmc.h>
#include "fmc-adc-100m14b4cha-private.h"
#include "platform_data/fmc-adc-100m14b4cha.h"
#include "platform_data/fmc-adc-100m14b4cha.h"
#define SVEC_FMC_SLOTS 2
#define SVEC_FMC_SLOTS 2
...
@@ -28,10 +29,12 @@
...
@@ -28,10 +29,12 @@
#define SVEC_FPGA_DDR5_DMA (0x3000)
#define SVEC_FPGA_DDR5_DMA (0x3000)
enum
fa_svec_dev_offsets
{
enum
fa_svec_dev_offsets
{
FA_SVEC_ADC1_MEM_START
=
0x00002000
,
FA_SVEC_DBL_ADC_META_START
=
0x00000000
,
FA_SVEC_ADC1_MEM_END
=
0x00003FFF
,
FA_SVEC_DBL_ADC_META_END
=
0x00000040
,
FA_SVEC_ADC2_MEM_START
=
0x00004000
,
FA_SVEC_ADC1_MEM_START
=
0x00002000
,
FA_SVEC_ADC2_MEM_END
=
0x00005FFF
,
FA_SVEC_ADC1_MEM_END
=
0x00003FFF
,
FA_SVEC_ADC2_MEM_START
=
0x00004000
,
FA_SVEC_ADC2_MEM_END
=
0x00005FFF
,
};
};
static
inline
struct
platform_device
*
platform_device_register_resndata_mask
(
static
inline
struct
platform_device
*
platform_device_register_resndata_mask
(
...
@@ -57,19 +60,19 @@ static inline struct platform_device *platform_device_register_resndata_mask(
...
@@ -57,19 +60,19 @@ static inline struct platform_device *platform_device_register_resndata_mask(
static
struct
fmc_adc_platform_data
fa_svec_adc_pdata
[]
=
{
static
struct
fmc_adc_platform_data
fa_svec_adc_pdata
[]
=
{
{
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
|
FMC_ADC_SVEC
|
FMC_ADC_NOSQUASH_SCATTERLIST
,
FMC_ADC_NOSQUASH_SCATTERLIST
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR4_ADDR
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR4_ADDR
,
.
vme_dma_offset
=
SVEC_FPGA_DDR4_DMA
,
.
vme_dma_offset
=
SVEC_FPGA_DDR4_DMA
,
.
calib_trig_time
=
0
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
.
calib_trig_internal
=
0
,
},
{
},
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
|
FMC_ADC_SVEC
|
FMC_ADC_NOSQUASH_SCATTERLIST
,
FMC_ADC_NOSQUASH_SCATTERLIST
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR5_ADDR
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR5_ADDR
,
.
vme_dma_offset
=
SVEC_FPGA_DDR5_DMA
,
.
vme_dma_offset
=
SVEC_FPGA_DDR5_DMA
,
.
calib_trig_time
=
0
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
.
calib_trig_internal
=
0
,
...
@@ -93,6 +96,12 @@ static struct resource fa_svec_res1[] = {
...
@@ -93,6 +96,12 @@ static struct resource fa_svec_res1[] = {
.
start
=
0
,
.
start
=
0
,
.
end
=
0
,
.
end
=
0
,
},
},
{
.
name
=
"fmc-adc-100m-meta.1"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
FA_SVEC_DBL_ADC_META_START
,
.
end
=
FA_SVEC_DBL_ADC_META_END
,
},
};
};
static
struct
resource
fa_svec_res2
[]
=
{
static
struct
resource
fa_svec_res2
[]
=
{
...
@@ -112,6 +121,12 @@ static struct resource fa_svec_res2[] = {
...
@@ -112,6 +121,12 @@ static struct resource fa_svec_res2[] = {
.
start
=
1
,
.
start
=
1
,
.
end
=
1
,
.
end
=
1
,
},
},
{
.
name
=
"fmc-adc-100m-meta.2"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
FA_SVEC_DBL_ADC_META_START
,
.
end
=
FA_SVEC_DBL_ADC_META_END
,
},
};
};
static
struct
resource
*
fa_svec_res
[]
=
{
static
struct
resource
*
fa_svec_res
[]
=
{
...
@@ -131,7 +146,7 @@ static int fa_svec_probe(struct platform_device *pdev)
...
@@ -131,7 +146,7 @@ static int fa_svec_probe(struct platform_device *pdev)
int
irq
;
int
irq
;
int
i
;
int
i
;
rmem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
rmem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
rmem
)
{
if
(
!
rmem
)
{
dev_err
(
&
pdev
->
dev
,
"Missing memory resource
\n
"
);
dev_err
(
&
pdev
->
dev
,
"Missing memory resource
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -153,7 +168,7 @@ static int fa_svec_probe(struct platform_device *pdev)
...
@@ -153,7 +168,7 @@ static int fa_svec_probe(struct platform_device *pdev)
struct
fmc_slot
*
slot
=
fmc_slot_get
(
pdev
->
dev
.
parent
,
i
+
1
);
struct
fmc_slot
*
slot
=
fmc_slot_get
(
pdev
->
dev
.
parent
,
i
+
1
);
int
present
;
int
present
;
if
(
IS_ERR
(
slot
))
{
if
(
IS_ERR
(
slot
))
{
dev_err
(
&
pdev
->
dev
,
dev_err
(
&
pdev
->
dev
,
"Can't find FMC slot %d err: %ld
\n
"
,
"Can't find FMC slot %d err: %ld
\n
"
,
i
+
1
,
PTR_ERR
(
slot
));
i
+
1
,
PTR_ERR
(
slot
));
...
@@ -169,10 +184,13 @@ static int fa_svec_probe(struct platform_device *pdev)
...
@@ -169,10 +184,13 @@ static int fa_svec_probe(struct platform_device *pdev)
memcpy
(
res
,
fa_svec_res
[
i
],
sizeof
(
res
));
memcpy
(
res
,
fa_svec_res
[
i
],
sizeof
(
res
));
res
[
0
].
parent
=
rmem
;
res
[
0
].
parent
=
rmem
;
res
[
0
].
start
+=
rmem
->
start
;
res
[
0
].
start
+=
rmem
->
start
;
res
[
0
].
end
+=
rmem
->
start
;
res
[
0
].
end
+=
rmem
->
start
;
res
[
2
].
start
+=
irq
;
res
[
2
].
start
+=
irq
;
res
[
3
].
start
=
rmem
->
start
+
FA_SVEC_DBL_ADC_META_START
;
res
[
3
].
end
=
rmem
->
start
+
FA_SVEC_DBL_ADC_META_END
;
pdev_data
->
adc
[
i
]
=
platform_device_register_resndata_mask
(
&
pdev
->
dev
,
pdev_data
->
adc
[
i
]
=
platform_device_register_resndata_mask
(
&
pdev
->
dev
,
"fmc-adc-100m"
,
"fmc-adc-100m"
,
PLATFORM_DEVID_AUTO
,
PLATFORM_DEVID_AUTO
,
...
@@ -190,7 +208,7 @@ static int fa_svec_probe(struct platform_device *pdev)
...
@@ -190,7 +208,7 @@ static int fa_svec_probe(struct platform_device *pdev)
}
}
platform_set_drvdata
(
pdev
,
pdev_data
);
platform_set_drvdata
(
pdev
,
pdev_data
);
return
0
;
return
0
;
}
}
static
int
fa_svec_remove
(
struct
platform_device
*
pdev
)
static
int
fa_svec_remove
(
struct
platform_device
*
pdev
)
...
@@ -201,12 +219,12 @@ static int fa_svec_remove(struct platform_device *pdev)
...
@@ -201,12 +219,12 @@ static int fa_svec_remove(struct platform_device *pdev)
if
(
!
pdev_data
)
if
(
!
pdev_data
)
return
0
;
return
0
;
for
(
i
=
0
;
i
<
SVEC_FMC_SLOTS
;
++
i
)
for
(
i
=
0
;
i
<
SVEC_FMC_SLOTS
;
++
i
)
if
(
pdev_data
->
adc
[
i
])
if
(
pdev_data
->
adc
[
i
])
platform_device_unregister
(
pdev_data
->
adc
[
i
]);
platform_device_unregister
(
pdev_data
->
adc
[
i
]);
kfree
(
pdev_data
);
kfree
(
pdev_data
);
return
0
;
return
0
;
}
}
/**
/**
...
...
software/kernel/fmc-adc-100m14b4cha-private.h
View file @
05bbebf8
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/fmc.h>
#include <linux/fmc.h>
#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/version.h>
#include <linux/zio.h>
#include <linux/zio.h>
#include <linux/zio-dma.h>
#include <linux/zio-dma.h>
...
@@ -31,6 +32,20 @@ enum fa_versions {
...
@@ -31,6 +32,20 @@ enum fa_versions {
ADC_VER
=
0
,
ADC_VER
=
0
,
};
};
/**
* struct device_meta_id Metadata
*/
struct
device_meta_id
{
uint32_t
vendor
;
uint32_t
device
;
uint32_t
version
;
uint32_t
bom
;
uint32_t
src
[
4
];
uint32_t
cap
;
uint32_t
uuid
[
4
];
};
enum
fa100m14b4c_trg_ext_attr_krn
{
enum
fa100m14b4c_trg_ext_attr_krn
{
FA100M14B4C_TATTR_TRG_SU
=
__FA100M14B4C_TATTR_TRG_MAX
,
FA100M14B4C_TATTR_TRG_SU
=
__FA100M14B4C_TATTR_TRG_MAX
,
FA100M14B4C_TATTR_TRG_SL
,
FA100M14B4C_TATTR_TRG_SL
,
...
@@ -42,8 +57,7 @@ enum fa100m14b4c_trg_ext_attr_krn {
...
@@ -42,8 +57,7 @@ enum fa100m14b4c_trg_ext_attr_krn {
#define ADC_SPI_OFF 0x1800
#define ADC_SPI_OFF 0x1800
#define ADC_UTC_OFF 0x1900
#define ADC_UTC_OFF 0x1900
#define DAC_SAT_LOW -5000000
#define DAC_VAL_MASK 0xFFFF
#define DAC_SAT_UP 5000000
#define ADC_DMA 0
#define ADC_DMA 0
...
@@ -57,6 +71,7 @@ enum fa_irq_resource {
...
@@ -57,6 +71,7 @@ enum fa_irq_resource {
enum
fa_mem_resource
{
enum
fa_mem_resource
{
ADC_MEM_BASE
=
0
,
ADC_MEM_BASE
=
0
,
ADC_MEM_META
,
};
};
enum
fa_bus_resource
{
enum
fa_bus_resource
{
...
@@ -64,7 +79,11 @@ enum fa_bus_resource {
...
@@ -64,7 +79,11 @@ enum fa_bus_resource {
};
};
struct
fa_memory_ops
{
struct
fa_memory_ops
{
#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
u32
(
*
read
)(
const
void
*
addr
);
#else
u32
(
*
read
)(
void
*
addr
);
u32
(
*
read
)(
void
*
addr
);
#endif
void
(
*
write
)(
u32
value
,
void
*
addr
);
void
(
*
write
)(
u32
value
,
void
*
addr
);
};
};
...
@@ -272,8 +291,8 @@ struct fa_dev; /* forward declaration */
...
@@ -272,8 +291,8 @@ struct fa_dev; /* forward declaration */
* @n_fires: number of trigger fire occurred within an acquisition
* @n_fires: number of trigger fire occurred within an acquisition
*
*
* @n_dma_err: number of errors
* @n_dma_err: number of errors
* @user_offset: user offset
(micro-Volts)
* @user_offset: user offset
* @zero_offset: necessary offset to push the channel to zero
(micro-Volts)
* @zero_offset: necessary offset to push the channel to zero
*/
*/
struct
fa_dev
{
struct
fa_dev
{
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -289,6 +308,8 @@ struct fa_dev {
...
@@ -289,6 +308,8 @@ struct fa_dev {
struct
fmc_slot
*
slot
;
struct
fmc_slot
*
slot
;
struct
fa_memory_ops
memops
;
struct
fa_memory_ops
memops
;
struct
device_meta_id
meta
;
/* carrier common base offset addresses */
/* carrier common base offset addresses */
void
*
fa_adc_csr_base
;
void
*
fa_adc_csr_base
;
void
*
fa_spi_base
;
void
*
fa_spi_base
;
...
@@ -319,8 +340,8 @@ struct fa_dev {
...
@@ -319,8 +340,8 @@ struct fa_dev {
unsigned
int
n_dma_err
;
unsigned
int
n_dma_err
;
/* Configuration */
/* Configuration */
int32_t
user_offset
[
4
];
/* one per channel */
uint16_t
user_offset
[
FA100M14B4C_NCHAN
];
/* one per channel */
int32
_t
zero_offset
[
FA100M14B4C_NCHAN
];
uint16
_t
zero_offset
[
FA100M14B4C_NCHAN
];
/* one-wire */
/* one-wire */
uint8_t
ds18_id
[
8
];
uint8_t
ds18_id
[
8
];
unsigned
long
next_t
;
unsigned
long
next_t
;
...
@@ -336,7 +357,6 @@ struct fa_dev {
...
@@ -336,7 +357,6 @@ struct fa_dev {
struct
dentry
*
dbg_dir
;
struct
dentry
*
dbg_dir
;
struct
debugfs_regset32
dbg_reg32
;
struct
debugfs_regset32
dbg_reg32
;
struct
dentry
*
dbg_reg
;
struct
dentry
*
dbg_reg_spi
;
struct
dentry
*
dbg_reg_spi
;
struct
dentry
*
dbg_trg_sw
;
struct
dentry
*
dbg_trg_sw
;
struct
dentry
*
dbg_data_pattern
;
struct
dentry
*
dbg_data_pattern
;
...
...
software/kernel/fmc-adc-100m14b4cha.h
View file @
05bbebf8
...
@@ -139,4 +139,15 @@ struct fa_calib {
...
@@ -139,4 +139,15 @@ struct fa_calib {
struct
fa_calib_stanza
dac
[
FA_CALIB_STANZA_N
];
/* For user offset, one per range */
struct
fa_calib_stanza
dac
[
FA_CALIB_STANZA_N
];
/* For user offset, one per range */
};
};
#define FA_VERSION_DRV FA_VERSION_BLD
#define FA_VERSION_MAJ(_VER) ((_VER >> 24) & 0xFF)
#define FA_VERSION_MIN(_VER) ((_VER >> 16) & 0xFF)
#define FA_VERSION_PATCH(_VER) (_VER & 0xFFFF)
#define PCI_VENDOR_ID_CERN (0x10DC)
#define FA_META_VENDOR_ID PCI_VENDOR_ID_CERN
#define FA_META_DEVICE_ID_SPEC 0x41444301
#define FA_META_DEVICE_ID_SVEC_DBL_ADC 0x41444302
#endif
/* FMC_ADC_H_ */
#endif
/* FMC_ADC_H_ */
software/kernel/platform_data/fmc-adc-100m14b4cha.h
View file @
05bbebf8
...
@@ -7,9 +7,8 @@
...
@@ -7,9 +7,8 @@
#ifndef __FMC_ADC_PDATA_H__
#ifndef __FMC_ADC_PDATA_H__
#define __FMC_ADC_PDATA_H__
#define __FMC_ADC_PDATA_H__
#define FMC_ADC_BIG_ENDIAN BIT(0)
#define FMC_ADC_BIG_ENDIAN BIT(0)
/* Registers are in BIG ENDIAN */
#define FMC_ADC_NOSQUASH_SCATTERLIST BIT(1)
#define FMC_ADC_NOSQUASH_SCATTERLIST BIT(1)
#define FMC_ADC_DATA_NO_SWAP BIT(2)
/*
/*
* In principle this should not be necessary. The two variants should
* In principle this should not be necessary. The two variants should
...
...
software/kernel/spi.c
View file @
05bbebf8
...
@@ -49,7 +49,7 @@ int fa_spi_xfer(struct fa_dev *fa, int cs, int num_bits,
...
@@ -49,7 +49,7 @@ int fa_spi_xfer(struct fa_dev *fa, int cs, int num_bits,
/* Wait transfer complete */
/* Wait transfer complete */
while
(
fa_ioread
(
fa
,
fa
->
fa_spi_base
+
FA_SPI_CTRL
)
while
(
fa_ioread
(
fa
,
fa
->
fa_spi_base
+
FA_SPI_CTRL
)
&
FA_SPI_CTRL_BUSY
)
{
&
FA_SPI_CTRL_BUSY
)
{
if
(
jiffies
>
j
)
{
if
(
time_after
(
jiffies
,
j
)
)
{
dev_err
(
fa
->
msgdev
,
"SPI transfer error cs:%d, ctrl: 0x%x
\n
"
,
dev_err
(
fa
->
msgdev
,
"SPI transfer error cs:%d, ctrl: 0x%x
\n
"
,
cs
,
fa_ioread
(
fa
,
fa
->
fa_spi_base
+
FA_SPI_CTRL
));
cs
,
fa_ioread
(
fa
,
fa
->
fa_spi_base
+
FA_SPI_CTRL
));
err
=
-
EIO
;
err
=
-
EIO
;
...
@@ -77,11 +77,14 @@ int fa_spi_init(struct fa_dev *fa)
...
@@ -77,11 +77,14 @@ int fa_spi_init(struct fa_dev *fa)
/* software reset the ADC chip (register 0) */
/* software reset the ADC chip (register 0) */
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
BIT
(
7
),
&
rx
);
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
BIT
(
7
),
&
rx
);
msleep
(
5
);
msleep
(
20
);
/* Force 2's complement data output (register 1, bit 5) */
/* Force 2's complement data output (register 1, bit 5) */
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
BIT
(
8
)
|
BIT
(
5
),
&
rx
);
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
BIT
(
8
)
|
BIT
(
5
),
&
rx
);
/* 2 lanes, 14-bit serializaion (register 2) */
fa_spi_xfer
(
fa
,
FA_SPI_SS_ADC
,
16
,
(
2
<<
8
)
|
0x1
,
&
rx
);
return
0
;
return
0
;
}
}
...
...
software/tools/Makefile
View file @
05bbebf8
...
@@ -19,6 +19,7 @@ CFLAGS += -I../kernel -Wno-trigraphs -Wall -Werror -ggdb -O2 $(EXTRACFLAGS)
...
@@ -19,6 +19,7 @@ CFLAGS += -I../kernel -Wno-trigraphs -Wall -Werror -ggdb -O2 $(EXTRACFLAGS)
CFLAGS
+=
-DGIT_VERSION
=
"
\"
$(GIT_VERSION)
\"
"
CFLAGS
+=
-DGIT_VERSION
=
"
\"
$(GIT_VERSION)
\"
"
CPPCHECK
?=
cppcheck
CPPCHECK
?=
cppcheck
FLAWFINDER
?=
flawfinder
CC
?=
$(CROSS_COMPILE)
gcc
CC
?=
$(CROSS_COMPILE)
gcc
progs
:=
fau-trg-config
progs
:=
fau-trg-config
...
@@ -45,3 +46,6 @@ install:
...
@@ -45,3 +46,6 @@ install:
cppcheck
:
cppcheck
:
$(CPPCHECK)
-q
-I
.
--suppress
=
missingIncludeSystem
--enable
=
all
*
.c
*
.h
--error-exitcode
=
1
$(CPPCHECK)
-q
-I
.
--suppress
=
missingIncludeSystem
--enable
=
all
*
.c
*
.h
--error-exitcode
=
1
flawfinder
:
$(FLAWFINDER)
-SQDC
--error-level
=
4 .
software/tools/fau-acq-time.c
View file @
05bbebf8
...
@@ -17,9 +17,10 @@
...
@@ -17,9 +17,10 @@
static
char
git_version
[]
=
"version: "
GIT_VERSION
;
static
char
git_version
[]
=
"version: "
GIT_VERSION
;
#define buf_len 50
#define path_len 200
#define base_len 40
/* user will edit by adding the device name */
/* user will edit by adding the device name */
char
basepath
[
40
]
=
"/sys/bus/zio/devices/"
;
char
basepath
[
base_len
]
=
"/sys/bus/zio/devices/"
;
enum
fau_attribute
{
enum
fau_attribute
{
FAU_UTR_STR_S
,
FAU_UTR_STR_S
,
...
@@ -55,10 +56,10 @@ const char *attribute[] = {
...
@@ -55,10 +56,10 @@ const char *attribute[] = {
/* Write a sysfs attribute */
/* Write a sysfs attribute */
int
fau_read_attribute
(
enum
fau_attribute
attr
,
long
*
val
)
int
fau_read_attribute
(
enum
fau_attribute
attr
,
long
*
val
)
{
{
char
fullpath
[
200
];
char
fullpath
[
path_len
];
FILE
*
f
;
FILE
*
f
;
s
printf
(
fullpath
,
"%s%s"
,
basepath
,
attribute
[
attr
]);
s
nprintf
(
fullpath
,
path_len
,
"%s%s"
,
basepath
,
attribute
[
attr
]);
f
=
fopen
(
fullpath
,
"r"
);
f
=
fopen
(
fullpath
,
"r"
);
if
(
!
f
)
if
(
!
f
)
return
-
1
;
return
-
1
;
...
@@ -153,7 +154,7 @@ int main(int argc, char *argv[])
...
@@ -153,7 +154,7 @@ int main(int argc, char *argv[])
exit
(
1
);
exit
(
1
);
}
}
str
cat
(
basepath
,
argv
[
argc
-
1
]
);
str
ncat
(
basepath
,
argv
[
argc
-
1
],
base_len
);
printf
(
"Sysfs path to device is: %s
\n
"
,
basepath
);
printf
(
"Sysfs path to device is: %s
\n
"
,
basepath
);
if
(
last
)
{
if
(
last
)
{
...
...
software/tools/fau-calibration.c
View file @
05bbebf8
...
@@ -18,28 +18,32 @@
...
@@ -18,28 +18,32 @@
#include <fmc-adc-100m14b4cha.h>
#include <fmc-adc-100m14b4cha.h>
#define MAX_OPT_NR 5
static
char
options
[]
=
"hf:o:D:b"
;
static
char
options
[]
=
"hf:o:D:b"
;
static
const
char
help_msg
[]
=
"Usage: fau-calibration [options]
\n
"
static
void
fau_calibration_help
(
void
)
"
\n
"
{
"It reads calibration data from a file that contains it in binary
\n
"
fputs
(
"Usage: fau-calibration [options]
\n
"
"form and it shows it on STDOUT in binary form or in human readable
\n
"
"
\n
"
"one (default).
\n
"
"It reads calibration data from a file that contains it in binary
\n
"
"This could be used to change the ADC calibration data at runtime
\n
"
"form and it shows it on STDOUT in binary form or in human readable
\n
"
"by redirectiong the binary output of this program to the proper
\n
"
"one (default).
\n
"
"sysfs binary attribute
\n
"
"This could be used to change the ADC calibration data at runtime
\n
"
"Rembember that we expect all values to be little endian
\n
"
"by redirectiong the binary output of this program to the proper
\n
"
"
\n
"
"sysfs binary attribute
\n
"
"General options:
\n
"
"Rembember that we expect all values to be little endian
\n
"
"-h Print this message
\n
"
"
\n
"
"-b Show Calibration in binary form
\n
"
"General options:
\n
"
"
\n
"
"-h Print this message
\n
"
"Read options:
\n
"
"-b Show Calibration in binary form
\n
"
"-f Source file where to read calibration data from
\n
"
"
\n
"
"-o Offset in bytes within the file (default 0)
\n
"
"Read options:
\n
"
"Write options:
\n
"
"-f Source file where to read calibration data from
\n
"
"-D FMC ADC Target Device ID
\n
"
"-o Offset in bytes within the file (default 0)
\n
"
"
\n
"
;
"Write options:
\n
"
"-D FMC ADC Target Device ID
\n
"
"
\n
"
,
stdout
);
}
/**
/**
* Read calibration data from file
* Read calibration data from file
...
@@ -49,7 +53,7 @@ static const char help_msg[] =
...
@@ -49,7 +53,7 @@ static const char help_msg[] =
*
*
* Return: number of bytes read
* Return: number of bytes read
*/
*/
static
int
fau_calibration_read
(
char
*
path
,
struct
fa_calib
*
calib
,
static
int
fau_calibration_read
(
c
onst
c
har
*
path
,
struct
fa_calib
*
calib
,
off_t
offset
)
off_t
offset
)
{
{
int
fd
;
int
fd
;
...
@@ -59,8 +63,13 @@ static int fau_calibration_read(char *path, struct fa_calib *calib,
...
@@ -59,8 +63,13 @@ static int fau_calibration_read(char *path, struct fa_calib *calib,
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
1
;
return
-
1
;
ret
=
lseek
(
fd
,
offset
,
SEEK_SET
);
ret
=
lseek
(
fd
,
offset
,
SEEK_SET
);
if
(
ret
>=
0
)
if
(
ret
>=
0
)
{
ret
=
read
(
fd
,
calib
,
sizeof
(
*
calib
));
ret
=
read
(
fd
,
calib
,
sizeof
(
*
calib
));
if
(
ret
!=
sizeof
(
*
calib
))
{
ret
=
-
1
;
errno
=
EINVAL
;
}
}
close
(
fd
);
close
(
fd
);
return
ret
;
return
ret
;
...
@@ -121,11 +130,11 @@ static int fau_calibration_dump_machine(struct fa_calib *calib)
...
@@ -121,11 +130,11 @@ static int fau_calibration_dump_machine(struct fa_calib *calib)
*/
*/
static
int
fau_calibration_write
(
unsigned
int
devid
,
struct
fa_calib
*
calib
)
static
int
fau_calibration_write
(
unsigned
int
devid
,
struct
fa_calib
*
calib
)
{
{
char
path
[
128
];
char
path
[
55
];
// store exactly the path we need
int
fd
;
int
fd
;
int
ret
;
int
ret
;
s
printf
(
path
,
s
nprintf
(
path
,
sizeof
(
path
)
,
"/sys/bus/zio/devices/adc-100m14b-%04x/calibration_data"
,
"/sys/bus/zio/devices/adc-100m14b-%04x/calibration_data"
,
devid
);
devid
);
...
@@ -148,11 +157,24 @@ int main(int argc, char *argv[])
...
@@ -148,11 +157,24 @@ int main(int argc, char *argv[])
int
show_bin
=
0
,
write
=
0
;
int
show_bin
=
0
,
write
=
0
;
struct
fa_calib
calib
;
struct
fa_calib
calib
;
if
(
argc
<=
0
)
{
fprintf
(
stderr
,
"What is going on here?
\n
"
);
exit
(
EXIT_FAILURE
);
}
if
(
argc
>
MAX_OPT_NR
)
{
fprintf
(
stderr
,
"This program accepts no more that %d arguments, you provides %d
\n
"
,
MAX_OPT_NR
,
argc
);
fau_calibration_help
();
exit
(
EXIT_FAILURE
);
}
while
((
c
=
getopt
(
argc
,
argv
,
options
))
!=
-
1
)
{
while
((
c
=
getopt
(
argc
,
argv
,
options
))
!=
-
1
)
{
switch
(
c
)
{
switch
(
c
)
{
default:
default:
case
'h'
:
case
'h'
:
f
printf
(
stderr
,
help_msg
);
f
au_calibration_help
(
);
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
case
'D'
:
case
'D'
:
ret
=
sscanf
(
optarg
,
"0x%x"
,
&
devid
);
ret
=
sscanf
(
optarg
,
"0x%x"
,
&
devid
);
...
...
software/tools/fau-trg-config.c
View file @
05bbebf8
...
@@ -12,16 +12,20 @@
...
@@ -12,16 +12,20 @@
#include <stdlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdint.h>
#include <getopt.h>
#include <getopt.h>
#include <errno.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <fcntl.h>
#include <errno.h>
#include <errno.h>
static
char
git_version
[]
=
"version: "
GIT_VERSION
;
static
char
git_version
[]
=
"version: "
GIT_VERSION
;
#define path_len 200
#define buf_len 50
#define buf_len 50
#define base_len 40
/* user will edit by adding the device name */
/* user will edit by adding the device name */
char
basepath
[
40
]
=
"/sys/bus/zio/devices/"
;
char
basepath
[
base_len
]
=
"/sys/bus/zio/devices/"
;
enum
fau_attribute
{
enum
fau_attribute
{
FAU_TRG_EN
,
FAU_TRG_EN
,
...
@@ -54,19 +58,21 @@ const char *attribute[] = {
...
@@ -54,19 +58,21 @@ const char *attribute[] = {
int
fau_write_attribute
(
enum
fau_attribute
attr
,
uint32_t
val
)
int
fau_write_attribute
(
enum
fau_attribute
attr
,
uint32_t
val
)
{
{
int
ret
,
fd
;
int
ret
,
fd
;
char
buf
[
buf_len
],
fullpath
[
200
];
char
buf
[
buf_len
],
fullpath
[
path_len
];
/* convert val to string */
/* convert val to string */
s
printf
(
buf
,
"%u"
,
val
);
s
nprintf
(
buf
,
buf_len
,
"%u"
,
val
);
/* build the attribute path */
/* build the attribute path */
strcpy
(
fullpath
,
basepath
);
strncpy
(
fullpath
,
basepath
,
path_len
);
strcat
(
fullpath
,
attribute
[
attr
]);
if
(
path_len
>
0
)
fullpath
[
path_len
-
1
]
=
'\0'
;
strncat
(
fullpath
,
attribute
[
attr
],
path_len
);
/* Write the attribute */
/* Write the attribute */
printf
(
"Writing %s in %s
\n
"
,
buf
,
fullpath
);
printf
(
"Writing %s in %s
\n
"
,
buf
,
fullpath
);
fd
=
open
(
fullpath
,
O_WRONLY
);
fd
=
open
(
fullpath
,
O_WRONLY
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
ENOENT
;
return
-
ENOENT
;
ret
=
write
(
fd
,
buf
,
str
len
(
buf
));
ret
=
write
(
fd
,
buf
,
str
nlen
(
buf
,
buf_len
));
close
(
fd
);
close
(
fd
);
return
ret
;
return
ret
;
}
}
...
@@ -102,6 +108,19 @@ static void print_version(char *pname)
...
@@ -102,6 +108,19 @@ static void print_version(char *pname)
printf
(
"%s %s
\n
"
,
pname
,
git_version
);
printf
(
"%s %s
\n
"
,
pname
,
git_version
);
}
}
static
long
strtol_or_die
(
const
char
*
arg
)
{
long
val
=
strtol
(
arg
,
NULL
,
0
);
if
((
errno
==
ERANGE
&&
(
val
==
LONG_MAX
||
val
==
LONG_MIN
))
||
(
errno
!=
0
&&
val
==
0
))
{
fprintf
(
stderr
,
"Can't convert
\"
%s
\"
to integer
\n
"
,
optarg
);
exit
(
EXIT_FAILURE
);
}
return
val
;
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
/* default attribute */
/* default attribute */
...
@@ -137,22 +156,22 @@ int main(int argc, char *argv[])
...
@@ -137,22 +156,22 @@ int main(int argc, char *argv[])
options
,
&
opt_index
))
>=
0
){
options
,
&
opt_index
))
>=
0
){
switch
(
c
){
switch
(
c
){
case
'p'
:
case
'p'
:
attrval
[
FAU_TRG_PRE
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_PRE
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
'P'
:
case
'P'
:
attrval
[
FAU_TRG_PST
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_PST
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
'n'
:
case
'n'
:
attrval
[
FAU_TRG_RE_EN
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_RE_EN
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
'd'
:
case
'd'
:
attrval
[
FAU_TRG_DLY
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_DLY
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
't'
:
case
't'
:
attrval
[
FAU_TRG_THR
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_THR
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
'c'
:
case
'c'
:
attrval
[
FAU_TRG_CHN
]
=
atoi
(
optarg
);
attrval
[
FAU_TRG_CHN
]
=
strtol_or_die
(
optarg
);
break
;
break
;
case
'V'
:
case
'V'
:
print_version
(
argv
[
0
]);
print_version
(
argv
[
0
]);
...
@@ -171,7 +190,7 @@ int main(int argc, char *argv[])
...
@@ -171,7 +190,7 @@ int main(int argc, char *argv[])
exit
(
1
);
exit
(
1
);
}
}
str
cat
(
basepath
,
argv
[
optind
]
);
str
ncat
(
basepath
,
argv
[
optind
],
base_len
);
printf
(
"Sysfs path to device is: %s
\n
"
,
basepath
);
printf
(
"Sysfs path to device is: %s
\n
"
,
basepath
);
for
(
i
=
0
;
i
<
FAU_TRIG_NUM_ATTR
;
++
i
)
{
for
(
i
=
0
;
i
<
FAU_TRIG_NUM_ATTR
;
++
i
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment