mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Nokia N800 machine support (ARM).
Also add various peripherals: two miscellaneous Nokia CBUS chips, EPSON S1D13745 LCD/TV remote-framebuffer controller, TWL92230 - standard OMAP2 power management companion chip on i2c. Generic OneNAND flash memory, TMP105 temperature sensor on i2c. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4215 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -51,7 +51,8 @@ OBJS+=block.o
|
||||
|
||||
OBJS+=irq.o
|
||||
OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
|
||||
OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o
|
||||
OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
|
||||
OBJS+=tmp105.o
|
||||
OBJS+=scsi-disk.o cdrom.o
|
||||
OBJS+=scsi-generic.o
|
||||
OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o usb-serial.o
|
||||
|
||||
@@ -612,6 +612,7 @@ OBJS+= spitz.o ide.o serial.o nand.o ecc.o
|
||||
OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
|
||||
OBJS+= omap2.o omap_dss.o
|
||||
OBJS+= palm.o tsc210x.o
|
||||
OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o
|
||||
OBJS+= mst_fpga.o mainstone.o
|
||||
CPPFLAGS += -DHAS_AUDIO
|
||||
endif
|
||||
|
||||
+1001
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* QEMU Epson S1D13744/S1D13745 templates
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Written by Andrzej Zaborowski <andrew@openedhand.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define SKIP_PIXEL(to) to += deststep
|
||||
#if DEPTH == 8
|
||||
# define PIXEL_TYPE uint8_t
|
||||
# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
|
||||
# define COPY_PIXEL1(to, from) *to ++ = from
|
||||
#elif DEPTH == 15 || DEPTH == 16
|
||||
# define PIXEL_TYPE uint16_t
|
||||
# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
|
||||
# define COPY_PIXEL1(to, from) *to ++ = from
|
||||
#elif DEPTH == 24
|
||||
# define PIXEL_TYPE uint8_t
|
||||
# define COPY_PIXEL(to, from) \
|
||||
to[0] = from; to[1] = (from) >> 8; to[2] = (from) >> 16; SKIP_PIXEL(to)
|
||||
# define COPY_PIXEL1(to, from) \
|
||||
*to ++ = from; *to ++ = (from) >> 8; *to ++ = (from) >> 16
|
||||
#elif DEPTH == 32
|
||||
# define PIXEL_TYPE uint32_t
|
||||
# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
|
||||
# define COPY_PIXEL1(to, from) *to ++ = from
|
||||
#else
|
||||
# error unknown bit depth
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SWAP_WORDS 1
|
||||
#endif
|
||||
|
||||
static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
|
||||
const uint16_t *src, unsigned int width)
|
||||
{
|
||||
#if !defined(SWAP_WORDS) && DEPTH == 16
|
||||
memcpy(dest, src, width << 1);
|
||||
#else
|
||||
uint16_t data;
|
||||
unsigned int r, g, b;
|
||||
const uint16_t *end = (void *) src + width;
|
||||
while (src < end) {
|
||||
data = lduw_raw(src ++);
|
||||
b = (data & 0x1f) << 3;
|
||||
data >>= 5;
|
||||
g = (data & 0x3f) << 2;
|
||||
data >>= 6;
|
||||
r = (data & 0x1f) << 3;
|
||||
data >>= 5;
|
||||
COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
|
||||
const uint8_t *src, unsigned int width)
|
||||
{
|
||||
/* TODO: check if SDL 24-bit planes are not in the same format and
|
||||
* if so, use memcpy */
|
||||
unsigned int r[2], g[2], b[2];
|
||||
const uint8_t *end = src + width;
|
||||
while (src < end) {
|
||||
g[0] = *src ++;
|
||||
r[0] = *src ++;
|
||||
r[1] = *src ++;
|
||||
b[0] = *src ++;
|
||||
COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0]));
|
||||
b[1] = *src ++;
|
||||
g[1] = *src ++;
|
||||
COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1]));
|
||||
}
|
||||
}
|
||||
|
||||
static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
|
||||
const uint8_t *src, unsigned int width)
|
||||
{
|
||||
unsigned int r, g, b;
|
||||
const uint8_t *end = src + width;
|
||||
while (src < end) {
|
||||
r = *src ++;
|
||||
src ++;
|
||||
b = *src ++;
|
||||
g = *src ++;
|
||||
COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
/* No rotation */
|
||||
static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
|
||||
NULL,
|
||||
/* RGB 5:6:5*/
|
||||
(blizzard_fn_t) glue(blizzard_draw_line16_, DEPTH),
|
||||
/* RGB 6:6:6 mode 1 */
|
||||
(blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
|
||||
/* RGB 8:8:8 mode 1 */
|
||||
(blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
|
||||
NULL, NULL,
|
||||
/* RGB 6:6:6 mode 2 */
|
||||
(blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
|
||||
/* RGB 8:8:8 mode 2 */
|
||||
(blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
|
||||
/* YUV 4:2:2 */
|
||||
NULL,
|
||||
/* YUV 4:2:0 */
|
||||
NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
/* 90deg, 180deg and 270deg rotation */
|
||||
static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = {
|
||||
/* TODO */
|
||||
[0 ... 0xf] = NULL,
|
||||
};
|
||||
|
||||
#undef DEPTH
|
||||
#undef SKIP_PIXEL
|
||||
#undef COPY_PIXEL
|
||||
#undef COPY_PIXEL1
|
||||
#undef PIXEL_TYPE
|
||||
|
||||
#undef SWAP_WORDS
|
||||
@@ -81,6 +81,9 @@ extern QEMUMachine terrierpda_machine;
|
||||
/* palm.c */
|
||||
extern QEMUMachine palmte_machine;
|
||||
|
||||
/* nseries.c */
|
||||
extern QEMUMachine n800_machine;
|
||||
|
||||
/* gumstix.c */
|
||||
extern QEMUMachine connex_machine;
|
||||
extern QEMUMachine verdex_machine;
|
||||
|
||||
@@ -31,4 +31,25 @@ void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down);
|
||||
/* stellaris_input.c */
|
||||
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
|
||||
|
||||
/* blizzard.c */
|
||||
void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds);
|
||||
void s1d13745_write(void *opaque, int dc, uint16_t value);
|
||||
void s1d13745_write_block(void *opaque, int dc,
|
||||
void *buf, size_t len, int pitch);
|
||||
uint16_t s1d13745_read(void *opaque, int dc);
|
||||
|
||||
/* cbus.c */
|
||||
struct cbus_s {
|
||||
qemu_irq clk;
|
||||
qemu_irq dat;
|
||||
qemu_irq sel;
|
||||
};
|
||||
struct cbus_s *cbus_init(qemu_irq dat_out);
|
||||
void cbus_attach(struct cbus_s *bus, void *slave_opaque);
|
||||
|
||||
void *retu_init(qemu_irq irq, int vilma);
|
||||
void *tahvo_init(qemu_irq irq, int betty);
|
||||
|
||||
void retu_key_event(void *retu, int state);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,11 @@ uint8_t nand_getio(struct nand_flash_s *s);
|
||||
#define NAND_MFR_HYNIX 0xad
|
||||
#define NAND_MFR_MICRON 0x2c
|
||||
|
||||
/* onenand.c */
|
||||
void onenand_base_update(void *opaque, target_phys_addr_t new);
|
||||
void onenand_base_unmap(void *opaque);
|
||||
void *onenand_init(uint32_t id, int regshift, qemu_irq irq);
|
||||
|
||||
/* ecc.c */
|
||||
struct ecc_state_s {
|
||||
uint8_t cp; /* Column parity */
|
||||
|
||||
@@ -71,4 +71,14 @@ uint32_t wm8750_adc_dat(void *opaque);
|
||||
/* ssd0303.c */
|
||||
void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address);
|
||||
|
||||
/* twl92230.c */
|
||||
i2c_slave *twl92230_init(i2c_bus *bus, qemu_irq irq);
|
||||
qemu_irq *twl92230_gpio_in_get(i2c_slave *i2c);
|
||||
void twl92230_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler);
|
||||
|
||||
/* tmp105.c */
|
||||
struct i2c_slave *tmp105_init(i2c_bus *bus, qemu_irq alarm);
|
||||
void tmp105_reset(i2c_slave *i2c);
|
||||
void tmp105_set(i2c_slave *i2c, int temp);
|
||||
|
||||
#endif
|
||||
|
||||
+918
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -3496,7 +3496,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
|
||||
{
|
||||
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||
qemu_mallocz(sizeof(struct omap_mpu_state_s));
|
||||
ram_addr_t sram_base, q3_base;
|
||||
ram_addr_t sram_base, q2_base;
|
||||
qemu_irq *cpu_irq;
|
||||
qemu_irq dma_irqs[4];
|
||||
omap_clk gpio_clks[4];
|
||||
@@ -3520,7 +3520,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
|
||||
|
||||
/* Memory-mapped stuff */
|
||||
cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
|
||||
(q3_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
|
||||
(q2_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
|
||||
cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
|
||||
(sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
|
||||
|
||||
|
||||
+642
File diff suppressed because it is too large
Load Diff
+249
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Texas Instruments TMP105 temperature sensor.
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Written by Andrzej Zaborowski <andrew@openedhand.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "i2c.h"
|
||||
|
||||
struct tmp105_s {
|
||||
i2c_slave i2c;
|
||||
int len;
|
||||
uint8_t buf[2];
|
||||
qemu_irq pin;
|
||||
|
||||
uint8_t pointer;
|
||||
uint8_t config;
|
||||
int16_t temperature;
|
||||
int16_t limit[2];
|
||||
int faults;
|
||||
int alarm;
|
||||
};
|
||||
|
||||
static void tmp105_interrupt_update(struct tmp105_s *s)
|
||||
{
|
||||
qemu_set_irq(s->pin, s->alarm ^ ((~s->config >> 2) & 1)); /* POL */
|
||||
}
|
||||
|
||||
static void tmp105_alarm_update(struct tmp105_s *s)
|
||||
{
|
||||
if ((s->config >> 0) & 1) { /* SD */
|
||||
if ((s->config >> 7) & 1) /* OS */
|
||||
s->config &= ~(1 << 7); /* OS */
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if ((s->config >> 1) & 1) { /* TM */
|
||||
if (s->temperature >= s->limit[1])
|
||||
s->alarm = 1;
|
||||
else if (s->temperature < s->limit[0])
|
||||
s->alarm = 1;
|
||||
} else {
|
||||
if (s->temperature >= s->limit[1])
|
||||
s->alarm = 1;
|
||||
else if (s->temperature < s->limit[0])
|
||||
s->alarm = 0;
|
||||
}
|
||||
|
||||
tmp105_interrupt_update(s);
|
||||
}
|
||||
|
||||
/* Units are 0.001 centigrades relative to 0 C. */
|
||||
void tmp105_set(i2c_slave *i2c, int temp)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) i2c;
|
||||
|
||||
if (temp >= 128000 || temp < -128000) {
|
||||
fprintf(stderr, "%s: values is out of range (%i.%03i C)\n",
|
||||
__FUNCTION__, temp / 1000, temp % 1000);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
s->temperature = ((int16_t) (temp * 0x800 / 128000)) << 4;
|
||||
|
||||
tmp105_alarm_update(s);
|
||||
}
|
||||
|
||||
static const int tmp105_faultq[4] = { 1, 2, 4, 6 };
|
||||
|
||||
static void tmp105_read(struct tmp105_s *s)
|
||||
{
|
||||
s->len = 0;
|
||||
|
||||
if ((s->config >> 1) & 1) { /* TM */
|
||||
s->alarm = 0;
|
||||
tmp105_interrupt_update(s);
|
||||
}
|
||||
|
||||
switch (s->pointer & 3) {
|
||||
case 0: /* Temperature */
|
||||
s->buf[s->len ++] = (((uint16_t) s->temperature) >> 8);
|
||||
s->buf[s->len ++] = (((uint16_t) s->temperature) >> 0) &
|
||||
(0xf0 << ((~s->config >> 5) & 3)); /* R */
|
||||
break;
|
||||
|
||||
case 1: /* Configuration */
|
||||
s->buf[s->len ++] = s->config;
|
||||
break;
|
||||
|
||||
case 2: /* T_LOW */
|
||||
s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 8;
|
||||
s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 0;
|
||||
break;
|
||||
|
||||
case 3: /* T_HIGH */
|
||||
s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 8;
|
||||
s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tmp105_write(struct tmp105_s *s)
|
||||
{
|
||||
switch (s->pointer & 3) {
|
||||
case 0: /* Temperature */
|
||||
break;
|
||||
|
||||
case 1: /* Configuration */
|
||||
if (s->buf[0] & ~s->config & (1 << 0)) /* SD */
|
||||
printf("%s: TMP105 shutdown\n", __FUNCTION__);
|
||||
s->config = s->buf[0];
|
||||
s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */
|
||||
tmp105_alarm_update(s);
|
||||
break;
|
||||
|
||||
case 2: /* T_LOW */
|
||||
case 3: /* T_HIGH */
|
||||
if (s->len >= 3)
|
||||
s->limit[s->pointer & 1] = (int16_t)
|
||||
((((uint16_t) s->buf[0]) << 8) | s->buf[1]);
|
||||
tmp105_alarm_update(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int tmp105_rx(i2c_slave *i2c)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) i2c;
|
||||
|
||||
if (s->len < 2)
|
||||
return s->buf[s->len ++];
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static int tmp105_tx(i2c_slave *i2c, uint8_t data)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) i2c;
|
||||
|
||||
if (!s->len ++)
|
||||
s->pointer = data;
|
||||
else {
|
||||
if (s->len <= 2)
|
||||
s->buf[s->len - 1] = data;
|
||||
tmp105_write(s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tmp105_event(i2c_slave *i2c, enum i2c_event event)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) i2c;
|
||||
|
||||
if (event == I2C_START_RECV)
|
||||
tmp105_read(s);
|
||||
|
||||
s->len = 0;
|
||||
}
|
||||
|
||||
static void tmp105_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) opaque;
|
||||
|
||||
qemu_put_byte(f, s->len);
|
||||
qemu_put_8s(f, &s->buf[0]);
|
||||
qemu_put_8s(f, &s->buf[1]);
|
||||
|
||||
qemu_put_8s(f, &s->pointer);
|
||||
qemu_put_8s(f, &s->config);
|
||||
qemu_put_be16s(f, &s->temperature);
|
||||
qemu_put_be16s(f, &s->limit[0]);
|
||||
qemu_put_be16s(f, &s->limit[1]);
|
||||
qemu_put_byte(f, s->alarm);
|
||||
s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */
|
||||
|
||||
i2c_slave_save(f, &s->i2c);
|
||||
}
|
||||
|
||||
static int tmp105_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) opaque;
|
||||
|
||||
s->len = qemu_get_byte(f);
|
||||
qemu_get_8s(f, &s->buf[0]);
|
||||
qemu_get_8s(f, &s->buf[1]);
|
||||
|
||||
qemu_get_8s(f, &s->pointer);
|
||||
qemu_get_8s(f, &s->config);
|
||||
qemu_get_be16s(f, &s->temperature);
|
||||
qemu_get_be16s(f, &s->limit[0]);
|
||||
qemu_get_be16s(f, &s->limit[1]);
|
||||
s->alarm = qemu_get_byte(f);
|
||||
|
||||
tmp105_interrupt_update(s);
|
||||
|
||||
i2c_slave_load(f, &s->i2c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tmp105_reset(i2c_slave *i2c)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *) i2c;
|
||||
|
||||
s->temperature = 0;
|
||||
s->pointer = 0;
|
||||
s->config = 0;
|
||||
s->faults = tmp105_faultq[(s->config >> 3) & 3];
|
||||
s->alarm = 0;
|
||||
|
||||
tmp105_interrupt_update(s);
|
||||
}
|
||||
|
||||
static int tmp105_iid = 0;
|
||||
|
||||
struct i2c_slave *tmp105_init(i2c_bus *bus, qemu_irq alarm)
|
||||
{
|
||||
struct tmp105_s *s = (struct tmp105_s *)
|
||||
i2c_slave_init(bus, 0, sizeof(struct tmp105_s));
|
||||
|
||||
s->i2c.event = tmp105_event;
|
||||
s->i2c.recv = tmp105_rx;
|
||||
s->i2c.send = tmp105_tx;
|
||||
s->pin = alarm;
|
||||
|
||||
tmp105_reset(&s->i2c);
|
||||
|
||||
register_savevm("TMP105", tmp105_iid ++, 0,
|
||||
tmp105_save, tmp105_load, s);
|
||||
|
||||
return &s->i2c;
|
||||
}
|
||||
+923
File diff suppressed because it is too large
Load Diff
@@ -8051,6 +8051,7 @@ static void register_machines(void)
|
||||
qemu_register_machine(&borzoipda_machine);
|
||||
qemu_register_machine(&terrierpda_machine);
|
||||
qemu_register_machine(&palmte_machine);
|
||||
qemu_register_machine(&n800_machine);
|
||||
qemu_register_machine(&lm3s811evb_machine);
|
||||
qemu_register_machine(&lm3s6965evb_machine);
|
||||
qemu_register_machine(&connex_machine);
|
||||
|
||||
Reference in New Issue
Block a user