This source file includes following definitions.
- mk48txx_attach
- mk48txx_gettime
- mk48txx_settime
- mk48txx_getcal
- mk48txx_setcal
- mk48txx_get_nvram_size
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #include <sys/param.h>
44 #include <sys/malloc.h>
45 #include <sys/systm.h>
46 #include <sys/errno.h>
47
48 #include <machine/bus.h>
49 #include <dev/clock_subr.h>
50 #include <dev/ic/mk48txxreg.h>
51
52
53 struct mk48txx {
54 bus_space_tag_t mk_bt;
55 bus_space_handle_t mk_bh;
56 bus_size_t mk_nvramsz;
57 bus_size_t mk_clkoffset;
58 u_int mk_year0;
59
60 };
61
62 int mk48txx_gettime(todr_chip_handle_t, struct timeval *);
63 int mk48txx_settime(todr_chip_handle_t, struct timeval *);
64 int mk48txx_getcal(todr_chip_handle_t, int *);
65 int mk48txx_setcal(todr_chip_handle_t, int);
66
67 int mk48txx_auto_century_adjust = 1;
68
69 struct {
70 const char *name;
71 bus_size_t nvramsz;
72 bus_size_t clkoff;
73 int flags;
74 #define MK48TXX_EXT_REGISTERS 1
75 } mk48txx_models[] = {
76 { "mk48t02", MK48T02_CLKSZ, MK48T02_CLKOFF, 0 },
77 { "mk48t08", MK48T08_CLKSZ, MK48T08_CLKOFF, 0 },
78 { "mk48t18", MK48T18_CLKSZ, MK48T18_CLKOFF, 0 },
79 { "mk48t59", MK48T59_CLKSZ, MK48T59_CLKOFF, MK48TXX_EXT_REGISTERS },
80 };
81
82 todr_chip_handle_t
83 mk48txx_attach(bt, bh, model, year0)
84 bus_space_tag_t bt;
85 bus_space_handle_t bh;
86 const char *model;
87 int year0;
88 {
89 todr_chip_handle_t handle;
90 struct mk48txx *mk;
91 bus_size_t nvramsz, clkoff;
92 int sz;
93 int i;
94
95 printf(": %s", model);
96
97 i = sizeof(mk48txx_models)/sizeof(mk48txx_models[0]);
98 while (--i >= 0) {
99 if (strcmp(model, mk48txx_models[i].name) == 0) {
100 nvramsz = mk48txx_models[i].nvramsz;
101 clkoff = mk48txx_models[i].clkoff;
102 break;
103 }
104 }
105 if (i < 0) {
106 printf(": unsupported model");
107 return (NULL);
108 }
109
110 sz = ALIGN(sizeof(struct todr_chip_handle)) + sizeof(struct mk48txx);
111 handle = malloc(sz, M_DEVBUF, M_NOWAIT);
112 if (handle == NULL) {
113 printf(": failed to allocate memory");
114 return NULL;
115 }
116 mk = (struct mk48txx *)((u_long)handle +
117 ALIGN(sizeof(struct todr_chip_handle)));
118 handle->cookie = mk;
119 handle->todr_gettime = mk48txx_gettime;
120 handle->todr_settime = mk48txx_settime;
121 handle->todr_getcal = mk48txx_getcal;
122 handle->todr_setcal = mk48txx_setcal;
123 handle->todr_setwen = NULL;
124 mk->mk_bt = bt;
125 mk->mk_bh = bh;
126 mk->mk_nvramsz = nvramsz;
127 mk->mk_clkoffset = clkoff;
128 mk->mk_year0 = year0;
129
130 return (handle);
131 }
132
133
134
135
136
137 int
138 mk48txx_gettime(handle, tv)
139 todr_chip_handle_t handle;
140 struct timeval *tv;
141 {
142 struct mk48txx *mk = handle->cookie;
143 bus_space_tag_t bt = mk->mk_bt;
144 bus_space_handle_t bh = mk->mk_bh;
145 bus_size_t clkoff = mk->mk_clkoffset;
146 struct clock_ymdhms dt;
147 int year;
148 u_int8_t csr;
149
150 todr_wenable(handle, 1);
151
152
153 csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
154 csr |= MK48TXX_CSR_READ;
155 bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
156
157 dt.dt_sec = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_ISEC));
158 dt.dt_min = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IMIN));
159 dt.dt_hour = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IHOUR));
160 dt.dt_day = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IDAY));
161 dt.dt_wday = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IWDAY));
162 dt.dt_mon = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IMON));
163 year = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IYEAR));
164
165 year += mk->mk_year0;
166 if (year < POSIX_BASE_YEAR && mk48txx_auto_century_adjust != 0)
167 year += 100;
168
169 dt.dt_year = year;
170
171
172 csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
173 csr &= ~MK48TXX_CSR_READ;
174 bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
175 todr_wenable(handle, 0);
176
177
178 if (dt.dt_mon > 12 || dt.dt_day > 31 ||
179 dt.dt_hour >= 24 || dt.dt_min >= 60 || dt.dt_sec >= 60)
180 return (1);
181
182 tv->tv_sec = clock_ymdhms_to_secs(&dt);
183 tv->tv_usec = 0;
184 return (0);
185 }
186
187
188
189
190
191 int
192 mk48txx_settime(handle, tv)
193 todr_chip_handle_t handle;
194 struct timeval *tv;
195 {
196 struct mk48txx *mk = handle->cookie;
197 bus_space_tag_t bt = mk->mk_bt;
198 bus_space_handle_t bh = mk->mk_bh;
199 bus_size_t clkoff = mk->mk_clkoffset;
200 struct clock_ymdhms dt;
201 u_int8_t csr;
202 int year;
203
204
205 clock_secs_to_ymdhms(tv->tv_sec, &dt);
206
207 year = dt.dt_year - mk->mk_year0;
208 if (year > 99 && mk48txx_auto_century_adjust != 0)
209 year -= 100;
210
211 todr_wenable(handle, 1);
212
213 csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
214 csr |= MK48TXX_CSR_WRITE;
215 bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
216
217 bus_space_write_1(bt, bh, clkoff + MK48TXX_ISEC, TOBCD(dt.dt_sec));
218 bus_space_write_1(bt, bh, clkoff + MK48TXX_IMIN, TOBCD(dt.dt_min));
219 bus_space_write_1(bt, bh, clkoff + MK48TXX_IHOUR, TOBCD(dt.dt_hour));
220 bus_space_write_1(bt, bh, clkoff + MK48TXX_IWDAY, TOBCD(dt.dt_wday));
221 bus_space_write_1(bt, bh, clkoff + MK48TXX_IDAY, TOBCD(dt.dt_day));
222 bus_space_write_1(bt, bh, clkoff + MK48TXX_IMON, TOBCD(dt.dt_mon));
223 bus_space_write_1(bt, bh, clkoff + MK48TXX_IYEAR, TOBCD(year));
224
225
226 csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
227 csr &= ~MK48TXX_CSR_WRITE;
228 bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
229 todr_wenable(handle, 0);
230 return (0);
231 }
232
233 int
234 mk48txx_getcal(handle, vp)
235 todr_chip_handle_t handle;
236 int *vp;
237 {
238 return (EOPNOTSUPP);
239 }
240
241 int
242 mk48txx_setcal(handle, v)
243 todr_chip_handle_t handle;
244 int v;
245 {
246 return (EOPNOTSUPP);
247 }
248
249 int
250 mk48txx_get_nvram_size(handle, vp)
251 todr_chip_handle_t handle;
252 bus_size_t *vp;
253 {
254 struct mk48txx *mk = handle->cookie;
255 *vp = mk->mk_nvramsz;
256 return (0);
257 }