Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
rtc
rtc-ds3234.c
Go to the documentation of this file.
1
/* rtc-ds3234.c
2
*
3
* Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
4
* and SRAM.
5
*
6
* Copyright (C) 2008 MIMOMax Wireless Ltd.
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
11
*
12
*/
13
14
#include <
linux/init.h
>
15
#include <linux/module.h>
16
#include <linux/device.h>
17
#include <
linux/platform_device.h
>
18
#include <linux/rtc.h>
19
#include <
linux/spi/spi.h
>
20
#include <
linux/bcd.h
>
21
22
#define DS3234_REG_SECONDS 0x00
23
#define DS3234_REG_MINUTES 0x01
24
#define DS3234_REG_HOURS 0x02
25
#define DS3234_REG_DAY 0x03
26
#define DS3234_REG_DATE 0x04
27
#define DS3234_REG_MONTH 0x05
28
#define DS3234_REG_YEAR 0x06
29
#define DS3234_REG_CENTURY (1 << 7)
/* Bit 7 of the Month register */
30
31
#define DS3234_REG_CONTROL 0x0E
32
#define DS3234_REG_CONT_STAT 0x0F
33
34
static
int
ds3234_set_reg(
struct
device
*
dev
,
unsigned
char
address
,
35
unsigned
char
data
)
36
{
37
struct
spi_device
*
spi
= to_spi_device(dev);
38
unsigned
char
buf
[2];
39
40
/* MSB must be '1' to indicate write */
41
buf[0] = address | 0x80;
42
buf[1] =
data
;
43
44
return
spi_write_then_read
(spi, buf, 2,
NULL
, 0);
45
}
46
47
static
int
ds3234_get_reg(
struct
device
*
dev
,
unsigned
char
address
,
48
unsigned
char
*
data
)
49
{
50
struct
spi_device
*
spi
= to_spi_device(dev);
51
52
*data = address & 0x7f;
53
54
return
spi_write_then_read
(spi, data, 1, data, 1);
55
}
56
57
static
int
ds3234_read_time(
struct
device
*
dev
,
struct
rtc_time
*dt)
58
{
59
int
err
;
60
unsigned
char
buf
[8];
61
struct
spi_device
*
spi
= to_spi_device(dev);
62
63
buf[0] = 0x00;
/* Start address */
64
65
err =
spi_write_then_read
(spi, buf, 1, buf, 8);
66
if
(err != 0)
67
return
err
;
68
69
/* Seconds, Minutes, Hours, Day, Date, Month, Year */
70
dt->
tm_sec
=
bcd2bin
(buf[0]);
71
dt->
tm_min
=
bcd2bin
(buf[1]);
72
dt->
tm_hour
=
bcd2bin
(buf[2] & 0x3f);
73
dt->
tm_wday
=
bcd2bin
(buf[3]) - 1;
/* 0 = Sun */
74
dt->
tm_mday
=
bcd2bin
(buf[4]);
75
dt->
tm_mon
=
bcd2bin
(buf[5] & 0x1f) - 1;
/* 0 = Jan */
76
dt->
tm_year
=
bcd2bin
(buf[6] & 0xff) + 100;
/* Assume 20YY */
77
78
return
rtc_valid_tm
(dt);
79
}
80
81
static
int
ds3234_set_time(
struct
device
*dev,
struct
rtc_time
*dt)
82
{
83
ds3234_set_reg(dev,
DS3234_REG_SECONDS
,
bin2bcd
(dt->
tm_sec
));
84
ds3234_set_reg(dev,
DS3234_REG_MINUTES
,
bin2bcd
(dt->
tm_min
));
85
ds3234_set_reg(dev,
DS3234_REG_HOURS
,
bin2bcd
(dt->
tm_hour
) & 0x3f);
86
87
/* 0 = Sun */
88
ds3234_set_reg(dev,
DS3234_REG_DAY
,
bin2bcd
(dt->
tm_wday
+ 1));
89
ds3234_set_reg(dev,
DS3234_REG_DATE
,
bin2bcd
(dt->
tm_mday
));
90
91
/* 0 = Jan */
92
ds3234_set_reg(dev,
DS3234_REG_MONTH
,
bin2bcd
(dt->
tm_mon
+ 1));
93
94
/* Assume 20YY although we just want to make sure not to go negative. */
95
if
(dt->
tm_year
> 100)
96
dt->
tm_year
-= 100;
97
98
ds3234_set_reg(dev,
DS3234_REG_YEAR
,
bin2bcd
(dt->
tm_year
));
99
100
return
0;
101
}
102
103
static
const
struct
rtc_class_ops
ds3234_rtc_ops = {
104
.read_time = ds3234_read_time,
105
.set_time = ds3234_set_time,
106
};
107
108
static
int
__devinit
ds3234_probe(
struct
spi_device
*spi)
109
{
110
struct
rtc_device
*
rtc
;
111
unsigned
char
tmp
;
112
int
res
;
113
114
spi->
mode
=
SPI_MODE_3
;
115
spi->
bits_per_word
= 8;
116
spi_setup
(spi);
117
118
res = ds3234_get_reg(&spi->
dev
,
DS3234_REG_SECONDS
, &tmp);
119
if
(res != 0)
120
return
res
;
121
122
/* Control settings
123
*
124
* CONTROL_REG
125
* BIT 7 6 5 4 3 2 1 0
126
* EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
127
*
128
* 0 0 0 1 1 1 0 0
129
*
130
* CONTROL_STAT_REG
131
* BIT 7 6 5 4 3 2 1 0
132
* OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F
133
*
134
* 1 0 0 0 1 0 0 0
135
*/
136
ds3234_get_reg(&spi->
dev
,
DS3234_REG_CONTROL
, &tmp);
137
ds3234_set_reg(&spi->
dev
,
DS3234_REG_CONTROL
, tmp & 0x1c);
138
139
ds3234_get_reg(&spi->
dev
,
DS3234_REG_CONT_STAT
, &tmp);
140
ds3234_set_reg(&spi->
dev
,
DS3234_REG_CONT_STAT
, tmp & 0x88);
141
142
/* Print our settings */
143
ds3234_get_reg(&spi->
dev
,
DS3234_REG_CONTROL
, &tmp);
144
dev_info
(&spi->
dev
,
"Control Reg: 0x%02x\n"
, tmp);
145
146
ds3234_get_reg(&spi->
dev
,
DS3234_REG_CONT_STAT
, &tmp);
147
dev_info
(&spi->
dev
,
"Ctrl/Stat Reg: 0x%02x\n"
, tmp);
148
149
rtc =
rtc_device_register
(
"ds3234"
,
150
&spi->
dev
, &ds3234_rtc_ops,
THIS_MODULE
);
151
if
(IS_ERR(rtc))
152
return
PTR_ERR(rtc);
153
154
dev_set_drvdata
(&spi->
dev
, rtc);
155
156
return
0;
157
}
158
159
static
int
__devexit
ds3234_remove(
struct
spi_device
*spi)
160
{
161
struct
rtc_device
*rtc = spi_get_drvdata(spi);
162
163
rtc_device_unregister
(rtc);
164
return
0;
165
}
166
167
static
struct
spi_driver
ds3234_driver = {
168
.driver = {
169
.name =
"ds3234"
,
170
.owner =
THIS_MODULE
,
171
},
172
.probe = ds3234_probe,
173
.remove =
__devexit_p
(ds3234_remove),
174
};
175
176
module_spi_driver
(ds3234_driver);
177
178
MODULE_DESCRIPTION
(
"DS3234 SPI RTC driver"
);
179
MODULE_AUTHOR
(
"Dennis Aberilla <denzzzhome@yahoo.com>"
);
180
MODULE_LICENSE
(
"GPL"
);
181
MODULE_ALIAS
(
"spi:ds3234"
);
Generated on Thu Jan 10 2013 14:16:48 for Linux Kernel by
1.8.2