Theme Editor: Put together a simple GUI to test going back and forth between a tree...
[kugel-rb.git] / firmware / drivers / mas.c
blob4f384d3b98832ae09a947dc3b89fe55c598910b1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "stdbool.h"
22 #include "config.h"
23 #include "sh7034.h"
24 #include "i2c.h"
25 #include "debug.h"
26 #include "mas.h"
27 #include "kernel.h"
28 #include "system.h"
29 #include "hwcompat.h"
31 static int mas_devread(unsigned long *dest, int len);
33 int mas_default_read(unsigned short *buf)
35 unsigned char *dest = (unsigned char *)buf;
36 int ret = 0;
38 i2c_begin();
40 i2c_start();
41 i2c_outb(MAS_DEV_WRITE);
42 if (i2c_getack()) {
43 i2c_outb(MAS_DATA_READ);
44 if (i2c_getack()) {
45 i2c_start();
46 i2c_outb(MAS_DEV_READ);
47 if (i2c_getack()) {
48 dest[0] = i2c_inb(0);
49 dest[1] = i2c_inb(1);
51 else
52 ret = -3;
54 else
55 ret = -2;
57 else
58 ret = -1;
60 i2c_stop();
62 i2c_end();
63 return ret;
66 int mas_run(unsigned short address)
68 int ret = 0;
69 unsigned char buf[3];
71 i2c_begin();
73 buf[0] = MAS_DATA_WRITE;
74 buf[1] = address >> 8;
75 buf[2] = address & 0xff;
77 /* send run command */
78 if (i2c_write(MAS_DEV_WRITE,buf,3))
80 ret = -1;
83 i2c_end();
84 return ret;
87 /* note: 'len' is number of 32-bit words, not number of bytes! */
88 int mas_readmem(int bank, int addr, unsigned long* dest, int len)
90 int ret = 0;
91 unsigned char buf[7];
93 i2c_begin();
95 buf[0] = MAS_DATA_WRITE;
96 buf[1] = bank?MAS_CMD_READ_D1_MEM:MAS_CMD_READ_D0_MEM;
97 buf[2] = 0x00;
98 buf[3] = (len & 0xff00) >> 8;
99 buf[4] = len & 0xff;
100 buf[5] = (addr & 0xff00) >> 8;
101 buf[6] = addr & 0xff;
103 /* send read command */
104 if (i2c_write(MAS_DEV_WRITE,buf,7))
106 ret = -1;
109 ret = mas_devread(dest, len);
111 i2c_end();
112 return ret;
115 /* note: 'len' is number of 32-bit words, not number of bytes! */
116 int mas_writemem(int bank, int addr, const unsigned long* src, int len)
118 int ret = 0;
119 int i, j;
120 unsigned char buf[60];
121 const unsigned char* ptr = (const unsigned char*)src;
123 i2c_begin();
125 i=0;
126 buf[i++] = MAS_DATA_WRITE;
127 buf[i++] = bank?MAS_CMD_WRITE_D1_MEM:MAS_CMD_WRITE_D0_MEM;
128 buf[i++] = 0x00;
129 buf[i++] = (len & 0xff00) >> 8;
130 buf[i++] = len & 0xff;
131 buf[i++] = (addr & 0xff00) >> 8;
132 buf[i++] = addr & 0xff;
134 j = 0;
135 while(len--) {
136 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
137 buf[i++] = 0;
138 buf[i++] = ptr[j+1];
139 buf[i++] = ptr[j+2];
140 buf[i++] = ptr[j+3];
141 #else
142 buf[i++] = ptr[j+2];
143 buf[i++] = ptr[j+3];
144 buf[i++] = 0;
145 buf[i++] = ptr[j+1];
146 #endif
147 j += 4;
150 /* send write command */
151 if (i2c_write(MAS_DEV_WRITE,buf,i))
153 ret = -1;
156 i2c_end();
157 return ret;
160 int mas_readreg(int reg)
162 int ret = 0;
163 unsigned char buf[16];
164 unsigned long value;
166 i2c_begin();
168 buf[0] = MAS_DATA_WRITE;
169 buf[1] = MAS_CMD_READ_REG | (reg >> 4);
170 buf[2] = (reg & 0x0f) << 4;
172 /* send read command */
173 if (i2c_write(MAS_DEV_WRITE,buf,3))
175 ret = -1;
177 else
179 if(mas_devread(&value, 1))
181 ret = -2;
183 else
185 ret = value;
189 i2c_end();
190 return ret;
193 int mas_writereg(int reg, unsigned int val)
195 int ret = 0;
196 unsigned char buf[5];
198 i2c_begin();
200 buf[0] = MAS_DATA_WRITE;
201 buf[1] = MAS_CMD_WRITE_REG | (reg >> 4);
202 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
203 buf[2] = ((reg & 0x0f) << 4) | (val >> 16 & 0x0f);
204 buf[3] = (val >> 8) & 0xff;
205 buf[4] = val & 0xff;
206 #else
207 buf[2] = ((reg & 0x0f) << 4) | (val & 0x0f);
208 buf[3] = (val >> 12) & 0xff;
209 buf[4] = (val >> 4) & 0xff;
210 #endif
212 /* send write command */
213 if (i2c_write(MAS_DEV_WRITE,buf,5))
215 ret = -1;
218 i2c_end();
219 return ret;
222 /* note: 'len' is number of 32-bit words, not number of bytes! */
223 static int mas_devread(unsigned long *dest, int len)
225 int ret = 0;
226 unsigned char* ptr = (unsigned char*)dest;
227 int i;
229 /* handle read-back */
230 /* Remember, the MAS values are only 20 bits, so we set
231 the upper 12 bits to 0 */
232 i2c_start();
233 i2c_outb(MAS_DEV_WRITE);
234 if (i2c_getack()) {
235 i2c_outb(MAS_DATA_READ);
236 if (i2c_getack()) {
237 i2c_start();
238 i2c_outb(MAS_DEV_READ);
239 if (i2c_getack()) {
240 for (i=0;len;i++) {
241 len--;
242 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
243 i2c_inb(0); /* Dummy read */
244 ptr[i*4+0] = 0;
245 ptr[i*4+1] = i2c_inb(0) & 0x0f;
246 ptr[i*4+2] = i2c_inb(0);
247 if(len)
248 ptr[i*4+3] = i2c_inb(0);
249 else
250 ptr[i*4+3] = i2c_inb(1); /* NAK the last byte */
251 #else
252 ptr[i*4+2] = i2c_inb(0);
253 ptr[i*4+3] = i2c_inb(0);
254 ptr[i*4+0] = i2c_inb(0);
255 if(len)
256 ptr[i*4+1] = i2c_inb(0);
257 else
258 ptr[i*4+1] = i2c_inb(1); /* NAK the last byte */
259 #endif
262 else
263 ret = -3;
265 else
266 ret = -2;
268 else
269 ret = -1;
271 i2c_stop();
273 return ret;
276 void mas_reset(void)
278 or_b(0x01, &PAIORH);
280 #if CONFIG_CODEC == MAS3507D
281 /* PB5 is "MAS enable". make it GPIO output and high */
282 PBCR2 &= ~0x0c00;
283 or_b(0x20, &PBIORL);
284 or_b(0x20, &PBDRL);
286 and_b(~0x01, &PADRH);
287 sleep(HZ/100);
288 or_b(0x01, &PADRH);
289 sleep(HZ/5);
290 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
291 if (HW_MASK & ATA_ADDRESS_200)
293 and_b(~0x01, &PADRH);
294 sleep(HZ/100);
295 or_b(0x01, &PADRH);
296 sleep(HZ/5);
298 else
300 /* Older recorder models don't invert the POR signal */
301 or_b(0x01, &PADRH);
302 sleep(HZ/100);
303 and_b(~0x01, &PADRH);
304 sleep(HZ/5);
306 #endif
309 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
310 int mas_direct_config_read(unsigned char reg)
312 int ret = 0;
313 unsigned char tmp[2];
315 i2c_begin();
317 i2c_start();
318 i2c_outb(MAS_DEV_WRITE);
319 if (i2c_getack()) {
320 i2c_outb(reg);
321 if (i2c_getack()) {
322 i2c_start();
323 i2c_outb(MAS_DEV_READ);
324 if (i2c_getack()) {
325 tmp[0] = i2c_inb(0);
326 tmp[1] = i2c_inb(1); /* NAK the last byte */
327 ret = (tmp[0] << 8) | tmp[1];
329 else
330 ret = -3;
332 else
333 ret = -2;
335 else
336 ret = -1;
338 i2c_stop();
340 i2c_end();
341 return ret;
344 int mas_direct_config_write(unsigned char reg, unsigned int val)
346 int ret = 0;
347 unsigned char buf[3];
349 i2c_begin();
351 buf[0] = reg;
352 buf[1] = (val >> 8) & 0xff;
353 buf[2] = val & 0xff;
355 /* send write command */
356 if (i2c_write(MAS_DEV_WRITE,buf,3))
358 ret = -1;
361 i2c_end();
362 return ret;
365 int mas_codec_writereg(int reg, unsigned int val)
367 int ret = 0;
368 unsigned char buf[5];
370 i2c_begin();
372 buf[0] = MAS_CODEC_WRITE;
373 buf[1] = (reg >> 8) & 0xff;
374 buf[2] = reg & 0xff;
375 buf[3] = (val >> 8) & 0xff;
376 buf[4] = val & 0xff;
378 /* send write command */
379 if (i2c_write(MAS_DEV_WRITE,buf,5))
381 ret = -1;
384 i2c_end();
385 return ret;
388 int mas_codec_readreg(int reg)
390 int ret = 0;
391 unsigned char buf[16];
392 unsigned char tmp[2];
394 i2c_begin();
396 buf[0] = MAS_CODEC_WRITE;
397 buf[1] = (reg >> 8) & 0xff;
398 buf[2] = reg & 0xff;
400 /* send read command */
401 if (i2c_write(MAS_DEV_WRITE,buf,3))
403 ret = -1;
405 else
407 i2c_start();
408 i2c_outb(MAS_DEV_WRITE);
409 if (i2c_getack()) {
410 i2c_outb(MAS_CODEC_READ);
411 if (i2c_getack()) {
412 i2c_start();
413 i2c_outb(MAS_DEV_READ);
414 if (i2c_getack()) {
415 tmp[0] = i2c_inb(0);
416 tmp[1] = i2c_inb(1); /* NAK the last byte */
417 ret = (tmp[0] << 8) | tmp[1];
419 else
420 ret = -4;
422 else
423 ret = -3;
425 else
426 ret = -2;
428 i2c_stop();
431 i2c_end();
432 return ret;
435 unsigned long mas_readver(void)
437 int ret = 0;
438 unsigned char buf[16];
439 unsigned long value;
441 i2c_begin();
443 buf[0] = MAS_DATA_WRITE;
444 buf[1] = MAS_CMD_READ_IC_VER;
445 buf[2] = 0;
447 /* send read command */
448 if (i2c_write(MAS_DEV_WRITE,buf,3))
450 ret = -1;
452 else
454 if(mas_devread(&value, 1))
456 ret = -2;
458 else
460 ret = value;
464 i2c_end();
465 return ret;
468 #endif
470 #if CONFIG_TUNER & S1A0903X01
471 static int pllfreq;
473 void mas_store_pllfreq(int freq)
475 pllfreq = freq;
478 int mas_get_pllfreq(void)
480 return pllfreq;
482 #endif