Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
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 - Software
Commits
33ce2ce4
Commit
33ce2ce4
authored
Aug 06, 2012
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TEMP add onewire (NOT TESTED)
Signed-off-by:
Federico Vaga
<
federico.vaga@gmail.com
>
parent
92318393
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
276 additions
and
6 deletions
+276
-6
Makefile
Makefile
+1
-0
fa-core.c
fa-core.c
+33
-6
onewire.c
onewire.c
+242
-0
No files found.
Makefile
View file @
33ce2ce4
...
...
@@ -18,6 +18,7 @@ spec-fmc-adc-objs = fa-zio-drv.o
spec-fmc-adc-objs
+=
fa-core.o
spec-fmc-adc-objs
+=
fa-zio-trg.o
spec-fmc-adc-objs
+=
fa-dma.o
spec-fmc-adc-objs
+=
onewire.o
all
:
modules
...
...
fa-core.c
View file @
33ce2ce4
...
...
@@ -13,11 +13,25 @@
#include "spec.h"
#include "fmc-adc.h"
/* This structure lists the various subsystems */
struct
fa_modlist
{
char
*
name
;
int
(
*
init
)(
struct
spec_fa
*
);
void
(
*
exit
)(
struct
spec_fa
*
);
};
#define SUBSYS(x) { #x, fa_ ## x ## _init, fa_ ## x ## _exit }
static
struct
fa_modlist
mods
[]
=
{
SUBSYS
(
onewire
),
SUBSYS
(
zio
),
};
/* probe and remove are called by fa-spec.c */
int
fa_probe
(
struct
fmc_device
*
fmc
)
{
struct
fa_modlist
*
m
;
struct
spec_fa
*
fa
;
struct
spec_dev
*
spec
=
fmc
->
carrier_data
;
int
err
;
int
err
,
i
;
pr_info
(
"%s:%d
\n
"
,
__func__
,
__LINE__
);
/* Driver data */
...
...
@@ -29,13 +43,26 @@ int fa_probe(struct fmc_device *fmc)
fa
->
fmc
=
fmc
;
fa
->
base
=
spec
->
remap
[
0
];
/* Initliaze sub-system (FIXME only ZIO at the moment) */
err
=
fa_zio_init
(
fa
);
if
(
err
)
{
devm_kfree
(
&
fmc
->
dev
,
fa
);
return
err
;
/* 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
);
err
=
m
->
init
(
fa
);
if
(
err
)
{
pr_err
(
"%s: error initializing %s
\n
"
,
__func__
,
m
->
name
);
goto
out
;
}
}
return
0
;
out:
while
(
--
m
,
--
i
>=
0
)
if
(
m
->
exit
)
m
->
exit
(
fa
);
devm_kfree
(
&
fmc
->
dev
,
fa
);
return
err
;
}
int
fa_remove
(
struct
fmc_device
*
fmc
)
{
...
...
onewire.c
0 → 100644
View file @
33ce2ce4
/*
* 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/interrupt.h>
#include <linux/io.h>
#include <linux/delay.h>
#include "fmc-adc.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 FD_OW_PORT 0
/* what is this slow? */
static
void
ow_writel
(
struct
spec_fa
*
fa
,
uint32_t
val
,
unsigned
long
reg
)
{
writel
(
val
,
fa
->
base
+
FA_OWI_MEM_OFF
+
reg
);
}
static
uint32_t
ow_readl
(
struct
spec_fa
*
fa
,
unsigned
long
reg
)
{
return
readl
(
fa
->
base
+
FA_OWI_MEM_OFF
+
reg
);
}
static
int
ow_reset
(
struct
spec_fa
*
fa
,
int
port
)
{
uint32_t
reg
,
data
;
data
=
((
port
<<
CSR_SEL_OFS
)
&
CSR_SEL_MSK
)
|
CSR_CYC_MSK
|
CSR_RST_MSK
;
ow_writel
(
fa
,
data
,
R_CSR
);
while
(
ow_readl
(
fa
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
fa
,
R_CSR
);
return
~
reg
&
CSR_DAT_MSK
;
}
static
int
slot
(
struct
spec_fa
*
fa
,
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
(
fa
,
data
,
R_CSR
);
while
(
ow_readl
(
fa
,
R_CSR
)
&
CSR_CYC_MSK
)
/* FIXME: timeout */
;
reg
=
ow_readl
(
fa
,
R_CSR
);
return
reg
&
CSR_DAT_MSK
;
}
static
int
read_bit
(
struct
spec_fa
*
fa
,
int
port
)
{
return
slot
(
fa
,
port
,
0x1
);
}
static
int
write_bit
(
struct
spec_fa
*
fa
,
int
port
,
int
bit
)
{
return
slot
(
fa
,
port
,
bit
);
}
static
int
ow_read_byte
(
struct
spec_fa
*
fa
,
int
port
)
{
int
byte
=
0
,
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
byte
|=
(
read_bit
(
fa
,
port
)
<<
i
);
return
byte
;
}
static
int
ow_write_byte
(
struct
spec_fa
*
fa
,
int
port
,
int
byte
)
{
int
data
=
0
;
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
){
data
|=
write_bit
(
fa
,
port
,
(
byte
&
0x1
))
<<
i
;
byte
>>=
1
;
}
return
0
;
/* success */
}
static
int
ow_write_block
(
struct
spec_fa
*
fa
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
ow_write_byte
(
fa
,
port
,
block
[
i
]);
return
0
;
}
static
int
ow_read_block
(
struct
spec_fa
*
fa
,
int
port
,
uint8_t
*
block
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
block
[
i
]
=
ow_read_byte
(
fa
,
port
);
return
0
;
}
static
int
ds18x_read_serial
(
struct
spec_fa
*
fa
)
{
if
(
!
ow_reset
(
fa
,
0
))
{
pr_err
(
"%s: Failure in resetting one-wire channel
\n
"
,
KBUILD_MODNAME
);
return
-
EIO
;
}
ow_write_byte
(
fa
,
FD_OW_PORT
,
CMD_ROM_READ
);
return
ow_read_block
(
fa
,
FD_OW_PORT
,
fa
->
ds18_id
,
8
);
}
static
int
ds18x_access
(
struct
spec_fa
*
fa
)
{
if
(
!
ow_reset
(
fa
,
0
))
goto
out
;
if
(
0
)
{
/* select the rom among several of them */
if
(
ow_write_byte
(
fa
,
FD_OW_PORT
,
CMD_ROM_MATCH
)
<
0
)
goto
out
;
return
ow_write_block
(
fa
,
FD_OW_PORT
,
fa
->
ds18_id
,
8
);
}
else
{
/* we have one only, so skip rom */
return
ow_write_byte
(
fa
,
FD_OW_PORT
,
CMD_ROM_SKIP
);
}
out:
pr_err
(
"%s: Failure in one-wire communication
\n
"
,
KBUILD_MODNAME
);
return
-
EIO
;
}
static
void
__temp_command_and_next_t
(
struct
spec_fa
*
fa
,
int
cfg_reg
)
{
int
ms
;
ds18x_access
(
fa
);
ow_write_byte
(
fa
,
FD_OW_PORT
,
CMD_CONVERT_TEMP
);
/* The conversion takes some time, so mark when will it be ready */
ms
=
94
*
(
1
<<
(
cfg_reg
>>
5
));
fa
->
next_t
=
jiffies
+
msecs_to_jiffies
(
ms
);
}
int
fa_read_temp
(
struct
spec_fa
*
fa
,
int
verbose
)
{
int
i
,
temp
;
unsigned
long
j
;
uint8_t
data
[
9
];
/* If first conversion, ask for it first */
if
(
fa
->
next_t
==
0
)
__temp_command_and_next_t
(
fa
,
0x7f
/* we ignore: max time */
);
/* Wait for it to be ready: (FIXME: we need a time policy here) */
j
=
jiffies
;
if
(
time_before
(
j
,
fa
->
next_t
))
{
/* If we cannot sleep, return the previous value */
if
(
in_atomic
())
return
fa
->
temp
;
msleep
(
jiffies_to_msecs
(
fa
->
next_t
-
j
));
}
ds18x_access
(
fa
);
ow_write_byte
(
fa
,
FD_OW_PORT
,
CMD_READ_SCRATCHPAD
);
ow_read_block
(
fa
,
FD_OW_PORT
,
data
,
9
);
if
(
verbose
>
1
)
{
pr_info
(
"%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
;
fa
->
temp
=
temp
;
if
(
verbose
)
{
pr_info
(
"%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
(
fa
,
data
[
4
]);
/* start next conversion */
return
temp
;
}
int
fa_onewire_init
(
struct
spec_fa
*
fa
)
{
ow_writel
(
fa
,
((
CLK_DIV_NOR
&
CDR_NOR_MSK
)
|
((
CLK_DIV_OVD
<<
CDR_OVD_OFS
)
&
CDR_OVD_MSK
)),
R_CDR
);
if
(
ds18x_read_serial
(
fa
)
<
0
)
return
-
EIO
;
/* read the temperature once, to ensure it works, and print it */
fa_read_temp
(
fa
,
2
);
return
0
;
}
void
fa_onewire_exit
(
struct
spec_fa
*
fa
)
{
/* 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