From: M. R. B. <mr...@0x...> - 2001-12-02 19:05:34
|
* Adrian McMenamin <ad...@mc...> on Sun, Dec 02, 2001: >=20 > Now, is it right to just copy a lump of memory over from user space in th= is=20 > way? >=20 Well even if it was ok (I don't know) semantically, you can't do it realistically for the AICA. Remember the discussion on dcdev? You can only copy so much data to AICA RAM at once - if you don't wait for the FIFO to be clear then you'll crash the AICA. > I haven't specifically allocated a buffer inside the sound RAM area - jus= t=20 > claimed it for the kernel when initiating the module and assumed that it'= s=20 > there - the function doesn't fail in the sense that the -EFAULT error is= =20 > never reported, but does that mean it has actually worked? >=20 > Should I be allocating a buffer first and copying the data from user spac= e=20 > into that? >=20 Damn, I need time :P. Check out the latest KOS which (apparently) has AICA DMA working. You want to use DMA. You have to use DMA. It's DMA or die =2E.. ok maybe that's too much. But that's the only way you'll effectively get anything to AICA RAM without choking on the FIFO. I still have to sit down and write the register test to see if it's feasible to play with the AICA regs directly from the SH4. Or you could :P. > Perhaps I am just clutching at straws. >=20 What you need is a AICA test program. It doesn't even have to be kernel related, and you can provide your own inX() outX() routines that treat the AICA registers as latches and checks *every* value you get back from the AICA. I still believe you can play with AICA registers from the SH4, take a look at this: =46rom arch/sh/kernel/rtc-aica.c: /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 * 16-bit registers.*/ #define AICA_RTC_SECS_H 0xa0710000 #define AICA_RTC_SECS_L 0xa0710004 /** * aica_rtc_gettimeofday - Get the time from the AICA RTC * @tv: pointer to resulting timeval * * Grabs the current RTC seconds counter and adjusts it to the Unix * Epoch. */ void aica_rtc_gettimeofday(struct timeval *tv) { unsigned long val1, val2; do { val1 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); val2 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); } while (val1 !=3D val2); tv->tv_sec =3D val1 - TWENTY_YEARS; /* Can't get microseconds with just a seconds counter. */ tv->tv_usec =3D 0; } Now, you see how I'm grabbing those registers? In your test program (or your kernel driver), write a generic routine that does just that. You may end up with valid values after all. The aica_rtc_settimeofday() is basically the same, except at the top of the while loop, there are ctrl_outl() statements that write the register value. You could even throw the FIFO check in there just to be on the safe side. Let's prove those dcdev'rs wrong :P. Let me know what you come up with, and I'll try to work on something later. Hope this helps, M. R. |