blob: 32b986e0ed786c1379d3a83dbefca980693f3f9f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * drivers/sbus/char/vfc_i2c.c
3 *
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
9 *
10 * Copyright (C) 1996 Manish Vachharajani (mvachhar@noc.rutgers.edu)
11 *
12 */
13
14/* NOTE: It seems to me that the documentation regarding the
15pcd8584t/pcf8584 does not show the correct way to address the i2c bus.
16Based on the information on the I2C bus itself and the remainder of
Robert P. J. Dayd08df602007-02-17 19:07:33 +010017the Phillips docs the following algorithms appear to be correct. I am
Linus Torvalds1da177e2005-04-16 15:20:36 -070018fairly certain that the flowcharts in the phillips docs are wrong. */
19
20
21#include <linux/kernel.h>
22#include <linux/string.h>
23#include <linux/slab.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>
33
34#if 0
35#define VFC_I2C_DEBUG
36#endif
37
38#include "vfc.h"
39#include "vfc_i2c.h"
40
41#define WRITE_S1(__val) \
42 sbus_writel(__val, &dev->regs->i2c_s1)
43#define WRITE_REG(__val) \
44 sbus_writel(__val, &dev->regs->i2c_reg)
45
46#define VFC_I2C_READ (0x1)
47#define VFC_I2C_WRITE (0x0)
48
49/******
50 The i2c bus controller chip on the VFC is a pcd8584t, but
51 phillips claims it doesn't exist. As far as I can tell it is
52 identical to the PCF8584 so I treat it like it is the pcf8584.
53
54 NOTE: The pcf8584 only cares
55 about the msb of the word you feed it
56*****/
57
58int vfc_pcf8584_init(struct vfc_dev *dev)
59{
60 /* This will also choose register S0_OWN so we can set it. */
61 WRITE_S1(RESET);
62
63 /* The pcf8584 shifts this value left one bit and uses
64 * it as its i2c bus address.
65 */
66 WRITE_REG(0x55000000);
67
68 /* This will set the i2c bus at the same speed sun uses,
69 * and set another magic bit.
70 */
71 WRITE_S1(SELECT(S2));
72 WRITE_REG(0x14000000);
73
74 /* Enable the serial port, idle the i2c bus and set
75 * the data reg to s0.
76 */
77 WRITE_S1(CLEAR_I2C_BUS);
78 udelay(100);
79 return 0;
80}
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs)
83{
Nishanth Aravamudan074c5272005-09-12 14:16:17 -070084 schedule_timeout_uninterruptible(usecs_to_jiffies(usecs));
Linus Torvalds1da177e2005-04-16 15:20:36 -070085}
86
87void inline vfc_i2c_delay(struct vfc_dev *dev)
88{
89 vfc_i2c_delay_no_busy(dev, 100);
90}
91
92int vfc_init_i2c_bus(struct vfc_dev *dev)
93{
94 WRITE_S1(ENABLE_SERIAL | SELECT(S0) | ACK);
95 vfc_i2c_reset_bus(dev);
96 return 0;
97}
98
99int vfc_i2c_reset_bus(struct vfc_dev *dev)
100{
101 VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n",
102 dev->instance));
103 if(dev == NULL)
104 return -EINVAL;
105 if(dev->regs == NULL)
106 return -EINVAL;
107 WRITE_S1(SEND_I2C_STOP);
108 WRITE_S1(SEND_I2C_STOP | ACK);
109 vfc_i2c_delay(dev);
110 WRITE_S1(CLEAR_I2C_BUS);
111 VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: I2C status %x\n",
112 dev->instance,
113 sbus_readl(&dev->regs->i2c_s1)));
114 return 0;
115}
116
Adrian Bunk96068142008-06-05 11:44:39 -0700117static int vfc_i2c_wait_for_bus(struct vfc_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118{
119 int timeout = 1000;
120
121 while(!(sbus_readl(&dev->regs->i2c_s1) & BB)) {
122 if(!(timeout--))
123 return -ETIMEDOUT;
124 vfc_i2c_delay(dev);
125 }
126 return 0;
127}
128
Adrian Bunk96068142008-06-05 11:44:39 -0700129static int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130{
131 int timeout = 1000;
132 int s1;
133
134 while ((s1 = sbus_readl(&dev->regs->i2c_s1)) & PIN) {
135 if (!(timeout--))
136 return -ETIMEDOUT;
137 vfc_i2c_delay(dev);
138 }
139 if (ack == VFC_I2C_ACK_CHECK) {
140 if(s1 & LRB)
141 return -EIO;
142 }
143 return 0;
144}
145
146#define SHIFT(a) ((a) << 24)
Adrian Bunk96068142008-06-05 11:44:39 -0700147static int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr,
148 char mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149{
150 int ret, raddr;
151#if 1
152 WRITE_S1(SEND_I2C_STOP | ACK);
153 WRITE_S1(SELECT(S0) | ENABLE_SERIAL);
154 vfc_i2c_delay(dev);
155#endif
156
157 switch(mode) {
158 case VFC_I2C_READ:
159 raddr = SHIFT(((unsigned int)addr | 0x1));
160 WRITE_REG(raddr);
161 VFC_I2C_DEBUG_PRINTK(("vfc%d: receiving from i2c addr 0x%x\n",
162 dev->instance, addr | 0x1));
163 break;
164 case VFC_I2C_WRITE:
165 raddr = SHIFT((unsigned int)addr & ~0x1);
166 WRITE_REG(raddr);
167 VFC_I2C_DEBUG_PRINTK(("vfc%d: sending to i2c addr 0x%x\n",
168 dev->instance, addr & ~0x1));
169 break;
170 default:
171 return -EINVAL;
172 };
173
174 WRITE_S1(SEND_I2C_START);
175 vfc_i2c_delay(dev);
176 ret = vfc_i2c_wait_for_pin(dev,VFC_I2C_ACK_CHECK); /* We wait
177 for the
178 i2c send
179 to finish
180 here but
181 Sun
182 doesn't,
183 hmm */
184 if (ret) {
185 printk(KERN_ERR "vfc%d: VFC xmit addr timed out or no ack\n",
186 dev->instance);
187 return ret;
188 } else if (mode == VFC_I2C_READ) {
189 if ((ret = sbus_readl(&dev->regs->i2c_reg) & 0xff000000) != raddr) {
190 printk(KERN_WARNING
191 "vfc%d: returned slave address "
192 "mismatch(%x,%x)\n",
193 dev->instance, raddr, ret);
194 }
195 }
196 return 0;
197}
198
Adrian Bunk96068142008-06-05 11:44:39 -0700199static int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200{
201 int ret;
202 u32 val = SHIFT((unsigned int)*byte);
203
204 WRITE_REG(val);
205
206 ret = vfc_i2c_wait_for_pin(dev, VFC_I2C_ACK_CHECK);
207 switch(ret) {
208 case -ETIMEDOUT:
209 printk(KERN_ERR "vfc%d: VFC xmit byte timed out or no ack\n",
210 dev->instance);
211 break;
212 case -EIO:
213 ret = XMIT_LAST_BYTE;
214 break;
215 default:
216 break;
217 };
218
219 return ret;
220}
221
Adrian Bunk96068142008-06-05 11:44:39 -0700222static int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte,
223 int last)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
225 int ret;
226
227 if (last) {
228 WRITE_REG(NEGATIVE_ACK);
229 VFC_I2C_DEBUG_PRINTK(("vfc%d: sending negative ack\n",
230 dev->instance));
231 } else {
232 WRITE_S1(ACK);
233 }
234
235 ret = vfc_i2c_wait_for_pin(dev, VFC_I2C_NO_ACK_CHECK);
236 if(ret) {
237 printk(KERN_ERR "vfc%d: "
238 "VFC recv byte timed out\n",
239 dev->instance);
240 }
241 *byte = (sbus_readl(&dev->regs->i2c_reg)) >> 24;
242 return ret;
243}
244
245int vfc_i2c_recvbuf(struct vfc_dev *dev, unsigned char addr,
246 char *buf, int count)
247{
248 int ret, last;
249
250 if(!(count && buf && dev && dev->regs) )
251 return -EINVAL;
252
253 if ((ret = vfc_i2c_wait_for_bus(dev))) {
254 printk(KERN_ERR "vfc%d: VFC I2C bus busy\n", dev->instance);
255 return ret;
256 }
257
258 if ((ret = vfc_i2c_xmit_addr(dev, addr, VFC_I2C_READ))) {
259 WRITE_S1(SEND_I2C_STOP);
260 vfc_i2c_delay(dev);
261 return ret;
262 }
263
264 last = 0;
265 while (count--) {
266 if (!count)
267 last = 1;
268 if ((ret = vfc_i2c_recv_byte(dev, buf, last))) {
269 printk(KERN_ERR "vfc%d: "
270 "VFC error while receiving byte\n",
271 dev->instance);
272 WRITE_S1(SEND_I2C_STOP);
273 ret = -EINVAL;
274 }
275 buf++;
276 }
277 WRITE_S1(SEND_I2C_STOP | ACK);
278 vfc_i2c_delay(dev);
279 return ret;
280}
281
282int vfc_i2c_sendbuf(struct vfc_dev *dev, unsigned char addr,
283 char *buf, int count)
284{
285 int ret;
286
287 if (!(buf && dev && dev->regs))
288 return -EINVAL;
289
290 if ((ret = vfc_i2c_wait_for_bus(dev))) {
291 printk(KERN_ERR "vfc%d: VFC I2C bus busy\n", dev->instance);
292 return ret;
293 }
294
295 if ((ret = vfc_i2c_xmit_addr(dev, addr, VFC_I2C_WRITE))) {
296 WRITE_S1(SEND_I2C_STOP);
297 vfc_i2c_delay(dev);
298 return ret;
299 }
300
301 while(count--) {
302 ret = vfc_i2c_xmit_byte(dev, buf);
303 switch(ret) {
304 case XMIT_LAST_BYTE:
305 VFC_I2C_DEBUG_PRINTK(("vfc%d: "
306 "Receiver ended transmission with "
307 " %d bytes remaining\n",
308 dev->instance, count));
309 ret = 0;
310 goto done;
311 break;
312 case 0:
313 break;
314 default:
315 printk(KERN_ERR "vfc%d: "
316 "VFC error while sending byte\n", dev->instance);
317 break;
318 };
319
320 buf++;
321 }
322done:
323 WRITE_S1(SEND_I2C_STOP | ACK);
324 vfc_i2c_delay(dev);
325 return ret;
326}
327
328
329
330
331
332
333
334
335