a bit of code cleanup.. use a single function to get the statusbar height (or lack...
[Rockbox.git] / firmware / drivers / mas.c
blob6a1b7cde9adf282cc2b65d649a8421c1a3fa2d21
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "stdbool.h"
20 #include "config.h"
21 #include "sh7034.h"
22 #include "i2c.h"
23 #include "debug.h"
24 #include "mas.h"
25 #include "kernel.h"
26 #include "system.h"
27 #include "hwcompat.h"
29 static int mas_devread(unsigned long *dest, int len);
31 int mas_default_read(unsigned short *buf)
33 unsigned char *dest = (unsigned char *)buf;
34 int ret = 0;
36 i2c_begin();
38 i2c_start();
39 i2c_outb(MAS_DEV_WRITE);
40 if (i2c_getack()) {
41 i2c_outb(MAS_DATA_READ);
42 if (i2c_getack()) {
43 i2c_start();
44 i2c_outb(MAS_DEV_READ);
45 if (i2c_getack()) {
46 dest[0] = i2c_inb(0);
47 dest[1] = i2c_inb(1);
49 else
50 ret = -3;
52 else
53 ret = -2;
55 else
56 ret = -1;
58 i2c_stop();
60 i2c_end();
61 return ret;
64 int mas_run(unsigned short address)
66 int ret = 0;
67 unsigned char buf[3];
69 i2c_begin();
71 buf[0] = MAS_DATA_WRITE;
72 buf[1] = address >> 8;
73 buf[2] = address & 0xff;
75 /* send run command */
76 if (i2c_write(MAS_DEV_WRITE,buf,3))
78 ret = -1;
81 i2c_end();
82 return ret;
85 /* note: 'len' is number of 32-bit words, not number of bytes! */
86 int mas_readmem(int bank, int addr, unsigned long* dest, int len)
88 int ret = 0;
89 unsigned char buf[7];
91 i2c_begin();
93 buf[0] = MAS_DATA_WRITE;
94 buf[1] = bank?MAS_CMD_READ_D1_MEM:MAS_CMD_READ_D0_MEM;
95 buf[2] = 0x00;
96 buf[3] = (len & 0xff00) >> 8;
97 buf[4] = len & 0xff;
98 buf[5] = (addr & 0xff00) >> 8;
99 buf[6] = addr & 0xff;
101 /* send read command */
102 if (i2c_write(MAS_DEV_WRITE,buf,7))
104 ret = -1;
107 ret = mas_devread(dest, len);
109 i2c_end();
110 return ret;
113 /* note: 'len' is number of 32-bit words, not number of bytes! */
114 int mas_writemem(int bank, int addr, const unsigned long* src, int len)
116 int ret = 0;
117 int i, j;
118 unsigned char buf[60];
119 const unsigned char* ptr = (const unsigned char*)src;
121 i2c_begin();
123 i=0;
124 buf[i++] = MAS_DATA_WRITE;
125 buf[i++] = bank?MAS_CMD_WRITE_D1_MEM:MAS_CMD_WRITE_D0_MEM;
126 buf[i++] = 0x00;
127 buf[i++] = (len & 0xff00) >> 8;
128 buf[i++] = len & 0xff;
129 buf[i++] = (addr & 0xff00) >> 8;
130 buf[i++] = addr & 0xff;
132 j = 0;
133 while(len--) {
134 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
135 buf[i++] = 0;
136 buf[i++] = ptr[j+1];
137 buf[i++] = ptr[j+2];
138 buf[i++] = ptr[j+3];
139 #else
140 buf[i++] = ptr[j+2];
141 buf[i++] = ptr[j+3];
142 buf[i++] = 0;
143 buf[i++] = ptr[j+1];
144 #endif
145 j += 4;
148 /* send write command */
149 if (i2c_write(MAS_DEV_WRITE,buf,i))
151 ret = -1;
154 i2c_end();
155 return ret;
158 int mas_readreg(int reg)
160 int ret = 0;
161 unsigned char buf[16];
162 unsigned long value;
164 i2c_begin();
166 buf[0] = MAS_DATA_WRITE;
167 buf[1] = MAS_CMD_READ_REG | (reg >> 4);
168 buf[2] = (reg & 0x0f) << 4;
170 /* send read command */
171 if (i2c_write(MAS_DEV_WRITE,buf,3))
173 ret = -1;
175 else
177 if(mas_devread(&value, 1))
179 ret = -2;
181 else
183 ret = value;
187 i2c_end();
188 return ret;
191 int mas_writereg(int reg, unsigned int val)
193 int ret = 0;
194 unsigned char buf[5];
196 i2c_begin();
198 buf[0] = MAS_DATA_WRITE;
199 buf[1] = MAS_CMD_WRITE_REG | (reg >> 4);
200 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
201 buf[2] = ((reg & 0x0f) << 4) | (val >> 16 & 0x0f);
202 buf[3] = (val >> 8) & 0xff;
203 buf[4] = val & 0xff;
204 #else
205 buf[2] = ((reg & 0x0f) << 4) | (val & 0x0f);
206 buf[3] = (val >> 12) & 0xff;
207 buf[4] = (val >> 4) & 0xff;
208 #endif
210 /* send write command */
211 if (i2c_write(MAS_DEV_WRITE,buf,5))
213 ret = -1;
216 i2c_end();
217 return ret;
220 /* note: 'len' is number of 32-bit words, not number of bytes! */
221 static int mas_devread(unsigned long *dest, int len)
223 int ret = 0;
224 unsigned char* ptr = (unsigned char*)dest;
225 int i;
227 /* handle read-back */
228 /* Remember, the MAS values are only 20 bits, so we set
229 the upper 12 bits to 0 */
230 i2c_start();
231 i2c_outb(MAS_DEV_WRITE);
232 if (i2c_getack()) {
233 i2c_outb(MAS_DATA_READ);
234 if (i2c_getack()) {
235 i2c_start();
236 i2c_outb(MAS_DEV_READ);
237 if (i2c_getack()) {
238 for (i=0;len;i++) {
239 len--;
240 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
241 i2c_inb(0); /* Dummy read */
242 ptr[i*4+0] = 0;
243 ptr[i*4+1] = i2c_inb(0) & 0x0f;
244 ptr[i*4+2] = i2c_inb(0);
245 if(len)
246 ptr[i*4+3] = i2c_inb(0);
247 else
248 ptr[i*4+3] = i2c_inb(1); /* NAK the last byte */
249 #else
250 ptr[i*4+2] = i2c_inb(0);
251 ptr[i*4+3] = i2c_inb(0);
252 ptr[i*4+0] = i2c_inb(0);
253 if(len)
254 ptr[i*4+1] = i2c_inb(0);
255 else
256 ptr[i*4+1] = i2c_inb(1); /* NAK the last byte */
257 #endif
260 else
261 ret = -3;
263 else
264 ret = -2;
266 else
267 ret = -1;
269 i2c_stop();
271 return ret;
274 void mas_reset(void)
276 or_b(0x01, &PAIORH);
278 #if CONFIG_CODEC == MAS3507D
279 /* PB5 is "MAS enable". make it GPIO output and high */
280 PBCR2 &= ~0x0c00;
281 or_b(0x20, &PBIORL);
282 or_b(0x20, &PBDRL);
284 and_b(~0x01, &PADRH);
285 sleep(HZ/100);
286 or_b(0x01, &PADRH);
287 sleep(HZ/5);
288 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
289 if (HW_MASK & ATA_ADDRESS_200)
291 and_b(~0x01, &PADRH);
292 sleep(HZ/100);
293 or_b(0x01, &PADRH);
294 sleep(HZ/5);
296 else
298 /* Older recorder models don't invert the POR signal */
299 or_b(0x01, &PADRH);
300 sleep(HZ/100);
301 and_b(~0x01, &PADRH);
302 sleep(HZ/5);
304 #endif
307 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
308 int mas_direct_config_read(unsigned char reg)
310 int ret = 0;
311 unsigned char tmp[2];
313 i2c_begin();
315 i2c_start();
316 i2c_outb(MAS_DEV_WRITE);
317 if (i2c_getack()) {
318 i2c_outb(reg);
319 if (i2c_getack()) {
320 i2c_start();
321 i2c_outb(MAS_DEV_READ);
322 if (i2c_getack()) {
323 tmp[0] = i2c_inb(0);
324 tmp[1] = i2c_inb(1); /* NAK the last byte */
325 ret = (tmp[0] << 8) | tmp[1];
327 else
328 ret = -3;
330 else
331 ret = -2;
333 else
334 ret = -1;
336 i2c_stop();
338 i2c_end();
339 return ret;
342 int mas_direct_config_write(unsigned char reg, unsigned int val)
344 int ret = 0;
345 unsigned char buf[3];
347 i2c_begin();
349 buf[0] = reg;
350 buf[1] = (val >> 8) & 0xff;
351 buf[2] = val & 0xff;
353 /* send write command */
354 if (i2c_write(MAS_DEV_WRITE,buf,3))
356 ret = -1;
359 i2c_end();
360 return ret;
363 int mas_codec_writereg(int reg, unsigned int val)
365 int ret = 0;
366 unsigned char buf[5];
368 i2c_begin();
370 buf[0] = MAS_CODEC_WRITE;
371 buf[1] = (reg >> 8) & 0xff;
372 buf[2] = reg & 0xff;
373 buf[3] = (val >> 8) & 0xff;
374 buf[4] = val & 0xff;
376 /* send write command */
377 if (i2c_write(MAS_DEV_WRITE,buf,5))
379 ret = -1;
382 i2c_end();
383 return ret;
386 int mas_codec_readreg(int reg)
388 int ret = 0;
389 unsigned char buf[16];
390 unsigned char tmp[2];
392 i2c_begin();
394 buf[0] = MAS_CODEC_WRITE;
395 buf[1] = (reg >> 8) & 0xff;
396 buf[2] = reg & 0xff;
398 /* send read command */
399 if (i2c_write(MAS_DEV_WRITE,buf,3))
401 ret = -1;
403 else
405 i2c_start();
406 i2c_outb(MAS_DEV_WRITE);
407 if (i2c_getack()) {
408 i2c_outb(MAS_CODEC_READ);
409 if (i2c_getack()) {
410 i2c_start();
411 i2c_outb(MAS_DEV_READ);
412 if (i2c_getack()) {
413 tmp[0] = i2c_inb(0);
414 tmp[1] = i2c_inb(1); /* NAK the last byte */
415 ret = (tmp[0] << 8) | tmp[1];
417 else
418 ret = -4;
420 else
421 ret = -3;
423 else
424 ret = -2;
426 i2c_stop();
429 i2c_end();
430 return ret;
433 unsigned long mas_readver(void)
435 int ret = 0;
436 unsigned char buf[16];
437 unsigned long value;
439 i2c_begin();
441 buf[0] = MAS_DATA_WRITE;
442 buf[1] = MAS_CMD_READ_IC_VER;
443 buf[2] = 0;
445 /* send read command */
446 if (i2c_write(MAS_DEV_WRITE,buf,3))
448 ret = -1;
450 else
452 if(mas_devread(&value, 1))
454 ret = -2;
456 else
458 ret = value;
462 i2c_end();
463 return ret;
466 #endif