• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Fn-Tasten von Asus A6V00VA unter SuSE Linux 10.0

chrizzo

Member
Yo.

Meine Fn-Tasten funkionieren nicht, weil die leider Gottes software- und nicht hardwarebasiert laufen.

Wäre schon cool, per Tastendruck mal Helligkeit zu regulieren und Lautstärke zu regeln.

Hilfe? :D
 
Sollte kein Problem sein, da die dann ACPI-Events generieren. Musst nur ein passendes Skript in /usr/lib/powersave/scripts/ platzieren, das die entsprechenden Aktionen tätigt und das dann im sysconfig-Editor unter EVENTS_OTHER eintragen.
Du benötigst dazu
a) Die Key-Codes (erhältst du, indem du die Taste drückst und dann die letzte Zeile der Ausgabe von dmesg analysierst)
b) Kenntnis des umzusetzenden Befehls
c) Kernel-Modul asus_acpi
d) eine Skript-Vorlage für den Handler (für ein M6 hat Manfred Tremmel einmal ein solches Skript geschrieben, das du noch anpassen müsstest: http://www.iiv.de/schwinde/buerger/tremmel/suse_m6842nw.html)

Greetz, HB
 
OP
chrizzo

chrizzo

Member
Ich bin ein relativ YaST-Verwöhnter Linux-N00b, kannst du mir das bitte etwas detaillierter erklären oder ein (SuSE-kombatibles) Tutorial verlinken? Das wäre sehr hilfreich, ich hab immer noch keine Ahnung, wonach ich suchen soll...
 
OP
chrizzo

chrizzo

Member
Ja, und wenn man sich dann wundert, dass die Dateien, die man modifizieren soll, nicht existieren, googelt man ein bisschen und erfährt vom Script-Autor auf einer anderen Page, dass sein Trick unter SuSE 10.0 nicht funktioniert.

Das zum Thema. :D

Weitere Ideen? :p
 
Nur so viel: Ich setze openSuSE 10.0 ein, und das von Manfred beschriebene Vorgehen funktioniert hier.
Wo hast du denn gelesen, dass das nicht mehr gehe?

Greetz, HB
 
OP
chrizzo

chrizzo

Member
Ich habe heute so viel gegoogelt, ich habe den Link verbaselt.

Der Typ postete irgendwo etwa (nicht wörtlich) "...aber ACPI kann man unter SuSe 10 eh vergessen..."

Ich hätte es ja trotzdem versucht, aber in den Links wird auf Dateien verwiesen, die bei mir garnicht existieren, irgendwelches Zeug das "powersave" etc. heißt:

/etc/sysconfig/powermanagement
/etc/sysconfig/powersave/common

Ich werde mich damit die nächsten Tage noch mal beschäftigen, könntest du mir in der Zeit mal erklären, wo ich die benötigten Files auf meiner Platte finde ("Vollinstalltion" von einer gesaugten SuSE 10.0 EvalDVD), welche ich überhaupt brauche und woher ich (wenn nötig) irgendwelche Programme und Packages kriege?

Ich habe gerade 4 Stunden lang versucht, amaroK Töne zu entlocken (hat geklappt!), für heute reicht es. :D

Wäre auf jeden Fall sehr cool, wenn du mir da helfen könntest, am besten so weit, dass ich die Tasten selber belegen kann, ich möchte die eh mit amaroK (DCOP-Tabelle für amaroK hab ich schon! :D) und kMix, Thunderbird und Firefox verwenden, also ganz anders als der Autor des angebotenen Scripts.

Ich weiß seit heute, was Packman ist. :D

Hmm... ja, also, Danke für deine Hilfe bis hierhin und vielleicht auch im vorraus für zukünftige Ratschläge.

Ich geh ins Bett! :D
 
OP
chrizzo

chrizzo

Member
Also: Die von dir verlinkte Anleitung hat mir nicht weitergeholfen, bzw. nur bedingt. Das asus-acpi Modul wird bei mir geladen, ich kann mit dem beschriebenen Kommando

echo 1 > /proc/acpi/asus/mled

die LED ein- und ausschalten, kein Problem.

Allerdings habe ich nicht gerafft, wo ich dieses Script hinspeichern soll, in welche Datei ich den Verweis aufnehmen soll (die in der Anleitung beschriebene kann ich nicht finden).

Ich habe darum ein bisschen gegoogelt und nach einem anderen Lösungsvorschlag versucht, die Tasten zu belegen. (Hier.) Hat natürlich nicht funktioniert, bzw. nur bedingt. Die Sondertasten (Play, Stop, Internet, E-Mail etc.) funktionieren gar nicht, die FN-Tasten nur mit Verzögerung. Wenn ich das neunte Mal auf eine Taste drücke, wird die Anweisung ausgeführt, die ich beim ersten Tastendruck erzeugt habe. Wenn ich das neunte Mal auf "Display Aus" drücke, geht der Display aus, wenn ich dann neun Mal auf "Ton aus" drücke, geht 8 mal der Diplay an und aus, eh dann der Ton ausgeht. Nur so als Beispiel. Ich glaube, der Ton geht nie aus. Aber egal. Ich denke, du verstehst, was ich meine.
 
OK, dann braucht dein Kernel einen sog. ec_burst-Patch. Du musst dir einen eigenen Kernel kompilieren, dessen Sourcen du vorher mittels
Code:
patch -p0 < ec_burst.patch
gepatcht hast. Den Befehl führst du in /usr/src/linux/drivers/acpi/ als root aus, wobei du ec_burst.patch durch den Pfad und Namen der unten stehenden Datei ersetzt.

Greetz, HB

Code:
--- ec.c.0	2005-08-10 10:20:15.000000000 +0800
+++ ec.c	2005-08-10 11:25:59.000000000 +0800
@@ -234,18 +234,29 @@
 	ec->burst.expect_event = event;
 	smp_mb();
 
-	result = wait_event_interruptible_timeout(ec->burst.wait,
+	switch (event) {
+	case ACPI_EC_EVENT_OBF:
+		if (acpi_ec_read_status(ec) & event) {
+			ec->burst.expect_event = 0;
+			return_VALUE(0);
+		}
+		break;
+
+	case ACPI_EC_EVENT_IBE:
+		if (~acpi_ec_read_status(ec) & event) {
+			ec->burst.expect_event = 0;
+			return_VALUE(0);
+		}
+		break;
+	}
+
+	result = wait_event_timeout(ec->burst.wait,
 					!ec->burst.expect_event,
 					msecs_to_jiffies(ACPI_EC_DELAY));
 	
 	ec->burst.expect_event = 0;
 	smp_mb();
 
-	if (result < 0){
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result  = %d ", result));
-		return_VALUE(result);
-	}
-
 	/*
 	 * Verify that the event in question has actually happened by
 	 * querying EC status. Do the check even if operation timed-out
@@ -280,14 +291,14 @@
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL &&
 		!(status & ACPI_EC_FLAG_BURST)){
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+		if(status)
+			goto end;
 		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-		if (status){
-			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		if (status)
 			return_VALUE(-EINVAL);
-		}
 		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 		if(tmp != 0x90 ) {/* Burst ACK byte*/
 			return_VALUE(-EINVAL);
 		}
@@ -295,31 +306,19 @@
 
 	atomic_set(&ec->burst.leaving_burst , 0);
 	return_VALUE(0);
+end:
+	printk("Error in acpi_ec_wait\n");
+	return_VALUE(-1);
 }
 
 static int
 acpi_ec_leave_burst_mode (
 	union acpi_ec		*ec)
 {
-	int			status =0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
 
-	atomic_set(&ec->burst.leaving_burst , 1);
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL &&
-		(status & ACPI_EC_FLAG_BURST)){
-		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
-		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
-		if (status){
-			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
-			return_VALUE(-EINVAL);
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		status = acpi_ec_read_status(ec);
-	}
-
+	atomic_set(&ec->burst.leaving_burst, 1);
 	return_VALUE(0);
 }
 
@@ -461,7 +460,6 @@
 	if (!ec || !data)
 		return_VALUE(-EINVAL);
 
-retry:
 	*data = 0;
 
 	if (ec->common.global_lock) {
@@ -473,26 +471,25 @@
 	WARN_ON(in_interrupt());
 	down(&ec->burst.sem);
 
-	if(acpi_ec_enter_burst_mode(ec))
+	acpi_ec_enter_burst_mode(ec);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status) {
+		printk("read EC, IB not empty\n");
 		goto end;
-
+	}
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 	if (status) {
-		goto end;
+		printk("read EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		printk("read EC, OB not full\n");
 		goto end;
 	}
-
 	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
 	
@@ -503,15 +500,6 @@
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->burst.pending_gpe)){
-			msleep(1);	
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto retry;
-	}
-
 	return_VALUE(status);
 }
 
@@ -524,13 +512,12 @@
 {
 	int			status = 0;
 	u32			glk;
-	u32			tmp;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_write");
 
 	if (!ec)
 		return_VALUE(-EINVAL);
-retry:
+
 	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
@@ -540,61 +527,35 @@
 	WARN_ON(in_interrupt());
 	down(&ec->burst.sem);
 
-	if(acpi_ec_enter_burst_mode(ec))
-		goto end;
+	acpi_ec_enter_burst_mode(ec);
 
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL &&
-		!(status & ACPI_EC_FLAG_BURST)){
-		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
-		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-		if (status)
-			goto end;
-		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
-		if(tmp != 0x90 ) /* Burst ACK byte*/
-			goto end;
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if ( status) {
+		printk("write EC, IB not empty\n");
 	}
-	/*Now we are in burst mode*/
-
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-	if (status){
-		goto end;
+	if (status) {
+		printk ("write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto end;
+		printk("write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
-	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-	if (status)
-		goto end;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
 		data, address));
 
-end:
 	acpi_ec_leave_burst_mode(ec);
 	up(&ec->burst.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->burst.pending_gpe)){
-			msleep(1);	
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto retry;
-	}
-
 	return_VALUE(status);
 }
 
@@ -719,8 +680,12 @@
 	}
 
 	down(&ec->burst.sem);
-	if(acpi_ec_enter_burst_mode(ec))
+
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status) {
+		printk("query EC, IB not empty\n");
 		goto end;
+	}
 	/*
 	 * Query the EC to find out which _Qxx method we need to evaluate.
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
@@ -729,27 +694,20 @@
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		printk("query EC, OB not full\n");
 		goto end;
 	}
 
 	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 	if (!*data)
 		status = -ENODATA;
 
 end:
-	acpi_ec_leave_burst_mode(ec);
 	up(&ec->burst.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		status = -ENODATA;
-	}
 	return_VALUE(status);
 }
 
@@ -885,31 +843,21 @@
 	if (!ec)
 		return ACPI_INTERRUPT_NOT_HANDLED;
 
-	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
-
+	acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
 	value = acpi_ec_read_status(ec);
 
-	if((value & ACPI_EC_FLAG_IBF) &&
-		!(value & ACPI_EC_FLAG_BURST) &&
-			(atomic_read(&ec->burst.leaving_burst) == 0)) { 
-	/*
-	 * the embedded controller disables 
-	 * burst mode for any reason other 
-	 * than the burst disable command
-	 * to process critical event.
-	 */
-		atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
-					and retry */
+	switch ( ec->burst.expect_event) {
+	case ACPI_EC_EVENT_OBF:
+		if (!(value & ACPI_EC_FLAG_OBF))
+			break;
+	case ACPI_EC_EVENT_IBE:
+		if ((value & ACPI_EC_FLAG_IBF))
+			break;
+		ec->burst.expect_event = 0;
 		wake_up(&ec->burst.wait);
-	}else {
-		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
-				(value & ACPI_EC_FLAG_OBF)) ||
-	    			(ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
-				!(value & ACPI_EC_FLAG_IBF))) {
-			ec->burst.expect_event = 0;
-			wake_up(&ec->burst.wait);
-			return ACPI_INTERRUPT_HANDLED;
-		}
+		return ACPI_INTERRUPT_HANDLED;
+	default:
+		break;
 	}
 
 	if (value & ACPI_EC_FLAG_SCI){
@@ -1242,6 +1190,7 @@
 	if (result)
 		goto end;
 
+	printk("burst-mode-ec-10-Aug\n");
 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
 		acpi_device_name(device), acpi_device_bid(device),
 		(u32) ec->common.gpe_bit);
 
OP
chrizzo

chrizzo

Member
Angenommen ich hätte noch nie alleine einen Kernel kompiliert und würde nicht wissen, wie ich das mache... wie würdest du mir dann erklären, was genau ich tun muss? :D
 

Oli-nux

Hacker
chrizzo schrieb:
HansBauer schrieb:
Das würde ich nicht tun, das steht schon an jeder Ecke hier im Forum. Eine gute Anlaufstelle ist auch http://www.thomashertweck.de/kernel26.html.

Greetz, HB

Toter Link.
Dann stell dich nicht so an und geh auf die Hauptseite und dort auf Documents.
Um es abzukürzen hier:
http://www.thomashertweck.de/docu.html
 
OP
chrizzo

chrizzo

Member
Aaaaaaaaaah shit.

Irgendwie muss ich für euch schon aussehen wie der letzte Honk, weil ich nix auf die Reihe bekomme. :D Ich hab den Punkt nicht gesehen, mein Fehler - wie immer. Allerdings scheint das kompilieren eines Kernels eine seeeeeeeeeeeeeeeeeeeeeeeeeeeeeeehr schwierige Angelegenheit zu sein. Ich glaube, das traue ich mir im Moment noch nicht zu. Ich bin auf den Laptop angewiesen wg. des Studiums, ich kann mir keinen Systemausfall leisten. Ich probiere das eventuell in den Semesterferien mal. :D
 
Oben