~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to debian/patches/linaro-patches-1.5.0/0030-SPI-devices-convert-to-qdev.patch

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From f92321d5d80ca6920ca37f010a71e9ac3ad4cc01 Mon Sep 17 00:00:00 2001
2
 
From: Peter Maydell <peter.maydell@linaro.org>
3
 
Date: Mon, 18 Feb 2013 16:58:28 +0000
4
 
Subject: [PATCH 30/69] SPI devices: convert to qdev
5
 
MIME-Version: 1.0
6
 
Content-Type: text/plain; charset=UTF-8
7
 
Content-Transfer-Encoding: 8bit
8
 
 
9
 
Introduce a new SPI bus type, and use it to convert
10
 
all the OMAP SPI devices to qdev.
11
 
 
12
 
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
13
 
---
14
 
 hw/arm/nseries.c      |  90 ++++++++++++++++++++------------
15
 
 hw/arm/omap2.c        |  34 +++++++-----
16
 
 hw/input/tsc2005.c    |  62 +++++++++++++++-------
17
 
 hw/input/tsc210x.c    | 113 +++++++++++++++++++++++++++-------------
18
 
 hw/ssi/Makefile.objs  |   1 +
19
 
 hw/ssi/omap_spi.c     | 140 +++++++++++++++++++++++++++++++++-----------------
20
 
 hw/ssi/spi.c          | 121 +++++++++++++++++++++++++++++++++++++++++++
21
 
 include/hw/arm/omap.h |  14 ++---
22
 
 include/hw/devices.h  |  11 ++--
23
 
 include/hw/spi.h      |  62 ++++++++++++++++++++++
24
 
 10 files changed, 482 insertions(+), 166 deletions(-)
25
 
 create mode 100644 hw/ssi/spi.c
26
 
 create mode 100644 include/hw/spi.h
27
 
 
28
 
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
29
 
index 6478501..f4218f0 100644
30
 
--- a/hw/arm/nseries.c
31
 
+++ b/hw/arm/nseries.c
32
 
@@ -28,6 +28,7 @@
33
 
 #include "hw/i2c/i2c.h"
34
 
 #include "hw/devices.h"
35
 
 #include "hw/block/flash.h"
36
 
+#include "hw/spi.h"
37
 
 #include "hw/hw.h"
38
 
 #include "hw/bt.h"
39
 
 #include "hw/loader.h"
40
 
@@ -40,11 +41,8 @@ struct n800_s {
41
 
     struct omap_mpu_state_s *mpu;
42
 
 
43
 
     struct rfbi_chip_s blizzard;
44
 
-    struct {
45
 
-        void *opaque;
46
 
-        uint32_t (*txrx)(void *opaque, uint32_t value, int len);
47
 
-        uWireSlave *chip;
48
 
-    } ts;
49
 
+    DeviceState *mipid;
50
 
+    DeviceState *tsc;
51
 
 
52
 
     int keymap[0x80];
53
 
     DeviceState *kbd;
54
 
@@ -244,7 +242,7 @@ static void n800_key_event(void *opaque, int keycode)
55
 
         return;
56
 
     }
57
 
 
58
 
-    tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
59
 
+    tsc2301_key_event(s->tsc, code, !(keycode & 0x80));
60
 
 }
61
 
 
62
 
 static const int n800_keys[16] = {
63
 
@@ -272,13 +270,12 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
64
 
 
65
 
     /* XXX: are the three pins inverted inside the chip between the
66
 
      * tsc and the cpu (N4111)?  */
67
 
-    qemu_irq penirq = NULL;    /* NC */
68
 
-    qemu_irq kbirq = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_KP_IRQ_GPIO);
69
 
-    qemu_irq dav = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_TS_GPIO);
70
 
-
71
 
-    s->ts.chip = tsc2301_init(penirq, kbirq, dav);
72
 
-    s->ts.opaque = s->ts.chip->opaque;
73
 
-    s->ts.txrx = tsc210x_txrx;
74
 
+    s->tsc = spi_create_device(omap_mcspi_bus(s->mpu->mcspi, 0), "tsc2301", 0);
75
 
+    /* penirq NC */
76
 
+    qdev_connect_gpio_out(s->tsc, 1, qdev_get_gpio_in(s->mpu->gpio,
77
 
+                                                      N800_TSC_KP_IRQ_GPIO));
78
 
+    qdev_connect_gpio_out(s->tsc, 2, qdev_get_gpio_in(s->mpu->gpio,
79
 
+                                                      N800_TSC_TS_GPIO));
80
 
 
81
 
     for (i = 0; i < 0x80; i ++)
82
 
         s->keymap[i] = -1;
83
 
@@ -288,17 +285,15 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
84
 
 
85
 
     qemu_add_kbd_event_handler(n800_key_event, s);
86
 
 
87
 
-    tsc210x_set_transform(s->ts.chip, &n800_pointercal);
88
 
+    tsc2301_set_transform(s->tsc, &n800_pointercal);
89
 
 }
90
 
 
91
 
 static void n810_tsc_setup(struct n800_s *s)
92
 
 {
93
 
-    qemu_irq pintdav = qdev_get_gpio_in(s->mpu->gpio, N810_TSC_TS_GPIO);
94
 
-
95
 
-    s->ts.opaque = tsc2005_init(pintdav);
96
 
-    s->ts.txrx = tsc2005_txrx;
97
 
-
98
 
-    tsc2005_set_transform(s->ts.opaque, &n810_pointercal, 400, 4000);
99
 
+    s->tsc = spi_create_device(omap_mcspi_bus(s->mpu->mcspi, 0), "tsc2005", 0);
100
 
+    qdev_connect_gpio_out(s->tsc, 0, qdev_get_gpio_in(s->mpu->gpio,
101
 
+                                                      N810_TSC_TS_GPIO));
102
 
+    tsc2005_set_transform(s->tsc, &n810_pointercal, 400, 4000);
103
 
 }
104
 
 
105
 
 /* N810 Keyboard controller */
106
 
@@ -405,6 +400,7 @@ static void n810_kbd_setup(struct n800_s *s)
107
 
 
108
 
 /* LCD MIPI DBI-C controller (URAL) */
109
 
 struct mipid_s {
110
 
+    SPIDevice spi;
111
 
     int resp[4];
112
 
     int param[4];
113
 
     int p;
114
 
@@ -424,8 +420,11 @@ struct mipid_s {
115
 
     uint32_t id;
116
 
 };
117
 
 
118
 
-static void mipid_reset(struct mipid_s *s)
119
 
+static void mipid_reset(DeviceState *qdev)
120
 
 {
121
 
+    struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s,
122
 
+                                        SPI_DEVICE_FROM_QDEV(qdev));
123
 
+
124
 
     s->pm = 0;
125
 
     s->cmd = 0;
126
 
 
127
 
@@ -444,9 +443,9 @@ static void mipid_reset(struct mipid_s *s)
128
 
     s->gamma = 0;
129
 
 }
130
 
 
131
 
-static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
132
 
+static uint32_t mipid_txrx(SPIDevice *spidev, uint32_t cmd, int len)
133
 
 {
134
 
-    struct mipid_s *s = (struct mipid_s *) opaque;
135
 
+    struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s, spidev);
136
 
     uint8_t ret;
137
 
 
138
 
     if (len > 9)
139
 
@@ -466,7 +465,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
140
 
         break;
141
 
 
142
 
     case 0x01: /* SWRESET */
143
 
-        mipid_reset(s);
144
 
+        mipid_reset(&s->spi.qdev);
145
 
         break;
146
 
 
147
 
     case 0x02: /* BSTROFF */
148
 
@@ -670,23 +669,40 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
149
 
     return ret;
150
 
 }
151
 
 
152
 
-static void *mipid_init(void)
153
 
+static int mipid_init(SPIDevice *spidev)
154
 
 {
155
 
-    struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s));
156
 
+    return 0;
157
 
+}
158
 
+
159
 
+static Property mipid_properties[] = {
160
 
+    DEFINE_PROP_UINT32("id", struct mipid_s, id, 0),
161
 
+    DEFINE_PROP_END_OF_LIST()
162
 
+};
163
 
 
164
 
-    s->id = 0x838f03;
165
 
-    mipid_reset(s);
166
 
+static void mipid_class_init(ObjectClass *klass, void *data)
167
 
+{
168
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
169
 
+    SPIDeviceClass *k = SPI_DEVICE_CLASS(klass);
170
 
 
171
 
-    return s;
172
 
+    k->init = mipid_init;
173
 
+    k->txrx = mipid_txrx;
174
 
+    dc->reset = mipid_reset;
175
 
+    dc->props = mipid_properties;
176
 
 }
177
 
 
178
 
+static TypeInfo mipid_info = {
179
 
+    .name = "lcd_mipid",
180
 
+    .parent = TYPE_SPI_DEVICE,
181
 
+    .instance_size = sizeof(struct mipid_s),
182
 
+    .class_init = mipid_class_init,
183
 
+};
184
 
+
185
 
 static void n8x0_spi_setup(struct n800_s *s)
186
 
 {
187
 
-    void *tsc = s->ts.opaque;
188
 
-    void *mipid = mipid_init();
189
 
-
190
 
-    omap_mcspi_attach(s->mpu->mcspi[0], s->ts.txrx, tsc, 0);
191
 
-    omap_mcspi_attach(s->mpu->mcspi[0], mipid_txrx, mipid, 1);
192
 
+    s->mipid = spi_create_device_noinit(omap_mcspi_bus(s->mpu->mcspi, 0),
193
 
+                                        "lcd_mipid", 1);
194
 
+    qdev_prop_set_uint32(s->mipid, "id", 0x838f03);
195
 
+    qdev_init_nofail(s->mipid);
196
 
 }
197
 
 
198
 
 /* This task is normally performed by the bootloader.  If we're loading
199
 
@@ -1406,10 +1422,16 @@ static QEMUMachine n810_machine = {
200
 
     DEFAULT_MACHINE_OPTIONS,
201
 
 };
202
 
 
203
 
+static void nseries_register_types(void)
204
 
+{
205
 
+    type_register_static(&mipid_info);
206
 
+}
207
 
+
208
 
 static void nseries_machine_init(void)
209
 
 {
210
 
     qemu_register_machine(&n800_machine);
211
 
     qemu_register_machine(&n810_machine);
212
 
 }
213
 
 
214
 
+type_init(nseries_register_types);
215
 
 machine_init(nseries_machine_init);
216
 
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
217
 
index cd53ec6..6c21886 100644
218
 
--- a/hw/arm/omap2.c
219
 
+++ b/hw/arm/omap2.c
220
 
@@ -2220,8 +2220,6 @@ static void omap2_mpu_reset(void *opaque)
221
 
     omap_uart_reset(mpu->uart[1]);
222
 
     omap_uart_reset(mpu->uart[2]);
223
 
     omap_mmc_reset(mpu->mmc);
224
 
-    omap_mcspi_reset(mpu->mcspi[0]);
225
 
-    omap_mcspi_reset(mpu->mcspi[1]);
226
 
     cpu_reset(CPU(mpu->cpu));
227
 
 }
228
 
 
229
 
@@ -2464,16 +2462,28 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
230
 
                     &s->drq[OMAP24XX_DMA_MMC1_TX],
231
 
                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
232
 
 
233
 
-    s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), s, 4,
234
 
-                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ),
235
 
-                    &s->drq[OMAP24XX_DMA_SPI1_TX0],
236
 
-                    omap_findclk(s, "spi1_fclk"),
237
 
-                    omap_findclk(s, "spi1_iclk"));
238
 
-    s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), s, 2,
239
 
-                    qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ),
240
 
-                    &s->drq[OMAP24XX_DMA_SPI2_TX0],
241
 
-                    omap_findclk(s, "spi2_fclk"),
242
 
-                    omap_findclk(s, "spi2_iclk"));
243
 
+    s->mcspi = qdev_create(NULL, "omap_mcspi");
244
 
+    qdev_prop_set_int32(s->mcspi, "mpu_model", s->mpu_model);
245
 
+    qdev_init_nofail(s->mcspi);
246
 
+    busdev = SYS_BUS_DEVICE(s->mcspi);
247
 
+    sysbus_connect_irq(busdev, 0,
248
 
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ));
249
 
+    sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_SPI1_TX0]);
250
 
+    sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_SPI1_RX0]);
251
 
+    sysbus_connect_irq(busdev, 3, s->drq[OMAP24XX_DMA_SPI1_TX1]);
252
 
+    sysbus_connect_irq(busdev, 4, s->drq[OMAP24XX_DMA_SPI1_RX1]);
253
 
+    sysbus_connect_irq(busdev, 5, s->drq[OMAP24XX_DMA_SPI1_TX2]);
254
 
+    sysbus_connect_irq(busdev, 6, s->drq[OMAP24XX_DMA_SPI1_RX2]);
255
 
+    sysbus_connect_irq(busdev, 7, s->drq[OMAP24XX_DMA_SPI1_TX3]);
256
 
+    sysbus_connect_irq(busdev, 8, s->drq[OMAP24XX_DMA_SPI1_RX3]);
257
 
+    sysbus_connect_irq(busdev, 9,
258
 
+                       qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ));
259
 
+    sysbus_connect_irq(busdev, 10, s->drq[OMAP24XX_DMA_SPI2_TX0]);
260
 
+    sysbus_connect_irq(busdev, 11, s->drq[OMAP24XX_DMA_SPI2_RX0]);
261
 
+    sysbus_connect_irq(busdev, 12, s->drq[OMAP24XX_DMA_SPI2_TX1]);
262
 
+    sysbus_connect_irq(busdev, 13, s->drq[OMAP24XX_DMA_SPI2_RX1]);
263
 
+    sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4ta(s->l4, 35), 0));
264
 
+    sysbus_mmio_map(busdev, 1, omap_l4_region_base(omap_l4ta(s->l4, 36), 0));
265
 
 
266
 
     s->dss = omap_dss_init(omap_l4ta(s->l4, 10), sysmem, 0x68000800,
267
 
                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
268
 
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
269
 
index 89168a3..7e7fa59 100644
270
 
--- a/hw/input/tsc2005.c
271
 
+++ b/hw/input/tsc2005.c
272
 
@@ -22,6 +22,7 @@
273
 
 #include "qemu/timer.h"
274
 
 #include "ui/console.h"
275
 
 #include "hw/devices.h"
276
 
+#include "hw/spi.h"
277
 
 
278
 
 //#define TSC2005_DEBUG
279
 
 
280
 
@@ -35,6 +36,7 @@
281
 
 #define TSC_CUT_RESOLUTION(value, p)   ((value) >> (16 - (p ? 12 : 10)))
282
 
 
283
 
 typedef struct {
284
 
+    SPIDevice spi;
285
 
     qemu_irq pint;     /* Combination of the nPENIRQ and DAV signals */
286
 
     QEMUTimer *timer;
287
 
     uint16_t model;
288
 
@@ -326,8 +328,10 @@ static void tsc2005_pin_update(TSC2005State *s)
289
 
     }
290
 
 }
291
 
 
292
 
-static void tsc2005_reset(TSC2005State *s)
293
 
+static void tsc2005_reset(DeviceState *qdev)
294
 
 {
295
 
+    TSC2005State *s = FROM_SPI_DEVICE(TSC2005State,
296
 
+                                      SPI_DEVICE_FROM_QDEV(qdev));
297
 
     s->state = 0;
298
 
     s->pin_func = 0;
299
 
     s->enabled = 0;
300
 
@@ -350,18 +354,17 @@ static void tsc2005_reset(TSC2005State *s)
301
 
     tsc2005_pin_update(s);
302
 
 }
303
 
 
304
 
-static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
305
 
+static uint8_t tsc2005_txrx_word(TSC2005State *s, uint8_t value)
306
 
 {
307
 
-    TSC2005State *s = opaque;
308
 
     uint32_t ret = 0;
309
 
     TRACE("value = 0x%08x, state=%d", value, s->state + 1);
310
 
     switch (s->state ++) {
311
 
     case 0:
312
 
         if (value & 0x80) {
313
 
             /* Command */
314
 
-            if (value & (1 << 1))
315
 
-                tsc2005_reset(s);
316
 
-            else {
317
 
+            if (value & (1 << 1)) {
318
 
+                tsc2005_reset(&s->spi.qdev);
319
 
+            } else {
320
 
                 s->nextfunction = (value >> 3) & 0xf;
321
 
                 s->nextprecision = (value >> 2) & 1;
322
 
                 if (s->enabled != !(value & 1)) {
323
 
@@ -415,14 +418,15 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
324
 
     return ret;
325
 
 }
326
 
 
327
 
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len)
328
 
+static uint32_t tsc2005_txrx(SPIDevice *spidev, uint32_t value, int len)
329
 
 {
330
 
+    TSC2005State *s = FROM_SPI_DEVICE(TSC2005State, spidev);
331
 
     uint32_t ret = 0;
332
 
     TRACE("value=0x%08x, len=%d", value, len);
333
 
     len &= ~7;
334
 
     while (len > 0) {
335
 
         len -= 8;
336
 
-        ret |= tsc2005_txrx_word(opaque, (value >> len) & 0xff) << len;
337
 
+        ret |= tsc2005_txrx_word(s, (value >> len) & 0xff) << len;
338
 
     }
339
 
 
340
 
     return ret;
341
 
@@ -578,18 +582,16 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
342
 
     return 0;
343
 
 }
344
 
 
345
 
-void *tsc2005_init(qemu_irq pintdav)
346
 
+static int tsc2005_init(SPIDevice *spidev)
347
 
 {
348
 
-    TSC2005State *s;
349
 
+    TSC2005State *s = FROM_SPI_DEVICE(TSC2005State, spidev);
350
 
 
351
 
-    s = (TSC2005State *)
352
 
-            g_malloc0(sizeof(TSC2005State));
353
 
     s->x = 400;
354
 
     s->y = 240;
355
 
     s->pressure = 0;
356
 
     s->precision = s->nextprecision = 0;
357
 
     s->timer = qemu_new_timer_ns(vm_clock, tsc2005_timer_tick, s);
358
 
-    s->pint = pintdav;
359
 
+    qdev_init_gpio_out(&spidev->qdev, &s->pint, 1);
360
 
     s->model = 0x2005;
361
 
 
362
 
     s->tr[0] = 0;
363
 
@@ -604,15 +606,12 @@ void *tsc2005_init(qemu_irq pintdav)
364
 
     s->z1_cons = 400;
365
 
     s->z2_cons = 4000;
366
 
 
367
 
-    tsc2005_reset(s);
368
 
-
369
 
     qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, 1,
370
 
                     "QEMU TSC2005-driven Touchscreen");
371
 
 
372
 
-    qemu_register_reset((void *) tsc2005_reset, s);
373
 
     register_savevm(NULL, "tsc2005", -1, 0, tsc2005_save, tsc2005_load, s);
374
 
 
375
 
-    return s;
376
 
+    return 0;
377
 
 }
378
 
 
379
 
 /*
380
 
@@ -620,10 +619,11 @@ void *tsc2005_init(qemu_irq pintdav)
381
 
  * from the touchscreen.  Assuming 12-bit precision was used during
382
 
  * tslib calibration.
383
 
  */
384
 
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info,
385
 
+void tsc2005_set_transform(DeviceState *qdev, MouseTransformInfo *info,
386
 
                            int z1_cons, int z2_cons)
387
 
 {
388
 
-    TSC2005State *s = (TSC2005State *) opaque;
389
 
+    TSC2005State *s = FROM_SPI_DEVICE(TSC2005State,
390
 
+                                      SPI_DEVICE_FROM_QDEV(qdev));
391
 
 
392
 
     /* This version assumes touchscreen X & Y axis are parallel or
393
 
      * perpendicular to LCD's  X & Y axis in some way.  */
394
 
@@ -657,3 +657,27 @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info,
395
 
     s->z1_cons = z1_cons;
396
 
     s->z2_cons = z2_cons;
397
 
 }
398
 
+
399
 
+static void tsc2005_class_init(ObjectClass *klass, void *data)
400
 
+{
401
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
402
 
+    SPIDeviceClass *k = SPI_DEVICE_CLASS(klass);
403
 
+
404
 
+    k->init = tsc2005_init;
405
 
+    k->txrx = tsc2005_txrx;
406
 
+    dc->reset = tsc2005_reset;
407
 
+}
408
 
+
409
 
+static TypeInfo tsc2005_info = {
410
 
+    .name = "tsc2005",
411
 
+    .parent = TYPE_SPI_DEVICE,
412
 
+    .instance_size = sizeof(TSC2005State),
413
 
+    .class_init = tsc2005_class_init,
414
 
+};
415
 
+
416
 
+static void tsc2005_register_types(void)
417
 
+{
418
 
+    type_register_static(&tsc2005_info);
419
 
+}
420
 
+
421
 
+type_init(tsc2005_register_types)
422
 
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
423
 
index 9b854e7..a801fcf 100644
424
 
--- a/hw/input/tsc210x.c
425
 
+++ b/hw/input/tsc210x.c
426
 
@@ -25,6 +25,7 @@
427
 
 #include "ui/console.h"
428
 
 #include "hw/arm/omap.h"       /* For I2SCodec and uWireSlave */
429
 
 #include "hw/devices.h"
430
 
+#include "hw/spi.h"
431
 
 
432
 
 #define TSC_DATA_REGISTERS_PAGE                0x0
433
 
 #define TSC_CONTROL_REGISTERS_PAGE     0x1
434
 
@@ -35,9 +36,7 @@
435
 
 #define TSC_CUT_RESOLUTION(value, p)   ((value) >> (16 - resolution[p]))
436
 
 
437
 
 typedef struct {
438
 
-    qemu_irq pint;
439
 
-    qemu_irq kbint;
440
 
-    qemu_irq davint;
441
 
+    qemu_irq irq[3]; /* pint, kbint, davint */
442
 
     QEMUTimer *timer;
443
 
     QEMUSoundCard card;
444
 
     uWireSlave chip;
445
 
@@ -49,7 +48,7 @@ typedef struct {
446
 
     int x, y;
447
 
     int pressure;
448
 
 
449
 
-    int state, page, offset, irq;
450
 
+    int state, page, offset, pint;
451
 
     uint16_t command, dav;
452
 
 
453
 
     int busy;
454
 
@@ -94,6 +93,11 @@ typedef struct {
455
 
     } kb;
456
 
 } TSC210xState;
457
 
 
458
 
+typedef struct {
459
 
+    SPIDevice spi;
460
 
+    TSC210xState tsc210x;
461
 
+} TSC2301State;
462
 
+
463
 
 static const int resolution[4] = { 12, 8, 10, 12 };
464
 
 
465
 
 #define TSC_MODE_NO_SCAN       0x0
466
 
@@ -160,7 +164,7 @@ static void tsc210x_reset(TSC210xState *s)
467
 
     s->nextfunction = 0;
468
 
     s->ref = 0;
469
 
     s->timing = 0;
470
 
-    s->irq = 0;
471
 
+    s->pint = 0;
472
 
     s->dav = 0;
473
 
 
474
 
     s->audio_ctrl1 = 0x0000;
475
 
@@ -204,9 +208,15 @@ static void tsc210x_reset(TSC210xState *s)
476
 
     s->kb.mode = 3;
477
 
     s->kb.intr = 0;
478
 
 
479
 
-    qemu_set_irq(s->pint, !s->irq);
480
 
-    qemu_set_irq(s->davint, !s->dav);
481
 
-    qemu_irq_raise(s->kbint);
482
 
+    qemu_set_irq(s->irq[0], !s->pint);
483
 
+    qemu_set_irq(s->irq[2], !s->dav);
484
 
+    qemu_irq_raise(s->irq[1]);
485
 
+}
486
 
+
487
 
+static void tsc2301_reset(DeviceState *qdev)
488
 
+{
489
 
+    tsc210x_reset(&FROM_SPI_DEVICE(TSC2301State,
490
 
+                                   SPI_DEVICE_FROM_QDEV(qdev))->tsc210x);
491
 
 }
492
 
 
493
 
 typedef struct {
494
 
@@ -383,7 +393,7 @@ static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
495
 
         if ((s->model & 0xff00) == 0x2300) {
496
 
             if (s->kb.intr && (s->kb.mode & 2)) {
497
 
                 s->kb.intr = 0;
498
 
-                qemu_irq_raise(s->kbint);
499
 
+                qemu_irq_raise(s->irq[1]);
500
 
             }
501
 
             return s->kb.down;
502
 
         }
503
 
@@ -609,7 +619,7 @@ static void tsc2102_control_register_write(
504
 
             s->kb.debounce = (value >> 11) & 7;
505
 
             if (s->kb.intr && s->kb.scan) {
506
 
                 s->kb.intr = 0;
507
 
-                qemu_irq_raise(s->kbint);
508
 
+                qemu_irq_raise(s->irq[1]);
509
 
             }
510
 
         }
511
 
         return;
512
 
@@ -819,9 +829,9 @@ static void tsc210x_pin_update(TSC210xState *s)
513
 
     if (!s->enabled)
514
 
         pin_state = 0;
515
 
 
516
 
-    if (pin_state != s->irq) {
517
 
-        s->irq = pin_state;
518
 
-        qemu_set_irq(s->pint, !s->irq);
519
 
+    if (pin_state != s->pint) {
520
 
+        s->pint = pin_state;
521
 
+        qemu_set_irq(s->irq[0], !s->pint);
522
 
     }
523
 
 
524
 
     switch (s->nextfunction) {
525
 
@@ -879,7 +889,7 @@ static uint16_t tsc210x_read(TSC210xState *s)
526
 
     case TSC_DATA_REGISTERS_PAGE:
527
 
         ret = tsc2102_data_register_read(s, s->offset);
528
 
         if (!s->dav)
529
 
-            qemu_irq_raise(s->davint);
530
 
+            qemu_irq_raise(s->irq[2]);
531
 
         break;
532
 
     case TSC_CONTROL_REGISTERS_PAGE:
533
 
         ret = tsc2102_control_register_read(s, s->offset);
534
 
@@ -933,9 +943,9 @@ static void tsc210x_write(TSC210xState *s, uint16_t value)
535
 
     }
536
 
 }
537
 
 
538
 
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
539
 
+static uint32_t tsc2301_txrx(SPIDevice *spidev, uint32_t value, int len)
540
 
 {
541
 
-    TSC210xState *s = opaque;
542
 
+    TSC210xState *s = &FROM_SPI_DEVICE(TSC2301State, spidev)->tsc210x;
543
 
     uint32_t ret = 0;
544
 
 
545
 
     if (len != 16)
546
 
@@ -964,7 +974,7 @@ static void tsc210x_timer_tick(void *opaque)
547
 
     s->busy = 0;
548
 
     s->dav |= mode_regs[s->function];
549
 
     tsc210x_pin_update(s);
550
 
-    qemu_irq_lower(s->davint);
551
 
+    qemu_irq_lower(s->irq[2]);
552
 
 }
553
 
 
554
 
 static void tsc210x_touchscreen_event(void *opaque,
555
 
@@ -1017,7 +1027,7 @@ static void tsc210x_save(QEMUFile *f, void *opaque)
556
 
     qemu_put_byte(f, s->offset);
557
 
     qemu_put_byte(f, s->command);
558
 
 
559
 
-    qemu_put_byte(f, s->irq);
560
 
+    qemu_put_byte(f, s->pint);
561
 
     qemu_put_be16s(f, &s->dav);
562
 
 
563
 
     qemu_put_timer(f, s->timer);
564
 
@@ -1063,7 +1073,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
565
 
     s->offset = qemu_get_byte(f);
566
 
     s->command = qemu_get_byte(f);
567
 
 
568
 
-    s->irq = qemu_get_byte(f);
569
 
+    s->pint = qemu_get_byte(f);
570
 
     qemu_get_be16s(f, &s->dav);
571
 
 
572
 
     qemu_get_timer(f, s->timer);
573
 
@@ -1094,8 +1104,8 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
574
 
         qemu_get_be16s(f, &s->filter_data[i]);
575
 
 
576
 
     s->busy = qemu_timer_pending(s->timer);
577
 
-    qemu_set_irq(s->pint, !s->irq);
578
 
-    qemu_set_irq(s->davint, !s->dav);
579
 
+    qemu_set_irq(s->irq[0], !s->pint);
580
 
+    qemu_set_irq(s->irq[2], !s->dav);
581
 
 
582
 
     return 0;
583
 
 }
584
 
@@ -1112,7 +1122,7 @@ uWireSlave *tsc2102_init(qemu_irq pint)
585
 
     s->pressure = 0;
586
 
     s->precision = s->nextprecision = 0;
587
 
     s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
588
 
-    s->pint = pint;
589
 
+    s->irq[0] = pint;
590
 
     s->model = 0x2102;
591
 
     s->name = "tsc2102";
592
 
 
593
 
@@ -1149,21 +1159,16 @@ uWireSlave *tsc2102_init(qemu_irq pint)
594
 
     return &s->chip;
595
 
 }
596
 
 
597
 
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
598
 
+static int tsc2301_init(SPIDevice *spidev)
599
 
 {
600
 
-    TSC210xState *s;
601
 
+    TSC210xState *s = &FROM_SPI_DEVICE(TSC2301State, spidev)->tsc210x;
602
 
 
603
 
-    s = (TSC210xState *)
604
 
-            g_malloc0(sizeof(TSC210xState));
605
 
-    memset(s, 0, sizeof(TSC210xState));
606
 
     s->x = 400;
607
 
     s->y = 240;
608
 
     s->pressure = 0;
609
 
     s->precision = s->nextprecision = 0;
610
 
     s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
611
 
-    s->pint = penirq;
612
 
-    s->kbint = kbirq;
613
 
-    s->davint = dav;
614
 
+    qdev_init_gpio_out(&spidev->qdev, s->irq, 3);
615
 
     s->model = 0x2301;
616
 
     s->name = "tsc2301";
617
 
 
618
 
@@ -1186,17 +1191,36 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
619
 
     s->codec.in.fifo = s->in_fifo;
620
 
     s->codec.out.fifo = s->out_fifo;
621
 
 
622
 
-    tsc210x_reset(s);
623
 
-
624
 
     qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
625
 
                     "QEMU TSC2301-driven Touchscreen");
626
 
 
627
 
     AUD_register_card(s->name, &s->card);
628
 
 
629
 
-    qemu_register_reset((void *) tsc210x_reset, s);
630
 
     register_savevm(NULL, s->name, -1, 0, tsc210x_save, tsc210x_load, s);
631
 
 
632
 
-    return &s->chip;
633
 
+    return 0;
634
 
+}
635
 
+
636
 
+static void tsc2301_class_init(ObjectClass *klass, void *data)
637
 
+{
638
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
639
 
+    SPIDeviceClass *k = SPI_DEVICE_CLASS(klass);
640
 
+
641
 
+    k->init = tsc2301_init;
642
 
+    k->txrx = tsc2301_txrx;
643
 
+    dc->reset = tsc2301_reset;
644
 
+}
645
 
+
646
 
+static TypeInfo tsc2301_info = {
647
 
+    .name = "tsc2301",
648
 
+    .parent = TYPE_SPI_DEVICE,
649
 
+    .instance_size = sizeof(TSC2301State),
650
 
+    .class_init = tsc2301_class_init,
651
 
+};
652
 
+
653
 
+static void tsc210x_register_types(void)
654
 
+{
655
 
+    type_register_static(&tsc2301_info);
656
 
 }
657
 
 
658
 
 I2SCodec *tsc210x_codec(uWireSlave *chip)
659
 
@@ -1273,6 +1297,14 @@ void tsc210x_set_transform(uWireSlave *chip,
660
 
 #endif
661
 
 }
662
 
 
663
 
+void tsc2301_set_transform(DeviceState *qdev, MouseTransformInfo *info)
664
 
+{
665
 
+    tsc210x_set_transform(
666
 
+        &FROM_SPI_DEVICE(TSC2301State,
667
 
+                         SPI_DEVICE_FROM_QDEV(qdev))->tsc210x.chip,
668
 
+        info);
669
 
+}
670
 
+
671
 
 void tsc210x_key_event(uWireSlave *chip, int key, int down)
672
 
 {
673
 
     TSC210xState *s = (TSC210xState *) chip->opaque;
674
 
@@ -1284,10 +1316,19 @@ void tsc210x_key_event(uWireSlave *chip, int key, int down)
675
 
 
676
 
     if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
677
 
         s->kb.intr = 1;
678
 
-        qemu_irq_lower(s->kbint);
679
 
+        qemu_irq_lower(s->irq[1]);
680
 
     } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
681
 
                     !(s->kb.mode & 1)) {
682
 
         s->kb.intr = 0;
683
 
-        qemu_irq_raise(s->kbint);
684
 
+        qemu_irq_raise(s->irq[1]);
685
 
     }
686
 
 }
687
 
+
688
 
+void tsc2301_key_event(DeviceState *qdev, int key, int down)
689
 
+{
690
 
+    TSC2301State *s = FROM_SPI_DEVICE(TSC2301State,
691
 
+                                      SPI_DEVICE_FROM_QDEV(qdev));
692
 
+    tsc210x_key_event(&s->tsc210x.chip, key, down);
693
 
+}
694
 
+
695
 
+type_init(tsc210x_register_types)
696
 
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
697
 
index 9555825..c89c2a7 100644
698
 
--- a/hw/ssi/Makefile.objs
699
 
+++ b/hw/ssi/Makefile.objs
700
 
@@ -2,5 +2,6 @@ common-obj-$(CONFIG_PL022) += pl022.o
701
 
 common-obj-$(CONFIG_SSI) += ssi.o
702
 
 common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
703
 
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
704
 
+common-obj-$(CONFIG_SSI) += spi.o
705
 
 
706
 
 obj-$(CONFIG_OMAP) += omap_spi.o
707
 
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
708
 
index 7a79df4..d9f2e0e 100644
709
 
--- a/hw/ssi/omap_spi.c
710
 
+++ b/hw/ssi/omap_spi.c
711
 
@@ -21,6 +21,8 @@
712
 
  */
713
 
 #include "hw/hw.h"
714
 
 #include "hw/arm/omap.h"
715
 
+#include "hw/sysbus.h"
716
 
+#include "hw/spi.h"
717
 
 
718
 
 //#define SPI_DEBUG
719
 
 
720
 
@@ -36,7 +38,8 @@
721
 
 #define SPI_REV_OMAP3430 0x21
722
 
 #define IS_OMAP3_SPI(s) ((s)->revision >= SPI_REV_OMAP3430)
723
 
 
724
 
-struct omap_mcspi_s {
725
 
+typedef struct omap_mcspi_bus_s {
726
 
+    SPIBus *bus;
727
 
     MemoryRegion iomem;
728
 
     qemu_irq irq;
729
 
     int chnum;
730
 
@@ -62,8 +65,6 @@ struct omap_mcspi_s {
731
 
     struct omap_mcspi_ch_s {
732
 
         qemu_irq txdrq;
733
 
         qemu_irq rxdrq;
734
 
-        uint32_t (*txrx)(void *opaque, uint32_t, int);
735
 
-        void *opaque;
736
 
 
737
 
         uint32_t tx;
738
 
         uint32_t rx;
739
 
@@ -71,15 +72,22 @@ struct omap_mcspi_s {
740
 
         uint32_t config;
741
 
         uint32_t status;
742
 
         uint32_t control;
743
 
-    } ch[0];
744
 
-};
745
 
+    } *ch;
746
 
+} OMAPSPIBusState;
747
 
+
748
 
+typedef struct omap_mcspi_s {
749
 
+    SysBusDevice busdev;
750
 
+    int mpu_model;
751
 
+    int buscount;
752
 
+    OMAPSPIBusState *bus;
753
 
+} OMAPSPIState;
754
 
 
755
 
-static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
756
 
+static inline void omap_mcspi_interrupt_update(OMAPSPIBusState *s)
757
 
 {
758
 
     qemu_set_irq(s->irq, s->irqst & s->irqen);
759
 
 }
760
 
 
761
 
-static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_s *s,
762
 
+static inline void omap_mcspi_dmarequest_update(OMAPSPIBusState *s,
763
 
                                                 int chnum)
764
 
 {
765
 
     struct omap_mcspi_ch_s *ch = &s->ch[chnum];
766
 
@@ -107,7 +115,7 @@ static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_s *s,
767
 
     }
768
 
 }
769
 
 
770
 
-static void omap_mcspi_fifo_reset(struct omap_mcspi_s *s)
771
 
+static void omap_mcspi_fifo_reset(OMAPSPIBusState *s)
772
 
 {
773
 
     struct omap_mcspi_ch_s *ch;
774
 
 
775
 
@@ -156,7 +164,7 @@ static void omap_mcspi_fifo_put(struct omap_mcspi_fifo_s *s, int wl,
776
 
     }
777
 
 }
778
 
 
779
 
-static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
780
 
+static void omap_mcspi_transfer_run(OMAPSPIBusState *s, int chnum)
781
 
 {
782
 
     struct omap_mcspi_ch_s *ch = s->ch + chnum;
783
 
     int trm = (ch->config >> 12) & 3;
784
 
@@ -172,21 +180,20 @@ static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
785
 
 
786
 
     if (!(s->control & 1) ||        /* SINGLE */
787
 
         (ch->config & (1 << 20))) { /* FORCE */
788
 
-        if (ch->txrx) {
789
 
             wl = 1 + (0x1f & (ch->config >> 7)); /* WL */
790
 
             if (!IS_OMAP3_SPI(s) || s->fifo_ch != chnum ||
791
 
                 !((ch->config >> 27) & 3)) {     /* FFER | FFEW */
792
 
-                ch->rx = ch->txrx(ch->opaque, ch->tx, wl);
793
 
+                ch->rx = spi_txrx(s->bus, chnum, ch->tx, wl);
794
 
             } else {
795
 
                 switch ((ch->config >> 27) & 3) {
796
 
                 case 1: /* !FFER, FFEW */
797
 
                     if (trm != 1)
798
 
                         ch->tx = omap_mcspi_fifo_get(&s->tx_fifo, wl);
799
 
-                    ch->rx = ch->txrx(ch->opaque, ch->tx, wl);
800
 
+                    ch->rx = spi_txrx(s->bus, chnum, ch->tx, wl);
801
 
                     s->fifo_wcnt--;
802
 
                     break;
803
 
                 case 2: /* FFER, !FFEW */
804
 
-                    ch->rx = ch->txrx(ch->opaque, ch->tx, wl);
805
 
+                    ch->rx = spi_txrx(s->bus, chnum, ch->tx, wl);
806
 
                     if (trm != 2)
807
 
                         omap_mcspi_fifo_put(&s->rx_fifo, wl, ch->rx);
808
 
                     s->fifo_wcnt--;
809
 
@@ -196,7 +203,7 @@ static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
810
 
                            s->tx_fifo.len && s->fifo_wcnt) {
811
 
                         if (trm != 1)
812
 
                             ch->tx = omap_mcspi_fifo_get(&s->tx_fifo, wl);
813
 
-                        ch->rx = ch->txrx(ch->opaque, ch->tx, wl);
814
 
+                        ch->rx = spi_txrx(s->bus, chnum, ch->tx, wl);
815
 
                         if (trm != 2)
816
 
                             omap_mcspi_fifo_put(&s->rx_fifo, wl, ch->rx);
817
 
                         s->fifo_wcnt--;
818
 
@@ -217,7 +224,6 @@ static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
819
 
                     ((s->xferlevel >> 16) & 0xffff))   /* WCNT */
820
 
                     s->irqst |= 1 << 17;               /* EOW */
821
 
             }
822
 
-        }
823
 
     }
824
 
 
825
 
     ch->tx = 0;
826
 
@@ -242,7 +248,7 @@ intr_update:
827
 
     omap_mcspi_dmarequest_update(s, chnum);
828
 
 }
829
 
 
830
 
-void omap_mcspi_reset(struct omap_mcspi_s *s)
831
 
+static void omap_mcspi_bus_reset(OMAPSPIBusState *s)
832
 
 {
833
 
     int ch;
834
 
 
835
 
@@ -270,7 +276,7 @@ void omap_mcspi_reset(struct omap_mcspi_s *s)
836
 
 static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
837
 
                                 unsigned size)
838
 
 {
839
 
-    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
840
 
+    OMAPSPIBusState *s = (OMAPSPIBusState *) opaque;
841
 
     int ch = 0;
842
 
     uint32_t ret;
843
 
 
844
 
@@ -415,7 +421,7 @@ static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
845
 
 static void omap_mcspi_write(void *opaque, hwaddr addr,
846
 
                              uint64_t value, unsigned size)
847
 
 {
848
 
-    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
849
 
+    OMAPSPIBusState *s = (OMAPSPIBusState *) opaque;
850
 
     uint32_t old;
851
 
     int ch = 0;
852
 
 
853
 
@@ -441,7 +447,7 @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
854
 
     case 0x10: /* MCSPI_SYSCONFIG */
855
 
         TRACE("SYSCONFIG = 0x%08x", value);
856
 
         if (value & (1 << 1))                          /* SOFTRESET */
857
 
-            omap_mcspi_reset(s);
858
 
+            omap_mcspi_bus_reset(s);
859
 
         s->sysconfig = value & 0x31d;
860
 
         break;
861
 
 
862
 
@@ -598,41 +604,79 @@ static const MemoryRegionOps omap_mcspi_ops = {
863
 
     .endianness = DEVICE_NATIVE_ENDIAN,
864
 
 };
865
 
 
866
 
-struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta,
867
 
-                                     struct omap_mpu_state_s *mpu,
868
 
-                                     int chnum, qemu_irq irq, qemu_irq *drq,
869
 
-                                     omap_clk fclk, omap_clk iclk)
870
 
+static void omap_mcspi_reset(DeviceState *qdev)
871
 
 {
872
 
-    struct omap_mcspi_s *s = g_malloc0(sizeof(*s) +
873
 
-        chnum * sizeof(struct omap_mcspi_ch_s));
874
 
-    struct omap_mcspi_ch_s *ch = s->ch;
875
 
-
876
 
-    s->irq = irq;
877
 
-    s->chnum = chnum;
878
 
-    /* revision was hardcoded as 0x91 in original code -- odd */
879
 
-    s->revision = cpu_class_omap3(mpu) ? SPI_REV_OMAP3430 : SPI_REV_OMAP2420;
880
 
-    while (chnum --) {
881
 
-        ch->txdrq = *drq ++;
882
 
-        ch->rxdrq = *drq ++;
883
 
-        ch ++;
884
 
+    int i;
885
 
+    OMAPSPIState *s = FROM_SYSBUS(OMAPSPIState, SYS_BUS_DEVICE(qdev));
886
 
+    for (i = 0; i < s->buscount; i++) {
887
 
+        omap_mcspi_bus_reset(&s->bus[i]);
888
 
     }
889
 
-    omap_mcspi_reset(s);
890
 
+}
891
 
 
892
 
-    memory_region_init_io(&s->iomem, &omap_mcspi_ops, s, "omap.mcspi",
893
 
-                          omap_l4_region_size(ta, 0));
894
 
-    omap_l4_attach(ta, 0, &s->iomem);
895
 
+static int omap_mcspi_init(SysBusDevice *busdev)
896
 
+{
897
 
+    int i, j;
898
 
+    OMAPSPIBusState *bs;
899
 
+    OMAPSPIState *s = FROM_SYSBUS(OMAPSPIState, busdev);
900
 
+    
901
 
+    s->buscount = (s->mpu_model < omap3430) ? 2 : 4;
902
 
+    s->bus = g_new0(OMAPSPIBusState, s->buscount);
903
 
+    for (i = 0; i < s->buscount; i++) {
904
 
+        bs = &s->bus[i];
905
 
+        if (s->mpu_model < omap3430) {
906
 
+            bs->revision = SPI_REV_OMAP2420;
907
 
+            bs->chnum = i ? 2 : 4;
908
 
+        } else {
909
 
+            bs->revision = SPI_REV_OMAP3430;
910
 
+            bs->chnum = (i > 2) ? 1 : (i ? 2 : 4);
911
 
+        }
912
 
+        sysbus_init_irq(busdev, &bs->irq);
913
 
+        bs->bus = spi_init_bus(&busdev->qdev, NULL, bs->chnum);
914
 
+        bs->ch = g_new0(struct omap_mcspi_ch_s, bs->chnum);
915
 
+        for (j = 0; j < bs->chnum; j++) {
916
 
+            sysbus_init_irq(busdev, &bs->ch[j].txdrq);
917
 
+            sysbus_init_irq(busdev, &bs->ch[j].rxdrq);
918
 
+        }
919
 
+        memory_region_init_io(&bs->iomem, &omap_mcspi_ops, bs, "omap.mcspi",
920
 
+                              0x1000);
921
 
+        sysbus_init_mmio(busdev, &bs->iomem);
922
 
+    }
923
 
+    return 0;
924
 
+}
925
 
 
926
 
-    return s;
927
 
+SPIBus *omap_mcspi_bus(DeviceState *qdev, int bus_number)
928
 
+{
929
 
+    OMAPSPIState *s = FROM_SYSBUS(OMAPSPIState, SYS_BUS_DEVICE(qdev));
930
 
+    if (bus_number < s->buscount) {
931
 
+        return s->bus[bus_number].bus;
932
 
+    }
933
 
+    hw_error("%s: invalid bus number %d\n", __FUNCTION__, bus_number);
934
 
 }
935
 
 
936
 
-void omap_mcspi_attach(struct omap_mcspi_s *s,
937
 
-                       uint32_t (*txrx)(void *opaque, uint32_t, int),
938
 
-                       void *opaque,
939
 
-                       int chipselect)
940
 
+static Property omap_mcspi_properties[] = {
941
 
+    DEFINE_PROP_INT32("mpu_model", OMAPSPIState, mpu_model, 0),
942
 
+    DEFINE_PROP_END_OF_LIST()
943
 
+};
944
 
+
945
 
+static void omap_mcspi_class_init(ObjectClass *klass, void *data)
946
 
 {
947
 
-    if (chipselect < 0 || chipselect >= s->chnum)
948
 
-        hw_error("%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
949
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
950
 
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
951
 
+    k->init = omap_mcspi_init;
952
 
+    dc->props = omap_mcspi_properties;
953
 
+    dc->reset = omap_mcspi_reset;
954
 
+}
955
 
 
956
 
-    s->ch[chipselect].txrx = txrx;
957
 
-    s->ch[chipselect].opaque = opaque;
958
 
+static TypeInfo omap_mcspi_info = {
959
 
+    .name = "omap_mcspi",
960
 
+    .parent = TYPE_SYS_BUS_DEVICE,
961
 
+    .instance_size = sizeof(OMAPSPIState),
962
 
+    .class_init = omap_mcspi_class_init,
963
 
+};
964
 
+
965
 
+static void omap_mcspi_register_types(void)
966
 
+{
967
 
+    type_register_static(&omap_mcspi_info);
968
 
 }
969
 
+
970
 
+type_init(omap_mcspi_register_types)
971
 
diff --git a/hw/ssi/spi.c b/hw/ssi/spi.c
972
 
new file mode 100644
973
 
index 0000000..d38050e
974
 
--- /dev/null
975
 
+++ b/hw/ssi/spi.c
976
 
@@ -0,0 +1,121 @@
977
 
+/*
978
 
+ * SPI interface.
979
 
+ *
980
 
+ * Copyright (C) 2007-2010 Nokia Corporation
981
 
+ *
982
 
+ * This program is free software; you can redistribute it and/or
983
 
+ * modify it under the terms of the GNU General Public License as
984
 
+ * published by the Free Software Foundation; either version 2 or
985
 
+ * (at your option) any later version of the License.
986
 
+ *
987
 
+ * This program is distributed in the hope that it will be useful,
988
 
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
989
 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
990
 
+ * GNU General Public License for more details.
991
 
+ *
992
 
+ * You should have received a copy of the GNU General Public License along
993
 
+ * with this program; if not, write to the Free Software Foundation, Inc.,
994
 
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
995
 
+ */
996
 
+#include "hw/spi.h"
997
 
+
998
 
+struct SPIBus {
999
 
+    BusState qbus;
1000
 
+    int channels;
1001
 
+    SPIDevice **device;
1002
 
+};
1003
 
+
1004
 
+#define TYPE_SPI_BUS "spi-bus"
1005
 
+#define SPI_BUS(obj) OBJECT_CHECK(SPIBus, (obj), TYPE_SPI_BUS)
1006
 
+
1007
 
+static Property spi_props[] = {
1008
 
+    DEFINE_PROP_UINT8("channel", SPIDevice, channel, 0),
1009
 
+    DEFINE_PROP_END_OF_LIST()
1010
 
+};
1011
 
+
1012
 
+static const TypeInfo spi_bus_info = {
1013
 
+    .name = TYPE_SPI_BUS,
1014
 
+    .parent = TYPE_BUS,
1015
 
+    .instance_size = sizeof(SPIBus),
1016
 
+};
1017
 
+
1018
 
+SPIBus *spi_init_bus(DeviceState *parent, const char *name, int num_channels)
1019
 
+{
1020
 
+    SPIBus *bus = FROM_QBUS(SPIBus, qbus_create(TYPE_SPI_BUS, parent, name));
1021
 
+    bus->channels = num_channels;
1022
 
+    bus->device = g_new0(SPIDevice*, bus->channels);
1023
 
+    return bus;
1024
 
+}
1025
 
+
1026
 
+uint32_t spi_txrx(SPIBus *bus, int channel, uint32_t data, int len)
1027
 
+{
1028
 
+    SPIDevice *dev;
1029
 
+    SPIDeviceClass *sc;
1030
 
+
1031
 
+    if (channel < bus->channels) {
1032
 
+        if ((dev = bus->device[channel])) {
1033
 
+            sc = SPI_DEVICE_GET_CLASS(dev);
1034
 
+            if (sc->txrx) {
1035
 
+                return sc->txrx(dev, data, len);
1036
 
+            }
1037
 
+        }
1038
 
+    } else {
1039
 
+        hw_error("%s: invalid channel %d\n", __FUNCTION__, channel);
1040
 
+    }
1041
 
+    return 0;
1042
 
+}
1043
 
+
1044
 
+DeviceState *spi_create_device_noinit(SPIBus *bus, const char *name, int ch)
1045
 
+{
1046
 
+    if (ch >= bus->channels) {
1047
 
+        hw_error("%s: invalid channel %d\n", __FUNCTION__, ch);
1048
 
+    }
1049
 
+    if (bus->device[ch]) {
1050
 
+        hw_error("%s: channel %d already has a device attached\n",
1051
 
+                 __FUNCTION__, ch);
1052
 
+    }
1053
 
+    DeviceState *qdev = qdev_create(&bus->qbus, name);
1054
 
+    qdev_prop_set_uint8(qdev, "channel", ch);
1055
 
+    SPIDevice *dev = SPI_DEVICE_FROM_QDEV(qdev);
1056
 
+    bus->device[ch] = dev;
1057
 
+    return qdev;
1058
 
+}
1059
 
+
1060
 
+DeviceState *spi_create_device(SPIBus *bus, const char *name, int ch)
1061
 
+{
1062
 
+    DeviceState *dev = spi_create_device_noinit(bus, name, ch);
1063
 
+    qdev_init_nofail(dev);
1064
 
+    return dev;
1065
 
+}
1066
 
+
1067
 
+static int spi_device_qdev_init(DeviceState *dev)
1068
 
+{
1069
 
+    SPIDevice *s = SPI_DEVICE_FROM_QDEV(dev);
1070
 
+    SPIDeviceClass *sc = SPI_DEVICE_GET_CLASS(s);
1071
 
+    return sc->init(s);
1072
 
+}
1073
 
+
1074
 
+static void spi_device_class_init(ObjectClass *klass, void *data)
1075
 
+{
1076
 
+    DeviceClass *k = DEVICE_CLASS(klass);
1077
 
+    k->init = spi_device_qdev_init;
1078
 
+    k->bus_type = TYPE_SPI_BUS;
1079
 
+    k->props = spi_props;
1080
 
+}
1081
 
+
1082
 
+static TypeInfo spi_device_type_info = {
1083
 
+    .name = TYPE_SPI_DEVICE,
1084
 
+    .parent = TYPE_DEVICE,
1085
 
+    .instance_size = sizeof(SPIDevice),
1086
 
+    .abstract = true,
1087
 
+    .class_size = sizeof(SPIDeviceClass),
1088
 
+    .class_init = spi_device_class_init,
1089
 
+};
1090
 
+
1091
 
+static void spi_device_register_types(void)
1092
 
+{
1093
 
+    type_register_static(&spi_bus_info);
1094
 
+    type_register_static(&spi_device_type_info);
1095
 
+}
1096
 
+
1097
 
+type_init(spi_device_register_types)
1098
 
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
1099
 
index 9f2612e..21d83a6 100644
1100
 
--- a/include/hw/arm/omap.h
1101
 
+++ b/include/hw/arm/omap.h
1102
 
@@ -21,6 +21,8 @@
1103
 
 # define hw_omap_h             "omap.h"
1104
 
 #include "hw/irq.h"
1105
 
 
1106
 
+#include "hw/spi.h"
1107
 
+
1108
 
 # define OMAP_EMIFS_BASE       0x00000000
1109
 
 # define OMAP2_Q0_BASE         0x00000000
1110
 
 # define OMAP_CS0_BASE         0x00000000
1111
 
@@ -897,15 +899,7 @@ void omap_uwire_attach(struct omap_uwire_s *s,
1112
 
                 uWireSlave *slave, int chipselect);
1113
 
 
1114
 
 /* OMAP2 spi */
1115
 
-struct omap_mcspi_s;
1116
 
-struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta,
1117
 
-                                     struct omap_mpu_state_s *mp,
1118
 
-                                     int chnum, qemu_irq irq, qemu_irq *drq,
1119
 
-                                     omap_clk fclk, omap_clk iclk);
1120
 
-void omap_mcspi_attach(struct omap_mcspi_s *s,
1121
 
-                uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
1122
 
-                int chipselect);
1123
 
-void omap_mcspi_reset(struct omap_mcspi_s *s);
1124
 
+SPIBus *omap_mcspi_bus(DeviceState *omap_mcspi, int bus_number);
1125
 
 
1126
 
 struct I2SCodec {
1127
 
     void *opaque;
1128
 
@@ -1138,7 +1132,7 @@ struct omap_mpu_state_s {
1129
 
     struct omap_gpmc_s *gpmc;
1130
 
     struct omap_sysctl_s *sysc;
1131
 
 
1132
 
-    struct omap_mcspi_s *mcspi[2];
1133
 
+    DeviceState *mcspi;
1134
 
 
1135
 
     struct omap_dss_s *dss;
1136
 
 
1137
 
diff --git a/include/hw/devices.h b/include/hw/devices.h
1138
 
index 545b53a..f10de3d 100644
1139
 
--- a/include/hw/devices.h
1140
 
+++ b/include/hw/devices.h
1141
 
@@ -16,17 +16,14 @@ void lan9118_init(NICInfo *, uint32_t, qemu_irq);
1142
 
 
1143
 
 /* tsc210x.c */
1144
 
 uWireSlave *tsc2102_init(qemu_irq pint);
1145
 
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
1146
 
 I2SCodec *tsc210x_codec(uWireSlave *chip);
1147
 
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
1148
 
-void tsc210x_set_transform(uWireSlave *chip,
1149
 
-                MouseTransformInfo *info);
1150
 
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
1151
 
+void tsc2301_set_transform(DeviceState *qdev, MouseTransformInfo *info);
1152
 
 void tsc210x_key_event(uWireSlave *chip, int key, int down);
1153
 
+void tsc2301_key_event(DeviceState *qdev, int key, int down);
1154
 
 
1155
 
 /* tsc2005.c */
1156
 
-void *tsc2005_init(qemu_irq pintdav);
1157
 
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
1158
 
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info,
1159
 
+void tsc2005_set_transform(DeviceState *qdev, MouseTransformInfo *info,
1160
 
                            int z1_cons, int z2_cons);
1161
 
 
1162
 
 /* stellaris_input.c */
1163
 
diff --git a/include/hw/spi.h b/include/hw/spi.h
1164
 
new file mode 100644
1165
 
index 0000000..fa59f40
1166
 
--- /dev/null
1167
 
+++ b/include/hw/spi.h
1168
 
@@ -0,0 +1,62 @@
1169
 
+/*
1170
 
+ * SPI interface.
1171
 
+ *
1172
 
+ * Copyright (C) 2007-2010 Nokia Corporation
1173
 
+ *
1174
 
+ * This program is free software; you can redistribute it and/or
1175
 
+ * modify it under the terms of the GNU General Public License as
1176
 
+ * published by the Free Software Foundation; either version 2 or
1177
 
+ * (at your option) any later version of the License.
1178
 
+ *
1179
 
+ * This program is distributed in the hope that it will be useful,
1180
 
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1181
 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1182
 
+ * GNU General Public License for more details.
1183
 
+ *
1184
 
+ * You should have received a copy of the GNU General Public License along
1185
 
+ * with this program; if not, write to the Free Software Foundation, Inc.,
1186
 
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1187
 
+ */
1188
 
+#ifndef HW_SPI_H__
1189
 
+#define HW_SPI_H__
1190
 
+#include "hw.h"
1191
 
+#include "qdev.h"
1192
 
+
1193
 
+typedef struct SPIDevice SPIDevice;
1194
 
+typedef struct SPIBus SPIBus;
1195
 
+
1196
 
+#define TYPE_SPI_DEVICE "spi-device"
1197
 
+#define SPI_DEVICE(obj) \
1198
 
+    OBJECT_CHECK(SPIDevice, (obj), TYPE_SPI_DEVICE)
1199
 
+#define SPI_DEVICE_CLASS(klass) \
1200
 
+    OBJECT_CLASS_CHECK(SPIDeviceClass, (klass), TYPE_SPI_DEVICE)
1201
 
+#define SPI_DEVICE_GET_CLASS(obj) \
1202
 
+    OBJECT_GET_CLASS(SPIDeviceClass, (obj), TYPE_SPI_DEVICE)
1203
 
+
1204
 
+typedef int (*spi_device_initfn)(SPIDevice *dev);
1205
 
+typedef uint32_t (*spi_txrx_cb)(SPIDevice *dev, uint32_t, int);
1206
 
+
1207
 
+typedef struct SPIDeviceClass {
1208
 
+    DeviceClass parent_class;
1209
 
+
1210
 
+    spi_device_initfn init;
1211
 
+    spi_txrx_cb txrx;
1212
 
+} SPIDeviceClass;
1213
 
+
1214
 
+struct SPIDevice {
1215
 
+    DeviceState qdev;
1216
 
+
1217
 
+    /* internal fields used by SPI code */
1218
 
+    uint8_t channel;
1219
 
+};
1220
 
+
1221
 
+SPIBus *spi_init_bus(DeviceState *parent, const char *name, int num_channels);
1222
 
+uint32_t spi_txrx(SPIBus *bus, int channel, uint32_t data, int len);
1223
 
+
1224
 
+#define SPI_DEVICE_FROM_QDEV(dev) DO_UPCAST(SPIDevice, qdev, dev)
1225
 
+#define FROM_SPI_DEVICE(type, dev) DO_UPCAST(type, spi, dev)
1226
 
+
1227
 
+DeviceState *spi_create_device(SPIBus *bus, const char *name, int ch);
1228
 
+DeviceState *spi_create_device_noinit(SPIBus *bus, const char *name, int ch);
1229
 
+
1230
 
+#endif
1231
 
1.8.1.2
1232