summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/mas.c160
-rw-r--r--firmware/drivers/mas.h43
2 files changed, 190 insertions, 13 deletions
diff --git a/firmware/drivers/mas.c b/firmware/drivers/mas.c
index 38344ecc23..e8587487dc 100644
--- a/firmware/drivers/mas.c
+++ b/firmware/drivers/mas.c
@@ -77,7 +77,7 @@ int mas_readmem(int bank, int addr, unsigned long* dest, int len)
77 77
78 i=0; 78 i=0;
79 buf[i++] = MAS_DATA_WRITE; 79 buf[i++] = MAS_DATA_WRITE;
80 buf[i++] = bank?0xf0:0xe0; 80 buf[i++] = bank?MAS_CMD_READ_D1_MEM:MAS_CMD_READ_D0_MEM;
81 buf[i++] = 0x00; 81 buf[i++] = 0x00;
82 buf[i++] = (len & 0xff00) >> 8; 82 buf[i++] = (len & 0xff00) >> 8;
83 buf[i++] = len & 0xff; 83 buf[i++] = len & 0xff;
@@ -102,7 +102,7 @@ int mas_writemem(int bank, int addr, unsigned long* src, int len)
102 102
103 i=0; 103 i=0;
104 buf[i++] = MAS_DATA_WRITE; 104 buf[i++] = MAS_DATA_WRITE;
105 buf[i++] = bank; 105 buf[i++] = bank?MAS_CMD_WRITE_D1_MEM:MAS_CMD_WRITE_D0_MEM;
106 buf[i++] = 0x00; 106 buf[i++] = 0x00;
107 buf[i++] = (len & 0xff00) >> 8; 107 buf[i++] = (len & 0xff00) >> 8;
108 buf[i++] = len & 0xff; 108 buf[i++] = len & 0xff;
@@ -111,10 +111,17 @@ int mas_writemem(int bank, int addr, unsigned long* src, int len)
111 111
112 j = 0; 112 j = 0;
113 while(len--) { 113 while(len--) {
114 buf[i++] = ptr[j*4+1]; 114#ifdef ARCHOS_RECORDER
115 buf[i++] = ptr[j*4+0];
116 buf[i++] = 0; 115 buf[i++] = 0;
117 buf[i++] = ptr[j*4+2]; 116 buf[i++] = ptr[j+1];
117 buf[i++] = ptr[j+2];
118 buf[i++] = ptr[j+3];
119#else
120 buf[i++] = ptr[j+2];
121 buf[i++] = ptr[j+3];
122 buf[i++] = 0;
123 buf[i++] = ptr[j+1];
124#endif
118 j += 4; 125 j += 4;
119 } 126 }
120 127
@@ -131,10 +138,11 @@ int mas_readreg(int reg)
131{ 138{
132 int i; 139 int i;
133 unsigned char buf[16]; 140 unsigned char buf[16];
141 unsigned long value;
134 142
135 i=0; 143 i=0;
136 buf[i++] = MAS_DATA_WRITE; 144 buf[i++] = MAS_DATA_WRITE;
137 buf[i++] = 0xd0 | reg >> 4; 145 buf[i++] = MAS_CMD_READ_REG | (reg >> 4);
138 buf[i++] = (reg & 0x0f) << 4; 146 buf[i++] = (reg & 0x0f) << 4;
139 147
140 /* send read command */ 148 /* send read command */
@@ -143,12 +151,12 @@ int mas_readreg(int reg)
143 return -1; 151 return -1;
144 } 152 }
145 153
146 if(mas_devread((unsigned long *)buf, 1)) 154 if(mas_devread(&value, 1))
147 { 155 {
148 return -2; 156 return -2;
149 } 157 }
150 158
151 return buf[0] | buf[1] << 8 | buf[3] << 16; 159 return value;
152} 160}
153 161
154int mas_writereg(int reg, unsigned int val) 162int mas_writereg(int reg, unsigned int val)
@@ -158,7 +166,7 @@ int mas_writereg(int reg, unsigned int val)
158 166
159 i=0; 167 i=0;
160 buf[i++] = MAS_DATA_WRITE; 168 buf[i++] = MAS_DATA_WRITE;
161 buf[i++] = 0x90 | reg >> 4; 169 buf[i++] = MAS_CMD_READ_REG | (reg >> 4);
162 buf[i++] = ((reg & 0x0f) << 4) | (val & 0x0f); 170 buf[i++] = ((reg & 0x0f) << 4) | (val & 0x0f);
163 buf[i++] = (val >> 12) & 0xff; 171 buf[i++] = (val >> 12) & 0xff;
164 buf[i++] = (val >> 4) & 0xff; 172 buf[i++] = (val >> 4) & 0xff;
@@ -179,6 +187,8 @@ int mas_devread(unsigned long *dest, int len)
179 int i; 187 int i;
180 188
181 /* handle read-back */ 189 /* handle read-back */
190 /* Remember, the MAS values are only 20 bits, so we set
191 the upper 12 bits to 0 */
182 i2c_start(); 192 i2c_start();
183 i2c_outb(MAS_DEV_WRITE); 193 i2c_outb(MAS_DEV_WRITE);
184 if (i2c_getack()) { 194 if (i2c_getack()) {
@@ -189,13 +199,24 @@ int mas_devread(unsigned long *dest, int len)
189 if (i2c_getack()) { 199 if (i2c_getack()) {
190 for (i=0;len;i++) { 200 for (i=0;len;i++) {
191 len--; 201 len--;
192 ptr[i*4+1] = i2c_inb(0); 202#ifdef ARCHOS_RECORDER
193 ptr[i*4+0] = i2c_inb(0); 203 i2c_inb(0); /* Dummy read */
204 ptr[i*4+0] = 0;
205 ptr[i*4+1] = i2c_inb(0) & 0x0f;
206 ptr[i*4+2] = i2c_inb(0);
207 if(len)
208 ptr[i*4+3] = i2c_inb(0);
209 else
210 ptr[i*4+3] = i2c_inb(1); /* NAK the last byte */
211#else
212 ptr[i*4+2] = i2c_inb(0);
194 ptr[i*4+3] = i2c_inb(0); 213 ptr[i*4+3] = i2c_inb(0);
214 ptr[i*4+0] = i2c_inb(0);
195 if(len) 215 if(len)
196 ptr[i*4+2] = i2c_inb(0); 216 ptr[i*4+1] = i2c_inb(0);
197 else 217 else
198 ptr[i*4+2] = i2c_inb(1); /* NAK the last byte */ 218 ptr[i*4+1] = i2c_inb(1); /* NAK the last byte */
219#endif
199 } 220 }
200 } 221 }
201 else 222 else
@@ -211,3 +232,116 @@ int mas_devread(unsigned long *dest, int len)
211 232
212 return ret; 233 return ret;
213} 234}
235
236#ifdef ARCHOS_RECORDER
237int mas_direct_config_read(unsigned char reg)
238{
239 unsigned char tmp[2];
240 int ret = 0;
241
242 i2c_start();
243 i2c_outb(MAS_DEV_WRITE);
244 if (i2c_getack()) {
245 i2c_outb(reg);
246 if (i2c_getack()) {
247 i2c_start();
248 i2c_outb(MAS_DEV_READ);
249 if (i2c_getack()) {
250 tmp[0] = i2c_inb(0);
251 tmp[1] = i2c_inb(1); /* NAK the last byte */
252 ret = (tmp[0] << 8) | tmp[1];
253 }
254 else
255 ret = -3;
256 }
257 else
258 ret = -2;
259 }
260 else
261 ret = -1;
262
263 i2c_stop();
264
265 return ret;
266}
267
268int mas_direct_config_write(unsigned char reg, unsigned int val)
269{
270 unsigned char buf[3];
271
272 buf[0] = reg;
273 buf[1] = (val >> 8) & 0xff;
274 buf[2] = val & 0xff;
275
276 /* send write command */
277 if (i2c_write(MAS_DEV_WRITE,buf,3))
278 {
279 return -1;
280 }
281 return 0;
282}
283
284int mas_codec_writereg(int reg, unsigned int val)
285{
286 int i;
287 unsigned char buf[16];
288
289 i=0;
290 buf[i++] = MAS_CODEC_WRITE;
291 buf[i++] = (reg >> 8) & 0xff;
292 buf[i++] = reg & 0xff;
293 buf[i++] = (val >> 8) & 0xff;
294 buf[i++] = val & 0xff;
295
296 /* send write command */
297 if (i2c_write(MAS_DEV_WRITE,buf,i))
298 {
299 return -1;
300 }
301 return 0;
302}
303
304int mas_codec_readreg(int reg)
305{
306 int i;
307 int ret = 0;
308 unsigned char buf[16];
309 unsigned char tmp[2];
310
311 i=0;
312 buf[i++] = MAS_CODEC_WRITE;
313 buf[i++] = (reg >> 8) & 0xff;
314 buf[i++] = reg & 0xff;
315
316 /* send read command */
317 if (i2c_write(MAS_DEV_WRITE,buf,i))
318 {
319 return -1;
320 }
321
322 i2c_start();
323 i2c_outb(MAS_DEV_WRITE);
324 if (i2c_getack()) {
325 i2c_outb(MAS_CODEC_READ);
326 if (i2c_getack()) {
327 i2c_start();
328 i2c_outb(MAS_DEV_READ);
329 if (i2c_getack()) {
330 tmp[0] = i2c_inb(0);
331 tmp[1] = i2c_inb(1); /* NAK the last byte */
332 ret = (tmp[0] << 8) | tmp[1];
333 }
334 else
335 ret = -3;
336 }
337 else
338 ret = -2;
339 }
340 else
341 ret = -1;
342
343 i2c_stop();
344
345 return ret;
346}
347#endif
diff --git a/firmware/drivers/mas.h b/firmware/drivers/mas.h
index a538bbcbf0..86aaabf786 100644
--- a/firmware/drivers/mas.h
+++ b/firmware/drivers/mas.h
@@ -25,14 +25,30 @@
25/* 25/*
26 MAS I2C defs 26 MAS I2C defs
27*/ 27*/
28#ifdef ARCHOS_RECORDER
29#define MAS_ADR 0x3c
30#define MAS_DEV_WRITE (MAS_ADR | 0x00)
31#define MAS_DEV_READ (MAS_ADR | 0x01)
32#else
28#define MAS_ADR 0x3a 33#define MAS_ADR 0x3a
29#define MAS_DEV_WRITE (MAS_ADR | 0x00) 34#define MAS_DEV_WRITE (MAS_ADR | 0x00)
30#define MAS_DEV_READ (MAS_ADR | 0x01) 35#define MAS_DEV_READ (MAS_ADR | 0x01)
36#endif
31 37
32/* registers..*/ 38/* registers..*/
39#ifdef ARCHOS_RECORDER
40#define MAS_DATA_WRITE 0x68
41#define MAS_DATA_READ 0x69
42#define MAS_CODEC_WRITE 0x6c
43#define MAS_CODEC_READ 0x6d
44#define MAS_CONTROL 0x6a
45#define MAS_DCCF 0x76
46#define MAS_DCFR 0x77
47#else
33#define MAS_DATA_WRITE 0x68 48#define MAS_DATA_WRITE 0x68
34#define MAS_DATA_READ 0x69 49#define MAS_DATA_READ 0x69
35#define MAS_CONTROL 0x6a 50#define MAS_CONTROL 0x6a
51#endif
36 52
37/* 53/*
38 * MAS register 54 * MAS register
@@ -45,6 +61,29 @@
45#define MAS_REG_KBASS 0x6b 61#define MAS_REG_KBASS 0x6b
46#define MAS_REG_KTREBLE 0x6f 62#define MAS_REG_KTREBLE 0x6f
47 63
64/*
65 * MAS commands
66 */
67#ifdef ARCHOS_RECORDER
68#define MAS_CMD_READ_ANCILLARY 0x50
69#define MAS_CMD_FAST_PRG_DL 0x60
70#define MAS_CMD_READ_IC_VER 0x70
71#define MAS_CMD_READ_REG 0xa0
72#define MAS_CMD_WRITE_REG 0xb0
73#define MAS_CMD_READ_D0_MEM 0xc0
74#define MAS_CMD_READ_D1_MEM 0xd0
75#define MAS_CMD_WRITE_D0_MEM 0xe0
76#define MAS_CMD_WRITE_D1_MEM 0xf0
77#else
78#define MAS_CMD_READ_ANCILLARY 0x30
79#define MAS_CMD_WRITE_REG 0x90
80#define MAS_CMD_WRITE_D0_MEM 0xa0
81#define MAS_CMD_WRITE_D1_MEM 0xb0
82#define MAS_CMD_READ_REG 0xd0
83#define MAS_CMD_READ_D0_MEM 0xe0
84#define MAS_CMD_READ_D1_MEM 0xf0
85#endif
86
48int mas_default_read(unsigned short *buf); 87int mas_default_read(unsigned short *buf);
49int mas_run(unsigned short address); 88int mas_run(unsigned short address);
50int mas_readmem(int bank, int addr, unsigned long* dest, int len); 89int mas_readmem(int bank, int addr, unsigned long* dest, int len);
@@ -53,5 +92,9 @@ int mas_devread(unsigned long *buf, int len);
53int mas_readreg(int reg); 92int mas_readreg(int reg);
54int mas_writereg(int reg, unsigned int val); 93int mas_writereg(int reg, unsigned int val);
55int dac_volume(unsigned int volume); 94int dac_volume(unsigned int volume);
95int mas_direct_config_read(unsigned char reg);
96int mas_direct_config_write(unsigned char reg, unsigned int val);
97int mas_codec_writereg(int reg, unsigned int val);
98int mas_codec_readreg(int reg);
56 99
57#endif 100#endif