add st STDS75 emulation
[qemu/qemu-loongson.git] / hw / st_stds75.c
blob094fa49ccd16f2a7994194fa17dd6a6ff83a3c41
1 /*
2 * QEMU st STDS75 Digital temperature sensor and thermal watchdog emulation
4 * Copyright (c) 2009 yajin <yajin@vm-kernel.org>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
28 #include "hw.h"
29 #include "qemu-timer.h"
30 #include "i2c.h"
31 #include "sysemu.h"
32 #include "console.h"
35 struct stds75_s
37 i2c_slave i2c;
38 qemu_irq irq;
40 int firstbyte;
41 uint8_t reg;
42 uint8_t index;
44 uint16_t temp;
45 uint8_t conf;
46 uint16_t thys;
47 uint16_t tos;
50 static void stds75_event(i2c_slave * i2c, enum i2c_event event)
52 struct stds75_s *s = (struct stds75_s *) i2c;
53 printf("stds75_event %d \n", event);
54 if (event == I2C_START_SEND)
55 s->firstbyte = 1;
58 static int stds75_rx(i2c_slave * i2c)
60 struct stds75_s *s = (struct stds75_s *) i2c;
61 printf("stds75_rx s->reg %d \n", s->reg);
62 uint8_t ret = 0;
64 switch (s->reg)
66 case 0x0:
67 ret = (s->temp >> ((1 - s->index) * 8)) & 0xff;
68 break;
69 case 0x1:
70 ret = s->conf;
71 break;
72 case 0x2:
73 /*first byte is the MSB */
74 ret = (s->thys >> ((1 - s->index) * 8)) & 0xff;
75 break;
76 case 0x03:
77 ret = (s->tos >> ((1 - s->index) * 8)) & 0xff;
78 break;
79 default:
80 fprintf(stderr, "%s: read from index %d of stds75 \n",
81 __FUNCTION__, s->reg);
82 break;
84 s->index++;
85 return ret;
88 static int stds75_tx(i2c_slave * i2c, uint8_t data)
90 struct stds75_s *s = (struct stds75_s *) i2c;
91 printf("stds75_tx %d \n", data);
92 if (s->firstbyte)
94 s->reg = data;
95 s->firstbyte = 0;
96 s->index = 0;
98 else
100 switch (s->reg)
102 case 0x0:
103 fprintf(stderr, "%s: write to index 0 of stds75 \n", __FUNCTION__);
104 break;
105 case 0x1:
106 s->conf = data;
107 break;
108 case 0x2:
109 /*first byte is the MSB */
110 s->thys &= (0xff) << (s->index * 8);
111 s->thys |= data << ((1 - s->index) * 8);
112 s->index++;
113 break;
114 case 0x03:
115 s->tos &= (0xff) << (s->index * 8);
116 s->tos |= data << ((1 - s->index) * 8);
117 s->index++;
118 break;
119 default:
120 fprintf(stderr, "%s: write to index %d of stds75 \n",
121 __FUNCTION__, s->reg);
122 break;
128 return 0;
132 static void stds75_reset(struct stds75_s *s)
134 s->thys = 0x4800;
135 s->tos = 0x5000;
138 i2c_slave *stds75_init(i2c_bus * bus, qemu_irq irq, int i2c_address)
140 struct stds75_s *s = (struct stds75_s *)
141 i2c_slave_init(bus, i2c_address, sizeof(struct stds75_s));
143 s->i2c.event = stds75_event;
144 s->i2c.recv = stds75_rx;
145 s->i2c.send = stds75_tx;
147 s->irq = irq;
149 stds75_reset(s);
151 //register_savevm("menelaus", -1, 0, menelaus_save, menelaus_load, s);
153 return &s->i2c;