* Re: [PATCH, 2.6.17-rc4-git10] ieee80211softmac_io.c: fix warning "defined but not used"
From: John W. Linville @ 2006-05-26 19:24 UTC (permalink / raw)
To: Toralf Förster; +Cc: netdev, linuxppc-dev
In-Reply-To: <200605231549.43430.toralf.foerster@gmx.de>
On Tue, May 23, 2006 at 03:49:40PM +0200, Toralf Förster wrote:
> Got this compiler warning today and Johannes Berg <johannes@sipsolutions.net> wrote:
>
> Yeah, known 'bug', we have that code there but never use it. Feel free
> to submit a patch (to John Linville, CC netdev and softmac-dev) to
> remove it.
>
> Signed-off-by: Toralf Foerster <toralf.foerster@gmx.de>
This patch is whitespace-damaged. Please teach your mailer not to
convert tabs to spaces and resubmit.
Thanks!
John
> --- linux-2.6.17-rc4-git10-pcie-rme9652/net/ieee80211/softmac/ieee80211softmac_io.c.old 2006-05-12 09:44:47.000000000 +0200
> +++ linux-2.6.17-rc4-git10-pcie-rme9652/net/ieee80211/softmac/ieee80211softmac_io.c 2006-05-23 15:16:38.000000000 +0200
> @@ -456,31 +456,3 @@
> return IEEE80211_2ADDR_LEN;
> }
>
> -
> -/* Sends a control packet */
> -static int
> -ieee80211softmac_send_ctl_frame(struct ieee80211softmac_device *mac,
> - struct ieee80211softmac_network *net, u32 type, u32 arg)
> -{
> - void *pkt = NULL;
> - u32 pkt_size = 0;
<snip>
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
* Re: [openib-general] [PATCH 06/16] ehca: interrupt handling routines
From: Roland Dreier @ 2006-05-26 20:06 UTC (permalink / raw)
To: Heiko J Schick
Cc: linux-kernel, openib-general, linuxppc-dev, Christoph Raisch,
Hoang-Nam Nguyen, Marcus Eder
In-Reply-To: <4468BD63.6070509@de.ibm.com>
> + for_each_online_cpu(cpu) {
> + task = create_comp_task(pool, cpu);
> + if (task) {
> + kthread_bind(task, cpu);
> + wake_up_process(task);
> + }
> + }
How does this creation of a thread pool work with respect to CPU
hotplug? What happens if a CPU goes away? How about if only one CPU
is running when the driver is loaded, and then 15 more are hot-added?
> + for (i = 0; i < NR_CPUS; i++) {
> + if (cpu_online(i))
> + destroy_comp_task(pool, i);
> + }
And it seems in the destroy function, you will possibly leak threads
or try to kill a non-existent thread if the set of online CPUs has
changed since the driver started...
- R.
^ permalink raw reply
* 440gx dma transfer with no data change at dest
From: John Lange @ 2006-05-26 20:58 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 401 bytes --]
Hi Kevin
I saw a posting from March where you were asking about problems doing
memory to memory DMA transfers with the ppc4xx_dma module of Linux. I'm
curious if you figured out that issue. Would you be kind enough to
share how you fixed the issue you were having? I would sure appreciate
a snippet of working example code if it's not proprietary.
Best regards,
John
[-- Attachment #2: Type: text/html, Size: 2267 bytes --]
^ permalink raw reply
* Re: [snd] looking for layout-ids
From: Benjamin Herrenschmidt @ 2006-05-26 21:41 UTC (permalink / raw)
To: Eddy Petrişor; +Cc: linuxppc-dev list, Johannes Berg, debian-powerpc
In-Reply-To: <60381eeb0605260902p4420757ai3669aba711122014@mail.gmail.com>
On Fri, 2006-05-26 at 19:02 +0300, Eddy Petrişor wrote:
> On 5/25/06, Johannes Berg <johannes@sipsolutions.net> wrote:
> > Hey,
>
> Hi,
>
> > [1] to find your layout-id, execute the following:
> >
> > find /proc/device-tree/ -name layout-id | xargs hexdump -e '1/4 "0x%x\n"'
> >
> > If you get no output, you have no layout-id property. If you do get
>
> What are the plans for machines without layout-id, like the 5,2 model?
> Will there be any alsa/aoa support at some point?
There will be, but let's get the ones with layout-id first since
snd-powermac should work on the older ones.
Ben.
^ permalink raw reply
* Re: [RFC] snd-aoa and interrupts (headphone detection etc)
From: Benjamin Herrenschmidt @ 2006-05-26 21:45 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev list
In-Reply-To: <1148055359.6228.20.camel@johannes.berg>
> The problematic part is things that the codec must control. Say we want
> line-in detection to automatically switch to line-in if microphone is
> selected (does anyone ever want this?). Then the problem is that the
> interrupt arrives at the GPIO layer, and I can easily make it seen in
> the fabric too. However, then propagating it to the codec is a bit
> harder. Or we don't have it in the fabric but have the codec register
> for that interrupt (through our GPIO layer). This is the first option.
No. I don't think the codecs should mess with the GPIOs directly. The
policy should be implemented in the fabric. If in some case you need to
change some codec settings, then the codec shall provide an accessor for
doing so.
> The second option is changing the whole in-/output control code that we
> have and moving it from the codec to the fabric layer. The fabric
> already knows what in- and outputs a codec has (in order to know what is
> connected), hence if we added a codec driver function to turn on/off any
> in- or output we could have the fabric control this. But then we'd also
> have to make known to the codec which of those are mutually exclusive,
> and generally make it more complicated.
We don't have to make known to the codec, we just turn on/off the right
ones.
> I currently favour the first option, the codec driver can know when it
> makes sense to try registering the interrupt (if it isn't present it
> fails anyway) and then do the appropriate stuff (possibly giving the
> user a choice).
I disagree :) But then, it's your code :)
Ben.
^ permalink raw reply
* Howto allocate non-cacheable memory
From: Muneeswaran P - TLS, Chennai @ 2006-05-27 5:38 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
How to allocate non-cacheable kernel memory ?
Pls help me.
I am writing device driver (kernel 2.6 ) for PCI-X card.
Pls clarify the following doubts:
1. DPRAM is memory mapped to PCI-X card.
2. I have to transfer data from main memory to DPRAM using bus
master concept and vice-versa.
3. How to make this memory area as non-cacheable one ?=20
4. Whether DMA mapping (pci_map_single() call ) should be done for
both DPRAM and main memory ?
4.a) I will get the physical address of DPRAM memory (memory
mapped to PCI-X card) from BAR-0 register. Can i use this physical =
addres
directly for data transer using bus master (without pci_map_single() =
call.)
?
4.b) How to make main memory area as non-cacheable one ?
Regards,
Munees.
DISCLAIMER=20
The contents of this e-mail and any attachment(s) are confidential and =
intended for the=20
named recipient(s) only. It shall not attach any liability on the =
originator or HCL or its=20
affiliates. Any views or opinions presented in this email are solely =
those of the author and=20
may not necessarily reflect the opinions of HCL or its affiliates. Any =
form of reproduction,=20
dissemination, copying, disclosure, modification, distribution and / or =
publication of this=20
message without the prior written consent of the author of this e-mail =
is strictly=20
prohibited. If you have received this email in error please delete it =
and notify the sender=20
immediately. Before opening any mail and attachments please check them =
for viruses and=20
defect.
^ permalink raw reply
* [PATCH, 2.6.17-rc5-git3] ieee80211softmac_io.c: fix warning "defined but not used"
From: Toralf Förster @ 2006-05-27 9:04 UTC (permalink / raw)
To: John W. Linville; +Cc: netdev, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1755 bytes --]
Got this compiler warning and Johannes Berg <johannes@sipsolutions.net> wrote:
Yeah, known 'bug', we have that code there but never use it. Feel free
to submit a patch (to John Linville, CC netdev and softmac-dev) to
remove it.
Signed-off-by: Toralf Foerster <toralf.foerster@gmx.de>
--- src/net/ieee80211/softmac/ieee80211softmac_io.c_orig 2006-05-27 10:50:56.000000000 +0200
+++ src/net/ieee80211/softmac/ieee80211softmac_io.c 2006-05-27 10:51:45.000000000 +0200
@@ -440,47 +440,3 @@
return 0;
}
-
-/* Create an rts/cts frame */
-static u32
-ieee80211softmac_rts_cts(struct ieee80211_hdr_2addr **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
- u32 type)
-{
- /* Allocate Packet */
- (*pkt) = kmalloc(IEEE80211_2ADDR_LEN, GFP_ATOMIC);
- memset(*pkt, 0, IEEE80211_2ADDR_LEN);
- if((*pkt) == NULL)
- return 0;
- ieee80211softmac_hdr_2addr(mac, (*pkt), type, net->bssid);
- return IEEE80211_2ADDR_LEN;
-}
-
-
-/* Sends a control packet */
-static int
-ieee80211softmac_send_ctl_frame(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net, u32 type, u32 arg)
-{
- void *pkt = NULL;
- u32 pkt_size = 0;
-
- switch(type) {
- case IEEE80211_STYPE_RTS:
- case IEEE80211_STYPE_CTS:
- pkt_size = ieee80211softmac_rts_cts((struct ieee80211_hdr_2addr **)(&pkt), mac, net, type);
- break;
- default:
- printkl(KERN_DEBUG PFX "Unsupported Control Frame type: %i\n", type);
- return -EINVAL;
- }
-
- if(pkt_size == 0)
- return -ENOMEM;
-
- /* Send the packet to the ieee80211 layer for tx */
- ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *) pkt, pkt_size);
-
- kfree(pkt);
- return 0;
-}
--
MfG/Sincerely
Toralf Förster
[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]
^ permalink raw reply
* Re: [PATCH] force 64bit mode in system_reset_fwnmi for broken POWER4 firmware
From: Olaf Hering @ 2006-05-27 11:34 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17526.59069.781220.922878@cargo.ozlabs.ibm.com>
On Fri, May 26, Paul Mackeras wrote:
> Olaf Hering writes:
>
> > According to this change for EXCEPTION_PROLOG_COMMON, I get still into
> > decremeter_common, but its not fatal anymore because the cpu is now in
> > 64bit mode and the stack is forced to PACAKSAVE(r13).
> >
> > subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
> > beq- 1f; \
> > ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
> > -1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
> > +1: \
> > + cmpdi cr1,r29,0x42; \
>
> Ummm, what's r29 supposed to have in it here?
>
> > + bne cr1,2f; \
> > + li r29,2f@l; \
>
> And why are we setting it?
>
> Does it look like the SRR0 and SRR1 values are correct when we get
> this problem occurring? Is it just the MSR that is bogus?
I looked into this again, my debug patch was wrong. I cant rely on the
hello32, r29 has to be set in the system_reset path. This is the
register dump. It shows that the cpus are in 32bit mode, and that
system_reset_fwnmi calls system_reset_common correctly.
0:mon> r
R00 = 000000001000036c R16 = 0000000000000042
R01 = 00000000ffe96ad0 R17 = 0000000000000042
R02 = 000000001009b470 R18 = 0000000000000042
R03 = 0000000000000009 R19 = 0000000000000042
R04 = 000000001002228c R20 = 0000000000000042
R05 = 0000000040042082 R21 = 0000000000000042
R06 = 0000000000004000 R22 = 0000000000000042
R07 = 0000000010008af0 R23 = 0000000000000042
R08 = 0000000000000000 R24 = 0000000000000042
R09 = 0000000000000000 R25 = 0000000000000042
R10 = 8000000000001032 R26 = 0000000000000042
R11 = 00000000ffe96a50 R27 = 0000000000000042
R12 = 0000000020000082 R28 = 0000000000000042
R13 = 000000001009a410 R29 = 0000000000003220
R14 = 0000000000000042 R30 = 0000000000001002
R15 = 0000000000000042 R31 = a000000000001032
pc = 00000000100003b4
lr = 000000001000036c
msr = 000000000000d032 cr = 20000082
ctr = 0000000000032ddc xer = 00000000000fffff trap = 100
0:mon> c1
1:mon> r
R00 = 000000001000036c R16 = 0000000000000042
R01 = 00000000ffe96ad0 R17 = 0000000000000042
R02 = 000000001009b470 R18 = 0000000000000042
R03 = 0000000000000007 R19 = 0000000000000042
R04 = 000000001002228c R20 = 0000000000000042
R05 = 0000000040022082 R21 = 0000000000000042
R06 = 0000000000004000 R22 = 0000000000000042
R07 = 0000000010008af0 R23 = 0000000000000042
R08 = 0000000000000000 R24 = 0000000000000042
R09 = 0000000000000000 R25 = 0000000000000042
R10 = 8000000000001032 R26 = 0000000000000042
R11 = 00000000ffe96a50 R27 = 0000000000000042
R12 = 0000000020000082 R28 = 0000000000000042
R13 = 000000001009a410 R29 = 0000000000003220
R14 = 0000000000000042 R30 = 0000000000001002
R15 = 0000000000000042 R31 = a000000000001032
pc = 00000000100003b4
lr = 000000001000036c
msr = 000000000000d032 cr = 20000082
ctr = 0000000000032ddc xer = 00000000000fffff trap = 100
Index: linux-2.6/arch/powerpc/kernel/head_64.S
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/head_64.S
+++ linux-2.6/arch/powerpc/kernel/head_64.S
@@ -211,6 +211,31 @@ exception_marker:
ori reg,reg,(label)@l; /* virt addr of handler ... */
#endif
+#define EXCEPTION_PROLOG_PSERIES_BROKEN_POWER4_FIRMWARE(area, label) \
+ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRN_SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9; \
+ clrrdi r12,r13,32; /* get high part of &label */ \
+ mfmsr r10; \
+ mr r30,r10; \
+ li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \
+ rldicr r11,r11,61,2; /* (5 << 61) */ \
+ or r10,r10,r11; \
+ mfspr r11,SPRN_SRR0; /* save SRR0 */ \
+ LOAD_HANDLER(r12,label) \
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
+ mtspr SPRN_SRR0,r12; \
+ mfspr r12,SPRN_SRR1; /* and SRR1 */ \
+ mr r31,r10; \
+ mtspr SPRN_SRR1,r10; \
+ rfid; \
+ b . /* prevent speculative execution */
+
#define EXCEPTION_PROLOG_PSERIES(area, label) \
mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
@@ -269,7 +294,12 @@ exception_marker:
subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
beq- 1f; \
ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
-1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
+1: \
+ cmpdi cr1,r29,0x42; \
+ bne cr1,2f; \
+ li r29,2f@l; \
+2: ; \
+ cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
bge- cr1,bad_stack; /* abort if it is */ \
std r9,_CCR(r1); /* save CR in stackframe */ \
std r11,_NIP(r1); /* save SRR0 in stackframe */ \
@@ -600,14 +630,15 @@ slb_miss_user_pseries:
system_reset_fwnmi:
HMT_MEDIUM
mtspr SPRN_SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+ li r29,0x42
+ EXCEPTION_PROLOG_PSERIES_BROKEN_POWER4_FIRMWARE(PACA_EXGEN, system_reset_common)
.globl machine_check_fwnmi
.align 7
machine_check_fwnmi:
HMT_MEDIUM
mtspr SPRN_SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+ EXCEPTION_PROLOG_PSERIES_BROKEN_POWER4_FIRMWARE(PACA_EXMC, machine_check_common)
#ifdef CONFIG_PPC_ISERIES
/*** ISeries-LPAR interrupt handlers ***/
^ permalink raw reply
* please pull powerpc.git 'merge' branch
From: Paul Mackerras @ 2006-05-27 13:17 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev
Linus,
Please do a pull from the "merge" branch of
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git
There are 3 commits there: an update to MAINTAINERS, a fix for the
"Maple" PPC970FX evaluation boards, and a fix for the Freescale
embedded 8272 processor that is apparently needed for the console to
work on those chips. These fixes won't affect any other platforms and
are safe to go in for 2.6.17 IMO.
Thanks,
Paul.
MAINTAINERS | 4 +--
arch/powerpc/kernel/prom_init.c | 48 +++++++++++++++++++++++++++++--
arch/ppc/platforms/mpc8272ads_setup.c | 10 +++---
arch/ppc/syslib/pq2_devices.c | 16 +++++-----
arch/ppc/syslib/pq2_sys.c | 8 +++--
drivers/serial/cpm_uart/cpm_uart_core.c | 8 +++--
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 2 +
7 files changed, 70 insertions(+), 26 deletions(-)
commit 54f4ee183aea859eb09f141dad3fc3c6f4fe0446
Author: Hollis Blanchard <hollisb@us.ibm.com>
Date: Thu May 25 16:36:53 2006 -0500
[PATCH] powerpc: fix RTC/NVRAM accesses on Maple
Due to a firmware device tree bug, RTC and NVRAM accesses (including
halt/reboot) on Maple have been broken since January, when an untested
build fix went in. This code patches the device tree in Linux.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
commit 8e30a9a299ca30b6c4072c2182238d5f5dd1590d
Author: Vitaly Bordug <vbordug@ru.mvista.com>
Date: Wed May 24 21:40:18 2006 +0400
[PATCH] ppc32 CPM_UART: various fixes for pq2 uart users
This fixes various odd things that missed update together with cpm_uart
platform_device move. Unified resources names, restructurisation, etc.
Also, addressed issue with recent phys/virt translation rework. Being
cache-coherent, CPM2's do alloc_bootmem() for the console stuff, and it was
used to treat console buffer descriptor mapping 1:1 (as in CPM1 case),
which is definitely wrong.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
commit 6d923f98fe0f31c174ace92f8b680d0d153663aa
Author: Arthur Othieno <apgo@patchbomb.org>
Date: Fri May 19 06:22:23 2006 -0400
[PATCH] powerpc: linuxppc64.org no more
http://linuxppc64.org has long been a redirect to the canonical
http://penguinppc.org/ppc64/ -- update all instances accordingly,
as ACKed by Hollis:
On Wed, Jan 18, 2006 at 09:48:08AM -0600, Hollis Blanchard wrote:
> On Wed, 2006-01-18 at 13:07 +0100, Olaf Hering wrote:
> > On Wed, Jan 18, Arthur Othieno wrote:
> > >
> > > What about the s/linuxppc64\.org/penguinppc\.org/g case? Or is
> > > penguinppc64.org preferable? Or am I just taking it too far? ;)
> >
> > They are redirected on DNS or HTTP level.
>
> HTTP level, but that doesn't answer his question.
>
> As the maintainer of that site, I would prefer to remove the
> linuxppc64.org reference.
Signed-off-by: Arthur Othieno <apgo@patchbomb.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
^ permalink raw reply
* Re: [PATCH] make ams work with latest kernels
From: Pavel Machek @ 2006-05-26 17:39 UTC (permalink / raw)
To: Stelian Pop
Cc: Andrew Morton, linuxppc-dev list, Johannes Berg,
Linux Kernel list
In-Reply-To: <1148465069.6723.26.camel@localhost.localdomain>
Hi!
> From: Stelian Pop <stelian@popies.net>
>
> This driver provides support for the Apple Motion Sensor (ams),
> which provides an accelerometer and other misc. data.
> Some Apple PowerBooks (the series the PowerBook5,6 falls into,
> later ones have a slightly different one the driver doesn't handle)
> are supported. The accelerometer data is readable via sysfs.
>
> This driver also provides an absolute input class device, allowing
> the laptop to act as a pinball machine-esque joystick.
Is it useful to have /sysfs interface when we already have same data
available as joystick?
--
Thanks for all the (sleeping) penguins.
^ permalink raw reply
* Re: [PATCH] make ams work with latest kernels
From: Johannes Berg @ 2006-05-27 20:06 UTC (permalink / raw)
To: Pavel Machek; +Cc: Andrew Morton, Linux Kernel list, linuxppc-dev list
In-Reply-To: <20060526173908.GA3357@ucw.cz>
[-- Attachment #1: Type: text/plain, Size: 417 bytes --]
On Fri, 2006-05-26 at 17:39 +0000, Pavel Machek wrote:
> > This driver also provides an absolute input class device, allowing
> > the laptop to act as a pinball machine-esque joystick.
>
> Is it useful to have /sysfs interface when we already have same data
> available as joystick?
Might be useful if you need to turn off the "joystick" because X gets
confused with it. Other than that, no.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply
* Re: [PATCH] make ams work with latest kernels
From: Stelian Pop @ 2006-05-27 20:31 UTC (permalink / raw)
To: Johannes Berg
Cc: Andrew Morton, linuxppc-dev list, Linux Kernel list, Pavel Machek
In-Reply-To: <1148760414.16989.59.camel@johannes.berg>
Le samedi 27 mai 2006 à 22:06 +0200, Johannes Berg a écrit :
> On Fri, 2006-05-26 at 17:39 +0000, Pavel Machek wrote:
>
> > > This driver also provides an absolute input class device, allowing
> > > the laptop to act as a pinball machine-esque joystick.
> >
> > Is it useful to have /sysfs interface when we already have same data
> > available as joystick?
>
> Might be useful if you need to turn off the "joystick" because X gets
> confused with it. Other than that, no.
/sysfs interface also exports the 'z' coordinate, the input interface
does not.
Stelian.
--
Stelian Pop <stelian@popies.net>
^ permalink raw reply
* Re: [RFC] snd-aoa and interrupts (headphone detection etc)
From: Johannes Berg @ 2006-05-27 20:41 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1148679918.8089.166.camel@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 1825 bytes --]
On Sat, 2006-05-27 at 07:45 +1000, Benjamin Herrenschmidt wrote:
> > The problematic part is things that the codec must control. Say we want
> > line-in detection to automatically switch to line-in if microphone is
> > selected (does anyone ever want this?). Then the problem is that the
> > interrupt arrives at the GPIO layer, and I can easily make it seen in
> > the fabric too. However, then propagating it to the codec is a bit
> > harder. Or we don't have it in the fabric but have the codec register
> > for that interrupt (through our GPIO layer). This is the first option.
>
> No. I don't think the codecs should mess with the GPIOs directly. The
> policy should be implemented in the fabric. If in some case you need to
> change some codec settings, then the codec shall provide an accessor for
> doing so.
Yeah. That was my second option mostly.
> > The second option is changing the whole in-/output control code that we
> > have and moving it from the codec to the fabric layer. The fabric
> > already knows what in- and outputs a codec has (in order to know what is
> > connected), hence if we added a codec driver function to turn on/off any
> > in- or output we could have the fabric control this. But then we'd also
> > have to make known to the codec which of those are mutually exclusive,
> > and generally make it more complicated.
>
> We don't have to make known to the codec, we just turn on/off the right
> ones.
Hmm, ok, good point, then we don't even need the complication of telling
the codec what is connected to it. Maybe that simplifies the code in
total... But the codecs will still need hardcoded numbers for the
various in- and outputs that the fabric needs to know.
I'll think about this a bit more, maybe experiment with the code a
bit :)
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply
* Re: [PATCH] make ams work with latest kernels
From: Pavel Machek @ 2006-05-27 20:34 UTC (permalink / raw)
To: Stelian Pop
Cc: Andrew Morton, linuxppc-dev list, Johannes Berg,
Linux Kernel list
In-Reply-To: <1148761919.3132.1.camel@deep-space-9.dsnet>
On So 27-05-06 22:31:58, Stelian Pop wrote:
> Le samedi 27 mai 2006 ? 22:06 +0200, Johannes Berg a écrit :
> > On Fri, 2006-05-26 at 17:39 +0000, Pavel Machek wrote:
> >
> > > > This driver also provides an absolute input class device, allowing
> > > > the laptop to act as a pinball machine-esque joystick.
> > >
> > > Is it useful to have /sysfs interface when we already have same data
> > > available as joystick?
> >
> > Might be useful if you need to turn off the "joystick" because X gets
> > confused with it. Other than that, no.
>
> /sysfs interface also exports the 'z' coordinate, the input interface
> does not.
Can that be fixed? z coordinate should be useful for input, too.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Tutorial on PPC exception
From: jeanwelly @ 2006-05-28 3:18 UTC (permalink / raw)
To: linuxppc-embedded@ozlabs.org
SGkgQWxsLA0KRG9lcyBhbnlib2R5IGtub3cgaG93IHRvIGdldCB0aGUgZnVsbCBleGNlcHRpb25z
IG9mIHRoZSBQUEM/IFdoaWNoIHR1dG9yaWFsIGNvdWxkIGJlIGZldGNoZWQgYXMgYSByZWZlcmVu
Y2U/DQoNCkkgZ290IGFuIGV4Y2VwdGlvbiBmcm9tIHRoZSBoYXJkd2FyZSwgYnV0IEkgZG9uJ3Qg
a25vdyB0aGUgZGV0YWlsZWQgbWVhbmluZ3MsIGJlY3Vhc2UgaXQgd2FzIHRha2VuIGFzIGFuICJ1
bmtub3duIGV4cGVjdGlvbiIgYnkgbXkgc3lzdGVtLiBQZXJzb25hbGx5LCBJIHRoaW5rIGFuIGV4
Y2VwdGlvbiBpcyBhbiBodyBiZWhhcmlvdXIsIHNvIEkgZ3Vlc3MgdGhlcmUgc2hvdWxkIGJlIGFu
IHRoaXMga2luZCBvZiBkb2N1bWVudC4NCg0KVGhhbmsgeW91ISAJCQkJDQoNCqGhoaGhoaGhoaGh
oaGhoaFqZWFud2VsbHkNCqGhoaGhoaGhoaGhoaGhoaFqZWFud2VsbHlAMTI2LmNvbQ0KoaGhoaGh
oaGhoaGhoaGhoaGhoaEyMDA2LTA1LTI4DQo=
^ permalink raw reply
* [PATCH] powerpc: add dmesg command to xmon
From: Olaf Hering @ 2006-05-28 10:46 UTC (permalink / raw)
To: linuxppc-dev
Based on work by Linas Vepstas:
dump dmesg buffer in xmon, with a new 'D' command.
Use kallsyms to lookup the symbols to avoid touching generic code in printk.c
Signed-off-by: Olaf Hering <olh@suse.de>
---
arch/powerpc/xmon/xmon.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
Index: linux-2.6/arch/powerpc/xmon/xmon.c
===================================================================
--- linux-2.6.orig/arch/powerpc/xmon/xmon.c
+++ linux-2.6/arch/powerpc/xmon/xmon.c
@@ -143,6 +143,7 @@ void dump_segments(void);
static void symbol_lookup(void);
static void xmon_print_symbol(unsigned long address, const char *mid,
const char *after);
+static void xmon_show_dmesg(void);
static const char *getvecname(unsigned long vec);
extern int print_insn_powerpc(unsigned long, unsigned long, int);
@@ -192,6 +193,7 @@ Commands:\n\
df dump float values\n\
dd dump double values\n\
dr dump stream of raw bytes\n\
+ D show dmesg (printk) buffer\n\
e print exception information\n\
f flush cache\n\
la lookup symbol+offset of specified address\n\
@@ -781,6 +783,9 @@ cmds(struct pt_regs *excp)
case 'd':
dump();
break;
+ case 'D':
+ xmon_show_dmesg();
+ break;
case 'l':
symbol_lookup();
break;
@@ -2488,6 +2493,113 @@ static void xmon_print_symbol(unsigned l
printf("%s", after);
}
+#ifdef CONFIG_KALLSYMS
+static const char *xmon_log_buf;
+static int xmon_log_buf_len;
+static unsigned long xmon_log_end, xmon_logged_chars;
+
+static int xmon_init_dmesg(void)
+{
+ const char **p;
+ const int *i;
+ const unsigned long *l;
+
+ if (!xmon_log_buf && setjmp(bus_error_jmp) == 0) {
+ catch_memory_errors = 1;
+ sync();
+
+ p = (const char **)kallsyms_lookup_name("log_buf");
+ if (p) {
+ xmon_log_buf = *p;
+ sync();
+ __delay(200);
+ }
+
+ i = (const int *)kallsyms_lookup_name("log_buf_len");
+ if (i) {
+ xmon_log_buf_len = *i;
+ sync();
+ __delay(200);
+ }
+
+ l = (const unsigned long *)kallsyms_lookup_name("log_end");
+ if (l) {
+ xmon_log_end = *l;
+ sync();
+ __delay(200);
+ }
+
+ l = (const unsigned long *)kallsyms_lookup_name("logged_chars");
+ if (l) {
+ xmon_logged_chars = *l;
+ sync();
+ __delay(200);
+ }
+
+ }
+ catch_memory_errors = 0;
+ return !!xmon_log_buf;
+}
+#else
+static inline int xmon_init_dmesg(void)
+{
+ return 0;
+}
+#endif
+
+static void xmon_show_dmesg(void)
+{
+ if (xmon_init_dmesg()) {
+ const char *p_start, *p_end, *l_start, *l_end, *start, *end;
+ char c;
+
+ p_start = xmon_log_buf;
+ p_end = p_start + xmon_log_buf_len;
+ l_start = p_start + xmon_log_end - (xmon_logged_chars < xmon_log_buf_len ? xmon_logged_chars : xmon_log_buf_len);
+ l_end = p_start + xmon_log_end;
+ if (l_start == l_end)
+ return;
+ start = p_start + (l_start - p_start) % xmon_log_buf_len;
+ end = p_start + (l_end - p_start) % xmon_log_buf_len;
+ c = '\0';
+ while (1) {
+ const char *p;
+ int chars = 0;
+ if (!*start) {
+ while (!*start) {
+ start++;
+ if (start < p_start)
+ start = p_end - 1;
+ else if (start >= p_end)
+ start = p_start;
+ if (start == end)
+ break;
+ }
+ if (start == end)
+ break;
+ }
+ p = start;
+ while (*start && chars < 200) {
+ c = *start;
+ chars++;
+ start++;
+ if (start < p_start)
+ start = p_end - 1;
+ else if (start >= p_end)
+ start = p_start;
+ if (start == end)
+ break;
+ }
+ if (chars)
+ printf("%.*s", chars, p);
+ if (start == end)
+ break;
+ }
+ if (c != '\n')
+ printf("\n");
+ }
+}
+
#ifdef CONFIG_PPC64
static void dump_slb(void)
{
^ permalink raw reply
* Re: [PATCH] powerpc: add dmesg command to xmon
From: Arnd Bergmann @ 2006-05-28 12:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Olaf Hering
In-Reply-To: <20060528104621.GA7126@suse.de>
T24gU3VuZGF5IDI4IE1heSAyMDA2IDEyOjQ2LCBPbGFmIEhlcmluZyB3cm90ZToKPiArc3RhdGlj
IGludCB4bW9uX2luaXRfZG1lc2codm9pZCkKPiArewo+ICugoKCgoKCgY29uc3QgY2hhciAqKnA7
Cj4gK6CgoKCgoKBjb25zdCBpbnQgKmk7Cj4gK6CgoKCgoKBjb25zdCB1bnNpZ25lZCBsb25nICps
Owo+ICsKPiAroKCgoKCgoGlmICgheG1vbl9sb2dfYnVmICYmIHNldGptcChidXNfZXJyb3Jfam1w
KSA9PSAwKSB7Cj4gK6CgoKCgoKCgoKCgoKCgoGNhdGNoX21lbW9yeV9lcnJvcnMgPSAxOwo+ICug
oKCgoKCgoKCgoKCgoKBzeW5jKCk7Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKBwID0gKGNvbnN0IGNo
YXIgKiopa2FsbHN5bXNfbG9va3VwX25hbWUoImxvZ19idWYiKTsKPiAroKCgoKCgoKCgoKCgoKCg
aWYgKHApIHsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB4bW9uX2xvZ19idWYgPSAqcDsKPiAr
oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBzeW5jKCk7Cj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
X19kZWxheSgyMDApOwo+ICugoKCgoKCgoKCgoKCgoKB9Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKBp
ID0gKGNvbnN0IGludCAqKWthbGxzeW1zX2xvb2t1cF9uYW1lKCJsb2dfYnVmX2xlbiIpOwo+ICug
oKCgoKCgoKCgoKCgoKBpZiAoaSkgewo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoHhtb25fbG9n
X2J1Zl9sZW4gPSAqaTsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBzeW5jKCk7Cj4gK6CgoKCg
oKCgoKCgoKCgoKCgoKCgoKCgX19kZWxheSgyMDApOwo+ICugoKCgoKCgoKCgoKCgoKB9Cj4gKwo+
ICugoKCgoKCgoKCgoKCgoKBsID0gKGNvbnN0IHVuc2lnbmVkIGxvbmcgKilrYWxsc3ltc19sb29r
dXBfbmFtZSgibG9nX2VuZCIpOwo+ICugoKCgoKCgoKCgoKCgoKBpZiAobCkgewo+ICugoKCgoKCg
oKCgoKCgoKCgoKCgoKCgoHhtb25fbG9nX2VuZCA9ICpsOwo+ICugoKCgoKCgoKCgoKCgoKCgoKCg
oKCgoHN5bmMoKTsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBfX2RlbGF5KDIwMCk7Cj4gK6Cg
oKCgoKCgoKCgoKCgoH0KPiArCj4gK6CgoKCgoKCgoKCgoKCgoGwgPSAoY29uc3QgdW5zaWduZWQg
bG9uZyAqKWthbGxzeW1zX2xvb2t1cF9uYW1lKCJsb2dnZWRfY2hhcnMiKTsKPiAroKCgoKCgoKCg
oKCgoKCgaWYgKGwpIHsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB4bW9uX2xvZ2dlZF9jaGFy
cyA9ICpsOwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoHN5bmMoKTsKPiAroKCgoKCgoKCgoKCg
oKCgoKCgoKCgoKBfX2RlbGF5KDIwMCk7Cj4gK6CgoKCgoKCgoKCgoKCgoH0KPiArCj4gK6CgoKCg
oKB9Cj4gK6CgoKCgoKBjYXRjaF9tZW1vcnlfZXJyb3JzID0gMDsKPiAroKCgoKCgoHJldHVybiAh
IXhtb25fbG9nX2J1ZjsKClRoaXMgd2hvbGUgZnVuY3Rpb24gbG9va3MgZmlzaHkgdG8gbWUuIEl0
IHNlZW1zIHVubmVjZXNzYXJpbHkgcnVkZSB0byBtZSB0bwp1c2Uga2FsbHN5bXNfbG9va3VwX25h
bWUgaW4gb3JkZXIgdG8gZ2V0IGF0IGEgc3RhdGljIHZhcmlhYmxlIGZyb20gYW5vdGhlcgpmaWxl
LiBDYW4ndCB5b3UgaW5zdGVhZCBhZGQgYSBnbG9iYWwgZnVuY3Rpb24gdG8ga2VybmVsL3ByaW50
ay5jIHRvIHJldHVybgp0aGUgYnVmZmVyPwoKQWxzbywgd2hhdCdzIHRoZSBwdXJwb3NlIG9mIHRo
ZSBzeW5jL19fZGVsYXkgY29kZSBpbiBoZXJlPyBJZiB5b3UgdXNlIHRoYXQKdG8gY2hlY2sgZm9y
IGEgcG9zc2libGUgbWFjaGluZSBjaGVjayB0aGF0IG1heSBoYXZlIGhhcHBlbmVkLCB3aHkgbm90
IGluCnRoZSBjYXNlIHdoZXJlIHRoZSBsb29rdXAgZmFpbHM/CgoJQXJuZCA8PjwK
^ permalink raw reply
* Re: [PATCH] powerpc: add dmesg command to xmon
From: Olaf Hering @ 2006-05-28 12:07 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
In-Reply-To: <200605281404.26070.arnd@arndb.de>
On Sun, May 28, Arnd Bergmann wrote:
> This whole function looks fishy to me. It seems unnecessarily rude to me to
> use kallsyms_lookup_name in order to get at a static variable from another
> file. Can't you instead add a global function to kernel/printk.c to return
> the buffer?
Its possible, but it wont end up in Linus tree.
> Also, what's the purpose of the sync/__delay code in here? If you use that
> to check for a possible machine check that may have happened, why not in
> the case where the lookup fails?
I just copied the other usages. Accessing the dmesg buffer itself may
need similar checks.
^ permalink raw reply
* Re: Howto allocate non-cacheable memory
From: Arnd Bergmann @ 2006-05-28 15:36 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: Muneeswaran P - TLS, Chennai
In-Reply-To: <012301731C23DE4DBFE035647C68F1CC0331C84F@sindhu.ctd.hcltech.com>
On Saturday 27 May 2006 07:38, Muneeswaran P - TLS, Chennai wrote:
> =A0=A0=A0=A0=A0=A0=A0=A0Pls clarify the following doubts:
> =A0=A0=A0=A0=A0=A0=A0=A01. DPRAM is memory mapped to PCI-X card.
> =A0=A0=A0=A0=A0=A0=A0=A02. I have to transfer data from main memory to DP=
RAM using bus
> master concept and vice-versa.
> =A0=A0=A0=A0=A0=A0=A0=A03. How to make this memory area as non-cacheable =
one ?=20
> =A0=A0=A0=A0=A0=A0=A0=A04. Whether DMA mapping (pci_map_single() call ) s=
hould be done for
> both DPRAM and main memory ?
> =A0=A0=A0=A0=A0=A0=A0=A0 =A0 4.a) I will get the physical address of DPRA=
M memory (memory
> mapped to PCI-X card) from BAR-0 register. Can i use this physical addres
> directly for data transer using bus master (without pci_map_single() call=
=2E)
> ?
> =A0=A0=A0=A0=A0=A0=A0=A0 =A0 4.b) =A0How to make main memory area as non-=
cacheable one ?
You need pci_map_single() for all bus-master accesses from the PCI-X card
and ioremap() to map the card's registers and/or memory into your kernel
address space as cache-inhibited.
Depending on what your adapter does, you might want to map memory areas
on the card with __ioremap(addr, size, _PAGE_NO_CACHE) instead of
ioremap(addr, size) in order to get a non-guarded mapping.
Arnd <><
^ permalink raw reply
* Re: [PATCH] powerpc: add dmesg command to xmon
From: Arnd Bergmann @ 2006-05-28 16:12 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20060528120748.GA7608@suse.de>
On Sunday 28 May 2006 14:07, Olaf Hering wrote:
> > This whole function looks fishy to me. It seems unnecessarily rude to me to
> > use kallsyms_lookup_name in order to get at a static variable from another
> > file. Can't you instead add a global function to kernel/printk.c to return
> > the buffer?
>
> Its possible, but it wont end up in Linus tree.
Hmm, so the idea is that because Linus doesn't like kernel debuggers, we just
obfuscate the code for any improvements to xmon and hope he doesn't notice?
Don't get me wrong, I think having dmesg in xmon is a good idea, but this is
probably not the best strategy of getting it in there.
Arnd <><
^ permalink raw reply
* Re: Tutorial on PPC exception
From: Mark Chambers @ 2006-05-28 18:15 UTC (permalink / raw)
To: jeanwelly, linuxppc-embedded
In-Reply-To: <200605281118066622530@126.com>
> Hi All,
> Does anybody know how to get the full exceptions of the PPC? Which
> tutorial could be fetched as a reference?
>
Freescale has complete documentation for their processors available at
www.freescale.com
Mark C.
^ permalink raw reply
* [RFC 7/7] snd-aoa: wire up aoa in sound/
From: Johannes Berg @ 2006-05-28 19:00 UTC (permalink / raw)
To: alsa-devel; +Cc: linuxppc-dev
In-Reply-To: <20060528190026.754474000@johannes.berg>
This patch adds the necessary Kconfig and Makefile hooks to make aoa
buildable inside the kernel tree.
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -58,6 +58,8 @@ source "sound/pci/Kconfig"
source "sound/ppc/Kconfig"
+source "sound/aoa/Kconfig"
+
source "sound/arm/Kconfig"
source "sound/mips/Kconfig"
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -4,7 +4,7 @@ #
obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_SOUND_PRIME) += oss/
obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ aoa/
ifeq ($(CONFIG_SND),y)
obj-y += last.o
--
^ permalink raw reply
* [RFC 1/7] snd-aoa: add aoa header files
From: Johannes Berg @ 2006-05-28 19:00 UTC (permalink / raw)
To: alsa-devel; +Cc: linuxppc-dev
In-Reply-To: <20060528190026.754474000@johannes.berg>
This patch adds header files to use for communication between the various
parts of aoa.
--- /dev/null
+++ b/sound/aoa/aoa-gpio.h
@@ -0,0 +1,44 @@
+/*
+ * Apple Onboard Audio GPIO definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __AOA_GPIO_H
+#define __AOA_GPIO_H
+#include <asm/prom.h>
+
+struct gpio_runtime;
+struct gpio_methods {
+ /* for initialisation/de-initialisation of the GPIO layer */
+ void (*init)(struct gpio_runtime *rt);
+ void (*exit)(struct gpio_runtime *rt);
+
+ /* turn off headphone, speakers, lineout */
+ void (*all_amps_off)(struct gpio_runtime *rt);
+ /* turn headphone, speakers, lineout back to previous setting */
+ void (*all_amps_restore)(struct gpio_runtime *rt);
+
+ void (*set_headphone)(struct gpio_runtime *rt, int on);
+ void (*set_speakers)(struct gpio_runtime *rt, int on);
+ void (*set_lineout)(struct gpio_runtime *rt, int on);
+
+ int (*get_headphone)(struct gpio_runtime *rt);
+ int (*get_speakers)(struct gpio_runtime *rt);
+ int (*get_lineout)(struct gpio_runtime *rt);
+
+ void (*set_hw_reset)(struct gpio_runtime *rt, int on);
+};
+
+struct gpio_runtime {
+ /* to be assigned by fabric */
+ struct device_node *node;
+ /* since everyone needs this pointer anyway... */
+ struct gpio_methods *methods;
+ /* to be used by the gpio implementation */
+ int implementation_private;
+};
+
+#endif /* __AOA_GPIO_H */
--- /dev/null
+++ b/sound/aoa/aoa.h
@@ -0,0 +1,130 @@
+/*
+ * Apple Onboard Audio definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __AOA_H
+#define __AOA_H
+#include <asm/prom.h>
+#include <linux/module.h>
+/* So apparently there's a reason for requiring driver.h to be included first! */
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/asound.h>
+#include <sound/control.h>
+#include "aoa-gpio.h"
+#include "soundbus/soundbus.h"
+
+#define MAX_CODEC_NAME_LEN 32
+
+struct aoa_codec {
+ char name[MAX_CODEC_NAME_LEN];
+
+ struct module *owner;
+
+ /* called when the fabric wants to init this codec.
+ * Do alsa card manipulations from here. */
+ int (*init)(struct aoa_codec *codec);
+
+ /* called when the fabric is done with the codec.
+ * The alsa card will be cleaned up so don't bother. */
+ void (*exit)(struct aoa_codec *codec);
+
+ /* May be NULL, but can be used by the fabric.
+ * Refcounting is the codec driver's responsibility */
+ struct device_node *node;
+
+ /* assigned by fabric before init() is called, points
+ * to the soundbus device. Cannot be NULL. */
+ struct soundbus_dev *soundbus_dev;
+
+ /* assigned by the fabric before init() is called, points
+ * to the fabric's gpio runtime record for the relevant
+ * device. */
+ struct gpio_runtime *gpio;
+
+ /* assigned by the fabric before init() is called, contains
+ * a codec specific bitmask of what outputs and inputs are
+ * actually connected */
+ u32 connected;
+
+ /* data the fabric can associate with this structure */
+ void *fabric_data;
+
+ /* private! */
+ struct list_head list;
+ struct aoa_fabric *fabric;
+};
+
+/* return 0 on success */
+extern int
+aoa_codec_register(struct aoa_codec *codec);
+extern void
+aoa_codec_unregister(struct aoa_codec *codec);
+
+#define MAX_LAYOUT_NAME_LEN 32
+
+struct aoa_fabric {
+ char name[MAX_LAYOUT_NAME_LEN];
+
+ struct module *owner;
+
+ /* once codecs register, they are passed here after.
+ * They are of course not initialised, since the
+ * fabric is responsible for initialising some fields
+ * in the codec structure! */
+ int (*found_codec)(struct aoa_codec *codec);
+ /* called for each codec when it is removed,
+ * also in the case that aoa_fabric_unregister
+ * is called and all codecs are removed
+ * from this fabric.
+ * Also called if found_codec returned 0 but
+ * the codec couldn't initialise. */
+ void (*remove_codec)(struct aoa_codec *codec);
+ /* If found_codec returned 0, and the codec
+ * could be initialised, this is called. */
+ void (*attached_codec)(struct aoa_codec *codec);
+};
+
+/* return 0 on success, -EEXIST if another fabric is
+ * registered, -EALREADY if the same fabric is registered.
+ * Passing NULL can be used to test for the presence
+ * of another fabric, if -EALREADY is returned there is
+ * no other fabric present.
+ * In the case that the function returns -EALREADY
+ * and the fabric passed is not NULL, all codecs
+ * that are not assigned yet are passed to the fabric
+ * again for reconsideration. */
+extern int
+aoa_fabric_register(struct aoa_fabric *fabric);
+
+/* it is vital to call this when the fabric exits!
+ * When calling, the remove_codec will be called
+ * for all codecs, unless it is NULL. */
+extern void
+aoa_fabric_unregister(struct aoa_fabric *fabric);
+
+/* if for some reason you want to get rid of a codec
+ * before the fabric is removed, use this.
+ * Note that remove_codec is called for it! */
+extern void
+aoa_fabric_unlink_codec(struct aoa_codec *codec);
+
+/* alsa help methods */
+struct aoa_card {
+ struct snd_card *alsa_card;
+};
+
+extern int aoa_snd_device_new(snd_device_type_t type,
+ void * device_data, struct snd_device_ops * ops);
+extern struct snd_card *aoa_get_card(void);
+extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
+
+/* GPIO stuff */
+extern struct gpio_methods *pmf_gpio_methods;
+/* extern struct gpio_methods *map_gpio_methods; */
+
+#endif /* __AOA_H */
--
^ permalink raw reply
* [RFC 2/7] snd-aoa: add aoa core
From: Johannes Berg @ 2006-05-28 19:00 UTC (permalink / raw)
To: alsa-devel; +Cc: linuxppc-dev
In-Reply-To: <20060528190026.754474000@johannes.berg>
This patch adds the core of aoa, in itself pretty useless, but providing
useful functions to other modules.
--- /dev/null
+++ b/sound/aoa/core/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_SND_AOA) += snd-aoa.o
+snd-aoa-objs := snd-aoa-core.o \
+ snd-aoa-alsa.o \
+ snd-aoa-gpio-pmf.o
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.c
@@ -0,0 +1,91 @@
+/*
+ * Apple Onboard Audio Alsa helpers
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#include <linux/module.h>
+#include "snd-aoa-alsa.h"
+
+static struct aoa_card *aoa_card;
+
+int aoa_alsa_init(char *name, struct module *mod)
+{
+ struct snd_card *alsa_card;
+ int err;
+
+ if (aoa_card)
+ /* cannot be EEXIST due to usage in aoa_fabric_register */
+ return -EBUSY;
+
+ alsa_card = snd_card_new(-1, name, mod, sizeof(struct aoa_card));
+ if (!alsa_card)
+ return -ENOMEM;
+ aoa_card = alsa_card->private_data;
+ aoa_card->alsa_card = alsa_card;
+ strncpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
+ strncpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
+ strncpy(alsa_card->longname, name, sizeof(alsa_card->longname));
+ strncpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
+ err = snd_card_register(aoa_card->alsa_card);
+ if (err < 0) {
+ printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
+ snd_card_free(aoa_card->alsa_card);
+ aoa_card = NULL;
+ return err;
+ }
+ return 0;
+}
+
+struct snd_card *aoa_get_card(void)
+{
+ if (aoa_card)
+ return aoa_card->alsa_card;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(aoa_get_card);
+
+void aoa_alsa_cleanup(void)
+{
+ if (aoa_card) {
+ snd_card_free(aoa_card->alsa_card);
+ aoa_card = NULL;
+ }
+}
+
+int aoa_snd_device_new(snd_device_type_t type,
+ void * device_data, struct snd_device_ops * ops)
+{
+ struct snd_card *card = aoa_get_card();
+ int err;
+
+ if (!card) return -ENOMEM;
+
+ err = snd_device_new(card, type, device_data, ops);
+ if (err) {
+ printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
+ return err;
+ }
+ err = snd_device_register(card, device_data);
+ if (err) {
+ printk(KERN_ERR "snd-aoa: failed to register snd device (%d)\n", err);
+ printk(KERN_ERR "snd-aoa: have you forgotten the dev_register callback?\n");
+ snd_device_free(card, device_data);
+ }
+ return err;
+}
+EXPORT_SYMBOL_GPL(aoa_snd_device_new);
+
+int aoa_snd_ctl_add(struct snd_kcontrol* control)
+{
+ int err;
+
+ if (!aoa_card) return -ENODEV;
+
+ err = snd_ctl_add(aoa_card->alsa_card, control);
+ if (err)
+ printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n", err);
+ return err;
+}
+EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.h
@@ -0,0 +1,17 @@
+/*
+ * Apple Onboard Audio Alsa private helpers
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __SND_AOA_ALSA_H
+#define __SND_AOA_ALSA_H
+/* FIXME */
+#include "../aoa.h"
+
+extern int aoa_alsa_init(char *name, struct module *mod);
+extern void aoa_alsa_cleanup(void);
+
+#endif /* __SND_AOA_ALSA_H */
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-core.c
@@ -0,0 +1,153 @@
+/*
+ * Apple Onboard Audio driver core
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include "../aoa.h"
+#include "snd-aoa-alsa.h"
+
+MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+
+/* We allow only one fabric. This simplifies things,
+ * and more don't really make that much sense */
+static struct aoa_fabric *fabric;
+static LIST_HEAD(codec_list);
+
+static void attach_codec_to_fabric(struct aoa_codec *c)
+{
+ int err;
+
+ if (!try_module_get(c->owner))
+ return;
+ /* found_codec has to be assigned */
+ err = -ENOENT;
+ if (fabric->found_codec)
+ err = fabric->found_codec(c);
+ if (err) {
+ module_put(c->owner);
+ printk("snd-aoa: fabric didn't like codec %s\n", c->name);
+ return;
+ }
+ c->fabric = fabric;
+
+ err = 0;
+ if (c->init)
+ err = c->init(c);
+ if (err) {
+ printk("snd-aoa: codec %s didn't init\n", c->name);
+ c->fabric = NULL;
+ if (fabric->remove_codec)
+ fabric->remove_codec(c);
+ module_put(c->owner);
+ return;
+ }
+ if (fabric->attached_codec)
+ fabric->attached_codec(c);
+}
+
+int aoa_codec_register(struct aoa_codec *codec)
+{
+ list_add(&codec->list, &codec_list);
+ if (fabric)
+ attach_codec_to_fabric(codec);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(aoa_codec_register);
+
+void aoa_codec_unregister(struct aoa_codec *codec)
+{
+ list_del(&codec->list);
+ if (codec->fabric && codec->exit)
+ codec->exit(codec);
+ if (fabric && fabric->remove_codec)
+ fabric->remove_codec(codec);
+ codec->fabric = NULL;
+ module_put(codec->owner);
+}
+EXPORT_SYMBOL_GPL(aoa_codec_unregister);
+
+int aoa_fabric_register(struct aoa_fabric *new_fabric)
+{
+ struct aoa_codec *c;
+ int err;
+
+ /* allow querying for presence of fabric
+ * (i.e. do this test first!) */
+ if (new_fabric == fabric) {
+ err = -EALREADY;
+ goto attach;
+ }
+ if (fabric)
+ return -EEXIST;
+ if (!new_fabric)
+ return -EINVAL;
+
+ err = aoa_alsa_init(new_fabric->name, new_fabric->owner);
+ if (err) {
+ return err;
+ }
+ fabric = new_fabric;
+
+ attach:
+ list_for_each_entry(c, &codec_list, list) {
+ if (c->fabric != fabric)
+ attach_codec_to_fabric(c);
+ }
+ return err;
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_register);
+
+void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
+{
+ struct aoa_codec *c;
+
+ if (fabric != old_fabric)
+ return;
+
+ list_for_each_entry(c, &codec_list, list) {
+ if (c->fabric)
+ aoa_fabric_unlink_codec(c);
+ }
+
+ aoa_alsa_cleanup();
+
+ fabric = NULL;
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
+
+void aoa_fabric_unlink_codec(struct aoa_codec *codec)
+{
+ if (!codec->fabric) {
+ printk(KERN_ERR "snd-aoa: fabric unassigned in aoa_fabric_unlink_codec\n");
+ dump_stack();
+ return;
+ }
+ if (codec->exit)
+ codec->exit(codec);
+ if (codec->fabric->remove_codec)
+ codec->fabric->remove_codec(codec);
+ codec->fabric = NULL;
+ module_put(codec->owner);
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
+
+static int __init aoa_init(void)
+{
+ return 0;
+}
+
+static void __exit aoa_exit(void)
+{
+ aoa_alsa_cleanup();
+}
+
+module_init(aoa_init);
+module_exit(aoa_exit);
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-pmf.c
@@ -0,0 +1,91 @@
+/*
+ * Apple Onboard Audio pmf GPIOs
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <asm/pmac_feature.h>
+#include <asm/pmac_pfunc.h>
+#include "../aoa.h"
+
+#define PMF_GPIO(name, bit) \
+static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
+{ \
+ struct pmf_args args = { .count = 1, .u[0].v = !on }; \
+ \
+ if (unlikely(!rt)) return; \
+ pmf_call_function(rt->node, #name "-mute", &args); \
+ rt->implementation_private &= ~(1<<bit); \
+ rt->implementation_private |= (!!on << bit); \
+} \
+static int pmf_gpio_get_##name(struct gpio_runtime *rt) \
+{ \
+ if (unlikely(!rt)) return 0; \
+ return (rt->implementation_private>>bit)&1; \
+}
+
+PMF_GPIO(headphone, 0);
+PMF_GPIO(amp, 1);
+PMF_GPIO(lineout, 2);
+
+static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
+{
+ struct pmf_args args = { .count = 1, .u[0].v = !!on };
+
+ if (unlikely(!rt)) return;
+ pmf_call_function(rt->node, "hw-reset", &args);
+}
+
+static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
+{
+ int saved;
+
+ if (unlikely(!rt)) return;
+ saved = rt->implementation_private;
+ pmf_gpio_set_headphone(rt, 0);
+ pmf_gpio_set_amp(rt, 0);
+ pmf_gpio_set_lineout(rt, 0);
+ rt->implementation_private = saved;
+}
+
+static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt)
+{
+ int s;
+
+ if (unlikely(!rt)) return;
+ s = rt->implementation_private;
+ pmf_gpio_set_headphone(rt, (s>>0)&1);
+ pmf_gpio_set_amp(rt, (s>>1)&1);
+ pmf_gpio_set_lineout(rt, (s>>2)&1);
+}
+
+static void pmf_gpio_init(struct gpio_runtime *rt)
+{
+ pmf_gpio_all_amps_off(rt);
+ rt->implementation_private = 0;
+}
+
+static void pmf_gpio_exit(struct gpio_runtime *rt)
+{
+ pmf_gpio_all_amps_off(rt);
+ rt->implementation_private = 0;
+}
+
+static struct gpio_methods methods = {
+ .init = pmf_gpio_init,
+ .exit = pmf_gpio_exit,
+ .all_amps_off = pmf_gpio_all_amps_off,
+ .all_amps_restore = pmf_gpio_all_amps_restore,
+ .set_headphone = pmf_gpio_set_headphone,
+ .set_speakers = pmf_gpio_set_amp,
+ .set_lineout = pmf_gpio_set_lineout,
+ .set_hw_reset = pmf_gpio_set_hw_reset,
+ .get_headphone = pmf_gpio_get_headphone,
+ .get_speakers = pmf_gpio_get_amp,
+ .get_lineout = pmf_gpio_get_lineout,
+};
+
+struct gpio_methods *pmf_gpio_methods = &methods;
+EXPORT_SYMBOL_GPL(pmf_gpio_methods);
--
^ permalink raw reply
* [RFC 5/7] snd-aoa: add layout-id fabric
From: Johannes Berg @ 2006-05-28 19:00 UTC (permalink / raw)
To: alsa-devel; +Cc: linuxppc-dev
In-Reply-To: <20060528190026.754474000@johannes.berg>
The 'fabric' is the thing that pulls all of snd-aoa together, this patch
adds the 'layout' or 'layout-id' fabric that keys off the 'layout-id'
property in the device-tree to pull in the proper modules. It itself loads
if an i2sbus is present with a layout-id (exported in modalias) that it can
use.
--- /dev/null
+++ b/sound/aoa/fabrics/Kconfig
@@ -0,0 +1,12 @@
+config SND_AOA_FABRIC_LAYOUT
+ tristate "layout-id fabric"
+ depends SND_AOA
+ select SND_AOA_SOUNDBUS
+ select SND_AOA_SOUNDBUS_I2S
+ ---help---
+ This enables the layout-id fabric for the Apple Onboard
+ Audio driver, the module holding it all together
+ based on the device-tree's layout-id property.
+
+ If you are unsure and have a later Apple machine,
+ compile it as a module.
--- /dev/null
+++ b/sound/aoa/fabrics/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
--- /dev/null
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -0,0 +1,605 @@
+/*
+ * Apple Onboard Audio driver -- layout fabric
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ *
+ * This fabric module looks for sound codecs
+ * based on the layout-id property in the device tree.
+ *
+ */
+
+#include <asm/prom.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include "../aoa.h"
+#include "../soundbus/soundbus.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
+
+#define MAX_CODECS_PER_BUS 2
+
+/* These are the connections the layout fabric
+ * knows about. It doesn't really care about the
+ * input ones, but I thought I'd separate them
+ * to give them proper names. The thing is that
+ * Apple usually will distinguish the active output
+ * by GPIOs, while the active input is set directly
+ * on the codec. Hence we here tell the codec what
+ * we think is connected. This information is hard-
+ * coded below ... */
+#define CC_SPEAKERS (1<<0)
+#define CC_HEADPHONE (1<<1)
+#define CC_LINEOUT (1<<2)
+#define CC_DIGITALOUT (1<<3)
+#define CC_LINEIN (1<<4)
+#define CC_MICROPHONE (1<<5)
+#define CC_DIGITALIN (1<<6)
+/* pretty bogus but users complain...
+ * This is a flag saying that the LINEOUT
+ * should be renamed to HEADPHONE.
+ * be careful with input detection! */
+#define CC_LINEOUT_LABELLED_HEADPHONE (1<<7)
+
+struct codec_connection {
+ /* CC_ flags from above */
+ int connected;
+ /* codec dependent bit to be set in the aoa_codec.connected field.
+ * This intentionally doesn't have any generic flags because the
+ * fabric has to know the codec anyway and all codecs might have
+ * different connectors */
+ int codec_bit;
+};
+
+struct codec_connect_info {
+ char *name;
+ struct codec_connection *connections;
+};
+
+#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0)
+
+struct layout {
+ unsigned int layout_id;
+ struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
+ int flags;
+
+ /* if busname is not assigned, we use 'Master' below,
+ * so that our layout table doesn't need to be filled
+ * too much.
+ * We only assign these two if we expect to find more
+ * than one soundbus, i.e. on those machines with
+ * multiple layout-ids */
+ char *busname;
+ int pcmid;
+};
+
+MODULE_ALIAS("sound-layout-82");
+MODULE_ALIAS("sound-layout-45");
+MODULE_ALIAS("sound-layout-64");
+MODULE_ALIAS("sound-layout-65");
+MODULE_ALIAS("sound-layout-68");
+MODULE_ALIAS("sound-layout-69");
+MODULE_ALIAS("sound-layout-70");
+MODULE_ALIAS("sound-layout-72");
+MODULE_ALIAS("sound-layout-80");
+MODULE_ALIAS("sound-layout-86");
+MODULE_ALIAS("sound-layout-84");
+MODULE_ALIAS("sound-layout-92");
+
+/* onyx with all but microphone connected */
+static struct codec_connection onyx_connections_nomic[] = {
+ {
+ .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
+ .codec_bit = 0,
+ },
+ {
+ .connected = CC_DIGITALOUT,
+ .codec_bit = 1,
+ },
+ {
+ .connected = CC_LINEIN,
+ .codec_bit = 2,
+ },
+ {} /* terminate array by .connected == 0 */
+};
+
+/* onyx on machines without headphone */
+static struct codec_connection onyx_connections_noheadphones[] = {
+ {
+ .connected = CC_SPEAKERS | CC_LINEOUT |
+ CC_LINEOUT_LABELLED_HEADPHONE,
+ .codec_bit = 0,
+ },
+ {
+ .connected = CC_DIGITALOUT,
+ .codec_bit = 1,
+ },
+ /* FIXME: are these correct? probably not for all the machines
+ * below ... If not this will need separating. */
+ {
+ .connected = CC_LINEIN,
+ .codec_bit = 2,
+ },
+ {
+ .connected = CC_MICROPHONE,
+ .codec_bit = 3,
+ },
+ {} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines without line out */
+static struct codec_connection tas_connections_nolineout[] = {
+ {
+ .connected = CC_SPEAKERS | CC_HEADPHONE,
+ .codec_bit = 0,
+ },
+ {
+ .connected = CC_LINEIN,
+ .codec_bit = 2,
+ },
+ {
+ .connected = CC_MICROPHONE,
+ .codec_bit = 3,
+ },
+ {} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines with neither line out nor line in */
+static struct codec_connection tas_connections_noline[] = {
+ {
+ .connected = CC_SPEAKERS | CC_HEADPHONE,
+ .codec_bit = 0,
+ },
+ {
+ .connected = CC_MICROPHONE,
+ .codec_bit = 3,
+ },
+ {} /* terminate array by .connected == 0 */
+};
+
+static struct layout layouts[] = {
+ /* last PowerBooks (15" Oct 2005) */
+ { .layout_id = 82,
+ .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_noheadphones,
+ },
+ .codecs[1] = {
+ .name = "topaz",
+ .connections = NULL /* TBD */,
+ },
+ },
+ /* PowerBook5,7 */
+ { .layout_id = 64,
+ .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_noheadphones,
+ },
+ },
+ /* PowerBook5,7 */
+ { .layout_id = 65,
+ .codecs[0] = {
+ .name = "topaz",
+ .connections = NULL, /* TBD */
+ },
+ },
+ /* PowerBook5,9 [17" Oct 2005] */
+ { .layout_id = 84,
+ .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_noheadphones,
+ },
+ .codecs[1] = {
+ .name = "topaz",
+ .connections = NULL /* TBD */,
+ },
+ },
+ /* PowerMac8,1 */
+ { .layout_id = 45,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_noheadphones,
+ },
+ .codecs[1] = {
+ .name = "topaz",
+ .connections = NULL /* TBD */,
+ },
+ },
+ /* Quad PowerMac (analog in, analog/digital out) */
+ { .layout_id = 68,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_nomic,
+ },
+ },
+ /* Quad PowerMac (digital in) */
+ { .layout_id = 69,
+ .codecs[0] = {
+ .name = "topaz",
+ .connections = NULL /* TBD */,
+ },
+ .busname = "digital in", .pcmid = 1 },
+ /* Early 2005 PowerBook */
+ { .layout_id = 70,
+ .codecs[0] = {
+ .name = "tas",
+ .connections = tas_connections_nolineout,
+ },
+ },
+ /* PowerBook6,7 */
+ { .layout_id = 80,
+ .codecs[0] = {
+ .name = "tas",
+ .connections = tas_connections_noline,
+ },
+ },
+ /* PowerBook6,8 */
+ { .layout_id = 72,
+ .codecs[0] = {
+ .name = "tas",
+ .connections = tas_connections_nolineout,
+ },
+ },
+ /* PowerMac8,2 */
+ { .layout_id = 86,
+ .codecs[0] = {
+ .name = "onyx",
+ .connections = onyx_connections_nomic, /* ??? */
+ },
+ .codecs[1] = {
+ .name = "topaz",
+ .connections = NULL /* TBD */,
+ },
+ },
+ /* PowerBook6,7 */
+ { .layout_id = 92,
+ .codecs[0] = {
+ .name = "tas",
+ .connections = tas_connections_nolineout,
+ },
+ },
+ {}
+};
+
+static struct layout *find_layout_by_id(unsigned int id)
+{
+ struct layout *l;
+
+ l = layouts;
+ while (l->layout_id) {
+ if (l->layout_id == id)
+ return l;
+ l++;
+ }
+ return NULL;
+}
+
+static void use_layout(struct layout *l)
+{
+ int i;
+
+ for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+ if (l->codecs[i].name) {
+ request_module("snd-aoa-codec-%s", l->codecs[i].name);
+ }
+ }
+ /* now we wait for the codecs to call us back */
+}
+
+struct layout_dev {
+ struct list_head list;
+ struct soundbus_dev *sdev;
+ struct device_node *sound;
+ struct aoa_codec *codecs[MAX_CODECS_PER_BUS];
+ struct layout *layout;
+ struct gpio_runtime gpio;
+};
+
+static LIST_HEAD(layouts_list);
+static int layouts_list_items;
+
+static int control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+#define AMP_CONTROL(n, description) \
+static int n##_control_get(struct snd_kcontrol *kcontrol, \
+ struct snd_ctl_elem_value *ucontrol) \
+{ \
+ struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
+ if (gpio->methods && gpio->methods->get_##n) \
+ ucontrol->value.integer.value[0] = \
+ gpio->methods->get_##n(gpio); \
+ return 0; \
+} \
+static int n##_control_put(struct snd_kcontrol *kcontrol, \
+ struct snd_ctl_elem_value *ucontrol) \
+{ \
+ struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
+ if (gpio->methods && gpio->methods->get_##n) \
+ gpio->methods->set_##n(gpio, \
+ ucontrol->value.integer.value[0]); \
+ return 1; \
+} \
+static struct snd_kcontrol_new n##_ctl = { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = description, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+ .info = control_info, \
+ .get = n##_control_get, \
+ .put = n##_control_put, \
+}
+
+AMP_CONTROL(headphone, "Headphone Switch");
+AMP_CONTROL(speakers, "Speakers Switch");
+AMP_CONTROL(lineout, "Line-out Switch");
+
+static int check_codec(struct aoa_codec *codec, struct layout_dev *ldev, struct codec_connect_info *cci)
+{
+ u32 *ref;
+ char propname[32];
+ struct codec_connection *cc;
+
+ if (codec->node) {
+ snprintf(propname, sizeof(propname), "platform-%s-codec-ref", codec->name);
+ ref = (u32*)get_property(ldev->sound, propname, NULL);
+ /* if the codec has a node, we require a reference */
+ if (!ref) {
+ printk(KERN_INFO "snd-aoa-fabric-layout: required property %s not present\n", propname);
+ return -ENODEV;
+ }
+ if (*ref != codec->node->linux_phandle) {
+ printk(KERN_INFO "snd-aoa-fabric-layout: %s doesn't match!\n", propname);
+ return -ENODEV;
+ }
+ } else {
+ if (layouts_list_items != 1) {
+ printk(KERN_INFO "snd-aoa-fabric-layout: more than one soundbus, but no references. eek!\n");
+ return -ENODEV;
+ }
+ }
+ codec->soundbus_dev = ldev->sdev;
+ codec->gpio = &ldev->gpio;
+
+ cc = cci->connections;
+ if (!cc)
+ return -EINVAL;
+
+ printk(KERN_INFO "snd-aoa-fabric-layout: can use this codec\n");
+
+ codec->connected = 0;
+ codec->fabric_data = cc;
+
+ while (cc->connected) {
+ codec->connected |= 1<<cc->codec_bit;
+ cc++;
+ }
+
+ return 0;
+}
+
+static int layout_found_codec(struct aoa_codec *codec)
+{
+ struct layout_dev *ldev;
+ int i;
+
+ list_for_each_entry(ldev, &layouts_list, list) {
+ for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+ if (!ldev->layout->codecs[i].name)
+ continue;
+ if (strcmp(ldev->layout->codecs[i].name, codec->name) == 0) {
+ if (check_codec(codec, ldev, &ldev->layout->codecs[i]) == 0)
+ return 0;
+ }
+ }
+ }
+ return -ENODEV;
+}
+
+static void layout_remove_codec(struct aoa_codec *codec)
+{
+ int i;
+ /* here remove the codec from the layout dev's
+ * codec reference */
+
+ codec->soundbus_dev = NULL;
+ codec->gpio = NULL;
+ for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+ }
+}
+
+static void layout_attached_codec(struct aoa_codec *codec)
+{
+ struct codec_connection *cc;
+ struct snd_kcontrol *ctl;
+
+ /* need to add this codec to our codec array! */
+
+ cc = codec->fabric_data;
+
+ while (cc->connected) {
+ if (cc->connected & CC_SPEAKERS)
+ aoa_snd_ctl_add(snd_ctl_new1(&speakers_ctl, codec->gpio));
+ if (cc->connected & CC_HEADPHONE)
+ aoa_snd_ctl_add(snd_ctl_new1(&headphone_ctl, codec->gpio));
+ if (cc->connected & CC_LINEOUT) {
+ ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
+ if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+ strlcpy(ctl->id.name,
+ "Headphone Switch", sizeof(ctl->id.name));
+ aoa_snd_ctl_add(ctl);
+ }
+ cc++;
+ }
+}
+static struct aoa_fabric layout_fabric = {
+ .name = "SoundByLayout",
+ .owner = THIS_MODULE,
+ .found_codec = layout_found_codec,
+ .remove_codec = layout_remove_codec,
+ .attached_codec = layout_attached_codec,
+};
+
+static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
+{
+ struct device_node *sound = NULL;
+ unsigned int *layout_id;
+ struct layout *layout;
+ struct layout_dev *ldev = NULL;
+ int err;
+
+ /* by breaking out we keep a reference */
+ while ((sound = of_get_next_child(sdev->ofdev.node, sound))) {
+ if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
+ break;
+ }
+ if (!sound) return -ENODEV;
+
+ layout_id = (unsigned int *) get_property(sound, "layout-id", NULL);
+ if (!layout_id)
+ goto outnodev;
+ printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d ", *layout_id);
+
+ layout = find_layout_by_id(*layout_id);
+ if (!layout) {
+ printk("(no idea how to handle)\n");
+ goto outnodev;
+ }
+
+ ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL);
+ if (!ldev)
+ goto outnodev;
+
+ ldev->sdev = sdev;
+ ldev->sound = sound;
+ ldev->layout = layout;
+ ldev->gpio.node = sound->parent;
+ ldev->gpio.methods = pmf_gpio_methods;
+ sdev->ofdev.dev.driver_data = ldev;
+
+ printk("(using)\n");
+ list_add(&ldev->list, &layouts_list);
+ layouts_list_items++;
+
+ /* assign these before registering ourselves, so
+ * callbacks that are done during registration
+ * already have the values */
+ sdev->pcmid = ldev->layout->pcmid;
+ if (ldev->layout->busname) {
+ sdev->pcmname = ldev->layout->busname;
+ } else {
+ sdev->pcmname = "Master";
+ }
+
+ err = aoa_fabric_register(&layout_fabric);
+ if (err && err != -EALREADY) {
+ printk(KERN_INFO "snd-aoa-fabric-layout: can't use,"
+ " another fabric is active!\n");
+ goto outlistdel;
+ }
+
+ ldev->gpio.methods->init(&ldev->gpio);
+ use_layout(layout);
+ return 0;
+ outlistdel:
+ /* reset if we didn't use it */
+ sdev->pcmname = NULL;
+ sdev->pcmid = -1;
+ list_del(&ldev->list);
+ layouts_list_items--;
+ outnodev:
+ if (sound) of_node_put(sound);
+ if (ldev) kfree(ldev);
+ return -ENODEV;
+}
+
+static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
+{
+ struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+ int i;
+
+ for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+ if (ldev->codecs[i]) {
+ aoa_fabric_unlink_codec(ldev->codecs[i]);
+ }
+ ldev->codecs[i] = NULL;
+ }
+ list_del(&ldev->list);
+ layouts_list_items--;
+ of_node_put(ldev->sound);
+
+ ldev->gpio.methods->exit(&ldev->gpio);
+ kfree(ldev);
+ sdev->pcmid = -1;
+ sdev->pcmname = NULL;
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
+{
+ struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+
+ printk("aoa_fabric_layout_suspend()\n");
+
+ if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
+ ldev->gpio.methods->all_amps_off(&ldev->gpio);
+
+ return 0;
+}
+
+static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
+{
+ struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+
+ printk("aoa_fabric_layout_resume()\n");
+
+ if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
+ ldev->gpio.methods->all_amps_restore(&ldev->gpio);
+
+ return 0;
+}
+#endif
+
+static struct soundbus_driver aoa_soundbus_driver = {
+ .name = "snd_aoa_soundbus_drv",
+ .owner = THIS_MODULE,
+ .probe = aoa_fabric_layout_probe,
+ .remove = aoa_fabric_layout_remove,
+#ifdef CONFIG_PM
+ .suspend = aoa_fabric_layout_suspend,
+ .resume = aoa_fabric_layout_resume,
+#endif
+};
+
+static int __init aoa_fabric_layout_init(void)
+{
+ int err;
+
+ err = soundbus_register_driver(&aoa_soundbus_driver);
+ if (err)
+ return err;
+ return 0;
+}
+
+static void __exit aoa_fabric_layout_exit(void)
+{
+ soundbus_unregister_driver(&aoa_soundbus_driver);
+ aoa_fabric_unregister(&layout_fabric);
+}
+
+module_init(aoa_fabric_layout_init);
+module_exit(aoa_fabric_layout_exit);
--
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox