18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Helper functions for jack-detection kcontrols 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include <linux/export.h> 108c2ecf20Sopenharmony_ci#include <sound/core.h> 118c2ecf20Sopenharmony_ci#include <sound/control.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define jack_detect_kctl_info snd_ctl_boolean_mono_info 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic int jack_detect_kctl_get(struct snd_kcontrol *kcontrol, 168c2ecf20Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci ucontrol->value.integer.value[0] = kcontrol->private_value; 198c2ecf20Sopenharmony_ci return 0; 208c2ecf20Sopenharmony_ci} 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new jack_detect_kctl = { 238c2ecf20Sopenharmony_ci /* name is filled later */ 248c2ecf20Sopenharmony_ci .iface = SNDRV_CTL_ELEM_IFACE_CARD, 258c2ecf20Sopenharmony_ci .access = SNDRV_CTL_ELEM_ACCESS_READ, 268c2ecf20Sopenharmony_ci .info = jack_detect_kctl_info, 278c2ecf20Sopenharmony_ci .get = jack_detect_kctl_get, 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic int get_available_index(struct snd_card *card, const char *name) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci struct snd_ctl_elem_id sid; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci memset(&sid, 0, sizeof(sid)); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci sid.index = 0; 378c2ecf20Sopenharmony_ci sid.iface = SNDRV_CTL_ELEM_IFACE_CARD; 388c2ecf20Sopenharmony_ci strlcpy(sid.name, name, sizeof(sid.name)); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci while (snd_ctl_find_id(card, &sid)) { 418c2ecf20Sopenharmony_ci sid.index++; 428c2ecf20Sopenharmony_ci /* reset numid; otherwise snd_ctl_find_id() hits this again */ 438c2ecf20Sopenharmony_ci sid.numid = 0; 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci return sid.index; 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic void jack_kctl_name_gen(char *name, const char *src_name, int size) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci size_t count = strlen(src_name); 528c2ecf20Sopenharmony_ci bool need_cat = true; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci /* remove redundant " Jack" from src_name */ 558c2ecf20Sopenharmony_ci if (count >= 5) 568c2ecf20Sopenharmony_ci need_cat = strncmp(&src_name[count - 5], " Jack", 5) ? true : false; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci snprintf(name, size, need_cat ? "%s Jack" : "%s", src_name); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistruct snd_kcontrol * 638c2ecf20Sopenharmony_cisnd_kctl_jack_new(const char *name, struct snd_card *card) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci struct snd_kcontrol *kctl; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci kctl = snd_ctl_new1(&jack_detect_kctl, NULL); 688c2ecf20Sopenharmony_ci if (!kctl) 698c2ecf20Sopenharmony_ci return NULL; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci jack_kctl_name_gen(kctl->id.name, name, sizeof(kctl->id.name)); 728c2ecf20Sopenharmony_ci kctl->id.index = get_available_index(card, kctl->id.name); 738c2ecf20Sopenharmony_ci kctl->private_value = 0; 748c2ecf20Sopenharmony_ci return kctl; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_civoid snd_kctl_jack_report(struct snd_card *card, 788c2ecf20Sopenharmony_ci struct snd_kcontrol *kctl, bool status) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci if (kctl->private_value == status) 818c2ecf20Sopenharmony_ci return; 828c2ecf20Sopenharmony_ci kctl->private_value = status; 838c2ecf20Sopenharmony_ci snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); 848c2ecf20Sopenharmony_ci} 85