struct snd_jack_kctl { struct snd_kcontrol *kctl; struct list_head list; /* list of controls belong to the same jack */ unsignedint mask_bits; /* only masked status bits are reported via kctl */ struct snd_jack *jack; /* pointer to struct snd_jack */ bool sw_inject_enable; /* allow to inject plug event via debugfs */ #ifdef CONFIG_SND_JACK_INJECTION_DEBUG struct dentry *jack_debugfs_root; /* jack_kctl debugfs root */ #endif
};
#ifdef CONFIG_SND_JACK_INPUT_DEV
guard(mutex)(&jack->input_dev_lock); if (!jack->input_dev) return 0;
/* If the input device is registered with the input subsystem
* then we need to use a different deallocator. */ if (jack->registered)
input_unregister_device(jack->input_dev); else
input_free_device(jack->input_dev);
jack->input_dev = NULL; #endif/* CONFIG_SND_JACK_INPUT_DEV */ return 0;
}
/** * snd_jack_add_new_kctl - Create a new snd_jack_kctl and add it to jack * @jack: the jack instance which the kctl will attaching to * @name: the name for the snd_kcontrol object * @mask: a bitmask of enum snd_jack_type values that can be detected * by this snd_jack_kctl object. * * Creates a new snd_kcontrol object and adds it to the jack kctl_list. * * Return: Zero if successful, or a negative error code on failure.
*/ int snd_jack_add_new_kctl(struct snd_jack *jack, constchar * name, int mask)
{ struct snd_jack_kctl *jack_kctl;
jack_kctl = snd_jack_kctl_new(jack->card, name, mask); if (!jack_kctl) return -ENOMEM;
/** * snd_jack_new - Create a new jack * @card: the card instance * @id: an identifying string for this jack * @type: a bitmask of enum snd_jack_type values that can be detected by * this jack * @jjack: Used to provide the allocated jack object to the caller. * @initial_kctl: if true, create a kcontrol and add it to the jack list. * @phantom_jack: Don't create a input device for phantom jacks. * * Creates a new jack object. * * Return: Zero if successful, or a negative error code on failure. * On success @jjack will be initialised.
*/ int snd_jack_new(struct snd_card *card, constchar *id, int type, struct snd_jack **jjack, bool initial_kctl, bool phantom_jack)
{ struct snd_jack *jack; struct snd_jack_kctl *jack_kctl = NULL; int err; staticconststruct snd_device_ops ops = {
.dev_free = snd_jack_dev_free, #ifdef CONFIG_SND_JACK_INPUT_DEV
.dev_register = snd_jack_dev_register, #endif/* CONFIG_SND_JACK_INPUT_DEV */
.dev_disconnect = snd_jack_dev_disconnect,
};
if (initial_kctl) {
jack_kctl = snd_jack_kctl_new(card, id, type); if (!jack_kctl) return -ENOMEM;
}
jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL); if (jack == NULL) return -ENOMEM;
#ifdef CONFIG_SND_JACK_INPUT_DEV /** * snd_jack_set_key - Set a key mapping on a jack * * @jack: The jack to configure * @type: Jack report type for this key * @keytype: Input layer key type to be reported * * Map a SND_JACK_BTN_* button type to an input layer key, allowing * reporting of keys on accessories via the jack abstraction. If no * mapping is provided but keys are enabled in the jack type then * BTN_n numeric buttons will be reported. * * If jacks are not reporting via the input API this call will have no * effect. * * Note that this is intended to be use by simple devices with small * numbers of keys that can be reported. It is also possible to * access the input device directly - devices with complex input * capabilities on accessories should consider doing this rather than * using this abstraction. * * This function may only be called prior to registration of the jack. * * Return: Zero if successful, or a negative error code on failure.
*/ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, int keytype)
{ int key = fls(SND_JACK_BTN_0) - fls(type);
WARN_ON(jack->registered);
if (!keytype || key >= ARRAY_SIZE(jack->key)) return -EINVAL;
/** * snd_jack_report - Report the current status of a jack * Note: This function uses mutexes and should be called from a * context which can sleep (such as a workqueue). * * @jack: The jack to report status for * @status: The current status of the jack
*/ void snd_jack_report(struct snd_jack *jack, int status)
{ struct snd_jack_kctl *jack_kctl; unsignedint mask_bits = 0; #ifdef CONFIG_SND_JACK_INPUT_DEV struct input_dev *idev; int i; #endif
if (!jack) return;
jack->hw_status_cache = status;
list_for_each_entry(jack_kctl, &jack->kctl_list, list) if (jack_kctl->sw_inject_enable)
mask_bits |= jack_kctl->mask_bits; else
snd_kctl_jack_report(jack->card, jack_kctl->kctl,
status & jack_kctl->mask_bits);
#ifdef CONFIG_SND_JACK_INPUT_DEV
idev = input_get_device(jack->input_dev); if (!idev) return;
for (i = 0; i < ARRAY_SIZE(jack->key); i++) { int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);
if (jack->type & testbit)
input_report_key(idev, jack->key[i],
status & testbit);
}
for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { int testbit = ((1 << i) & ~mask_bits);
if (jack->type & testbit)
input_report_switch(idev,
jack_switch_types[i],
status & testbit);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.