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