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 <
[email protected]
>"
);
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