Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Trigger Distribution
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
White Rabbit Trigger Distribution
Commits
cefbf7b2
Commit
cefbf7b2
authored
Mar 01, 2021
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drivers: add adc-x2
parent
e78a5e9f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
324 additions
and
2 deletions
+324
-2
Kbuild
software/drivers/Kbuild
+6
-0
Makefile
software/drivers/Makefile
+14
-2
wrtd-ref-svec-adc-x2-core.c
software/drivers/wrtd-ref-svec-adc-x2-core.c
+304
-0
No files found.
software/drivers/Kbuild
View file @
cefbf7b2
...
...
@@ -7,16 +7,22 @@ endif
endif
# add versions of used submodules
KBUILD_EXTRA_SYMBOLS += $(FMC_EXTRA_SYMBOLS-y)
ccflags-y += -DADDITIONAL_VERSIONS="$(SUBMODULE_VERSIONS)"
ccflags-y += -DDRV_VERSION=\"$(DRV_VERSION)\"
ccflags-y += -Wall -Werror
ccflags-y += -I$(FMC_ABS)/include
ccflags-y += -I$(ADC_ABS)/software/kernel
obj-m := wrtd-ref-spec150t-adc.o
obj-m += wrtd-ref-svec-tdc-fd.o
obj-m += wrtd-ref-svec-tdc-x2.o
obj-m += wrtd-ref-svec-fd-x2.o
obj-m += wrtd-ref-svec-adc-x2.o
wrtd-ref-spec150t-adc-objs := wrtd-ref-spec150t-adc-core.o
wrtd-ref-svec-tdc-fd-objs := wrtd-ref-svec-tdc-fd-core.o
wrtd-ref-svec-tdc-x2-objs := wrtd-ref-svec-tdc-x2-core.o
wrtd-ref-svec-fd-x2-objs := wrtd-ref-svec-fd-x2-core.o
wrtd-ref-svec-adc-x2-objs := wrtd-ref-svec-adc-x2-core.o
software/drivers/Makefile
View file @
cefbf7b2
...
...
@@ -7,17 +7,29 @@ REPO_PARENT ?= $(shell /bin/pwd)/../..
LINUX
?=
/lib/modules/
$(
shell
uname
-r
)
/build
ifdef
REPO_PARENT
FMC
?=
$(REPO_PARENT)
/fmc-sw
endif
DRV_VERSION
:=
$(
shell
git describe
--always
--dirty
--long
--tags
)
FMC_ABS
?=
$
(
abspath
$(FMC)
)
FMC_EXTRA_SYMBOLS-y
=
$(FMC_ABS)
/drivers/fmc/Module.symvers
ADC_ABS
?=
$
(
abspath
$(FETCHTO)
/fmc-adc-100m14b4cha
)
all
:
modules
.PHONY
:
all modules clean help install modules_install
modules help modules_install
:
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
pwd
)
DRV_VERSION
=
$(DRV_VERSION)
$@
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
pwd
)
DRV_VERSION
=
$(DRV_VERSION)
\
FMC_ABS
=
$(FMC_ABS)
ADC_ABS
=
$(ADC_ABS)
\
FMC_EXTRA_SYMBOLS-y
=
$
(
FMC_EXTRA_SYMBOLS-y
)
$@
install
:
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
pwd
)
DRV_VERSION
=
$(DRV_VERSION)
modules_install
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
pwd
)
DRV_VERSION
=
$(DRV_VERSION)
\
FMC_ABS
=
$(FMC_ABS)
ADC_ABS
=
$(ADC_ABS)
modules_install
# be able to run the "clean" rule even if $(LINUX) is not valid
clean
:
...
...
software/drivers/wrtd-ref-svec-adc-x2-core.c
0 → 100644
View file @
cefbf7b2
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/fmc.h>
#include "platform_data/fmc-adc-100m14b4cha.h"
#define SVEC_FMC_SLOTS 2
/*
* From SVEC but we do not want to add a dependency for these 4 registers
* which should never change by design. If they do, and you end up here:
* sorry! It shouldn't have happened.
*/
#define SVEC_BASE_REGS_CSR 0x40UL
#define SVEC_FPGA_CSR_DDR4_ADDR (SVEC_BASE_REGS_CSR + 0x18)
#define SVEC_FPGA_DDR4_DMA (0x2000)
#define SVEC_FPGA_CSR_DDR5_ADDR (SVEC_BASE_REGS_CSR + 0x1C)
#define SVEC_FPGA_DDR5_DMA (0x3000)
enum
wrtd_adcx2_dev_offsets
{
WRTD_ADCX2_ADC1_MEM_START
=
0x00002000
,
WRTD_ADCX2_ADC1_MEM_END
=
0x00003fff
,
WRTD_ADCX2_ADC2_MEM_START
=
0x00004000
,
WRTD_ADCX2_ADC2_MEM_END
=
0x00005fff
,
WRTD_ADCX2_TRTL_MEM_START
=
0x0001C000
,
WRTD_ADCX2_TRTL_MEM_END
=
0x0003bfff
,
};
static
inline
struct
platform_device
*
platform_device_register_resndata_mask
(
struct
device
*
parent
,
const
char
*
name
,
int
id
,
const
struct
resource
*
res
,
unsigned
int
num
,
const
void
*
data
,
size_t
size
,
u64
dma_mask
)
{
struct
platform_device_info
pdevinfo
=
{
.
parent
=
parent
,
.
name
=
name
,
.
id
=
id
,
.
res
=
res
,
.
num_res
=
num
,
.
data
=
data
,
.
size_data
=
size
,
.
dma_mask
=
dma_mask
,
};
return
platform_device_register_full
(
&
pdevinfo
);
}
static
struct
fmc_adc_platform_data
wrtd_adcx2_pdata
[]
=
{
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
|
FMC_ADC_NOSQUASH_SCATTERLIST
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR4_ADDR
,
.
vme_dma_offset
=
SVEC_FPGA_DDR4_DMA
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
},
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
|
FMC_ADC_NOSQUASH_SCATTERLIST
,
.
vme_reg_offset
=
SVEC_FPGA_CSR_DDR5_ADDR
,
.
vme_dma_offset
=
SVEC_FPGA_DDR5_DMA
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
}
};
static
struct
resource
wrtd_adcx2_res1
[]
=
{
{
.
name
=
"fmc-adc-100m-mem.1"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
WRTD_ADCX2_ADC1_MEM_START
,
.
end
=
WRTD_ADCX2_ADC1_MEM_END
,
},
{
.
name
=
"fmc-adc-100m-dma.1"
,
.
flags
=
IORESOURCE_DMA
,
},
{
.
name
=
"fmc-adc-100m-irq.1"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
0
,
.
end
=
0
,
},
};
static
struct
resource
wrtd_adcx2_res2
[]
=
{
{
.
name
=
"fmc-adc-100m-mem.2"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
WRTD_ADCX2_ADC2_MEM_START
,
.
end
=
WRTD_ADCX2_ADC2_MEM_END
,
},
{
.
name
=
"fmc-adc-100m-dma.2"
,
.
flags
=
IORESOURCE_DMA
,
},
{
.
name
=
"fmc-adc-100m-irq.2"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
1
,
.
end
=
1
,
},
};
static
struct
resource
wrtd_adcx2_trtl_res
[]
=
{
{
.
name
=
"mock-turtle-mem"
,
.
flags
=
IORESOURCE_MEM
,
.
start
=
WRTD_ADCX2_TRTL_MEM_START
,
.
end
=
WRTD_ADCX2_TRTL_MEM_END
,
},
{
.
name
=
"mock-turtle-irq_in"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
2
,
},
{
.
name
=
"mock-turtle-irq_out"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
3
,
},
{
.
name
=
"mock-turtle-irq_con"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
4
,
},
{
.
name
=
"mock-turtle-irq_not"
,
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHLEVEL
,
.
start
=
5
,
},
};
static
struct
resource
*
wrtd_adcx2_res
[]
=
{
wrtd_adcx2_res1
,
wrtd_adcx2_res2
,
};
struct
wrtd_adcx2_data
{
struct
platform_device
*
adc
[
2
];
struct
platform_device
*
trtl
;
};
static
int
wrtd_adcx2_probe
(
struct
platform_device
*
pdev
)
{
struct
wrtd_adcx2_data
*
pdev_data
;
struct
resource
*
rmem
;
int
irq
;
int
i
;
rmem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
rmem
)
{
dev_err
(
&
pdev
->
dev
,
"Missing memory resource
\n
"
);
return
-
EINVAL
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Missing IRQ number
\n
"
);
return
-
EINVAL
;
}
pdev_data
=
kmalloc
(
sizeof
(
*
pdev_data
),
GFP_KERNEL
);
if
(
!
pdev_data
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
SVEC_FMC_SLOTS
;
++
i
)
{
unsigned
int
res_n
=
ARRAY_SIZE
(
wrtd_adcx2_res1
);
struct
resource
res
[
res_n
];
struct
fmc_slot
*
slot
=
fmc_slot_get
(
pdev
->
dev
.
parent
,
i
+
1
);
int
present
;
if
(
IS_ERR
(
slot
))
{
dev_err
(
&
pdev
->
dev
,
"Can't find FMC slot %d err: %ld
\n
"
,
i
+
1
,
PTR_ERR
(
slot
));
continue
;
}
present
=
fmc_slot_present
(
slot
);
fmc_slot_put
(
slot
);
dev_dbg
(
&
pdev
->
dev
,
"FMC slot: %d, present: %d
\n
"
,
i
+
1
,
present
);
if
(
!
present
)
continue
;
memcpy
(
res
,
wrtd_adcx2_res
[
i
],
sizeof
(
res
));
res
[
0
].
parent
=
rmem
;
res
[
0
].
start
+=
rmem
->
start
;
res
[
0
].
end
+=
rmem
->
start
;
res
[
2
].
start
+=
irq
;
pdev_data
->
adc
[
i
]
=
platform_device_register_resndata_mask
(
&
pdev
->
dev
,
"fmc-adc-100m"
,
PLATFORM_DEVID_AUTO
,
res
,
res_n
,
&
wrtd_adcx2_pdata
[
i
],
sizeof
(
wrtd_adcx2_pdata
[
i
]),
DMA_BIT_MASK
(
32
));
if
(
IS_ERR
(
pdev_data
->
adc
[
i
]))
{
dev_err
(
&
pdev
->
dev
,
"Faild to register ADC instance %d
\n
"
,
i
);
pdev_data
->
adc
[
i
]
=
NULL
;
}
}
{
unsigned
int
res_n
=
ARRAY_SIZE
(
wrtd_adcx2_trtl_res
);
struct
resource
res
[
res_n
];
memcpy
(
res
,
wrtd_adcx2_trtl_res
,
sizeof
(
res
));
res
[
0
].
parent
=
rmem
;
res
[
0
].
start
+=
rmem
->
start
;
res
[
0
].
end
+=
rmem
->
start
;
res
[
1
].
start
+=
irq
;
res
[
2
].
start
+=
irq
;
res
[
3
].
start
+=
irq
;
res
[
4
].
start
+=
irq
;
pdev_data
->
trtl
=
platform_device_register_resndata
(
&
pdev
->
dev
,
"mock-turtle"
,
PLATFORM_DEVID_AUTO
,
res
,
res_n
,
NULL
,
0
);
if
(
IS_ERR
(
pdev_data
->
trtl
))
{
dev_err
(
&
pdev
->
dev
,
"Faild to register TRTL instance
\n
"
);
pdev_data
->
trtl
=
NULL
;
}
}
platform_set_drvdata
(
pdev
,
pdev_data
);
return
0
;
}
static
int
wrtd_adcx2_remove
(
struct
platform_device
*
pdev
)
{
struct
wrtd_adcx2_data
*
pdev_data
=
platform_get_drvdata
(
pdev
);
int
i
;
if
(
!
pdev_data
)
return
0
;
for
(
i
=
0
;
i
<
SVEC_FMC_SLOTS
;
++
i
)
if
(
pdev_data
->
adc
[
i
])
platform_device_unregister
(
pdev_data
->
adc
[
i
]);
platform_device_unregister
(
pdev_data
->
trtl
);
kfree
(
pdev_data
);
return
0
;
}
/**
* List of supported platform
*/
enum
wrtd_adcx2_version
{
WRTD_ADCX2_VER
=
0
,
};
static
const
struct
platform_device_id
wrtd_adcx2_id_table
[]
=
{
{
.
name
=
"wrtd-adcx2"
,
.
driver_data
=
WRTD_ADCX2_VER
,
},
{
.
name
=
"id:000010DC57544E05"
,
.
driver_data
=
WRTD_ADCX2_VER
,
},
{
.
name
=
"id:000010dc57544e05"
,
.
driver_data
=
WRTD_ADCX2_VER
,
},
{},
};
static
struct
platform_driver
wrtd_adcx2_driver
=
{
.
driver
=
{
.
name
=
"wrtd-adcx2"
,
.
owner
=
THIS_MODULE
,
},
.
id_table
=
wrtd_adcx2_id_table
,
.
probe
=
wrtd_adcx2_probe
,
.
remove
=
wrtd_adcx2_remove
,
};
module_platform_driver
(
wrtd_adcx2_driver
);
MODULE_AUTHOR
(
"Federico Vaga <federico.vaga@cern.ch>"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_VERSION
(
DRV_VERSION
);
MODULE_DESCRIPTION
(
"Driver for the WRTD SVEC ADCx2"
);
MODULE_DEVICE_TABLE
(
platform
,
wrtd_adcx2_id_table
);
MODULE_SOFTDEP
(
"pre: svec_fmc_carrier fmc-adc-100m14b4ch"
);
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