Annotation of qemu/hw/versatile_i2c.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * ARM Versatile I2C controller
                      3:  *
                      4:  * Copyright (c) 2006-2007 CodeSourcery.
                      5:  * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
                      6:  *
                      7:  * This file is derived from hw/realview.c by Paul Brook
                      8:  *
                      9:  * This program is free software; you can redistribute it and/or
                     10:  * modify it under the terms of the GNU General Public License
                     11:  * as published by the Free Software Foundation; either version 2
                     12:  * of the License, or (at your option) any later version.
                     13:  *
                     14:  * This program is distributed in the hope that it will be useful,
                     15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17:  * GNU General Public License for more details.
                     18:  *
                     19:  * You should have received a copy of the GNU General Public License
                     20:  * along with this program; if not, see <http://www.gnu.org/licenses/>.
                     21:  *
                     22:  */
                     23: 
                     24: #include "sysbus.h"
                     25: #include "bitbang_i2c.h"
                     26: 
                     27: typedef struct {
                     28:     SysBusDevice busdev;
                     29:     MemoryRegion iomem;
                     30:     bitbang_i2c_interface *bitbang;
                     31:     int out;
                     32:     int in;
                     33: } VersatileI2CState;
                     34: 
                     35: static uint64_t versatile_i2c_read(void *opaque, target_phys_addr_t offset,
                     36:                                    unsigned size)
                     37: {
                     38:     VersatileI2CState *s = (VersatileI2CState *)opaque;
                     39: 
                     40:     if (offset == 0) {
                     41:         return (s->out & 1) | (s->in << 1);
                     42:     } else {
                     43:         hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset);
                     44:         return -1;
                     45:     }
                     46: }
                     47: 
                     48: static void versatile_i2c_write(void *opaque, target_phys_addr_t offset,
                     49:                                 uint64_t value, unsigned size)
                     50: {
                     51:     VersatileI2CState *s = (VersatileI2CState *)opaque;
                     52: 
                     53:     switch (offset) {
                     54:     case 0:
                     55:         s->out |= value & 3;
                     56:         break;
                     57:     case 4:
                     58:         s->out &= ~value;
                     59:         break;
                     60:     default:
                     61:         hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset);
                     62:     }
                     63:     bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
                     64:     s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
                     65: }
                     66: 
                     67: static const MemoryRegionOps versatile_i2c_ops = {
                     68:     .read = versatile_i2c_read,
                     69:     .write = versatile_i2c_write,
                     70:     .endianness = DEVICE_NATIVE_ENDIAN,
                     71: };
                     72: 
                     73: static int versatile_i2c_init(SysBusDevice *dev)
                     74: {
                     75:     VersatileI2CState *s = FROM_SYSBUS(VersatileI2CState, dev);
                     76:     i2c_bus *bus;
                     77: 
                     78:     bus = i2c_init_bus(&dev->qdev, "i2c");
                     79:     s->bitbang = bitbang_i2c_init(bus);
                     80:     memory_region_init_io(&s->iomem, &versatile_i2c_ops, s,
                     81:                           "versatile_i2c", 0x1000);
                     82:     sysbus_init_mmio(dev, &s->iomem);
                     83:     return 0;
                     84: }
                     85: 
                     86: static void versatile_i2c_class_init(ObjectClass *klass, void *data)
                     87: {
                     88:     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
                     89: 
                     90:     k->init = versatile_i2c_init;
                     91: }
                     92: 
                     93: static const TypeInfo versatile_i2c_info = {
                     94:     .name          = "versatile_i2c",
                     95:     .parent        = TYPE_SYS_BUS_DEVICE,
                     96:     .instance_size = sizeof(VersatileI2CState),
                     97:     .class_init    = versatile_i2c_class_init,
                     98: };
                     99: 
                    100: static void versatile_i2c_register_types(void)
                    101: {
                    102:     type_register_static(&versatile_i2c_info);
                    103: }
                    104: 
                    105: type_init(versatile_i2c_register_types)

unix.superglobalmegacorp.com