Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DEL 1ns 4cha - 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 DEL 1ns 4cha - Software
Commits
dc59bb4f
Commit
dc59bb4f
authored
Apr 22, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
onewire: copied tom's code, not fully working here
parent
315877b3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
238 additions
and
1 deletion
+238
-1
fd-core.c
fd-core.c
+4
-1
fine-delay.h
fine-delay.h
+12
-0
onewire.c
onewire.c
+222
-0
No files found.
fd-core.c
View file @
dc59bb4f
...
...
@@ -74,7 +74,7 @@ static struct modlist mods[] = {
SUBSYS
(
spi
),
SUBSYS
(
gpio
),
SUBSYS
(
pll
),
//SUBSYS(w1
),
SUBSYS
(
onewire
),
{
"gpio-default"
,
fd_gpio_defaults
},
{
"reset-again"
,
fd_reset_again
},
//SUBSYS(acam),
...
...
@@ -100,12 +100,15 @@ int fd_probe(struct spec_dev *dev)
fd
->
spec
=
dev
;
fd
->
base
=
dev
->
remap
[
0
];
fd
->
regs
=
fd
->
base
+
FD_REGS_OFFSET
;
fd
->
ow_regs
=
fd
->
regs
+
0x500
;
/* First, hardware reset */
fd_do_reset
(
fd
,
1
);
/* init all subsystems */
for
(
i
=
0
,
m
=
mods
;
i
<
ARRAY_SIZE
(
mods
);
i
++
,
m
++
)
{
pr_debug
(
"%s: Calling init for
\"
%s
\"\n
"
,
__func__
,
m
->
name
);
ret
=
m
->
init
(
fd
);
if
(
ret
<
0
)
{
pr_err
(
"%s: error initializing %s
\n
"
,
__func__
,
...
...
fine-delay.h
View file @
dc59bb4f
...
...
@@ -5,6 +5,7 @@ struct spec_fd {
struct
spec_dev
*
spec
;
unsigned
char
__iomem
*
base
;
/* regs files are byte-oriented */
unsigned
char
__iomem
*
regs
;
unsigned
char
__iomem
*
ow_regs
;
int
acam_addr
;
/* cache of currently active addr */
};
...
...
@@ -14,6 +15,12 @@ struct spec_fd {
#define ACAM_DESIRED_BIN 80.9553
#define ACAM_CLOCK_FREQ_KHZ 31250
/* ACAM TDC operation modes */
enum
fd_acam_modes
{
ACAM_RMODE
,
ACAM_IMODE
};
/*
* You can change the following value to have a pll with smaller divisor,
* at the cost of potentially less precision in the desired bin value.
...
...
@@ -50,6 +57,11 @@ extern void fd_spi_exit(struct spec_fd *fd);
extern
int
fd_pll_init
(
struct
spec_fd
*
fd
);
extern
void
fd_pll_exit
(
struct
spec_fd
*
fd
);
/* Functions exported by onewire.c */
extern
int
fd_onewire_init
(
struct
spec_fd
*
fd
);
extern
void
fd_onewire_exit
(
struct
spec_fd
*
fd
);
extern
int
fd_read_temp
(
struct
spec_fd
*
fd
);
/* Functions exported by gpio.c */
extern
int
fd_gpio_init
(
struct
spec_fd
*
fd
);
extern
void
fd_gpio_exit
(
struct
spec_fd
*
fd
);
...
...
onewire.c
View file @
dc59bb4f
/*
* Access to 1w thermometer
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include <linux/jiffies.h>
#include <linux/io.h>
#include "fine-delay.h"
#include "hw/fd_main_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)
static
void
ow_writel
(
struct
spec_fd
*
fd
,
uint32_t
val
,
unsigned
long
reg
)
{
writel
(
val
,
fd
->
ow_regs
+
reg
);
}
static
uint32_t
ow_readl
(
struct
spec_fd
*
fd
,
unsigned
long
reg
)
{
return
readl
(
fd
->
ow_regs
+
reg
);
}
static
int
ow_reset
(
struct
spec_fd
*
fd
,
int
port
)
{
uint32_t
reg
,
data
;
data
=
((
port
<<
CSR_SEL_OFS
)
&
CSR_SEL_MSK
)
|
CSR_CYC_MSK
|
CSR_RST_MSK
;
ow_writel
(
fd
,
data
,
R_CSR
);
while
(
ow_readl
(
fd
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
fd
,
R_CSR
);
return
~
reg
&
CSR_DAT_MSK
;
}
static
int
slot
(
struct
spec_fd
*
fd
,
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
(
fd
,
data
,
R_CSR
);
while
(
ow_readl
(
fd
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
fd
,
R_CSR
);
return
reg
&
CSR_DAT_MSK
;
}
static
int
read_bit
(
struct
spec_fd
*
fd
,
int
port
)
{
return
slot
(
fd
,
port
,
0x1
);
}
static
int
write_bit
(
struct
spec_fd
*
fd
,
int
port
,
int
bit
)
{
return
slot
(
fd
,
port
,
bit
);
}
static
int
ow_read_byte
(
struct
spec_fd
*
fd
,
int
port
)
{
int
data
=
0
,
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
data
|=
(
read_bit
(
fd
,
port
)
<<
i
);
return
data
;
}
static
int
ow_write_byte
(
struct
spec_fd
*
fd
,
int
port
,
int
byte
)
{
int
data
=
0
;
int
byte_old
=
byte
,
i
;
for
(
i
=
0
;
i
<
8
;
i
++
){
data
|=
write_bit
(
fd
,
port
,
(
byte
&
0x1
))
<<
i
;
byte
>>=
1
;
}
return
byte_old
==
data
?
0
:
-
1
;
}
static
int
ow_write_block
(
struct
spec_fd
*
fd
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
ow_write_byte
(
fd
,
port
,
block
[
i
]);
return
0
;
}
static
int
ow_read_block
(
struct
spec_fd
*
fd
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
block
[
i
]
=
ow_read_byte
(
fd
,
port
);
return
0
;
}
#define ROM_SEARCH 0xF0
#define ROM_READ 0x33
#define ROM_MATCH 0x55
#define ROM_SKIP 0xCC
#define ROM_ALARM_SEARCH 0xEC
#define CONVERT_TEMP 0x44
#define WRITE_SCRATCHPAD 0x4E
#define READ_SCRATCHPAD 0xBE
#define COPY_SCRATCHPAD 0x48
#define RECALL_EEPROM 0xB8
#define READ_POWER_SUPPLY 0xB4
static
uint8_t
ds18x_id
[
8
];
static
int
ds18x_read_serial
(
struct
spec_fd
*
fd
,
uint8_t
*
id
)
{
int
i
;
if
(
!
ow_reset
(
fd
,
0
))
return
-
EIO
;
ow_write_byte
(
fd
,
0
,
ROM_READ
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
*
id
=
ow_read_byte
(
fd
,
0
);
id
++
;
}
return
0
;
}
static
int
ds18x_access
(
struct
spec_fd
*
fd
,
uint8_t
*
id
)
{
int
i
;
if
(
!
ow_reset
(
fd
,
0
))
return
-
EIO
;
if
(
ow_write_byte
(
fd
,
0
,
ROM_MATCH
)
<
0
)
return
-
EIO
;
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
ow_write_byte
(
fd
,
0
,
id
[
i
])
<
0
)
return
-
EIO
;
return
0
;
}
static
int
ds18x_read_temp
(
struct
spec_fd
*
fd
,
int
*
temp_r
)
{
int
i
,
temp
;
uint8_t
data
[
9
];
if
(
ds18x_access
(
fd
,
ds18x_id
)
<
0
)
return
-
1
;
ow_write_byte
(
fd
,
0
,
READ_SCRATCHPAD
);
for
(
i
=
0
;
i
<
9
;
i
++
)
data
[
i
]
=
ow_read_byte
(
fd
,
0
);
temp
=
((
int
)
data
[
1
]
<<
8
)
|
((
int
)
data
[
0
]);
if
(
temp
&
0x1000
)
temp
=
-
0x10000
+
temp
;
ds18x_access
(
fd
,
ds18x_id
);
ow_write_byte
(
fd
,
0
,
CONVERT_TEMP
);
if
(
temp_r
)
*
temp_r
=
temp
;
return
0
;
}
int
fd_read_temp
(
struct
spec_fd
*
fd
)
{
int
i
;
//ow_init(dev);
if
(
ds18x_read_serial
(
fd
,
ds18x_id
)
<
0
)
return
-
EIO
;
pr_debug
(
"%s: Found DS18xx sensor: "
,
__func__
);
for
(
i
=
0
;
i
<
8
;
i
++
)
printk
(
"%02x%c"
,
ds18x_id
[
i
],
i
==
7
?
'\n'
:
':'
);
return
ds18x_read_temp
(
fd
,
NULL
);
}
int
fd_onewire_init
(
struct
spec_fd
*
fd
)
{
int
temp
;
ow_writel
(
fd
,
((
CLK_DIV_NOR
&
CDR_NOR_MSK
)
|
((
CLK_DIV_OVD
<<
CDR_OVD_OFS
)
&
CDR_OVD_MSK
)),
R_CDR
);
temp
=
fd_read_temp
(
fd
);
printk
(
"temp: %x
\n
"
,
temp
);
return
0
;
}
void
fd_onewire_exit
(
struct
spec_fd
*
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