4 * http://www.dave-tech.it
5 * http://www.wawnet.biz
6 * mailto:info@wawnet.biz
8 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/hardware.h>
16 * Initialization, must be called once on start up, may be called
17 * repeatedly to change the speed and slave addresses.
19 void i2c_init(int speed, int slaveaddr)
22 setting up I2C support
24 unsigned int save_F,save_PF,rIICCON,rPCONA,rPDATA,rPCONF,rPUPF;
29 rPCONF = ((save_F & ~(0xF))| 0xa);
30 rPUPF = (save_PF | 0x3);
31 PCONF = rPCONF; /*PF0:IICSCL, PF1:IICSDA*/
32 PUPF = rPUPF; /* Disable pull-up */
34 /* Configuring pin for WC pin of EEprom */
44 Enable ACK, IICCLK=MCLK/16, enable interrupt
45 75MHz/16/(12+1) = 390625 Hz
47 rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xC);
54 * Probe the given I2C chip address. Returns 0 if a chip responded,
57 int i2c_probe(uchar chip)
63 printf("i2c_probe chip %d\n", (int) chip);
68 * Read/Write interface:
69 * chip: I2C chip address, range 0..127
70 * addr: Memory (register) address within the chip
71 * alen: Number of bytes to use for addr (typically 1, 2 for larger
72 * memories, 0 for register type devices with only one
74 * buffer: Where to read/write the data
75 * len: How many bytes to read/write
77 * Returns: 0 on success, not 0 on failure
80 #define S3C44B0X_rIIC_INTPEND (1<<4)
81 #define S3C44B0X_rIIC_LAST_RECEIV_BIT (1<<0)
82 #define S3C44B0X_rIIC_INTERRUPT_ENABLE (1<<5)
83 #define S3C44B0_IIC_TIMEOUT 100
85 int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
92 send the device offset
98 IICDS = chip; /* this is a write operation... */
103 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
105 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
109 if (k==S3C44B0_IIC_TIMEOUT)
112 /* wait and check ACK */
114 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
118 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
120 /* wait and check ACK */
121 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
123 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
127 if (k==S3C44B0_IIC_TIMEOUT)
131 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
135 now we can start with the read operation...
138 IICDS = chip | 0x01; /* this is a read operation... */
140 rIICSTAT = 0x90; /*master recv*/
144 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
146 /* wait and check ACK */
147 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
149 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
153 if (k==S3C44B0_IIC_TIMEOUT)
157 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
160 for (j=0; j<len-1; j++) {
162 /*clear pending bit to resume */
164 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
167 /* wait and check ACK */
168 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
170 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
174 if (k==S3C44B0_IIC_TIMEOUT)
178 buffer[j] = IICDS; /*save readed data*/
183 reading the last data
186 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND | (1<<7));
189 /* wait but NOT check ACK */
190 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
192 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
196 if (k==S3C44B0_IIC_TIMEOUT)
199 buffer[j] = IICDS; /*save readed data*/
201 rIICSTAT = 0x90; /*master recv*/
203 /* Write operation Terminate sending STOP */
205 /*Clear Int Pending Bit to RESUME*/
207 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);
209 IICCON = IICCON | (1<<7); /*restore ACK generation*/
214 int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
221 send the device offset
227 IICDS = chip; /* this is a write operation... */
232 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
234 /* wait and check ACK */
235 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
237 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
241 if (k==S3C44B0_IIC_TIMEOUT)
245 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
249 IICCON = IICCON & ~(S3C44B0X_rIIC_INTPEND);
251 /* wait and check ACK */
252 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
254 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
258 if (k==S3C44B0_IIC_TIMEOUT)
262 if ((temp & S3C44B0X_rIIC_LAST_RECEIV_BIT) == S3C44B0X_rIIC_LAST_RECEIV_BIT )
266 now we can start with the read write operation
268 for (j=0; j<len; j++) {
270 IICDS = buffer[j]; /*prerare data to write*/
272 /*clear pending bit to resume*/
274 temp = IICCON & ~(S3C44B0X_rIIC_INTPEND);
277 /* wait but NOT check ACK */
278 for(k=0; k<S3C44B0_IIC_TIMEOUT; k++) {
280 if( (temp & S3C44B0X_rIIC_INTPEND) == S3C44B0X_rIIC_INTPEND)
286 if (k==S3C44B0_IIC_TIMEOUT)
291 /* sending stop to terminate */
292 rIICSTAT = 0xD0; /*master send*/
294 /*Clear Int Pending Bit to RESUME*/
296 IICCON = temp & (~S3C44B0X_rIIC_INTPEND);