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

« back to all changes in this revision

Viewing changes to debian/patches/linaro-patches-1.5.0/0054-hw-nseries.c-Add-n900-machine.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 857440d639c4b87ca46d7b34b791b09bc1323e31 Mon Sep 17 00:00:00 2001
2
 
From: Peter Maydell <peter.maydell@linaro.org>
3
 
Date: Mon, 18 Feb 2013 16:58:32 +0000
4
 
Subject: [PATCH 54/69] hw/nseries.c: Add n900 machine
5
 
 
6
 
add n900 to nseries.c
7
 
---
8
 
 hw/arm/nseries.c | 1048 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
9
 
 1 file changed, 1048 insertions(+)
10
 
 
11
 
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
12
 
index 88fab81..b599854 100644
13
 
--- a/hw/arm/nseries.c
14
 
+++ b/hw/arm/nseries.c
15
 
@@ -32,6 +32,7 @@
16
 
 #include "hw/hw.h"
17
 
 #include "hw/bt.h"
18
 
 #include "hw/loader.h"
19
 
+#include "net/net.h"
20
 
 #include "sysemu/blockdev.h"
21
 
 #include "hw/sysbus.h"
22
 
 #include "exec/address-spaces.h"
23
 
@@ -1556,8 +1557,1054 @@ static QEMUMachine n810_machine = {
24
 
     DEFAULT_MACHINE_OPTIONS,
25
 
 };
26
 
 
27
 
+#define N900_SDRAM_SIZE (256 * 1024 * 1024)
28
 
+#define N900_ONENAND_CS 0
29
 
+#define N900_ONENAND_BUFSIZE (0xc000 << 1)
30
 
+#define N900_SMC_CS 1
31
 
+
32
 
+#define N900_ONENAND_GPIO       65
33
 
+#define N900_CAMFOCUS_GPIO      68
34
 
+#define N900_CAMLAUNCH_GPIO     69
35
 
+#define N900_SLIDE_GPIO         71
36
 
+#define N900_PROXIMITY_GPIO     89
37
 
+#define N900_HEADPHONE_EN_GPIO  98
38
 
+#define N900_TSC2005_IRQ_GPIO   100
39
 
+#define N900_TSC2005_RESET_GPIO 104
40
 
+#define N900_CAMCOVER_GPIO      110
41
 
+#define N900_KBLOCK_GPIO        113
42
 
+#define N900_HEADPHONE_GPIO     177
43
 
+#define N900_LIS302DL_INT2_GPIO 180
44
 
+#define N900_LIS302DL_INT1_GPIO 181
45
 
+
46
 
+//#define DEBUG_BQ2415X
47
 
+//#define DEBUG_TPA6130
48
 
+//#define DEBUG_LIS302DL
49
 
+
50
 
+#define N900_TRACE(fmt, ...) \
51
 
+    fprintf(stderr, "%s@%d: " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
52
 
+
53
 
+#ifdef DEBUG_BQ2415X
54
 
+#define TRACE_BQ2415X(fmt, ...) N900_TRACE(fmt, ##__VA_ARGS__)
55
 
+#else
56
 
+#define TRACE_BQ2415X(...)
57
 
+#endif
58
 
+#ifdef DEBUG_TPA6130
59
 
+#define TRACE_TPA6130(fmt, ...) N900_TRACE(fmt, ##__VA_ARGS__)
60
 
+#else
61
 
+#define TRACE_TPA6130(...)
62
 
+#endif
63
 
+#ifdef DEBUG_LIS302DL
64
 
+#define TRACE_LIS302DL(fmt, ...) N900_TRACE(fmt, ##__VA_ARGS__)
65
 
+#else
66
 
+#define TRACE_LIS302DL(...)
67
 
+#endif
68
 
+
69
 
+static uint64_t ssi_read(void *opaque, hwaddr addr, unsigned size)
70
 
+{
71
 
+    switch (addr) {
72
 
+        case 0x00: /* REVISION */
73
 
+            return 0x10;
74
 
+        case 0x14: /* SYSSTATUS */
75
 
+            return 1; /* RESETDONE */
76
 
+        default:
77
 
+            break;
78
 
+    }
79
 
+    //printf("%s: addr= " OMAP_FMT_plx "\n", __FUNCTION__, addr);
80
 
+    return 0;
81
 
+}
82
 
+
83
 
+static void ssi_write(void *opaque, hwaddr addr, uint64_t value,
84
 
+                      unsigned size)
85
 
+{
86
 
+    //printf("%s: addr=" OMAP_FMT_plx ", value=0x%08x\n", __FUNCTION__, addr, value);
87
 
+}
88
 
+
89
 
+static const MemoryRegionOps ssi_ops = {
90
 
+    .read = ssi_read,
91
 
+    .write = ssi_write,
92
 
+    .endianness = DEVICE_NATIVE_ENDIAN,
93
 
+};
94
 
+
95
 
+typedef struct LIS302DLState_s {
96
 
+    I2CSlave i2c;
97
 
+    int firstbyte;
98
 
+    uint8_t reg;
99
 
+
100
 
+    qemu_irq irq[2];
101
 
+    int8_t axis_max, axis_step;
102
 
+    int noise, dr_test_ack;
103
 
+
104
 
+    uint8_t ctrl1, ctrl2, ctrl3;
105
 
+    uint8_t status;
106
 
+    struct {
107
 
+        uint8_t cfg, src, ths, dur;
108
 
+    } ff_wu[2];
109
 
+    struct {
110
 
+        uint8_t cfg, src, thsy_x, thsz;
111
 
+        uint8_t timelimit, latency, window;
112
 
+    } click;
113
 
+    
114
 
+    int32_t x, y, z;
115
 
+} LIS302DLState;
116
 
+
117
 
+static void lis302dl_interrupt_update(LIS302DLState *s)
118
 
+{
119
 
+#ifdef DEBUG_LIS302DL
120
 
+    static const char *rules[8] = {
121
 
+        "GND", "FF_WU_1", "FF_WU_2", "FF_WU_1|2", "DR",
122
 
+        "???", "???", "CLICK"
123
 
+    };
124
 
+#endif
125
 
+    int active = (s->ctrl3 & 0x80) ? 0 : 1;
126
 
+    int cond, latch;
127
 
+    int i;
128
 
+    for (i = 0; i < 2; i++) {
129
 
+        switch ((s->ctrl3 >> (i * 3)) & 0x07) {
130
 
+            case 0:
131
 
+                cond = 0;
132
 
+                break;
133
 
+            case 1:
134
 
+                cond = s->ff_wu[0].src & 0x40;
135
 
+                latch = s->ff_wu[0].cfg & 0x40;
136
 
+                break;
137
 
+            case 2:
138
 
+                cond = s->ff_wu[1].src & 0x40;
139
 
+                latch = s->ff_wu[1].cfg & 0x40;
140
 
+                break;
141
 
+            case 3:
142
 
+                cond = ((s->ff_wu[0].src | s->ff_wu[1].src) & 0x40);
143
 
+                latch = ((s->ff_wu[0].cfg | s->ff_wu[1].cfg) & 0x40);
144
 
+                break;
145
 
+            case 4:
146
 
+                cond = (((s->ff_wu[0].src | s->ff_wu[1].src) & 0x3f) &
147
 
+                        (((s->ctrl1 & 0x01) ? 0x03 : 0x00) |
148
 
+                         ((s->ctrl1 & 0x02) ? 0x0c : 0x00) |
149
 
+                         ((s->ctrl1 & 0x04) ? 0x30 : 0x00)));
150
 
+                latch = 0;
151
 
+                break;
152
 
+            case 7:
153
 
+                cond = s->click.src & 0x40;
154
 
+                latch = s->click.cfg & 0x40;
155
 
+                break;
156
 
+            default:
157
 
+                TRACE_LIS302DL("unsupported irq config (%d)",
158
 
+                               (s->ctrl3 >> (i * 3)) & 0x07);
159
 
+                cond = 0;
160
 
+                latch = 0;
161
 
+                break;
162
 
+        }
163
 
+        TRACE_LIS302DL("%s: %s irq%d", rules[(s->ctrl3 >> (i * 3)) & 0x07],
164
 
+                       cond ? (latch ? "activate" : "pulse") : "deactivate",
165
 
+                       i);
166
 
+        qemu_set_irq(s->irq[i], cond ? active : !active);
167
 
+        if (cond && !latch) {
168
 
+            qemu_set_irq(s->irq[i], !active);
169
 
+        }
170
 
+    }
171
 
+}
172
 
+
173
 
+static void lis302dl_trigger(LIS302DLState *s, int axis, int value)
174
 
+{
175
 
+    if (value > s->axis_max) value = s->axis_max;
176
 
+    if (value < -s->axis_max) value = -s->axis_max;
177
 
+    switch (axis) {
178
 
+        case 0: s->x = value; break;
179
 
+        case 1: s->y = value; break;
180
 
+        case 2: s->z = value; break;
181
 
+        default: break;
182
 
+    }
183
 
+    if (s->status & (0x01 << axis)) {
184
 
+        s->status |= 0x10 << axis;
185
 
+    } else {
186
 
+        s->status |= 0x01 << axis;
187
 
+    }
188
 
+    if ((s->status & 0x07) == 0x07) {
189
 
+        s->status |= 0x08;
190
 
+    }
191
 
+    if ((s->status & 0x70) == 0x70) {
192
 
+        s->status |= 0x80;
193
 
+    }
194
 
+    uint8_t bit = 0x02 << (axis << 1); /* over threshold */
195
 
+    s->ff_wu[0].src |= bit;
196
 
+    s->ff_wu[1].src |= bit;
197
 
+    
198
 
+    int i = 0;
199
 
+    for (; i < 2; i++) {
200
 
+        if (s->ff_wu[i].src & 0x3f) {
201
 
+            if (s->ff_wu[i].cfg & 0x80) {
202
 
+                if ((s->ff_wu[i].cfg & 0x3f) == (s->ff_wu[i].src & 0x3f)) {
203
 
+                    s->ff_wu[i].src |= 0x40;
204
 
+                }
205
 
+            } else {
206
 
+                if (s->ff_wu[i].src & s->ff_wu[i].cfg & 0x3f) {
207
 
+                    s->ff_wu[i].src |= 0x40;
208
 
+                }
209
 
+            }
210
 
+        }
211
 
+        TRACE_LIS302DL("FF_WU_%d: CFG=0x%02x, SRC=0x%02x",
212
 
+                       i, s->ff_wu[i].cfg, s->ff_wu[i].src);
213
 
+    }
214
 
+    
215
 
+    lis302dl_interrupt_update(s);
216
 
+}
217
 
+
218
 
+static void lis302dl_step(void *opaque, int axis, int high, int activate)
219
 
+{
220
 
+    TRACE_LIS302DL("axis=%d, high=%d, activate=%d", axis, high, activate);
221
 
+    LIS302DLState *s = opaque;
222
 
+    if (activate) {
223
 
+        int v = 0;
224
 
+        switch (axis) {
225
 
+            case 0: v = s->x + (high ? s->axis_step : -s->axis_step); break;
226
 
+            case 1: v = s->y + (high ? s->axis_step : -s->axis_step); break;
227
 
+            case 2: v = s->z + (high ? s->axis_step : -s->axis_step); break;
228
 
+            default: break;
229
 
+        }
230
 
+        if (v > s->axis_max) v = -(s->axis_max - s->axis_step);
231
 
+        if (v < -s->axis_max) v = s->axis_max - s->axis_step;
232
 
+        lis302dl_trigger(s, axis, v);
233
 
+    }
234
 
+}
235
 
+
236
 
+static void lis302dl_reset(DeviceState *ds)
237
 
+{
238
 
+    LIS302DLState *s = FROM_I2C_SLAVE(LIS302DLState, I2C_SLAVE(ds));
239
 
+    
240
 
+    s->firstbyte = 0;
241
 
+    s->reg = 0;
242
 
+
243
 
+    s->noise = 4;
244
 
+    s->dr_test_ack = 0;
245
 
+
246
 
+    s->ctrl1 = 0x03;
247
 
+    s->ctrl2 = 0x00;
248
 
+    s->ctrl3 = 0x00;
249
 
+    s->status = 0x00;
250
 
+
251
 
+    memset(s->ff_wu, 0x00, sizeof(s->ff_wu));
252
 
+    memset(&s->click, 0x00, sizeof(s->click));
253
 
+    
254
 
+    s->x = 0;
255
 
+    s->y = -s->axis_max;
256
 
+    s->z = 0;
257
 
+
258
 
+    lis302dl_interrupt_update(s);
259
 
+}
260
 
+
261
 
+static void lis302dl_event(I2CSlave *i2c, enum i2c_event event)
262
 
+{
263
 
+    LIS302DLState *s = FROM_I2C_SLAVE(LIS302DLState, i2c);
264
 
+    if (event == I2C_START_SEND)
265
 
+        s->firstbyte = 1;
266
 
+}
267
 
+
268
 
+static uint8_t lis302dl_readcoord(LIS302DLState *s, int coord)
269
 
+{
270
 
+    int v;
271
 
+
272
 
+    switch (coord) {
273
 
+        case 0:
274
 
+            v = s->x;
275
 
+            break;
276
 
+        case 1:
277
 
+            v = s->y;
278
 
+            break;
279
 
+        case 2:
280
 
+            v = s->z;
281
 
+            break;
282
 
+        default:
283
 
+            hw_error("%s: unknown axis %d", __FUNCTION__, coord);
284
 
+            break;
285
 
+    }
286
 
+    s->status &= ~(0x88 | (0x11 << coord));
287
 
+    if (s->ctrl1 & 0x10) {
288
 
+        switch (coord) {
289
 
+            case 0:
290
 
+                v -= s->noise;
291
 
+                break;
292
 
+            case 1:
293
 
+            case 2:
294
 
+                v += s->noise;
295
 
+                break;
296
 
+            default:
297
 
+                break;
298
 
+        }
299
 
+        if (++s->noise == 32) {
300
 
+            s->noise = 4;
301
 
+        }
302
 
+        int dr1 = ((s->ctrl3 & 0x07) == 4);
303
 
+        int dr2 = (((s->ctrl3 >> 3) & 0x07) == 4);
304
 
+        if (!s->dr_test_ack++) {
305
 
+            if (dr1) {
306
 
+                qemu_irq_pulse(s->irq[0]);
307
 
+            }
308
 
+            if (dr2) {
309
 
+                qemu_irq_pulse(s->irq[1]);
310
 
+            }
311
 
+        } else if (s->dr_test_ack == 1 + (dr1 + dr2) * 3) {
312
 
+            s->dr_test_ack = 0;
313
 
+        }
314
 
+    }
315
 
+    return (uint8_t)v;
316
 
+}
317
 
+
318
 
+static int lis302dl_rx(I2CSlave *i2c)
319
 
+{
320
 
+    LIS302DLState *s = FROM_I2C_SLAVE(LIS302DLState, i2c);
321
 
+    int value = -1;
322
 
+    int n = 0;
323
 
+    switch (s->reg & 0x7f) {
324
 
+        case 0x00 ... 0x0e:
325
 
+        case 0x10 ... 0x1f:
326
 
+        case 0x23 ... 0x26:
327
 
+        case 0x28:
328
 
+        case 0x2a:
329
 
+        case 0x2c:
330
 
+        case 0x2e ... 0x2f:
331
 
+        case 0x3a:
332
 
+            value = 0;
333
 
+            TRACE_LIS302DL("reg 0x%02x = 0x%02x (unused/reserved reg)",
334
 
+                           s->reg & 0x7f, value);
335
 
+            break;
336
 
+        case 0x0f:
337
 
+            value = 0x3b;
338
 
+            TRACE_LIS302DL("WHOAMI = 0x%02x", value);
339
 
+            break;
340
 
+        case 0x20:
341
 
+            value = s->ctrl1;
342
 
+            TRACE_LIS302DL("CTRL1 = 0x%02x", value);
343
 
+            break;
344
 
+        case 0x21:
345
 
+            value = s->ctrl2;
346
 
+            TRACE_LIS302DL("CTRL2 = 0x%02x", value);
347
 
+            break;
348
 
+        case 0x22:
349
 
+            value = s->ctrl3;
350
 
+            TRACE_LIS302DL("CTRL3 = 0x%02x", value);
351
 
+            break;
352
 
+        case 0x27:
353
 
+            value = s->status;
354
 
+            TRACE_LIS302DL("STATUS = 0x%02x", value);
355
 
+            break;
356
 
+        case 0x29:
357
 
+            value = lis302dl_readcoord(s, 0);
358
 
+            TRACE_LIS302DL("X = 0x%02x", value);
359
 
+            break;
360
 
+        case 0x2b:
361
 
+            value = lis302dl_readcoord(s, 1);
362
 
+            TRACE_LIS302DL("Y = 0x%02x", value);
363
 
+            break;
364
 
+        case 0x2d:
365
 
+            value = lis302dl_readcoord(s, 2);
366
 
+            TRACE_LIS302DL("Z = 0x%02x", value);
367
 
+            break;
368
 
+        case 0x34: n++;
369
 
+        case 0x30:
370
 
+            value = s->ff_wu[n].cfg;
371
 
+            TRACE_LIS302DL("FF_WU%d.CFG = 0x%02x", n + 1, value);
372
 
+            break;
373
 
+        case 0x35: n++;
374
 
+        case 0x31:
375
 
+            value = s->ff_wu[n].src;
376
 
+            TRACE_LIS302DL("FF_WU%d.SRC = 0x%02x", n + 1, value);
377
 
+            s->ff_wu[n].src = 0; //&= ~0x40;
378
 
+            lis302dl_interrupt_update(s);
379
 
+            break;
380
 
+        case 0x36: n++;
381
 
+        case 0x32:
382
 
+            value = s->ff_wu[n].ths;
383
 
+            TRACE_LIS302DL("FF_WU%d.THS = 0x%02x", n + 1, value);
384
 
+            break;
385
 
+        case 0x37: n++;
386
 
+        case 0x33:
387
 
+            value = s->ff_wu[n].dur;
388
 
+            TRACE_LIS302DL("FF_WU%d.DUR = 0x%02x", n + 1, value);
389
 
+            break;
390
 
+        case 0x38:
391
 
+            value = s->click.cfg;
392
 
+            TRACE_LIS302DL("CLICK_CFG = 0x%02x", value);
393
 
+            break;
394
 
+        case 0x39:
395
 
+            value = s->click.src;
396
 
+            TRACE_LIS302DL("CLICK_SRC = 0x%02x", value);
397
 
+            s->click.src &= ~0x40;
398
 
+            lis302dl_interrupt_update(s);
399
 
+            break;
400
 
+        case 0x3b:
401
 
+            value = s->click.thsy_x;
402
 
+            TRACE_LIS302DL("CLICK_THSY_X = 0x%02x", value);
403
 
+            break;
404
 
+        case 0x3c:
405
 
+            value = s->click.thsz;
406
 
+            TRACE_LIS302DL("CLICK_THSZ = 0x%02x", value);
407
 
+            break;
408
 
+        case 0x3d:
409
 
+            value = s->click.timelimit;
410
 
+            TRACE_LIS302DL("CLICK_TIMELIMIT = 0x%02x", value);
411
 
+            break;
412
 
+        case 0x3e:
413
 
+            value = s->click.latency;
414
 
+            TRACE_LIS302DL("CLICK_LATENCY = 0x%02x", value);
415
 
+            break;
416
 
+        case 0x3f:
417
 
+            value = s->click.window;
418
 
+            TRACE_LIS302DL("CLICK_WINDOW = 0x%02x", value);
419
 
+            break;
420
 
+        default:
421
 
+            hw_error("%s: unknown register 0x%02x", __FUNCTION__,
422
 
+                     s->reg & 0x7f);
423
 
+            value = 0;
424
 
+            break;
425
 
+    }
426
 
+    if (s->reg & 0x80) { /* auto-increment? */
427
 
+        s->reg = (s->reg + 1) | 0x80;
428
 
+    }
429
 
+    return value;
430
 
+}
431
 
+
432
 
+static int lis302dl_tx(I2CSlave *i2c, uint8_t data)
433
 
+{
434
 
+    LIS302DLState *s = FROM_I2C_SLAVE(LIS302DLState, i2c);
435
 
+    if (s->firstbyte) {
436
 
+        s->reg = data;
437
 
+        s->firstbyte = 0;
438
 
+    } else {
439
 
+        int n = 0;
440
 
+        switch (s->reg & 0x7f) {
441
 
+            case 0x20:
442
 
+                TRACE_LIS302DL("CTRL1 = 0x%02x", data);
443
 
+                s->ctrl1 = data;
444
 
+                break;
445
 
+            case 0x21:
446
 
+                TRACE_LIS302DL("CTRL2 = 0x%02x", data);
447
 
+                s->ctrl2 = data;
448
 
+                break;
449
 
+            case 0x22:
450
 
+                TRACE_LIS302DL("CTRL3 = 0x%02x", data);
451
 
+                s->ctrl3 = data;
452
 
+                lis302dl_interrupt_update(s);
453
 
+                break;
454
 
+            case 0x34: n++;
455
 
+            case 0x30:
456
 
+                TRACE_LIS302DL("FF_WU%d.CFG = 0x%02x", n + 1, data);
457
 
+                s->ff_wu[n].cfg = data;
458
 
+                break;
459
 
+            case 0x36: n++;
460
 
+            case 0x32:
461
 
+                TRACE_LIS302DL("FF_WU%d.THS = 0x%02x", n + 1, data);
462
 
+                s->ff_wu[n].ths = data;
463
 
+                break;
464
 
+            case 0x37: n++;
465
 
+            case 0x33:
466
 
+                TRACE_LIS302DL("FF_WU%d.DUR = 0x%02x", n + 1, data);
467
 
+                s->ff_wu[n].dur = data;
468
 
+                break;
469
 
+            case 0x38:
470
 
+                TRACE_LIS302DL("CLICK_CFG = 0x%02x", data);
471
 
+                s->click.cfg = data;
472
 
+                break;
473
 
+            case 0x39:
474
 
+                TRACE_LIS302DL("CLICK_SRC = 0x%02x", data);
475
 
+                s->click.src = data;
476
 
+                break;
477
 
+            case 0x3b:
478
 
+                TRACE_LIS302DL("CLICK_THSY_X = 0x%02x", data);
479
 
+                s->click.thsy_x = data;
480
 
+                break;
481
 
+            case 0x3c:
482
 
+                TRACE_LIS302DL("CLICK_THSZ = 0x%02x", data);
483
 
+                s->click.thsz = data;
484
 
+                break;
485
 
+            case 0x3d:
486
 
+                TRACE_LIS302DL("CLICK_TIMELIMIT = 0x%02x", data);
487
 
+                s->click.timelimit = data;
488
 
+                break;
489
 
+            case 0x3e:
490
 
+                TRACE_LIS302DL("CLICK_LATENCY = 0x%02x", data);
491
 
+                s->click.latency = data;
492
 
+                break;
493
 
+            case 0x3f:
494
 
+                TRACE_LIS302DL("CLICK_WINDOW = 0x%02x", data);
495
 
+                s->click.window = data;
496
 
+                break;
497
 
+            default:
498
 
+                hw_error("%s: unknown register 0x%02x (value 0x%02x)",
499
 
+                         __FUNCTION__, s->reg & 0x7f, data);
500
 
+                break;
501
 
+        }
502
 
+        if (s->reg & 0x80) { /* auto-increment? */
503
 
+            s->reg = (s->reg + 1) | 0x80;
504
 
+        }
505
 
+    }
506
 
+    return 1;
507
 
+}
508
 
+
509
 
+static int lis302dl_init(I2CSlave *i2c)
510
 
+{
511
 
+    LIS302DLState *s = FROM_I2C_SLAVE(LIS302DLState, i2c);
512
 
+    s->axis_max = 58;
513
 
+    s->axis_step = s->axis_max;// / 2;
514
 
+    qdev_init_gpio_out(&i2c->qdev, s->irq, 2);
515
 
+    return 0;
516
 
+}
517
 
+
518
 
+/* TODO: ideally x, y, z should be runtime modifiable properties,
519
 
+ * which can be set by calling
520
 
+ *     lis302dl_trigger(s, axis, value);
521
 
+ * where axis is 0,1,2 for x,y,z
522
 
+ */
523
 
+static Property lis302dl_properties[] = {
524
 
+    DEFINE_PROP_INT32("x", LIS302DLState, x, 0),
525
 
+    DEFINE_PROP_INT32("y", LIS302DLState, y, 0),
526
 
+    DEFINE_PROP_INT32("z", LIS302DLState, z, 0),
527
 
+    DEFINE_PROP_END_OF_LIST(),
528
 
+};
529
 
+
530
 
+static void lis302dl_class_init(ObjectClass *klass, void *data)
531
 
+{
532
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
533
 
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
534
 
+    k->init = lis302dl_init;
535
 
+    k->event = lis302dl_event;
536
 
+    k->recv = lis302dl_rx;
537
 
+    k->send = lis302dl_tx;
538
 
+    dc->props = lis302dl_properties;
539
 
+    dc->reset = lis302dl_reset;
540
 
+}
541
 
+
542
 
+static TypeInfo lis302dl_info = {
543
 
+    .name = "lis302dl",
544
 
+    .parent = TYPE_I2C_SLAVE,
545
 
+    .instance_size = sizeof(LIS302DLState),
546
 
+    .class_init = lis302dl_class_init,
547
 
+};
548
 
+
549
 
+typedef struct BQ2415XState_s {
550
 
+    I2CSlave i2c;
551
 
+    int firstbyte;
552
 
+    uint8 reg;
553
 
+    
554
 
+    uint8_t id;
555
 
+    uint8_t st_ctrl;
556
 
+    uint8_t ctrl;
557
 
+    uint8_t bat_v;
558
 
+    uint8_t tcc;
559
 
+} BQ2415XState;
560
 
+
561
 
+static void bq2415x_reset(DeviceState *ds)
562
 
+{
563
 
+    BQ2415XState *s = FROM_I2C_SLAVE(BQ2415XState, I2C_SLAVE(ds));
564
 
+    
565
 
+    s->firstbyte = 0;
566
 
+    s->reg = 0;
567
 
+
568
 
+    s->st_ctrl = 0x50 | 0x80; // 40
569
 
+    s->ctrl = 0x30;
570
 
+    s->bat_v = 0x0a;
571
 
+    s->tcc = 0xa1; // 89
572
 
+}
573
 
+
574
 
+static void bq2415x_event(I2CSlave *i2c, enum i2c_event event)
575
 
+{
576
 
+    BQ2415XState *s = FROM_I2C_SLAVE(BQ2415XState, i2c);
577
 
+    if (event == I2C_START_SEND)
578
 
+        s->firstbyte = 1;
579
 
+}
580
 
+
581
 
+static int bq2415x_rx(I2CSlave *i2c)
582
 
+{
583
 
+    BQ2415XState *s = FROM_I2C_SLAVE(BQ2415XState, i2c);
584
 
+    int value = -1;
585
 
+    switch (s->reg) {
586
 
+        case 0x00:
587
 
+            value = s->st_ctrl;
588
 
+            TRACE_BQ2415X("st_ctrl = 0x%02x", value);
589
 
+            break;
590
 
+        case 0x01:
591
 
+            value = s->ctrl;
592
 
+            TRACE_BQ2415X("ctrl = 0x%02x", value);
593
 
+            break;
594
 
+        case 0x02:
595
 
+            value = s->bat_v;
596
 
+            TRACE_BQ2415X("bat_v = 0x%02x", value);
597
 
+            break;
598
 
+        case 0x03:
599
 
+        case 0x3b:
600
 
+            value = s->id;
601
 
+            TRACE_BQ2415X("id = 0x%02x", value);
602
 
+            break;
603
 
+        case 0x04:
604
 
+            value = s->tcc;
605
 
+            TRACE_BQ2415X("tcc = 0x%02x", value);
606
 
+            break;
607
 
+        default:
608
 
+            TRACE_BQ2415X("unknown register 0x%02x", s->reg);
609
 
+            value = 0;
610
 
+            break;
611
 
+    }
612
 
+    s->reg++;
613
 
+    return value;
614
 
+}
615
 
+
616
 
+static int bq2415x_tx(I2CSlave *i2c, uint8_t data)
617
 
+{
618
 
+    BQ2415XState *s = FROM_I2C_SLAVE(BQ2415XState, i2c);
619
 
+    if (s->firstbyte) {
620
 
+        s->reg = data;
621
 
+        s->firstbyte = 0;
622
 
+    } else {
623
 
+        switch (s->reg) {
624
 
+            case 0x00:
625
 
+                TRACE_BQ2415X("st_ctrl = 0x%02x", data);
626
 
+                s->st_ctrl = (s->st_ctrl & 0x3f) | (data & 0x40) | 0x80;
627
 
+                break;
628
 
+            case 0x01:
629
 
+                TRACE_BQ2415X("ctrl = 0x%02x", data);
630
 
+                s->ctrl = data;
631
 
+                break;
632
 
+            case 0x02:
633
 
+                TRACE_BQ2415X("bat_v = 0x%02x", data);
634
 
+                s->bat_v = data;
635
 
+                break;
636
 
+            case 0x04:
637
 
+                TRACE_BQ2415X("tcc = 0x%02x", data);
638
 
+                s->tcc = data | 0x80;
639
 
+                break;
640
 
+            default:
641
 
+                TRACE_BQ2415X("unknown register 0x%02x (value 0x%02x)",
642
 
+                              s->reg, data);
643
 
+                break;
644
 
+        }
645
 
+        s->reg++;
646
 
+    }
647
 
+    return 1;
648
 
+}
649
 
+
650
 
+static int bq2415x_init(I2CSlave *i2c)
651
 
+{
652
 
+    return 0;
653
 
+}
654
 
+
655
 
+static Property bq2415x_properties[] = {
656
 
+    DEFINE_PROP_UINT8("id", BQ2415XState, id, 0x49),
657
 
+    DEFINE_PROP_END_OF_LIST(),
658
 
+};
659
 
+
660
 
+static void bq2415x_class_init(ObjectClass *klass, void *data)
661
 
+{
662
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
663
 
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
664
 
+    k->init = bq2415x_init;
665
 
+    k->event = bq2415x_event;
666
 
+    k->recv = bq2415x_rx;
667
 
+    k->send = bq2415x_tx;
668
 
+    dc->props = bq2415x_properties;
669
 
+    dc->reset = bq2415x_reset;
670
 
+}
671
 
+
672
 
+static TypeInfo bq2415x_info = {
673
 
+    .name = "bq2415x",
674
 
+    .parent = TYPE_I2C_SLAVE,
675
 
+    .instance_size = sizeof(BQ2415XState),
676
 
+    .class_init = bq2415x_class_init,
677
 
+};
678
 
+
679
 
+typedef struct tpa6130_s {
680
 
+    I2CSlave i2c;
681
 
+    int firstbyte;
682
 
+    int reg;
683
 
+    uint8_t data[3];
684
 
+} TPA6130State;
685
 
+
686
 
+static void tpa6130_reset(DeviceState *ds)
687
 
+{
688
 
+    TPA6130State *s = FROM_I2C_SLAVE(TPA6130State, I2C_SLAVE(ds));
689
 
+    s->firstbyte = 0;
690
 
+    s->reg = 0;
691
 
+    memset(s->data, 0, sizeof(s->data));
692
 
+}
693
 
+
694
 
+static void tpa6130_event(I2CSlave *i2c, enum i2c_event event)
695
 
+{
696
 
+    TPA6130State *s = FROM_I2C_SLAVE(TPA6130State, i2c);
697
 
+    if (event == I2C_START_SEND)
698
 
+        s->firstbyte = 1;
699
 
+}
700
 
+
701
 
+static int tpa6130_rx(I2CSlave *i2c)
702
 
+{
703
 
+    TPA6130State *s = FROM_I2C_SLAVE(TPA6130State, i2c);
704
 
+    int value = 0;
705
 
+    switch (s->reg) {
706
 
+        case 1 ... 3:
707
 
+            value = s->data[s->reg - 1];
708
 
+            TRACE_TPA6130("reg %d = 0x%02x", s->reg, value);
709
 
+            break;
710
 
+        case 4: /* VERSION */
711
 
+            value = 0x01;
712
 
+            TRACE_TPA6130("version = 0x%02x", value);
713
 
+            break;
714
 
+        default:
715
 
+            TRACE_TPA6130("unknown register 0x%02x", s->reg);
716
 
+            break;
717
 
+    }
718
 
+    s->reg++;
719
 
+    return value;
720
 
+}
721
 
+
722
 
+static int tpa6130_tx(I2CSlave *i2c, uint8_t data)
723
 
+{
724
 
+    TPA6130State *s = FROM_I2C_SLAVE(TPA6130State, i2c);
725
 
+    if (s->firstbyte) {
726
 
+        s->reg = data;
727
 
+        s->firstbyte = 0;
728
 
+    } else {
729
 
+        switch (s->reg) {
730
 
+            case 1 ... 3:
731
 
+                TRACE_TPA6130("reg %d = 0x%02x", s->reg, data);
732
 
+                s->data[s->reg - 1] = data;
733
 
+                break;
734
 
+            default:
735
 
+                TRACE_TPA6130("unknown register 0x%02x", s->reg);
736
 
+                break;
737
 
+        }
738
 
+        s->reg++;
739
 
+    }
740
 
+    return 1;
741
 
+}
742
 
+
743
 
+static void tpa6130_irq(void *opaque, int n, int level)
744
 
+{
745
 
+    if (n) {
746
 
+        hw_error("%s: unknown interrupt source %d\n", __FUNCTION__, n);
747
 
+    } else {
748
 
+        /* headphone enable */
749
 
+        TRACE_TPA6130("enable = %d", level);
750
 
+    }
751
 
+}
752
 
+
753
 
+static int tpa6130_init(I2CSlave *i2c)
754
 
+{
755
 
+    qdev_init_gpio_in(&i2c->qdev, tpa6130_irq, 1);
756
 
+    return 0;
757
 
+}
758
 
+
759
 
+static void tpa6130_class_init(ObjectClass *klass, void *data)
760
 
+{
761
 
+    DeviceClass *dc = DEVICE_CLASS(klass);
762
 
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
763
 
+    k->init = tpa6130_init;
764
 
+    k->event = tpa6130_event;
765
 
+    k->recv = tpa6130_rx;
766
 
+    k->send = tpa6130_tx;
767
 
+    dc->reset = tpa6130_reset;
768
 
+}
769
 
+
770
 
+static TypeInfo tpa6130_info = {
771
 
+    .name = "tpa6130",
772
 
+    .parent = TYPE_I2C_SLAVE,
773
 
+    .instance_size = sizeof(TPA6130State),
774
 
+    .class_init = tpa6130_class_init,
775
 
+};
776
 
+
777
 
+struct n900_s {
778
 
+    struct omap_mpu_state_s *cpu;
779
 
+    void *twl4030;
780
 
+    DeviceState *nand;
781
 
+    DeviceState *mipid;
782
 
+    DeviceState *tsc2005;
783
 
+    DeviceState *bq2415x;
784
 
+    DeviceState *tpa6130;
785
 
+    DeviceState *lis302dl;
786
 
+    DeviceState *smc;
787
 
+#ifdef CONFIG_GLES2
788
 
+    void *gles2;
789
 
+#endif
790
 
+    int extended_key;
791
 
+    int slide_open;
792
 
+    int camera_cover_open;
793
 
+    int headphone_connected;
794
 
+};
795
 
+
796
 
+/* this takes care of the keys which are not located on the
797
 
+ * n900 keypad (note that volume up/down keys are handled by
798
 
+ * the keypad eventhough the keys are not located on the keypad)
799
 
+ * as well as triggering some other hardware button/switch-like
800
 
+ * events that are mapped to the host keyboard:
801
 
+ *
802
 
+ * escape ... power
803
 
+ * f1 ....... keypad slider open/close
804
 
+ * f2 ....... keypad lock
805
 
+ * f3 ....... camera lens cover open/close
806
 
+ * f4 ....... camera focus
807
 
+ * f5 ....... camera take picture
808
 
+ * f6 ....... stereo headphone connect/disconnect
809
 
+ * kp1 ...... decrease accelerometer x axis value
810
 
+ * kp2 ...... increase accelerometer x axis value
811
 
+ * kp4 ...... decrease accelerometer y axis value
812
 
+ * kp5 ...... increase accelerometer y axis value
813
 
+ * kp7 ...... decrease accelerometer z axis value
814
 
+ * kp8 ...... increase accelerometer z axis value
815
 
+ */
816
 
+static void n900_key_handler(void *opaque, int keycode)
817
 
+{
818
 
+    struct n900_s *s = opaque;
819
 
+    if (!s->extended_key && keycode == 0xe0) {
820
 
+        s->extended_key = 0x80;
821
 
+    } else {
822
 
+        int release = keycode & 0x80;
823
 
+        keycode = (keycode & 0x7f) | s->extended_key;
824
 
+        s->extended_key = 0;
825
 
+        switch (keycode) {
826
 
+            case 0x01: /* escape */
827
 
+                twl4030_set_powerbutton_state(s->twl4030, !release);
828
 
+                break;
829
 
+            case 0x3b: /* f1 */
830
 
+                if (release) {
831
 
+                    s->slide_open = !s->slide_open;
832
 
+                    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio,
833
 
+                                                  N900_SLIDE_GPIO),
834
 
+                                 !s->slide_open);
835
 
+                }
836
 
+                break;
837
 
+            case 0x3c: /* f2 */
838
 
+                qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, N900_KBLOCK_GPIO),
839
 
+                             !!release);
840
 
+                break;
841
 
+            case 0x3d: /* f3 */
842
 
+                if (release) {
843
 
+                    s->camera_cover_open = !s->camera_cover_open;
844
 
+                    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio,
845
 
+                                                  N900_CAMCOVER_GPIO),
846
 
+                                 s->camera_cover_open);
847
 
+                }
848
 
+                break;
849
 
+            case 0x3e: /* f4 */
850
 
+                qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio,
851
 
+                                              N900_CAMFOCUS_GPIO),
852
 
+                             !!release);
853
 
+                break;
854
 
+            case 0x3f: /* f5 */
855
 
+                qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio,
856
 
+                                              N900_CAMLAUNCH_GPIO),
857
 
+                             !!release);
858
 
+                break;
859
 
+            case 0x40: /* f6 */
860
 
+                if (release) {
861
 
+                    s->headphone_connected = !s->headphone_connected;
862
 
+                    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio,
863
 
+                                                  N900_HEADPHONE_GPIO),
864
 
+                                 !s->headphone_connected);
865
 
+                }
866
 
+                break;
867
 
+            case 0x4f ... 0x50: /* kp1,2 */
868
 
+                lis302dl_step(s->lis302dl, 0, keycode - 0x4f, !release);
869
 
+                break;
870
 
+            case 0x4b ... 0x4c: /* kp4,5 */
871
 
+                lis302dl_step(s->lis302dl, 1, keycode - 0x4b, !release);
872
 
+                break;
873
 
+            case 0x47 ... 0x48: /* kp7,8 */
874
 
+                lis302dl_step(s->lis302dl, 2, keycode - 0x47, !release);
875
 
+                break;
876
 
+            default:
877
 
+                break;
878
 
+        }
879
 
+    }
880
 
+}
881
 
+
882
 
+static void n900_reset(void *opaque)
883
 
+{
884
 
+    struct n900_s *s = opaque;
885
 
+    s->slide_open = 1;
886
 
+    s->camera_cover_open = 0;
887
 
+    s->headphone_connected = 0;
888
 
+    qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N900_KBLOCK_GPIO));
889
 
+    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, N900_HEADPHONE_GPIO), 
890
 
+                 !s->headphone_connected);
891
 
+    qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N900_CAMLAUNCH_GPIO));
892
 
+    qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N900_CAMFOCUS_GPIO));
893
 
+    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, N900_CAMCOVER_GPIO),
894
 
+                 s->camera_cover_open);
895
 
+    qemu_set_irq(qdev_get_gpio_in(s->cpu->gpio, N900_SLIDE_GPIO),
896
 
+                 !s->slide_open);
897
 
+    omap3_boot_rom_emu(s->cpu);
898
 
+}
899
 
+
900
 
+
901
 
+static uint16_t n900_twl4030_madc_callback(twl4030_adc_type type, int ch)
902
 
+{
903
 
+    return 0x3ff;
904
 
+}
905
 
+
906
 
+static const TWL4030KeyMap n900_twl4030_keymap[] = {
907
 
+    {0x10, 0, 0}, /* Q */
908
 
+    {0x11, 0, 1}, /* W */
909
 
+    {0x12, 0, 2}, /* E */
910
 
+    {0x13, 0, 3}, /* R */
911
 
+    {0x14, 0, 4}, /* T */
912
 
+    {0x15, 0, 5}, /* Y */
913
 
+    {0x16, 0, 6}, /* U */
914
 
+    {0x17, 0, 7}, /* I */
915
 
+    {0x18, 1, 0}, /* O */
916
 
+    {0x20, 1, 1}, /* D */
917
 
+    {0x34, 1, 2}, /* . */
918
 
+    {0x2f, 1, 3}, /* V */
919
 
+    {0xd0, 1, 4}, /* DOWN */
920
 
+    {0x41, 1, 7}, /* F7 -- volume/zoom down */
921
 
+    {0x19, 2, 0}, /* P */
922
 
+    {0x21, 2, 1}, /* F */
923
 
+    {0xc8, 2, 2}, /* UP */
924
 
+    {0x30, 2, 3}, /* B */
925
 
+    {0xcd, 2, 4}, /* RIGHT */
926
 
+    {0x42, 2, 7}, /* F8 -- volume/zoom up */
927
 
+    {0x33, 3, 0}, /* , */
928
 
+    {0x22, 3, 1}, /* G */
929
 
+    {0x1c, 3, 2}, /* ENTER */
930
 
+    {0x31, 3, 3}, /* N */
931
 
+    {0x0e, 4, 0}, /* BACKSPACE */
932
 
+    {0x23, 4, 1}, /* H */
933
 
+    {0x32, 4, 3}, /* M */
934
 
+    {0x1d, 4, 4}, /* LEFTCTRL */
935
 
+    {0x9d, 4, 4}, /* RIGHTCTRL */
936
 
+    {0x24, 5, 1}, /* J */
937
 
+    {0x2c, 5, 2}, /* Z */
938
 
+    {0x39, 5, 3}, /* SPACE */
939
 
+    {0x38, 5, 4}, /* LEFTALT -- "fn" */
940
 
+    {0xb8, 5, 4}, /* RIGHTALT -- "fn" */
941
 
+    {0x1e, 6, 0}, /* A */
942
 
+    {0x25, 6, 1}, /* K */
943
 
+    {0x2d, 6, 2}, /* X */
944
 
+    {0x39, 6, 3}, /* SPACE */
945
 
+    {0x2a, 6, 4}, /* LEFTSHIFT */
946
 
+    {0x36, 6, 4}, /* RIGHTSHIFT */
947
 
+    {0x1f, 7, 0}, /* S */
948
 
+    {0x26, 7, 1}, /* L */
949
 
+    {0x2e, 7, 2}, /* C */
950
 
+    {0xcb, 7, 3}, /* LEFT */
951
 
+    //    {0x10, 0xff, 2}, /* F9 */
952
 
+    //    {0x10, 0xff, 4}, /* F10 */
953
 
+    //    {0x10, 0xff, 5}, /* F11 */
954
 
+    {-1, -1, -1}
955
 
+};
956
 
+
957
 
+static MouseTransformInfo n900_pointercal = {
958
 
+    .x = 800,
959
 
+    .y = 480,
960
 
+    .a = {14114,  18, -2825064,  34,  -8765, 32972906, 65536},
961
 
+};
962
 
+
963
 
+static void n900_init(QEMUMachineInitArgs *args)
964
 
+{
965
 
+    MemoryRegion *sysmem = get_system_memory();
966
 
+    MemoryRegion *ssi_iomem = g_new(MemoryRegion, 1);
967
 
+    struct n900_s *s = g_malloc0(sizeof(*s));
968
 
+    DriveInfo *dmtd = drive_get(IF_MTD, 0, 0);
969
 
+    DriveInfo *dsd  = drive_get(IF_SD, 0, 0);
970
 
+
971
 
+    if (!dmtd && !dsd) {
972
 
+        hw_error("%s: SD or NAND image required", __FUNCTION__);
973
 
+    }
974
 
+#if MAX_SERIAL_PORTS < 3
975
 
+#error MAX_SERIAL_PORTS must be at least 3!
976
 
+#endif
977
 
+    s->cpu = omap3_mpu_init(sysmem, omap3430, N900_SDRAM_SIZE,
978
 
+                            serial_hds[1], serial_hds[2],
979
 
+                            serial_hds[0], NULL);
980
 
+    omap_lcd_panel_attach(s->cpu->dss);
981
 
+
982
 
+    s->tsc2005 = spi_create_device(omap_mcspi_bus(s->cpu->mcspi, 0),
983
 
+                                   "tsc2005", 0);
984
 
+    qdev_connect_gpio_out(s->tsc2005, 0,
985
 
+                          qdev_get_gpio_in(s->cpu->gpio,
986
 
+                                           N900_TSC2005_IRQ_GPIO));
987
 
+    tsc2005_set_transform(s->tsc2005, &n900_pointercal, 600, 1500);
988
 
+    cursor_hide = 0; // who wants to use touchscreen without a pointer?
989
 
+
990
 
+    s->mipid = spi_create_device_noinit(omap_mcspi_bus(s->cpu->mcspi, 0),
991
 
+                                        "lcd_mipid", 2);
992
 
+    qdev_prop_set_uint32(s->mipid, "id", 0x101234);
993
 
+    qdev_prop_set_uint8(s->mipid, "n900", 1);
994
 
+    qdev_init_nofail(s->mipid);
995
 
+
996
 
+
997
 
+    s->nand = qdev_create(NULL, "onenand");
998
 
+    qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
999
 
+    qdev_prop_set_uint16(s->nand, "device_id", 0x40);
1000
 
+    qdev_prop_set_uint16(s->nand, "version_id", 0x121);
1001
 
+    qdev_prop_set_int32(s->nand, "shift", 1);
1002
 
+    if (dmtd && dmtd->bdrv) {
1003
 
+        qdev_prop_set_drive_nofail(s->nand, "drive", dmtd->bdrv);
1004
 
+    }
1005
 
+    qdev_init_nofail(s->nand);
1006
 
+    sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
1007
 
+                       qdev_get_gpio_in(s->cpu->gpio, N900_ONENAND_GPIO));
1008
 
+    omap_gpmc_attach(s->cpu->gpmc, 0,
1009
 
+                     sysbus_mmio_get_region(SYS_BUS_DEVICE(s->nand), 0));
1010
 
+
1011
 
+    if (dsd) {
1012
 
+        omap3_mmc_attach(s->cpu->omap3_mmc[1], dsd->bdrv, 0, 1);
1013
 
+    }
1014
 
+    if ((dsd = drive_get(IF_SD, 0, 1)) != NULL) {
1015
 
+        omap3_mmc_attach(s->cpu->omap3_mmc[0], dsd->bdrv, 0, 0);
1016
 
+        //qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N900_SDCOVER_GPIO));
1017
 
+    }
1018
 
+
1019
 
+    memory_region_init_io(ssi_iomem, &ssi_ops, 0, "n900_ssi", 0x3c00);
1020
 
+    memory_region_add_subregion(sysmem, 0x48058000, ssi_iomem);
1021
 
+
1022
 
+    s->twl4030 = twl4030_init(omap_i2c_bus(s->cpu->i2c[0]),
1023
 
+                              qdev_get_gpio_in(s->cpu->ih[0],
1024
 
+                                               OMAP_INT_3XXX_SYS_NIRQ),
1025
 
+                              NULL, n900_twl4030_keymap);
1026
 
+    twl4030_madc_attach(s->twl4030, n900_twl4030_madc_callback);
1027
 
+    i2c_bus *i2c2 = omap_i2c_bus(s->cpu->i2c[1]);
1028
 
+    s->bq2415x = i2c_create_slave(i2c2, "bq2415x", 0x6b);
1029
 
+    s->tpa6130 = i2c_create_slave(i2c2, "tpa6130", 0x60);
1030
 
+    qdev_connect_gpio_out(s->cpu->gpio, N900_HEADPHONE_EN_GPIO,
1031
 
+                          qdev_get_gpio_in(s->tpa6130, 0));
1032
 
+    i2c_bus *i2c3 = omap_i2c_bus(s->cpu->i2c[2]);
1033
 
+    s->lis302dl = i2c_create_slave(i2c3, "lis302dl", 0x1d);
1034
 
+    qdev_connect_gpio_out(s->lis302dl, 0,
1035
 
+                          qdev_get_gpio_in(s->cpu->gpio,
1036
 
+                                           N900_LIS302DL_INT1_GPIO));
1037
 
+    qdev_connect_gpio_out(s->lis302dl, 1,
1038
 
+                          qdev_get_gpio_in(s->cpu->gpio,
1039
 
+                                           N900_LIS302DL_INT2_GPIO));
1040
 
+
1041
 
+    int i;
1042
 
+    for (i = 0; i < nb_nics; i++) {
1043
 
+        if (!nd_table[i].model || !strcmp(nd_table[i].model, "smc91c111")) {
1044
 
+            break;
1045
 
+        }
1046
 
+    }
1047
 
+    if (i < nb_nics) {
1048
 
+        s->smc = qdev_create(NULL, "smc91c111");
1049
 
+        qdev_set_nic_properties(s->smc, &nd_table[i]);
1050
 
+        qdev_init_nofail(s->smc);
1051
 
+        sysbus_connect_irq(SYS_BUS_DEVICE(s->smc), 0,
1052
 
+                           qdev_get_gpio_in(s->cpu->gpio, 54));
1053
 
+        omap_gpmc_attach(s->cpu->gpmc, 1,
1054
 
+                         sysbus_mmio_get_region(SYS_BUS_DEVICE(s->smc), 0));
1055
 
+    } else {
1056
 
+        hw_error("%s: no NIC for smc91c111\n", __FUNCTION__);
1057
 
+    }
1058
 
+
1059
 
+    qemu_add_kbd_event_handler(n900_key_handler, s);
1060
 
+
1061
 
+    qemu_register_reset(n900_reset, s);
1062
 
+}
1063
 
+
1064
 
+static QEMUMachine n900_machine = {
1065
 
+    .name = "n900",
1066
 
+    .desc = "Nokia N900 (OMAP3)",
1067
 
+    .init = n900_init,
1068
 
+};
1069
 
+
1070
 
 static void nseries_register_types(void)
1071
 
 {
1072
 
+    type_register_static(&bq2415x_info);
1073
 
+    type_register_static(&tpa6130_info);
1074
 
+    type_register_static(&lis302dl_info);
1075
 
     type_register_static(&mipid_info);
1076
 
 }
1077
 
 
1078
 
@@ -1565,6 +2612,7 @@ static void nseries_machine_init(void)
1079
 
 {
1080
 
     qemu_register_machine(&n800_machine);
1081
 
     qemu_register_machine(&n810_machine);
1082
 
+    qemu_register_machine(&n900_machine);
1083
 
 }
1084
 
 
1085
 
 type_init(nseries_register_types);
1086
 
1.8.1.2
1087