Commit a984a69e570d7639dba3f0b4a21b5169955162e4

Authored by Paul Brook
1 parent 5493e33f

PXA SSI qdev conversion

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/ads7846.c
@@ -7,11 +7,11 @@ @@ -7,11 +7,11 @@
7 * This code is licensed under the GNU GPL v2. 7 * This code is licensed under the GNU GPL v2.
8 */ 8 */
9 9
10 -#include "hw.h"  
11 -#include "devices.h" 10 +#include "ssi.h"
12 #include "console.h" 11 #include "console.h"
13 12
14 -struct ADS7846State { 13 +typedef struct {
  14 + SSISlave ssidev;
15 qemu_irq interrupt; 15 qemu_irq interrupt;
16 16
17 int input[8]; 17 int input[8];
@@ -20,7 +20,7 @@ struct ADS7846State { @@ -20,7 +20,7 @@ struct ADS7846State {
20 20
21 int cycle; 21 int cycle;
22 int output; 22 int output;
23 -}; 23 +} ADS7846State;
24 24
25 /* Control-byte bitfields */ 25 /* Control-byte bitfields */
26 #define CB_PD0 (1 << 0) 26 #define CB_PD0 (1 << 0)
@@ -52,16 +52,9 @@ static void ads7846_int_update(ADS7846State *s) @@ -52,16 +52,9 @@ static void ads7846_int_update(ADS7846State *s)
52 qemu_set_irq(s->interrupt, s->pressure == 0); 52 qemu_set_irq(s->interrupt, s->pressure == 0);
53 } 53 }
54 54
55 -uint32_t ads7846_read(void *opaque)  
56 -{  
57 - ADS7846State *s = (ADS7846State *) opaque;  
58 -  
59 - return s->output;  
60 -}  
61 -  
62 -void ads7846_write(void *opaque, uint32_t value) 55 +static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
63 { 56 {
64 - ADS7846State *s = (ADS7846State *) opaque; 57 + ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
65 58
66 switch (s->cycle ++) { 59 switch (s->cycle ++) {
67 case 0: 60 case 0:
@@ -89,6 +82,7 @@ void ads7846_write(void *opaque, uint32_t value) @@ -89,6 +82,7 @@ void ads7846_write(void *opaque, uint32_t value)
89 s->cycle = 0; 82 s->cycle = 0;
90 break; 83 break;
91 } 84 }
  85 + return s->output;
92 } 86 }
93 87
94 static void ads7846_ts_event(void *opaque, 88 static void ads7846_ts_event(void *opaque,
@@ -140,14 +134,11 @@ static int ads7846_load(QEMUFile *f, void *opaque, int version_id) @@ -140,14 +134,11 @@ static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
140 return 0; 134 return 0;
141 } 135 }
142 136
143 -ADS7846State *ads7846_init(qemu_irq penirq) 137 +static void ads7846_init(SSISlave *dev)
144 { 138 {
145 - ADS7846State *s;  
146 - s = (ADS7846State *)  
147 - qemu_mallocz(sizeof(ADS7846State));  
148 - memset(s, 0, sizeof(ADS7846State)); 139 + ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
149 140
150 - s->interrupt = penirq; 141 + qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
151 142
152 s->input[0] = ADS_TEMP0; /* TEMP0 */ 143 s->input[0] = ADS_TEMP0; /* TEMP0 */
153 s->input[2] = ADS_VBAT; /* VBAT */ 144 s->input[2] = ADS_VBAT; /* VBAT */
@@ -161,6 +152,16 @@ ADS7846State *ads7846_init(qemu_irq penirq) @@ -161,6 +152,16 @@ ADS7846State *ads7846_init(qemu_irq penirq)
161 ads7846_int_update(s); 152 ads7846_int_update(s);
162 153
163 register_savevm("ads7846", -1, 0, ads7846_save, ads7846_load, s); 154 register_savevm("ads7846", -1, 0, ads7846_save, ads7846_load, s);
  155 +}
164 156
165 - return s; 157 +static SSISlaveInfo ads7846_info = {
  158 + .init = ads7846_init,
  159 + .transfer = ads7846_transfer
  160 +};
  161 +
  162 +static void ads7846_register_devices(void)
  163 +{
  164 + ssi_register_slave("ads7846", sizeof(ADS7846State), &ads7846_info);
166 } 165 }
  166 +
  167 +device_init(ads7846_register_devices)
hw/devices.h
@@ -6,12 +6,6 @@ @@ -6,12 +6,6 @@
6 /* smc91c111.c */ 6 /* smc91c111.c */
7 void smc91c111_init(NICInfo *, uint32_t, qemu_irq); 7 void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
8 8
9 -/* ads7846.c */  
10 -typedef struct ADS7846State ADS7846State;  
11 -uint32_t ads7846_read(void *opaque);  
12 -void ads7846_write(void *opaque, uint32_t value);  
13 -ADS7846State *ads7846_init(qemu_irq penirq);  
14 -  
15 /* tsc210x.c */ 9 /* tsc210x.c */
16 uWireSlave *tsc2102_init(qemu_irq pint); 10 uWireSlave *tsc2102_init(qemu_irq pint);
17 uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav); 11 uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
hw/i2c.h
@@ -61,14 +61,6 @@ void i2c_register_slave(const char *name, int size, I2CSlaveInfo *type); @@ -61,14 +61,6 @@ void i2c_register_slave(const char *name, int size, I2CSlaveInfo *type);
61 61
62 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr); 62 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr);
63 63
64 -/* max111x.c */  
65 -typedef struct MAX111xState MAX111xState;  
66 -uint32_t max111x_read(void *opaque);  
67 -void max111x_write(void *opaque, uint32_t value);  
68 -MAX111xState *max1110_init(qemu_irq cb);  
69 -MAX111xState *max1111_init(qemu_irq cb);  
70 -void max111x_set_input(MAX111xState *s, int line, uint8_t value);  
71 -  
72 /* max7310.c */ 64 /* max7310.c */
73 void max7310_reset(i2c_slave *i2c); 65 void max7310_reset(i2c_slave *i2c);
74 qemu_irq *max7310_gpio_in_get(i2c_slave *i2c); 66 qemu_irq *max7310_gpio_in_get(i2c_slave *i2c);
hw/max111x.c
@@ -7,17 +7,17 @@ @@ -7,17 +7,17 @@
7 * This code is licensed under the GNU GPLv2. 7 * This code is licensed under the GNU GPLv2.
8 */ 8 */
9 9
10 -#include "hw.h"  
11 -#include "i2c.h" 10 +#include "ssi.h"
12 11
13 -struct MAX111xState { 12 +typedef struct {
  13 + SSISlave ssidev;
14 qemu_irq interrupt; 14 qemu_irq interrupt;
15 uint8_t tb1, rb2, rb3; 15 uint8_t tb1, rb2, rb3;
16 int cycle; 16 int cycle;
17 17
18 int input[8]; 18 int input[8];
19 int inputs, com; 19 int inputs, com;
20 -}; 20 +} MAX111xState;
21 21
22 /* Control-byte bitfields */ 22 /* Control-byte bitfields */
23 #define CB_PD0 (1 << 0) 23 #define CB_PD0 (1 << 0)
@@ -34,10 +34,8 @@ struct MAX111xState { @@ -34,10 +34,8 @@ struct MAX111xState {
34 (((v) >> (3 + (b1))) & 2) | \ 34 (((v) >> (3 + (b1))) & 2) | \
35 (((v) >> (4 + (b2))) & 1)) 35 (((v) >> (4 + (b2))) & 1))
36 36
37 -uint32_t max111x_read(void *opaque) 37 +static uint32_t max111x_read(MAX111xState *s)
38 { 38 {
39 - MAX111xState *s = (MAX111xState *) opaque;  
40 -  
41 if (!s->tb1) 39 if (!s->tb1)
42 return 0; 40 return 0;
43 41
@@ -52,9 +50,8 @@ uint32_t max111x_read(void *opaque) @@ -52,9 +50,8 @@ uint32_t max111x_read(void *opaque)
52 } 50 }
53 51
54 /* Interpret a control-byte */ 52 /* Interpret a control-byte */
55 -void max111x_write(void *opaque, uint32_t value) 53 +static void max111x_write(MAX111xState *s, uint32_t value)
56 { 54 {
57 - MAX111xState *s = (MAX111xState *) opaque;  
58 int measure, chan; 55 int measure, chan;
59 56
60 /* Ignore the value if START bit is zero */ 57 /* Ignore the value if START bit is zero */
@@ -86,8 +83,15 @@ void max111x_write(void *opaque, uint32_t value) @@ -86,8 +83,15 @@ void max111x_write(void *opaque, uint32_t value)
86 s->rb2 = (measure >> 2) & 0x3f; 83 s->rb2 = (measure >> 2) & 0x3f;
87 s->rb3 = (measure << 6) & 0xc0; 84 s->rb3 = (measure << 6) & 0xc0;
88 85
89 - if (s->interrupt)  
90 - qemu_irq_raise(s->interrupt); 86 + /* FIXME: When should the IRQ be lowered? */
  87 + qemu_irq_raise(s->interrupt);
  88 +}
  89 +
  90 +static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
  91 +{
  92 + MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
  93 + max111x_write(s, value);
  94 + return max111x_read(s);
91 } 95 }
92 96
93 static void max111x_save(QEMUFile *f, void *opaque) 97 static void max111x_save(QEMUFile *f, void *opaque)
@@ -121,15 +125,13 @@ static int max111x_load(QEMUFile *f, void *opaque, int version_id) @@ -121,15 +125,13 @@ static int max111x_load(QEMUFile *f, void *opaque, int version_id)
121 return 0; 125 return 0;
122 } 126 }
123 127
124 -static MAX111xState *max111x_init(qemu_irq cb) 128 +static void max111x_init(SSISlave *dev, int inputs)
125 { 129 {
126 - MAX111xState *s;  
127 - s = (MAX111xState *)  
128 - qemu_mallocz(sizeof(MAX111xState));  
129 - memset(s, 0, sizeof(MAX111xState)); 130 + MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
130 131
131 - s->interrupt = cb; 132 + qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
132 133
  134 + s->inputs = inputs;
133 /* TODO: add a user interface for setting these */ 135 /* TODO: add a user interface for setting these */
134 s->input[0] = 0xf0; 136 s->input[0] = 0xf0;
135 s->input[1] = 0xe0; 137 s->input[1] = 0xe0;
@@ -142,30 +144,39 @@ static MAX111xState *max111x_init(qemu_irq cb) @@ -142,30 +144,39 @@ static MAX111xState *max111x_init(qemu_irq cb)
142 s->com = 0; 144 s->com = 0;
143 145
144 register_savevm("max111x", -1, 0, max111x_save, max111x_load, s); 146 register_savevm("max111x", -1, 0, max111x_save, max111x_load, s);
145 -  
146 - return s;  
147 } 147 }
148 148
149 -MAX111xState *max1110_init(qemu_irq cb) 149 +static void max1110_init(SSISlave *dev)
150 { 150 {
151 - MAX111xState *s = max111x_init(cb);  
152 - s->inputs = 8;  
153 - return s; 151 + max111x_init(dev, 8);
154 } 152 }
155 153
156 -MAX111xState *max1111_init(qemu_irq cb) 154 +static void max1111_init(SSISlave *dev)
157 { 155 {
158 - MAX111xState *s = max111x_init(cb);  
159 - s->inputs = 4;  
160 - return s; 156 + max111x_init(dev, 4);
161 } 157 }
162 158
163 -void max111x_set_input(MAX111xState *s, int line, uint8_t value) 159 +void max111x_set_input(DeviceState *dev, int line, uint8_t value)
164 { 160 {
165 - if (line >= s->inputs) {  
166 - printf("%s: There's no input %i\n", __FUNCTION__, line);  
167 - return;  
168 - }  
169 - 161 + MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, SSI_SLAVE_FROM_QDEV(dev));
  162 + assert(line >= 0 && line < s->inputs);
170 s->input[line] = value; 163 s->input[line] = value;
171 } 164 }
  165 +
  166 +static SSISlaveInfo max1110_info = {
  167 + .init = max1110_init,
  168 + .transfer = max111x_transfer
  169 +};
  170 +
  171 +static SSISlaveInfo max1111_info = {
  172 + .init = max1111_init,
  173 + .transfer = max111x_transfer
  174 +};
  175 +
  176 +static void max111x_register_devices(void)
  177 +{
  178 + ssi_register_slave("max1110", sizeof(MAX111xState), &max1110_info);
  179 + ssi_register_slave("max1111", sizeof(MAX111xState), &max1111_info);
  180 +}
  181 +
  182 +device_init(max111x_register_devices)
hw/pxa.h
@@ -119,11 +119,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map, @@ -119,11 +119,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
119 int size); 119 int size);
120 120
121 /* pxa2xx.c */ 121 /* pxa2xx.c */
122 -typedef struct PXA2xxSSPState PXA2xxSSPState;  
123 -void pxa2xx_ssp_attach(PXA2xxSSPState *port,  
124 - uint32_t (*readfn)(void *opaque),  
125 - void (*writefn)(void *opaque, uint32_t value), void *opaque);  
126 -  
127 typedef struct PXA2xxI2CState PXA2xxI2CState; 122 typedef struct PXA2xxI2CState PXA2xxI2CState;
128 PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base, 123 PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
129 qemu_irq irq, uint32_t page_size); 124 qemu_irq irq, uint32_t page_size);
@@ -139,7 +134,7 @@ typedef struct { @@ -139,7 +134,7 @@ typedef struct {
139 PXA2xxDMAState *dma; 134 PXA2xxDMAState *dma;
140 PXA2xxGPIOInfo *gpio; 135 PXA2xxGPIOInfo *gpio;
141 PXA2xxLCDState *lcd; 136 PXA2xxLCDState *lcd;
142 - PXA2xxSSPState **ssp; 137 + SSIBus **ssp;
143 PXA2xxI2CState *i2c[2]; 138 PXA2xxI2CState *i2c[2];
144 PXA2xxMMCIState *mmc; 139 PXA2xxMMCIState *mmc;
145 PXA2xxPCMCIAState *pcmcia[2]; 140 PXA2xxPCMCIAState *pcmcia[2];
hw/pxa2xx.c
@@ -7,11 +7,12 @@ @@ -7,11 +7,12 @@
7 * This code is licenced under the GPL. 7 * This code is licenced under the GPL.
8 */ 8 */
9 9
10 -#include "hw.h" 10 +#include "sysbus.h"
11 #include "pxa.h" 11 #include "pxa.h"
12 #include "sysemu.h" 12 #include "sysemu.h"
13 #include "pc.h" 13 #include "pc.h"
14 #include "i2c.h" 14 #include "i2c.h"
  15 +#include "ssi.h"
15 #include "qemu-timer.h" 16 #include "qemu-timer.h"
16 #include "qemu-char.h" 17 #include "qemu-char.h"
17 18
@@ -547,9 +548,11 @@ static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id) @@ -547,9 +548,11 @@ static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id)
547 } 548 }
548 549
549 /* Synchronous Serial Ports */ 550 /* Synchronous Serial Ports */
550 -struct PXA2xxSSPState { 551 +typedef struct {
  552 + SysBusDevice busdev;
551 qemu_irq irq; 553 qemu_irq irq;
552 int enable; 554 int enable;
  555 + SSIBus *bus;
553 556
554 uint32_t sscr[2]; 557 uint32_t sscr[2];
555 uint32_t sspsp; 558 uint32_t sspsp;
@@ -563,11 +566,7 @@ struct PXA2xxSSPState { @@ -563,11 +566,7 @@ struct PXA2xxSSPState {
563 uint32_t rx_fifo[16]; 566 uint32_t rx_fifo[16];
564 int rx_level; 567 int rx_level;
565 int rx_start; 568 int rx_start;
566 -  
567 - uint32_t (*readfn)(void *opaque);  
568 - void (*writefn)(void *opaque, uint32_t value);  
569 - void *opaque;  
570 -}; 569 +} PXA2xxSSPState;
571 570
572 #define SSCR0 0x00 /* SSP Control register 0 */ 571 #define SSCR0 0x00 /* SSP Control register 0 */
573 #define SSCR1 0x04 /* SSP Control register 1 */ 572 #define SSCR1 0x04 /* SSP Control register 1 */
@@ -763,17 +762,13 @@ static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr, @@ -763,17 +762,13 @@ static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr,
763 * there directly to the slave, no need to buffer it. 762 * there directly to the slave, no need to buffer it.
764 */ 763 */
765 if (s->enable) { 764 if (s->enable) {
766 - if (s->writefn)  
767 - s->writefn(s->opaque, value);  
768 - 765 + uint32_t readval;
  766 + readval = ssi_transfer(s->bus, value);
769 if (s->rx_level < 0x10) { 767 if (s->rx_level < 0x10) {
770 - if (s->readfn)  
771 - s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] =  
772 - s->readfn(s->opaque);  
773 - else  
774 - s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = 0x0;  
775 - } else 768 + s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = readval;
  769 + } else {
776 s->sssr |= SSSR_ROR; 770 s->sssr |= SSSR_ROR;
  771 + }
777 } 772 }
778 pxa2xx_ssp_fifo_update(s); 773 pxa2xx_ssp_fifo_update(s);
779 break; 774 break;
@@ -796,20 +791,6 @@ static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr, @@ -796,20 +791,6 @@ static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr,
796 } 791 }
797 } 792 }
798 793
799 -void pxa2xx_ssp_attach(PXA2xxSSPState *port,  
800 - uint32_t (*readfn)(void *opaque),  
801 - void (*writefn)(void *opaque, uint32_t value), void *opaque)  
802 -{  
803 - if (!port) {  
804 - printf("%s: no such SSP\n", __FUNCTION__);  
805 - exit(-1);  
806 - }  
807 -  
808 - port->opaque = opaque;  
809 - port->readfn = readfn;  
810 - port->writefn = writefn;  
811 -}  
812 -  
813 static CPUReadMemoryFunc *pxa2xx_ssp_readfn[] = { 794 static CPUReadMemoryFunc *pxa2xx_ssp_readfn[] = {
814 pxa2xx_ssp_read, 795 pxa2xx_ssp_read,
815 pxa2xx_ssp_read, 796 pxa2xx_ssp_read,
@@ -869,6 +850,23 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id) @@ -869,6 +850,23 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
869 return 0; 850 return 0;
870 } 851 }
871 852
  853 +static void pxa2xx_ssp_init(SysBusDevice *dev)
  854 +{
  855 + int iomemtype;
  856 + PXA2xxSSPState *s = FROM_SYSBUS(PXA2xxSSPState, dev);
  857 +
  858 + sysbus_init_irq(dev, &s->irq);
  859 +
  860 + iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
  861 + pxa2xx_ssp_writefn, s);
  862 + sysbus_init_mmio(dev, 0x1000, iomemtype);
  863 + register_savevm("pxa2xx_ssp", -1, 0,
  864 + pxa2xx_ssp_save, pxa2xx_ssp_load, s);
  865 +
  866 + s->bus = ssi_create_bus();
  867 + qdev_attach_child_bus(&dev->qdev, "ssi", s->bus);
  868 +}
  869 +
872 /* Real-Time Clock */ 870 /* Real-Time Clock */
873 #define RCNR 0x00 /* RTC Counter register */ 871 #define RCNR 0x00 /* RTC Counter register */
874 #define RTAR 0x04 /* RTC Alarm register */ 872 #define RTAR 0x04 /* RTC Alarm register */
@@ -2034,7 +2032,6 @@ static void pxa2xx_reset(void *opaque, int line, int level) @@ -2034,7 +2032,6 @@ static void pxa2xx_reset(void *opaque, int line, int level)
2034 PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) 2032 PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
2035 { 2033 {
2036 PXA2xxState *s; 2034 PXA2xxState *s;
2037 - PXA2xxSSPState *ssp;  
2038 int iomemtype, i; 2035 int iomemtype, i;
2039 int index; 2036 int index;
2040 s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState)); 2037 s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
@@ -2115,21 +2112,12 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) @@ -2115,21 +2112,12 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
2115 register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); 2112 register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
2116 2113
2117 for (i = 0; pxa27x_ssp[i].io_base; i ++); 2114 for (i = 0; pxa27x_ssp[i].io_base; i ++);
2118 - s->ssp = (PXA2xxSSPState **)  
2119 - qemu_mallocz(sizeof(PXA2xxSSPState *) * i);  
2120 - ssp = (PXA2xxSSPState *)  
2121 - qemu_mallocz(sizeof(PXA2xxSSPState) * i); 2115 + s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
2122 for (i = 0; pxa27x_ssp[i].io_base; i ++) { 2116 for (i = 0; pxa27x_ssp[i].io_base; i ++) {
2123 - target_phys_addr_t ssp_base;  
2124 - s->ssp[i] = &ssp[i];  
2125 - ssp_base = pxa27x_ssp[i].io_base;  
2126 - ssp[i].irq = s->pic[pxa27x_ssp[i].irqn];  
2127 -  
2128 - iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,  
2129 - pxa2xx_ssp_writefn, &ssp[i]);  
2130 - cpu_register_physical_memory(ssp_base, 0x1000, iomemtype);  
2131 - register_savevm("pxa2xx_ssp", i, 0,  
2132 - pxa2xx_ssp_save, pxa2xx_ssp_load, s); 2117 + DeviceState *dev;
  2118 + dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base,
  2119 + s->pic[pxa27x_ssp[i].irqn]);
  2120 + s->ssp[i] = qdev_get_child_bus(dev, "ssi");
2133 } 2121 }
2134 2122
2135 if (usb_enabled) { 2123 if (usb_enabled) {
@@ -2163,7 +2151,6 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) @@ -2163,7 +2151,6 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
2163 PXA2xxState *pxa255_init(unsigned int sdram_size) 2151 PXA2xxState *pxa255_init(unsigned int sdram_size)
2164 { 2152 {
2165 PXA2xxState *s; 2153 PXA2xxState *s;
2166 - PXA2xxSSPState *ssp;  
2167 int iomemtype, i; 2154 int iomemtype, i;
2168 int index; 2155 int index;
2169 2156
@@ -2237,21 +2224,12 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) @@ -2237,21 +2224,12 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
2237 register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); 2224 register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
2238 2225
2239 for (i = 0; pxa255_ssp[i].io_base; i ++); 2226 for (i = 0; pxa255_ssp[i].io_base; i ++);
2240 - s->ssp = (PXA2xxSSPState **)  
2241 - qemu_mallocz(sizeof(PXA2xxSSPState *) * i);  
2242 - ssp = (PXA2xxSSPState *)  
2243 - qemu_mallocz(sizeof(PXA2xxSSPState) * i); 2227 + s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
2244 for (i = 0; pxa255_ssp[i].io_base; i ++) { 2228 for (i = 0; pxa255_ssp[i].io_base; i ++) {
2245 - target_phys_addr_t ssp_base;  
2246 - s->ssp[i] = &ssp[i];  
2247 - ssp_base = pxa255_ssp[i].io_base;  
2248 - ssp[i].irq = s->pic[pxa255_ssp[i].irqn];  
2249 -  
2250 - iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,  
2251 - pxa2xx_ssp_writefn, &ssp[i]);  
2252 - cpu_register_physical_memory(ssp_base, 0x1000, iomemtype);  
2253 - register_savevm("pxa2xx_ssp", i, 0,  
2254 - pxa2xx_ssp_save, pxa2xx_ssp_load, s); 2229 + DeviceState *dev;
  2230 + dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,
  2231 + s->pic[pxa255_ssp[i].irqn]);
  2232 + s->ssp[i] = qdev_get_child_bus(dev, "ssi");
2255 } 2233 }
2256 2234
2257 if (usb_enabled) { 2235 if (usb_enabled) {
@@ -2283,6 +2261,7 @@ static void pxa2xx_register_devices(void) @@ -2283,6 +2261,7 @@ static void pxa2xx_register_devices(void)
2283 { 2261 {
2284 i2c_register_slave("pxa2xx-i2c-slave", sizeof(PXA2xxI2CSlaveState), 2262 i2c_register_slave("pxa2xx-i2c-slave", sizeof(PXA2xxI2CSlaveState),
2285 &pxa2xx_i2c_slave_info); 2263 &pxa2xx_i2c_slave_info);
  2264 + sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init);
2286 } 2265 }
2287 2266
2288 device_init(pxa2xx_register_devices) 2267 device_init(pxa2xx_register_devices)
hw/spitz.c
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 #include "sysemu.h" 13 #include "sysemu.h"
14 #include "pcmcia.h" 14 #include "pcmcia.h"
15 #include "i2c.h" 15 #include "i2c.h"
  16 +#include "ssi.h"
16 #include "flash.h" 17 #include "flash.h"
17 #include "qemu-timer.h" 18 #include "qemu-timer.h"
18 #include "devices.h" 19 #include "devices.h"
@@ -525,40 +526,50 @@ static void spitz_keyboard_register(PXA2xxState *cpu) @@ -525,40 +526,50 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
525 #define LCDTG_PICTRL 0x06 526 #define LCDTG_PICTRL 0x06
526 #define LCDTG_POLCTRL 0x07 527 #define LCDTG_POLCTRL 0x07
527 528
528 -static int bl_intensity, bl_power; 529 +typedef struct {
  530 + SSISlave ssidev;
  531 + int bl_intensity;
  532 + int bl_power;
  533 +} SpitzLCDTG;
529 534
530 -static void spitz_bl_update(PXA2xxState *s) 535 +static void spitz_bl_update(SpitzLCDTG *s)
531 { 536 {
532 - if (bl_power && bl_intensity)  
533 - zaurus_printf("LCD Backlight now at %i/63\n", bl_intensity); 537 + if (s->bl_power && s->bl_intensity)
  538 + zaurus_printf("LCD Backlight now at %i/63\n", s->bl_intensity);
534 else 539 else
535 zaurus_printf("LCD Backlight now off\n"); 540 zaurus_printf("LCD Backlight now off\n");
536 } 541 }
537 542
  543 +/* FIXME: Implement GPIO properly and remove this hack. */
  544 +static SpitzLCDTG *spitz_lcdtg;
  545 +
538 static inline void spitz_bl_bit5(void *opaque, int line, int level) 546 static inline void spitz_bl_bit5(void *opaque, int line, int level)
539 { 547 {
540 - int prev = bl_intensity; 548 + SpitzLCDTG *s = spitz_lcdtg;
  549 + int prev = s->bl_intensity;
541 550
542 if (level) 551 if (level)
543 - bl_intensity &= ~0x20; 552 + s->bl_intensity &= ~0x20;
544 else 553 else
545 - bl_intensity |= 0x20; 554 + s->bl_intensity |= 0x20;
546 555
547 - if (bl_power && prev != bl_intensity)  
548 - spitz_bl_update((PXA2xxState *) opaque); 556 + if (s->bl_power && prev != s->bl_intensity)
  557 + spitz_bl_update(s);
549 } 558 }
550 559
551 static inline void spitz_bl_power(void *opaque, int line, int level) 560 static inline void spitz_bl_power(void *opaque, int line, int level)
552 { 561 {
553 - bl_power = !!level;  
554 - spitz_bl_update((PXA2xxState *) opaque); 562 + SpitzLCDTG *s = spitz_lcdtg;
  563 + s->bl_power = !!level;
  564 + spitz_bl_update(s);
555 } 565 }
556 566
557 -static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd) 567 +static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
558 { 568 {
559 - int addr, value;  
560 - addr = cmd >> 5;  
561 - value = cmd & 0x1f; 569 + SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
  570 + int addr;
  571 + addr = value >> 5;
  572 + value &= 0x1f;
562 573
563 switch (addr) { 574 switch (addr) {
564 case LCDTG_RESCTL: 575 case LCDTG_RESCTL:
@@ -569,16 +580,44 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd) @@ -569,16 +580,44 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd)
569 break; 580 break;
570 581
571 case LCDTG_DUTYCTRL: 582 case LCDTG_DUTYCTRL:
572 - bl_intensity &= ~0x1f;  
573 - bl_intensity |= value;  
574 - if (bl_power)  
575 - spitz_bl_update((PXA2xxState *) opaque); 583 + s->bl_intensity &= ~0x1f;
  584 + s->bl_intensity |= value;
  585 + if (s->bl_power)
  586 + spitz_bl_update(s);
576 break; 587 break;
577 588
578 case LCDTG_POWERREG0: 589 case LCDTG_POWERREG0:
579 /* Set common voltage to M62332FP */ 590 /* Set common voltage to M62332FP */
580 break; 591 break;
581 } 592 }
  593 + return 0;
  594 +}
  595 +
  596 +static void spitz_lcdtg_save(QEMUFile *f, void *opaque)
  597 +{
  598 + SpitzLCDTG *s = (SpitzLCDTG *)opaque;
  599 + qemu_put_be32(f, s->bl_intensity);
  600 + qemu_put_be32(f, s->bl_power);
  601 +}
  602 +
  603 +static int spitz_lcdtg_load(QEMUFile *f, void *opaque, int version_id)
  604 +{
  605 + SpitzLCDTG *s = (SpitzLCDTG *)opaque;
  606 + s->bl_intensity = qemu_get_be32(f);
  607 + s->bl_power = qemu_get_be32(f);
  608 + return 0;
  609 +}
  610 +
  611 +static void spitz_lcdtg_init(SSISlave *dev)
  612 +{
  613 + SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
  614 +
  615 + spitz_lcdtg = s;
  616 + s->bl_power = 0;
  617 + s->bl_intensity = 0x20;
  618 +
  619 + register_savevm("spitz-lcdtg", -1, 1,
  620 + spitz_lcdtg_save, spitz_lcdtg_load, s);
582 } 621 }
583 622
584 /* SSP devices */ 623 /* SSP devices */
@@ -590,45 +629,33 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd) @@ -590,45 +629,33 @@ static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd)
590 #define SPITZ_GPIO_MAX1111_CS 20 629 #define SPITZ_GPIO_MAX1111_CS 20
591 #define SPITZ_GPIO_TP_INT 11 630 #define SPITZ_GPIO_TP_INT 11
592 631
593 -static int lcd_en, ads_en, max_en;  
594 -static MAX111xState *max1111;  
595 -static ADS7846State *ads7846; 632 +static DeviceState *max1111;
596 633
597 /* "Demux" the signal based on current chipselect */ 634 /* "Demux" the signal based on current chipselect */
598 -static uint32_t corgi_ssp_read(void *opaque)  
599 -{  
600 - if (lcd_en)  
601 - return 0;  
602 - if (ads_en)  
603 - return ads7846_read(ads7846);  
604 - if (max_en)  
605 - return max111x_read(max1111);  
606 - return 0;  
607 -} 635 +typedef struct {
  636 + SSISlave ssidev;
  637 + SSIBus *bus[3];
  638 + int enable[3];
  639 +} CorgiSSPState;
608 640
609 -static void corgi_ssp_write(void *opaque, uint32_t value) 641 +static uint32_t corgi_ssp_transfer(SSISlave *dev, uint32_t value)
610 { 642 {
611 - if (lcd_en)  
612 - spitz_lcdtg_dac_put(opaque, value);  
613 - if (ads_en)  
614 - ads7846_write(ads7846, value);  
615 - if (max_en)  
616 - max111x_write(max1111, value); 643 + CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
  644 + int i;
  645 +
  646 + for (i = 0; i < 3; i++) {
  647 + if (s->enable[i]) {
  648 + return ssi_transfer(s->bus[i], value);
  649 + }
  650 + }
  651 + return 0;
617 } 652 }
618 653
619 static void corgi_ssp_gpio_cs(void *opaque, int line, int level) 654 static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
620 { 655 {
621 - switch (line) {  
622 - case 0:  
623 - lcd_en = !level;  
624 - break;  
625 - case 1:  
626 - ads_en = !level;  
627 - break;  
628 - case 2:  
629 - max_en = !level;  
630 - break;  
631 - } 656 + CorgiSSPState *s = (CorgiSSPState *)opaque;
  657 + assert(line >= 0 && line < 3);
  658 + s->enable[line] = !level;
632 } 659 }
633 660
634 #define MAX1111_BATT_VOLT 1 661 #define MAX1111_BATT_VOLT 1
@@ -652,49 +679,71 @@ static void spitz_adc_temp_on(void *opaque, int line, int level) @@ -652,49 +679,71 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
652 679
653 static void spitz_ssp_save(QEMUFile *f, void *opaque) 680 static void spitz_ssp_save(QEMUFile *f, void *opaque)
654 { 681 {
655 - qemu_put_be32(f, lcd_en);  
656 - qemu_put_be32(f, ads_en);  
657 - qemu_put_be32(f, max_en);  
658 - qemu_put_be32(f, bl_intensity);  
659 - qemu_put_be32(f, bl_power); 682 + CorgiSSPState *s = (CorgiSSPState *)opaque;
  683 + int i;
  684 +
  685 + for (i = 0; i < 3; i++) {
  686 + qemu_put_be32(f, s->enable[i]);
  687 + }
660 } 688 }
661 689
662 static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id) 690 static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id)
663 { 691 {
664 - lcd_en = qemu_get_be32(f);  
665 - ads_en = qemu_get_be32(f);  
666 - max_en = qemu_get_be32(f);  
667 - bl_intensity = qemu_get_be32(f);  
668 - bl_power = qemu_get_be32(f); 692 + CorgiSSPState *s = (CorgiSSPState *)opaque;
  693 + int i;
669 694
  695 + if (version_id != 1) {
  696 + return -EINVAL;
  697 + }
  698 + for (i = 0; i < 3; i++) {
  699 + s->enable[i] = qemu_get_be32(f);
  700 + }
670 return 0; 701 return 0;
671 } 702 }
672 703
  704 +static void corgi_ssp_init(SSISlave *dev)
  705 +{
  706 + CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
  707 +
  708 + qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3);
  709 + s->bus[0] = ssi_create_bus();
  710 + qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]);
  711 + s->bus[1] = ssi_create_bus();
  712 + qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]);
  713 + s->bus[2] = ssi_create_bus();
  714 + qdev_attach_child_bus(&dev->qdev, "ssi2", s->bus[2]);
  715 +
  716 + register_savevm("spitz_ssp", -1, 1, spitz_ssp_save, spitz_ssp_load, s);
  717 +}
  718 +
673 static void spitz_ssp_attach(PXA2xxState *cpu) 719 static void spitz_ssp_attach(PXA2xxState *cpu)
674 { 720 {
675 - qemu_irq *chipselects; 721 + DeviceState *mux;
  722 + DeviceState *dev;
  723 + void *bus;
  724 +
  725 + mux = ssi_create_slave(cpu->ssp[CORGI_SSP_PORT - 1], "corgi-ssp");
676 726
677 - lcd_en = ads_en = max_en = 0; 727 + bus = qdev_get_child_bus(mux, "ssi0");
  728 + dev = ssi_create_slave(bus, "spitz-lcdtg");
678 729
679 - ads7846 = ads7846_init(pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_TP_INT]); 730 + bus = qdev_get_child_bus(mux, "ssi1");
  731 + dev = ssi_create_slave(bus, "ads7846");
  732 + qdev_connect_gpio_out(dev, 0,
  733 + pxa2xx_gpio_in_get(cpu->gpio)[SPITZ_GPIO_TP_INT]);
680 734
681 - max1111 = max1111_init(0); 735 + bus = qdev_get_child_bus(mux, "ssi2");
  736 + max1111 = ssi_create_slave(bus, "max1111");
682 max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT); 737 max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT);
683 max111x_set_input(max1111, MAX1111_BATT_TEMP, 0); 738 max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
684 max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN); 739 max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN);
685 740
686 - pxa2xx_ssp_attach(cpu->ssp[CORGI_SSP_PORT - 1], corgi_ssp_read,  
687 - corgi_ssp_write, cpu);  
688 -  
689 - chipselects = qemu_allocate_irqs(corgi_ssp_gpio_cs, cpu, 3);  
690 - pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_LCDCON_CS, chipselects[0]);  
691 - pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ADS7846_CS, chipselects[1]);  
692 - pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_MAX1111_CS, chipselects[2]);  
693 -  
694 - bl_intensity = 0x20;  
695 - bl_power = 0;  
696 -  
697 - register_savevm("spitz_ssp", 0, 0, spitz_ssp_save, spitz_ssp_load, cpu); 741 + pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_LCDCON_CS,
  742 + qdev_get_gpio_in(mux, 0));
  743 + pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_ADS7846_CS,
  744 + qdev_get_gpio_in(mux, 1));
  745 + pxa2xx_gpio_out_set(cpu->gpio, SPITZ_GPIO_MAX1111_CS,
  746 + qdev_get_gpio_in(mux, 2));
698 } 747 }
699 748
700 /* CF Microdrive */ 749 /* CF Microdrive */
@@ -1018,3 +1067,21 @@ QEMUMachine terrierpda_machine = { @@ -1018,3 +1067,21 @@ QEMUMachine terrierpda_machine = {
1018 .desc = "Terrier PDA (PXA270)", 1067 .desc = "Terrier PDA (PXA270)",
1019 .init = terrier_init, 1068 .init = terrier_init,
1020 }; 1069 };
  1070 +
  1071 +static SSISlaveInfo corgi_ssp_info = {
  1072 + .init = corgi_ssp_init,
  1073 + .transfer = corgi_ssp_transfer
  1074 +};
  1075 +
  1076 +static SSISlaveInfo spitz_lcdtg_info = {
  1077 + .init = spitz_lcdtg_init,
  1078 + .transfer = spitz_lcdtg_transfer
  1079 +};
  1080 +
  1081 +static void spitz_register_devices(void)
  1082 +{
  1083 + ssi_register_slave("corgi-ssp", sizeof(CorgiSSPState), &corgi_ssp_info);
  1084 + ssi_register_slave("spitz-lcdtg", sizeof(SpitzLCDTG), &spitz_lcdtg_info);
  1085 +}
  1086 +
  1087 +device_init(spitz_register_devices)
hw/ssi.h
@@ -38,4 +38,7 @@ SSIBus *ssi_create_bus(void); @@ -38,4 +38,7 @@ SSIBus *ssi_create_bus(void);
38 38
39 uint32_t ssi_transfer(SSIBus *bus, uint32_t val); 39 uint32_t ssi_transfer(SSIBus *bus, uint32_t val);
40 40
  41 +/* max111x.c */
  42 +void max111x_set_input(DeviceState *dev, int line, uint8_t value);
  43 +
41 #endif 44 #endif
hw/tosa.c
@@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
18 #include "block.h" 18 #include "block.h"
19 #include "boards.h" 19 #include "boards.h"
20 #include "i2c.h" 20 #include "i2c.h"
  21 +#include "ssi.h"
21 22
22 #define TOSA_RAM 0x04000000 23 #define TOSA_RAM 0x04000000
23 #define TOSA_ROM 0x00800000 24 #define TOSA_ROM 0x00800000
@@ -114,14 +115,15 @@ static void tosa_gpio_setup(PXA2xxState *cpu, @@ -114,14 +115,15 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
114 scoop_gpio_out_set(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio)); 115 scoop_gpio_out_set(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
115 } 116 }
116 117
117 -static uint32_t tosa_ssp_read(void *opaque) 118 +static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
118 { 119 {
  120 + fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f);
119 return 0; 121 return 0;
120 } 122 }
121 123
122 -static void tosa_ssp_write(void *opaque, uint32_t value) 124 +static void tosa_ssp_init(SSISlave *dev)
123 { 125 {
124 - fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f); 126 + /* Nothing to do. */
125 } 127 }
126 128
127 typedef struct { 129 typedef struct {
@@ -187,8 +189,7 @@ static void tosa_tg_init(PXA2xxState *cpu) @@ -187,8 +189,7 @@ static void tosa_tg_init(PXA2xxState *cpu)
187 { 189 {
188 i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); 190 i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
189 i2c_create_slave(bus, "tosa_dac", DAC_BASE); 191 i2c_create_slave(bus, "tosa_dac", DAC_BASE);
190 - pxa2xx_ssp_attach(cpu->ssp[1], tosa_ssp_read,  
191 - tosa_ssp_write, cpu); 192 + ssi_create_slave(cpu->ssp[1], "tosa-ssp");
192 } 193 }
193 194
194 195
@@ -250,9 +251,15 @@ static I2CSlaveInfo tosa_dac_info = { @@ -250,9 +251,15 @@ static I2CSlaveInfo tosa_dac_info = {
250 .send = tosa_dac_send 251 .send = tosa_dac_send
251 }; 252 };
252 253
  254 +static SSISlaveInfo tosa_ssp_info = {
  255 + .init = tosa_ssp_init,
  256 + .transfer = tosa_ssp_tansfer
  257 +};
  258 +
253 static void tosa_register_devices(void) 259 static void tosa_register_devices(void)
254 { 260 {
255 i2c_register_slave("tosa_dac", sizeof(TosaDACState), &tosa_dac_info); 261 i2c_register_slave("tosa_dac", sizeof(TosaDACState), &tosa_dac_info);
  262 + ssi_register_slave("tosa-ssp", sizeof(SSISlave), &tosa_ssp_info);
256 } 263 }
257 264
258 device_init(tosa_register_devices) 265 device_init(tosa_register_devices)