root/sound/core/jack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_jack_dev_disconnect
  2. snd_jack_dev_free
  3. snd_jack_dev_register
  4. snd_jack_kctl_private_free
  5. snd_jack_kctl_add
  6. snd_jack_kctl_new
  7. snd_jack_add_new_kctl
  8. snd_jack_new
  9. snd_jack_set_parent
  10. snd_jack_set_key
  11. snd_jack_report

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Jack abstraction layer
   4  *
   5  *  Copyright 2008 Wolfson Microelectronics
   6  */
   7 
   8 #include <linux/input.h>
   9 #include <linux/slab.h>
  10 #include <linux/module.h>
  11 #include <sound/jack.h>
  12 #include <sound/core.h>
  13 #include <sound/control.h>
  14 
  15 struct snd_jack_kctl {
  16         struct snd_kcontrol *kctl;
  17         struct list_head list;  /* list of controls belong to the same jack */
  18         unsigned int mask_bits; /* only masked status bits are reported via kctl */
  19 };
  20 
  21 #ifdef CONFIG_SND_JACK_INPUT_DEV
  22 static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
  23         SW_HEADPHONE_INSERT,
  24         SW_MICROPHONE_INSERT,
  25         SW_LINEOUT_INSERT,
  26         SW_JACK_PHYSICAL_INSERT,
  27         SW_VIDEOOUT_INSERT,
  28         SW_LINEIN_INSERT,
  29 };
  30 #endif /* CONFIG_SND_JACK_INPUT_DEV */
  31 
  32 static int snd_jack_dev_disconnect(struct snd_device *device)
  33 {
  34 #ifdef CONFIG_SND_JACK_INPUT_DEV
  35         struct snd_jack *jack = device->device_data;
  36 
  37         if (!jack->input_dev)
  38                 return 0;
  39 
  40         /* If the input device is registered with the input subsystem
  41          * then we need to use a different deallocator. */
  42         if (jack->registered)
  43                 input_unregister_device(jack->input_dev);
  44         else
  45                 input_free_device(jack->input_dev);
  46         jack->input_dev = NULL;
  47 #endif /* CONFIG_SND_JACK_INPUT_DEV */
  48         return 0;
  49 }
  50 
  51 static int snd_jack_dev_free(struct snd_device *device)
  52 {
  53         struct snd_jack *jack = device->device_data;
  54         struct snd_card *card = device->card;
  55         struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
  56 
  57         list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {
  58                 list_del_init(&jack_kctl->list);
  59                 snd_ctl_remove(card, jack_kctl->kctl);
  60         }
  61         if (jack->private_free)
  62                 jack->private_free(jack);
  63 
  64         snd_jack_dev_disconnect(device);
  65 
  66         kfree(jack->id);
  67         kfree(jack);
  68 
  69         return 0;
  70 }
  71 
  72 #ifdef CONFIG_SND_JACK_INPUT_DEV
  73 static int snd_jack_dev_register(struct snd_device *device)
  74 {
  75         struct snd_jack *jack = device->device_data;
  76         struct snd_card *card = device->card;
  77         int err, i;
  78 
  79         snprintf(jack->name, sizeof(jack->name), "%s %s",
  80                  card->shortname, jack->id);
  81 
  82         if (!jack->input_dev)
  83                 return 0;
  84 
  85         jack->input_dev->name = jack->name;
  86 
  87         /* Default to the sound card device. */
  88         if (!jack->input_dev->dev.parent)
  89                 jack->input_dev->dev.parent = snd_card_get_device_link(card);
  90 
  91         /* Add capabilities for any keys that are enabled */
  92         for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
  93                 int testbit = SND_JACK_BTN_0 >> i;
  94 
  95                 if (!(jack->type & testbit))
  96                         continue;
  97 
  98                 if (!jack->key[i])
  99                         jack->key[i] = BTN_0 + i;
 100 
 101                 input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
 102         }
 103 
 104         err = input_register_device(jack->input_dev);
 105         if (err == 0)
 106                 jack->registered = 1;
 107 
 108         return err;
 109 }
 110 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 111 
 112 static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
 113 {
 114         struct snd_jack_kctl *jack_kctl;
 115 
 116         jack_kctl = kctl->private_data;
 117         if (jack_kctl) {
 118                 list_del(&jack_kctl->list);
 119                 kfree(jack_kctl);
 120         }
 121 }
 122 
 123 static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl)
 124 {
 125         list_add_tail(&jack_kctl->list, &jack->kctl_list);
 126 }
 127 
 128 static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask)
 129 {
 130         struct snd_kcontrol *kctl;
 131         struct snd_jack_kctl *jack_kctl;
 132         int err;
 133 
 134         kctl = snd_kctl_jack_new(name, card);
 135         if (!kctl)
 136                 return NULL;
 137 
 138         err = snd_ctl_add(card, kctl);
 139         if (err < 0)
 140                 return NULL;
 141 
 142         jack_kctl = kzalloc(sizeof(*jack_kctl), GFP_KERNEL);
 143 
 144         if (!jack_kctl)
 145                 goto error;
 146 
 147         jack_kctl->kctl = kctl;
 148         jack_kctl->mask_bits = mask;
 149 
 150         kctl->private_data = jack_kctl;
 151         kctl->private_free = snd_jack_kctl_private_free;
 152 
 153         return jack_kctl;
 154 error:
 155         snd_ctl_free_one(kctl);
 156         return NULL;
 157 }
 158 
 159 /**
 160  * snd_jack_add_new_kctl - Create a new snd_jack_kctl and add it to jack
 161  * @jack:  the jack instance which the kctl will attaching to
 162  * @name:  the name for the snd_kcontrol object
 163  * @mask:  a bitmask of enum snd_jack_type values that can be detected
 164  *         by this snd_jack_kctl object.
 165  *
 166  * Creates a new snd_kcontrol object and adds it to the jack kctl_list.
 167  *
 168  * Return: Zero if successful, or a negative error code on failure.
 169  */
 170 int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
 171 {
 172         struct snd_jack_kctl *jack_kctl;
 173 
 174         jack_kctl = snd_jack_kctl_new(jack->card, name, mask);
 175         if (!jack_kctl)
 176                 return -ENOMEM;
 177 
 178         snd_jack_kctl_add(jack, jack_kctl);
 179         return 0;
 180 }
 181 EXPORT_SYMBOL(snd_jack_add_new_kctl);
 182 
 183 /**
 184  * snd_jack_new - Create a new jack
 185  * @card:  the card instance
 186  * @id:    an identifying string for this jack
 187  * @type:  a bitmask of enum snd_jack_type values that can be detected by
 188  *         this jack
 189  * @jjack: Used to provide the allocated jack object to the caller.
 190  * @initial_kctl: if true, create a kcontrol and add it to the jack list.
 191  * @phantom_jack: Don't create a input device for phantom jacks.
 192  *
 193  * Creates a new jack object.
 194  *
 195  * Return: Zero if successful, or a negative error code on failure.
 196  * On success @jjack will be initialised.
 197  */
 198 int snd_jack_new(struct snd_card *card, const char *id, int type,
 199                  struct snd_jack **jjack, bool initial_kctl, bool phantom_jack)
 200 {
 201         struct snd_jack *jack;
 202         struct snd_jack_kctl *jack_kctl = NULL;
 203         int err;
 204         static struct snd_device_ops ops = {
 205                 .dev_free = snd_jack_dev_free,
 206 #ifdef CONFIG_SND_JACK_INPUT_DEV
 207                 .dev_register = snd_jack_dev_register,
 208                 .dev_disconnect = snd_jack_dev_disconnect,
 209 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 210         };
 211 
 212         if (initial_kctl) {
 213                 jack_kctl = snd_jack_kctl_new(card, id, type);
 214                 if (!jack_kctl)
 215                         return -ENOMEM;
 216         }
 217 
 218         jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
 219         if (jack == NULL)
 220                 return -ENOMEM;
 221 
 222         jack->id = kstrdup(id, GFP_KERNEL);
 223 
 224         /* don't creat input device for phantom jack */
 225         if (!phantom_jack) {
 226 #ifdef CONFIG_SND_JACK_INPUT_DEV
 227                 int i;
 228 
 229                 jack->input_dev = input_allocate_device();
 230                 if (jack->input_dev == NULL) {
 231                         err = -ENOMEM;
 232                         goto fail_input;
 233                 }
 234 
 235                 jack->input_dev->phys = "ALSA";
 236 
 237                 jack->type = type;
 238 
 239                 for (i = 0; i < SND_JACK_SWITCH_TYPES; i++)
 240                         if (type & (1 << i))
 241                                 input_set_capability(jack->input_dev, EV_SW,
 242                                                      jack_switch_types[i]);
 243 
 244 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 245         }
 246 
 247         err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
 248         if (err < 0)
 249                 goto fail_input;
 250 
 251         jack->card = card;
 252         INIT_LIST_HEAD(&jack->kctl_list);
 253 
 254         if (initial_kctl)
 255                 snd_jack_kctl_add(jack, jack_kctl);
 256 
 257         *jjack = jack;
 258 
 259         return 0;
 260 
 261 fail_input:
 262 #ifdef CONFIG_SND_JACK_INPUT_DEV
 263         input_free_device(jack->input_dev);
 264 #endif
 265         kfree(jack->id);
 266         kfree(jack);
 267         return err;
 268 }
 269 EXPORT_SYMBOL(snd_jack_new);
 270 
 271 #ifdef CONFIG_SND_JACK_INPUT_DEV
 272 /**
 273  * snd_jack_set_parent - Set the parent device for a jack
 274  *
 275  * @jack:   The jack to configure
 276  * @parent: The device to set as parent for the jack.
 277  *
 278  * Set the parent for the jack devices in the device tree.  This
 279  * function is only valid prior to registration of the jack.  If no
 280  * parent is configured then the parent device will be the sound card.
 281  */
 282 void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
 283 {
 284         WARN_ON(jack->registered);
 285         if (!jack->input_dev)
 286                 return;
 287 
 288         jack->input_dev->dev.parent = parent;
 289 }
 290 EXPORT_SYMBOL(snd_jack_set_parent);
 291 
 292 /**
 293  * snd_jack_set_key - Set a key mapping on a jack
 294  *
 295  * @jack:    The jack to configure
 296  * @type:    Jack report type for this key
 297  * @keytype: Input layer key type to be reported
 298  *
 299  * Map a SND_JACK_BTN_* button type to an input layer key, allowing
 300  * reporting of keys on accessories via the jack abstraction.  If no
 301  * mapping is provided but keys are enabled in the jack type then
 302  * BTN_n numeric buttons will be reported.
 303  *
 304  * If jacks are not reporting via the input API this call will have no
 305  * effect.
 306  *
 307  * Note that this is intended to be use by simple devices with small
 308  * numbers of keys that can be reported.  It is also possible to
 309  * access the input device directly - devices with complex input
 310  * capabilities on accessories should consider doing this rather than
 311  * using this abstraction.
 312  *
 313  * This function may only be called prior to registration of the jack.
 314  *
 315  * Return: Zero if successful, or a negative error code on failure.
 316  */
 317 int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
 318                      int keytype)
 319 {
 320         int key = fls(SND_JACK_BTN_0) - fls(type);
 321 
 322         WARN_ON(jack->registered);
 323 
 324         if (!keytype || key >= ARRAY_SIZE(jack->key))
 325                 return -EINVAL;
 326 
 327         jack->type |= type;
 328         jack->key[key] = keytype;
 329         return 0;
 330 }
 331 EXPORT_SYMBOL(snd_jack_set_key);
 332 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 333 
 334 /**
 335  * snd_jack_report - Report the current status of a jack
 336  *
 337  * @jack:   The jack to report status for
 338  * @status: The current status of the jack
 339  */
 340 void snd_jack_report(struct snd_jack *jack, int status)
 341 {
 342         struct snd_jack_kctl *jack_kctl;
 343 #ifdef CONFIG_SND_JACK_INPUT_DEV
 344         int i;
 345 #endif
 346 
 347         if (!jack)
 348                 return;
 349 
 350         list_for_each_entry(jack_kctl, &jack->kctl_list, list)
 351                 snd_kctl_jack_report(jack->card, jack_kctl->kctl,
 352                                             status & jack_kctl->mask_bits);
 353 
 354 #ifdef CONFIG_SND_JACK_INPUT_DEV
 355         if (!jack->input_dev)
 356                 return;
 357 
 358         for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
 359                 int testbit = SND_JACK_BTN_0 >> i;
 360 
 361                 if (jack->type & testbit)
 362                         input_report_key(jack->input_dev, jack->key[i],
 363                                          status & testbit);
 364         }
 365 
 366         for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
 367                 int testbit = 1 << i;
 368                 if (jack->type & testbit)
 369                         input_report_switch(jack->input_dev,
 370                                             jack_switch_types[i],
 371                                             status & testbit);
 372         }
 373 
 374         input_sync(jack->input_dev);
 375 #endif /* CONFIG_SND_JACK_INPUT_DEV */
 376 }
 377 EXPORT_SYMBOL(snd_jack_report);

/* [<][>][^][v][top][bottom][index][help] */