]> rtime.felk.cvut.cz Git - mf6xx.git/blob - src/qemu/hw/mf624.c
QEMU mf624.c formatted to make QEMU checkpatch.pl mostly happy.
[mf6xx.git] / src / qemu / hw / mf624.c
1 /*
2  * Humusoft MF624 DAQ card implementation
3  *
4  * Copyright (C) 2011 Rostislav Lisovy (lisovy@gmail.com)
5  *
6  * Licensed under GPLv2 license
7  */
8 #include "hw/hw.h"
9 #include "hw/pci/pci.h"
10 #include "qemu/event_notifier.h"
11 #include "qemu/osdep.h"
12 #include "qemu/thread.h"
13 #include "qemu/sockets.h"
14 #include "sysemu/char.h"
15
16 #define TYPE_MF624_DEV "mf624"
17
18 #define MF624_DEV(obj) \
19     OBJECT_CHECK(mf624_state_t, (obj), TYPE_MF624_DEV)
20
21 #define PCI_VENDOR_ID_HUMUSOFT        0x186c
22 #define PCI_DEVICE_ID_MF624        0x0624
23 #define PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER     0x1180
24
25
26 #define BAR0_size        32
27 #define BAR2_size        128
28 #define BAR4_size        128
29
30 /* BAR0 */
31 #define INTCSR_off       0x4C
32 #define GPIOC_off        0x54
33
34 /* BAR2 */
35 #define ADDATA_off       0x00
36 #define ADCTRL_off       0x00
37 #define ADDATA1_off      0x02
38 #define ADDATA2_off      0x04
39 #define ADDATA3_off      0x06
40 #define ADDATA4_off      0x08
41 #define ADDATA5_off      0x0A
42 #define ADDATA6_off      0x0C
43 #define ADDATA7_off      0x0E
44 #define DOUT_off         0x10
45 #define DIN_off          0x10
46 #define ADSTART_off      0x20
47 #define DA0_off          0x20
48 #define DA1_off          0x22
49 #define DA2_off          0x24
50 #define DA3_off          0x26
51 #define DA4_off          0x28
52 #define DA5_off          0x2A
53 #define DA6_off          0x2C
54 #define DA7_off          0x2E
55
56 #define GPIOC_EOLC_mask  (1 << 17)
57 #define GPIOC_LDAC_mask  (1 << 23)
58 #define GPIOC_DACEN_mask (1 << 26)
59
60
61 typedef struct {
62     uint32_t INTCSR;
63     uint32_t GPIOC;
64 } BAR0_t;
65
66 typedef struct {
67     uint16_t ADDATA;
68     uint16_t ADCTRL;
69     uint16_t ADDATA1;
70     uint16_t ADDATA2;
71     uint16_t ADDATA3;
72     uint16_t ADDATA4;
73     uint16_t ADDATA5;
74     uint16_t ADDATA6;
75     uint16_t ADDATA7;
76     uint16_t DIN;
77     uint16_t DOUT;
78     uint16_t DA0;
79     uint16_t DA1;
80     uint16_t DA2;
81     uint16_t DA3;
82     uint16_t DA4;
83     uint16_t DA5;
84     uint16_t DA6;
85     uint16_t DA7;
86 } BAR2_t;
87
88 /* Not implemented */
89 typedef struct {
90 //    uint32_t CTR0STATUS;
91 //    uint32_t CTR0MODE;
92 //    uint32_t CTR0;
93 //    uint32_t CTR0A;
94 //     ...
95 } BAR4_t;
96
97 typedef struct {
98     PCIDevice dev;
99     MemoryRegion mmio_bar0;
100     MemoryRegion mmio_bar2;
101     MemoryRegion mmio_bar4;
102         qemu_irq     irq;
103
104         QemuThread socket_thread;
105     int socket_srv;
106     int socket_tmp;
107     uint32_t port;
108     int addr;
109
110     /* The real voltage which is on inputs od A/D convertors.
111     Until new conversion is started, there is still old value in ADC registers*/
112     unsigned int real_world_AD0; /* Value in "ADC internal" format */
113     unsigned int real_world_AD1;
114     unsigned int real_world_AD2;
115     unsigned int real_world_AD3;
116     unsigned int real_world_AD4;
117     unsigned int real_world_AD5;
118     unsigned int real_world_AD6;
119     unsigned int real_world_AD7;
120
121     /* for cpu_register_physical_memory() function */
122     unsigned int BAR0_mem_table_index;
123     unsigned int BAR2_mem_table_index;
124     unsigned int BAR4_mem_table_index;
125
126     /* Internal registers values */
127     BAR0_t BAR0;
128     BAR2_t BAR2;
129     BAR4_t BAR4;
130
131
132     int ADDATA_FIFO[8]; /* this array tells us which ADCs are being converted */
133     unsigned int ADDATA_FIFO_POSITION; /* ADDATA is FIFO register;
134                  * We need to know, position in this FIFO =
135                  * Which value will come next */
136 } mf624_state_t;
137
138 int mf624_instance; /* Global variable shared between multiple mf624 devices */
139
140
141 static int16_t volts_to_adinternal(double volt)
142 {
143     if (volt > 9.99) {
144         volt = 9.99;
145     } else if (volt < -10) {
146         volt = -10;
147     }
148
149     return ((int16_t) ((volt*0x8000)/10))>>2;
150 }
151
152 static double dacinternal_to_volts(int16_t dacinternal)
153 {
154     return (((double)dacinternal)/0x4000)*20.0 - 10.0;
155 }
156
157 /*----------------------------------------------------------------------------*/
158
159 /* Initialize register values due to MF624 manual */
160 static void mf624_init_registers(mf624_state_t *s)
161 {
162 #define INTCSR_default_value    0x000300
163 #define GPIOC_default_value     (0x006C0 | (0x10 << 21) | (2 << 25))
164
165     /* Initialize all registers to default values */
166     s->BAR0.INTCSR = INTCSR_default_value;
167     s->BAR0.GPIOC = GPIOC_default_value;
168     s->BAR2.ADDATA = 0x0;
169     s->BAR2.ADCTRL = 0x0;
170     s->BAR2.ADDATA1 = 0x0;
171     s->BAR2.ADDATA2 = 0x0;
172     s->BAR2.ADDATA3 = 0x0;
173     s->BAR2.ADDATA4 = 0x0;
174     s->BAR2.ADDATA5 = 0x0;
175     s->BAR2.ADDATA6 = 0x0;
176     s->BAR2.ADDATA7 = 0x0;
177
178     s->BAR2.DIN = 0xFF;
179     s->BAR2.DOUT = 0x00;
180     s->BAR2.DA0 = 0x3FFF;
181     s->BAR2.DA1 = 0x3FFF;
182     s->BAR2.DA2 = 0x3FFF;
183     s->BAR2.DA3 = 0x3FFF;
184     s->BAR2.DA4 = 0x3FFF;
185     s->BAR2.DA5 = 0x3FFF;
186     s->BAR2.DA6 = 0x3FFF;
187     s->BAR2.DA7 = 0x3FFF;
188
189     s->ADDATA_FIFO_POSITION = 0;
190 }
191
192 static void
193 mf624_reset(void *opaque)
194 {
195     mf624_state_t *s = (mf624_state_t *)opaque;
196
197     mf624_init_registers(s);
198 }
199
200 /* After some widget's value is changed, new value is send via socket to QEMU */
201 static void socket_write(mf624_state_t *s, const char* reg, double val)
202 {
203     int status;
204     char write_buffer[256];
205     snprintf(write_buffer, 255, "%s=%f\n", reg, val);
206
207     status = write(s->socket_tmp, write_buffer, strlen(write_buffer));
208     if (status < 0) {
209         /* perror("write()"); */
210         printf("Error writing into socket. Is there no client connected?\n");
211     }
212 }
213
214 #define STRING_BUFF_SIZE    256
215 static void socket_read(mf624_state_t *dev)
216 {
217     /* For parsing read instructions */
218     char reg[STRING_BUFF_SIZE+1];
219     float val;
220     /* For reading from socket */
221     char read_buffer[STRING_BUFF_SIZE];
222     int received_length = 0;
223     int status;
224
225
226     while (1) {
227         memset(read_buffer, '\0', STRING_BUFF_SIZE);
228
229         received_length = read(dev->socket_tmp, read_buffer,
230                                STRING_BUFF_SIZE-1);
231
232         if (received_length < 0) {
233             perror("read()");
234             return;
235         }
236
237         if (received_length == 0) {
238             printf("Error while reading from socket. Client disconnected?\n");
239             return;
240         }
241
242         /* REG has "same size +1" as READ_BUFFER to avoid buffer overflow */
243         status = sscanf(read_buffer, "%[A-Z0-9]=%f", reg, &val);
244         if (status == 2) {
245             if (!strcmp(reg, "DIN")) {
246                 dev->BAR2.DIN = val;
247             } else if (!strcmp(reg, "ADC0")) {
248                 dev->real_world_AD0 = volts_to_adinternal(val);
249             } else if (!strcmp(reg, "ADC1")) {
250                 dev->real_world_AD1 = volts_to_adinternal(val);
251             } else if (!strcmp(reg, "ADC2")) {
252                 dev->real_world_AD2 = volts_to_adinternal(val);
253             } else if (!strcmp(reg, "ADC3")) {
254                 dev->real_world_AD3 = volts_to_adinternal(val);
255             } else if (!strcmp(reg, "ADC4")) {
256                 dev->real_world_AD4 = volts_to_adinternal(val);
257             } else if (!strcmp(reg, "ADC5")) {
258                 dev->real_world_AD5 = volts_to_adinternal(val);
259             } else if (!strcmp(reg, "ADC6")) {
260                 dev->real_world_AD6 = volts_to_adinternal(val);
261             } else if (!strcmp(reg, "ADC7")) {
262                 dev->real_world_AD7 = volts_to_adinternal(val);
263             } else {
264                 printf("reg = %s; val = %f\n", reg, val);
265             }
266         }
267     }
268 }
269
270
271 static void *init_socket(void * ptr)
272 {
273     struct sockaddr_in addr_client;
274     struct sockaddr_in addr_srv;
275     int port;
276     int yes = 1;
277
278     mf624_state_t *dev = (mf624_state_t *) ptr;
279
280     dev->socket_tmp = -1;
281     port = dev->port;
282
283     dev->socket_srv = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
284     if (dev->socket_srv == -1) {
285         perror("socket()");
286         return NULL;
287     }
288
289     if (setsockopt(dev->socket_srv,
290                    SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
291         perror("setsockopt()");
292         return NULL;
293     }
294
295
296     socklen_t len = sizeof(addr_srv);
297     memset(&addr_srv, 0, len);
298     addr_srv.sin_family = AF_INET;
299     addr_srv.sin_addr.s_addr = htonl(INADDR_ANY);
300     addr_srv.sin_port = htons(port);
301     if (bind(dev->socket_srv, (struct sockaddr *) &addr_srv, len) == -1) {
302         perror("bind()");
303         return NULL;
304     }
305
306     if (listen(dev->socket_srv, 5) == -1) {
307         perror("listen()");
308         return NULL;
309     }
310
311
312     while (1) {
313         printf("Waiting on port %d for MF624 client to connect\n", dev->port);
314         socklen_t len_client = sizeof(addr_client);
315         dev->socket_tmp = accept(dev->socket_srv,
316                                  (struct sockaddr *) &addr_client, &len_client);
317         if (dev->socket_tmp == -1) {
318             perror("accept()");
319                         return NULL;
320         }
321
322         printf("Client connected\n");
323
324         socket_read(dev); /* should run forever if everything is OK; */
325                        /* If error occurs (client disconnected), returns here */
326
327         close(dev->socket_tmp);
328     }
329
330     return NULL;
331 }
332
333 /*----------------------------------------------------------------------------*/
334
335 static void mf624_BAR0_write32(void *opaque, hwaddr addr, uint64_t value, unsigned size)
336 {
337     mf624_state_t *s = opaque;
338
339     switch (addr % BAR0_size) {
340     case INTCSR_off:
341         s->BAR0.INTCSR = (value & 0x7FF) | INTCSR_default_value; /* Only first 11 bits are writable */
342         socket_write(s, "INTCSR", s->BAR0.INTCSR);
343         break;
344
345     case GPIOC_off:
346         /* Don't write anywhere else than into these two bits */
347         s->BAR0.GPIOC = (value & (GPIOC_LDAC_mask | GPIOC_DACEN_mask)) |
348                          GPIOC_default_value;
349
350         socket_write(s, "GPIOC", s->BAR0.GPIOC);
351
352         /* Is DAC enabled & Output enabled? */
353         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
354             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
355             socket_write(s, "DA0", dacinternal_to_volts(s->BAR2.DA0));
356             socket_write(s, "DA1", dacinternal_to_volts(s->BAR2.DA1));
357             socket_write(s, "DA2", dacinternal_to_volts(s->BAR2.DA2));
358             socket_write(s, "DA3", dacinternal_to_volts(s->BAR2.DA3));
359             socket_write(s, "DA4", dacinternal_to_volts(s->BAR2.DA4));
360             socket_write(s, "DA5", dacinternal_to_volts(s->BAR2.DA5));
361             socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
362             socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
363         }
364
365         /* Is output forced to GND? */
366         if (!(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
367             #define GND     0
368             socket_write(s, "DA0", dacinternal_to_volts(GND));
369             socket_write(s, "DA1", dacinternal_to_volts(GND));
370             socket_write(s, "DA2", dacinternal_to_volts(GND));
371             socket_write(s, "DA3", dacinternal_to_volts(GND));
372             socket_write(s, "DA4", dacinternal_to_volts(GND));
373             socket_write(s, "DA5", dacinternal_to_volts(GND));
374             socket_write(s, "DA6", dacinternal_to_volts(GND));
375             socket_write(s, "DA7", dacinternal_to_volts(GND));
376         }
377         break;
378
379     default:
380         printf("mf624_BAR0_write32(): addr = " TARGET_FMT_plx
381                            "; value = 0x%" PRIx64 "\n", addr, value);
382         break;
383     }
384 }
385
386 static uint64_t mf624_BAR0_read32(void *opaque, hwaddr addr, unsigned size)
387 {
388     mf624_state_t *s = opaque;
389
390     switch (addr % BAR0_size) {
391     case INTCSR_off:
392         return s->BAR0.INTCSR;
393
394     case GPIOC_off:
395         return s->BAR0.GPIOC;
396
397     default:
398         printf("mf624_BAR0_read32(): addr = "
399                            TARGET_FMT_plx "\n", addr);
400         return 0x0;
401     }
402 }
403
404 static uint64_t mf624_BAR2_read16(void *opaque, hwaddr addr, unsigned size)
405 {
406     int i;
407     int ADDATA_val = 0xFFFF;
408     mf624_state_t *s = opaque;
409
410     switch (addr % BAR2_size) {
411     /* Reading from ADDATA FIFO register */
412     case ADDATA_off:
413     case ADDATA1_off: /* Mirrored registers */
414     case ADDATA2_off:
415     case ADDATA3_off:
416     case ADDATA4_off:
417     case ADDATA5_off:
418     case ADDATA6_off:
419     case ADDATA7_off:
420         if (!(s->BAR0.GPIOC & GPIOC_EOLC_mask)) { /* Has the conversion already ended? */
421             #define ADC_CHANNELS    8
422             for (i = s->ADDATA_FIFO_POSITION; i < ADC_CHANNELS; i++) {
423                 if (s->BAR2.ADCTRL & (1 << i)) {
424                     s->ADDATA_FIFO_POSITION = i; /* Move to next AD to be read */
425                 }
426             }
427
428             switch (s->ADDATA_FIFO_POSITION) {
429             case 0:
430                 ADDATA_val = s->BAR2.ADDATA;
431                 break;
432             case 1:
433                 ADDATA_val = s->BAR2.ADDATA1;
434                 break;
435             case 2:
436                 ADDATA_val = s->BAR2.ADDATA2;
437                 break;
438             case 3:
439                 ADDATA_val = s->BAR2.ADDATA3;
440                 break;
441             case 4:
442                 ADDATA_val = s->BAR2.ADDATA4;
443                 break;
444             case 5:
445                 ADDATA_val = s->BAR2.ADDATA5;
446                 break;
447             case 6:
448                 ADDATA_val = s->BAR2.ADDATA6;
449                 break;
450             case 7:
451                 ADDATA_val = s->BAR2.ADDATA7;
452                 break;
453             default: /* restart counter */
454                 s->ADDATA_FIFO_POSITION = 0;
455                 ADDATA_val = s->BAR2.ADDATA;
456                 break;
457             }
458             s->ADDATA_FIFO_POSITION++;
459             return ADDATA_val;
460         }
461         return 0xFFFF; /* Semirandom value */
462
463     /* Digital Input*/
464     case DIN_off:
465         return s->BAR2.DIN;
466
467     /* A/D Conversion Start. Reading this register triggers A/D
468     conversion for all channels selected in ADCTRL. */
469     case ADSTART_off:
470         s->BAR0.GPIOC |= GPIOC_EOLC_mask; /* Conversion in progress */
471         s->ADDATA_FIFO_POSITION = 0;
472
473         /* Simulation of the time delay of real conversion should be implemented there */
474
475         /* Check before assignement, if particular ADC is enabled */
476         s->BAR2.ADDATA  = (s->BAR2.ADCTRL & (1 << 0)) ?
477                               s->real_world_AD0 : s->BAR2.ADDATA;
478         s->BAR2.ADDATA1 = (s->BAR2.ADCTRL & (1 << 1)) ?
479                               s->real_world_AD1 : s->BAR2.ADDATA1;
480         s->BAR2.ADDATA2 = (s->BAR2.ADCTRL & (1 << 2)) ?
481                               s->real_world_AD2 : s->BAR2.ADDATA2;
482         s->BAR2.ADDATA3 = (s->BAR2.ADCTRL & (1 << 3)) ?
483                               s->real_world_AD3 : s->BAR2.ADDATA3;
484         s->BAR2.ADDATA4 = (s->BAR2.ADCTRL & (1 << 4)) ?
485                               s->real_world_AD4 : s->BAR2.ADDATA4;
486         s->BAR2.ADDATA5 = (s->BAR2.ADCTRL & (1 << 5)) ?
487                               s->real_world_AD5 : s->BAR2.ADDATA5;
488         s->BAR2.ADDATA6 = (s->BAR2.ADCTRL & (1 << 6)) ?
489                               s->real_world_AD6 : s->BAR2.ADDATA6;
490         s->BAR2.ADDATA7 = (s->BAR2.ADCTRL & (1 << 7)) ?
491                               s->real_world_AD7 : s->BAR2.ADDATA7;
492
493         /* All channels converted */
494         s->BAR0.GPIOC &= ~GPIOC_EOLC_mask;
495
496         return 0xFFFF; /* Semirandom value */
497
498     default:
499         printf("mf624_BAR2_read16(): addr = "
500                            TARGET_FMT_plx "\n", addr);
501         return 0x0;
502     }
503 }
504
505 static void mf624_BAR2_write16(void *opaque, hwaddr addr, uint64_t value, unsigned size)
506 {
507     mf624_state_t *s = opaque;
508
509     switch (addr % BAR2_size) {
510     case ADCTRL_off:
511         s->BAR2.ADCTRL = value;
512         socket_write(s, "ADCTRL", s->BAR2.ADCTRL);
513         break;
514
515     case DOUT_off:
516         s->BAR2.DOUT = value;
517         socket_write(s, "DOUT", s->BAR2.DOUT);
518         break;
519
520     case DA0_off:
521         s->BAR2.DA0 = value;
522         /* Is DAC enabled & Output enabled? */
523         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
524             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
525             socket_write(s, "DA0", dacinternal_to_volts(s->BAR2.DA0));
526         }
527         break;
528
529     case DA1_off:
530         s->BAR2.DA1 = value;
531         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
532             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
533             socket_write(s, "DA1", dacinternal_to_volts(s->BAR2.DA1));
534         }
535         break;
536
537     case DA2_off:
538         s->BAR2.DA2 = value;
539         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
540             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
541             socket_write(s, "DA2", dacinternal_to_volts(s->BAR2.DA2));
542         }
543         break;
544
545     case DA3_off:
546         s->BAR2.DA3 = value;
547         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
548             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
549             socket_write(s, "DA3", dacinternal_to_volts(s->BAR2.DA3));
550         }
551         break;
552
553     case DA4_off:
554         s->BAR2.DA4 = value;
555         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
556             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
557             socket_write(s, "DA4", dacinternal_to_volts(s->BAR2.DA4));
558         }
559         break;
560
561     case DA5_off:
562         s->BAR2.DA5 = value;
563         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
564             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
565             socket_write(s, "DA5", dacinternal_to_volts(s->BAR2.DA5));
566         }
567         break;
568
569     case DA6_off:
570         s->BAR2.DA6 = value;
571         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
572             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
573             socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
574         }
575         break;
576
577     case DA7_off:
578         s->BAR2.DA7 = value;
579         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
580             (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
581             socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
582         }
583         break;
584
585     default:
586         printf("mf624_BAR2_write16(): addr = " TARGET_FMT_plx
587                            "; value = 0x%" PRIx64 "\n", addr, value);
588         break;
589     }
590 }
591
592 static void mf624_BAR4_write32(void *opaque, hwaddr addr, uint64_t value, unsigned size)
593 {
594     printf("mf624_BAR4_write32(): addr = " TARGET_FMT_plx
595                "; value = 0x%" PRIx64 "\n", addr, value);
596 }
597
598 static uint64_t mf624_BAR4_read32(void *opaque, hwaddr addr, unsigned size)
599 {
600     printf("mf624_BAR4_read32(): addr = " TARGET_FMT_plx "\n", addr);
601     return 0x0;
602 }
603
604 /*----------------------------------------------------------------------------*/
605
606 static const MemoryRegionOps mf624_BAR0_mmio_ops = {
607     .read = mf624_BAR0_read32,
608     .write = mf624_BAR0_write32,
609     .endianness = DEVICE_LITTLE_ENDIAN,
610     .impl = {
611         .min_access_size = 4,
612         .max_access_size = 4,
613     },
614 };
615
616 static const MemoryRegionOps mf624_BAR2_mmio_ops = {
617     .read = mf624_BAR2_read16,
618     .write = mf624_BAR2_write16,
619     .endianness = DEVICE_LITTLE_ENDIAN,
620     .impl = {
621         .min_access_size = 2,
622         .max_access_size = 2,
623     },
624 };
625
626 static const MemoryRegionOps mf624_BAR4_mmio_ops = {
627     .read = mf624_BAR4_read32,
628     .write = mf624_BAR4_write32,
629     .endianness = DEVICE_LITTLE_ENDIAN,
630     .impl = {
631         .min_access_size = 4,
632         .max_access_size = 4,
633     },
634 };
635
636 #define DEFAULT_PORT            55555
637 static int mf624_init(PCIDevice *pci_dev)
638 {
639     mf624_state_t *s = MF624_DEV(pci_dev); /* alocation of mf624_state_t */
640     uint8_t *pci_conf;
641
642     if (s->port == DEFAULT_PORT) {
643         s->port += mf624_instance; /* Each instance of the same device should have another port number */
644         mf624_instance++;
645     }
646
647     /* Set all internal registers to default values */
648     mf624_init_registers(s);
649
650     pci_conf = pci_dev->config;
651     pci_conf[PCI_INTERRUPT_PIN] = 0x1; /* interrupt pin 0 */
652
653     s->irq = pci_allocate_irq(&s->dev);
654
655     qemu_register_reset(mf624_reset, s);
656
657     memory_region_init_io(&s->mmio_bar0, OBJECT(s), &mf624_BAR0_mmio_ops, s, "mf624_bar0", BAR0_size);
658     memory_region_init_io(&s->mmio_bar2, OBJECT(s), &mf624_BAR2_mmio_ops, s, "mf624_bar2", BAR2_size);
659     memory_region_init_io(&s->mmio_bar4, OBJECT(s), &mf624_BAR4_mmio_ops, s, "mf624_bar4", BAR4_size);
660     pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar0);
661     pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar2);
662     pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar4);
663
664     /* Create thread, which will be blocked on reading from socket (connected to "I/O GUI") */
665
666     qemu_thread_create(&s->socket_thread, "mf624_io_thread",
667                        init_socket, (void *) s, QEMU_THREAD_JOINABLE);
668     return 0;
669 }
670
671 static void qdev_mf624_reset(DeviceState *dev)
672 {
673     mf624_state_t *s = MF624_DEV(dev);
674     mf624_init_registers(s);
675 }
676
677 static void mf624_exit(PCIDevice *pci_dev)
678 {
679     mf624_state_t *s = MF624_DEV(pci_dev);
680
681     close(s->socket_srv);
682
683     qemu_thread_join(&s->socket_thread);
684
685     qemu_unregister_reset(mf624_reset, s);
686
687     memory_region_destroy(&s->mmio_bar0);
688     memory_region_destroy(&s->mmio_bar2);
689     memory_region_destroy(&s->mmio_bar4);
690
691     qemu_free_irq(s->irq);
692 }
693
694 static const VMStateDescription vmstate_mf624 = {
695     .name = "mf624",
696     .version_id = 1,
697     .minimum_version_id = 1,
698     .minimum_version_id_old = 1,
699
700     .fields = (VMStateField[]) {
701         VMSTATE_PCI_DEVICE(dev, mf624_state_t),
702         VMSTATE_UINT32(port, mf624_state_t),
703         VMSTATE_END_OF_LIST()
704     }
705
706 };
707
708 static Property mf624_properties[] = {
709     DEFINE_PROP_UINT32("port", mf624_state_t, port, DEFAULT_PORT),
710     DEFINE_PROP_END_OF_LIST(),
711 };
712
713 static void mf624_class_init(ObjectClass *klass, void *data)
714 {
715     DeviceClass *dc = DEVICE_CLASS(klass);
716     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
717
718     k->init = mf624_init;
719     k->exit = mf624_exit;
720     k->vendor_id = PCI_VENDOR_ID_HUMUSOFT;
721     k->device_id = PCI_DEVICE_ID_MF624;
722     k->revision = 0x00;
723     k->class_id = PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER;
724     k->subsystem_vendor_id = PCI_VENDOR_ID_HUMUSOFT;
725     k->subsystem_id = PCI_DEVICE_ID_MF624;
726     dc->desc = "Humusoft MF624";
727     dc->props = mf624_properties;
728     dc->vmsd = &vmstate_mf624;
729     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
730     dc->reset = qdev_mf624_reset;
731 }
732
733 static const TypeInfo mf624_info = {
734     .name          = TYPE_MF624_DEV,
735     .parent        = TYPE_PCI_DEVICE,
736     .instance_size = sizeof(mf624_state_t),
737     .class_init    = mf624_class_init,
738 };
739
740 static void mf624_register_types(void)
741 {
742     type_register_static(&mf624_info);
743 }
744
745 type_init(mf624_register_types)