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+=irq.o
|
||||||
OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.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-disk.o cdrom.o
|
||||||
OBJS+=scsi-generic.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
|
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+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
|
||||||
OBJS+= omap2.o omap_dss.o
|
OBJS+= omap2.o omap_dss.o
|
||||||
OBJS+= palm.o tsc210x.o
|
OBJS+= palm.o tsc210x.o
|
||||||
|
OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o
|
||||||
OBJS+= mst_fpga.o mainstone.o
|
OBJS+= mst_fpga.o mainstone.o
|
||||||
CPPFLAGS += -DHAS_AUDIO
|
CPPFLAGS += -DHAS_AUDIO
|
||||||
endif
|
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 */
|
/* palm.c */
|
||||||
extern QEMUMachine palmte_machine;
|
extern QEMUMachine palmte_machine;
|
||||||
|
|
||||||
|
/* nseries.c */
|
||||||
|
extern QEMUMachine n800_machine;
|
||||||
|
|
||||||
/* gumstix.c */
|
/* gumstix.c */
|
||||||
extern QEMUMachine connex_machine;
|
extern QEMUMachine connex_machine;
|
||||||
extern QEMUMachine verdex_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 */
|
/* stellaris_input.c */
|
||||||
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
|
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
|
#endif
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ uint8_t nand_getio(struct nand_flash_s *s);
|
|||||||
#define NAND_MFR_HYNIX 0xad
|
#define NAND_MFR_HYNIX 0xad
|
||||||
#define NAND_MFR_MICRON 0x2c
|
#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 */
|
/* ecc.c */
|
||||||
struct ecc_state_s {
|
struct ecc_state_s {
|
||||||
uint8_t cp; /* Column parity */
|
uint8_t cp; /* Column parity */
|
||||||
|
|||||||
@@ -71,4 +71,14 @@ uint32_t wm8750_adc_dat(void *opaque);
|
|||||||
/* ssd0303.c */
|
/* ssd0303.c */
|
||||||
void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address);
|
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
|
#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 *)
|
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||||
qemu_mallocz(sizeof(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 *cpu_irq;
|
||||||
qemu_irq dma_irqs[4];
|
qemu_irq dma_irqs[4];
|
||||||
omap_clk gpio_clks[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 */
|
/* Memory-mapped stuff */
|
||||||
cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
|
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,
|
cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
|
||||||
(sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
|
(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(&borzoipda_machine);
|
||||||
qemu_register_machine(&terrierpda_machine);
|
qemu_register_machine(&terrierpda_machine);
|
||||||
qemu_register_machine(&palmte_machine);
|
qemu_register_machine(&palmte_machine);
|
||||||
|
qemu_register_machine(&n800_machine);
|
||||||
qemu_register_machine(&lm3s811evb_machine);
|
qemu_register_machine(&lm3s811evb_machine);
|
||||||
qemu_register_machine(&lm3s6965evb_machine);
|
qemu_register_machine(&lm3s6965evb_machine);
|
||||||
qemu_register_machine(&connex_machine);
|
qemu_register_machine(&connex_machine);
|
||||||
|
|||||||
Reference in New Issue
Block a user