/** * 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; }
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; }
/** * 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. * * Currently, only one beep device is allowed to each codec. */ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) { static struct snd_device_ops ops = { .dev_register = beep_dev_register, .dev_disconnect = beep_dev_disconnect, .dev_free = beep_dev_free, }; struct input_dev *input_dev; 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); input_dev = input_allocate_device(); if (!input_dev) { err = -ENOMEM; goto err_free; } /* setup digital beep device */ input_dev->name = "HDA Digital PCBeep"; input_dev->phys = beep->phys; input_dev->id.bustype = BUS_PCI; input_dev->dev.parent = &codec->card->card_dev; input_dev->id.vendor = codec->core.vendor_id >> 16; input_dev->id.product = codec->core.vendor_id & 0xffff; input_dev->id.version = 0x01; input_dev->evbit[0] = BIT_MASK(EV_SND); input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); input_dev->event = snd_hda_beep_event; input_set_drvdata(input_dev, beep); beep->dev = input_dev; err = snd_device_new(codec->card, SNDRV_DEV_JACK, beep, &ops); if (err < 0) goto err_input; return 0; err_input: input_free_device(beep->dev); err_free: kfree(beep); codec->beep = NULL; return err; }