diff options
Diffstat (limited to 'sound/pci/hda/hda_beep.c')
| -rw-r--r-- | sound/pci/hda/hda_beep.c | 55 |
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) | |||
| 45 | AC_VERB_SET_BEEP_CONTROL, beep->tone); | 45 | AC_VERB_SET_BEEP_CONTROL, beep->tone); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | /* (non-standard) Linear beep tone calculation for IDT/STAC codecs | ||
| 49 | * | ||
| 50 | * The tone frequency of beep generator on IDT/STAC codecs is | ||
| 51 | * defined from the 8bit tone parameter, in Hz, | ||
| 52 | * freq = 48000 * (257 - tone) / 1024 | ||
| 53 | * that is from 12kHz to 93.75kHz in step of 46.875 hz | ||
| 54 | */ | ||
| 55 | static int beep_linear_tone(struct hda_beep *beep, int hz) | ||
| 56 | { | ||
| 57 | hz *= 1000; /* fixed point */ | ||
| 58 | hz = hz - DIGBEEP_HZ_MIN; | ||
| 59 | if (hz < 0) | ||
| 60 | hz = 0; /* turn off PC beep*/ | ||
| 61 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | ||
| 62 | hz = 0xff; | ||
| 63 | else { | ||
| 64 | hz /= DIGBEEP_HZ_STEP; | ||
| 65 | hz++; | ||
| 66 | } | ||
| 67 | return hz; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* HD-audio standard beep tone parameter calculation | ||
| 71 | * | ||
| 72 | * The tone frequency in Hz is calculated as | ||
| 73 | * freq = 48000 / (tone * 4) | ||
| 74 | * from 47Hz to 12kHz | ||
| 75 | */ | ||
| 76 | static int beep_standard_tone(struct hda_beep *beep, int hz) | ||
| 77 | { | ||
| 78 | if (hz <= 0) | ||
| 79 | return 0; /* disabled */ | ||
| 80 | hz = 12000 / hz; | ||
| 81 | if (hz > 0xff) | ||
| 82 | return 0xff; | ||
| 83 | if (hz <= 0) | ||
| 84 | return 1; | ||
| 85 | return hz; | ||
| 86 | } | ||
| 87 | |||
| 48 | static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, | 88 | static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, |
| 49 | unsigned int code, int hz) | 89 | unsigned int code, int hz) |
| 50 | { | 90 | { |
| @@ -55,21 +95,14 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, | |||
| 55 | if (hz) | 95 | if (hz) |
| 56 | hz = 1000; | 96 | hz = 1000; |
| 57 | case SND_TONE: | 97 | case SND_TONE: |
| 58 | hz *= 1000; /* fixed point */ | 98 | if (beep->linear_tone) |
| 59 | hz = hz - DIGBEEP_HZ_MIN; | 99 | beep->tone = beep_linear_tone(beep, hz); |
| 60 | if (hz < 0) | 100 | else |
| 61 | hz = 0; /* turn off PC beep*/ | 101 | beep->tone = beep_standard_tone(beep, hz); |
| 62 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | ||
| 63 | hz = 0xff; | ||
| 64 | else { | ||
| 65 | hz /= DIGBEEP_HZ_STEP; | ||
| 66 | hz++; | ||
| 67 | } | ||
| 68 | break; | 102 | break; |
| 69 | default: | 103 | default: |
| 70 | return -1; | 104 | return -1; |
| 71 | } | 105 | } |
| 72 | beep->tone = hz; | ||
| 73 | 106 | ||
| 74 | /* schedule beep event */ | 107 | /* schedule beep event */ |
| 75 | schedule_work(&beep->beep_work); | 108 | schedule_work(&beep->beep_work); |
