xref: /netbsd-src/sys/dev/i2c/x1226.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: x1226.c,v 1.16 2014/03/17 15:57:56 skrll Exp $	*/
2 
3 /*
4  * Copyright (c) 2003 Shigeyuki Fukushima.
5  * All rights reserved.
6  *
7  * Written by Shigeyuki Fukushima for the NetBSD Project.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Shigeyuki Fukushima.
21  * 4. The name of Shigeyuki Fukushima may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY SHIGEYUKI FUKUSHIMA ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SHIGEYUKI FUKUSHIMA
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: x1226.c,v 1.16 2014/03/17 15:57:56 skrll Exp $");
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/device.h>
44 #include <sys/kernel.h>
45 #include <sys/fcntl.h>
46 #include <sys/uio.h>
47 #include <sys/conf.h>
48 #include <sys/event.h>
49 
50 #include <dev/clock_subr.h>
51 
52 #include <dev/i2c/i2cvar.h>
53 #include <dev/i2c/x1226reg.h>
54 
55 struct xrtc_softc {
56 	device_t		sc_dev;
57 	i2c_tag_t		sc_tag;
58 	int			sc_address;
59 	int			sc_open;
60 	struct todr_chip_handle	sc_todr;
61 };
62 
63 static void	xrtc_attach(device_t, device_t, void *);
64 static int	xrtc_match(device_t, cfdata_t, void *);
65 
66 CFATTACH_DECL_NEW(xrtc, sizeof(struct xrtc_softc),
67     xrtc_match, xrtc_attach, NULL, NULL);
68 extern struct cfdriver xrtc_cd;
69 
70 dev_type_open(xrtc_open);
71 dev_type_close(xrtc_close);
72 dev_type_read(xrtc_read);
73 dev_type_write(xrtc_write);
74 
75 const struct cdevsw xrtc_cdevsw = {
76 	.d_open = xrtc_open,
77 	.d_close = xrtc_close,
78 	.d_read = xrtc_read,
79 	.d_write = xrtc_write,
80 	.d_ioctl = noioctl,
81 	.d_stop = nostop,
82 	.d_tty = notty,
83 	.d_poll = nopoll,
84 	.d_mmap = nommap,
85 	.d_kqfilter = nokqfilter,
86 	.d_flag = D_OTHER
87 };
88 
89 static int xrtc_clock_read(struct xrtc_softc *, struct clock_ymdhms *);
90 static int xrtc_clock_write(struct xrtc_softc *, struct clock_ymdhms *);
91 static int xrtc_gettime(struct todr_chip_handle *, struct timeval *);
92 static int xrtc_settime(struct todr_chip_handle *, struct timeval *);
93 
94 /*
95  * xrtc_match()
96  */
97 static int
98 xrtc_match(device_t parent, cfdata_t cf, void *arg)
99 {
100 	struct i2c_attach_args *ia = arg;
101 
102 	/* match only this RTC devices */
103 	if (ia->ia_addr == X1226_ADDR)
104 		return (1);
105 
106 	return (0);
107 }
108 
109 /*
110  * xrtc_attach()
111  */
112 static void
113 xrtc_attach(device_t parent, device_t self, void *arg)
114 {
115 	struct xrtc_softc *sc = device_private(self);
116 	struct i2c_attach_args *ia = arg;
117 
118 	aprint_naive(": Real-time Clock/NVRAM\n");
119 	aprint_normal(": Xicor X1226 Real-time Clock/NVRAM\n");
120 
121 	sc->sc_tag = ia->ia_tag;
122 	sc->sc_address = ia->ia_addr;
123 	sc->sc_dev = self;
124 	sc->sc_open = 0;
125 	sc->sc_todr.cookie = sc;
126 	sc->sc_todr.todr_gettime = xrtc_gettime;
127 	sc->sc_todr.todr_settime = xrtc_settime;
128 	sc->sc_todr.todr_setwen = NULL;
129 
130 	todr_attach(&sc->sc_todr);
131 }
132 
133 
134 /*ARGSUSED*/
135 int
136 xrtc_open(dev_t dev, int flag, int fmt, struct lwp *l)
137 {
138 	struct xrtc_softc *sc;
139 
140 	if ((sc = device_lookup_private(&xrtc_cd, minor(dev))) == NULL)
141 		return (ENXIO);
142 
143 	/* XXX: Locking */
144 
145 	if (sc->sc_open)
146 		return (EBUSY);
147 
148 	sc->sc_open = 1;
149 	return (0);
150 }
151 
152 /*ARGSUSED*/
153 int
154 xrtc_close(dev_t dev, int flag, int fmt, struct lwp *l)
155 {
156 	struct xrtc_softc *sc;
157 
158 	if ((sc = device_lookup_private(&xrtc_cd, minor(dev))) == NULL)
159 		return (ENXIO);
160 
161 	sc->sc_open = 0;
162 	return (0);
163 }
164 
165 /*ARGSUSED*/
166 int
167 xrtc_read(dev_t dev, struct uio *uio, int flags)
168 {
169 	struct xrtc_softc *sc;
170 	u_int8_t ch, cmdbuf[2];
171 	int addr, error;
172 
173 	if ((sc = device_lookup_private(&xrtc_cd, minor(dev))) == NULL)
174 		return (ENXIO);
175 
176 	if (uio->uio_offset >= X1226_NVRAM_SIZE)
177 		return (EINVAL);
178 
179 	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
180 		return (error);
181 
182 	while (uio->uio_resid && uio->uio_offset < X1226_NVRAM_SIZE) {
183 		addr = (int)uio->uio_offset + X1226_NVRAM_START;
184 		cmdbuf[0] = (addr >> 8) && 0xff;
185 		cmdbuf[1] = addr && 0xff;
186 		if ((error = iic_exec(sc->sc_tag,
187 			I2C_OP_READ_WITH_STOP,
188 			sc->sc_address, cmdbuf, 2, &ch, 1, 0)) != 0) {
189 			iic_release_bus(sc->sc_tag, 0);
190 			aprint_error_dev(sc->sc_dev,
191 			    "xrtc_read: read failed at 0x%x\n",
192 				(int)uio->uio_offset);
193 			return (error);
194 		}
195 		if ((error = uiomove(&ch, 1, uio)) != 0) {
196 			iic_release_bus(sc->sc_tag, 0);
197 			return (error);
198 		}
199 	}
200 
201 	iic_release_bus(sc->sc_tag, 0);
202 
203 	return (0);
204 }
205 
206 /*ARGSUSED*/
207 int
208 xrtc_write(dev_t dev, struct uio *uio, int flags)
209 {
210 	struct xrtc_softc *sc;
211 	u_int8_t cmdbuf[3];
212 	int addr, error;
213 
214 	if ((sc = device_lookup_private(&xrtc_cd, minor(dev))) == NULL)
215 		return (ENXIO);
216 
217 	if (uio->uio_offset >= X1226_NVRAM_SIZE)
218 		return (EINVAL);
219 
220 	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
221 		return (error);
222 
223 	while (uio->uio_resid && uio->uio_offset < X1226_NVRAM_SIZE) {
224 		addr = (int)uio->uio_offset + X1226_NVRAM_START;
225 		cmdbuf[0] = (addr >> 8) && 0xff;
226 		cmdbuf[1] = addr && 0xff;
227 		if ((error = uiomove(&cmdbuf[2], 1, uio)) != 0) {
228 			break;
229 		}
230 		if ((error = iic_exec(sc->sc_tag,
231 			uio->uio_resid ? I2C_OP_WRITE : I2C_OP_WRITE_WITH_STOP,
232 			sc->sc_address, cmdbuf, 2, &cmdbuf[2], 1, 0)) != 0) {
233 			iic_release_bus(sc->sc_tag, 0);
234 			aprint_error_dev(sc->sc_dev,
235 			    "xrtc_write: write failed at 0x%x\n",
236 				(int)uio->uio_offset);
237 			return (error);
238 		}
239 	}
240 
241 	iic_release_bus(sc->sc_tag, 0);
242 
243 	return (0);
244 }
245 
246 
247 static int
248 xrtc_gettime(struct todr_chip_handle *ch, struct timeval *tv)
249 {
250 	struct xrtc_softc *sc = ch->cookie;
251 	struct clock_ymdhms dt, check;
252 	int retries;
253 
254 	memset(&dt, 0, sizeof(dt));
255 	memset(&check, 0, sizeof(check));
256 
257 	retries = 5;
258 	do {
259 		xrtc_clock_read(sc, &dt);
260 		xrtc_clock_read(sc, &check);
261 	} while (memcmp(&dt, &check, sizeof(check)) != 0 && --retries);
262 
263 	tv->tv_sec = clock_ymdhms_to_secs(&dt);
264 	tv->tv_usec = 0;
265 
266 	return (0);
267 }
268 
269 static int
270 xrtc_settime(struct todr_chip_handle *ch, struct timeval *tv)
271 {
272 	struct xrtc_softc *sc = ch->cookie;
273 	struct clock_ymdhms dt;
274 
275 	clock_secs_to_ymdhms(tv->tv_sec, &dt);
276 
277 	if (xrtc_clock_write(sc, &dt) == 0)
278 		return (-1);
279 
280 	return (0);
281 }
282 
283 static int
284 xrtc_clock_read(struct xrtc_softc *sc, struct clock_ymdhms *dt)
285 {
286 	int i = 0;
287 	u_int8_t bcd[X1226_REG_RTC_SIZE], cmdbuf[2];
288 
289 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
290 		aprint_error_dev(sc->sc_dev,
291 		    "xrtc_clock_read: failed to acquire I2C bus\n");
292 		return (0);
293 	}
294 
295 	/* Read each RTC register in order */
296 	for (i = 0 ; i < X1226_REG_RTC_SIZE ; i++) {
297 		int addr = i + X1226_REG_RTC_BASE;
298 		cmdbuf[0] = (addr >> 8) & 0xff;
299 		cmdbuf[1] = addr & 0xff;
300 
301 		if (iic_exec(sc->sc_tag,
302 			I2C_OP_READ_WITH_STOP,
303 			sc->sc_address, cmdbuf, 2,
304 			&bcd[i], 1, I2C_F_POLL)) {
305 			iic_release_bus(sc->sc_tag, I2C_F_POLL);
306 			aprint_error_dev(sc->sc_dev,
307 			    "xrtc_clock_read: failed to read rtc "
308 				"at 0x%x\n", i);
309 			return (0);
310 		}
311 	}
312 
313 	/* Done with I2C */
314 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
315 
316 	/*
317 	 * Convert the X1226's register bcd values
318 	 */
319 	dt->dt_sec = FROMBCD(bcd[X1226_REG_SC - X1226_REG_RTC_BASE]
320 			& X1226_REG_SC_MASK);
321 	dt->dt_min = FROMBCD(bcd[X1226_REG_MN - X1226_REG_RTC_BASE]
322 			& X1226_REG_MN_MASK);
323 	if (!(bcd[X1226_REG_HR - X1226_REG_RTC_BASE] & X1226_FLAG_HR_24H)) {
324 		dt->dt_hour = FROMBCD(bcd[X1226_REG_HR - X1226_REG_RTC_BASE]
325 				& X1226_REG_HR12_MASK);
326 		if (bcd[X1226_REG_HR - X1226_REG_RTC_BASE] & X1226_FLAG_HR_12HPM) {
327 			dt->dt_hour += 12;
328 		}
329 	} else {
330 		dt->dt_hour = FROMBCD(bcd[X1226_REG_HR - X1226_REG_RTC_BASE]
331 			& X1226_REG_HR24_MASK);
332 	}
333 	dt->dt_wday = FROMBCD(bcd[X1226_REG_DW - X1226_REG_RTC_BASE]
334 			& X1226_REG_DT_MASK);
335 	dt->dt_day = FROMBCD(bcd[X1226_REG_DT - X1226_REG_RTC_BASE]
336 			& X1226_REG_DT_MASK);
337 	dt->dt_mon = FROMBCD(bcd[X1226_REG_MO - X1226_REG_RTC_BASE]
338 			& X1226_REG_MO_MASK);
339 	dt->dt_year = FROMBCD(bcd[X1226_REG_YR - X1226_REG_RTC_BASE]
340 			& X1226_REG_YR_MASK);
341 	dt->dt_year += FROMBCD(bcd[X1226_REG_Y2K - X1226_REG_RTC_BASE]
342 			& X1226_REG_Y2K_MASK) * 100;
343 
344 	return (1);
345 }
346 
347 static int
348 xrtc_clock_write(struct xrtc_softc *sc, struct clock_ymdhms *dt)
349 {
350 	int i = 0, addr;
351 	u_int8_t bcd[X1226_REG_RTC_SIZE], cmdbuf[3];
352 
353 	/*
354 	 * Convert our time to bcd values
355 	 */
356 	bcd[X1226_REG_SC - X1226_REG_RTC_BASE] = TOBCD(dt->dt_sec);
357 	bcd[X1226_REG_MN - X1226_REG_RTC_BASE] = TOBCD(dt->dt_min);
358 	bcd[X1226_REG_HR - X1226_REG_RTC_BASE] = TOBCD(dt->dt_hour)
359 						| X1226_FLAG_HR_24H;
360 	bcd[X1226_REG_DW - X1226_REG_RTC_BASE] = TOBCD(dt->dt_wday);
361 	bcd[X1226_REG_DT - X1226_REG_RTC_BASE] = TOBCD(dt->dt_day);
362 	bcd[X1226_REG_MO - X1226_REG_RTC_BASE] = TOBCD(dt->dt_mon);
363 	bcd[X1226_REG_YR - X1226_REG_RTC_BASE] = TOBCD(dt->dt_year % 100);
364 	bcd[X1226_REG_Y2K - X1226_REG_RTC_BASE] = TOBCD(dt->dt_year / 100);
365 
366 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) {
367 		aprint_error_dev(sc->sc_dev,
368 		    "xrtc_clock_write: failed to acquire I2C bus\n");
369 		return (0);
370 	}
371 
372 	/* Unlock register: Write Enable Latch */
373 	addr = X1226_REG_SR;
374 	cmdbuf[0] = ((addr >> 8) & 0xff);
375 	cmdbuf[1] = (addr & 0xff);
376 	cmdbuf[2] = X1226_FLAG_SR_WEL;
377 	if (iic_exec(sc->sc_tag,
378 		I2C_OP_WRITE_WITH_STOP,
379 		sc->sc_address, cmdbuf, 2, &cmdbuf[2], 1, 0) != 0) {
380 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
381 		aprint_error_dev(sc->sc_dev, "xrtc_clock_write: "
382 			"failed to write-unlock status register(WEL=1)\n");
383 		return (0);
384 	}
385 
386 	/* Unlock register: Register Write Enable Latch */
387 	addr = X1226_REG_SR;
388 	cmdbuf[0] = ((addr >> 8) & 0xff);
389 	cmdbuf[1] = (addr & 0xff);
390 	cmdbuf[2] = X1226_FLAG_SR_WEL | X1226_FLAG_SR_RWEL;
391 	if (iic_exec(sc->sc_tag,
392 		I2C_OP_WRITE_WITH_STOP,
393 		sc->sc_address, cmdbuf, 2, &cmdbuf[2], 1, 0) != 0) {
394 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
395 		aprint_error_dev(sc->sc_dev, "xrtc_clock_write: "
396 			"failed to write-unlock status register(RWEL=1)\n");
397 		return (0);
398 	}
399 
400 	/* Write each RTC register in reverse order */
401 	for (i = (X1226_REG_RTC_SIZE - 1) ; i >= 0; i--) {
402 		addr = i + X1226_REG_RTC_BASE;
403 		cmdbuf[0] = ((addr >> 8) & 0xff);
404 		cmdbuf[1] = (addr & 0xff);
405 		if (iic_exec(sc->sc_tag,
406 			I2C_OP_WRITE_WITH_STOP,
407 			sc->sc_address, cmdbuf, 2,
408 			&bcd[i], 1, I2C_F_POLL)) {
409 
410 			/* Lock register: WEL/RWEL off */
411 			addr = X1226_REG_SR;
412 			cmdbuf[0] = ((addr >> 8) & 0xff);
413 			cmdbuf[1] = (addr & 0xff);
414 			cmdbuf[2] = 0;
415 			iic_exec(sc->sc_tag,
416 				I2C_OP_WRITE_WITH_STOP,
417 				sc->sc_address, cmdbuf, 2,
418 				&cmdbuf[2], 1, 0);
419 
420 			iic_release_bus(sc->sc_tag, I2C_F_POLL);
421 			aprint_error_dev(sc->sc_dev, "xrtc_clock_write: failed to write rtc "
422 				"at 0x%x\n", i);
423 			return (0);
424 		}
425 	}
426 
427 	/* Lock register: WEL/RWEL off */
428 	addr = X1226_REG_SR;
429 	cmdbuf[0] = ((addr >> 8) & 0xff);
430 	cmdbuf[1] = (addr & 0xff);
431 	cmdbuf[2] = 0;
432 	if (iic_exec(sc->sc_tag,
433 		I2C_OP_WRITE_WITH_STOP,
434 		sc->sc_address, cmdbuf, 2, &cmdbuf[2], 1, 0) != 0) {
435 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
436 		aprint_error_dev(sc->sc_dev, "xrtc_clock_write: "
437 			"failed to write-lock status register\n");
438 		return (0);
439 	}
440 
441 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
442 	return (1);
443 }
444