* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / sbus / char / vfc_i2c.c
blob8302316aab6d46d99247aa7f182e21f484597fc5
1 /*
2 * drivers/sbus/char/vfc_i2c.c
4 * Driver for the Videopix Frame Grabber.
5 *
6 * Functions that support the Phillips i2c(I squared C) bus on the vfc
7 * Documentation for the Phillips I2C bus can be found on the
8 * phillips home page
10 * Copyright (C) 1996 Manish Vachharajani (mvachhar@noc.rutgers.edu)
14 /* NOTE: It seems to me that the documentation regarding the
15 pcd8584t/pcf8584 does not show the correct way to address the i2c bus.
16 Based on the information on the I2C bus itself and the remainder of
17 the Phillips docs the following algorithims apper to be correct. I am
18 fairly certain that the flowcharts in the phillips docs are wrong. */
21 #include <linux/kernel.h>
22 #include <linux/string.h>
23 #include <linux/malloc.h>
24 #include <linux/errno.h>
25 #include <linux/sched.h>
26 #include <linux/wait.h>
27 #include <linux/delay.h>
28 #include <asm/openprom.h>
29 #include <asm/oplib.h>
30 #include <asm/io.h>
31 #include <asm/system.h>
32 #include <asm/sbus.h>
34 #if 0
35 #define VFC_I2C_DEBUG
36 #endif
38 #include "vfc.h"
39 #include "vfc_i2c.h"
41 #define VFC_I2C_READ (0x1)
42 #define VFC_I2C_WRITE (0x0)
44 /******
45 The i2c bus controller chip on the VFC is a pcd8584t, but
46 phillips claims it doesn't exist. As far as I can tell it is
47 identical to the PCF8584 so I treat it like it is the pcf8584.
49 NOTE: The pcf8584 only cares
50 about the msb of the word you feed it
51 *****/
53 int vfc_pcf8584_init(struct vfc_dev *dev)
55 dev->regs->i2c_s1=RESET; /* This will also choose
56 register S0_OWN so we can set it*/
58 dev->regs->i2c_reg=0x55000000; /* the pcf8584 shifts this
59 value left one bit and uses
60 it as its i2c bus address */
61 dev->regs->i2c_s1=SELECT(S2);
62 dev->regs->i2c_reg=0x14000000; /* this will set the i2c bus at
63 the same speed sun uses,
64 and set another magic bit */
66 dev->regs->i2c_s1=CLEAR_I2C_BUS; /* enable the serial port,
67 idle the i2c bus and set
68 the data reg to s0 */
69 udelay(100);
70 return 0;
73 void vfc_i2c_delay_wakeup(struct vfc_dev *dev)
75 /* Used to profile code and eliminate too many delays */
76 VFC_I2C_DEBUG_PRINTK(("vfc%d: Delaying\n",dev->instance));
77 wake_up(&dev->poll_wait);
80 void vfc_i2c_delay_no_busy(struct vfc_dev *dev,unsigned long usecs)
82 dev->poll_timer.next = NULL;
83 dev->poll_timer.prev = NULL;
84 dev->poll_timer.expires = jiffies +
85 ((unsigned long)usecs*(HZ))/1000000;
86 dev->poll_timer.data=(unsigned long)dev;
87 dev->poll_timer.function=(void *)(unsigned long)vfc_i2c_delay_wakeup;
88 add_timer(&dev->poll_timer);
89 sleep_on(&dev->poll_wait);
90 del_timer(&dev->poll_timer);
93 void inline vfc_i2c_delay(struct vfc_dev *dev)
95 vfc_i2c_delay_no_busy(dev,100);
98 int vfc_init_i2c_bus(struct vfc_dev *dev)
100 dev->regs->i2c_s1= ENABLE_SERIAL | SELECT(S0) | ACK;
101 vfc_i2c_reset_bus(dev);
102 return 0;
105 int vfc_i2c_reset_bus(struct vfc_dev *dev)
107 VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n",
108 dev->instance));
109 if(!dev) return -EINVAL;
110 if(!dev->regs) return -EINVAL;
111 dev->regs->i2c_s1=SEND_I2C_STOP;
112 dev->regs->i2c_s1=SEND_I2C_STOP | ACK;
113 vfc_i2c_delay(dev);
114 dev->regs->i2c_s1=CLEAR_I2C_BUS;
115 VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: I2C status %x\n",
116 dev->instance, dev->regs->i2c_s1));
117 return 0;
120 int vfc_i2c_wait_for_bus(struct vfc_dev *dev)
122 int timeout=1000;
124 while(!(dev->regs->i2c_s1 & BB)) {
125 if(!(timeout--)) return -ETIMEDOUT;
126 vfc_i2c_delay(dev);
128 return 0;
131 int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
133 int timeout=1000;
134 int s1;
136 while((s1=dev->regs->i2c_s1) & PIN) {
137 if(!(timeout--)) return -ETIMEDOUT;
138 vfc_i2c_delay(dev);
140 if(ack==VFC_I2C_ACK_CHECK) {
141 if(s1 & LRB) return -EIO;
143 return 0;
146 #define SHIFT(a) ((a) << 24)
147 int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode)
149 int ret,raddr;
150 #if 1
151 dev->regs->i2c_s1=SEND_I2C_STOP | ACK;
152 dev->regs->i2c_s1=SELECT(S0) | ENABLE_SERIAL;
153 vfc_i2c_delay(dev);
154 #endif
156 switch(mode) {
157 case VFC_I2C_READ:
158 dev->regs->i2c_reg=raddr=SHIFT((unsigned int)addr | 0x1);
159 VFC_I2C_DEBUG_PRINTK(("vfc%d: receiving from i2c addr 0x%x\n",
160 dev->instance,addr | 0x1));
161 break;
162 case VFC_I2C_WRITE:
163 dev->regs->i2c_reg=raddr=SHIFT((unsigned int)addr & ~0x1);
164 VFC_I2C_DEBUG_PRINTK(("vfc%d: sending to i2c addr 0x%x\n",
165 dev->instance,addr & ~0x1));
166 break;
167 default:
168 return -EINVAL;
170 dev->regs->i2c_s1 = SEND_I2C_START;
171 vfc_i2c_delay(dev);
172 ret=vfc_i2c_wait_for_pin(dev,VFC_I2C_ACK_CHECK); /* We wait
173 for the
174 i2c send
175 to finish
176 here but
178 doesn't,
179 hmm */
180 if(ret) {
181 printk(KERN_ERR "vfc%d: VFC xmit addr timed out or no ack\n",
182 dev->instance);
183 return ret;
184 } else if(mode == VFC_I2C_READ) {
185 if((ret=dev->regs->i2c_reg & 0xff000000) != raddr) {
186 printk(KERN_WARNING
187 "vfc%d: returned slave address "
188 "mismatch(%x,%x)\n",
189 dev->instance,raddr,ret);
192 return 0;
195 int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte)
197 int ret;
198 dev->regs->i2c_reg=SHIFT((unsigned int)*byte);
200 ret=vfc_i2c_wait_for_pin(dev,VFC_I2C_ACK_CHECK);
201 switch(ret) {
202 case -ETIMEDOUT:
203 printk(KERN_ERR "vfc%d: VFC xmit byte timed out or no ack\n",
204 dev->instance);
205 break;
206 case -EIO:
207 ret=XMIT_LAST_BYTE;
208 break;
209 default:
210 break;
212 return ret;
215 int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte, int last)
217 int ret;
218 if(last) {
219 dev->regs->i2c_reg=NEGATIVE_ACK;
220 VFC_I2C_DEBUG_PRINTK(("vfc%d: sending negative ack\n",
221 dev->instance));
222 } else {
223 dev->regs->i2c_s1=ACK;
226 ret=vfc_i2c_wait_for_pin(dev,VFC_I2C_NO_ACK_CHECK);
227 if(ret) {
228 printk(KERN_ERR "vfc%d: "
229 "VFC recv byte timed out\n",dev->instance);
231 *byte=(dev->regs->i2c_reg) >> 24;
232 return ret;
235 int vfc_i2c_recvbuf(struct vfc_dev *dev, unsigned char addr,
236 char *buf, int count)
238 int ret,last;
240 if(!(count && buf && dev && dev->regs) ) return -EINVAL;
242 if((ret=vfc_i2c_wait_for_bus(dev))) {
243 printk(KERN_ERR "vfc%d: VFC I2C bus busy\n",dev->instance);
244 return ret;
247 if((ret=vfc_i2c_xmit_addr(dev,addr,VFC_I2C_READ))) {
248 dev->regs->i2c_s1=SEND_I2C_STOP;
249 vfc_i2c_delay(dev);
250 return ret;
253 last=0;
254 while(count--) {
255 if(!count) last=1;
256 if((ret=vfc_i2c_recv_byte(dev,buf,last))) {
257 printk(KERN_ERR "vfc%d: "
258 "VFC error while receiving byte\n",
259 dev->instance);
260 dev->regs->i2c_s1=SEND_I2C_STOP;
261 ret=-EINVAL;
263 buf++;
266 dev->regs->i2c_s1=SEND_I2C_STOP | ACK;
267 vfc_i2c_delay(dev);
268 return ret;
271 int vfc_i2c_sendbuf(struct vfc_dev *dev, unsigned char addr,
272 char *buf, int count)
274 int ret;
276 if(!(buf && dev && dev->regs) ) return -EINVAL;
278 if((ret=vfc_i2c_wait_for_bus(dev))) {
279 printk(KERN_ERR "vfc%d: VFC I2C bus busy\n",dev->instance);
280 return ret;
283 if((ret=vfc_i2c_xmit_addr(dev,addr,VFC_I2C_WRITE))) {
284 dev->regs->i2c_s1=SEND_I2C_STOP;
285 vfc_i2c_delay(dev);
286 return ret;
289 while(count--) {
290 ret=vfc_i2c_xmit_byte(dev,buf);
291 switch(ret) {
292 case XMIT_LAST_BYTE:
293 VFC_I2C_DEBUG_PRINTK(("vfc%d: "
294 "Reciever ended transmission with "
295 " %d bytes remaining\n",
296 dev->instance,count));
297 ret=0;
298 goto done;
299 break;
300 case 0:
301 break;
302 default:
303 printk(KERN_ERR "vfc%d: "
304 "VFC error while sending byte\n",dev->instance);
305 break;
307 buf++;
309 done:
310 dev->regs->i2c_s1=SEND_I2C_STOP | ACK;
312 vfc_i2c_delay(dev);
313 return ret;