]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/ppc/platforms/pmac_low_i2c.c
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.git] / arch / ppc / platforms / pmac_low_i2c.c
1 /*
2 * arch/ppc/platforms/pmac_low_i2c.c
3 *
4 * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * This file contains some low-level i2c access routines that
12 * need to be used by various bits of the PowerMac platform code
13 * at times where the real asynchronous & interrupt driven driver
14 * cannot be used. The API borrows some semantics from the darwin
15 * driver in order to ease the implementation of the platform
16 * properties parser
17 */
18
19 #include <linux/config.h>
20 #include <linux/types.h>
21 #include <linux/delay.h>
22 #include <linux/sched.h>
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/adb.h>
26 #include <linux/pmu.h>
27 #include <asm/keylargo.h>
28 #include <asm/uninorth.h>
29 #include <asm/io.h>
30 #include <asm/prom.h>
31 #include <asm/machdep.h>
32 #include <asm/pmac_low_i2c.h>
33
34 #define MAX_LOW_I2C_HOST 4
35
36 #if 1
37 #define DBG(x...) do {\
38 printk(KERN_DEBUG "KW:" x); \
39 } while(0)
40 #else
41 #define DBGG(x...)
42 #endif
43
44 struct low_i2c_host;
45
46 typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
47
48 struct low_i2c_host
49 {
50 struct device_node *np; /* OF device node */
51 struct semaphore mutex; /* Access mutex for use by i2c-keywest */
52 low_i2c_func_t func; /* Access function */
53 int is_open : 1; /* Poor man's access control */
54 int mode; /* Current mode */
55 int channel; /* Current channel */
56 int num_channels; /* Number of channels */
57 unsigned long base; /* For keywest-i2c, base address */
58 int bsteps; /* And register stepping */
59 int speed; /* And speed */
60 };
61
62 static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST];
63
64 /* No locking is necessary on allocation, we are running way before
65 * anything can race with us
66 */
67 static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
68 {
69 int i;
70
71 for (i = 0; i < MAX_LOW_I2C_HOST; i++)
72 if (low_i2c_hosts[i].np == np)
73 return &low_i2c_hosts[i];
74 return NULL;
75 }
76
77 /*
78 *
79 * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
80 *
81 */
82
83 /*
84 * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
85 * should be moved somewhere in include/asm-ppc/
86 */
87 /* Register indices */
88 typedef enum {
89 reg_mode = 0,
90 reg_control,
91 reg_status,
92 reg_isr,
93 reg_ier,
94 reg_addr,
95 reg_subaddr,
96 reg_data
97 } reg_t;
98
99
100 /* Mode register */
101 #define KW_I2C_MODE_100KHZ 0x00
102 #define KW_I2C_MODE_50KHZ 0x01
103 #define KW_I2C_MODE_25KHZ 0x02
104 #define KW_I2C_MODE_DUMB 0x00
105 #define KW_I2C_MODE_STANDARD 0x04
106 #define KW_I2C_MODE_STANDARDSUB 0x08
107 #define KW_I2C_MODE_COMBINED 0x0C
108 #define KW_I2C_MODE_MODE_MASK 0x0C
109 #define KW_I2C_MODE_CHAN_MASK 0xF0
110
111 /* Control register */
112 #define KW_I2C_CTL_AAK 0x01
113 #define KW_I2C_CTL_XADDR 0x02
114 #define KW_I2C_CTL_STOP 0x04
115 #define KW_I2C_CTL_START 0x08
116
117 /* Status register */
118 #define KW_I2C_STAT_BUSY 0x01
119 #define KW_I2C_STAT_LAST_AAK 0x02
120 #define KW_I2C_STAT_LAST_RW 0x04
121 #define KW_I2C_STAT_SDA 0x08
122 #define KW_I2C_STAT_SCL 0x10
123
124 /* IER & ISR registers */
125 #define KW_I2C_IRQ_DATA 0x01
126 #define KW_I2C_IRQ_ADDR 0x02
127 #define KW_I2C_IRQ_STOP 0x04
128 #define KW_I2C_IRQ_START 0x08
129 #define KW_I2C_IRQ_MASK 0x0F
130
131 /* State machine states */
132 enum {
133 state_idle,
134 state_addr,
135 state_read,
136 state_write,
137 state_stop,
138 state_dead
139 };
140
141 #define WRONG_STATE(name) do {\
142 printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
143 name, __kw_state_names[state], isr); \
144 } while(0)
145
146 static const char *__kw_state_names[] = {
147 "state_idle",
148 "state_addr",
149 "state_read",
150 "state_write",
151 "state_stop",
152 "state_dead"
153 };
154
155 static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
156 {
157 return in_8(((volatile u8 *)host->base)
158 + (((unsigned)reg) << host->bsteps));
159 }
160
161 static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
162 {
163 out_8(((volatile u8 *)host->base)
164 + (((unsigned)reg) << host->bsteps), val);
165 (void)__kw_read_reg(host, reg_subaddr);
166 }
167
168 #define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
169 #define kw_read_reg(reg) __kw_read_reg(host, reg)
170
171
172 /* Don't schedule, the g5 fan controller is too
173 * timing sensitive
174 */
175 static u8 kw_wait_interrupt(struct low_i2c_host* host)
176 {
177 int i;
178 u8 isr;
179
180 for (i = 0; i < 200000; i++) {
181 isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
182 if (isr != 0)
183 return isr;
184 udelay(1);
185 }
186 return isr;
187 }
188
189 static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
190 {
191 u8 ack;
192
193 if (isr == 0) {
194 if (state != state_stop) {
195 DBG("KW: Timeout !\n");
196 *rc = -EIO;
197 goto stop;
198 }
199 if (state == state_stop) {
200 ack = kw_read_reg(reg_status);
201 if (!(ack & KW_I2C_STAT_BUSY)) {
202 state = state_idle;
203 kw_write_reg(reg_ier, 0x00);
204 }
205 }
206 return state;
207 }
208
209 if (isr & KW_I2C_IRQ_ADDR) {
210 ack = kw_read_reg(reg_status);
211 if (state != state_addr) {
212 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
213 WRONG_STATE("KW_I2C_IRQ_ADDR");
214 *rc = -EIO;
215 goto stop;
216 }
217 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
218 *rc = -ENODEV;
219 DBG("KW: NAK on address\n");
220 return state_stop;
221 } else {
222 if (rw) {
223 state = state_read;
224 if (*len > 1)
225 kw_write_reg(reg_control, KW_I2C_CTL_AAK);
226 } else {
227 state = state_write;
228 kw_write_reg(reg_data, **data);
229 (*data)++; (*len)--;
230 }
231 }
232 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
233 }
234
235 if (isr & KW_I2C_IRQ_DATA) {
236 if (state == state_read) {
237 **data = kw_read_reg(reg_data);
238 (*data)++; (*len)--;
239 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
240 if ((*len) == 0)
241 state = state_stop;
242 else if ((*len) == 1)
243 kw_write_reg(reg_control, 0);
244 } else if (state == state_write) {
245 ack = kw_read_reg(reg_status);
246 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
247 DBG("KW: nack on data write\n");
248 *rc = -EIO;
249 goto stop;
250 } else if (*len) {
251 kw_write_reg(reg_data, **data);
252 (*data)++; (*len)--;
253 } else {
254 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
255 state = state_stop;
256 *rc = 0;
257 }
258 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
259 } else {
260 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
261 WRONG_STATE("KW_I2C_IRQ_DATA");
262 if (state != state_stop) {
263 *rc = -EIO;
264 goto stop;
265 }
266 }
267 }
268
269 if (isr & KW_I2C_IRQ_STOP) {
270 kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
271 if (state != state_stop) {
272 WRONG_STATE("KW_I2C_IRQ_STOP");
273 *rc = -EIO;
274 }
275 return state_idle;
276 }
277
278 if (isr & KW_I2C_IRQ_START)
279 kw_write_reg(reg_isr, KW_I2C_IRQ_START);
280
281 return state;
282
283 stop:
284 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
285 return state_stop;
286 }
287
288 static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
289 {
290 u8 mode_reg = host->speed;
291 int state = state_addr;
292 int rc = 0;
293
294 /* Setup mode & subaddress if any */
295 switch(host->mode) {
296 case pmac_low_i2c_mode_dumb:
297 printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
298 return -EINVAL;
299 case pmac_low_i2c_mode_std:
300 mode_reg |= KW_I2C_MODE_STANDARD;
301 break;
302 case pmac_low_i2c_mode_stdsub:
303 mode_reg |= KW_I2C_MODE_STANDARDSUB;
304 kw_write_reg(reg_subaddr, subaddr);
305 break;
306 case pmac_low_i2c_mode_combined:
307 mode_reg |= KW_I2C_MODE_COMBINED;
308 kw_write_reg(reg_subaddr, subaddr);
309 break;
310 }
311
312 /* Setup channel & clear pending irqs */
313 kw_write_reg(reg_isr, kw_read_reg(reg_isr));
314 kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
315 kw_write_reg(reg_status, 0);
316
317 /* Set up address and r/w bit */
318 kw_write_reg(reg_addr, addr);
319
320 /* Start sending address & disable interrupt*/
321 kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
322 kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
323
324 /* State machine, to turn into an interrupt handler */
325 while(state != state_idle) {
326 u8 isr = kw_wait_interrupt(host);
327 state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
328 }
329
330 return rc;
331 }
332
333 static void keywest_low_i2c_add(struct device_node *np)
334 {
335 struct low_i2c_host *host = find_low_i2c_host(NULL);
336 unsigned long *psteps, *prate, steps, aoffset = 0;
337 struct device_node *parent;
338
339 if (host == NULL) {
340 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
341 np->full_name);
342 return;
343 }
344 memset(host, 0, sizeof(*host));
345
346 init_MUTEX(&host->mutex);
347 host->np = of_node_get(np);
348 psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
349 steps = psteps ? (*psteps) : 0x10;
350 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
351 steps >>= 1;
352 parent = of_get_parent(np);
353 host->num_channels = 1;
354 if (parent && parent->name[0] == 'u') {
355 host->num_channels = 2;
356 aoffset = 3;
357 }
358 /* Select interface rate */
359 host->speed = KW_I2C_MODE_100KHZ;
360 prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
361 if (prate) switch(*prate) {
362 case 100:
363 host->speed = KW_I2C_MODE_100KHZ;
364 break;
365 case 50:
366 host->speed = KW_I2C_MODE_50KHZ;
367 break;
368 case 25:
369 host->speed = KW_I2C_MODE_25KHZ;
370 break;
371 }
372 host->mode = pmac_low_i2c_mode_std;
373 host->base = (unsigned long)ioremap(np->addrs[0].address + aoffset,
374 np->addrs[0].size);
375 host->func = keywest_low_i2c_func;
376 }
377
378 /*
379 *
380 * PMU implementation
381 *
382 */
383
384
385 #ifdef CONFIG_ADB_PMU
386
387 static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
388 {
389 // TODO
390 return -ENODEV;
391 }
392
393 static void pmu_low_i2c_add(struct device_node *np)
394 {
395 struct low_i2c_host *host = find_low_i2c_host(NULL);
396
397 if (host == NULL) {
398 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
399 np->full_name);
400 return;
401 }
402 memset(host, 0, sizeof(*host));
403
404 init_MUTEX(&host->mutex);
405 host->np = of_node_get(np);
406 host->num_channels = 3;
407 host->mode = pmac_low_i2c_mode_std;
408 host->func = pmu_low_i2c_func;
409 }
410
411 #endif /* CONFIG_ADB_PMU */
412
413 void __init pmac_init_low_i2c(void)
414 {
415 struct device_node *np;
416
417 /* Probe keywest-i2c busses */
418 np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
419 while(np) {
420 keywest_low_i2c_add(np);
421 np = of_find_compatible_node(np, "i2c", "keywest-i2c");
422 }
423
424 #ifdef CONFIG_ADB_PMU
425 /* Probe PMU busses */
426 np = of_find_node_by_name(NULL, "via-pmu");
427 if (np)
428 pmu_low_i2c_add(np);
429 #endif /* CONFIG_ADB_PMU */
430
431 /* TODO: Add CUDA support as well */
432 }
433
434 int pmac_low_i2c_lock(struct device_node *np)
435 {
436 struct low_i2c_host *host = find_low_i2c_host(np);
437
438 if (!host)
439 return -ENODEV;
440 down(&host->mutex);
441 return 0;
442 }
443 EXPORT_SYMBOL(pmac_low_i2c_lock);
444
445 int pmac_low_i2c_unlock(struct device_node *np)
446 {
447 struct low_i2c_host *host = find_low_i2c_host(np);
448
449 if (!host)
450 return -ENODEV;
451 up(&host->mutex);
452 return 0;
453 }
454 EXPORT_SYMBOL(pmac_low_i2c_unlock);
455
456
457 int pmac_low_i2c_open(struct device_node *np, int channel)
458 {
459 struct low_i2c_host *host = find_low_i2c_host(np);
460
461 if (!host)
462 return -ENODEV;
463
464 if (channel >= host->num_channels)
465 return -EINVAL;
466
467 down(&host->mutex);
468 host->is_open = 1;
469 host->channel = channel;
470
471 return 0;
472 }
473 EXPORT_SYMBOL(pmac_low_i2c_open);
474
475 int pmac_low_i2c_close(struct device_node *np)
476 {
477 struct low_i2c_host *host = find_low_i2c_host(np);
478
479 if (!host)
480 return -ENODEV;
481
482 host->is_open = 0;
483 up(&host->mutex);
484
485 return 0;
486 }
487 EXPORT_SYMBOL(pmac_low_i2c_close);
488
489 int pmac_low_i2c_setmode(struct device_node *np, int mode)
490 {
491 struct low_i2c_host *host = find_low_i2c_host(np);
492
493 if (!host)
494 return -ENODEV;
495 WARN_ON(!host->is_open);
496 host->mode = mode;
497
498 return 0;
499 }
500 EXPORT_SYMBOL(pmac_low_i2c_setmode);
501
502 int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
503 {
504 struct low_i2c_host *host = find_low_i2c_host(np);
505
506 if (!host)
507 return -ENODEV;
508 WARN_ON(!host->is_open);
509
510 return host->func(host, addrdir, subaddr, data, len);
511 }
512 EXPORT_SYMBOL(pmac_low_i2c_xfer);
513