(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/i2c.c

    1: /*
    2:  * QEMU I2C bus interface.
    3:  *
    4:  * Copyright (c) 2007 CodeSourcery.
    5:  * Written by Paul Brook
    6:  *
    7:  * This code is licenced under the LGPL.
    8:  */
    9: 
   10: #include "hw.h"
   11: #include "i2c.h"
   12: 
   13: struct i2c_bus
   14: {
   15:     i2c_slave *current_dev;
   16:     i2c_slave *dev;
   17: };
   18: 
   19: /* Create a new I2C bus.  */
   20: i2c_bus *i2c_init_bus(void)
   21: {
   22:     i2c_bus *bus;
   23: 
   24:     bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
   25:     return bus;
   26: }
   27: 
   28: /* Create a new slave device.  */
   29: i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size)
   30: {
   31:     i2c_slave *dev;
   32: 
   33:     if (size < sizeof(i2c_slave))
   34:         hw_error("I2C struct too small");
   35: 
   36:     dev = (i2c_slave *)qemu_mallocz(size);
   37:     dev->address = address;
   38:     dev->next = bus->dev;
   39:     bus->dev = dev;
   40: 
   41:     return dev;
   42: }
   43: 
   44: void i2c_set_slave_address(i2c_slave *dev, int address)
   45: {
   46:     dev->address = address;
   47: }
   48: 
   49: /* Return nonzero if bus is busy.  */
   50: int i2c_bus_busy(i2c_bus *bus)
   51: {
   52:     return bus->current_dev != NULL;
   53: }
   54: 
   55: /* Returns non-zero if the address is not valid.  */
   56: /* TODO: Make this handle multiple masters.  */
   57: int i2c_start_transfer(i2c_bus *bus, int address, int recv)
   58: {
   59:     i2c_slave *dev;
   60: 
   61:     for (dev = bus->dev; dev; dev = dev->next) {
   62:         if (dev->address == address)
   63:             break;
   64:     }
   65: 
   66:     if (!dev)
   67:         return 1;
   68: 
   69:     /* If the bus is already busy, assume this is a repeated
   70:        start condition.  */
   71:     bus->current_dev = dev;
   72:     dev->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
   73:     return 0;
   74: }
   75: 
   76: void i2c_end_transfer(i2c_bus *bus)
   77: {
   78:     i2c_slave *dev = bus->current_dev;
   79: 
   80:     if (!dev)
   81:         return;
   82: 
   83:     dev->event(dev, I2C_FINISH);
   84: 
   85:     bus->current_dev = NULL;
   86: }
   87: 
   88: int i2c_send(i2c_bus *bus, uint8_t data)
   89: {
   90:     i2c_slave *dev = bus->current_dev;
   91: 
   92:     if (!dev)
   93:         return -1;
   94: 
   95:     return dev->send(dev, data);
   96: }
   97: 
   98: int i2c_recv(i2c_bus *bus)
   99: {
  100:     i2c_slave *dev = bus->current_dev;
  101: 
  102:     if (!dev)
  103:         return -1;
  104: 
  105:     return dev->recv(dev);
  106: }
  107: 
  108: void i2c_nack(i2c_bus *bus)
  109: {
  110:     i2c_slave *dev = bus->current_dev;
  111: 
  112:     if (!dev)
  113:         return;
  114: 
  115:     dev->event(dev, I2C_NACK);
  116: }
  117: 
  118: void i2c_bus_save(QEMUFile *f, i2c_bus *bus)
  119: {
  120:     qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00);
  121: }
  122: 
  123: void i2c_bus_load(QEMUFile *f, i2c_bus *bus)
  124: {
  125:     i2c_slave *dev;
  126:     uint8_t address = qemu_get_byte(f);
  127: 
  128:     if (address) {
  129:         for (dev = bus->dev; dev; dev = dev->next)
  130:             if (dev->address == address) {
  131:                 bus->current_dev = dev;
  132:                 return;
  133:             }
  134: 
  135:         fprintf(stderr, "%s: I2C slave with address %02x disappeared\n",
  136:                 __FUNCTION__, address);
  137:     }
  138: }
  139: 
  140: void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
  141: {
  142:     qemu_put_byte(f, dev->address);
  143: }
  144: 
  145: void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
  146: {
  147:     dev->address = qemu_get_byte(f);
  148: }
Syntax (Markdown)