Statistics
| Branch: | Revision:

root / hw / palm.c @ 4f4cc0ef

History | View | Annotate | Download (9.1 kB)

1 c3d2689d balrog
/*
2 c3d2689d balrog
 * PalmOne's (TM) PDAs.
3 c3d2689d balrog
 *
4 c3d2689d balrog
 * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
5 c3d2689d balrog
 *
6 c3d2689d balrog
 * This program is free software; you can redistribute it and/or
7 c3d2689d balrog
 * modify it under the terms of the GNU General Public License as
8 827df9f3 balrog
 * published by the Free Software Foundation; either version 2 or
9 827df9f3 balrog
 * (at your option) version 3 of the License.
10 c3d2689d balrog
 *
11 c3d2689d balrog
 * This program is distributed in the hope that it will be useful,
12 c3d2689d balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 c3d2689d balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 c3d2689d balrog
 * GNU General Public License for more details.
15 c3d2689d balrog
 *
16 fad6cb1a aurel32
 * You should have received a copy of the GNU General Public License along
17 8167ee88 Blue Swirl
 * with this program; if not, see <http://www.gnu.org/licenses/>.
18 c3d2689d balrog
 */
19 87ecb68b pbrook
#include "hw.h"
20 87ecb68b pbrook
#include "audio/audio.h"
21 87ecb68b pbrook
#include "sysemu.h"
22 87ecb68b pbrook
#include "console.h"
23 87ecb68b pbrook
#include "omap.h"
24 87ecb68b pbrook
#include "boards.h"
25 87ecb68b pbrook
#include "arm-misc.h"
26 827df9f3 balrog
#include "devices.h"
27 c3d2689d balrog
28 c3d2689d balrog
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
29 c3d2689d balrog
{
30 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
31 c3d2689d balrog
    return *val >> ((offset & 3) << 3);
32 c3d2689d balrog
}
33 c3d2689d balrog
34 827df9f3 balrog
static uint32_t static_readh(void *opaque, target_phys_addr_t offset)
35 827df9f3 balrog
{
36 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
37 c3d2689d balrog
    return *val >> ((offset & 1) << 3);
38 c3d2689d balrog
}
39 c3d2689d balrog
40 827df9f3 balrog
static uint32_t static_readw(void *opaque, target_phys_addr_t offset)
41 827df9f3 balrog
{
42 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
43 c3d2689d balrog
    return *val >> ((offset & 0) << 3);
44 c3d2689d balrog
}
45 c3d2689d balrog
46 c3d2689d balrog
static void static_write(void *opaque, target_phys_addr_t offset,
47 d951f6ff balrog
                uint32_t value)
48 d951f6ff balrog
{
49 c3d2689d balrog
#ifdef SPY
50 c3d2689d balrog
    printf("%s: value %08lx written at " PA_FMT "\n",
51 c3d2689d balrog
                    __FUNCTION__, value, offset);
52 c3d2689d balrog
#endif
53 c3d2689d balrog
}
54 c3d2689d balrog
55 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const static_readfn[] = {
56 c3d2689d balrog
    static_readb,
57 c3d2689d balrog
    static_readh,
58 c3d2689d balrog
    static_readw,
59 c3d2689d balrog
};
60 c3d2689d balrog
61 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const static_writefn[] = {
62 c3d2689d balrog
    static_write,
63 c3d2689d balrog
    static_write,
64 c3d2689d balrog
    static_write,
65 c3d2689d balrog
};
66 c3d2689d balrog
67 c3d2689d balrog
/* Palm Tunsgten|E support */
68 8e129e07 balrog
69 8e129e07 balrog
/* Shared GPIOs */
70 8e129e07 balrog
#define PALMTE_USBDETECT_GPIO        0
71 8e129e07 balrog
#define PALMTE_USB_OR_DC_GPIO        1
72 8e129e07 balrog
#define PALMTE_TSC_GPIO                4
73 8e129e07 balrog
#define PALMTE_PINTDAV_GPIO        6
74 8e129e07 balrog
#define PALMTE_MMC_WP_GPIO        8
75 8e129e07 balrog
#define PALMTE_MMC_POWER_GPIO        9
76 8e129e07 balrog
#define PALMTE_HDQ_GPIO                11
77 8e129e07 balrog
#define PALMTE_HEADPHONES_GPIO        14
78 8e129e07 balrog
#define PALMTE_SPEAKER_GPIO        15
79 8e129e07 balrog
/* MPU private GPIOs */
80 8e129e07 balrog
#define PALMTE_DC_GPIO                2
81 8e129e07 balrog
#define PALMTE_MMC_SWITCH_GPIO        4
82 8e129e07 balrog
#define PALMTE_MMC1_GPIO        6
83 8e129e07 balrog
#define PALMTE_MMC2_GPIO        7
84 8e129e07 balrog
#define PALMTE_MMC3_GPIO        11
85 8e129e07 balrog
86 bc24a225 Paul Brook
static MouseTransformInfo palmte_pointercal = {
87 c38b6e25 balrog
    .x = 320,
88 c38b6e25 balrog
    .y = 320,
89 c38b6e25 balrog
    .a = { -5909, 8, 22465308, 104, 7644, -1219972, 65536 },
90 c38b6e25 balrog
};
91 c38b6e25 balrog
92 c3d2689d balrog
static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
93 c3d2689d balrog
{
94 bc24a225 Paul Brook
    uWireSlave *tsc;
95 d8f699cb balrog
96 22d83b14 Paul Brook
    tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO]);
97 d8f699cb balrog
98 d8f699cb balrog
    omap_uwire_attach(cpu->microwire, tsc, 0);
99 d8f699cb balrog
    omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
100 c38b6e25 balrog
101 c38b6e25 balrog
    tsc210x_set_transform(tsc, &palmte_pointercal);
102 c3d2689d balrog
}
103 c3d2689d balrog
104 38a34e1d balrog
static struct {
105 38a34e1d balrog
    int row;
106 38a34e1d balrog
    int column;
107 38a34e1d balrog
} palmte_keymap[0x80] = {
108 38a34e1d balrog
    [0 ... 0x7f] = { -1, -1 },
109 38a34e1d balrog
    [0x3b] = { 0, 0 },        /* F1        -> Calendar */
110 38a34e1d balrog
    [0x3c] = { 1, 0 },        /* F2        -> Contacts */
111 38a34e1d balrog
    [0x3d] = { 2, 0 },        /* F3        -> Tasks List */
112 38a34e1d balrog
    [0x3e] = { 3, 0 },        /* F4        -> Note Pad */
113 38a34e1d balrog
    [0x01] = { 4, 0 },        /* Esc        -> Power */
114 38a34e1d balrog
    [0x4b] = { 0, 1 },        /*            Left */
115 38a34e1d balrog
    [0x50] = { 1, 1 },        /*            Down */
116 38a34e1d balrog
    [0x48] = { 2, 1 },        /*           Up */
117 38a34e1d balrog
    [0x4d] = { 3, 1 },        /*           Right */
118 38a34e1d balrog
    [0x4c] = { 4, 1 },        /*            Centre */
119 38a34e1d balrog
    [0x39] = { 4, 1 },        /* Spc        -> Centre */
120 38a34e1d balrog
};
121 38a34e1d balrog
122 38a34e1d balrog
static void palmte_button_event(void *opaque, int keycode)
123 38a34e1d balrog
{
124 38a34e1d balrog
    struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
125 38a34e1d balrog
126 38a34e1d balrog
    if (palmte_keymap[keycode & 0x7f].row != -1)
127 38a34e1d balrog
        omap_mpuio_key(cpu->mpuio,
128 38a34e1d balrog
                        palmte_keymap[keycode & 0x7f].row,
129 38a34e1d balrog
                        palmte_keymap[keycode & 0x7f].column,
130 38a34e1d balrog
                        !(keycode & 0x80));
131 38a34e1d balrog
}
132 38a34e1d balrog
133 7fc42b4b balrog
static void palmte_onoff_gpios(void *opaque, int line, int level)
134 7fc42b4b balrog
{
135 7fc42b4b balrog
    switch (line) {
136 7fc42b4b balrog
    case 0:
137 7fc42b4b balrog
        printf("%s: current to MMC/SD card %sabled.\n",
138 7fc42b4b balrog
                        __FUNCTION__, level ? "dis" : "en");
139 7fc42b4b balrog
        break;
140 7fc42b4b balrog
    case 1:
141 7fc42b4b balrog
        printf("%s: internal speaker amplifier %s.\n",
142 7fc42b4b balrog
                        __FUNCTION__, level ? "down" : "on");
143 7fc42b4b balrog
        break;
144 7fc42b4b balrog
145 7fc42b4b balrog
    /* These LCD & Audio output signals have not been identified yet.  */
146 7fc42b4b balrog
    case 2:
147 7fc42b4b balrog
    case 3:
148 7fc42b4b balrog
    case 4:
149 7fc42b4b balrog
        printf("%s: LCD GPIO%i %s.\n",
150 7fc42b4b balrog
                        __FUNCTION__, line - 1, level ? "high" : "low");
151 7fc42b4b balrog
        break;
152 7fc42b4b balrog
    case 5:
153 7fc42b4b balrog
    case 6:
154 7fc42b4b balrog
        printf("%s: Audio GPIO%i %s.\n",
155 7fc42b4b balrog
                        __FUNCTION__, line - 4, level ? "high" : "low");
156 7fc42b4b balrog
        break;
157 7fc42b4b balrog
    }
158 7fc42b4b balrog
}
159 7fc42b4b balrog
160 7fc42b4b balrog
static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
161 7fc42b4b balrog
{
162 7fc42b4b balrog
    qemu_irq *misc_gpio;
163 7fc42b4b balrog
164 7fc42b4b balrog
    omap_mmc_handlers(cpu->mmc,
165 7fc42b4b balrog
                    omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
166 7fc42b4b balrog
                    qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
167 7fc42b4b balrog
                            [PALMTE_MMC_SWITCH_GPIO]));
168 7fc42b4b balrog
169 7fc42b4b balrog
    misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
170 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO,        misc_gpio[0]);
171 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO,        misc_gpio[1]);
172 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 11,                        misc_gpio[2]);
173 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 12,                        misc_gpio[3]);
174 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 13,                        misc_gpio[4]);
175 7fc42b4b balrog
    omap_mpuio_out_set(cpu->mpuio, 1,                        misc_gpio[5]);
176 7fc42b4b balrog
    omap_mpuio_out_set(cpu->mpuio, 3,                        misc_gpio[6]);
177 7fc42b4b balrog
178 7fc42b4b balrog
    /* Reset some inputs to initial state.  */
179 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]);
180 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]);
181 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]);
182 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]);
183 7fc42b4b balrog
    qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
184 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
185 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
186 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]);
187 7fc42b4b balrog
}
188 7fc42b4b balrog
189 f93eb9ff balrog
static struct arm_boot_info palmte_binfo = {
190 f93eb9ff balrog
    .loader_start = OMAP_EMIFF_BASE,
191 f93eb9ff balrog
    .ram_size = 0x02000000,
192 f93eb9ff balrog
    .board_id = 0x331,
193 f93eb9ff balrog
};
194 f93eb9ff balrog
195 fbe1b595 Paul Brook
static void palmte_init(ram_addr_t ram_size,
196 3023f332 aliguori
                const char *boot_device,
197 c3d2689d balrog
                const char *kernel_filename, const char *kernel_cmdline,
198 c3d2689d balrog
                const char *initrd_filename, const char *cpu_model)
199 c3d2689d balrog
{
200 c3d2689d balrog
    struct omap_mpu_state_s *cpu;
201 c3d2689d balrog
    int flash_size = 0x00800000;
202 f93eb9ff balrog
    int sdram_size = palmte_binfo.ram_size;
203 c3d2689d balrog
    int io;
204 c3d2689d balrog
    static uint32_t cs0val = 0xffffffff;
205 c3d2689d balrog
    static uint32_t cs1val = 0x0000e1a0;
206 c3d2689d balrog
    static uint32_t cs2val = 0x0000e1a0;
207 c3d2689d balrog
    static uint32_t cs3val = 0xe1a0e1a0;
208 c3d2689d balrog
    ram_addr_t phys_flash;
209 c3d2689d balrog
    int rom_size, rom_loaded = 0;
210 3023f332 aliguori
    DisplayState *ds = get_displaystate();
211 c3d2689d balrog
212 3023f332 aliguori
    cpu = omap310_mpu_init(sdram_size, cpu_model);
213 c3d2689d balrog
214 c3d2689d balrog
    /* External Flash (EMIFS) */
215 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
216 c3d2689d balrog
                    (phys_flash = qemu_ram_alloc(flash_size)) | IO_MEM_ROM);
217 c3d2689d balrog
218 1eed09cb Avi Kivity
    io = cpu_register_io_memory(static_readfn, static_writefn, &cs0val);
219 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS0_BASE + flash_size,
220 c3d2689d balrog
                    OMAP_CS0_SIZE - flash_size, io);
221 1eed09cb Avi Kivity
    io = cpu_register_io_memory(static_readfn, static_writefn, &cs1val);
222 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io);
223 1eed09cb Avi Kivity
    io = cpu_register_io_memory(static_readfn, static_writefn, &cs2val);
224 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io);
225 1eed09cb Avi Kivity
    io = cpu_register_io_memory(static_readfn, static_writefn, &cs3val);
226 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io);
227 c3d2689d balrog
228 c3d2689d balrog
    palmte_microwire_setup(cpu);
229 c3d2689d balrog
230 38a34e1d balrog
    qemu_add_kbd_event_handler(palmte_button_event, cpu);
231 38a34e1d balrog
232 7fc42b4b balrog
    palmte_gpio_setup(cpu);
233 8e129e07 balrog
234 c3d2689d balrog
    /* Setup initial (reset) machine state */
235 c3d2689d balrog
    if (nb_option_roms) {
236 c3d2689d balrog
        rom_size = get_image_size(option_rom[0]);
237 dcac9679 pbrook
        if (rom_size > flash_size) {
238 c3d2689d balrog
            fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
239 c3d2689d balrog
                            __FUNCTION__, rom_size, flash_size);
240 dcac9679 pbrook
            rom_size = 0;
241 dcac9679 pbrook
        }
242 dcac9679 pbrook
        if (rom_size > 0) {
243 dcac9679 pbrook
            rom_size = load_image_targphys(option_rom[0], OMAP_CS0_BASE,
244 dcac9679 pbrook
                                           flash_size);
245 c3d2689d balrog
            rom_loaded = 1;
246 c3d2689d balrog
            cpu->env->regs[15] = 0x00000000;
247 dcac9679 pbrook
        }
248 dcac9679 pbrook
        if (rom_size < 0) {
249 c3d2689d balrog
            fprintf(stderr, "%s: error loading '%s'\n",
250 c3d2689d balrog
                            __FUNCTION__, option_rom[0]);
251 dcac9679 pbrook
        }
252 c3d2689d balrog
    }
253 c3d2689d balrog
254 c3d2689d balrog
    if (!rom_loaded && !kernel_filename) {
255 c3d2689d balrog
        fprintf(stderr, "Kernel or ROM image must be specified\n");
256 c3d2689d balrog
        exit(1);
257 c3d2689d balrog
    }
258 c3d2689d balrog
259 c3d2689d balrog
    /* Load the kernel.  */
260 c3d2689d balrog
    if (kernel_filename) {
261 c3d2689d balrog
        /* Start at bootloader.  */
262 f93eb9ff balrog
        cpu->env->regs[15] = palmte_binfo.loader_start;
263 c3d2689d balrog
264 f93eb9ff balrog
        palmte_binfo.kernel_filename = kernel_filename;
265 f93eb9ff balrog
        palmte_binfo.kernel_cmdline = kernel_cmdline;
266 f93eb9ff balrog
        palmte_binfo.initrd_filename = initrd_filename;
267 f93eb9ff balrog
        arm_load_kernel(cpu->env, &palmte_binfo);
268 c3d2689d balrog
    }
269 c3d2689d balrog
270 c60e08d9 pbrook
    /* FIXME: We shouldn't really be doing this here.  The LCD controller
271 c60e08d9 pbrook
       will set the size once configured, so this just sets an initial
272 c60e08d9 pbrook
       size until the guest activates the display.  */
273 7b5d76da aliguori
    ds->surface = qemu_resize_displaysurface(ds, 320, 320);
274 7d957bd8 aliguori
    dpy_resize(ds);
275 c3d2689d balrog
}
276 c3d2689d balrog
277 f80f9ec9 Anthony Liguori
static QEMUMachine palmte_machine = {
278 4b32e168 aliguori
    .name = "cheetah",
279 4b32e168 aliguori
    .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
280 4b32e168 aliguori
    .init = palmte_init,
281 c3d2689d balrog
};
282 f80f9ec9 Anthony Liguori
283 f80f9ec9 Anthony Liguori
static void palmte_machine_init(void)
284 f80f9ec9 Anthony Liguori
{
285 f80f9ec9 Anthony Liguori
    qemu_register_machine(&palmte_machine);
286 f80f9ec9 Anthony Liguori
}
287 f80f9ec9 Anthony Liguori
288 f80f9ec9 Anthony Liguori
machine_init(palmte_machine_init);