1/* $Id: bbc_i2c.c,v 1.1.1.1 2007/08/03 18:52:55 Exp $
2 * bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III
3 *            platforms.
4 *
5 * Copyright (C) 2001 David S. Miller (davem@redhat.com)
6 */
7
8#include <linux/module.h>
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/slab.h>
12#include <linux/sched.h>
13#include <linux/wait.h>
14#include <linux/delay.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <asm/oplib.h>
18#include <asm/ebus.h>
19#include <asm/spitfire.h>
20#include <asm/bbc.h>
21#include <asm/io.h>
22
23#include "bbc_i2c.h"
24
25/* Convert this driver to use i2c bus layer someday... */
26#define I2C_PCF_PIN	0x80
27#define I2C_PCF_ESO	0x40
28#define I2C_PCF_ES1	0x20
29#define I2C_PCF_ES2	0x10
30#define I2C_PCF_ENI	0x08
31#define I2C_PCF_STA	0x04
32#define I2C_PCF_STO	0x02
33#define I2C_PCF_ACK	0x01
34
35#define I2C_PCF_START    (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ENI | I2C_PCF_STA | I2C_PCF_ACK)
36#define I2C_PCF_STOP     (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK)
37#define I2C_PCF_REPSTART (              I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK)
38#define I2C_PCF_IDLE     (I2C_PCF_PIN | I2C_PCF_ESO               | I2C_PCF_ACK)
39
40#define I2C_PCF_INI 0x40   /* 1 if not initialized */
41#define I2C_PCF_STS 0x20
42#define I2C_PCF_BER 0x10
43#define I2C_PCF_AD0 0x08
44#define I2C_PCF_LRB 0x08
45#define I2C_PCF_AAS 0x04
46#define I2C_PCF_LAB 0x02
47#define I2C_PCF_BB  0x01
48
49/* The BBC devices have two I2C controllers.  The first I2C controller
50 * connects mainly to configuration proms (NVRAM, cpu configuration,
51 * dimm types, etc.).  Whereas the second I2C controller connects to
52 * environmental control devices such as fans and temperature sensors.
53 * The second controller also connects to the smartcard reader, if present.
54 */
55
56#define NUM_CHILDREN	8
57struct bbc_i2c_bus {
58	struct bbc_i2c_bus		*next;
59	int				index;
60	spinlock_t			lock;
61	void				__iomem *i2c_bussel_reg;
62	void				__iomem *i2c_control_regs;
63	unsigned char			own, clock;
64
65	wait_queue_head_t		wq;
66	volatile int			waiting;
67
68	struct linux_ebus_device	*bus_edev;
69	struct {
70		struct linux_ebus_child	*device;
71		int			client_claimed;
72	} devs[NUM_CHILDREN];
73};
74
75static struct bbc_i2c_bus *all_bbc_i2c;
76
77struct bbc_i2c_client {
78	struct bbc_i2c_bus	*bp;
79	struct linux_ebus_child	*echild;
80	int			bus;
81	int			address;
82};
83
84static int find_device(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild)
85{
86	int i;
87
88	for (i = 0; i < NUM_CHILDREN; i++) {
89		if (bp->devs[i].device == echild) {
90			if (bp->devs[i].client_claimed)
91				return 0;
92			return 1;
93		}
94	}
95	return 0;
96}
97
98static void set_device_claimage(struct bbc_i2c_bus *bp, struct linux_ebus_child *echild, int val)
99{
100	int i;
101
102	for (i = 0; i < NUM_CHILDREN; i++) {
103		if (bp->devs[i].device == echild) {
104			bp->devs[i].client_claimed = val;
105			return;
106		}
107	}
108}
109
110#define claim_device(BP,ECHILD)		set_device_claimage(BP,ECHILD,1)
111#define release_device(BP,ECHILD)	set_device_claimage(BP,ECHILD,0)
112
113static struct bbc_i2c_bus *find_bus_for_device(struct linux_ebus_child *echild)
114{
115	struct bbc_i2c_bus *bp = all_bbc_i2c;
116
117	while (bp != NULL) {
118		if (find_device(bp, echild) != 0)
119			break;
120		bp = bp->next;
121	}
122
123	return bp;
124}
125
126struct linux_ebus_child *bbc_i2c_getdev(int index)
127{
128	struct bbc_i2c_bus *bp = all_bbc_i2c;
129	struct linux_ebus_child *echild = NULL;
130	int curidx = 0;
131
132	while (bp != NULL) {
133		struct bbc_i2c_bus *next = bp->next;
134		int i;
135
136		for (i = 0; i < NUM_CHILDREN; i++) {
137			if (!(echild = bp->devs[i].device))
138				break;
139			if (curidx == index)
140				goto out;
141			echild = NULL;
142			curidx++;
143		}
144		bp = next;
145	}
146out:
147	if (curidx == index)
148		return echild;
149	return NULL;
150}
151
152struct bbc_i2c_client *bbc_i2c_attach(struct linux_ebus_child *echild)
153{
154	struct bbc_i2c_bus *bp = find_bus_for_device(echild);
155	struct bbc_i2c_client *client;
156
157	if (!bp)
158		return NULL;
159	client = kmalloc(sizeof(*client), GFP_KERNEL);
160	if (!client)
161		return NULL;
162	memset(client, 0, sizeof(*client));
163	client->bp = bp;
164	client->echild = echild;
165	client->bus = echild->resource[0].start;
166	client->address = echild->resource[1].start;
167
168	claim_device(bp, echild);
169
170	return client;
171}
172
173void bbc_i2c_detach(struct bbc_i2c_client *client)
174{
175	struct bbc_i2c_bus *bp = client->bp;
176	struct linux_ebus_child *echild = client->echild;
177
178	release_device(bp, echild);
179	kfree(client);
180}
181
182static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
183{
184	DECLARE_WAITQUEUE(wait, current);
185	int limit = 32;
186	int ret = 1;
187
188	bp->waiting = 1;
189	add_wait_queue(&bp->wq, &wait);
190	while (limit-- > 0) {
191		unsigned long val;
192
193		val = wait_event_interruptible_timeout(
194				bp->wq,
195				(((*status = readb(bp->i2c_control_regs + 0))
196				  & I2C_PCF_PIN) == 0),
197				msecs_to_jiffies(250));
198		if (val > 0) {
199			ret = 0;
200			break;
201		}
202	}
203	remove_wait_queue(&bp->wq, &wait);
204	bp->waiting = 0;
205
206	return ret;
207}
208
209int bbc_i2c_writeb(struct bbc_i2c_client *client, unsigned char val, int off)
210{
211	struct bbc_i2c_bus *bp = client->bp;
212	int address = client->address;
213	u8 status;
214	int ret = -1;
215
216	if (bp->i2c_bussel_reg != NULL)
217		writeb(client->bus, bp->i2c_bussel_reg);
218
219	writeb(address, bp->i2c_control_regs + 0x1);
220	writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
221	if (wait_for_pin(bp, &status))
222		goto out;
223
224	writeb(off, bp->i2c_control_regs + 0x1);
225	if (wait_for_pin(bp, &status) ||
226	    (status & I2C_PCF_LRB) != 0)
227		goto out;
228
229	writeb(val, bp->i2c_control_regs + 0x1);
230	if (wait_for_pin(bp, &status))
231		goto out;
232
233	ret = 0;
234
235out:
236	writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
237	return ret;
238}
239
240int bbc_i2c_readb(struct bbc_i2c_client *client, unsigned char *byte, int off)
241{
242	struct bbc_i2c_bus *bp = client->bp;
243	unsigned char address = client->address, status;
244	int ret = -1;
245
246	if (bp->i2c_bussel_reg != NULL)
247		writeb(client->bus, bp->i2c_bussel_reg);
248
249	writeb(address, bp->i2c_control_regs + 0x1);
250	writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
251	if (wait_for_pin(bp, &status))
252		goto out;
253
254	writeb(off, bp->i2c_control_regs + 0x1);
255	if (wait_for_pin(bp, &status) ||
256	    (status & I2C_PCF_LRB) != 0)
257		goto out;
258
259	writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
260
261	address |= 0x1; /* READ */
262
263	writeb(address, bp->i2c_control_regs + 0x1);
264	writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
265	if (wait_for_pin(bp, &status))
266		goto out;
267
268	/* Set PIN back to one so the device sends the first
269	 * byte.
270	 */
271	(void) readb(bp->i2c_control_regs + 0x1);
272	if (wait_for_pin(bp, &status))
273		goto out;
274
275	writeb(I2C_PCF_ESO | I2C_PCF_ENI, bp->i2c_control_regs + 0x0);
276	*byte = readb(bp->i2c_control_regs + 0x1);
277	if (wait_for_pin(bp, &status))
278		goto out;
279
280	ret = 0;
281
282out:
283	writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
284	(void) readb(bp->i2c_control_regs + 0x1);
285
286	return ret;
287}
288
289int bbc_i2c_write_buf(struct bbc_i2c_client *client,
290		      char *buf, int len, int off)
291{
292	int ret = 0;
293
294	while (len > 0) {
295		int err = bbc_i2c_writeb(client, *buf, off);
296
297		if (err < 0) {
298			ret = err;
299			break;
300		}
301
302		len--;
303		buf++;
304		off++;
305	}
306	return ret;
307}
308
309int bbc_i2c_read_buf(struct bbc_i2c_client *client,
310		     char *buf, int len, int off)
311{
312	int ret = 0;
313
314	while (len > 0) {
315		int err = bbc_i2c_readb(client, buf, off);
316		if (err < 0) {
317			ret = err;
318			break;
319		}
320		len--;
321		buf++;
322		off++;
323	}
324
325	return ret;
326}
327
328EXPORT_SYMBOL(bbc_i2c_getdev);
329EXPORT_SYMBOL(bbc_i2c_attach);
330EXPORT_SYMBOL(bbc_i2c_detach);
331EXPORT_SYMBOL(bbc_i2c_writeb);
332EXPORT_SYMBOL(bbc_i2c_readb);
333EXPORT_SYMBOL(bbc_i2c_write_buf);
334EXPORT_SYMBOL(bbc_i2c_read_buf);
335
336static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id)
337{
338	struct bbc_i2c_bus *bp = dev_id;
339
340	/* PIN going from set to clear is the only event which
341	 * makes the i2c assert an interrupt.
342	 */
343	if (bp->waiting &&
344	    !(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN))
345		wake_up_interruptible(&bp->wq);
346
347	return IRQ_HANDLED;
348}
349
350static void __init reset_one_i2c(struct bbc_i2c_bus *bp)
351{
352	writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
353	writeb(bp->own, bp->i2c_control_regs + 0x1);
354	writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
355	writeb(bp->clock, bp->i2c_control_regs + 0x1);
356	writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0);
357}
358
359static int __init attach_one_i2c(struct linux_ebus_device *edev, int index)
360{
361	struct bbc_i2c_bus *bp = kmalloc(sizeof(*bp), GFP_KERNEL);
362	struct linux_ebus_child *echild;
363	int entry;
364
365	if (!bp)
366		return -ENOMEM;
367	memset(bp, 0, sizeof(*bp));
368
369	bp->i2c_control_regs = ioremap(edev->resource[0].start, 0x2);
370	if (!bp->i2c_control_regs)
371		goto fail;
372
373	if (edev->num_addrs == 2) {
374		bp->i2c_bussel_reg = ioremap(edev->resource[1].start, 0x1);
375		if (!bp->i2c_bussel_reg)
376			goto fail;
377	}
378
379	bp->waiting = 0;
380	init_waitqueue_head(&bp->wq);
381	if (request_irq(edev->irqs[0], bbc_i2c_interrupt,
382			IRQF_SHARED, "bbc_i2c", bp))
383		goto fail;
384
385	bp->index = index;
386	bp->bus_edev = edev;
387
388	spin_lock_init(&bp->lock);
389	bp->next = all_bbc_i2c;
390	all_bbc_i2c = bp;
391
392	entry = 0;
393	for (echild = edev->children;
394	     echild && entry < 8;
395	     echild = echild->next, entry++) {
396		bp->devs[entry].device = echild;
397		bp->devs[entry].client_claimed = 0;
398	}
399
400	writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0);
401	bp->own = readb(bp->i2c_control_regs + 0x01);
402	writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0);
403	bp->clock = readb(bp->i2c_control_regs + 0x01);
404
405	printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n",
406	       bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock);
407
408	reset_one_i2c(bp);
409
410	return 0;
411
412fail:
413	if (bp->i2c_bussel_reg)
414		iounmap(bp->i2c_bussel_reg);
415	if (bp->i2c_control_regs)
416		iounmap(bp->i2c_control_regs);
417	kfree(bp);
418	return -EINVAL;
419}
420
421static int __init bbc_present(void)
422{
423	struct linux_ebus *ebus = NULL;
424	struct linux_ebus_device *edev = NULL;
425
426	for_each_ebus(ebus) {
427		for_each_ebusdev(edev, ebus) {
428			if (!strcmp(edev->prom_node->name, "bbc"))
429				return 1;
430		}
431	}
432	return 0;
433}
434
435extern int bbc_envctrl_init(void);
436extern void bbc_envctrl_cleanup(void);
437static void bbc_i2c_cleanup(void);
438
439static int __init bbc_i2c_init(void)
440{
441	struct linux_ebus *ebus = NULL;
442	struct linux_ebus_device *edev = NULL;
443	int err, index = 0;
444
445	if ((tlb_type != cheetah && tlb_type != cheetah_plus) ||
446	    !bbc_present())
447		return -ENODEV;
448
449	for_each_ebus(ebus) {
450		for_each_ebusdev(edev, ebus) {
451			if (!strcmp(edev->prom_node->name, "i2c")) {
452				if (!attach_one_i2c(edev, index))
453					index++;
454			}
455		}
456	}
457
458	if (!index)
459		return -ENODEV;
460
461	err = bbc_envctrl_init();
462	if (err)
463		bbc_i2c_cleanup();
464	return err;
465}
466
467static void bbc_i2c_cleanup(void)
468{
469	struct bbc_i2c_bus *bp = all_bbc_i2c;
470
471	bbc_envctrl_cleanup();
472
473	while (bp != NULL) {
474		struct bbc_i2c_bus *next = bp->next;
475
476		free_irq(bp->bus_edev->irqs[0], bp);
477
478		if (bp->i2c_bussel_reg)
479			iounmap(bp->i2c_bussel_reg);
480		if (bp->i2c_control_regs)
481			iounmap(bp->i2c_control_regs);
482
483		kfree(bp);
484
485		bp = next;
486	}
487	all_bbc_i2c = NULL;
488}
489
490module_init(bbc_i2c_init);
491module_exit(bbc_i2c_cleanup);
492MODULE_LICENSE("GPL");
493