2
* PXA270-based Clamshell PDA platforms.
4
* Copyright (c) 2006 Openedhand Ltd.
5
* Written by Andrzej Zaborowski <balrog@zabor.org>
7
* This code is licensed under the GNU GPL v2.
17
#include "qemu-timer.h"
21
#include "audio/audio.h"
24
#define spitz_printf(format, ...) \
25
fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
27
#if TARGET_PHYS_ADDR_BITS == 32
28
#define REG_FMT "0x%02x"
30
#define REG_FMT "0x%02lx"
34
#define FLASH_BASE 0x0c000000
35
#define FLASH_ECCLPLB 0x00 /* Line parity 7 - 0 bit */
36
#define FLASH_ECCLPUB 0x04 /* Line parity 15 - 8 bit */
37
#define FLASH_ECCCP 0x08 /* Column parity 5 - 0 bit */
38
#define FLASH_ECCCNTR 0x0c /* ECC byte counter */
39
#define FLASH_ECCCLRR 0x10 /* Clear ECC */
40
#define FLASH_FLASHIO 0x14 /* Flash I/O */
41
#define FLASH_FLASHCTL 0x18 /* Flash Control */
43
#define FLASHCTL_CE0 (1 << 0)
44
#define FLASHCTL_CLE (1 << 1)
45
#define FLASHCTL_ALE (1 << 2)
46
#define FLASHCTL_WP (1 << 3)
47
#define FLASHCTL_CE1 (1 << 4)
48
#define FLASHCTL_RYBY (1 << 5)
49
#define FLASHCTL_NCE (FLASHCTL_CE0 | FLASHCTL_CE1)
52
target_phys_addr_t target_base;
53
struct nand_flash_s *nand;
55
struct ecc_state_s ecc;
58
static uint32_t sl_readb(void *opaque, target_phys_addr_t addr)
60
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
62
addr -= s->target_base;
65
#define BSHR(byte, from, to) ((s->ecc.lp[byte] >> (from - to)) & (1 << to))
67
return BSHR(0, 4, 0) | BSHR(0, 5, 2) | BSHR(0, 6, 4) | BSHR(0, 7, 6) |
68
BSHR(1, 4, 1) | BSHR(1, 5, 3) | BSHR(1, 6, 5) | BSHR(1, 7, 7);
70
#define BSHL(byte, from, to) ((s->ecc.lp[byte] << (to - from)) & (1 << to))
72
return BSHL(0, 0, 0) | BSHL(0, 1, 2) | BSHL(0, 2, 4) | BSHL(0, 3, 6) |
73
BSHL(1, 0, 1) | BSHL(1, 1, 3) | BSHL(1, 2, 5) | BSHL(1, 3, 7);
79
return s->ecc.count & 0xff;
82
nand_getpins(s->nand, &ryby);
84
return s->ctl | FLASHCTL_RYBY;
89
return ecc_digest(&s->ecc, nand_getio(s->nand));
92
spitz_printf("Bad register offset " REG_FMT "\n", addr);
97
static uint32_t sl_readl(void *opaque, target_phys_addr_t addr)
99
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
100
addr -= s->target_base;
102
if (addr == FLASH_FLASHIO)
103
return ecc_digest(&s->ecc, nand_getio(s->nand)) |
104
(ecc_digest(&s->ecc, nand_getio(s->nand)) << 16);
106
return sl_readb(opaque, addr);
109
static void sl_writeb(void *opaque, target_phys_addr_t addr,
112
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
113
addr -= s->target_base;
117
/* Value is ignored. */
122
s->ctl = value & 0xff & ~FLASHCTL_RYBY;
123
nand_setpins(s->nand,
124
s->ctl & FLASHCTL_CLE,
125
s->ctl & FLASHCTL_ALE,
126
s->ctl & FLASHCTL_NCE,
127
s->ctl & FLASHCTL_WP,
132
nand_setio(s->nand, ecc_digest(&s->ecc, value & 0xff));
136
spitz_printf("Bad register offset " REG_FMT "\n", addr);
140
static void sl_save(QEMUFile *f, void *opaque)
142
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
144
qemu_put_8s(f, &s->ctl);
148
static int sl_load(QEMUFile *f, void *opaque, int version_id)
150
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
152
qemu_get_8s(f, &s->ctl);
163
static void sl_flash_register(struct pxa2xx_state_s *cpu, int size)
167
CPUReadMemoryFunc *sl_readfn[] = {
172
CPUWriteMemoryFunc *sl_writefn[] = {
178
s = (struct sl_nand_s *) qemu_mallocz(sizeof(struct sl_nand_s));
179
s->target_base = FLASH_BASE;
181
if (size == FLASH_128M)
182
s->nand = nand_init(NAND_MFR_SAMSUNG, 0x73);
183
else if (size == FLASH_1024M)
184
s->nand = nand_init(NAND_MFR_SAMSUNG, 0xf1);
186
iomemtype = cpu_register_io_memory(0, sl_readfn,
188
cpu_register_physical_memory(s->target_base, 0x40, iomemtype);
190
register_savevm("sl_flash", 0, 0, sl_save, sl_load, s);
195
#define SPITZ_KEY_STROBE_NUM 11
196
#define SPITZ_KEY_SENSE_NUM 7
198
static const int spitz_gpio_key_sense[SPITZ_KEY_SENSE_NUM] = {
199
12, 17, 91, 34, 36, 38, 39
202
static const int spitz_gpio_key_strobe[SPITZ_KEY_STROBE_NUM] = {
203
88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114
206
/* Eighth additional row maps the special keys */
207
static int spitz_keymap[SPITZ_KEY_SENSE_NUM + 1][SPITZ_KEY_STROBE_NUM] = {
208
{ 0x1d, 0x02, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x3f, 0x40 },
209
{ -1 , 0x03, 0x05, 0x13, 0x15, 0x09, 0x17, 0x18, 0x19, 0x41, 0x42 },
210
{ 0x0f, 0x10, 0x12, 0x14, 0x22, 0x16, 0x24, 0x25, -1 , -1 , -1 },
211
{ 0x3c, 0x11, 0x1f, 0x21, 0x2f, 0x23, 0x32, 0x26, -1 , 0x36, -1 },
212
{ 0x3b, 0x1e, 0x20, 0x2e, 0x30, 0x31, 0x34, -1 , 0x1c, 0x2a, -1 },
213
{ 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33, -1 , 0x48, -1 , -1 , 0x38 },
214
{ 0x37, 0x3d, -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d, -1 , -1 },
215
{ 0x52, 0x43, 0x01, 0x47, 0x49, -1 , -1 , -1 , -1 , -1 , -1 },
218
#define SPITZ_GPIO_AK_INT 13 /* Remote control */
219
#define SPITZ_GPIO_SYNC 16 /* Sync button */
220
#define SPITZ_GPIO_ON_KEY 95 /* Power button */
221
#define SPITZ_GPIO_SWA 97 /* Lid */
222
#define SPITZ_GPIO_SWB 96 /* Tablet mode */
224
/* The special buttons are mapped to unused keys */
225
static const int spitz_gpiomap[5] = {
226
SPITZ_GPIO_AK_INT, SPITZ_GPIO_SYNC, SPITZ_GPIO_ON_KEY,
227
SPITZ_GPIO_SWA, SPITZ_GPIO_SWB,
229
static int spitz_gpio_invert[5] = { 0, 0, 0, 0, 0, };
231
struct spitz_keyboard_s {
232
qemu_irq sense[SPITZ_KEY_SENSE_NUM];
236
uint16_t keyrow[SPITZ_KEY_SENSE_NUM];
237
uint16_t strobe_state;
238
uint16_t sense_state;
240
uint16_t pre_map[0x100];
244
int fifopos, fifolen;
248
static void spitz_keyboard_sense_update(struct spitz_keyboard_s *s)
251
uint16_t strobe, sense = 0;
252
for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++) {
253
strobe = s->keyrow[i] & s->strobe_state;
256
if (!(s->sense_state & (1 << i)))
257
qemu_irq_raise(s->sense[i]);
258
} else if (s->sense_state & (1 << i))
259
qemu_irq_lower(s->sense[i]);
262
s->sense_state = sense;
265
static void spitz_keyboard_strobe(void *opaque, int line, int level)
267
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
270
s->strobe_state |= 1 << line;
272
s->strobe_state &= ~(1 << line);
273
spitz_keyboard_sense_update(s);
276
static void spitz_keyboard_keydown(struct spitz_keyboard_s *s, int keycode)
278
int spitz_keycode = s->keymap[keycode & 0x7f];
279
if (spitz_keycode == -1)
282
/* Handle the additional keys */
283
if ((spitz_keycode >> 4) == SPITZ_KEY_SENSE_NUM) {
284
qemu_set_irq(s->gpiomap[spitz_keycode & 0xf], (keycode < 0x80) ^
285
spitz_gpio_invert[spitz_keycode & 0xf]);
290
s->keyrow[spitz_keycode >> 4] &= ~(1 << (spitz_keycode & 0xf));
292
s->keyrow[spitz_keycode >> 4] |= 1 << (spitz_keycode & 0xf);
294
spitz_keyboard_sense_update(s);
297
#define SHIFT (1 << 7)
298
#define CTRL (1 << 8)
301
#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
303
static void spitz_keyboard_handler(struct spitz_keyboard_s *s, int keycode)
308
case 0x2a: /* Left Shift */
314
case 0x36: /* Right Shift */
320
case 0x1d: /* Control */
334
code = s->pre_map[mapcode = ((s->modifiers & 3) ?
336
(keycode & ~SHIFT))];
338
if (code != mapcode) {
340
if ((code & SHIFT) && !(s->modifiers & 1))
341
QUEUE_KEY(0x2a | (keycode & 0x80));
342
if ((code & CTRL ) && !(s->modifiers & 4))
343
QUEUE_KEY(0x1d | (keycode & 0x80));
344
if ((code & FN ) && !(s->modifiers & 8))
345
QUEUE_KEY(0x38 | (keycode & 0x80));
346
if ((code & FN ) && (s->modifiers & 1))
347
QUEUE_KEY(0x2a | (~keycode & 0x80));
348
if ((code & FN ) && (s->modifiers & 2))
349
QUEUE_KEY(0x36 | (~keycode & 0x80));
351
if (keycode & 0x80) {
352
if ((s->imodifiers & 1 ) && !(s->modifiers & 1))
353
QUEUE_KEY(0x2a | 0x80);
354
if ((s->imodifiers & 4 ) && !(s->modifiers & 4))
355
QUEUE_KEY(0x1d | 0x80);
356
if ((s->imodifiers & 8 ) && !(s->modifiers & 8))
357
QUEUE_KEY(0x38 | 0x80);
358
if ((s->imodifiers & 0x10) && (s->modifiers & 1))
360
if ((s->imodifiers & 0x20) && (s->modifiers & 2))
364
if ((code & SHIFT) && !((s->modifiers | s->imodifiers) & 1)) {
368
if ((code & CTRL ) && !((s->modifiers | s->imodifiers) & 4)) {
372
if ((code & FN ) && !((s->modifiers | s->imodifiers) & 8)) {
376
if ((code & FN ) && (s->modifiers & 1) &&
377
!(s->imodifiers & 0x10)) {
378
QUEUE_KEY(0x2a | 0x80);
379
s->imodifiers |= 0x10;
381
if ((code & FN ) && (s->modifiers & 2) &&
382
!(s->imodifiers & 0x20)) {
383
QUEUE_KEY(0x36 | 0x80);
384
s->imodifiers |= 0x20;
390
QUEUE_KEY((code & 0x7f) | (keycode & 0x80));
393
static void spitz_keyboard_tick(void *opaque)
395
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
398
spitz_keyboard_keydown(s, s->fifo[s->fifopos ++]);
400
if (s->fifopos >= 16)
404
qemu_mod_timer(s->kbdtimer, qemu_get_clock(vm_clock) + ticks_per_sec / 32);
407
static void spitz_keyboard_pre_map(struct spitz_keyboard_s *s)
410
for (i = 0; i < 0x100; i ++)
412
s->pre_map[0x02 | SHIFT ] = 0x02 | SHIFT; /* exclam */
413
s->pre_map[0x28 | SHIFT ] = 0x03 | SHIFT; /* quotedbl */
414
s->pre_map[0x04 | SHIFT ] = 0x04 | SHIFT; /* numbersign */
415
s->pre_map[0x05 | SHIFT ] = 0x05 | SHIFT; /* dollar */
416
s->pre_map[0x06 | SHIFT ] = 0x06 | SHIFT; /* percent */
417
s->pre_map[0x08 | SHIFT ] = 0x07 | SHIFT; /* ampersand */
418
s->pre_map[0x28 ] = 0x08 | SHIFT; /* apostrophe */
419
s->pre_map[0x0a | SHIFT ] = 0x09 | SHIFT; /* parenleft */
420
s->pre_map[0x0b | SHIFT ] = 0x0a | SHIFT; /* parenright */
421
s->pre_map[0x29 | SHIFT ] = 0x0b | SHIFT; /* asciitilde */
422
s->pre_map[0x03 | SHIFT ] = 0x0c | SHIFT; /* at */
423
s->pre_map[0xd3 ] = 0x0e | FN; /* Delete */
424
s->pre_map[0x3a ] = 0x0f | FN; /* Caps_Lock */
425
s->pre_map[0x07 | SHIFT ] = 0x11 | FN; /* asciicircum */
426
s->pre_map[0x0d ] = 0x12 | FN; /* equal */
427
s->pre_map[0x0d | SHIFT ] = 0x13 | FN; /* plus */
428
s->pre_map[0x1a ] = 0x14 | FN; /* bracketleft */
429
s->pre_map[0x1b ] = 0x15 | FN; /* bracketright */
430
s->pre_map[0x1a | SHIFT ] = 0x16 | FN; /* braceleft */
431
s->pre_map[0x1b | SHIFT ] = 0x17 | FN; /* braceright */
432
s->pre_map[0x27 ] = 0x22 | FN; /* semicolon */
433
s->pre_map[0x27 | SHIFT ] = 0x23 | FN; /* colon */
434
s->pre_map[0x09 | SHIFT ] = 0x24 | FN; /* asterisk */
435
s->pre_map[0x2b ] = 0x25 | FN; /* backslash */
436
s->pre_map[0x2b | SHIFT ] = 0x26 | FN; /* bar */
437
s->pre_map[0x0c | SHIFT ] = 0x30 | FN; /* underscore */
438
s->pre_map[0x33 | SHIFT ] = 0x33 | FN; /* less */
439
s->pre_map[0x35 ] = 0x33 | SHIFT; /* slash */
440
s->pre_map[0x34 | SHIFT ] = 0x34 | FN; /* greater */
441
s->pre_map[0x35 | SHIFT ] = 0x34 | SHIFT; /* question */
442
s->pre_map[0x49 ] = 0x48 | FN; /* Page_Up */
443
s->pre_map[0x51 ] = 0x50 | FN; /* Page_Down */
449
s->kbdtimer = qemu_new_timer(vm_clock, spitz_keyboard_tick, s);
450
spitz_keyboard_tick(s);
457
static void spitz_keyboard_save(QEMUFile *f, void *opaque)
459
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
462
qemu_put_be16s(f, &s->sense_state);
463
qemu_put_be16s(f, &s->strobe_state);
464
for (i = 0; i < 5; i ++)
465
qemu_put_byte(f, spitz_gpio_invert[i]);
468
static int spitz_keyboard_load(QEMUFile *f, void *opaque, int version_id)
470
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
473
qemu_get_be16s(f, &s->sense_state);
474
qemu_get_be16s(f, &s->strobe_state);
475
for (i = 0; i < 5; i ++)
476
spitz_gpio_invert[i] = qemu_get_byte(f);
478
/* Release all pressed keys */
479
memset(s->keyrow, 0, sizeof(s->keyrow));
480
spitz_keyboard_sense_update(s);
489
static void spitz_keyboard_register(struct pxa2xx_state_s *cpu)
492
struct spitz_keyboard_s *s;
494
s = (struct spitz_keyboard_s *)
495
qemu_mallocz(sizeof(struct spitz_keyboard_s));
496
memset(s, 0, sizeof(struct spitz_keyboard_s));
498
for (i = 0; i < 0x80; i ++)
500
for (i = 0; i < SPITZ_KEY_SENSE_NUM + 1; i ++)
501
for (j = 0; j < SPITZ_KEY_STROBE_NUM; j ++)
502
if (spitz_keymap[i][j] != -1)
503
s->keymap[spitz_keymap[i][j]] = (i << 4) | j;
505
for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++)
506
s->sense[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpio_key_sense[i]];
508
for (i = 0; i < 5; i ++)
509
s->gpiomap[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpiomap[i]];
511
s->strobe = qemu_allocate_irqs(spitz_keyboard_strobe, s,
512
SPITZ_KEY_STROBE_NUM);
513
for (i = 0; i < SPITZ_KEY_STROBE_NUM; i ++)
514
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
516
spitz_keyboard_pre_map(s);
517
qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
519
register_savevm("spitz_keyboard", 0, 0,
520
spitz_keyboard_save, spitz_keyboard_load, s);
525
struct scoop_info_s {
526
target_phys_addr_t target_base;
527
qemu_irq handler[16];
544
#define SCOOP_MCR 0x00
545
#define SCOOP_CDR 0x04
546
#define SCOOP_CSR 0x08
547
#define SCOOP_CPR 0x0c
548
#define SCOOP_CCR 0x10
549
#define SCOOP_IRR_IRM 0x14
550
#define SCOOP_IMR 0x18
551
#define SCOOP_ISR 0x1c
552
#define SCOOP_GPCR 0x20
553
#define SCOOP_GPWR 0x24
554
#define SCOOP_GPRR 0x28
556
static inline void scoop_gpio_handler_update(struct scoop_info_s *s) {
557
uint32_t level, diff;
559
level = s->gpio_level & s->gpio_dir;
561
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
563
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
566
s->prev_level = level;
569
static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr)
571
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
572
addr -= s->target_base;
594
return s->gpio_level;
598
spitz_printf("Bad register offset " REG_FMT "\n", addr);
604
static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
606
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
607
addr -= s->target_base;
636
scoop_gpio_handler_update(s);
639
s->gpio_level = value & s->gpio_dir;
640
scoop_gpio_handler_update(s);
646
spitz_printf("Bad register offset " REG_FMT "\n", addr);
650
CPUReadMemoryFunc *scoop_readfn[] = {
655
CPUWriteMemoryFunc *scoop_writefn[] = {
661
static void scoop_gpio_set(void *opaque, int line, int level)
663
struct scoop_info_s *s = (struct scoop_info_s *) s;
666
s->gpio_level |= (1 << line);
668
s->gpio_level &= ~(1 << line);
671
static inline qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s)
676
static inline void scoop_gpio_out_set(struct scoop_info_s *s, int line,
679
spitz_printf("No GPIO pin %i\n", line);
683
s->handler[line] = handler;
686
static void scoop_save(QEMUFile *f, void *opaque)
688
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
689
qemu_put_be16s(f, &s->status);
690
qemu_put_be16s(f, &s->power);
691
qemu_put_be32s(f, &s->gpio_level);
692
qemu_put_be32s(f, &s->gpio_dir);
693
qemu_put_be32s(f, &s->prev_level);
694
qemu_put_be16s(f, &s->mcr);
695
qemu_put_be16s(f, &s->cdr);
696
qemu_put_be16s(f, &s->ccr);
697
qemu_put_be16s(f, &s->irr);
698
qemu_put_be16s(f, &s->imr);
699
qemu_put_be16s(f, &s->isr);
700
qemu_put_be16s(f, &s->gprr);
703
static int scoop_load(QEMUFile *f, void *opaque, int version_id)
705
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
706
qemu_get_be16s(f, &s->status);
707
qemu_get_be16s(f, &s->power);
708
qemu_get_be32s(f, &s->gpio_level);
709
qemu_get_be32s(f, &s->gpio_dir);
710
qemu_get_be32s(f, &s->prev_level);
711
qemu_get_be16s(f, &s->mcr);
712
qemu_get_be16s(f, &s->cdr);
713
qemu_get_be16s(f, &s->ccr);
714
qemu_get_be16s(f, &s->irr);
715
qemu_get_be16s(f, &s->imr);
716
qemu_get_be16s(f, &s->isr);
717
qemu_get_be16s(f, &s->gprr);
722
static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu,
725
struct scoop_info_s *s;
727
s = (struct scoop_info_s *)
728
qemu_mallocz(sizeof(struct scoop_info_s) * 2);
729
memset(s, 0, sizeof(struct scoop_info_s) * count);
730
s[0].target_base = 0x10800000;
731
s[1].target_base = 0x08800040;
737
s[0].in = qemu_allocate_irqs(scoop_gpio_set, &s[0], 16);
738
iomemtype = cpu_register_io_memory(0, scoop_readfn,
739
scoop_writefn, &s[0]);
740
cpu_register_physical_memory(s[0].target_base, 0x1000, iomemtype);
741
register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]);
746
s[1].in = qemu_allocate_irqs(scoop_gpio_set, &s[1], 16);
747
iomemtype = cpu_register_io_memory(0, scoop_readfn,
748
scoop_writefn, &s[1]);
749
cpu_register_physical_memory(s[1].target_base, 0x1000, iomemtype);
750
register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]);
755
/* LCD backlight controller */
757
#define LCDTG_RESCTL 0x00
758
#define LCDTG_PHACTRL 0x01
759
#define LCDTG_DUTYCTRL 0x02
760
#define LCDTG_POWERREG0 0x03
761
#define LCDTG_POWERREG1 0x04
762
#define LCDTG_GPOR3 0x05
763
#define LCDTG_PICTRL 0x06
764
#define LCDTG_POLCTRL 0x07
766
static int bl_intensity, bl_power;
768
static void spitz_bl_update(struct pxa2xx_state_s *s)
770
if (bl_power && bl_intensity)
771
spitz_printf("LCD Backlight now at %i/63\n", bl_intensity);
773
spitz_printf("LCD Backlight now off\n");
776
static inline void spitz_bl_bit5(void *opaque, int line, int level)
778
int prev = bl_intensity;
781
bl_intensity &= ~0x20;
783
bl_intensity |= 0x20;
785
if (bl_power && prev != bl_intensity)
786
spitz_bl_update((struct pxa2xx_state_s *) opaque);
789
static inline void spitz_bl_power(void *opaque, int line, int level)
792
spitz_bl_update((struct pxa2xx_state_s *) opaque);
795
static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd)
804
spitz_printf("LCD in QVGA mode\n");
806
spitz_printf("LCD in VGA mode\n");
810
bl_intensity &= ~0x1f;
811
bl_intensity |= value;
813
spitz_bl_update((struct pxa2xx_state_s *) opaque);
816
case LCDTG_POWERREG0:
817
/* Set common voltage to M62332FP */
824
#define CORGI_SSP_PORT 2
826
#define SPITZ_GPIO_LCDCON_CS 53
827
#define SPITZ_GPIO_ADS7846_CS 14
828
#define SPITZ_GPIO_MAX1111_CS 20
829
#define SPITZ_GPIO_TP_INT 11
831
static int lcd_en, ads_en, max_en;
832
static struct max111x_s *max1111;
833
static struct ads7846_state_s *ads7846;
835
/* "Demux" the signal based on current chipselect */
836
static uint32_t corgi_ssp_read(void *opaque)
841
return ads7846_read(ads7846);
843
return max111x_read(max1111);
847
static void corgi_ssp_write(void *opaque, uint32_t value)
850
spitz_lcdtg_dac_put(opaque, value);
852
ads7846_write(ads7846, value);
854
max111x_write(max1111, value);
857
static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
872
#define MAX1111_BATT_VOLT 1
873
#define MAX1111_BATT_TEMP 2
874
#define MAX1111_ACIN_VOLT 3
876
#define SPITZ_BATTERY_TEMP 0xe0 /* About 2.9V */
877
#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
878
#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
880
static void spitz_adc_temp_on(void *opaque, int line, int level)
886
max111x_set_input(max1111, MAX1111_BATT_TEMP, SPITZ_BATTERY_TEMP);
888
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
891
static void spitz_ssp_save(QEMUFile *f, void *opaque)
893
qemu_put_be32(f, lcd_en);
894
qemu_put_be32(f, ads_en);
895
qemu_put_be32(f, max_en);
896
qemu_put_be32(f, bl_intensity);
897
qemu_put_be32(f, bl_power);
900
static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id)
902
lcd_en = qemu_get_be32(f);
903
ads_en = qemu_get_be32(f);
904
max_en = qemu_get_be32(f);
905
bl_intensity = qemu_get_be32(f);
906
bl_power = qemu_get_be32(f);
911
static void spitz_ssp_attach(struct pxa2xx_state_s *cpu)
913
qemu_irq *chipselects;
915
lcd_en = ads_en = max_en = 0;
917
ads7846 = ads7846_init(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_TP_INT]);
919
max1111 = max1111_init(0);
920
max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT);
921
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
922
max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN);
924
pxa2xx_ssp_attach(cpu->ssp[CORGI_SSP_PORT - 1], corgi_ssp_read,
925
corgi_ssp_write, cpu);
927
chipselects = qemu_allocate_irqs(corgi_ssp_gpio_cs, cpu, 3);
928
pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_LCDCON_CS, chipselects[0]);
929
pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ADS7846_CS, chipselects[1]);
930
pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_MAX1111_CS, chipselects[2]);
935
register_savevm("spitz_ssp", 0, 0, spitz_ssp_save, spitz_ssp_load, cpu);
940
static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu)
942
struct pcmcia_card_s *md;
944
BlockDriverState *bs;
946
index = drive_get_index(IF_IDE, 0, 0);
949
bs = drives_table[index].bdrv;
950
if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
951
md = dscm1xxxx_init(bs);
952
pxa2xx_pcmcia_attach(cpu->pcmcia[1], md);
956
/* Wm8750 and Max7310 on I2C */
958
#define AKITA_MAX_ADDR 0x18
959
#define SPITZ_WM_ADDRL 0x1b
960
#define SPITZ_WM_ADDRH 0x1a
962
#define SPITZ_GPIO_WM 5
965
static void spitz_wm8750_addr(void *opaque, int line, int level)
967
i2c_slave *wm = (i2c_slave *) opaque;
969
i2c_set_slave_address(wm, SPITZ_WM_ADDRH);
971
i2c_set_slave_address(wm, SPITZ_WM_ADDRL);
975
static void spitz_i2c_setup(struct pxa2xx_state_s *cpu)
977
/* Attach the CPU on one end of our I2C bus. */
978
i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
987
/* Attach a WM8750 to the bus */
988
wm = wm8750_init(bus, audio);
990
spitz_wm8750_addr(wm, 0, 0);
991
pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_WM,
992
qemu_allocate_irqs(spitz_wm8750_addr, wm, 1)[0]);
993
/* .. and to the sound interface. */
994
cpu->i2s->opaque = wm;
995
cpu->i2s->codec_out = wm8750_dac_dat;
996
cpu->i2s->codec_in = wm8750_adc_dat;
997
wm8750_data_req_set(wm, cpu->i2s->data_req, cpu->i2s);
1001
static void spitz_akita_i2c_setup(struct pxa2xx_state_s *cpu)
1003
/* Attach a Max7310 to Akita I2C bus. */
1004
i2c_set_slave_address(max7310_init(pxa2xx_i2c_bus(cpu->i2c[0])),
1008
/* Other peripherals */
1010
static void spitz_out_switch(void *opaque, int line, int level)
1014
spitz_printf("Charging %s.\n", level ? "off" : "on");
1017
spitz_printf("Discharging %s.\n", level ? "on" : "off");
1020
spitz_printf("Green LED %s.\n", level ? "on" : "off");
1023
spitz_printf("Orange LED %s.\n", level ? "on" : "off");
1026
spitz_bl_bit5(opaque, line, level);
1029
spitz_bl_power(opaque, line, level);
1032
spitz_adc_temp_on(opaque, line, level);
1037
#define SPITZ_SCP_LED_GREEN 1
1038
#define SPITZ_SCP_JK_B 2
1039
#define SPITZ_SCP_CHRG_ON 3
1040
#define SPITZ_SCP_MUTE_L 4
1041
#define SPITZ_SCP_MUTE_R 5
1042
#define SPITZ_SCP_CF_POWER 6
1043
#define SPITZ_SCP_LED_ORANGE 7
1044
#define SPITZ_SCP_JK_A 8
1045
#define SPITZ_SCP_ADC_TEMP_ON 9
1046
#define SPITZ_SCP2_IR_ON 1
1047
#define SPITZ_SCP2_AKIN_PULLUP 2
1048
#define SPITZ_SCP2_BACKLIGHT_CONT 7
1049
#define SPITZ_SCP2_BACKLIGHT_ON 8
1050
#define SPITZ_SCP2_MIC_BIAS 9
1052
static void spitz_scoop_gpio_setup(struct pxa2xx_state_s *cpu,
1053
struct scoop_info_s *scp, int num)
1055
qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8);
1057
scoop_gpio_out_set(&scp[0], SPITZ_SCP_CHRG_ON, outsignals[0]);
1058
scoop_gpio_out_set(&scp[0], SPITZ_SCP_JK_B, outsignals[1]);
1059
scoop_gpio_out_set(&scp[0], SPITZ_SCP_LED_GREEN, outsignals[2]);
1060
scoop_gpio_out_set(&scp[0], SPITZ_SCP_LED_ORANGE, outsignals[3]);
1063
scoop_gpio_out_set(&scp[1], SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
1064
scoop_gpio_out_set(&scp[1], SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
1067
scoop_gpio_out_set(&scp[0], SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
1070
#define SPITZ_GPIO_HSYNC 22
1071
#define SPITZ_GPIO_SD_DETECT 9
1072
#define SPITZ_GPIO_SD_WP 81
1073
#define SPITZ_GPIO_ON_RESET 89
1074
#define SPITZ_GPIO_BAT_COVER 90
1075
#define SPITZ_GPIO_CF1_IRQ 105
1076
#define SPITZ_GPIO_CF1_CD 94
1077
#define SPITZ_GPIO_CF2_IRQ 106
1078
#define SPITZ_GPIO_CF2_CD 93
1080
static int spitz_hsync;
1082
static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
1084
struct pxa2xx_state_s *cpu = (struct pxa2xx_state_s *) opaque;
1085
qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_HSYNC], spitz_hsync);
1089
static void spitz_gpio_setup(struct pxa2xx_state_s *cpu, int slots)
1093
* Bad hack: We toggle the LCD hsync GPIO on every GPIO status
1094
* read to satisfy broken guests that poll-wait for hsync.
1095
* Simulating a real hsync event would be less practical and
1096
* wouldn't guarantee that a guest ever exits the loop.
1099
lcd_hsync = qemu_allocate_irqs(spitz_lcd_hsync_handler, cpu, 1)[0];
1100
pxa2xx_gpio_read_notifier(cpu->gpio, lcd_hsync);
1101
pxa2xx_lcd_vsync_notifier(cpu->lcd, lcd_hsync);
1104
pxa2xx_mmci_handlers(cpu->mmc,
1105
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SD_WP],
1106
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SD_DETECT]);
1108
/* Battery lock always closed */
1109
qemu_irq_raise(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_BAT_COVER]);
1112
pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ON_RESET, cpu->reset);
1114
/* PCMCIA signals: card's IRQ and Card-Detect */
1116
pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
1117
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF1_IRQ],
1118
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF1_CD]);
1120
pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
1121
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF2_IRQ],
1122
pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_CF2_CD]);
1124
/* Initialise the screen rotation related signals */
1125
spitz_gpio_invert[3] = 0; /* Always open */
1126
if (graphic_rotate) { /* Tablet mode */
1127
spitz_gpio_invert[4] = 0;
1128
} else { /* Portrait mode */
1129
spitz_gpio_invert[4] = 1;
1131
qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SWA],
1132
spitz_gpio_invert[3]);
1133
qemu_set_irq(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_SWB],
1134
spitz_gpio_invert[4]);
1137
/* Write the bootloader parameters memory area. */
1139
#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a)
1141
struct __attribute__ ((__packed__)) sl_param_info {
1142
uint32_t comadj_keyword;
1145
uint32_t uuid_keyword;
1148
uint32_t touch_keyword;
1154
uint32_t adadj_keyword;
1157
uint32_t phad_keyword;
1159
} spitz_bootparam = {
1160
.comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'),
1162
.uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'),
1164
.touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'),
1166
.adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'),
1168
.phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'),
1172
static void sl_bootparam_write(uint32_t ptr)
1174
memcpy(phys_ram_base + ptr, &spitz_bootparam,
1175
sizeof(struct sl_param_info));
1178
#define SL_PXA_PARAM_BASE 0xa0000a00
1181
enum spitz_model_e { spitz, akita, borzoi, terrier };
1183
static void spitz_common_init(int ram_size, int vga_ram_size,
1184
DisplayState *ds, const char *kernel_filename,
1185
const char *kernel_cmdline, const char *initrd_filename,
1186
const char *cpu_model, enum spitz_model_e model, int arm_id)
1188
uint32_t spitz_ram = 0x04000000;
1189
uint32_t spitz_rom = 0x00800000;
1190
struct pxa2xx_state_s *cpu;
1191
struct scoop_info_s *scp;
1194
cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
1196
/* Setup CPU & memory */
1197
if (ram_size < spitz_ram + spitz_rom + PXA2XX_INTERNAL_SIZE) {
1198
fprintf(stderr, "This platform requires %i bytes of memory\n",
1199
spitz_ram + spitz_rom + PXA2XX_INTERNAL_SIZE);
1202
cpu = pxa270_init(spitz_ram, ds, cpu_model);
1204
sl_flash_register(cpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
1206
cpu_register_physical_memory(0, spitz_rom,
1207
qemu_ram_alloc(spitz_rom) | IO_MEM_ROM);
1209
/* Setup peripherals */
1210
spitz_keyboard_register(cpu);
1212
spitz_ssp_attach(cpu);
1214
scp = spitz_scoop_init(cpu, (model == akita) ? 1 : 2);
1216
spitz_scoop_gpio_setup(cpu, scp, (model == akita) ? 1 : 2);
1218
spitz_gpio_setup(cpu, (model == akita) ? 1 : 2);
1220
spitz_i2c_setup(cpu);
1223
spitz_akita_i2c_setup(cpu);
1225
if (model == terrier)
1226
/* A 6.0 GB microdrive is permanently sitting in CF slot 1. */
1227
spitz_microdrive_attach(cpu);
1228
else if (model != akita)
1229
/* A 4.0 GB microdrive is permanently sitting in CF slot 1. */
1230
spitz_microdrive_attach(cpu);
1232
/* Setup initial (reset) machine state */
1233
cpu->env->regs[15] = PXA2XX_SDRAM_BASE;
1235
arm_load_kernel(cpu->env, spitz_ram, kernel_filename, kernel_cmdline,
1236
initrd_filename, arm_id, PXA2XX_SDRAM_BASE);
1237
sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_SDRAM_BASE);
1240
static void spitz_init(int ram_size, int vga_ram_size,
1241
const char *boot_device, DisplayState *ds,
1242
const char *kernel_filename, const char *kernel_cmdline,
1243
const char *initrd_filename, const char *cpu_model)
1245
spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
1246
kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9);
1249
static void borzoi_init(int ram_size, int vga_ram_size,
1250
const char *boot_device, DisplayState *ds,
1251
const char *kernel_filename, const char *kernel_cmdline,
1252
const char *initrd_filename, const char *cpu_model)
1254
spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
1255
kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f);
1258
static void akita_init(int ram_size, int vga_ram_size,
1259
const char *boot_device, DisplayState *ds,
1260
const char *kernel_filename, const char *kernel_cmdline,
1261
const char *initrd_filename, const char *cpu_model)
1263
spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
1264
kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8);
1267
static void terrier_init(int ram_size, int vga_ram_size,
1268
const char *boot_device, DisplayState *ds,
1269
const char *kernel_filename, const char *kernel_cmdline,
1270
const char *initrd_filename, const char *cpu_model)
1272
spitz_common_init(ram_size, vga_ram_size, ds, kernel_filename,
1273
kernel_cmdline, initrd_filename, cpu_model, terrier, 0x33f);
1276
QEMUMachine akitapda_machine = {
1278
"Akita PDA (PXA270)",
1282
QEMUMachine spitzpda_machine = {
1284
"Spitz PDA (PXA270)",
1288
QEMUMachine borzoipda_machine = {
1290
"Borzoi PDA (PXA270)",
1294
QEMUMachine terrierpda_machine = {
1296
"Terrier PDA (PXA270)",