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