summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_beep.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-05-19 12:50:04 +0200
committerTakashi Iwai <tiwai@suse.de>2009-05-19 12:54:55 +0200
commitfa7979663190240b838ab8c8bad7f59e618bf77c (patch)
treee008dbd603562a54300ed8d189bd9bb59b5aa697 /sound/pci/hda/hda_beep.c
parent4abc1cc2f9fe4b6bb3acc1d78e2c15af47b8133d (diff)
downloadlinux-fa7979663190240b838ab8c8bad7f59e618bf77c.tar.bz2
ALSA: hda - Fix digital beep tone calculation
The digital beep tone is calculated in two different ways depending on the codec chip. The standard one is using a divider, and another one is a linear tone for IDT/STAC codecs. Currently, only the latter type is used for all codecs, which resulted in a wrong tone pitch. This patch adds the calculation of the standard HD-audio type. Also clean-up the fields in hda_beep struct. Reference: bko#13162 http://bugzilla.kernel.org/show_bug.cgi?id=13162 Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_beep.c')
-rw-r--r--sound/pci/hda/hda_beep.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 4de5bacd3929..29272f2e95a0 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -45,6 +45,46 @@ static void snd_hda_generate_beep(struct work_struct *work)
AC_VERB_SET_BEEP_CONTROL, beep->tone);
}
+/* (non-standard) Linear beep tone calculation for IDT/STAC codecs
+ *
+ * The tone frequency of beep generator on IDT/STAC codecs is
+ * defined from the 8bit tone parameter, in Hz,
+ * freq = 48000 * (257 - tone) / 1024
+ * that is from 12kHz to 93.75kHz in step of 46.875 hz
+ */
+static int beep_linear_tone(struct hda_beep *beep, int hz)
+{
+ hz *= 1000; /* fixed point */
+ hz = hz - DIGBEEP_HZ_MIN;
+ if (hz < 0)
+ hz = 0; /* turn off PC beep*/
+ else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
+ hz = 0xff;
+ else {
+ hz /= DIGBEEP_HZ_STEP;
+ hz++;
+ }
+ return hz;
+}
+
+/* HD-audio standard beep tone parameter calculation
+ *
+ * The tone frequency in Hz is calculated as
+ * freq = 48000 / (tone * 4)
+ * from 47Hz to 12kHz
+ */
+static int beep_standard_tone(struct hda_beep *beep, int hz)
+{
+ if (hz <= 0)
+ return 0; /* disabled */
+ hz = 12000 / hz;
+ if (hz > 0xff)
+ return 0xff;
+ if (hz <= 0)
+ return 1;
+ return hz;
+}
+
static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
unsigned int code, int hz)
{
@@ -55,21 +95,14 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
if (hz)
hz = 1000;
case SND_TONE:
- hz *= 1000; /* fixed point */
- hz = hz - DIGBEEP_HZ_MIN;
- if (hz < 0)
- hz = 0; /* turn off PC beep*/
- else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
- hz = 0xff;
- else {
- hz /= DIGBEEP_HZ_STEP;
- hz++;
- }
+ if (beep->linear_tone)
+ beep->tone = beep_linear_tone(beep, hz);
+ else
+ beep->tone = beep_standard_tone(beep, hz);
break;
default:
return -1;
}
- beep->tone = hz;
/* schedule beep event */
schedule_work(&beep->beep_work);