packing update
[qemu] / hw / twl4030.c
1 /*
2  * TI TWL4030 for beagle board
3  *
4  * Copyright (C) 2008 yajin<yajin@vm-kernel.org>
5  * Copyright (C) 2009 Nokia Corporation
6  *
7  * Register implementation based on TPS65950 ES1.0 specification.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24  
25 #include "hw.h"
26 #include "qemu-timer.h"
27 #include "i2c.h"
28 #include "sysemu.h"
29 #include "console.h"
30 #include "cpu-all.h"
31
32 #define VERBOSE 1
33 #define TRACEW(regname, value) fprintf(stderr, "%s: %s = 0x%02x\n", __FUNCTION__, regname, value);
34
35 //extern CPUState *cpu_single_env;
36
37 struct twl4030_i2c_s {
38     i2c_slave i2c;
39     int firstbyte;
40     uint8_t reg;
41     qemu_irq irq;
42     uint8 reg_data[256];
43     struct twl4030_s *twl4030;
44 };
45
46 struct twl4030_s {
47     struct twl4030_i2c_s *i2c[5];
48     
49     int key_cfg;
50     int key_tst;
51     
52     uint8_t seq_mem[64][4]; /* power-management sequencing memory */
53 };
54
55 static const uint8_t addr_48_reset_values[256] = {
56     0x51, 0x04, 0x02, 0xc0, 0x41, 0x41, 0x41, 0x10, /* 0x00...0x07 */
57     0x10, 0x10, 0x06, 0x06, 0x06, 0x1f, 0x1f, 0x1f, /* 0x08...0x0f */
58     0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */
59     0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, /* 0x18...0x1f */
60     0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x03, /* 0x20...0x27 */
61     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */
62     0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, /* 0x30...0x37 */
63     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38...0x3f */
64     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */
65     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */
66     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */
67     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */
68     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60...0x67 */
69     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */
70     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */
72     0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, /* 0x80...0x87 */
73     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88...0x8f */
74     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90...0x97 */
75     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98...0x9f */
76     0x00, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */
77     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */
78     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */
79     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8...0xb8 */
80     0xa0, 0xa0, 0x64, 0x7f, 0x6c, 0x75, 0x64, 0x20, /* 0xc0...0xc7 */
81     0x01, 0x17, 0x01, 0x02, 0x00, 0x36, 0x44, 0x07, /* 0xc8...0xcf */
82     0x3b, 0x17, 0x6b, 0x04, 0x00, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */
83     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */
84     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0...0xe7 */
85     0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */
86     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */
87     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00  /* 0xf8...0xff */
88 };
89
90 static const uint8_t addr_49_reset_values[256] = {
91     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */
92     0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, /* 0x08...0x0f */
93     0x3f, 0x3f, 0x3f, 0x3f, 0x25, 0x00, 0x00, 0x00, /* 0x10...0x17 */
94     0x00, 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x55, /* 0x18...0x1f */
95     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20...0x27 */
96     0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */
97     0x13, 0x00, 0x00, 0x00, 0x00, 0x79, 0x11, 0x00, /* 0x30...0x37 */
98     0x00, 0x00, 0x06, 0x00, 0x44, 0x69, 0x00, 0x00, /* 0x38...0x3f */
99     0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, /* 0x40...0x47 */
100     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */
101     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */
102     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */
103     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60...0x67 */
104     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */
105     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */
106     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */
107     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80...0x87 */
108     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88...0x8f */
109     0x00, 0x90, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, /* 0x90...0x97 */
110     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98...0x9f */
111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */
112     0x00, 0x00, 0x04, 0x00, 0x55, 0x01, 0x55, 0x05, /* 0xa8...0xaf */
113     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 0xb0...0xb7 */
114     0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, /* 0xb8...0xbf */
115     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 0xc0...0xc7 */
116     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8...0xcf */
117     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */
118     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */
119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0...0xe7 */
120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */
121     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */
122     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8...0xff */
123 };
124
125 static const uint8_t addr_4a_reset_values[256] = {
126     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */
127     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08...0x0f */
128     0xc0, 0x8c, 0xde, 0xde, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */
129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18...0x1f */
130     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20...0x27 */
131     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */
132     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30...0x37 */
133     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38...0x3f */
134     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */
135     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */
136     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */
137     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */
138     0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x55, 0x07, /* 0x60...0x67 */
139     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */
140     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */
141     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */
142     0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, /* 0x80...0x87 */
143     0x00, 0x68, 0x9b, 0x86, 0x48, 0x2a, 0x07, 0x28, /* 0x88...0x8f */
144     0x09, 0x69, 0x90, 0x00, 0x2a, 0x00, 0x02, 0x00, /* 0x90...0x97 */
145     0x10, 0xcd, 0x02, 0x68, 0x03, 0x00, 0x00, 0x00, /* 0x98...0x9f */
146     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */
147     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */
148     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */
149     0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, /* 0xb8...0xbf */
150     0x0f, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x01, 0x00, /* 0xc0...0xc7 */
151     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8...0xcf */
152     0x00, 0x00, 0x03, 0x00, 0x00, 0xe0, 0x00, 0x00, /* 0xd0...0xd7 */
153     0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */
154     0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, /* 0xe0...0xe7 */
155     0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */
156     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */
157     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xf8...0xff */
158 };
159
160 static const uint8_t addr_4b_reset_values[256] = {
161     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */
162     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08...0x0f */
163     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */
164     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x18...0x1f */
165     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, /* 0x20...0x27 */
166     0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */
167     0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0xbf, 0xbf, /* 0x30...0x37 */
168     0xbf, 0xab, 0x00, 0x08, 0x3f, 0x15, 0x40, 0x0e, /* 0x38...0x3f */
169     0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */
170     0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, /* 0x48...0x4f */
171     0x00, 0x02, 0x00, 0x04, 0x0d, 0x00, 0x00, 0x00, /* 0x50...0x57 */
172     0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */
173     0x00, 0x00, 0x2f, 0x18, 0x0f, 0x08, 0x0f, 0x08, /* 0x60...0x67 */
174     0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */
175     0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x03, /* 0x70...0x77 */
176     0x08, 0x09, 0x00, 0x00, 0x08, 0x03, 0x80, 0x03, /* 0x78...0x7f */
177     0x08, 0x02, 0x00, 0x00, 0x08, 0x00, 0x80, 0x03, /* 0x80...0x87 */
178     0x08, 0x08, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, /* 0x88...0x8f */
179     0x08, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, /* 0x90...0x97 */
180     0x08, 0x02, 0xe0, 0x01, 0x08, 0x00, 0xe0, 0x00, /* 0x98...0x9f */
181     0x08, 0x01, 0xe0, 0x01, 0x08, 0x04, 0xe0, 0x03, /* 0xa0...0xa7 */
182     0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */
183     0x20, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */
184     0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, /* 0xb8...0xbf */
185     0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, /* 0xc0...0xc7 */
186     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, /* 0xc8...0xcf */
187     0x00, 0x08, 0xe0, 0x00, 0x08, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */
188     0x14, 0x08, 0xe0, 0x02, 0x08, 0xe0, 0x00, 0x08, /* 0xd8...0xdf */
189     0xe0, 0x05, 0x08, 0xe0, 0x06, 0x08, 0xe0, 0x00, /* 0xe0...0xe7 */
190     0x08, 0xe0, 0x00, 0x08, 0xe0, 0x06, 0x06, 0xe0, /* 0xe8...0xef */
191     0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */
192     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xf8...0xff */
193 };
194
195 static uint8_t twl4030_48_read(void *opaque, uint8_t addr)
196 {
197     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
198         
199     switch (addr) {
200         case 0x00: /* VENDOR_ID_LO */
201         case 0x01: /* VENDOR_ID_HI */
202         case 0x02: /* PRODUCT_ID_LO */
203         case 0x03: /* PRODUCT_ID_HI */
204             return s->reg_data[addr];
205         case 0x04: /* FUNC_CTRL */
206         case 0x05: /* FUNC_CRTL_SET */
207         case 0x06: /* FUNC_CRTL_CLR */
208             return s->reg_data[0x04];
209         case 0x07: /* IFC_CTRL */
210         case 0x08: /* IFC_CRTL_SET */
211         case 0x09: /* IFC_CRTL_CLR */
212             return s->reg_data[0x07];
213         case 0xac: /* POWER_CTRL */
214         case 0xad: /* POWER_SET */
215         case 0xae: /* POWER_CLR */
216             return s->reg_data[0xac];
217         case 0xfd: /* PHY_PWR_CTRL */
218         case 0xfe: /* PHY_CLK_CTRL */
219             return s->reg_data[addr];
220         case 0xff: /* PHY_CLK_CTRL */
221             return s->reg_data[0xfe] & 0x1;
222         default:
223 #ifdef VERBOSE
224             printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );
225                 //printf("%s: unknown register %02x \n", __FUNCTION__, addr);
226 #endif
227             exit(-1);
228             break;
229     }
230 }
231
232 static void twl4030_48_write(void *opaque, uint8_t addr, uint8_t value)
233 {
234     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
235         
236     switch (addr) {
237         case 0x04: /* IFC_CTRL */
238             s->reg_data[0x04] = value & 0x80;
239             break;
240         case 0x05: /* IFC_CRTL_SET */
241             s->reg_data[0x04] =  (s->reg_data[0x04] | value) & 0x80;
242             break;
243         case 0x06: /* IFC_CRTL_CLEAR */
244             s->reg_data[0x04] =  (s->reg_data[0x04] & ~value) & 0x80;
245             break;
246         case 0x07: /* IFC_CTRL */
247             s->reg_data[0x07] = value & 0x61;
248             break;
249         case 0x08: /* IFC_CRTL_SET */
250             s->reg_data[0x07] =  (s->reg_data[0x07] | value) & 0x61;
251             break;
252         case 0x09: /* IFC_CRTL_CLEAR */
253             s->reg_data[0x07] =  (s->reg_data[0x07] & ~value) & 0x61;
254             break;
255         case 0xac: /* POWER_CTRL */
256             s->reg_data[0xac] = value & 0x20;
257             break;
258         case 0xad: /* POWER_SET */
259             s->reg_data[0xac] =  (s->reg_data[0xac] | value) & 0x20;
260             break;
261         case 0xae: /* POWER_CLEAR */
262             s->reg_data[0xac] =  (s->reg_data[0xac] & ~value) & 0x20;
263             break;
264         case 0xfd: /* PHY_PWR_CTRL */
265             s->reg_data[addr] = value & 0x1;
266             break;
267         case 0xfe: /* PHY_CLK_CTRL */
268             s->reg_data[addr] = value & 0x7;
269             break;
270         default:
271 #ifdef VERBOSE
272             printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );
273             //printf("%s: unknown register %02x \n", __FUNCTION__, addr);
274 #endif
275                         exit(-1);
276                         break;
277     }
278 }
279
280 static int twl4030_48_tx(i2c_slave *i2c, uint8_t data)
281 {
282     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
283     /* Interpret register address byte */
284     if (s->firstbyte) {
285         s->reg = data;
286         s->firstbyte = 0;
287     } else
288         twl4030_48_write(s, s->reg++, data);
289         
290     return 0;
291 }
292
293 static int twl4030_48_rx(i2c_slave *i2c)
294 {
295     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
296         
297     return twl4030_48_read(s, s->reg++);
298 }
299
300 static void twl4030_48_reset(i2c_slave *i2c)
301 {
302     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
303     s->reg = 0x00;
304     memcpy(s->reg_data, addr_48_reset_values, 256);
305 }
306
307 static void twl4030_48_event(i2c_slave *i2c, enum i2c_event event)
308 {
309     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
310     
311     if (event == I2C_START_SEND)
312         s->firstbyte = 1;
313 }
314
315 static uint8_t twl4030_49_read(void *opaque, uint8_t addr)
316 {
317     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
318
319     switch (addr) {
320         case 0x98: /* GPIO_DATAIN1 */
321         case 0x99: /* GPIO_DATAIN2 */
322         case 0x9a: /* GPIO_DATAIN3 */
323         case 0x9b: /* GPIO_DATADIR1 */
324         case 0x9c: /* GPIO_DATADIR2 */
325         case 0x9d: /* GPIO_DATADIR3 */
326         case 0xb1: /* GPIO_ISR1A */
327         case 0xb2: /* GPIO_ISR2A */
328         case 0xb3: /* GPIO_ISR3A */
329         case 0xc0: /* GPIO_EDR1 */
330         case 0xc1: /* GPIO_EDR2 */
331         case 0xc2: /* GPIO_EDR3 */
332         case 0xc3: /* GPIO_EDR4 */
333         case 0xc4: /* GPIO_EDR5 */
334             return s->reg_data[addr];
335         default:
336 #ifdef VERBOSE
337             fprintf(stderr, "%s: unknown register %02x pc %x\n",
338                     __FUNCTION__, addr,cpu_single_env->regs[15]);
339 #endif
340                         exit(-1);
341     }
342 }
343
344 static void twl4030_49_write(void *opaque, uint8_t addr, uint8_t value)
345 {
346     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
347         
348     switch (addr) {
349         case 0x9b: /* GPIODATADIR1 */
350         case 0x9c: /* GPIODATADIR2 */
351         case 0x9d: /* GPIODATADIR3 */
352         case 0x9e: /* GPIODATAOUT1 */
353         case 0x9f: /* GPIODATAOUT2 */
354         case 0xa0: /* GPIODATAOUT3 */
355         case 0xa1: /* CLEARGPIODATAOUT1 */
356         case 0xa2: /* CLEARGPIODATAOUT2 */
357         case 0xa3: /* CLEARGPIODATAOUT3 */
358         case 0xa4: /* SETGPIODATAOUT1 */
359         case 0xa5: /* SETGPIODATAOUT2 */
360         case 0xa6: /* SETGPIODATAOUT3 */
361         case 0xa7: /* GPIO_DEBEN1 */
362         case 0xa8: /* GPIO_DEBEN2 */
363         case 0xa9: /* GPIO_DEBEN3 */
364         case 0xaa: /* GPIO_CTRL */
365         case 0xab: /* GPIOPUPDCTR1 */
366         case 0xac: /* GPIOPUPDCTR2 */
367         case 0xad: /* GPIOPUPDCTR3 */
368         case 0xae: /* GPIOPUPDCTR4 */
369             s->reg_data[addr] = value;
370             break;
371         case 0xaf: /* GPIOPUPDCTR5 */
372             s->reg_data[addr] = value & 0x0f;
373             break;
374             case 0xb4: /* GPIO_IMR1A */
375             case 0xb5: /* GPIO_IMR2A */
376             s->reg_data[addr] = value;
377             break;
378             case 0xb6: /* GPIO_IMR3A */
379             s->reg_data[addr] = value & 0x03;
380             break;
381             case 0xc0: /* GPIO_EDR1 */
382             case 0xc1: /* GPIO_EDR2 */
383             case 0xc2: /* GPIO_EDR3 */
384             case 0xc3: /* GPIO_EDR4 */
385             case 0xc4: /* GPIO_EDR5 */
386             s->reg_data[addr] = value;
387             break;
388             case 0xc5: /* GPIO_SIH_CTRL */
389             s->reg_data[addr] = value & 0x07;
390             break;
391         default:
392 #ifdef VERBOSE
393             printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,
394                    cpu_single_env->regs[15]);
395             //printf("%s: unknown register %02x \n", __FUNCTION__, addr);
396 #endif
397             exit(-1);
398             break;
399     }
400 }
401
402
403 static int twl4030_49_tx(i2c_slave *i2c, uint8_t data)
404 {
405     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
406     /* Interpret register address byte */
407     if (s->firstbyte) {
408         s->reg = data;
409         s->firstbyte = 0;
410     } else
411         twl4030_49_write(s, s->reg++, data);
412         
413     return 0;
414 }
415
416 static int twl4030_49_rx(i2c_slave *i2c)
417 {
418     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
419         
420     return twl4030_49_read(s, s->reg++);
421 }
422
423 static void twl4030_49_reset(i2c_slave *i2c)
424 {
425     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
426     s->reg = 0x00;
427     memcpy(s->reg_data, addr_49_reset_values, 256);
428 }
429
430 static void twl4030_49_event(i2c_slave *i2c, enum i2c_event event)
431 {
432     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
433         
434     if (event == I2C_START_SEND)
435         s->firstbyte = 1;
436 }
437
438 static uint8_t twl4030_4a_read(void *opaque, uint8_t addr)
439 {
440     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
441         
442     switch (addr) {
443         case 0x61: /* MADC_ISR1 */
444         case 0xb9: /* BCIISR1A */
445         case 0xba: /* BCIISR2A */
446         case 0xe3: /* KEYP_ISR1 */
447         case 0xee: /* LEDEN */
448             return s->reg_data[addr];
449         default:
450 #ifdef VERBOSE
451                 printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );
452 #endif
453             exit(-1);
454             break;
455     }
456 }
457
458 static void twl4030_4a_write(void *opaque, uint8_t addr, uint8_t value)
459 {
460     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
461         
462     switch (addr) {
463         case 0x61: /* MADC_ISR1 */
464             s->reg_data[value] &= ~(value & 0x0f);
465             break;
466         case 0x62: /* MADC_IMR1 */
467             s->reg_data[value] = value & 0x0f;
468             break;
469         case 0xb9: /* BCIISR1A */
470             s->reg_data[value] &= ~value;
471             break;
472         case 0xba: /* BCIISR2A */
473             s->reg_data[value] &= ~(value & 0x0f);
474             break;
475         case 0xbb: /* BCIIMR1A */
476             s->reg_data[addr] = value;
477             break;
478         case 0xbc: /* BCIIMR2A */
479             s->reg_data[addr] = value & 0x0f;
480             break;
481         case 0xe4: /* KEYP_IMR1 */
482             s->reg_data[addr] = value & 0x0f;
483             break;
484         case 0xe9: /* KEYP_SIH_CTRL */
485             s->reg_data[addr] = value & 0x07;
486             break;
487         case 0xee: /* LEDEN */
488             s->reg_data[addr] = value;
489 #ifdef VERBOSE
490             fprintf(stderr, "%s: LEDA power=%s/enable=%s, LEDB power=%s/enable=%s\n", __FUNCTION__,
491                     value & 0x10 ? "on" : "off", value & 0x01 ? "yes" : "no",
492                     value & 0x20 ? "on" : "off", value & 0x02 ? "yes" : "no");
493 #endif      
494             break;
495         case 0xef: /* PWMAON */
496             s->reg_data[addr] = value;
497             break;
498         case 0xf0: /* PWMAOFF */
499             s->reg_data[addr] = value & 0x7f;
500             break;
501         default:
502 #ifdef VERBOSE
503                 printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );
504 #endif
505             exit(-1);
506             break;
507     }
508 }
509
510 static int twl4030_4a_tx(i2c_slave *i2c, uint8_t data)
511 {
512     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
513     /* Interpret register address byte */
514     if (s->firstbyte) {
515         s->reg = data;
516         s->firstbyte = 0;
517     } else
518         twl4030_4a_write(s, s->reg++, data);
519         
520     return 0;
521 }
522
523 static int twl4030_4a_rx(i2c_slave *i2c)
524 {
525     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
526         
527     return twl4030_4a_read(s, s->reg++);
528 }
529
530 static void twl4030_4a_reset(i2c_slave *i2c)
531 {
532     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
533     s->reg = 0x00;
534     memcpy(s->reg_data, addr_4a_reset_values, 256);
535 }
536
537 static void twl4030_4a_event(i2c_slave *i2c, enum i2c_event event)
538 {
539     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
540         
541     if (event == I2C_START_SEND)
542         s->firstbyte = 1;
543 }
544
545 static uint8_t twl4030_4b_read(void *opaque, uint8_t addr)
546 {
547     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
548         
549     switch (addr) {
550         case 0x1c: /* RTC */
551         case 0x1d:
552         case 0x1e:
553         case 0x1f:
554         case 0x20:
555         case 0x21:
556         case 0x22:
557         case 0x23:
558         case 0x24:
559         case 0x25:
560         case 0x26:
561         case 0x27:
562         case 0x28:
563         case 0x29:
564         case 0x2a:
565         case 0x2b:
566         case 0x2c:
567         case 0x2d: /*RTC end */
568         case 0x2e: /* PWR_ISR1 */
569         case 0x33: /* PWR_EDR1 */
570         case 0x34: /* PWR_EDR2 */
571             return s->reg_data[addr];
572         case 0x45: /* STS_HW_CONDITIONS - USB plugged, no VBUS -> host usb */
573             return 0x4;
574         default:
575 #ifdef VERBOSE
576                 printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );
577                 //printf("%s: unknown register %02x \n", __FUNCTION__, addr);
578 #endif
579             exit(-1);
580             break;
581     }
582 }
583
584
585 static void twl4030_4b_write(void *opaque, uint8_t addr, uint8_t value)
586 {
587     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;
588     uint8_t seq_addr, seq_sub;
589         
590     switch (addr) {
591         case 0x1c: /* SECONDS_REG */
592         case 0x1d: /* MINUTES_REG */
593         case 0x23: /* ALARM_SECONDS_REG */
594         case 0x24: /* ALARM_MINUTES_REG */
595             s->reg_data[addr] = value & 0x7f;
596             break;
597         case 0x1e: /* HOURS_REG */
598         case 0x25: /* ALARM_HOURS_REG */
599             s->reg_data[addr] = value & 0xbf;
600             break;
601         case 0x1f: /* DAYS_REG */
602         case 0x26: /* ALARM_DAYS_REG */
603             s->reg_data[addr] = value & 0x3f;
604             break;
605         case 0x20: /* MONTHS_REG */
606         case 0x27: /* ALARM_MONTHS_REG */
607             s->reg_data[addr] = value & 0x1f;
608             break;
609         case 0x21: /* YEARS_REG */
610         case 0x28: /* ALARM_YEARS_REG */
611             s->reg_data[addr] = value;
612             break;
613         case 0x22: /* WEEKS_REG */
614             s->reg_data[addr] = value & 0x07;
615             break;
616         case 0x29: /* RTC_CTRL_REG */
617             s->reg_data[addr] = value & 0x7f;
618             break;
619         case 0x2a: /* RTC_STATUS_REG */
620             s->reg_data[addr] = value & 0xfe;
621             break;
622         case 0x2b: /* RTC_INTERRUPTS_REG */
623             s->reg_data[addr] = value & 0x0f;
624             break;
625         case 0x2c: /* RTC_COMP_LSB_REG */
626         case 0x2d: /* RTC_COMP_MSB_REG */
627             s->reg_data[addr] = value;
628             break;
629         case 0x33: /* PWR_EDR1 */
630         case 0x34: /* PWR_EDR2 */
631             s->reg_data[addr] = value;
632             break;
633         case 0x46: /* P1_SW_EVENTS */
634         case 0x47: /* P2_SW_EVENTS */
635         case 0x48: /* P3_SW_EVENTS */
636             s->reg_data[addr] = value & 0x78;
637             break;
638         case 0x52: /* SEQ_ADD_W2P */
639         case 0x53: /* SEQ_ADD_P2A */
640         case 0x54: /* SEQ_ADD_A2W */
641         case 0x55: /* SEQ_ADD_A2S */
642         case 0x56: /* SEQ_ADD_S2A12 */
643         case 0x57: /* SEQ_ADD_S2A3 */
644         case 0x58: /* SEQ_ADD_WARM */
645             if (s->twl4030->key_cfg)
646                 s->reg_data[addr] = value & 0x3f;
647             break;
648         case 0x59: /* MEMORY_ADDRESS */
649             if (s->twl4030->key_cfg)
650                 s->reg_data[addr] = value;
651             break;
652         case 0x5a: /* MEMORY_DATA */
653             if (s->twl4030->key_cfg) {
654                 s->reg_data[addr] = value;
655                 seq_addr = s->reg_data[0x59];
656                 seq_sub = seq_addr & 3;
657                 seq_addr >>= 2;
658                 if ((seq_addr >= 0x2b && seq_addr <= 0x3e) || (seq_addr <= 0x0e && seq_sub == 3))
659                     s->twl4030->seq_mem[seq_addr][seq_sub] = value;
660             }
661             s->reg_data[0x59]++; /* TODO: check if autoincrement is write-protected as well */
662             break;
663         case 0x7a: /* VAUX3_DEV_GRP */
664         case 0x82: /* VMMC1_DEV_GRP */
665         case 0x8e: /* VPLL2_DEV_GRP */
666         case 0x96: /* VDAC_DEV_GRP */
667         case 0xcc: /* VUSB1V5_DEV_GRP */
668         case 0xcf: /* VUSB1V8_DEV_GRP */
669         case 0xd2: /* VUSB3V1_DEV_GRP */
670         case 0xe6: /* HFCLKOUT_DEV_GRP */
671             s->reg_data[addr] = (s->reg_data[addr] & 0x0f) | (value & 0xf0); 
672             break;
673         case 0x2f: /* PWR_IMR1 */
674             s->reg_data[addr] = value;
675             break;
676         case 0x35: /* PWR_SIH_CTRL */
677             s->reg_data[addr] = value & 0x07;
678             break;
679         case 0x3b: /* CFG_BOOT */
680             if (s->twl4030->key_cfg)
681                 s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x8f);
682             break;
683         case 0x44: /* PROTECT_KEY */
684             s->twl4030->key_cfg = 0;
685             s->twl4030->key_tst = 0;
686             switch (value) {
687                 case 0x0C: 
688                     if (s->reg_data[addr] == 0xC0)
689                         s->twl4030->key_cfg = 1;
690                     break;
691                 case 0xE0:
692                     if (s->reg_data[addr] == 0x0E)
693                         s->twl4030->key_tst = 1;
694                     break;
695                 case 0xEC:
696                     if (s->reg_data[addr] == 0xCE) {
697                         s->twl4030->key_cfg = 1;
698                         s->twl4030->key_tst = 1;
699                     }
700                     break;
701                 default:
702                     break;
703             }
704             s->reg_data[addr] = value;
705             break;
706         case 0x7d: /* VAUX3_DEDICATED */
707             if (s->twl4030->key_tst)
708                 s->reg_data[addr] = value & 0x77;
709             else
710                 s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x07);
711             break;
712         case 0x85: /* VMMC1_DEDICATED */
713         case 0x99: /* VDAC_DEDICATED */
714             if (s->twl4030->key_tst) 
715                 s->reg_data[addr] = value & 0x73;
716             else
717                 s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x03);
718             break;
719         case 0x91: /* VPLL2_DEDICATED */
720             if (s->twl4030->key_tst)
721                 s->reg_data[addr] = value & 0x7f;
722             else
723                 s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x0f);
724             break;
725         case 0xcd: /* VUSB1V5_TYPE */
726         case 0xd0: /* VUSB1V8_TYPE */
727         case 0xd3: /* VUSB3V1_TYPE */
728             s->reg_data[addr] = value & 0x1f;
729             break;
730         case 0xd8: /* VUSB_DEDICATED1 */
731             s->reg_data[addr] = value & 0x1f;
732             break;
733         case 0xd9: /* VUSB_DEDICATED2 */
734             s->reg_data[addr] = value & 0x08;
735             break;
736             
737         default:
738                 fprintf(stderr, "%s: unknown register %02x value %0x pc %x \n", __FUNCTION__, 
739                     addr, value, cpu_single_env->regs[15]);
740             exit(-1);
741             break;
742     }
743 }
744
745 static int twl4030_4b_tx(i2c_slave *i2c, uint8_t data)
746 {
747     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
748     /* Interpret register address byte */
749     if (s->firstbyte) {
750         s->reg = data;
751         s->firstbyte = 0;
752     } else
753         twl4030_4b_write(s, s->reg++, data);
754         
755     return 1;
756 }
757
758 static int twl4030_4b_rx(i2c_slave *i2c)
759 {
760     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
761         
762     return twl4030_4b_read(s, s->reg++);
763 }
764
765 static void twl4030_4b_reset(i2c_slave *i2c)
766 {
767     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
768     s->reg = 0x00;
769     memcpy(s->reg_data, addr_4b_reset_values, 256);
770     s->twl4030->key_cfg = 0;
771     s->twl4030->key_tst = 0;
772 }
773
774 static void twl4030_4b_event(i2c_slave *i2c, enum i2c_event event)
775 {
776     struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;
777         
778     if (event == I2C_START_SEND)
779         s->firstbyte = 1;
780 }
781
782 struct twl4030_s *twl4030_init(i2c_bus *bus, qemu_irq irq)
783 {
784     int i;
785         
786     struct twl4030_s *s = (struct twl4030_s *) qemu_mallocz(sizeof(*s));
787         
788     if (!s)
789     {
790         fprintf(stderr,"can not alloc memory space for twl4030_s \n");
791         exit(-1);
792     }
793     for (i=0;i<5;i++)
794     {
795         s->i2c[i]=(struct twl4030_i2c_s *)i2c_slave_init(bus, 0, sizeof(struct twl4030_i2c_s));
796         s->i2c[i]->irq = irq;
797         s->i2c[i]->twl4030 = s;
798     }
799     s->i2c[0]->i2c.event = twl4030_48_event;
800     s->i2c[0]->i2c.recv = twl4030_48_rx;
801     s->i2c[0]->i2c.send = twl4030_48_tx;
802     twl4030_48_reset(&s->i2c[0]->i2c);
803     i2c_set_slave_address((i2c_slave *)&s->i2c[0]->i2c,0x48);
804         
805     s->i2c[1]->i2c.event = twl4030_49_event;
806     s->i2c[1]->i2c.recv = twl4030_49_rx;
807     s->i2c[1]->i2c.send = twl4030_49_tx;
808     twl4030_49_reset(&s->i2c[1]->i2c);
809     i2c_set_slave_address((i2c_slave *)&s->i2c[1]->i2c,0x49);
810         
811     s->i2c[2]->i2c.event = twl4030_4a_event;
812     s->i2c[2]->i2c.recv = twl4030_4a_rx;
813     s->i2c[2]->i2c.send = twl4030_4a_tx;
814     twl4030_4a_reset(&s->i2c[2]->i2c);
815     i2c_set_slave_address((i2c_slave *)&s->i2c[2]->i2c,0x4a);
816         
817     s->i2c[3]->i2c.event = twl4030_4b_event;
818     s->i2c[3]->i2c.recv = twl4030_4b_rx;
819     s->i2c[3]->i2c.send = twl4030_4b_tx;
820     twl4030_4b_reset(&s->i2c[3]->i2c);
821     i2c_set_slave_address((i2c_slave *)&s->i2c[3]->i2c,0x4b);
822     /*TODO:other group*/
823         
824         
825     //register_savevm("menelaus", -1, 0, menelaus_save, menelaus_load, s);
826     return s;
827 }
828
829 #if 0
830 static uint8_t twl4030_read(void *opaque, uint8_t addr)
831 {
832 //    struct twl4030_s *s = (struct twl4030_s *) opaque;
833 //    int reg = 0;
834
835     printf("twl4030_read addr %x\n",addr);
836
837     switch (addr)
838     {
839         default:
840 #ifdef VERBOSE
841         printf("%s: unknown register %02x\n", __FUNCTION__, addr);
842 #endif
843                         //exit(-1);
844                         break;
845     }
846     return 0x00;
847 }
848
849 static void twl4030_write(void *opaque, uint8_t addr, uint8_t value)
850 {
851 //    struct twl4030_s *s = (struct twl4030_s *) opaque;
852 //    int line;
853 //    int reg = 0;
854 //    struct tm tm;
855
856     printf("twl4030_write addr %x value %x \n",addr,value);
857
858      switch (addr) 
859      {
860          case 0x82:
861          case 0x85:
862                 /*mmc*/
863                 break;
864         default:
865 #ifdef VERBOSE
866         printf("%s: unknown register %02x\n", __FUNCTION__, addr);
867 #endif
868                         //exit(-1);
869                         break;
870         }
871 }
872
873
874 static int twl4030_tx(i2c_slave *i2c, uint8_t data)
875 {
876     struct twl4030_s *s = (struct twl4030_s *) i2c;
877     /* Interpret register address byte */
878     if (s->firstbyte) {
879         s->reg = data;
880         s->firstbyte = 0;
881     } else
882         twl4030_write(s, s->reg ++, data);
883
884     return 0;
885 }
886
887 static int twl4030_rx(i2c_slave *i2c)
888 {
889     struct twl4030_s *s = (struct twl4030_s *) i2c;
890
891     return twl4030_read(s, s->reg ++);
892 }
893
894 static void twl4030_reset(i2c_slave *i2c)
895 {
896     struct twl4030_s *s = (struct twl4030_s *) i2c;
897     s->reg = 0x00;
898 }
899
900 static void twl4030_event(i2c_slave *i2c, enum i2c_event event)
901 {
902     struct twl4030_s *s = (struct twl4030_s *) i2c;
903
904     if (event == I2C_START_SEND)
905         s->firstbyte = 1;
906 }
907
908 i2c_slave *twl4030_init(i2c_bus *bus, qemu_irq irq)
909 {
910     struct twl4030_s *s = (struct twl4030_s *)
911             i2c_slave_init(bus, 0, sizeof(struct twl4030_s));
912
913     s->i2c.event = twl4030_event;
914     s->i2c.recv = twl4030_rx;
915     s->i2c.send = twl4030_tx;
916
917     s->irq = irq;
918     //s->rtc.hz_tm = qemu_new_timer(rt_clock, menelaus_rtc_hz, s);
919     //s->in = qemu_allocate_irqs(menelaus_gpio_set, s, 3);
920     //s->pwrbtn = qemu_allocate_irqs(menelaus_pwrbtn_set, s, 1)[0];
921
922     twl4030_reset(&s->i2c);
923
924     //register_savevm("menelaus", -1, 0, menelaus_save, menelaus_load, s);
925
926     return &s->i2c;
927 }
928 #endif
929  
930