Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC TDC 1ns 5cha - Software
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 TDC 1ns 5cha - Software
Commits
3f262454
Commit
3f262454
authored
Sep 11, 2018
by
Tomasz Wlostowski
Committed by
Federico Vaga
Sep 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel: use hardware DS18xx interface to read ID/temperature
parent
b71af2ab
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
259 deletions
+96
-259
Kbuild
kernel/Kbuild
+1
-1
fmc-tdc.h
kernel/fmc-tdc.h
+2
-4
ft-core.c
kernel/ft-core.c
+0
-1
ft-zio.c
kernel/ft-zio.c
+37
-1
tdc_onewire_regs.h
kernel/hw/tdc_onewire_regs.h
+56
-0
onewire.c
kernel/onewire.c
+0
-252
No files found.
kernel/Kbuild
View file @
3f262454
...
...
@@ -38,5 +38,5 @@ subdirs-ccflags-y = $(ccflags-y)
obj-m := fmc-tdc.o
fmc-tdc-objs = acam.o calibration.o fmc-util.o \
ft-core.o
onewire.o
ft-time.o ft-irq.o ft-zio.o\
ft-core.o ft-time.o ft-irq.o ft-zio.o\
fmc-bus-link/sdb-lib/access.o fmc-bus-link/sdb-lib/glue.o
kernel/fmc-tdc.h
View file @
3f262454
...
...
@@ -161,6 +161,7 @@ static inline struct fmctdc_trig *to_fmctdc_trig(struct zio_ti *ti_ptr)
/*
* Main TDC device context
* @unique_id unique identifier from the temperature sensor
* @lock it protects: irq_imr (irq vs user), offset (user vs user),
* wr_mode (user vs user)
* @irq_imr it holds the IMR value since our last modification
...
...
@@ -170,6 +171,7 @@ static inline struct fmctdc_trig *to_fmctdc_trig(struct zio_ti *ti_ptr)
* place where we use it: so, we do not need to protect it.
*/
struct
fmctdc_dev
{
uint64_t
unique_id
;
enum
ft_transfer_mode
mode
;
/* HW buffer/FIFO access lock */
spinlock_t
lock
;
...
...
@@ -249,10 +251,6 @@ void ft_enable_acquisition(struct fmctdc_dev *ft, int enable);
int
ft_acam_init
(
struct
fmctdc_dev
*
ft
);
void
ft_acam_exit
(
struct
fmctdc_dev
*
ft
);
int
ft_onewire_init
(
struct
fmctdc_dev
*
ft
);
void
ft_onewire_exit
(
struct
fmctdc_dev
*
ft
);
int
ft_read_temp
(
struct
fmctdc_dev
*
ft
,
int
verbose
);
int
ft_pll_init
(
struct
fmctdc_dev
*
ft
);
void
ft_pll_exit
(
struct
fmctdc_dev
*
ft
);
...
...
kernel/ft-core.c
View file @
3f262454
...
...
@@ -242,7 +242,6 @@ struct ft_modlist {
static
struct
ft_modlist
init_subsystems
[]
=
{
{
"acam-tdc"
,
ft_acam_init
,
ft_acam_exit
},
{
"onewire"
,
ft_onewire_init
,
ft_onewire_exit
},
{
"time"
,
ft_time_init
,
ft_time_exit
},
{
"channels"
,
ft_channels_init
,
ft_channels_exit
},
{
"zio"
,
ft_zio_init
,
ft_zio_exit
}
...
...
kernel/ft-zio.c
View file @
3f262454
...
...
@@ -25,6 +25,8 @@
#include "fmc-tdc.h"
#include "hw/timestamp_fifo_regs.h"
#include "hw/tdc_onewire_regs.h"
/* The sample size. Mandatory, device-wide */
ZIO_ATTR_DEFINE_STD
(
ZIO_DEV
,
ft_zattr_dev_std
)
=
{
...
...
@@ -169,6 +171,35 @@ static int ft_raw_mode_get(struct fmctdc_dev *ft,
}
static
int
ft_temperature_get
(
struct
fmctdc_dev
*
ft
,
int
*
temp
)
{
int
stat
=
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
TDC_OW_REG_CSR
);
if
(
!
(
stat
&
TDC_OW_CSR_VALID
))
return
-
EIO
;
*
temp
=
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
TDC_OW_REG_TEMP
);
return
0
;
}
static
int
ft_unique_id_get
(
struct
fmctdc_dev
*
ft
,
uint64_t
*
id
)
{
int
stat
=
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
TDC_OW_REG_CSR
);
uint32_t
tmp_l
,
tmp_h
;
if
(
!
(
stat
&
TDC_OW_CSR_VALID
)
)
return
-
EIO
;
tmp_l
=
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
TDC_OW_REG_ID_L
);
tmp_h
=
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
TDC_OW_REG_ID_H
);
*
id
=
((
uint64_t
)
tmp_h
<<
32
)
|
tmp_l
;
return
0
;
}
/* TDC input attributes: only the user offset is special */
static
int
ft_zio_info_channel
(
struct
device
*
dev
,
struct
zio_attribute
*
zattr
,
uint32_t
*
usr_val
)
...
...
@@ -214,6 +245,7 @@ static int ft_zio_info_get(struct device *dev, struct zio_attribute *zattr,
struct
zio_device
*
zdev
;
struct
fmctdc_dev
*
ft
;
struct
zio_attribute
*
attr
;
int
ret
;
if
(
__ft_get_type
(
dev
)
==
FT_TYPE_INPUT
)
return
ft_zio_info_channel
(
dev
,
zattr
,
usr_val
);
...
...
@@ -224,7 +256,9 @@ static int ft_zio_info_get(struct device *dev, struct zio_attribute *zattr,
switch
(
zattr
->
id
)
{
case
FT_ATTR_PARAM_TEMP
:
ft_read_temp
(
ft
,
ft
->
verbose
);
ret
=
ft_temperature_get
(
ft
,
&
ft
->
temp
);
if
(
ret
<
0
)
return
ret
;
*
usr_val
=
ft
->
temp
;
break
;
case
FT_ATTR_DEV_COARSE
:
...
...
@@ -685,6 +719,8 @@ int ft_zio_init(struct fmctdc_dev *ft)
ft_update_offsets
(
ft
,
i
);
}
ft_unique_id_get
(
ft
,
&
ft
->
unique_id
);
return
0
;
err_dev_reg:
...
...
kernel/hw/tdc_onewire_regs.h
0 → 100644
View file @
3f262454
/*
Register definitions for slave core: TDC Onewire Master
* File : tdc_onewire_regs.h
* Author : auto-generated by wbgen2 from wbgen/tdc_onewire_wb.wb
* Created : Tue Sep 11 11:16:49 2018
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_onewire_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_TDC_ONEWIRE_WB_WB
#define __WBGEN2_REGDEFS_TDC_ONEWIRE_WB_WB
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: Temperature & ID valid in reg: Status Register */
#define TDC_OW_CSR_VALID WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Board Temperature */
/* definitions for register: Board Unique ID (MSW) */
/* definitions for register: Board Unique ID (LSW) */
/* [0x0]: REG Status Register */
#define TDC_OW_REG_CSR 0x00000000
/* [0x4]: REG Board Temperature */
#define TDC_OW_REG_TEMP 0x00000004
/* [0x8]: REG Board Unique ID (MSW) */
#define TDC_OW_REG_ID_H 0x00000008
/* [0xc]: REG Board Unique ID (LSW) */
#define TDC_OW_REG_ID_L 0x0000000c
#endif
kernel/onewire.c
deleted
100644 → 0
View file @
b71af2ab
/*
* Access to a DS182x 1-Wire thermometers.
*
* Copyright (C) 2012-2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/delay.h>
#include "fmc-tdc.h"
#include "hw/tdc_regs.h"
#define R_CSR 0x0
#define R_CDR 0x4
#define CSR_DAT_MSK (1<<0)
#define CSR_RST_MSK (1<<1)
#define CSR_OVD_MSK (1<<2)
#define CSR_CYC_MSK (1<<3)
#define CSR_PWR_MSK (1<<4)
#define CSR_IRQ_MSK (1<<6)
#define CSR_IEN_MSK (1<<7)
#define CSR_SEL_OFS 8
#define CSR_SEL_MSK (0xF<<8)
#define CSR_POWER_OFS 16
#define CSR_POWER_MSK (0xFFFF<<16)
#define CDR_NOR_MSK (0xFFFF<<0)
#define CDR_OVD_OFS 16
#define CDR_OVD_MSK (0xFFFF<<16)
#define CLK_DIV_NOR (624/2)
#define CLK_DIV_OVD (124/2)
#define CMD_ROM_SEARCH 0xF0
#define CMD_ROM_READ 0x33
#define CMD_ROM_MATCH 0x55
#define CMD_ROM_SKIP 0xCC
#define CMD_ROM_ALARM_SEARCH 0xEC
#define CMD_CONVERT_TEMP 0x44
#define CMD_WRITE_SCRATCHPAD 0x4E
#define CMD_READ_SCRATCHPAD 0xBE
#define CMD_COPY_SCRATCHPAD 0x48
#define CMD_RECALL_EEPROM 0xB8
#define CMD_READ_POWER_SUPPLY 0xB4
#define FT_OW_PORT 0
/* what is this slow? */
static
void
ow_writel
(
struct
fmctdc_dev
*
ft
,
uint32_t
val
,
unsigned
long
reg
)
{
ft_iowrite
(
ft
,
val
,
ft
->
ft_owregs_base
+
reg
);
}
static
uint32_t
ow_readl
(
struct
fmctdc_dev
*
ft
,
unsigned
long
reg
)
{
return
ft_ioread
(
ft
,
ft
->
ft_owregs_base
+
reg
);
}
static
int
ow_reset
(
struct
fmctdc_dev
*
ft
,
int
port
)
{
uint32_t
reg
,
data
;
data
=
((
port
<<
CSR_SEL_OFS
)
&
CSR_SEL_MSK
)
|
CSR_CYC_MSK
|
CSR_RST_MSK
;
ow_writel
(
ft
,
data
,
R_CSR
);
while
(
ow_readl
(
ft
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
ft
,
R_CSR
);
return
~
reg
&
CSR_DAT_MSK
;
}
static
int
slot
(
struct
fmctdc_dev
*
ft
,
int
port
,
int
bit
)
{
uint32_t
reg
,
data
;
data
=
((
port
<<
CSR_SEL_OFS
)
&
CSR_SEL_MSK
)
|
CSR_CYC_MSK
|
(
bit
&
CSR_DAT_MSK
);
ow_writel
(
ft
,
data
,
R_CSR
);
while
(
ow_readl
(
ft
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
ft
,
R_CSR
);
return
reg
&
CSR_DAT_MSK
;
}
static
int
read_bit
(
struct
fmctdc_dev
*
ft
,
int
port
)
{
return
slot
(
ft
,
port
,
0x1
);
}
static
int
write_bit
(
struct
fmctdc_dev
*
ft
,
int
port
,
int
bit
)
{
return
slot
(
ft
,
port
,
bit
);
}
static
int
ow_read_byte
(
struct
fmctdc_dev
*
ft
,
int
port
)
{
int
byte
=
0
,
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
byte
|=
(
read_bit
(
ft
,
port
)
<<
i
);
return
byte
;
}
static
int
ow_write_byte
(
struct
fmctdc_dev
*
ft
,
int
port
,
int
byte
)
{
int
data
=
0
;
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
data
|=
write_bit
(
ft
,
port
,
(
byte
&
0x1
))
<<
i
;
byte
>>=
1
;
}
return
0
;
/* success */
}
static
int
ow_write_block
(
struct
fmctdc_dev
*
ft
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
ow_write_byte
(
ft
,
port
,
block
[
i
]);
return
0
;
}
static
int
ow_read_block
(
struct
fmctdc_dev
*
ft
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
block
[
i
]
=
ow_read_byte
(
ft
,
port
);
return
0
;
}
static
int
ds18x_read_serial
(
struct
fmctdc_dev
*
ft
)
{
if
(
!
ow_reset
(
ft
,
0
))
{
dev_err
(
&
ft
->
fmc
->
dev
,
"Failure in resetting one-wire channel
\n
"
);
return
-
EIO
;
}
ow_write_byte
(
ft
,
FT_OW_PORT
,
CMD_ROM_READ
);
return
ow_read_block
(
ft
,
FT_OW_PORT
,
ft
->
ds18_id
,
8
);
}
static
int
ds18x_access
(
struct
fmctdc_dev
*
ft
)
{
if
(
!
ow_reset
(
ft
,
0
))
goto
out
;
if
(
0
)
{
/* select the rom among several of them */
if
(
ow_write_byte
(
ft
,
FT_OW_PORT
,
CMD_ROM_MATCH
)
<
0
)
goto
out
;
return
ow_write_block
(
ft
,
FT_OW_PORT
,
ft
->
ds18_id
,
8
);
}
else
{
/* we have one only, so skip rom */
return
ow_write_byte
(
ft
,
FT_OW_PORT
,
CMD_ROM_SKIP
);
}
out:
dev_err
(
&
ft
->
fmc
->
dev
,
"Failure in one-wire communication
\n
"
);
return
-
EIO
;
}
static
void
__temp_command_and_next_t
(
struct
fmctdc_dev
*
ft
,
int
cfg_reg
)
{
int
ms
;
ds18x_access
(
ft
);
ow_write_byte
(
ft
,
FT_OW_PORT
,
CMD_CONVERT_TEMP
);
/* The conversion takes some time, so mark when will it be ready */
ms
=
94
*
(
1
<<
(
cfg_reg
>>
5
));
ft
->
next_t
=
jiffies
+
msecs_to_jiffies
(
ms
);
}
int
ft_read_temp
(
struct
fmctdc_dev
*
ft
,
int
verbose
)
{
int
i
,
temp
;
unsigned
long
j
;
uint8_t
data
[
9
];
struct
device
*
dev
=
&
ft
->
fmc
->
dev
;
/* If first conversion, ask for it first */
if
(
ft
->
next_t
==
0
)
__temp_command_and_next_t
(
ft
,
0x7f
/* we ignore: max time */
);
/* Wait for it to be ready: (FIXME: we need a time policy here) */
j
=
jiffies
;
if
(
time_before
(
j
,
ft
->
next_t
))
{
/* If we cannot sleep, return the previous value */
if
(
in_atomic
())
return
ft
->
temp
;
msleep
(
jiffies_to_msecs
(
ft
->
next_t
-
j
));
}
ds18x_access
(
ft
);
ow_write_byte
(
ft
,
FT_OW_PORT
,
CMD_READ_SCRATCHPAD
);
ow_read_block
(
ft
,
FT_OW_PORT
,
data
,
9
);
if
(
verbose
>
1
)
{
dev_info
(
dev
,
"%s: Scratchpad: "
,
__func__
);
for
(
i
=
0
;
i
<
9
;
i
++
)
printk
(
"%02x%c"
,
data
[
i
],
i
==
8
?
'\n'
:
':'
);
}
temp
=
((
int
)
data
[
1
]
<<
8
)
|
((
int
)
data
[
0
]);
if
(
temp
&
0x1000
)
temp
=
-
0x10000
+
temp
;
ft
->
temp
=
temp
;
ft
->
temp_ready
=
1
;
if
(
verbose
)
{
dev_info
(
dev
,
"%s: Temperature 0x%x (%i bits: %i.%03i)
\n
"
,
__func__
,
temp
,
9
+
(
data
[
4
]
>>
5
),
temp
/
16
,
(
temp
&
0xf
)
*
1000
/
16
);
}
__temp_command_and_next_t
(
ft
,
data
[
4
]);
/* start next conversion */
return
temp
;
}
int
ft_onewire_init
(
struct
fmctdc_dev
*
ft
)
{
int
i
;
ow_writel
(
ft
,
((
CLK_DIV_NOR
&
CDR_NOR_MSK
)
|
((
CLK_DIV_OVD
<<
CDR_OVD_OFS
)
&
CDR_OVD_MSK
)),
R_CDR
);
if
(
ds18x_read_serial
(
ft
)
<
0
)
return
-
EIO
;
if
(
ft
->
verbose
)
{
dev_info
(
&
ft
->
fmc
->
dev
,
"%s: Found DS18xx sensor: "
,
__func__
);
for
(
i
=
0
;
i
<
8
;
i
++
)
printk
(
"%02x%c"
,
ft
->
ds18_id
[
i
],
i
==
7
?
'\n'
:
':'
);
}
/* read the temperature once, to ensure it works, and print it */
ft_read_temp
(
ft
,
ft
->
verbose
);
return
0
;
}
void
ft_onewire_exit
(
struct
fmctdc_dev
*
fd
)
{
/* Nothing to do */
}
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