LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Xilinx BSP for linux 2.6
From: Ming Liu @ 2006-07-06 14:04 UTC (permalink / raw)
  To: ammubhai; +Cc: linuxppc-embedded
In-Reply-To: <44AD108A.8050802@gmail.com>

Dear Ameet,

>   I DONOT have a ML403 with me. But does Xilinx EDK generate
>xparameters_ml300.h in the BSP instead of xparameters_ml403.h for the
>ML403 board?

Yes. EKD only generates ml300.h instead of ml403.h, although you specify 
the platform is ML403.


>You need to just copy the xparameters_ml300.h file (if that is what
>xilinx EDK generates) as xparameters_ml403.h in
>arch/ppc/platforms/4xx/xparameters/ folder. Configure the kernel as ML403.

I don't think so. I have looked into these two files. I found that there 
are many differences between them. Not only the addresses for each 
peripheral are different, but also the parameters' names. So If we just 
simply copy ml300.h file as ml403.h, many parameters will be undefined. 

>Like I said to you before, if you want to get started quickly and
>without much headache.. then please go step-by-step. Try the things I
>mention in the article PART I without applying any patches.

Thanks for your suggestion. I will start from the beginning. 

>Please DONOT hesitate to ask further clarifications!

It is really like a big family in the Linux world because of the help among 
the persons. Thanks for all the help from the friends in Linux world!

Regards
Ming

_________________________________________________________________
免费下载 MSN Explorer:   http://explorer.msn.com/lccn/  

^ permalink raw reply

* Re: Xilinx BSP for linux 2.6
From: Ameet Patil @ 2006-07-06 14:40 UTC (permalink / raw)
  To: Ming Liu; +Cc: linuxppc-embedded
In-Reply-To: <BAY110-F14AAB7BEB55C4563A4598AB2770@phx.gbl>

Hi Ming,
   If your Xilinx EDK generates the xparameters_ml300.h file for the
ML403 board then it has been configured with the right parameters and
address required by Linux. Don't look at the existing
xparameters_ml403.h file in the kernel source. It has got too many
parameters with address initializations that might not suit you at all.
I think its safe to copy the ml300.h onto ml403.h. I tried it... the
kernel compiles without any problems.

-Ameet

Ming Liu wrote:
> Dear Ameet,
> 
>>   I DONOT have a ML403 with me. But does Xilinx EDK generate
>> xparameters_ml300.h in the BSP instead of xparameters_ml403.h for the
>> ML403 board?
> 
> Yes. EKD only generates ml300.h instead of ml403.h, although you specify 
> the platform is ML403.
> 
> 
>> You need to just copy the xparameters_ml300.h file (if that is what
>> xilinx EDK generates) as xparameters_ml403.h in
>> arch/ppc/platforms/4xx/xparameters/ folder. Configure the kernel as 
>> ML403.
> 
> I don't think so. I have looked into these two files. I found that there 
> are many differences between them. Not only the addresses for each 
> peripheral are different, but also the parameters' names. So If we just 
> simply copy ml300.h file as ml403.h, many parameters will be undefined.
>> Like I said to you before, if you want to get started quickly and
>> without much headache.. then please go step-by-step. Try the things I
>> mention in the article PART I without applying any patches.
> 
> Thanks for your suggestion. I will start from the beginning.
>> Please DONOT hesitate to ask further clarifications!
> 
> It is really like a big family in the Linux world because of the help 
> among the persons. Thanks for all the help from the friends in Linux world!
> 
> Regards
> Ming
> 
> _________________________________________________________________
> 免费下载 MSN Explorer:   http://explorer.msn.com/lccn/ 
> 

^ permalink raw reply

* G5 troubles booting powerpc-git (July 6)
From: Will Schmidt @ 2006-07-06 14:53 UTC (permalink / raw)
  To: linuxppc-dev


        Any other G5's having troubles booting with the powerpc-git
        tree? 
        
        Mine fails..   The last text to the console is "MacIO PCI driver
        attached to Shasta chipset",  then the fans ramp up.  
        
        Booted earlier this week OK, so seems like a change in the last
        couple
        days did something bad.
        
        -Will
        

^ permalink raw reply

* RE: rs232 endianness on PPC
From: Walter L. Wimer III @ 2006-07-06 15:31 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <200607021210.19130.antonio.dibacco@aruba.it>

On Sun, 2006-07-02 at 12:10 +0200, Antonio Di Bacco wrote:
> PowerPC is neither byte swapped nor bit swapped.
> When transmitting on a network card the most significant byte is transmitted 
> first, and, inside the byte, the most significant bit is sent first.

FYI, the *bit*-order on a network actually depends on the layer 2
network standard that you happen to be communicating over.  Ethernet /
IEEE 802.3 is *least significant* bit first on the wire.  SLIP and
asynchronous PPP (since they go over RS232) are also least-significant
bit first.  IBM Token-Ring / IEEE 802.5 was most-significant bit first
on the wire.

IETF protocols such as IP, TCP, UDP, etc., etc., etc., only specify the
*byte* order, which is most-significant *byte* first.

Generally speaking, a network device driver programmer need only worry
about getting the *byte* order correct.  The network interface hardware
generally takes care of the *bit* order.  (An exception to this can be
drivers and interface hardware for some low-speed "networks" such as I2C
or Dallas 1-Wire.  These may be very primitive and require software
"bit-banging" where the driver software must explicitly shift bits out
of a byte and transmit them one bit at a time.  Clearly in these cases,
the driver must transmit the bits in the correct order based on the
appropriate standard (e.g. I2C, Dallas 1-Wire, etc.).)



Cheers,

Walt Wimer
TimeSys Corporation

^ permalink raw reply

* Re: snd-aoa issues & fixes
From: Johannes Berg @ 2006-07-06 16:51 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1151481678.4044.11.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 3066 bytes --]

On Wed, 2006-06-28 at 18:01 +1000, Benjamin Herrenschmidt wrote:

> - Redefinition of various FCR related bits in i2s-control. I've fixed
> that in the patch and used existing definitions. However, we still have
> a problem that we don't properly lock with pmac_feature for access to
> these. We need to either expose new feature calls now that we are
> upstream or expose the pmac_feature spinlock

Oh, good point. I'd say we add feature calls for that.

> - I noticed you don't call pmac_feature and don't set bits in FCR3
> etc... (enabling the 18Mhz clock for example). Is that normal ? You
> don't use that clock ? That's the only difference in FCR content that
> I've been able to spot between snd-powermac and snd-aoa but hacking it
> doesn't seem to make much difference.

Nah, I simply forgot that. Apparently all the clocks are on anyway? All
rates seem to work here... We want clock refcounting so we can actually
turn them off again, turning them all on is easy enough.

> - The fabric stuff needs a bit of cleanup... You seem to be fond of
> defining lotsa struct's :) Even when they don't contain much :) Triggers
> another problem below

Awww :)

> - I've had a crash with built-in snd-aoa at boot... The problem is that
> when built-in, there is no enforced ordering between module_init() calls
> except for link order... What happens here is that soundbus is last in
> the Makefile, thus we try to register soundbus devices before we
> register the bus type. I fixes that in the patch both by putting
> soundbus first in the Make

Good point. I think someone else noticed that too.

> - If i2sbus is loaded after the codec and fabric, the codec fails to
> initialize. I haven't tried to debug that one

Uhh. I thought the codec couldn't be loaded before i2sbus. I'll have to
see what causes this, probably some reference missing.

> - The dmesg output could use some cleanup :)

:)

> I think we need to change the codec probe phase dramatically: 

It's not as dramatic as you think.

>   1 - codec drivers register the i2c thingy as normal
>   2 - i2c kicks in, they do the current device-node and/or i2c bus name
> check and register
>       themselves with the core. They do not try to touch the hardware at
> this point
>   3 - fabric kicks in (or was already there). It checks the list of
> codecs registered when
>       loaded and gets notified of new ones added. If codec matches the
> layout, then codec
>       init is called
>   4 - codec init called by fabric. That is where we try to tap the
> hardware. Might fail in
>       which case the fabric doesn't try to use the codec

> (That is, there is a global list of registered codecs at the core, and a
> list of "active" codecs in the fabric or bus, whatever...)

Nah. All we need to do is change the onyx codec driver to not try
probing the onyx. The tas already does it this way iirc. The toonie is a
bit different again, the module will fail loading when the fabric
doesn't want it. But that's fine.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: G5 troubles booting powerpc-git (July 6)
From: Benjamin Herrenschmidt @ 2006-07-06 22:53 UTC (permalink / raw)
  To: will_schmidt; +Cc: linuxppc-dev
In-Reply-To: <1152197602.14547.10.camel@farscape.rchland.ibm.com>

On Thu, 2006-07-06 at 09:53 -0500, Will Schmidt wrote:
>         Any other G5's having troubles booting with the powerpc-git
>         tree? 
>         
>         Mine fails..   The last text to the console is "MacIO PCI driver
>         attached to Shasta chipset",  then the fans ramp up.  
>         
>         Booted earlier this week OK, so seems like a change in the last
>         couple
>         days did something bad

I suspect there's still something wrong with mpic map callback, I'm
working on it

Ben.

^ permalink raw reply

* Re: G5 troubles booting powerpc-git (July 6)
From: Benjamin Herrenschmidt @ 2006-07-06 22:56 UTC (permalink / raw)
  To: will_schmidt; +Cc: Andrew Morton, linuxppc-dev
In-Reply-To: <1152197602.14547.10.camel@farscape.rchland.ibm.com>

If you look at arch/powerpc/kernel/irq.c from line 479:

	/* Check if mapping already exist, if it does, call
	 * host->ops->map() to update the flags
	 */
	virq = irq_find_mapping(host, hwirq);
	if (virq != IRQ_NONE) {
		pr_debug("irq: -> existing mapping on virq %d\n", virq);
		host->ops->map(host, virq, hwirq, flags);
		return virq;
	}

What if you comment out the host->ops->map(...) call in there ? Does it
help ?

I think I have a little misdesign in my new powerpc irq handling
regarding the mixing up of mapping and setting of triggers. I'm working
on a solution, hopefully patches early next week.

Ben.

^ permalink raw reply

* Re: [PATCH 4/20] Mark platform device data as const
From: Paul Mackerras @ 2006-07-06 23:41 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linuxppc-dev, greg
In-Reply-To: <45499930@toto.iv>

Jeremy Kerr writes:

> platform_device_add_data()'s data argument can be qualified as const -
> the function just copies it to another buffer.

Ummm, you change the actual function definition here, but you put the
change to the declaration in include/linux/platform_device.h in your
[5/20] patch.  Please redo this patch with the change to the
declaration included.

Paul.

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Benjamin Herrenschmidt @ 2006-07-07  5:38 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell,
	Johannes Berg
In-Reply-To: <jehd231rjx.fsf@sykes.suse.de>

On Fri, 2006-06-30 at 01:16 +0200, Andreas Schwab wrote:
> Lee Revell <rlrevell@joe-job.com> writes:
> 
> > What is the content of /proc/asound/cards?  The patches must have
> > changed the card name and failed to create a matching config file
> > in /usr/share/alsa/cards.
> 
> Thanks for the hint.  I have added 'AppleOnbdAudio cards.PMac' to
> /usr/share/alsa/cards/aliases.conf, and it works again.

There is still an issue... wether to enable softvol or not... With
snd-aoa, the card name is always the same but wether it has hardware
volume control or not (Toonie doesn't) is not known... Alsa should have
ways to add softvol automatically if no master volume control exist.

Ben.

^ permalink raw reply

* [PATCH] dtc: fix endian issue when reading blobs
From: Michael Neuling @ 2006-07-07  5:53 UTC (permalink / raw)
  To: linuxppc-dev, Jon Loeliger

The reserve mem regions are screwy if you read a blob on x86.  I'm
guessing there may be a few more of these lurking in the code. 

Signed-off-by: Michael Neuling <mikey@neuling.org>

---
This now gives clean diffs between running on big and little endian machines.

 flattree.c |    2 ++
 1 file changed, 2 insertions(+)

Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c
+++ dtc/flattree.c
@@ -619,6 +619,8 @@ static struct reserve_info *flat_read_me
 	p = inb->ptr;
 	while (1) {
 		flat_read_chunk(inb, &re, sizeof(re));
+		re.address  = cpu_to_be64(re.address);
+		re.size = cpu_to_be64(re.size);
 		if (re.size == 0)
 			break;
 

^ permalink raw reply

* snd-aoa: g5 tas codec problems
From: Benjamin Herrenschmidt @ 2006-07-07  7:47 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list, alsa-devel

Ok, so now I have it working on the G5 :)

(Patch below)

There are several issues (I would say in addition to what I listed
earlier):

 - Maybe it's me or maybe it's just too complicated, but I haven't quite
grasped the whole interaction between the soundbus,i2sbus,fabric and
codecs... especially initialisation ordering. It would be nice if we
could spend some time going through that and simplifying :) It leads to
at least one of the problems

 - The patch fixes a couple of nits related to having the modules
built-in: soundbus must really be a subsys_initcall() so it's
initialized before anybody else, and I've put the soundbus/ dir before
the codecs in the link order because the TAS is unhappy if loaded before
i2s (see below)

 - The TAS is a nasty beast. It needs the i2s clocks enabled or it goes
bunk... That's the problem with the G5. I've added a clock notifier and
reset it completely when the clocks come back, that's what fixes the G5
sound (looks like it loses state somewhat when not clocked). It would be
nice to streamline/cleanup some of the TAS handling, maybe with register
shadows like darwin or just with proper state variables to re-consitute
the whole thing and have a "fast mode" load since we need to do it so
often

 - Because of the above, starting to play a sound 1- takes some time to
init things and 2- clacks (setting the mutes on TAS before losing clocks
isn't enough, I think the fact that it goes bonk makes it parasite the
analog outputs). We need to also mute the amps around that. I haven't
quite figured how to do that from i2sbus though :) Also, we should try
(if not already the case) to cache our clock/i2s state so that
subsequent prepare() don't try to change things that are already ok.
That way we avoid having to blast the codec each time. But right now,
the important thing is to add mutes. People with external amplifiers
will really not like those clacs...

Note that the patch applies on top of Andreas latest one fixing the irq
on latest git.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Index: linux-irq-work/sound/aoa/soundbus/core.c
===================================================================
--- linux-irq-work.orig/sound/aoa/soundbus/core.c	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/soundbus/core.c	2006-07-07 15:58:25.000000000 +1000
@@ -246,5 +246,5 @@
 }
 EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
 
-module_init(soundbus_init);
+subsys_initcall(soundbus_init);
 module_exit(soundbus_exit);
Index: linux-irq-work/arch/powerpc/platforms/powermac/feature.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/feature.c	2006-07-01 13:51:11.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/feature.c	2006-07-07 16:13:20.000000000 +1000
@@ -2394,6 +2394,7 @@
 
 	return func(node, param, value);
 }
+EXPORT_SYMBOL_GPL(pmac_do_feature_call);
 
 static int __init probe_motherboard(void)
 {
Index: linux-irq-work/sound/aoa/Makefile
===================================================================
--- linux-irq-work.orig/sound/aoa/Makefile	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/Makefile	2006-07-07 16:11:35.000000000 +1000
@@ -1,4 +1,4 @@
 obj-$(CONFIG_SND_AOA) += core/
-obj-$(CONFIG_SND_AOA) += codecs/
-obj-$(CONFIG_SND_AOA) += fabrics/
 obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
+obj-$(CONFIG_SND_AOA) += fabrics/
+obj-$(CONFIG_SND_AOA) += codecs/
Index: linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.c
===================================================================
--- linux-irq-work.orig/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-07-07 15:46:30.000000000 +1000
+++ linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-07-07 17:45:06.000000000 +1000
@@ -75,19 +75,25 @@
 #include "../aoa.h"
 #include "../soundbus/soundbus.h"
 
-
 #define PFX "snd-aoa-codec-tas: "
 
+
 struct tas {
 	struct aoa_codec	codec;
 	struct i2c_client	i2c;
-	u32			muted_l:1, muted_r:1,
-				controls_created:1;
+	u32			mute_l:1, mute_r:1 ,
+				controls_created:1 ,
+				drc_enabled:1,
+				save_mute_l:1, save_mute_r:1,
+				hw_enabled:1;
 	u8			cached_volume_l, cached_volume_r;
 	u8			mixer_l[3], mixer_r[3];
 	u8			acr;
+	int			drc_range;
 };
 
+static int tas_reset_init(struct tas *tas);
+
 static struct tas *codec_to_tas(struct aoa_codec *codec)
 {
 	return container_of(codec, struct tas, codec);
@@ -101,6 +107,28 @@
 		return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
 }
 
+static void tas3004_set_drc(struct tas *tas)
+{
+	unsigned char val[6];
+
+	if (tas->drc_enabled)
+		val[0] = 0x50; /* 3:1 above threshold */
+	else
+		val[0] = 0x51; /* disabled */
+	val[1] = 0x02; /* 1:1 below threshold */
+	if (tas->drc_range > 0xef)
+		val[2] = 0xef;
+	else if (tas->drc_range < 0)
+		val[2] = 0x00;
+	else
+		val[2] = tas->drc_range;
+	val[3] = 0xb0;
+	val[4] = 0x60;
+	val[5] = 0xa0;
+
+	tas_write_reg(tas, TAS_REG_DRC, 6, val);
+}
+
 static void tas_set_volume(struct tas *tas)
 {
 	u8 block[6];
@@ -113,8 +141,8 @@
 	if (left > 177) left = 177;
 	if (right > 177) right = 177;
 
-	if (tas->muted_l) left = 0;
-	if (tas->muted_r) right = 0;
+	if (tas->mute_l) left = 0;
+	if (tas->mute_r) right = 0;
 
 	/* analysing the volume and mixer tables shows
 	 * that they are similar enough when we shift
@@ -202,7 +230,8 @@
 
 	tas->cached_volume_l = ucontrol->value.integer.value[0];
 	tas->cached_volume_r = ucontrol->value.integer.value[1];
-	tas_set_volume(tas);
+	if (tas->hw_enabled)
+		tas_set_volume(tas);
 	return 1;
 }
 
@@ -230,8 +259,8 @@
 {
 	struct tas *tas = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.integer.value[0] = !tas->muted_l;
-	ucontrol->value.integer.value[1] = !tas->muted_r;
+	ucontrol->value.integer.value[0] = !tas->mute_l;
+	ucontrol->value.integer.value[1] = !tas->mute_r;
 	return 0;
 }
 
@@ -240,13 +269,14 @@
 {
 	struct tas *tas = snd_kcontrol_chip(kcontrol);
 
-	if (tas->muted_l == !ucontrol->value.integer.value[0]
-	 && tas->muted_r == !ucontrol->value.integer.value[1])
+	if (tas->mute_l == !ucontrol->value.integer.value[0]
+	 && tas->mute_r == !ucontrol->value.integer.value[1])
 		return 0;
 
-	tas->muted_l = !ucontrol->value.integer.value[0];
-	tas->muted_r = !ucontrol->value.integer.value[1];
-	tas_set_volume(tas);
+	tas->mute_l = !ucontrol->value.integer.value[0];
+	tas->mute_r = !ucontrol->value.integer.value[1];
+	if (tas->hw_enabled)
+		tas_set_volume(tas);
 	return 1;
 }
 
@@ -294,7 +324,8 @@
 	tas->mixer_l[idx] = ucontrol->value.integer.value[0];
 	tas->mixer_r[idx] = ucontrol->value.integer.value[1];
 
-	tas_set_mixer(tas);
+	if (tas->hw_enabled)
+		tas_set_mixer(tas);
 	return 1;
 }
 
@@ -310,7 +341,6 @@
 }
 
 MIXER_CONTROL(pcm1, "PCM1", 0);
-MIXER_CONTROL(pcm2, "PCM2", 1);
 MIXER_CONTROL(monitor, "Monitor", 2);
 
 static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
@@ -347,7 +377,8 @@
 		tas->acr |= TAS_ACR_INPUT_B;
 	if (oldacr == tas->acr)
 		return 0;
-	tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
+	if (tas->hw_enabled)
+		tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
 	return 1;
 }
 
@@ -400,26 +431,68 @@
 static int tas_reset_init(struct tas *tas)
 {
 	u8 tmp;
+
+	msleep(5);
 	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
-	msleep(1);
+	msleep(5);
 	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
-	msleep(1);
+	msleep(20);
 	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
-	msleep(1);
-
-	tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
-	tas->acr |= TAS_ACR_B_MONAUREAL | TAS_ACR_B_MON_SEL_RIGHT;
-	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
-		return -ENODEV;
+	msleep(10);
 
 	tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
 	if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
 		return -ENODEV;
 
+	tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL |
+		TAS_ACR_B_MON_SEL_RIGHT;
+	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+		return -ENODEV;
+
 	tmp = 0;
 	if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
 		return -ENODEV;
 
+	tas3004_set_drc(tas);
+
+	/* Set treble & bass to 0dB */
+	tmp = 114;
+	tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp);
+	tas_write_reg(tas, TAS_REG_BASS, 1, &tmp);
+
+	tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
+	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock)
+{
+	struct tas *tas = cii->codec_data;
+
+	switch(clock) {
+	case CLOCK_SWITCH_PREPARE_SLAVE:
+		/* Clocks are going away, mute mute mute */
+		tas->save_mute_l = tas->mute_l;
+		tas->save_mute_r = tas->mute_r;
+		tas->mute_l = tas->mute_l = 1;
+		tas_set_volume(tas);
+		tas->hw_enabled = 0;
+		break;
+	case CLOCK_SWITCH_SLAVE:
+		/* Clocks are back, re-init the codec */
+		tas->mute_l = tas->save_mute_l;
+		tas->mute_r = tas->save_mute_r;
+		tas_reset_init(tas);
+		tas_set_volume(tas);
+		tas_set_mixer(tas);
+		tas->hw_enabled = 1;
+		break;
+	default:
+		/* Do we want to return an error here ? */
+		return 0;
+	}
 	return 0;
 }
 
@@ -428,6 +501,7 @@
  * our i2c device is suspended, and then take note of that! */
 static int tas_suspend(struct tas *tas)
 {
+	tas->hw_enabled = 0;
 	tas->acr |= TAS_ACR_ANALOG_PDOWN;
 	tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
 	return 0;
@@ -439,6 +513,7 @@
 	tas_reset_init(tas);
 	tas_set_volume(tas);
 	tas_set_mixer(tas);
+	tas->hw_enabled = 1;
 	return 0;
 }
 
@@ -464,6 +539,7 @@
 	.bus_factor = 64,
 	.owner = THIS_MODULE,
 	.usable = tas_usable,
+	.switch_clock = tas_switch_clock,
 #ifdef CONFIG_PM
 	.suspend = _tas_suspend,
 	.resume = _tas_resume,
@@ -480,11 +556,6 @@
 		return -EINVAL;
 	}
 
-	if (tas_reset_init(tas)) {
-		printk(KERN_ERR PFX "tas failed to initialise\n");
-		return -ENXIO;
-	}
-
 	if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
 						   aoa_get_card(),
 						   &tas_codec_info, tas)) {
@@ -508,10 +579,6 @@
 	if (err)
 		goto error;
 
-	err = aoa_snd_ctl_add(snd_ctl_new1(&pcm2_control, tas));
-	if (err)
-		goto error;
-
 	err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
 	if (err)
 		goto error;
@@ -553,6 +620,7 @@
 	tas->i2c.driver = &tas_driver;
 	tas->i2c.adapter = adapter;
 	tas->i2c.addr = addr;
+	tas->drc_range = TAS3004_DRC_MAX;
 	strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
 
 	if (i2c_attach_client(&tas->i2c)) {
@@ -569,7 +637,9 @@
 	if (aoa_codec_register(&tas->codec)) {
 		goto detach;
 	}
-	printk(KERN_DEBUG "snd-aoa-codec-tas: created and attached tas instance\n");
+	printk(KERN_DEBUG
+	       "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
+	       addr, node->full_name);
 	return 0;
  detach:
 	i2c_detach_client(&tas->i2c);
@@ -657,3 +727,5 @@
 
 module_init(tas_init);
 module_exit(tas_exit);
+
+
Index: linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.h
===================================================================
--- linux-irq-work.orig/sound/aoa/codecs/snd-aoa-codec-tas.h	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.h	2006-07-07 16:58:17.000000000 +1000
@@ -44,4 +44,12 @@
 #define TAS_REG_LEFT_BIQUAD6	0x10
 #define TAS_REG_RIGHT_BIQUAD6	0x19
 
+#define TAS_REG_LEFT_LOUDNESS		0x21
+#define TAS_REG_RIGHT_LOUDNESS		0x22
+#define TAS_REG_LEFT_LOUDNESS_GAIN	0x23
+#define TAS_REG_RIGHT_LOUDNESS_GAIN	0x24
+
+#define TAS3001_DRC_MAX		0x5f
+#define TAS3004_DRC_MAX		0xef
+
 #endif /* __SND_AOA_CODECTASH */
Index: linux-irq-work/sound/aoa/core/snd-aoa-gpio-pmf.c
===================================================================
--- linux-irq-work.orig/sound/aoa/core/snd-aoa-gpio-pmf.c	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/core/snd-aoa-gpio-pmf.c	2006-07-07 16:10:25.000000000 +1000
@@ -14,9 +14,13 @@
 static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
 {								\
 	struct pmf_args args = { .count = 1, .u[0].v = !on };	\
-								\
+	int rc;							\
+							\
 	if (unlikely(!rt)) return;				\
-	pmf_call_function(rt->node, #name "-mute", &args);	\
+	rc = pmf_call_function(rt->node, #name "-mute", &args);	\
+	if (rc)							\
+		printk(KERN_WARNING "pmf_gpio_set_" #name	\
+		" failed, rc: %d\n", rc);			\
 	rt->implementation_private &= ~(1<<bit);		\
 	rt->implementation_private |= (!!on << bit);		\
 }								\
@@ -33,9 +37,13 @@
 static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
 {
 	struct pmf_args args = { .count = 1, .u[0].v = !!on };
+	int rc;
 
 	if (unlikely(!rt)) return;
-	pmf_call_function(rt->node, "hw-reset", &args);
+	rc = pmf_call_function(rt->node, "hw-reset", &args);
+	if (rc)
+		printk(KERN_WARNING "pmf_gpio_set_hw_reset"
+		       " failed, rc: %d\n", rc);
 }
 
 static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
Index: linux-irq-work/sound/aoa/fabrics/snd-aoa-fabric-layout.c
===================================================================
--- linux-irq-work.orig/sound/aoa/fabrics/snd-aoa-fabric-layout.c	2006-07-01 13:51:30.000000000 +1000
+++ linux-irq-work/sound/aoa/fabrics/snd-aoa-fabric-layout.c	2006-07-07 16:17:43.000000000 +1000
@@ -950,11 +950,12 @@
 	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);
+	printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d\n",
+	       *layout_id);
 
 	layout = find_layout_by_id(*layout_id);
 	if (!layout) {
-		printk("(no idea how to handle)\n");
+		printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n");
 		goto outnodev;
 	}
 
@@ -972,15 +973,17 @@
 	case 51: /* PowerBook5,4 */
 	case 58: /* Mac Mini */
 		ldev->gpio.methods = ftr_gpio_methods;
+		printk(KERN_DEBUG
+		       "snd-aoa-fabric-layout: Using PMF GPIOs\n");
 		break;
 	default:
 		ldev->gpio.methods = pmf_gpio_methods;
+		printk(KERN_DEBUG
+		       "snd-aoa-fabric-layout: Using direct GPIOs\n");
 	}
 	ldev->selfptr_headphone.ptr = ldev;
 	ldev->selfptr_lineout.ptr = ldev;
 	sdev->ofdev.dev.driver_data = ldev;
-
-	printk("(using)\n");
 	list_add(&ldev->list, &layouts_list);
 	layouts_list_items++;
 

^ permalink raw reply

* Re: snd-aoa: g5 tas codec problems
From: Benjamin Herrenschmidt @ 2006-07-07  7:50 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list, alsa-devel
In-Reply-To: <1152258426.9862.44.camel@localhost.localdomain>

On Fri, 2006-07-07 at 17:47 +1000, Benjamin Herrenschmidt wrote:

> Note that the patch applies on top of Andreas latest one fixing the irq
> on latest git.

Actually, it applies on top of Andres patch, plus my patch fixing the
resources on g5, updated to apply on top of latest git:

I'll do a combo patch later (or you can do one if you want)

Ben.

Index: linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus-core.c
===================================================================
--- linux-irq-work.orig/sound/aoa/soundbus/i2sbus/i2sbus-core.c	2006-07-07 15:40:53.000000000 +1000
+++ linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus-core.c	2006-07-07 15:45:06.000000000 +1000
@@ -7,13 +7,16 @@
  */
 
 #include <linux/module.h>
-#include <asm/macio.h>
-#include <asm/dbdma.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
 #include <sound/driver.h>
 #include <sound/core.h>
-#include <linux/dma-mapping.h>
+
+#include <asm/macio.h>
+#include <asm/dbdma.h>
+
 #include "../soundbus.h"
 #include "i2sbus.h"
 
@@ -24,6 +27,12 @@
  * string that macio puts into the relevant device */
 MODULE_ALIAS("of:Ni2sTi2sC");
 
+static int force;
+module_param(force, int, 0444);
+MODULE_PARM_DESC(force, "Force loading i2sbus even when"
+		 " no layout-id property is present");
+
+
 static struct of_device_id i2sbus_match[] = {
 	{ .name = "i2s" },
 	{ }
@@ -73,7 +82,7 @@
  	if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
  	if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
  	if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
-	for (i=0;i<3;i++)
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
 		if (i2sdev->allocated_resource[i])
 			release_and_free_resource(i2sdev->allocated_resource[i]);
 	free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
@@ -101,10 +110,47 @@
 	return IRQ_HANDLED;
 }
 
-static int force;
-module_param(force, int, 0444);
-MODULE_PARM_DESC(force, "Force loading i2sbus even when"
-			" no layout-id property is present");
+/*
+ * XXX FIXME: We have to test the layout_id's here to get the proper way
+ * of mapping in various registers, thanks to bugs in Apple device-trees.
+ * Ideally, that should be handled by the layout fabric but doing so would
+ * require a little bit of shuffling around
+ */
+static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
+				     int layout, struct resource *res)
+{
+	struct device_node *parent;
+	int pindex, rc = -ENXIO;
+	u32 *reg;
+
+	/* Machines with layout 76 and 36 (K2 based) have a weird device
+	 * tree what we need to special case.
+	 * Normal machines just fetch the resource from the i2s-X node.
+	 * Darwin further divides normal machines into old and new layouts
+	 * with a subtely different code path but that doesn't seem necessary
+	 * in practice, they just bloated it. In addition, even on our K2
+	 * case the i2s-modem node, if we ever want to handle it, uses the
+	 * normal layout
+	 */
+	if (layout != 76 && layout != 36)
+		return of_address_to_resource(np, index, res);
+
+	parent = of_get_parent(np);
+	pindex = (index == aoa_resource_i2smmio) ? 0 : 1;
+	rc = of_address_to_resource(parent, pindex, res);
+	if (rc)
+		goto bail;
+	reg = (u32 *)get_property(np, "reg", NULL);
+	if (reg == NULL) {
+		rc = -ENXIO;
+		goto bail;
+	}
+	res->start += reg[index * 2];
+	res->end = res->start + reg[index * 2 + 1] - 1;
+ bail:
+	of_node_put(parent);
+	return rc;
+}
 
 /* FIXME: look at device node refcounting */
 static int i2sbus_add_dev(struct macio_dev *macio,
@@ -113,7 +159,8 @@
 {
 	struct i2sbus_dev *dev;
 	struct device_node *child = NULL, *sound = NULL;
-	int i;
+	struct resource *r;
+	int i, layout = 0;
 	static const char *rnames[] = { "i2sbus: %s (control)",
 					"i2sbus: %s (tx)",
 					"i2sbus: %s (rx)" };
@@ -144,8 +191,9 @@
 		u32 *layout_id;
 		layout_id = (u32*) get_property(sound, "layout-id", NULL);
 		if (layout_id) {
+			layout = *layout_id;
 			snprintf(dev->sound.modalias, 32,
-				 "sound-layout-%d", *layout_id);
+				 "sound-layout-%d", layout);
 			force = 1;
 		}
 	}
@@ -175,23 +223,32 @@
 	dev->bus_number = np->name[4] - 'a';
 	INIT_LIST_HEAD(&dev->sound.codec_list);
 
-	for (i=0;i<3;i++) {
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
 		dev->interrupts[i] = -1;
-		snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i], np->name);
+		snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i],
+			 np->name);
 	}
-	for (i=0;i<3;i++) {
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
 		int irq = irq_of_parse_and_map(np, i);
 		if (request_irq(irq, ints[i], 0, dev->rnames[i], dev))
 			goto err;
 		dev->interrupts[i] = irq;
 	}
 
-	for (i=0;i<3;i++) {
-		if (of_address_to_resource(np, i, &dev->resources[i]))
+	/* Resource handling is problematic as some device-trees contain
+	 * useless crap (ugh ugh ugh). We work around that here by calling
+	 * specific functions for calculating the appropriate resources.
+	 *
+	 * This will all be moved to macio_asic.c at one point
+	 */
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+		if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i]))
 			goto err;
-		/* if only we could use our resource dev->resources[i]...
+
+		/* If only we could use our resource dev->resources[i]...
 		 * but request_resource doesn't know about parents and
-		 * contained resources... */
+		 * contained resources...
+		 */
 		dev->allocated_resource[i] = 
 			request_mem_region(dev->resources[i].start,
 					   dev->resources[i].end -
@@ -203,12 +260,12 @@
 		}
 	}
 	/* should do sanity checking here about length of them */
-	dev->intfregs = ioremap(dev->resources[0].start,
-				dev->resources[0].end-dev->resources[0].start+1);
-	dev->out.dbdma = ioremap(dev->resources[1].start,
-			 	 dev->resources[1].end-dev->resources[1].start+1);
-	dev->in.dbdma = ioremap(dev->resources[2].start,
-				dev->resources[2].end-dev->resources[2].start+1);
+	r = &dev->resources[aoa_resource_i2smmio];
+	dev->intfregs = ioremap(r->start, r->end - r->start + 1);
+	r = &dev->resources[aoa_resource_txdbdma];
+	dev->out.dbdma = ioremap(r->start, r->end - r->start + 1);
+	r = &dev->resources[aoa_resource_rxdbdma];
+	dev->in.dbdma = ioremap(r->start, r->end - r->start + 1);
 	if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
 		goto err;
 
Index: linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus.h
===================================================================
--- linux-irq-work.orig/sound/aoa/soundbus/i2sbus/i2sbus.h	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus.h	2006-07-07 15:41:40.000000000 +1000
@@ -7,20 +7,22 @@
  */
 #ifndef __I2SBUS_H
 #define __I2SBUS_H
-#include <asm/dbdma.h>
 #include <linux/interrupt.h>
-#include <sound/pcm.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
+
+#include <sound/pcm.h>
+
 #include <asm/prom.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+
 #include "i2sbus-interface.h"
-#include "i2sbus-control.h"
 #include "../soundbus.h"
 
 struct i2sbus_control {
-	volatile struct i2s_control_regs __iomem *controlregs;
-	struct resource rsrc;
 	struct list_head list;
+	struct macio_chip *macio;
 };
 
 #define MAX_DBDMA_COMMANDS	32
@@ -45,6 +47,12 @@
 	volatile struct dbdma_regs __iomem *dbdma;
 };
 
+enum {
+	aoa_resource_i2smmio = 0,
+	aoa_resource_txdbdma,
+	aoa_resource_rxdbdma,
+};
+
 struct i2sbus_dev {
 	struct soundbus_dev sound;
 	struct macio_dev *macio;
Index: linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus-control.c
===================================================================
--- linux-irq-work.orig/sound/aoa/soundbus/i2sbus/i2sbus-control.c	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus-control.c	2006-07-07 15:41:40.000000000 +1000
@@ -6,12 +6,16 @@
  * GPL v2, can be found in COPYING.
  */
 
-#include <asm/io.h>
+#include <linux/kernel.h>
 #include <linux/delay.h>
+
+#include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/macio.h>
 #include <asm/pmac_feature.h>
 #include <asm/pmac_pfunc.h>
+#include <asm/keylargo.h>
+
 #include "i2sbus.h"
 
 int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
@@ -22,26 +26,12 @@
 
 	INIT_LIST_HEAD(&(*c)->list);
 
-	if (of_address_to_resource(dev->ofdev.node, 0, &(*c)->rsrc))
-		goto err;
-	/* we really should be using feature calls instead of mapping
-	 * these registers. It's safe for now since no one else is
-	 * touching them... */
-	(*c)->controlregs = ioremap((*c)->rsrc.start,
-				    sizeof(struct i2s_control_regs));
-	if (!(*c)->controlregs)
-		goto err;
-
+	(*c)->macio = dev->bus->chip;
 	return 0;
- err:
-	kfree(*c);
-	*c = NULL;
-	return -ENODEV;
 }
 
 void i2sbus_control_destroy(struct i2sbus_control *c)
 {
-	iounmap(c->controlregs);
 	kfree(c);
 }
 
@@ -93,19 +83,19 @@
 			  struct i2sbus_dev *i2sdev)
 {
 	struct pmf_args args = { .count = 0 };
-	int cc;
+	struct macio_chip *macio = c->macio;
 
 	if (i2sdev->enable)
 		return pmf_call_one(i2sdev->enable, &args);
 
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
 	switch (i2sdev->bus_number) {
 	case 0:
-		cc = in_le32(&c->controlregs->cell_control);
-		out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_0_ENABLE);
+		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
 		break;
 	case 1:
-		cc = in_le32(&c->controlregs->cell_control);
-		out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_1_ENABLE);
+		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
 		break;
 	default:
 		return -ENODEV;
@@ -118,7 +108,7 @@
 			int enable)
 {
 	struct pmf_args args = { .count = 0 };
-	int cc;
+	struct macio_chip *macio = c->macio;
 
 	switch (enable) {
 	case 0:
@@ -133,18 +123,21 @@
 		printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
 		return -ENODEV;
 	}
+
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
 	switch (i2sdev->bus_number) {
 	case 0:
-		cc = in_le32(&c->controlregs->cell_control);
-		cc &= ~CTRL_CLOCK_CELL_0_ENABLE;
-		cc |= enable * CTRL_CLOCK_CELL_0_ENABLE;
-		out_le32(&c->controlregs->cell_control, cc);
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
 		break;
 	case 1:
-		cc = in_le32(&c->controlregs->cell_control);
-		cc &= ~CTRL_CLOCK_CELL_1_ENABLE;
-		cc |= enable * CTRL_CLOCK_CELL_1_ENABLE;
-		out_le32(&c->controlregs->cell_control, cc);
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
 		break;
 	default:
 		return -ENODEV;
@@ -157,7 +150,7 @@
 			 int enable)
 {
 	struct pmf_args args = { .count = 0 };
-	int cc;
+	struct macio_chip *macio = c->macio;
 
 	switch (enable) {
 	case 0:
@@ -172,18 +165,20 @@
 		printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
 		return -ENODEV;
 	}
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
 	switch (i2sdev->bus_number) {
 	case 0:
-		cc = in_le32(&c->controlregs->cell_control);
-		cc &= ~CTRL_CLOCK_CLOCK_0_ENABLE;
-		cc |= enable * CTRL_CLOCK_CLOCK_0_ENABLE;
-		out_le32(&c->controlregs->cell_control, cc);
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
 		break;
 	case 1:
-		cc = in_le32(&c->controlregs->cell_control);
-		cc &= ~CTRL_CLOCK_CLOCK_1_ENABLE;
-		cc |= enable * CTRL_CLOCK_CLOCK_1_ENABLE;
-		out_le32(&c->controlregs->cell_control, cc);
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
 		break;
 	default:
 		return -ENODEV;
Index: linux-irq-work/sound/aoa/soundbus/i2sbus/i2sbus-control.h
===================================================================
--- linux-irq-work.orig/sound/aoa/soundbus/i2sbus/i2sbus-control.h	2006-06-23 13:22:14.000000000 +1000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-/*
- * i2sbus driver -- bus register definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __I2SBUS_CONTROLREGS_H
-#define __I2SBUS_CONTROLREGS_H
-
-/* i2s control registers, at least what we know about them */
-
-#define __PAD(m,n) u8 __pad##m[n]
-#define _PAD(line, n) __PAD(line, n)
-#define PAD(n) _PAD(__LINE__, (n))
-struct i2s_control_regs {
-	PAD(0x38);
-	__le32 fcr0;		/* 0x38 (unknown) */
-	__le32 cell_control;	/* 0x3c (fcr1) */
-	__le32 fcr2;		/* 0x40 (unknown) */
-	__le32 fcr3;		/* 0x44 (fcr3) */
-	__le32 clock_control;	/* 0x48 (unknown) */
-	PAD(4);
-	/* total size: 0x50 bytes */
-}  __attribute__((__packed__));
-
-#define CTRL_CLOCK_CELL_0_ENABLE	(1<<10)
-#define CTRL_CLOCK_CLOCK_0_ENABLE	(1<<12)
-#define CTRL_CLOCK_SWRESET_0		(1<<11)
-#define CTRL_CLOCK_INTF_0_ENABLE	(1<<13)
-
-#define CTRL_CLOCK_CELL_1_ENABLE	(1<<17)
-#define CTRL_CLOCK_CLOCK_1_ENABLE	(1<<18)
-#define CTRL_CLOCK_SWRESET_1		(1<<19)
-#define CTRL_CLOCK_INTF_1_ENABLE	(1<<20)
-
-#endif /* __I2SBUS_CONTROLREGS_H */
Index: linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.c
===================================================================
--- linux-irq-work.orig/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-06-23 13:22:14.000000000 +1000
+++ linux-irq-work/sound/aoa/codecs/snd-aoa-codec-tas.c	2006-07-07 17:49:19.000000000 +1000
@@ -310,6 +310,7 @@
 }
 
 MIXER_CONTROL(pcm1, "PCM1", 0);
+MIXER_CONTROL(pcm2, "PCM2", 1);
 MIXER_CONTROL(monitor, "Monitor", 2);
 
 static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
@@ -507,6 +508,10 @@
 	if (err)
 		goto error;
 
+	err = aoa_snd_ctl_add(snd_ctl_new1(&pcm2_control, tas));
+	if (err)
+		goto error;
+
 	err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
 	if (err)
 		goto error;

^ permalink raw reply

* Re: snd-aoa: g5 tas codec problems
From: Johannes Berg @ 2006-07-07  8:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, alsa-devel
In-Reply-To: <1152258426.9862.44.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 2332 bytes --]

On Fri, 2006-07-07 at 17:47 +1000, Benjamin Herrenschmidt wrote:
> Ok, so now I have it working on the G5 :)

Great :)
Powerbook woke itself an hour ago, no idea why, sorry for confusing you
on irc.

>  - Maybe it's me or maybe it's just too complicated, but I haven't quite
> grasped the whole interaction between the soundbus,i2sbus,fabric and
> codecs... especially initialisation ordering. It would be nice if we
> could spend some time going through that and simplifying :) It leads to
> at least one of the problems

Yeah, well... I sorta know.

>  - The patch fixes a couple of nits related to having the modules
> built-in: soundbus must really be a subsys_initcall() so it's
> initialized before anybody else, and I've put the soundbus/ dir before
> the codecs in the link order because the TAS is unhappy if loaded before
> i2s (see below)

Right.

>  - The TAS is a nasty beast. It needs the i2s clocks enabled or it goes
> bunk... That's the problem with the G5. I've added a clock notifier and
> reset it completely when the clocks come back, that's what fixes the G5
> sound (looks like it loses state somewhat when not clocked). It would be
> nice to streamline/cleanup some of the TAS handling, maybe with register
> shadows like darwin or just with proper state variables to re-consitute
> the whole thing and have a "fast mode" load since we need to do it so
> often

Ahrg

>  - Because of the above, starting to play a sound 1- takes some time to
> init things and 2- clacks (setting the mutes on TAS before losing clocks
> isn't enough, I think the fact that it goes bonk makes it parasite the
> analog outputs). We need to also mute the amps around that. I haven't
> quite figured how to do that from i2sbus though :) Also, we should try
> (if not already the case) to cache our clock/i2s state so that
> subsequent prepare() don't try to change things that are already ok.
> That way we avoid having to blast the codec each time. But right now,
> the important thing is to add mutes. People with external amplifiers
> will really not like those clacs...

Right. The way I did that with the onyx is that I told the GPIOs to mute
all amps from the clock switch callback.

I see you added DRC too, thanks :) I'll take a closer look after
breakfast ;)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Johannes Berg @ 2006-07-07  8:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell
In-Reply-To: <1152250720.9862.32.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 567 bytes --]

On Fri, 2006-07-07 at 15:38 +1000, Benjamin Herrenschmidt wrote:

> There is still an issue... wether to enable softvol or not... With
> snd-aoa, the card name is always the same but wether it has hardware
> volume control or not (Toonie doesn't) is not known... Alsa should have
> ways to add softvol automatically if no master volume control exist.

Hm, good point. I probably need to completely revamp the card handling
and not create a card object before the codecs are registered. That way,
I could influence the naming through the codecs.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: snd-aoa: g5 tas codec problems
From: Benjamin Herrenschmidt @ 2006-07-07  8:12 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list, alsa-devel
In-Reply-To: <1152259414.15068.12.camel@localhost>


> I see you added DRC too, thanks :) I'll take a closer look after
> breakfast ;)

Hehe :) Oh I just added a routine to program it in hardware, not any
control to actually change it.

Ben.

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Benjamin Herrenschmidt @ 2006-07-07  8:13 UTC (permalink / raw)
  To: Johannes Berg; +Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell
In-Reply-To: <1152259477.15068.15.camel@localhost>

On Fri, 2006-07-07 at 10:04 +0200, Johannes Berg wrote:
> On Fri, 2006-07-07 at 15:38 +1000, Benjamin Herrenschmidt wrote:
> 
> > There is still an issue... wether to enable softvol or not... With
> > snd-aoa, the card name is always the same but wether it has hardware
> > volume control or not (Toonie doesn't) is not known... Alsa should have
> > ways to add softvol automatically if no master volume control exist.
> 
> Hm, good point. I probably need to completely revamp the card handling
> and not create a card object before the codecs are registered. That way,
> I could influence the naming through the codecs.

Maybe ... or not... I'd rather not bother. I think Alsa should be able
to create softvol if there is no Master volume...

Ben.

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Johannes Berg @ 2006-07-07  8:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell
In-Reply-To: <1152260005.9862.53.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 442 bytes --]

On Fri, 2006-07-07 at 18:13 +1000, Benjamin Herrenschmidt wrote:

> Maybe ... or not... I'd rather not bother. I think Alsa should be able
> to create softvol if there is no Master volume...

But how long should it wait for the master volume to become available?
Thing is, as far as I understand this, the mixer is dynamic and you can
add and remove things at any time essentially. No one does, but that's
another story.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: G5 troubles booting powerpc-git (July 6)
From: Andrew Morton @ 2006-07-07  8:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1152226587.9862.19.camel@localhost.localdomain>

On Fri, 07 Jul 2006 08:56:27 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> If you look at arch/powerpc/kernel/irq.c from line 479:
> 
> 	/* Check if mapping already exist, if it does, call
> 	 * host->ops->map() to update the flags
> 	 */
> 	virq = irq_find_mapping(host, hwirq);
> 	if (virq != IRQ_NONE) {
> 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
> 		host->ops->map(host, virq, hwirq, flags);
> 		return virq;
> 	}
> 
> What if you comment out the host->ops->map(...) call in there ? Does it
> help ?

No, there's no change in behaviour.

^ permalink raw reply

* Re: G5 troubles booting powerpc-git (July 6)
From: Benjamin Herrenschmidt @ 2006-07-07  8:27 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev
In-Reply-To: <20060707012330.f1dea5ac.akpm@osdl.org>

On Fri, 2006-07-07 at 01:23 -0700, Andrew Morton wrote:
> On Fri, 07 Jul 2006 08:56:27 +1000
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> 
> > If you look at arch/powerpc/kernel/irq.c from line 479:
> > 
> > 	/* Check if mapping already exist, if it does, call
> > 	 * host->ops->map() to update the flags
> > 	 */
> > 	virq = irq_find_mapping(host, hwirq);
> > 	if (virq != IRQ_NONE) {
> > 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
> > 		host->ops->map(host, virq, hwirq, flags);
> > 		return virq;
> > 	}
> > 
> > What if you comment out the host->ops->map(...) call in there ? Does it
> > help ?
> 
> No, there's no change in behaviour.

Doh ! Ok, looks like a different issue. Can you try this patch ? Please,
do _not_ apply it to your tree as, as it is it will break non-powermac.
It's some work I'm doing to clean up a couple of rough edges in my irq
rework and fix a little misdesign.

If it doesn't fix it, then it's indeed a completely different issue that I'll have to track down tomorrow
hopefully.

Index: linux-irq-work/arch/powerpc/kernel/irq.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/kernel/irq.c	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/arch/powerpc/kernel/irq.c	2006-07-07 15:47:23.000000000 +1000
@@ -391,15 +391,14 @@
 			irq_map[i].host = host;
 			smp_wmb();
 
-			/* Clear some flags */
-			get_irq_desc(i)->status
-				&= ~(IRQ_NOREQUEST | IRQ_LEVEL);
+			/* Clear norequest flags */
+			get_irq_desc(i)->status &= ~IRQ_NOREQUEST;
 
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
 			 * explicitely change them
 			 */
-			ops->map(host, i, i, 0);
+			ops->map(host, i, i);
 		}
 		break;
 	case IRQ_HOST_MAP_LINEAR:
@@ -457,13 +456,11 @@
 }
 
 unsigned int irq_create_mapping(struct irq_host *host,
-				irq_hw_number_t hwirq,
-				unsigned int flags)
+				irq_hw_number_t hwirq)
 {
 	unsigned int virq, hint;
 
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx, 0x%x)\n",
-		 host, hwirq, flags);
+	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
 
 	/* Look for default host if nececssary */
 	if (host == NULL)
@@ -482,7 +479,6 @@
 	virq = irq_find_mapping(host, hwirq);
 	if (virq != IRQ_NONE) {
 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
-		host->ops->map(host, virq, hwirq, flags);
 		return virq;
 	}
 
@@ -504,18 +500,18 @@
 	}
 	pr_debug("irq: -> obtained virq %d\n", virq);
 
-	/* Clear some flags */
-	get_irq_desc(virq)->status &= ~(IRQ_NOREQUEST | IRQ_LEVEL);
+	/* Clear IRQ_NOREQUEST flag */
+	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
 
 	/* map it */
-	if (host->ops->map(host, virq, hwirq, flags)) {
+	smp_wmb();
+	irq_map[virq].hwirq = hwirq;
+	smp_mb();
+	if (host->ops->map(host, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
 		irq_free_virt(virq, 1);
 		return NO_IRQ;
 	}
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
 	return virq;
 }
 EXPORT_SYMBOL_GPL(irq_create_mapping);
@@ -525,7 +521,8 @@
 {
 	struct irq_host *host;
 	irq_hw_number_t hwirq;
-	unsigned int flags = IRQ_TYPE_NONE;
+	unsigned int type = IRQ_TYPE_NONE;
+	unsigned int virq;
 
 	if (controller == NULL)
 		host = irq_default_host;
@@ -539,11 +536,20 @@
 		hwirq = intspec[0];
 	else {
 		if (host->ops->xlate(host, controller, intspec, intsize,
-				     &hwirq, &flags))
+				     &hwirq, &type))
 			return NO_IRQ;
 	}
 
-	return irq_create_mapping(host, hwirq, flags);
+	/* Create mapping */
+	virq = irq_create_mapping(host, hwirq);
+	if (virq == NO_IRQ)
+		return virq;
+
+	/* Set type if specified and different than the current one */
+	if (type != IRQ_TYPE_NONE &&
+	    type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK))
+		set_irq_type(virq, type);
+	return virq;
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
Index: linux-irq-work/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/pci.c	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/pci.c	2006-07-07 15:47:23.000000000 +1000
@@ -46,7 +46,6 @@
 static struct pci_controller *u3_agp;
 static struct pci_controller *u4_pcie;
 static struct pci_controller *u3_ht;
-#define has_second_ohare 0
 #else
 static int has_second_ohare;
 #endif /* CONFIG_PPC64 */
@@ -993,6 +992,7 @@
 		/* Read interrupt from the device-tree */
 		pci_read_irq_line(dev);
 
+#ifdef CONFIG_PPC32
 		/* Fixup interrupt for the modem/ethernet combo controller.
 		 * on machines with a second ohare chip.
 		 * The number in the device tree (27) is bogus (correct for
@@ -1002,8 +1002,11 @@
 		 */
 		if (has_second_ohare &&
 		    dev->vendor == PCI_VENDOR_ID_DEC &&
-		    dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS)
-			dev->irq = irq_create_mapping(NULL, 60, 0);
+		    dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+			dev->irq = irq_create_mapping(NULL, 60);
+			set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+		}
+#endif /* CONFIG_PPC32 */
 	}
 }
 
Index: linux-irq-work/arch/powerpc/platforms/powermac/pic.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/platforms/powermac/pic.c	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/arch/powerpc/platforms/powermac/pic.c	2006-07-07 15:47:23.000000000 +1000
@@ -579,9 +579,10 @@
 		flags |= OF_IMAP_OLDWORLD_MAC;
 	if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
 		flags |= OF_IMAP_NO_PHANDLE;
-	of_irq_map_init(flags);
 #endif /* CONFIG_PPC_32 */
 
+	of_irq_map_init(flags);
+
 	/* We first try to detect Apple's new Core99 chipset, since mac-io
 	 * is quite different on those machines and contains an IBM MPIC2.
 	 */
Index: linux-irq-work/arch/powerpc/sysdev/mpic.c
===================================================================
--- linux-irq-work.orig/arch/powerpc/sysdev/mpic.c	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/arch/powerpc/sysdev/mpic.c	2006-07-07 15:47:23.000000000 +1000
@@ -337,6 +337,17 @@
 	}
 }
 
+#else /* CONFIG_MPIC_BROKEN_U3 */
+
+static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
+{
+	return 0;
+}
+
+static void __init mpic_scan_ht_pics(struct mpic *mpic)
+{
+}
+
 #endif /* CONFIG_MPIC_BROKEN_U3 */
 
 
@@ -405,11 +416,9 @@
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
-	unsigned long flags;
 
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
-	spin_lock_irqsave(&mpic_lock, flags);
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
 		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
 		       ~MPIC_VECPRI_MASK);
@@ -420,7 +429,6 @@
 			break;
 		}
 	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
-	spin_unlock_irqrestore(&mpic_lock, flags);
 }
 
 static void mpic_mask_irq(unsigned int irq)
@@ -428,11 +436,9 @@
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
-	unsigned long flags;
 
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
-	spin_lock_irqsave(&mpic_lock, flags);
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
 		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
 		       MPIC_VECPRI_MASK);
@@ -444,7 +450,6 @@
 			break;
 		}
 	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
-	spin_unlock_irqrestore(&mpic_lock, flags);
 }
 
 static void mpic_end_irq(unsigned int irq)
@@ -512,8 +517,7 @@
 		mpic_ht_end_irq(mpic, src);
 	mpic_eoi(mpic);
 }
-
-#endif /* CONFIG_MPIC_BROKEN_U3 */
+#endif /* !CONFIG_MPIC_BROKEN_U3 */
 
 #ifdef CONFIG_SMP
 
@@ -560,47 +564,74 @@
 		       mpic_physmask(cpus_addr(tmp)[0]));	
 }
 
-static unsigned int mpic_flags_to_vecpri(unsigned int flags, int *level)
+static unsigned int mpic_type_to_vecpri(unsigned int type)
 {
-	unsigned int vecpri;
-
 	/* Now convert sense value */
-	switch(flags & IRQ_TYPE_SENSE_MASK) {
+	switch(type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_RISING:
-		vecpri = MPIC_VECPRI_SENSE_EDGE |
-			MPIC_VECPRI_POLARITY_POSITIVE;
-		*level = 0;
-		break;
+		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
 	case IRQ_TYPE_EDGE_FALLING:
-		vecpri = MPIC_VECPRI_SENSE_EDGE |
-			MPIC_VECPRI_POLARITY_NEGATIVE;
-		*level = 0;
-		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
 	case IRQ_TYPE_LEVEL_HIGH:
-		vecpri = MPIC_VECPRI_SENSE_LEVEL |
-			MPIC_VECPRI_POLARITY_POSITIVE;
-		*level = 1;
-		break;
+		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
 	case IRQ_TYPE_LEVEL_LOW:
 	default:
-		vecpri = MPIC_VECPRI_SENSE_LEVEL |
-			MPIC_VECPRI_POLARITY_NEGATIVE;
-		*level = 1;
+		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
 	}
-	return vecpri;
+}
+
+static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+{
+	struct mpic *mpic = mpic_from_irq(virq);
+	unsigned int src = mpic_irq_to_hw(virq);
+	struct irq_desc *desc = get_irq_desc(virq);
+	unsigned int vecpri, vold, vnew;
+
+	pr_debug("mpic: set_irq_type(mpic:@%p,virq:%d,src:%d,type:0x%x)\n",
+		 mpic, virq, src, flow_type);
+
+	if (src >= mpic->irq_count)
+		return -EINVAL;
+
+	if (flow_type == IRQ_TYPE_NONE)
+		if (mpic->senses && src < mpic->senses_count)
+			flow_type = mpic->senses[src];
+	if (flow_type == IRQ_TYPE_NONE)
+		flow_type = IRQ_TYPE_LEVEL_LOW;
+
+	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+	if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+		desc->status |= IRQ_LEVEL;
+
+	if (mpic_is_ht_interrupt(mpic, src))
+		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
+			MPIC_VECPRI_SENSE_EDGE;
+	else
+		vecpri = mpic_type_to_vecpri(flow_type);
+
+	vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+	vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
+	vnew |= vecpri;
+	if (vold != vnew)
+		mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+
+	return 0;
 }
 
 static struct irq_chip mpic_irq_chip = {
-	.mask	= mpic_mask_irq,
-	.unmask	= mpic_unmask_irq,
-	.eoi	= mpic_end_irq,
+	.mask		= mpic_mask_irq,
+	.unmask		= mpic_unmask_irq,
+	.eoi		= mpic_end_irq,
+	.set_type	= mpic_set_irq_type,
 };
 
 #ifdef CONFIG_SMP
 static struct irq_chip mpic_ipi_chip = {
-	.mask	= mpic_mask_ipi,
-	.unmask	= mpic_unmask_ipi,
-	.eoi	= mpic_end_ipi,
+	.mask		= mpic_mask_ipi,
+	.unmask		= mpic_unmask_ipi,
+	.eoi		= mpic_end_ipi,
 };
 #endif /* CONFIG_SMP */
 
@@ -611,6 +642,7 @@
 	.mask		= mpic_mask_irq,
 	.unmask		= mpic_unmask_ht_irq,
 	.eoi		= mpic_end_ht_irq,
+	.set_type	= mpic_set_irq_type,
 };
 #endif /* CONFIG_MPIC_BROKEN_U3 */
 
@@ -624,18 +656,12 @@
 }
 
 static int mpic_host_map(struct irq_host *h, unsigned int virq,
-			 irq_hw_number_t hw, unsigned int flags)
+			 irq_hw_number_t hw)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
-	struct irq_chip *chip;
 	struct mpic *mpic = h->host_data;
-	u32 v, vecpri = MPIC_VECPRI_SENSE_LEVEL |
-		MPIC_VECPRI_POLARITY_NEGATIVE;
-	int level;
-	unsigned long iflags;
+	struct irq_chip *chip;
 
-	pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n",
-		 virq, hw, flags);
+	pr_debug("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
 
 	if (hw == MPIC_VEC_SPURRIOUS)
 		return -EINVAL;
@@ -654,44 +680,23 @@
 	if (hw >= mpic->irq_count)
 		return -EINVAL;
 
-	/* If no sense provided, check default sense array */
-	if (((flags & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE) &&
-	    mpic->senses && hw < mpic->senses_count)
-		flags |= mpic->senses[hw];
-
-	vecpri = mpic_flags_to_vecpri(flags, &level);
-	if (level)
-		desc->status |= IRQ_LEVEL;
+	/* Default chip */
 	chip = &mpic->hc_irq;
 
 #ifdef CONFIG_MPIC_BROKEN_U3
 	/* Check for HT interrupts, override vecpri */
-	if (mpic_is_ht_interrupt(mpic, hw)) {
-		vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
-			    MPIC_VECPRI_POLARITY_MASK);
-		vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
+	if (mpic_is_ht_interrupt(mpic, hw))
 		chip = &mpic->hc_ht_irq;
-	}
-#endif
-
-	/* Reconfigure irq. We must preserve the mask bit as we can be called
-	 * while the interrupt is still active (This may change in the future
-	 * but for now, it is the case).
-	 */
-	spin_lock_irqsave(&mpic_lock, iflags);
-	v = mpic_irq_read(hw, MPIC_IRQ_VECTOR_PRI);
-	vecpri = (v &
-		~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK)) |
-		vecpri;
-	if (vecpri != v)
-		mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri);
-	spin_unlock_irqrestore(&mpic_lock, iflags);
+#endif /* CONFIG_MPIC_BROKEN_U3 */
 
-	pr_debug("mpic: mapping as IRQ, vecpri = 0x%08x (was 0x%08x)\n",
-		 vecpri, v);
+	pr_debug("mpic: mapping to irq chip @%p\n", chip);
 
 	set_irq_chip_data(virq, mpic);
 	set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
+
+	/* Set default irq type */
+	set_irq_type(virq, IRQ_TYPE_NONE);
+
 	return 0;
 }
 
@@ -906,41 +911,16 @@
 	if (mpic->irq_count == 0)
 		mpic->irq_count = mpic->num_sources;
 
-#ifdef CONFIG_MPIC_BROKEN_U3
 	/* Do the HT PIC fixups on U3 broken mpic */
 	DBG("MPIC flags: %x\n", mpic->flags);
 	if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
  		mpic_scan_ht_pics(mpic);
-#endif /* CONFIG_MPIC_BROKEN_U3 */
 
 	for (i = 0; i < mpic->num_sources; i++) {
 		/* start with vector = source number, and masked */
-		u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT);
-		int level = 1;
+		u32 vecpri = MPIC_VECPRI_MASK | i |
+			(8 << MPIC_VECPRI_PRIORITY_SHIFT);
 		
-		/* do senses munging */
-		if (mpic->senses && i < mpic->senses_count)
-			vecpri |= mpic_flags_to_vecpri(mpic->senses[i],
-						       &level);
-		else
-			vecpri |= MPIC_VECPRI_SENSE_LEVEL;
-
-		/* deal with broken U3 */
-		if (mpic->flags & MPIC_BROKEN_U3) {
-#ifdef CONFIG_MPIC_BROKEN_U3
-			if (mpic_is_ht_interrupt(mpic, i)) {
-				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
-					    MPIC_VECPRI_POLARITY_MASK);
-				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
-			}
-#else
-			printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n");
-#endif
-		}
-
-		DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri,
-		    (level != 0));
-
 		/* init hw */
 		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
 		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
@@ -1154,7 +1134,7 @@
 
 	for (i = 0; i < 4; i++) {
 		unsigned int vipi = irq_create_mapping(mpic->irqhost,
-						       MPIC_VEC_IPI_0 + i, 0);
+						       MPIC_VEC_IPI_0 + i);
 		if (vipi == NO_IRQ) {
 			printk(KERN_ERR "Failed to map IPI %d\n", i);
 			break;
Index: linux-irq-work/drivers/macintosh/macio_asic.c
===================================================================
--- linux-irq-work.orig/drivers/macintosh/macio_asic.c	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/drivers/macintosh/macio_asic.c	2006-07-07 15:47:23.000000000 +1000
@@ -330,7 +330,7 @@
 {
 	unsigned int irq;
 
-	irq = irq_create_mapping(NULL, line, 0);
+	irq = irq_create_mapping(NULL, line);
 	if (irq != NO_IRQ) {
 		dev->interrupt[index].start = irq;
 		dev->interrupt[index].flags = IORESOURCE_IRQ;
Index: linux-irq-work/include/asm-powerpc/irq.h
===================================================================
--- linux-irq-work.orig/include/asm-powerpc/irq.h	2006-07-07 15:40:27.000000000 +1000
+++ linux-irq-work/include/asm-powerpc/irq.h	2006-07-07 15:47:23.000000000 +1000
@@ -83,25 +83,24 @@
 	int (*match)(struct irq_host *h, struct device_node *node);
 
 	/* Create or update a mapping between a virtual irq number and a hw
-	 * irq number. This can be called several times for the same mapping
-	 * but with different flags, though unmap shall always be called
-	 * before the virq->hw mapping is changed.
+	 * irq number. This is called only once for a given mapping.
 	 */
-	int (*map)(struct irq_host *h, unsigned int virq,
-		   irq_hw_number_t hw, unsigned int flags);
+	int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
 
 	/* Dispose of such a mapping */
 	void (*unmap)(struct irq_host *h, unsigned int virq);
 
 	/* Translate device-tree interrupt specifier from raw format coming
 	 * from the firmware to a irq_hw_number_t (interrupt line number) and
-	 * trigger flags that can be passed to irq_create_mapping().
-	 * If no translation is provided, raw format is assumed to be one cell
-	 * for interrupt line and default sense.
+	 * type (sense) that can be passed to set_irq_type(). In the absence
+	 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
+	 * will return the hw number in the first cell and IRQ_TYPE_NONE for
+	 * the type (which amount to keeping whatever default value the
+	 * interrupt controller has for that line)
 	 */
 	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
 		     u32 *intspec, unsigned int intsize,
-		     irq_hw_number_t *out_hwirq, unsigned int *out_flags);
+		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
 };
 
 struct irq_host {
@@ -193,25 +192,14 @@
  * irq_create_mapping - Map a hardware interrupt into linux virq space
  * @host: host owning this hardware interrupt or NULL for default host
  * @hwirq: hardware irq number in that host space
- * @flags: flags passed to the controller. contains the trigger type among
- *         others. Use IRQ_TYPE_* defined in include/linux/irq.h
  *
  * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number. The flags can be used to provide sense information to the
- * controller (typically extracted from the device-tree). If no information
- * is passed, the controller defaults will apply (for example, xics can only
- * do edge so flags are irrelevant for some pseries specific irqs).
- *
- * The device-tree generally contains the trigger info in an encoding that is
- * specific to a given type of controller. In that case, you can directly use
- * host->ops->trigger_xlate() to translate that.
- *
- * It is recommended that new PICs that don't have existing OF bindings chose
- * to use a representation of triggers identical to linux.
+ * virq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
  */
 extern unsigned int irq_create_mapping(struct irq_host *host,
-				       irq_hw_number_t hwirq,
-				       unsigned int flags);
+				       irq_hw_number_t hwirq);
 
 
 /***
@@ -295,7 +283,7 @@
  *
  * This function is identical to irq_create_mapping except that it takes
  * as input informations straight from the device-tree (typically the results
- * of the of_irq_map_*() functions
+ * of the of_irq_map_*() functions.
  */
 extern unsigned int irq_create_of_mapping(struct device_node *controller,
 					  u32 *intspec, unsigned int intsize);

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Benjamin Herrenschmidt @ 2006-07-07  8:27 UTC (permalink / raw)
  To: Johannes Berg; +Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell
In-Reply-To: <1152260564.15068.20.camel@localhost>

On Fri, 2006-07-07 at 10:22 +0200, Johannes Berg wrote:
> On Fri, 2006-07-07 at 18:13 +1000, Benjamin Herrenschmidt wrote:
> 
> > Maybe ... or not... I'd rather not bother. I think Alsa should be able
> > to create softvol if there is no Master volume...
> 
> But how long should it wait for the master volume to become available?
> Thing is, as far as I understand this, the mixer is dynamic and you can
> add and remove things at any time essentially. No one does, but that's
> another story.

Well, when the master volume shows up, softvol can "unplug" itself :)

Ben.

^ permalink raw reply

* Re: [Alsa-devel] [RFC 01/12] snd-powermac: no longer handle anything with a layout-id property
From: Johannes Berg @ 2006-07-07  8:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: alsa-devel, Takashi Iwai, netstar, linuxppc-dev, Lee Revell
In-Reply-To: <1152260861.9862.59.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 336 bytes --]

On Fri, 2006-07-07 at 18:27 +1000, Benjamin Herrenschmidt wrote:

> Well, when the master volume shows up, softvol can "unplug" itself :)

Hmm, not a bad idea, that way there's always a master volume. And when
some cards have an unusable master volume then softvol could be forced
to superimpose via the config file.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: snd-aoa: g5 tas codec problems
From: Johannes Berg @ 2006-07-07  8:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, alsa-devel
In-Reply-To: <1152258426.9862.44.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 331 bytes --]

On Fri, 2006-07-07 at 17:47 +1000, Benjamin Herrenschmidt wrote:
> Also, we should try
> (if not already the case) to cache our clock/i2s state so that
> subsequent prepare() don't try to change things that are already ok. 

I do that, the function reads the dws and sfr registers and exits early
if they match.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: G5 troubles booting powerpc-git (July 6)
From: Andrew Morton @ 2006-07-07  8:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1152260824.9862.57.camel@localhost.localdomain>

On Fri, 07 Jul 2006 18:27:04 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Fri, 2006-07-07 at 01:23 -0700, Andrew Morton wrote:
> > On Fri, 07 Jul 2006 08:56:27 +1000
> > Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> > 
> > > If you look at arch/powerpc/kernel/irq.c from line 479:
> > > 
> > > 	/* Check if mapping already exist, if it does, call
> > > 	 * host->ops->map() to update the flags
> > > 	 */
> > > 	virq = irq_find_mapping(host, hwirq);
> > > 	if (virq != IRQ_NONE) {
> > > 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
> > > 		host->ops->map(host, virq, hwirq, flags);
> > > 		return virq;
> > > 	}
> > > 
> > > What if you comment out the host->ops->map(...) call in there ? Does it
> > > help ?
> > 
> > No, there's no change in behaviour.
> 
> Doh ! Ok, looks like a different issue. Can you try this patch ? Please,
> do _not_ apply it to your tree as, as it is it will break non-powermac.
> It's some work I'm doing to clean up a couple of rough edges in my irq
> rework and fix a little misdesign.
> 
> If it doesn't fix it, then it's indeed a completely different issue that I'll have to track down tomorrow
> hopefully.

Needs this to compile:

diff -puN arch/powerpc/platforms/pseries/ras.c~a-fix arch/powerpc/platforms/pseries/ras.c
--- a/arch/powerpc/platforms/pseries/ras.c~a-fix
+++ a/arch/powerpc/platforms/pseries/ras.c
@@ -93,8 +93,7 @@ static void request_ras_irqs(struct devi
 		for (i = 0; i < opicplen; i++) {
 			if (count > 15)
 				break;
-			virqs[count] = irq_create_mapping(NULL, *(opicprop++),
-							 IRQ_TYPE_NONE);
+			virqs[count] = irq_create_mapping(NULL, *(opicprop++));
 			if (virqs[count] == NO_IRQ)
 				printk(KERN_ERR "Unable to allocate interrupt "
 				       "number for %s\n", np->full_name);
diff -puN arch/powerpc/platforms/pseries/xics.c~a-fix arch/powerpc/platforms/pseries/xics.c
--- a/arch/powerpc/platforms/pseries/xics.c~a-fix
+++ a/arch/powerpc/platforms/pseries/xics.c
@@ -757,7 +757,7 @@ void xics_request_IPIs(void)
 {
 	unsigned int ipi;
 
-	ipi = irq_create_mapping(xics_host, XICS_IPI, 0);
+	ipi = irq_create_mapping(xics_host, XICS_IPI);
 	BUG_ON(ipi == NO_IRQ);
 
 	/*
diff -puN drivers/char/hvsi.c~a-fix drivers/char/hvsi.c
--- a/drivers/char/hvsi.c~a-fix
+++ a/drivers/char/hvsi.c
@@ -1299,7 +1299,7 @@ static int __init hvsi_console_init(void
 		hp->inbuf_end = hp->inbuf;
 		hp->state = HVSI_CLOSED;
 		hp->vtermno = *vtermno;
-		hp->virq = irq_create_mapping(NULL, irq[0], 0);
+		hp->virq = irq_create_mapping(NULL, irq[0]);
 		if (hp->virq == NO_IRQ) {
 			printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
 				__FUNCTION__, irq[0]);
_

But it still doesn't help.


These:

arch/powerpc/sysdev/i8259.c:222: warning: initialization from incompatible pointer type
arch/powerpc/platforms/pseries/xics.c:555: warning: initialization from incompatible pointer type
arch/powerpc/platforms/pseries/xics.c:561: warning: initialization from incompatible pointer type

look like super-serious box-killers.  Hope I'm not using either of those.

^ permalink raw reply

* Re: snd-aoa: g5 tas codec problems
From: Benjamin Herrenschmidt @ 2006-07-07  8:56 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list, alsa-devel
In-Reply-To: <1152262148.15068.30.camel@localhost>

On Fri, 2006-07-07 at 10:49 +0200, Johannes Berg wrote:
> On Fri, 2006-07-07 at 17:47 +1000, Benjamin Herrenschmidt wrote:
> > Also, we should try
> > (if not already the case) to cache our clock/i2s state so that
> > subsequent prepare() don't try to change things that are already ok. 
> 
> I do that, the function reads the dws and sfr registers and exits early
> if they match.

Ok. Be careful that I've removed the initial init of TAS thinking we
always get to clock restart to do it in prepare()... might need to be
put back.

Ben.

^ permalink raw reply

* RE: [PATCH 1/3] Freescale QE UCC gigabit ethernet driver
From: Li Yang-r58472 @ 2006-07-07  8:59 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Andrew Morton, netdev, jgarzik, linuxppc-dev
In-Reply-To: <FA983307-6A01-4FCB-A15A-ACC0E7B068A9@kernel.crashing.org>

> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> Sent: Thursday, July 06, 2006 9:45 PM
> To: Li Yang-r58472
> Cc: Andrew Morton; jgarzik@pobox.com; netdev@vger.kernel.org;
> linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 1/3] Freescale QE UCC gigabit ethernet driver
>=20
> Nack.  Here are some high level things that should be addressed:
> * There is a ton of debug code that should probably be stripped out,
> such as dump_regs, etc..

The reason I left these debug code in is that, QE is very flexible.
User probably needs to fine tune parameters for their own application.
It will be good to give them some clue doing that.  It's fine to remove
them, if you do think they are too verbose.
> * The phy support should use the phylib instead

I'll do this when I do get some time. ;)
> * convert from being a platform_device to of_device

I'm not up against moving to use of_device.  But why are we putting
extra effort in closing the door to backward compatibility with ppc
arch, and doesn't provide any new feature. ;)
>=20
> - kumar
>=20

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox