/** * snd_hda_attach_beep_device - Attach a beep input device * @codec: the HDA codec * @nid: beep NID * * Attach a beep object to the given widget. If beep hint is turned off * explicitly or beep_mode of the codec is turned off, this doesn't nothing. * * The attached beep device has to be registered via * snd_hda_register_beep_device() and released via snd_hda_detach_beep_device() * appropriately. * * Currently, only one beep device is allowed to each codec. */ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) { struct hda_beep *beep; int err; if (!snd_hda_get_bool_hint(codec, "beep")) return 0; /* disabled explicitly by hints */ if (codec->beep_mode == HDA_BEEP_MODE_OFF) return 0; /* disabled by module option */ beep = kzalloc(sizeof(*beep), GFP_KERNEL); if (beep == NULL) return -ENOMEM; snprintf(beep->phys, sizeof(beep->phys), "card%d/codec#%d/beep0", codec->card->number, codec->addr); /* enable linear scale */ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, 0x01); beep->nid = nid; beep->codec = codec; codec->beep = beep; INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); mutex_init(&beep->mutex); err = snd_hda_do_attach(beep); if (err < 0) { kfree(beep); codec->beep = NULL; return err; } return 0; }
static void snd_hda_do_register(struct work_struct *work) { struct hda_beep *beep = container_of(work, struct hda_beep, register_work); mutex_lock(&beep->mutex); if (beep->enabled && !beep->dev) snd_hda_do_attach(beep); mutex_unlock(&beep->mutex); }
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; if (codec->beep_mode == HDA_BEEP_MODE_OFF) return 0; 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); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, 0x01); beep->nid = nid; beep->codec = codec; beep->mode = codec->beep_mode; codec->beep = beep; INIT_WORK(&beep->register_work, &snd_hda_do_register); INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); mutex_init(&beep->mutex); if (beep->mode == HDA_BEEP_MODE_ON) { int err = snd_hda_do_attach(beep); if (err < 0) { kfree(beep); codec->beep = NULL; return err; } } return 0; }