4 * http://www.dave-tech.it
5 * http://www.wawnet.biz
6 * mailto:info@wawnet.biz
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <asm/hardware.h>
32 * Initialization, must be called once on start up, may be called
33 * repeatedly to change the speed and slave addresses.
35 void i2c_init(int speed, int slaveaddr)
38 setting up I2C support
40 unsigned int save_F,save_PF,rIICCON,rPCONA,rPDATA,rPCONF,rPUPF;
45 rPCONF = ((save_F & ~(0xF))| 0xa);
46 rPUPF = (save_PF | 0x3);
47 PCONF = rPCONF; /*PF0:IICSCL, PF1:IICSDA*/
48 PUPF = rPUPF; /* Disable pull-up */
50 /* Configuring pin for WC pin of EEprom */
60 Enable ACK, IICCLK=MCLK/16, enable interrupt
61 75MHz/16/(12+1) = 390625 Hz
63 rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xC);
70 * Probe the given I2C chip address. Returns 0 if a chip responded,
73 int i2c_probe(uchar chip)
79 printf("i2c_probe chip %d\n", (int) chip);
84 * Read/Write interface:
85 * chip: I2C chip address, range 0..127
86 * addr: Memory (register) address within the chip
87 * alen: Number of bytes to use for addr (typically 1, 2 for larger
88 * memories, 0 for register type devices with only one
90 * buffer: Where to read/write the data
91 * len: How many bytes to read/write
93 * Returns: 0 on success, not 0 on failure
96 #define S3C44B0X_rIIC_INTPEND (1<<4)
97 #define S3C44B0X_rIIC_LAST_RECEIV_BIT (1<<0)
98 #define S3C44B0X_rIIC_INTERRUPT_ENABLE (1<<5)
99 #define S3C44B0_IIC_TIMEOUT 100
101 int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
108 send the device offset
114 IICDS = chip; /* this is a write operation... */
119 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
121 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
125 if (k==S3C44B0_IIC_TIMEOUT)
128 /* wait and check ACK */
130 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
134 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
136 /* wait and check ACK */
137 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
139 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
143 if (k==S3C44B0_IIC_TIMEOUT)
147 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
151 now we can start with the read operation...
154 IICDS = chip | 0x01; /* this is a read operation... */
156 rIICSTAT = 0x90; /*master recv*/
160 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
162 /* wait and check ACK */
163 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
165 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
169 if (k==S3C44B0_IIC_TIMEOUT)
173 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
176 for (j=0; j<len-1; j++) {
178 /*clear pending bit to resume */
180 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
183 /* wait and check ACK */
184 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
186 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
190 if (k==S3C44B0_IIC_TIMEOUT)
194 buffer[j] = IICDS; /*save readed data*/
199 reading the last data
202 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND | (1<<7));
205 /* wait but NOT check ACK */
206 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
208 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
212 if (k==S3C44B0_IIC_TIMEOUT)
215 buffer[j] = IICDS; /*save readed data*/
217 rIICSTAT = 0x90; /*master recv*/
219 /* Write operation Terminate sending STOP */
221 /*Clear Int Pending Bit to RESUME*/
223 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
225 IICCON = IICCON | (1<<7); /*restore ACK generation*/
230 int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
237 send the device offset
243 IICDS = chip; /* this is a write operation... */
248 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
250 /* wait and check ACK */
251 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
253 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
257 if (k==S3C44B0_IIC_TIMEOUT)
261 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
265 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
267 /* wait and check ACK */
268 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
270 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
274 if (k==S3C44B0_IIC_TIMEOUT)
278 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
282 now we can start with the read write operation
284 for (j=0; j<len; j++) {
286 IICDS = buffer[j]; /*prerare data to write*/
288 /*clear pending bit to resume*/
290 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
293 /* wait but NOT check ACK */
294 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
296 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
302 if (k==S3C44B0_IIC_TIMEOUT)
307 /* sending stop to terminate */
308 rIICSTAT = 0xD0; /*master send*/
310 /*Clear Int Pending Bit to RESUME*/
312 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);