xref: /openbmc/qemu/hw/i2c/npcm7xx_smbus.c (revision cba42d61)
1 /*
2  * Nuvoton NPCM7xx SMBus Module.
3  *
4  * Copyright 2020 Google LLC
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  */
16 
17 #include "qemu/osdep.h"
18 
19 #include "hw/i2c/npcm7xx_smbus.h"
20 #include "migration/vmstate.h"
21 #include "qemu/bitops.h"
22 #include "qemu/guest-random.h"
23 #include "qemu/log.h"
24 #include "qemu/module.h"
25 #include "qemu/units.h"
26 
27 #include "trace.h"
28 
29 enum NPCM7xxSMBusCommonRegister {
30     NPCM7XX_SMB_SDA     = 0x0,
31     NPCM7XX_SMB_ST      = 0x2,
32     NPCM7XX_SMB_CST     = 0x4,
33     NPCM7XX_SMB_CTL1    = 0x6,
34     NPCM7XX_SMB_ADDR1   = 0x8,
35     NPCM7XX_SMB_CTL2    = 0xa,
36     NPCM7XX_SMB_ADDR2   = 0xc,
37     NPCM7XX_SMB_CTL3    = 0xe,
38     NPCM7XX_SMB_CST2    = 0x18,
39     NPCM7XX_SMB_CST3    = 0x19,
40     NPCM7XX_SMB_VER     = 0x1f,
41 };
42 
43 enum NPCM7xxSMBusBank0Register {
44     NPCM7XX_SMB_ADDR3   = 0x10,
45     NPCM7XX_SMB_ADDR7   = 0x11,
46     NPCM7XX_SMB_ADDR4   = 0x12,
47     NPCM7XX_SMB_ADDR8   = 0x13,
48     NPCM7XX_SMB_ADDR5   = 0x14,
49     NPCM7XX_SMB_ADDR9   = 0x15,
50     NPCM7XX_SMB_ADDR6   = 0x16,
51     NPCM7XX_SMB_ADDR10  = 0x17,
52     NPCM7XX_SMB_CTL4    = 0x1a,
53     NPCM7XX_SMB_CTL5    = 0x1b,
54     NPCM7XX_SMB_SCLLT   = 0x1c,
55     NPCM7XX_SMB_FIF_CTL = 0x1d,
56     NPCM7XX_SMB_SCLHT   = 0x1e,
57 };
58 
59 enum NPCM7xxSMBusBank1Register {
60     NPCM7XX_SMB_FIF_CTS  = 0x10,
61     NPCM7XX_SMB_FAIR_PER = 0x11,
62     NPCM7XX_SMB_TXF_CTL  = 0x12,
63     NPCM7XX_SMB_T_OUT    = 0x14,
64     NPCM7XX_SMB_TXF_STS  = 0x1a,
65     NPCM7XX_SMB_RXF_STS  = 0x1c,
66     NPCM7XX_SMB_RXF_CTL  = 0x1e,
67 };
68 
69 /* ST fields */
70 #define NPCM7XX_SMBST_STP           BIT(7)
71 #define NPCM7XX_SMBST_SDAST         BIT(6)
72 #define NPCM7XX_SMBST_BER           BIT(5)
73 #define NPCM7XX_SMBST_NEGACK        BIT(4)
74 #define NPCM7XX_SMBST_STASTR        BIT(3)
75 #define NPCM7XX_SMBST_NMATCH        BIT(2)
76 #define NPCM7XX_SMBST_MODE          BIT(1)
77 #define NPCM7XX_SMBST_XMIT          BIT(0)
78 
79 /* CST fields */
80 #define NPCM7XX_SMBCST_ARPMATCH        BIT(7)
81 #define NPCM7XX_SMBCST_MATCHAF         BIT(6)
82 #define NPCM7XX_SMBCST_TGSCL           BIT(5)
83 #define NPCM7XX_SMBCST_TSDA            BIT(4)
84 #define NPCM7XX_SMBCST_GCMATCH         BIT(3)
85 #define NPCM7XX_SMBCST_MATCH           BIT(2)
86 #define NPCM7XX_SMBCST_BB              BIT(1)
87 #define NPCM7XX_SMBCST_BUSY            BIT(0)
88 
89 /* CST2 fields */
90 #define NPCM7XX_SMBCST2_INTSTS         BIT(7)
91 #define NPCM7XX_SMBCST2_MATCH7F        BIT(6)
92 #define NPCM7XX_SMBCST2_MATCH6F        BIT(5)
93 #define NPCM7XX_SMBCST2_MATCH5F        BIT(4)
94 #define NPCM7XX_SMBCST2_MATCH4F        BIT(3)
95 #define NPCM7XX_SMBCST2_MATCH3F        BIT(2)
96 #define NPCM7XX_SMBCST2_MATCH2F        BIT(1)
97 #define NPCM7XX_SMBCST2_MATCH1F        BIT(0)
98 
99 /* CST3 fields */
100 #define NPCM7XX_SMBCST3_EO_BUSY        BIT(7)
101 #define NPCM7XX_SMBCST3_MATCH10F       BIT(2)
102 #define NPCM7XX_SMBCST3_MATCH9F        BIT(1)
103 #define NPCM7XX_SMBCST3_MATCH8F        BIT(0)
104 
105 /* CTL1 fields */
106 #define NPCM7XX_SMBCTL1_STASTRE     BIT(7)
107 #define NPCM7XX_SMBCTL1_NMINTE      BIT(6)
108 #define NPCM7XX_SMBCTL1_GCMEN       BIT(5)
109 #define NPCM7XX_SMBCTL1_ACK         BIT(4)
110 #define NPCM7XX_SMBCTL1_EOBINTE     BIT(3)
111 #define NPCM7XX_SMBCTL1_INTEN       BIT(2)
112 #define NPCM7XX_SMBCTL1_STOP        BIT(1)
113 #define NPCM7XX_SMBCTL1_START       BIT(0)
114 
115 /* CTL2 fields */
116 #define NPCM7XX_SMBCTL2_SCLFRQ(rv)  extract8((rv), 1, 6)
117 #define NPCM7XX_SMBCTL2_ENABLE      BIT(0)
118 
119 /* CTL3 fields */
120 #define NPCM7XX_SMBCTL3_SCL_LVL     BIT(7)
121 #define NPCM7XX_SMBCTL3_SDA_LVL     BIT(6)
122 #define NPCM7XX_SMBCTL3_BNK_SEL     BIT(5)
123 #define NPCM7XX_SMBCTL3_400K_MODE   BIT(4)
124 #define NPCM7XX_SMBCTL3_IDL_START   BIT(3)
125 #define NPCM7XX_SMBCTL3_ARPMEN      BIT(2)
126 #define NPCM7XX_SMBCTL3_SCLFRQ(rv)  extract8((rv), 0, 2)
127 
128 /* ADDR fields */
129 #define NPCM7XX_ADDR_EN             BIT(7)
130 #define NPCM7XX_ADDR_A(rv)          extract8((rv), 0, 6)
131 
132 /* FIFO Mode Register Fields */
133 /* FIF_CTL fields */
134 #define NPCM7XX_SMBFIF_CTL_FIFO_EN          BIT(4)
135 #define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE      BIT(2)
136 #define NPCM7XX_SMBFIF_CTL_FAIR_RDY         BIT(1)
137 #define NPCM7XX_SMBFIF_CTL_FAIR_BUSY        BIT(0)
138 /* FIF_CTS fields */
139 #define NPCM7XX_SMBFIF_CTS_STR              BIT(7)
140 #define NPCM7XX_SMBFIF_CTS_CLR_FIFO         BIT(6)
141 #define NPCM7XX_SMBFIF_CTS_RFTE_IE          BIT(3)
142 #define NPCM7XX_SMBFIF_CTS_RXF_TXE          BIT(1)
143 /* TXF_CTL fields */
144 #define NPCM7XX_SMBTXF_CTL_THR_TXIE         BIT(6)
145 #define NPCM7XX_SMBTXF_CTL_TX_THR(rv)       extract8((rv), 0, 5)
146 /* T_OUT fields */
147 #define NPCM7XX_SMBT_OUT_ST                 BIT(7)
148 #define NPCM7XX_SMBT_OUT_IE                 BIT(6)
149 #define NPCM7XX_SMBT_OUT_CLKDIV(rv)         extract8((rv), 0, 6)
150 /* TXF_STS fields */
151 #define NPCM7XX_SMBTXF_STS_TX_THST          BIT(6)
152 #define NPCM7XX_SMBTXF_STS_TX_BYTES(rv)     extract8((rv), 0, 5)
153 /* RXF_STS fields */
154 #define NPCM7XX_SMBRXF_STS_RX_THST          BIT(6)
155 #define NPCM7XX_SMBRXF_STS_RX_BYTES(rv)     extract8((rv), 0, 5)
156 /* RXF_CTL fields */
157 #define NPCM7XX_SMBRXF_CTL_THR_RXIE         BIT(6)
158 #define NPCM7XX_SMBRXF_CTL_LAST             BIT(5)
159 #define NPCM7XX_SMBRXF_CTL_RX_THR(rv)       extract8((rv), 0, 5)
160 
161 #define KEEP_OLD_BIT(o, n, b)       (((n) & (~(b))) | ((o) & (b)))
162 #define WRITE_ONE_CLEAR(o, n, b)    ((n) & (b) ? (o) & (~(b)) : (o))
163 
164 #define NPCM7XX_SMBUS_ENABLED(s)    ((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
165 #define NPCM7XX_SMBUS_FIFO_ENABLED(s) ((s)->fif_ctl & \
166                                        NPCM7XX_SMBFIF_CTL_FIFO_EN)
167 
168 /* VERSION fields values, read-only. */
169 #define NPCM7XX_SMBUS_VERSION_NUMBER 1
170 #define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 1
171 
172 /* Reset values */
173 #define NPCM7XX_SMB_ST_INIT_VAL     0x00
174 #define NPCM7XX_SMB_CST_INIT_VAL    0x10
175 #define NPCM7XX_SMB_CST2_INIT_VAL   0x00
176 #define NPCM7XX_SMB_CST3_INIT_VAL   0x00
177 #define NPCM7XX_SMB_CTL1_INIT_VAL   0x00
178 #define NPCM7XX_SMB_CTL2_INIT_VAL   0x00
179 #define NPCM7XX_SMB_CTL3_INIT_VAL   0xc0
180 #define NPCM7XX_SMB_CTL4_INIT_VAL   0x07
181 #define NPCM7XX_SMB_CTL5_INIT_VAL   0x00
182 #define NPCM7XX_SMB_ADDR_INIT_VAL   0x00
183 #define NPCM7XX_SMB_SCLLT_INIT_VAL  0x00
184 #define NPCM7XX_SMB_SCLHT_INIT_VAL  0x00
185 #define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
186 #define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
187 #define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
188 #define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
189 #define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
190 #define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
191 #define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
192 #define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
193 
194 static uint8_t npcm7xx_smbus_get_version(void)
195 {
196     return NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED << 7 |
197            NPCM7XX_SMBUS_VERSION_NUMBER;
198 }
199 
200 static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
201 {
202     int level;
203 
204     if (s->ctl1 & NPCM7XX_SMBCTL1_INTEN) {
205         level = !!((s->ctl1 & NPCM7XX_SMBCTL1_NMINTE &&
206                     s->st & NPCM7XX_SMBST_NMATCH) ||
207                    (s->st & NPCM7XX_SMBST_BER) ||
208                    (s->st & NPCM7XX_SMBST_NEGACK) ||
209                    (s->st & NPCM7XX_SMBST_SDAST) ||
210                    (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
211                     s->st & NPCM7XX_SMBST_SDAST) ||
212                    (s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
213                     s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
214                    (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
215                     s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
216                    (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
217                     s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
218                    (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
219                     s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
220 
221         if (level) {
222             s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
223         } else {
224             s->cst2 &= ~NPCM7XX_SMBCST2_INTSTS;
225         }
226         qemu_set_irq(s->irq, level);
227     }
228 }
229 
230 static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
231 {
232     s->st &= ~NPCM7XX_SMBST_SDAST;
233     s->st |= NPCM7XX_SMBST_NEGACK;
234     s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
235 }
236 
237 static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
238 {
239     s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
240     s->txf_sts = 0;
241     s->rxf_sts = 0;
242 }
243 
244 static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
245 {
246     int rv = i2c_send(s->bus, value);
247 
248     if (rv) {
249         npcm7xx_smbus_nack(s);
250     } else {
251         s->st |= NPCM7XX_SMBST_SDAST;
252         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
253             s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
254             if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
255                 NPCM7XX_SMBTXF_CTL_TX_THR(s->txf_ctl)) {
256                 s->txf_sts = NPCM7XX_SMBTXF_STS_TX_THST;
257             } else {
258                 s->txf_sts = 0;
259             }
260         }
261     }
262     trace_npcm7xx_smbus_send_byte((DEVICE(s)->canonical_path), value, !rv);
263     npcm7xx_smbus_update_irq(s);
264 }
265 
266 static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
267 {
268     s->sda = i2c_recv(s->bus);
269     s->st |= NPCM7XX_SMBST_SDAST;
270     if (s->st & NPCM7XX_SMBCTL1_ACK) {
271         trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
272         i2c_nack(s->bus);
273         s->st &= NPCM7XX_SMBCTL1_ACK;
274     }
275     trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
276     npcm7xx_smbus_update_irq(s);
277 }
278 
279 static void npcm7xx_smbus_recv_fifo(NPCM7xxSMBusState *s)
280 {
281     uint8_t expected_bytes = NPCM7XX_SMBRXF_CTL_RX_THR(s->rxf_ctl);
282     uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
283     uint8_t pos;
284 
285     if (received_bytes == expected_bytes) {
286         return;
287     }
288 
289     while (received_bytes < expected_bytes &&
290            received_bytes < NPCM7XX_SMBUS_FIFO_SIZE) {
291         pos = (s->rx_cur + received_bytes) % NPCM7XX_SMBUS_FIFO_SIZE;
292         s->rx_fifo[pos] = i2c_recv(s->bus);
293         trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path),
294                                       s->rx_fifo[pos]);
295         ++received_bytes;
296     }
297 
298     trace_npcm7xx_smbus_recv_fifo((DEVICE(s)->canonical_path),
299                                   received_bytes, expected_bytes);
300     s->rxf_sts = received_bytes;
301     if (unlikely(received_bytes < expected_bytes)) {
302         qemu_log_mask(LOG_GUEST_ERROR,
303                       "%s: invalid rx_thr value: 0x%02x\n",
304                       DEVICE(s)->canonical_path, expected_bytes);
305         return;
306     }
307 
308     s->rxf_sts |= NPCM7XX_SMBRXF_STS_RX_THST;
309     if (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_LAST) {
310         trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
311         i2c_nack(s->bus);
312         s->rxf_ctl &= ~NPCM7XX_SMBRXF_CTL_LAST;
313     }
314     if (received_bytes == NPCM7XX_SMBUS_FIFO_SIZE) {
315         s->st |= NPCM7XX_SMBST_SDAST;
316         s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
317     } else if (!(s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE)) {
318         s->st |= NPCM7XX_SMBST_SDAST;
319     } else {
320         s->st &= ~NPCM7XX_SMBST_SDAST;
321     }
322     npcm7xx_smbus_update_irq(s);
323 }
324 
325 static void npcm7xx_smbus_read_byte_fifo(NPCM7xxSMBusState *s)
326 {
327     uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
328 
329     if (received_bytes == 0) {
330         npcm7xx_smbus_recv_fifo(s);
331         return;
332     }
333 
334     s->sda = s->rx_fifo[s->rx_cur];
335     s->rx_cur = (s->rx_cur + 1u) % NPCM7XX_SMBUS_FIFO_SIZE;
336     --s->rxf_sts;
337     npcm7xx_smbus_update_irq(s);
338 }
339 
340 static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
341 {
342     /*
343      * We can start the bus if one of these is true:
344      * 1. The bus is idle (so we can request it)
345      * 2. We are the occupier (it's a repeated start condition.)
346      */
347     int available = !i2c_bus_busy(s->bus) ||
348                     s->status != NPCM7XX_SMBUS_STATUS_IDLE;
349 
350     if (available) {
351         s->st |= NPCM7XX_SMBST_MODE | NPCM7XX_SMBST_XMIT | NPCM7XX_SMBST_SDAST;
352         s->cst |= NPCM7XX_SMBCST_BUSY;
353         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
354             s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
355         }
356     } else {
357         s->st &= ~NPCM7XX_SMBST_MODE;
358         s->cst &= ~NPCM7XX_SMBCST_BUSY;
359         s->st |= NPCM7XX_SMBST_BER;
360     }
361 
362     trace_npcm7xx_smbus_start(DEVICE(s)->canonical_path, available);
363     s->cst |= NPCM7XX_SMBCST_BB;
364     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
365     npcm7xx_smbus_update_irq(s);
366 }
367 
368 static void npcm7xx_smbus_send_address(NPCM7xxSMBusState *s, uint8_t value)
369 {
370     int recv;
371     int rv;
372 
373     recv = value & BIT(0);
374     rv = i2c_start_transfer(s->bus, value >> 1, recv);
375     trace_npcm7xx_smbus_send_address(DEVICE(s)->canonical_path,
376                                      value >> 1, recv, !rv);
377     if (rv) {
378         qemu_log_mask(LOG_GUEST_ERROR,
379                       "%s: requesting i2c bus for 0x%02x failed: %d\n",
380                       DEVICE(s)->canonical_path, value, rv);
381         /* Failed to start transfer. NACK to reject.*/
382         if (recv) {
383             s->st &= ~NPCM7XX_SMBST_XMIT;
384         } else {
385             s->st |= NPCM7XX_SMBST_XMIT;
386         }
387         npcm7xx_smbus_nack(s);
388         npcm7xx_smbus_update_irq(s);
389         return;
390     }
391 
392     s->st &= ~NPCM7XX_SMBST_NEGACK;
393     if (recv) {
394         s->status = NPCM7XX_SMBUS_STATUS_RECEIVING;
395         s->st &= ~NPCM7XX_SMBST_XMIT;
396     } else {
397         s->status = NPCM7XX_SMBUS_STATUS_SENDING;
398         s->st |= NPCM7XX_SMBST_XMIT;
399     }
400 
401     if (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE) {
402         s->st |= NPCM7XX_SMBST_STASTR;
403         if (!recv) {
404             s->st |= NPCM7XX_SMBST_SDAST;
405         }
406     } else if (recv) {
407         s->st |= NPCM7XX_SMBST_SDAST;
408         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
409             npcm7xx_smbus_recv_fifo(s);
410         } else {
411             npcm7xx_smbus_recv_byte(s);
412         }
413     } else if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
414         s->st |= NPCM7XX_SMBST_SDAST;
415         s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
416     }
417     npcm7xx_smbus_update_irq(s);
418 }
419 
420 static void npcm7xx_smbus_execute_stop(NPCM7xxSMBusState *s)
421 {
422     i2c_end_transfer(s->bus);
423     s->st = 0;
424     s->cst = 0;
425     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
426     s->cst3 |= NPCM7XX_SMBCST3_EO_BUSY;
427     trace_npcm7xx_smbus_stop(DEVICE(s)->canonical_path);
428     npcm7xx_smbus_update_irq(s);
429 }
430 
431 
432 static void npcm7xx_smbus_stop(NPCM7xxSMBusState *s)
433 {
434     if (s->st & NPCM7XX_SMBST_MODE) {
435         switch (s->status) {
436         case NPCM7XX_SMBUS_STATUS_RECEIVING:
437         case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
438             s->status = NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE;
439             break;
440 
441         case NPCM7XX_SMBUS_STATUS_NEGACK:
442             s->status = NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK;
443             break;
444 
445         default:
446             npcm7xx_smbus_execute_stop(s);
447             break;
448         }
449     }
450 }
451 
452 static uint8_t npcm7xx_smbus_read_sda(NPCM7xxSMBusState *s)
453 {
454     uint8_t value = s->sda;
455 
456     switch (s->status) {
457     case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
458         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
459             if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) <= 1) {
460                 npcm7xx_smbus_execute_stop(s);
461             }
462             if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) == 0) {
463                 qemu_log_mask(LOG_GUEST_ERROR,
464                               "%s: read to SDA with an empty rx-fifo buffer, "
465                               "result undefined: %u\n",
466                               DEVICE(s)->canonical_path, s->sda);
467                 break;
468             }
469             npcm7xx_smbus_read_byte_fifo(s);
470             value = s->sda;
471         } else {
472             npcm7xx_smbus_execute_stop(s);
473         }
474         break;
475 
476     case NPCM7XX_SMBUS_STATUS_RECEIVING:
477         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
478             npcm7xx_smbus_read_byte_fifo(s);
479             value = s->sda;
480         } else {
481             npcm7xx_smbus_recv_byte(s);
482         }
483         break;
484 
485     default:
486         /* Do nothing */
487         break;
488     }
489 
490     return value;
491 }
492 
493 static void npcm7xx_smbus_write_sda(NPCM7xxSMBusState *s, uint8_t value)
494 {
495     s->sda = value;
496     if (s->st & NPCM7XX_SMBST_MODE) {
497         switch (s->status) {
498         case NPCM7XX_SMBUS_STATUS_IDLE:
499             npcm7xx_smbus_send_address(s, value);
500             break;
501         case NPCM7XX_SMBUS_STATUS_SENDING:
502             npcm7xx_smbus_send_byte(s, value);
503             break;
504         default:
505             qemu_log_mask(LOG_GUEST_ERROR,
506                           "%s: write to SDA in invalid status %d: %u\n",
507                           DEVICE(s)->canonical_path, s->status, value);
508             break;
509         }
510     }
511 }
512 
513 static void npcm7xx_smbus_write_st(NPCM7xxSMBusState *s, uint8_t value)
514 {
515     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STP);
516     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_BER);
517     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STASTR);
518     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_NMATCH);
519 
520     if (value & NPCM7XX_SMBST_NEGACK) {
521         s->st &= ~NPCM7XX_SMBST_NEGACK;
522         if (s->status == NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK) {
523             npcm7xx_smbus_execute_stop(s);
524         }
525     }
526 
527     if (value & NPCM7XX_SMBST_STASTR &&
528         s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
529         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
530             npcm7xx_smbus_recv_fifo(s);
531         } else {
532             npcm7xx_smbus_recv_byte(s);
533         }
534     }
535 
536     npcm7xx_smbus_update_irq(s);
537 }
538 
539 static void npcm7xx_smbus_write_cst(NPCM7xxSMBusState *s, uint8_t value)
540 {
541     uint8_t new_value = s->cst;
542 
543     s->cst = WRITE_ONE_CLEAR(new_value, value, NPCM7XX_SMBCST_BB);
544     npcm7xx_smbus_update_irq(s);
545 }
546 
547 static void npcm7xx_smbus_write_cst3(NPCM7xxSMBusState *s, uint8_t value)
548 {
549     s->cst3 = WRITE_ONE_CLEAR(s->cst3, value, NPCM7XX_SMBCST3_EO_BUSY);
550     npcm7xx_smbus_update_irq(s);
551 }
552 
553 static void npcm7xx_smbus_write_ctl1(NPCM7xxSMBusState *s, uint8_t value)
554 {
555     s->ctl1 = KEEP_OLD_BIT(s->ctl1, value,
556             NPCM7XX_SMBCTL1_START | NPCM7XX_SMBCTL1_STOP | NPCM7XX_SMBCTL1_ACK);
557 
558     if (value & NPCM7XX_SMBCTL1_START) {
559         npcm7xx_smbus_start(s);
560     }
561 
562     if (value & NPCM7XX_SMBCTL1_STOP) {
563         npcm7xx_smbus_stop(s);
564     }
565 
566     npcm7xx_smbus_update_irq(s);
567 }
568 
569 static void npcm7xx_smbus_write_ctl2(NPCM7xxSMBusState *s, uint8_t value)
570 {
571     s->ctl2 = value;
572 
573     if (!NPCM7XX_SMBUS_ENABLED(s)) {
574         /* Disable this SMBus module. */
575         s->ctl1 = 0;
576         s->st = 0;
577         s->cst3 = s->cst3 & (~NPCM7XX_SMBCST3_EO_BUSY);
578         s->cst = 0;
579         npcm7xx_smbus_clear_buffer(s);
580     }
581 }
582 
583 static void npcm7xx_smbus_write_ctl3(NPCM7xxSMBusState *s, uint8_t value)
584 {
585     uint8_t old_ctl3 = s->ctl3;
586 
587     /* Write to SDA and SCL bits are ignored. */
588     s->ctl3 =  KEEP_OLD_BIT(old_ctl3, value,
589                             NPCM7XX_SMBCTL3_SCL_LVL | NPCM7XX_SMBCTL3_SDA_LVL);
590 }
591 
592 static void npcm7xx_smbus_write_fif_ctl(NPCM7xxSMBusState *s, uint8_t value)
593 {
594     uint8_t new_ctl = value;
595 
596     new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
597     new_ctl = WRITE_ONE_CLEAR(new_ctl, value, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
598     new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_BUSY);
599     s->fif_ctl = new_ctl;
600 }
601 
602 static void npcm7xx_smbus_write_fif_cts(NPCM7xxSMBusState *s, uint8_t value)
603 {
604     s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_STR);
605     s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_RXF_TXE);
606     s->fif_cts = KEEP_OLD_BIT(value, s->fif_cts, NPCM7XX_SMBFIF_CTS_RFTE_IE);
607 
608     if (value & NPCM7XX_SMBFIF_CTS_CLR_FIFO) {
609         npcm7xx_smbus_clear_buffer(s);
610     }
611 }
612 
613 static void npcm7xx_smbus_write_txf_ctl(NPCM7xxSMBusState *s, uint8_t value)
614 {
615     s->txf_ctl = value;
616 }
617 
618 static void npcm7xx_smbus_write_t_out(NPCM7xxSMBusState *s, uint8_t value)
619 {
620     uint8_t new_t_out = value;
621 
622     if ((value & NPCM7XX_SMBT_OUT_ST) || (!(s->t_out & NPCM7XX_SMBT_OUT_ST))) {
623         new_t_out &= ~NPCM7XX_SMBT_OUT_ST;
624     } else {
625         new_t_out |= NPCM7XX_SMBT_OUT_ST;
626     }
627 
628     s->t_out = new_t_out;
629 }
630 
631 static void npcm7xx_smbus_write_txf_sts(NPCM7xxSMBusState *s, uint8_t value)
632 {
633     s->txf_sts = WRITE_ONE_CLEAR(s->txf_sts, value, NPCM7XX_SMBTXF_STS_TX_THST);
634 }
635 
636 static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState *s, uint8_t value)
637 {
638     if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
639         s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
640         if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
641             npcm7xx_smbus_recv_fifo(s);
642         }
643     }
644 }
645 
646 static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState *s, uint8_t value)
647 {
648     uint8_t new_ctl = value;
649 
650     if (!(value & NPCM7XX_SMBRXF_CTL_LAST)) {
651         new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
652     }
653     s->rxf_ctl = new_ctl;
654 }
655 
656 static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
657 {
658     NPCM7xxSMBusState *s = opaque;
659     uint64_t value = 0;
660     uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
661 
662     /* The order of the registers are their order in memory. */
663     switch (offset) {
664     case NPCM7XX_SMB_SDA:
665         value = npcm7xx_smbus_read_sda(s);
666         break;
667 
668     case NPCM7XX_SMB_ST:
669         value = s->st;
670         break;
671 
672     case NPCM7XX_SMB_CST:
673         value = s->cst;
674         break;
675 
676     case NPCM7XX_SMB_CTL1:
677         value = s->ctl1;
678         break;
679 
680     case NPCM7XX_SMB_ADDR1:
681         value = s->addr[0];
682         break;
683 
684     case NPCM7XX_SMB_CTL2:
685         value = s->ctl2;
686         break;
687 
688     case NPCM7XX_SMB_ADDR2:
689         value = s->addr[1];
690         break;
691 
692     case NPCM7XX_SMB_CTL3:
693         value = s->ctl3;
694         break;
695 
696     case NPCM7XX_SMB_CST2:
697         value = s->cst2;
698         break;
699 
700     case NPCM7XX_SMB_CST3:
701         value = s->cst3;
702         break;
703 
704     case NPCM7XX_SMB_VER:
705         value = npcm7xx_smbus_get_version();
706         break;
707 
708     /* This register is either invalid or banked at this point. */
709     default:
710         if (bank) {
711             /* Bank 1 */
712             switch (offset) {
713             case NPCM7XX_SMB_FIF_CTS:
714                 value = s->fif_cts;
715                 break;
716 
717             case NPCM7XX_SMB_FAIR_PER:
718                 value = s->fair_per;
719                 break;
720 
721             case NPCM7XX_SMB_TXF_CTL:
722                 value = s->txf_ctl;
723                 break;
724 
725             case NPCM7XX_SMB_T_OUT:
726                 value = s->t_out;
727                 break;
728 
729             case NPCM7XX_SMB_TXF_STS:
730                 value = s->txf_sts;
731                 break;
732 
733             case NPCM7XX_SMB_RXF_STS:
734                 value = s->rxf_sts;
735                 break;
736 
737             case NPCM7XX_SMB_RXF_CTL:
738                 value = s->rxf_ctl;
739                 break;
740 
741             default:
742                 qemu_log_mask(LOG_GUEST_ERROR,
743                         "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
744                         DEVICE(s)->canonical_path, offset);
745                 break;
746             }
747         } else {
748             /* Bank 0 */
749             switch (offset) {
750             case NPCM7XX_SMB_ADDR3:
751                 value = s->addr[2];
752                 break;
753 
754             case NPCM7XX_SMB_ADDR7:
755                 value = s->addr[6];
756                 break;
757 
758             case NPCM7XX_SMB_ADDR4:
759                 value = s->addr[3];
760                 break;
761 
762             case NPCM7XX_SMB_ADDR8:
763                 value = s->addr[7];
764                 break;
765 
766             case NPCM7XX_SMB_ADDR5:
767                 value = s->addr[4];
768                 break;
769 
770             case NPCM7XX_SMB_ADDR9:
771                 value = s->addr[8];
772                 break;
773 
774             case NPCM7XX_SMB_ADDR6:
775                 value = s->addr[5];
776                 break;
777 
778             case NPCM7XX_SMB_ADDR10:
779                 value = s->addr[9];
780                 break;
781 
782             case NPCM7XX_SMB_CTL4:
783                 value = s->ctl4;
784                 break;
785 
786             case NPCM7XX_SMB_CTL5:
787                 value = s->ctl5;
788                 break;
789 
790             case NPCM7XX_SMB_SCLLT:
791                 value = s->scllt;
792                 break;
793 
794             case NPCM7XX_SMB_FIF_CTL:
795                 value = s->fif_ctl;
796                 break;
797 
798             case NPCM7XX_SMB_SCLHT:
799                 value = s->sclht;
800                 break;
801 
802             default:
803                 qemu_log_mask(LOG_GUEST_ERROR,
804                         "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
805                         DEVICE(s)->canonical_path, offset);
806                 break;
807             }
808         }
809         break;
810     }
811 
812     trace_npcm7xx_smbus_read(DEVICE(s)->canonical_path, offset, value, size);
813 
814     return value;
815 }
816 
817 static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
818                               unsigned size)
819 {
820     NPCM7xxSMBusState *s = opaque;
821     uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
822 
823     trace_npcm7xx_smbus_write(DEVICE(s)->canonical_path, offset, value, size);
824 
825     /* The order of the registers are their order in memory. */
826     switch (offset) {
827     case NPCM7XX_SMB_SDA:
828         npcm7xx_smbus_write_sda(s, value);
829         break;
830 
831     case NPCM7XX_SMB_ST:
832         npcm7xx_smbus_write_st(s, value);
833         break;
834 
835     case NPCM7XX_SMB_CST:
836         npcm7xx_smbus_write_cst(s, value);
837         break;
838 
839     case NPCM7XX_SMB_CTL1:
840         npcm7xx_smbus_write_ctl1(s, value);
841         break;
842 
843     case NPCM7XX_SMB_ADDR1:
844         s->addr[0] = value;
845         break;
846 
847     case NPCM7XX_SMB_CTL2:
848         npcm7xx_smbus_write_ctl2(s, value);
849         break;
850 
851     case NPCM7XX_SMB_ADDR2:
852         s->addr[1] = value;
853         break;
854 
855     case NPCM7XX_SMB_CTL3:
856         npcm7xx_smbus_write_ctl3(s, value);
857         break;
858 
859     case NPCM7XX_SMB_CST2:
860         qemu_log_mask(LOG_GUEST_ERROR,
861                 "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
862                 DEVICE(s)->canonical_path, offset);
863         break;
864 
865     case NPCM7XX_SMB_CST3:
866         npcm7xx_smbus_write_cst3(s, value);
867         break;
868 
869     case NPCM7XX_SMB_VER:
870         qemu_log_mask(LOG_GUEST_ERROR,
871                 "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
872                 DEVICE(s)->canonical_path, offset);
873         break;
874 
875     /* This register is either invalid or banked at this point. */
876     default:
877         if (bank) {
878             /* Bank 1 */
879             switch (offset) {
880             case NPCM7XX_SMB_FIF_CTS:
881                 npcm7xx_smbus_write_fif_cts(s, value);
882                 break;
883 
884             case NPCM7XX_SMB_FAIR_PER:
885                 s->fair_per = value;
886                 break;
887 
888             case NPCM7XX_SMB_TXF_CTL:
889                 npcm7xx_smbus_write_txf_ctl(s, value);
890                 break;
891 
892             case NPCM7XX_SMB_T_OUT:
893                 npcm7xx_smbus_write_t_out(s, value);
894                 break;
895 
896             case NPCM7XX_SMB_TXF_STS:
897                 npcm7xx_smbus_write_txf_sts(s, value);
898                 break;
899 
900             case NPCM7XX_SMB_RXF_STS:
901                 npcm7xx_smbus_write_rxf_sts(s, value);
902                 break;
903 
904             case NPCM7XX_SMB_RXF_CTL:
905                 npcm7xx_smbus_write_rxf_ctl(s, value);
906                 break;
907 
908             default:
909                 qemu_log_mask(LOG_GUEST_ERROR,
910                         "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
911                         DEVICE(s)->canonical_path, offset);
912                 break;
913             }
914         } else {
915             /* Bank 0 */
916             switch (offset) {
917             case NPCM7XX_SMB_ADDR3:
918                 s->addr[2] = value;
919                 break;
920 
921             case NPCM7XX_SMB_ADDR7:
922                 s->addr[6] = value;
923                 break;
924 
925             case NPCM7XX_SMB_ADDR4:
926                 s->addr[3] = value;
927                 break;
928 
929             case NPCM7XX_SMB_ADDR8:
930                 s->addr[7] = value;
931                 break;
932 
933             case NPCM7XX_SMB_ADDR5:
934                 s->addr[4] = value;
935                 break;
936 
937             case NPCM7XX_SMB_ADDR9:
938                 s->addr[8] = value;
939                 break;
940 
941             case NPCM7XX_SMB_ADDR6:
942                 s->addr[5] = value;
943                 break;
944 
945             case NPCM7XX_SMB_ADDR10:
946                 s->addr[9] = value;
947                 break;
948 
949             case NPCM7XX_SMB_CTL4:
950                 s->ctl4 = value;
951                 break;
952 
953             case NPCM7XX_SMB_CTL5:
954                 s->ctl5 = value;
955                 break;
956 
957             case NPCM7XX_SMB_SCLLT:
958                 s->scllt = value;
959                 break;
960 
961             case NPCM7XX_SMB_FIF_CTL:
962                 npcm7xx_smbus_write_fif_ctl(s, value);
963                 break;
964 
965             case NPCM7XX_SMB_SCLHT:
966                 s->sclht = value;
967                 break;
968 
969             default:
970                 qemu_log_mask(LOG_GUEST_ERROR,
971                         "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
972                         DEVICE(s)->canonical_path, offset);
973                 break;
974             }
975         }
976         break;
977     }
978 }
979 
980 static const MemoryRegionOps npcm7xx_smbus_ops = {
981     .read = npcm7xx_smbus_read,
982     .write = npcm7xx_smbus_write,
983     .endianness = DEVICE_LITTLE_ENDIAN,
984     .valid = {
985         .min_access_size = 1,
986         .max_access_size = 1,
987         .unaligned = false,
988     },
989 };
990 
991 static void npcm7xx_smbus_enter_reset(Object *obj, ResetType type)
992 {
993     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
994 
995     s->st = NPCM7XX_SMB_ST_INIT_VAL;
996     s->cst = NPCM7XX_SMB_CST_INIT_VAL;
997     s->cst2 = NPCM7XX_SMB_CST2_INIT_VAL;
998     s->cst3 = NPCM7XX_SMB_CST3_INIT_VAL;
999     s->ctl1 = NPCM7XX_SMB_CTL1_INIT_VAL;
1000     s->ctl2 = NPCM7XX_SMB_CTL2_INIT_VAL;
1001     s->ctl3 = NPCM7XX_SMB_CTL3_INIT_VAL;
1002     s->ctl4 = NPCM7XX_SMB_CTL4_INIT_VAL;
1003     s->ctl5 = NPCM7XX_SMB_CTL5_INIT_VAL;
1004 
1005     for (int i = 0; i < NPCM7XX_SMBUS_NR_ADDRS; ++i) {
1006         s->addr[i] = NPCM7XX_SMB_ADDR_INIT_VAL;
1007     }
1008     s->scllt = NPCM7XX_SMB_SCLLT_INIT_VAL;
1009     s->sclht = NPCM7XX_SMB_SCLHT_INIT_VAL;
1010 
1011     s->fif_ctl = NPCM7XX_SMB_FIF_CTL_INIT_VAL;
1012     s->fif_cts = NPCM7XX_SMB_FIF_CTS_INIT_VAL;
1013     s->fair_per = NPCM7XX_SMB_FAIR_PER_INIT_VAL;
1014     s->txf_ctl = NPCM7XX_SMB_TXF_CTL_INIT_VAL;
1015     s->t_out = NPCM7XX_SMB_T_OUT_INIT_VAL;
1016     s->txf_sts = NPCM7XX_SMB_TXF_STS_INIT_VAL;
1017     s->rxf_sts = NPCM7XX_SMB_RXF_STS_INIT_VAL;
1018     s->rxf_ctl = NPCM7XX_SMB_RXF_CTL_INIT_VAL;
1019 
1020     npcm7xx_smbus_clear_buffer(s);
1021     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
1022     s->rx_cur = 0;
1023 }
1024 
1025 static void npcm7xx_smbus_hold_reset(Object *obj)
1026 {
1027     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
1028 
1029     qemu_irq_lower(s->irq);
1030 }
1031 
1032 static void npcm7xx_smbus_init(Object *obj)
1033 {
1034     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
1035     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1036 
1037     sysbus_init_irq(sbd, &s->irq);
1038     memory_region_init_io(&s->iomem, obj, &npcm7xx_smbus_ops, s,
1039                           "regs", 4 * KiB);
1040     sysbus_init_mmio(sbd, &s->iomem);
1041 
1042     s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
1043 }
1044 
1045 static const VMStateDescription vmstate_npcm7xx_smbus = {
1046     .name = "npcm7xx-smbus",
1047     .version_id = 0,
1048     .minimum_version_id = 0,
1049     .fields = (VMStateField[]) {
1050         VMSTATE_UINT8(sda, NPCM7xxSMBusState),
1051         VMSTATE_UINT8(st, NPCM7xxSMBusState),
1052         VMSTATE_UINT8(cst, NPCM7xxSMBusState),
1053         VMSTATE_UINT8(cst2, NPCM7xxSMBusState),
1054         VMSTATE_UINT8(cst3, NPCM7xxSMBusState),
1055         VMSTATE_UINT8(ctl1, NPCM7xxSMBusState),
1056         VMSTATE_UINT8(ctl2, NPCM7xxSMBusState),
1057         VMSTATE_UINT8(ctl3, NPCM7xxSMBusState),
1058         VMSTATE_UINT8(ctl4, NPCM7xxSMBusState),
1059         VMSTATE_UINT8(ctl5, NPCM7xxSMBusState),
1060         VMSTATE_UINT8_ARRAY(addr, NPCM7xxSMBusState, NPCM7XX_SMBUS_NR_ADDRS),
1061         VMSTATE_UINT8(scllt, NPCM7xxSMBusState),
1062         VMSTATE_UINT8(sclht, NPCM7xxSMBusState),
1063         VMSTATE_UINT8(fif_ctl, NPCM7xxSMBusState),
1064         VMSTATE_UINT8(fif_cts, NPCM7xxSMBusState),
1065         VMSTATE_UINT8(fair_per, NPCM7xxSMBusState),
1066         VMSTATE_UINT8(txf_ctl, NPCM7xxSMBusState),
1067         VMSTATE_UINT8(t_out, NPCM7xxSMBusState),
1068         VMSTATE_UINT8(txf_sts, NPCM7xxSMBusState),
1069         VMSTATE_UINT8(rxf_sts, NPCM7xxSMBusState),
1070         VMSTATE_UINT8(rxf_ctl, NPCM7xxSMBusState),
1071         VMSTATE_UINT8_ARRAY(rx_fifo, NPCM7xxSMBusState,
1072                             NPCM7XX_SMBUS_FIFO_SIZE),
1073         VMSTATE_UINT8(rx_cur, NPCM7xxSMBusState),
1074         VMSTATE_END_OF_LIST(),
1075     },
1076 };
1077 
1078 static void npcm7xx_smbus_class_init(ObjectClass *klass, void *data)
1079 {
1080     ResettableClass *rc = RESETTABLE_CLASS(klass);
1081     DeviceClass *dc = DEVICE_CLASS(klass);
1082 
1083     dc->desc = "NPCM7xx System Management Bus";
1084     dc->vmsd = &vmstate_npcm7xx_smbus;
1085     rc->phases.enter = npcm7xx_smbus_enter_reset;
1086     rc->phases.hold = npcm7xx_smbus_hold_reset;
1087 }
1088 
1089 static const TypeInfo npcm7xx_smbus_types[] = {
1090     {
1091         .name = TYPE_NPCM7XX_SMBUS,
1092         .parent = TYPE_SYS_BUS_DEVICE,
1093         .instance_size = sizeof(NPCM7xxSMBusState),
1094         .class_init = npcm7xx_smbus_class_init,
1095         .instance_init = npcm7xx_smbus_init,
1096     },
1097 };
1098 DEFINE_TYPES(npcm7xx_smbus_types);
1099