xref: /openbmc/u-boot/drivers/rtc/ds1306.c (revision 0c698dcaa70275eb8814f665b545547cee013892)
1*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /*
2*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
3*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
4*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
5*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Stephan Linz <linz@li-pro.net>
6*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
7*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
8*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * project.
9*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
10*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
11*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
12*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
13*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
14*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
15*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
16*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
19*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
20*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
21*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
22*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
24*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  */
25*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
26*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /*
27*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Date & Time support for DS1306 RTC using SPI:
28*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *
29*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *    - SXNI855T:    it uses its own soft SPI here in this file
30*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *    - all other:   use the external spi_xfer() function
31*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  *                   (see include/spi.h)
32*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  */
33*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
34*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <common.h>
35*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <command.h>
36*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <rtc.h>
37*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <spi.h>
38*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
39*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_RTC_DS1306) && defined(CONFIG_CMD_DATE)
40*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
41*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_SECONDS		0x00
42*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_MINUTES		0x01
43*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_HOURS		0x02
44*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_DAY_OF_WEEK		0x03
45*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_DATE_OF_MONTH	0x04
46*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_MONTH		0x05
47*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_YEAR		0x06
48*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
49*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_SECONDS_ALARM0	0x07
50*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_MINUTES_ALARM0	0x08
51*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_HOURS_ALARM0	0x09
52*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_DAY_OF_WEEK_ALARM0	0x0a
53*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
54*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_SECONDS_ALARM1	0x0b
55*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_MINUTES_ALARM1	0x0c
56*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_HOURS_ALARM1	0x0d
57*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_DAY_OF_WEEK_ALARM1	0x0e
58*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
59*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_CONTROL		0x0f
60*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_STATUS		0x10
61*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_TRICKLE_CHARGER	0x11
62*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
63*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	RTC_USER_RAM_BASE	0x20
64*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
65*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /*
66*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * External table of chip select functions (see the appropriate board
67*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * support for the actual definition of the table).
68*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  */
69*0c698dcaSJean-Christophe PLAGNIOL-VILLARD extern spi_chipsel_type spi_chipsel[];
70*0c698dcaSJean-Christophe PLAGNIOL-VILLARD extern int spi_chipsel_cnt;
71*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
72*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned int bin2bcd (unsigned int n);
73*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char bcd2bin (unsigned char c);
74*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
75*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ************************************************************************* */
76*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SXNI855T		/* !!! SHOULD BE CHANGED TO NEW CODE !!! */
77*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
78*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void soft_spi_send (unsigned char n);
79*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char soft_spi_read (void);
80*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void init_spi (void);
81*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
82*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /*-----------------------------------------------------------------------
83*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  * Definitions
84*0c698dcaSJean-Christophe PLAGNIOL-VILLARD  */
85*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
86*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define	PB_SPISCK	0x00000002	/* PB 30 */
87*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define PB_SPIMOSI	0x00000004	/* PB 29 */
88*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define PB_SPIMISO	0x00000008	/* PB 28 */
89*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #define PB_SPI_CE	0x00010000	/* PB 15 */
90*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
91*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
92*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
93*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* read clock time from DS1306 and return it in *tmp */
94*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_get (struct rtc_time *tmp)
95*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
96*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
97*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char spi_byte;	/* Data Byte */
98*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
99*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	init_spi ();		/* set port B for software SPI */
100*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
101*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now we can enable the DS1306 RTC */
102*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
103*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
104*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
105*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Shift out the address (0) of the time in the Clock Chip */
106*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0);
107*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
108*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Put the clock readings into the rtc_time structure */
109*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_sec = bcd2bin (soft_spi_read ());	/* Read seconds */
110*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_min = bcd2bin (soft_spi_read ());	/* Read minutes */
111*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
112*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Hours are trickier */
113*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	spi_byte = soft_spi_read ();	/* Read Hours into temporary value */
114*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	if (spi_byte & 0x40) {
115*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		/* 12 hour mode bit is set (time is in 1-12 format) */
116*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		if (spi_byte & 0x20) {
117*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			/* since PM we add 11 to get 0-23 for hours */
118*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
119*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		} else {
120*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			/* since AM we subtract 1 to get 0-23 for hours */
121*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
122*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		}
123*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	} else {
124*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		/* Otherwise, 0-23 hour format */
125*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
126*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
127*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
128*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_read ();	/* Read and discard Day of week */
129*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_mday = bcd2bin (soft_spi_read ());	/* Read Day of the Month */
130*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_mon = bcd2bin (soft_spi_read ());	/* Read Month */
131*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
132*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Read Year and convert to this century */
133*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
134*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
135*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now we can disable the DS1306 RTC */
136*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
137*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
138*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
139*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	GregorianDay (tmp);	/* Determine the day of week */
140*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
141*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
142*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
143*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
144*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
145*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
146*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
147*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
148*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* set clock time in DS1306 RTC and in MPC8xx RTC */
149*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_set (struct rtc_time *tmp)
150*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
151*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
152*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
153*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	init_spi ();		/* set port B for software SPI */
154*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
155*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now we can enable the DS1306 RTC */
156*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
157*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
158*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
159*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* First disable write protect in the clock chip control register */
160*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0x8F);	/* send address of the control register */
161*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0x00);	/* send control register contents */
162*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
163*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now disable the DS1306 to terminate the write */
164*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
165*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
166*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
167*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now enable the DS1306 to initiate a new write */
168*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
169*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
170*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
171*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Next, send the address of the clock time write registers */
172*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0x80);	/* send address of the first time register */
173*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
174*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Use Burst Mode to send all of the time data to the clock */
175*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	bin2bcd (tmp->tm_sec);
176*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_sec));	/* Send Seconds */
177*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_min));	/* Send Minutes */
178*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_hour));	/* Send Hour */
179*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_wday));	/* Send Day of the Week */
180*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_mday));	/* Send Day of Month */
181*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_mon));	/* Send Month */
182*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (bin2bcd (tmp->tm_year - 2000));	/* Send Year */
183*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
184*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now we can disable the Clock chip to terminate the burst write */
185*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
186*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
187*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
188*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now we can enable the Clock chip to initiate a new write */
189*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
190*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
191*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
192*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* First we Enable write protect in the clock chip control register */
193*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0x8F);	/* send address of the control register */
194*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	soft_spi_send (0x40);	/* send out Control Register contents */
195*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
196*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Now disable the DS1306 */
197*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/*  Disable DS1306 Chip */
198*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
199*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
200*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Set standard MPC8xx clock to the same time so Linux will
201*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	 * see the time even if it doesn't have a DS1306 clock driver.
202*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	 * This helps with experimenting with standard kernels.
203*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	 */
204*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	{
205*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		ulong tim;
206*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
207*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
208*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
209*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
210*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_sitk.sitk_rtck = KAPWR_KEY;
211*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_sit.sit_rtc = tim;
212*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
213*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
214*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
215*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
216*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
217*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
218*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
219*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
220*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
221*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* Initialize Port B for software SPI */
222*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void init_spi (void)
223*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
224*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
225*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
226*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Force output pins to begin at logic 0 */
227*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
228*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
229*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Set these 3 signals as outputs */
230*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
231*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
232*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;	/* Make MISO pin an input */
233*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	udelay (10);
234*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
235*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
236*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
237*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
238*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
239*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void soft_spi_send (unsigned char n)
240*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
241*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
242*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char bitpos;	/* bit position to receive */
243*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char i;	/* Loop Control */
244*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
245*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* bit position to send, start with most significant bit */
246*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	bitpos = 0x80;
247*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
248*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Send 8 bits to software SPI */
249*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < 8; i++) {	/* Loop for 8 bits */
250*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
251*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
252*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		if (n & bitpos)
253*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			immap->im_cpm.cp_pbdat |= PB_SPIMOSI;	/* Set MOSI to 1 */
254*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		else
255*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;	/* Set MOSI to 0 */
256*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		udelay (10);
257*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
258*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
259*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		udelay (10);
260*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
261*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		bitpos >>= 1;	/* Shift for next bit position */
262*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
263*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
264*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
265*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
266*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
267*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
268*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char soft_spi_read (void)
269*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
270*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
271*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
272*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char spi_byte = 0;	/* Return value, assume success */
273*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char bitpos;	/* bit position to receive */
274*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char i;	/* Loop Control */
275*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
276*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* bit position to receive, start with most significant bit */
277*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	bitpos = 0x80;
278*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
279*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* Read 8 bits here */
280*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < 8; i++) {	/* Do 8 bits in loop */
281*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
282*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		udelay (10);
283*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		if (immap->im_cpm.cp_pbdat & PB_SPIMISO)	/* Get a bit of data */
284*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 			spi_byte |= bitpos;	/* Set data accordingly */
285*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
286*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		udelay (10);
287*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		bitpos >>= 1;	/* Shift for next bit position */
288*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
289*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
290*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	return spi_byte;	/* Return the byte read */
291*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
292*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
293*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
294*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
295*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_reset (void)
296*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
297*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	return;			/* nothing to do */
298*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
299*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
300*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #else  /* not CONFIG_SXNI855T */
301*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ************************************************************************* */
302*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
303*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char rtc_read (unsigned char reg);
304*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void rtc_write (unsigned char reg, unsigned char val);
305*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
306*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* read clock time from DS1306 and return it in *tmp */
307*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_get (struct rtc_time *tmp)
308*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
309*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char sec, min, hour, mday, wday, mon, year;
310*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
311*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	sec = rtc_read (RTC_SECONDS);
312*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	min = rtc_read (RTC_MINUTES);
313*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	hour = rtc_read (RTC_HOURS);
314*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	mday = rtc_read (RTC_DATE_OF_MONTH);
315*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	wday = rtc_read (RTC_DAY_OF_WEEK);
316*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	mon = rtc_read (RTC_MONTH);
317*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	year = rtc_read (RTC_YEAR);
318*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
319*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
320*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       "hr: %02x min: %02x sec: %02x\n",
321*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       year, mon, mday, wday, hour, min, sec);
322*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
323*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_DAY_OF_WEEK_ALARM0),
324*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_HOURS_ALARM0),
325*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
326*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
327*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_DAY_OF_WEEK_ALARM1),
328*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_HOURS_ALARM1),
329*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
330*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
331*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_sec = bcd2bin (sec & 0x7F);	/* convert Seconds */
332*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_min = bcd2bin (min & 0x7F);	/* convert Minutes */
333*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
334*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* convert Hours */
335*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_hour = (hour & 0x40)
336*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		? ((hour & 0x20)	/* 12 hour mode */
337*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		   ? bcd2bin (hour & 0x1F) + 11	/* PM */
338*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		   : bcd2bin (hour & 0x1F) - 1	/* AM */
339*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		)
340*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		: bcd2bin (hour & 0x3F);	/* 24 hour mode */
341*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
342*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_mday = bcd2bin (mday & 0x3F);	/* convert Day of the Month */
343*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_mon = bcd2bin (mon & 0x1F);	/* convert Month */
344*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_year = bcd2bin (year) + 2000;	/* convert Year */
345*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_wday = bcd2bin (wday & 0x07) - 1;	/* convert Day of the Week */
346*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_yday = 0;
347*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	tmp->tm_isdst = 0;
348*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
349*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
350*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
351*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
352*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
353*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
354*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
355*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
356*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* set clock time from *tmp in DS1306 RTC */
357*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_set (struct rtc_time *tmp)
358*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
359*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
360*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
361*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
362*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
363*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
364*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
365*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
366*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
367*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
368*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
369*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
370*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
371*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
372*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
373*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
374*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* reset the DS1306 */
375*0c698dcaSJean-Christophe PLAGNIOL-VILLARD void rtc_reset (void)
376*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
377*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* clear the control register */
378*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_CONTROL, 0x00);	/* 1st step: reset WP */
379*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_CONTROL, 0x00);	/* 2nd step: reset 1Hz, AIE1, AIE0 */
380*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
381*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	/* reset all alarms */
382*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_SECONDS_ALARM0, 0x00);
383*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_SECONDS_ALARM1, 0x00);
384*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_MINUTES_ALARM0, 0x00);
385*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_MINUTES_ALARM1, 0x00);
386*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_HOURS_ALARM0, 0x00);
387*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_HOURS_ALARM1, 0x00);
388*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
389*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
390*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
391*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
392*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
393*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
394*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char rtc_read (unsigned char reg)
395*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
396*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char dout[2];	/* SPI Output Data Bytes */
397*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char din[2];	/* SPI Input Data Bytes */
398*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
399*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	dout[0] = reg;
400*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
401*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
402*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		return 0;
403*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	} else {
404*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 		return din[1];
405*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	}
406*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
407*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
408*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
409*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
410*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static void rtc_write (unsigned char reg, unsigned char val)
411*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
412*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char dout[2];	/* SPI Output Data Bytes */
413*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	unsigned char din[2];	/* SPI Input Data Bytes */
414*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
415*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	dout[0] = 0x80 | reg;
416*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	dout[1] = val;
417*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
418*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
419*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
420*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
421*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
422*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
423*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
424*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
425*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char bcd2bin (unsigned char n)
426*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
427*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
428*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
429*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
430*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
431*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
432*0c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned int bin2bcd (unsigned int n)
433*0c698dcaSJean-Christophe PLAGNIOL-VILLARD {
434*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 	return (((n / 10) << 4) | (n % 10));
435*0c698dcaSJean-Christophe PLAGNIOL-VILLARD }
436*0c698dcaSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
437*0c698dcaSJean-Christophe PLAGNIOL-VILLARD 
438*0c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif
439