All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pmac mixer update from shadow register on resume and switching DRC on headphone plug
@ 2004-07-30 14:56 Rene Rebe
  2004-08-02 10:55 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Rene Rebe @ 2004-07-30 14:56 UTC (permalink / raw)
  To: alsa-devel

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

Hi all,

the attached patch improved the pmac driver by implementing updating the 
mixer from the shadow register after a resume or headphone interrupt, as 
well as automatically selecting DRC on headphone plug.

For normal line-out one does not want the DRC, but it should 
automatically be reenabled after the headphone is unplugged: Otherwise 
the power to the internal speakers is high enought to destroy them 
(happend once to my iBook - when it still had warrenty ... ;-)

I needed a work-queue / task-queue since it can not be done in the 
interrupt context - this is done in the way the OSS driver does it, too. 
I hope this is acceptable.

Have fun,
  René Rebe

[-- Attachment #2: alsa-pmac.patch --]
[-- Type: text/plain, Size: 4115 bytes --]

--- ppc/tumbler.c~	2004-06-16 07:18:52.000000000 +0200
+++ ppc/tumbler.c	2004-08-01 13:46:48.000000000 +0200
@@ -16,6 +16,11 @@
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   Rene Rebe <rene.rebe@gmx.net>:
+ *     * update from shadow registers on wakeup and headphone plug
+ *     * automatically toggle DRC on headphone plug
+ *	
  */
 
 
@@ -759,12 +764,6 @@
 	DEFINE_MONO("Tone Control - Treble", treble),
 	DEFINE_MONO("PCM Playback Volume", pcm),
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	  .name = "DRC Switch",
-	  .info = snd_pmac_boolean_mono_info,
-	  .get = tumbler_get_drc_switch,
-	  .put = tumbler_put_drc_switch
-	},
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "DRC Range",
 	  .info = tumbler_info_drc_value,
 	  .get = tumbler_get_drc_value,
@@ -791,12 +790,6 @@
 	DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
 	DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	  .name = "DRC Switch",
-	  .info = snd_pmac_boolean_mono_info,
-	  .get = tumbler_get_drc_switch,
-	  .put = tumbler_put_drc_switch
-	},
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "DRC Range",
 	  .info = tumbler_info_drc_value,
 	  .get = tumbler_get_drc_value,
@@ -826,6 +819,14 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_AMP,
 };
+static snd_kcontrol_new_t tumbler_drc_sw __initdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "DRC Switch",
+	.info = snd_pmac_boolean_mono_info,
+	.get = tumbler_get_drc_switch,
+	.put = tumbler_put_drc_switch
+};
+
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
 /*
@@ -847,6 +848,33 @@
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static struct tq_struct device_change;
+#else
+static struct work_struct device_change;
+#endif
+
+static void
+device_change_handler(void *self)
+{
+	pmac_t *chip = (pmac_t*) self;
+	pmac_tumbler_t *mix;
+
+	if (!chip)
+		return;
+
+	mix = chip->mixer_data;
+
+	/* first set the DRC so the speaker do not explode */
+	if (chip->model == PMAC_TUMBLER)
+		tumbler_set_drc(mix);
+	else
+		snapper_set_drc(mix);
+
+	/* reset the master volume so the correct amplification is applied */
+	tumbler_set_master_volume(mix);
+}
+
 static void tumbler_update_automute(pmac_t *chip, int do_notify)
 {
 	if (chip->auto_mute) {
@@ -856,14 +889,29 @@
 			/* mute speaker */
 			check_mute(chip, &mix->amp_mute, 1, do_notify, chip->speaker_sw_ctl);
 			check_mute(chip, &mix->hp_mute, 0, do_notify, chip->master_sw_ctl);
+			mix->drc_enable = 0;
+
 		} else {
 			/* unmute speaker */
 			check_mute(chip, &mix->amp_mute, 0, do_notify, chip->speaker_sw_ctl);
 			check_mute(chip, &mix->hp_mute, 1, do_notify, chip->master_sw_ctl);
+			mix->drc_enable = 1;
 		}
-		if (do_notify)
+		if (do_notify) {
 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 				       &chip->hp_detect_ctl->id);
+			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			               &chip->drc_sw_ctl->id);
+		}
+
+		/* finally we need to schedule an update of the mixer values
+		   (master and DRC are enough for now) -ReneR */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		schedule_task(&device_change);
+#else
+		schedule_work(&device_change);
+#endif
+
 	}
 }
 #endif /* PMAC_SUPPORT_AUTOMUTE */
@@ -1114,11 +1163,21 @@
 	chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
 	if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
 		return err;
+	chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);
+	if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
+		return err;
+
 
 #ifdef CONFIG_PMAC_PBOOK
 	chip->resume = tumbler_resume;
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	INIT_TQUEUE(&device_change, device_change_handler, (void *)chip);
+#else
+	INIT_WORK(&device_change, device_change_handler, (void *)chip);
+#endif
+
 #ifdef PMAC_SUPPORT_AUTOMUTE
 	if (mix->headphone_irq >=0 && (err = snd_pmac_add_automute(chip)) < 0)
 		return err;


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-08-02 10:55 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-30 14:56 [PATCH] pmac mixer update from shadow register on resume and switching DRC on headphone plug Rene Rebe
2004-08-02 10:55 ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.