Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 170327
b: refs/heads/master
c: 123c07a
h: refs/heads/master
i:
  170325: 0c19009
  170323: 229a07c
  170319: c4f45d8
v: v3
  • Loading branch information
Jaroslav Kysela authored and Takashi Iwai committed Nov 16, 2009
1 parent 3376ae9 commit b54719a
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fe705ab1526bc2c8b7756f3a855f040ab2060af2
refs/heads/master: 123c07aeddd71fbb295842a8c19866e780b9a100
88 changes: 70 additions & 18 deletions trunk/sound/pci/hda/hda_beep.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,23 +113,25 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
return 0;
}

int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
static void snd_hda_do_detach(struct hda_beep *beep)
{
input_unregister_device(beep->dev);
beep->dev = NULL;
cancel_work_sync(&beep->beep_work);
/* turn off beep for sure */
snd_hda_codec_write_cache(beep->codec, beep->nid, 0,
AC_VERB_SET_BEEP_CONTROL, 0);
}

static int snd_hda_do_attach(struct hda_beep *beep)
{
struct input_dev *input_dev;
struct hda_beep *beep;
struct hda_codec *codec = beep->codec;
int err;

if (!snd_hda_get_bool_hint(codec, "beep"))
return 0; /* disabled explicitly */

beep = kzalloc(sizeof(*beep), GFP_KERNEL);
if (beep == NULL)
return -ENOMEM;
snprintf(beep->phys, sizeof(beep->phys),
"card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
input_dev = input_allocate_device();
if (!input_dev) {
kfree(beep);
printk(KERN_INFO "hda_beep: unable to allocate input device\n");
return -ENOMEM;
}

Expand All @@ -151,21 +153,71 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
err = input_register_device(input_dev);
if (err < 0) {
input_free_device(input_dev);
kfree(beep);
printk(KERN_INFO "hda_beep: unable to register input device\n");
return err;
}
beep->dev = input_dev;
return 0;
}

static void snd_hda_do_register(struct work_struct *work)
{
struct hda_beep *beep =
container_of(work, struct hda_beep, register_work);
int request;

mutex_lock(&beep->mutex);
request = beep->request_enable;
if (beep->enabled != request) {
if (!request) {
snd_hda_do_detach(beep);
} else {
if (snd_hda_do_attach(beep) < 0)
goto __out;
}
beep->enabled = request;
}
__out:
mutex_unlock(&beep->mutex);
}

int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
{
struct hda_beep *beep = codec->beep;
enable = !!enable;
if (beep && beep->enabled != enable) {
beep->request_enable = enable;
schedule_work(&beep->register_work);
return 1;
}
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);

int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
{
struct hda_beep *beep;

if (!snd_hda_get_bool_hint(codec, "beep"))
return 0; /* disabled explicitly */

beep = kzalloc(sizeof(*beep), GFP_KERNEL);
if (beep == NULL)
return -ENOMEM;
snprintf(beep->phys, sizeof(beep->phys),
"card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
/* enable linear scale */
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_DIGI_CONVERT_2, 0x01);

beep->nid = nid;
beep->dev = input_dev;
beep->codec = codec;
beep->enabled = 1;
codec->beep = beep;

INIT_WORK(&beep->register_work, &snd_hda_do_register);
INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
mutex_init(&beep->mutex);

return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
Expand All @@ -174,11 +226,11 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
{
struct hda_beep *beep = codec->beep;
if (beep) {
cancel_work_sync(&beep->beep_work);

input_unregister_device(beep->dev);
kfree(beep);
cancel_work_sync(&beep->register_work);
if (beep->enabled)
snd_hda_do_detach(beep);
codec->beep = NULL;
kfree(beep);
}
}
EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
4 changes: 4 additions & 0 deletions trunk/sound/pci/hda/hda_beep.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ struct hda_beep {
int tone;
hda_nid_t nid;
unsigned int enabled:1;
unsigned int request_enable:1;
unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
struct work_struct register_work; /* scheduled task for beep event */
struct work_struct beep_work; /* scheduled task for beep event */
struct mutex mutex;
};

#ifdef CONFIG_SND_HDA_INPUT_BEEP
int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
void snd_hda_detach_beep_device(struct hda_codec *codec);
#else
Expand Down
12 changes: 12 additions & 0 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <sound/tlv.h>
#include <sound/initval.h>
#include "hda_local.h"
#include "hda_beep.h"
#include <sound/hda_hwdep.h>

/*
Expand Down Expand Up @@ -1734,6 +1735,17 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);

int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
long *valp = ucontrol->value.integer.value;

snd_hda_enable_beep_device(codec, *valp);
return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);

/*
* bound volume controls
*
Expand Down
15 changes: 15 additions & 0 deletions trunk/sound/pci/hda/hda_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@
/* stereo mute switch */
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_switch_info, \
.get = snd_hda_mixer_amp_switch_get, \
.put = snd_hda_mixer_amp_switch_put_beep, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
/* special beep mono mute switch */
#define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, 0, nid, channel, xindex, direction)
/* special beep stereo mute switch */
#define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_BEEP_MONO(xname, nid, 3, xindex, direction)

int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
Expand All @@ -81,6 +94,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
/* lowlevel accessor with caching; use carefully */
int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int index);
Expand Down
2 changes: 1 addition & 1 deletion trunk/sound/pci/hda/patch_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ static void ad198x_free_kctls(struct hda_codec *codec);
/* additional beep mixers; the actual parameters are overwritten at build */
static struct snd_kcontrol_new ad_beep_mixer[] = {
HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_OUTPUT),
HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
{ } /* end */
};

Expand Down
2 changes: 1 addition & 1 deletion trunk/sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -2413,7 +2413,7 @@ static void alc_free_kctls(struct hda_codec *codec);
/* additional beep mixers; the actual parameters are overwritten at build */
static struct snd_kcontrol_new alc_beep_mixer[] = {
HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
{ } /* end */
};

Expand Down
16 changes: 8 additions & 8 deletions trunk/sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2648,6 +2648,7 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
enum {
STAC_CTL_WIDGET_VOL,
STAC_CTL_WIDGET_MUTE,
STAC_CTL_WIDGET_MUTE_BEEP,
STAC_CTL_WIDGET_MONO_MUX,
STAC_CTL_WIDGET_HP_SWITCH,
STAC_CTL_WIDGET_IO_SWITCH,
Expand All @@ -2658,6 +2659,7 @@ enum {
static struct snd_kcontrol_new stac92xx_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
STAC_MONO_MUX,
STAC_CODEC_HP_SWITCH(NULL),
STAC_CODEC_IO_SWITCH(NULL, 0),
Expand Down Expand Up @@ -3221,11 +3223,14 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
{
struct sigmatel_spec *spec = codec->spec;
u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
int err;
int err, type = STAC_CTL_WIDGET_MUTE_BEEP;

if (spec->anabeep_nid == nid)
type = STAC_CTL_WIDGET_MUTE;

/* check for mute support for the the amp */
if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
err = stac92xx_add_control(spec, type,
"Beep Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
if (err < 0)
Expand Down Expand Up @@ -3258,12 +3263,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
int enabled = !!ucontrol->value.integer.value[0];
if (codec->beep->enabled != enabled) {
codec->beep->enabled = enabled;
return 1;
}
return 0;
return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
}

static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
Expand Down

0 comments on commit b54719a

Please sign in to comment.