1/* 2 * Jack abstraction layer 3 * 4 * Copyright 2008 Wolfson Microelectronics 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22#include <linux/input.h> 23#include <linux/slab.h> 24#include <linux/module.h> 25#include <sound/jack.h> 26#include <sound/core.h> 27#include <sound/control.h> 28 29struct snd_jack_kctl { 30 struct snd_kcontrol *kctl; 31 struct list_head list; /* list of controls belong to the same jack */ 32 unsigned int mask_bits; /* only masked status bits are reported via kctl */ 33}; 34 35static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { 36 SW_HEADPHONE_INSERT, 37 SW_MICROPHONE_INSERT, 38 SW_LINEOUT_INSERT, 39 SW_JACK_PHYSICAL_INSERT, 40 SW_VIDEOOUT_INSERT, 41 SW_LINEIN_INSERT, 42}; 43 44static int snd_jack_dev_disconnect(struct snd_device *device) 45{ 46 struct snd_jack *jack = device->device_data; 47 48 if (!jack->input_dev) 49 return 0; 50 51 /* If the input device is registered with the input subsystem 52 * then we need to use a different deallocator. */ 53 if (jack->registered) 54 input_unregister_device(jack->input_dev); 55 else 56 input_free_device(jack->input_dev); 57 jack->input_dev = NULL; 58 return 0; 59} 60 61static int snd_jack_dev_free(struct snd_device *device) 62{ 63 struct snd_jack *jack = device->device_data; 64 struct snd_card *card = device->card; 65 struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl; 66 67 list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) { 68 list_del_init(&jack_kctl->list); 69 snd_ctl_remove(card, jack_kctl->kctl); 70 } 71 if (jack->private_free) 72 jack->private_free(jack); 73 74 snd_jack_dev_disconnect(device); 75 76 kfree(jack->id); 77 kfree(jack); 78 79 return 0; 80} 81 82static int snd_jack_dev_register(struct snd_device *device) 83{ 84 struct snd_jack *jack = device->device_data; 85 struct snd_card *card = device->card; 86 int err, i; 87 88 snprintf(jack->name, sizeof(jack->name), "%s %s", 89 card->shortname, jack->id); 90 91 if (!jack->input_dev) 92 return 0; 93 94 jack->input_dev->name = jack->name; 95 96 /* Default to the sound card device. */ 97 if (!jack->input_dev->dev.parent) 98 jack->input_dev->dev.parent = snd_card_get_device_link(card); 99 100 /* Add capabilities for any keys that are enabled */ 101 for (i = 0; i < ARRAY_SIZE(jack->key); i++) { 102 int testbit = SND_JACK_BTN_0 >> i; 103 104 if (!(jack->type & testbit)) 105 continue; 106 107 if (!jack->key[i]) 108 jack->key[i] = BTN_0 + i; 109 110 input_set_capability(jack->input_dev, EV_KEY, jack->key[i]); 111 } 112 113 err = input_register_device(jack->input_dev); 114 if (err == 0) 115 jack->registered = 1; 116 117 return err; 118} 119 120static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) 121{ 122 struct snd_jack_kctl *jack_kctl; 123 124 jack_kctl = kctl->private_data; 125 if (jack_kctl) { 126 list_del(&jack_kctl->list); 127 kfree(jack_kctl); 128 } 129} 130 131static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl) 132{ 133 list_add_tail(&jack_kctl->list, &jack->kctl_list); 134} 135 136static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask) 137{ 138 struct snd_kcontrol *kctl; 139 struct snd_jack_kctl *jack_kctl; 140 int err; 141 142 kctl = snd_kctl_jack_new(name, card); 143 if (!kctl) 144 return NULL; 145 146 err = snd_ctl_add(card, kctl); 147 if (err < 0) 148 return NULL; 149 150 jack_kctl = kzalloc(sizeof(*jack_kctl), GFP_KERNEL); 151 152 if (!jack_kctl) 153 goto error; 154 155 jack_kctl->kctl = kctl; 156 jack_kctl->mask_bits = mask; 157 158 kctl->private_data = jack_kctl; 159 kctl->private_free = snd_jack_kctl_private_free; 160 161 return jack_kctl; 162error: 163 snd_ctl_free_one(kctl); 164 return NULL; 165} 166 167/** 168 * snd_jack_add_new_kctl - Create a new snd_jack_kctl and add it to jack 169 * @jack: the jack instance which the kctl will attaching to 170 * @name: the name for the snd_kcontrol object 171 * @mask: a bitmask of enum snd_jack_type values that can be detected 172 * by this snd_jack_kctl object. 173 * 174 * Creates a new snd_kcontrol object and adds it to the jack kctl_list. 175 * 176 * Return: Zero if successful, or a negative error code on failure. 177 */ 178int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask) 179{ 180 struct snd_jack_kctl *jack_kctl; 181 182 jack_kctl = snd_jack_kctl_new(jack->card, name, mask); 183 if (!jack_kctl) 184 return -ENOMEM; 185 186 snd_jack_kctl_add(jack, jack_kctl); 187 return 0; 188} 189EXPORT_SYMBOL(snd_jack_add_new_kctl); 190 191/** 192 * snd_jack_new - Create a new jack 193 * @card: the card instance 194 * @id: an identifying string for this jack 195 * @type: a bitmask of enum snd_jack_type values that can be detected by 196 * this jack 197 * @jjack: Used to provide the allocated jack object to the caller. 198 * @initial_kctl: if true, create a kcontrol and add it to the jack list. 199 * @phantom_jack: Don't create a input device for phantom jacks. 200 * 201 * Creates a new jack object. 202 * 203 * Return: Zero if successful, or a negative error code on failure. 204 * On success @jjack will be initialised. 205 */ 206int snd_jack_new(struct snd_card *card, const char *id, int type, 207 struct snd_jack **jjack, bool initial_kctl, bool phantom_jack) 208{ 209 struct snd_jack *jack; 210 struct snd_jack_kctl *jack_kctl = NULL; 211 int err; 212 int i; 213 static struct snd_device_ops ops = { 214 .dev_free = snd_jack_dev_free, 215 .dev_register = snd_jack_dev_register, 216 .dev_disconnect = snd_jack_dev_disconnect, 217 }; 218 219 if (initial_kctl) { 220 jack_kctl = snd_jack_kctl_new(card, id, type); 221 if (!jack_kctl) 222 return -ENOMEM; 223 } 224 225 jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL); 226 if (jack == NULL) 227 return -ENOMEM; 228 229 jack->id = kstrdup(id, GFP_KERNEL); 230 231 /* don't creat input device for phantom jack */ 232 if (!phantom_jack) { 233 jack->input_dev = input_allocate_device(); 234 if (jack->input_dev == NULL) { 235 err = -ENOMEM; 236 goto fail_input; 237 } 238 239 jack->input_dev->phys = "ALSA"; 240 241 jack->type = type; 242 243 for (i = 0; i < SND_JACK_SWITCH_TYPES; i++) 244 if (type & (1 << i)) 245 input_set_capability(jack->input_dev, EV_SW, 246 jack_switch_types[i]); 247 248 } 249 250 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 251 if (err < 0) 252 goto fail_input; 253 254 jack->card = card; 255 INIT_LIST_HEAD(&jack->kctl_list); 256 257 if (initial_kctl) 258 snd_jack_kctl_add(jack, jack_kctl); 259 260 *jjack = jack; 261 262 return 0; 263 264fail_input: 265 input_free_device(jack->input_dev); 266 kfree(jack->id); 267 kfree(jack); 268 return err; 269} 270EXPORT_SYMBOL(snd_jack_new); 271 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 */ 282void 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} 290EXPORT_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 */ 317int 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 330 return 0; 331} 332EXPORT_SYMBOL(snd_jack_set_key); 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 */ 340void snd_jack_report(struct snd_jack *jack, int status) 341{ 342 struct snd_jack_kctl *jack_kctl; 343 int i; 344 345 if (!jack) 346 return; 347 348 list_for_each_entry(jack_kctl, &jack->kctl_list, list) 349 snd_kctl_jack_report(jack->card, jack_kctl->kctl, 350 status & jack_kctl->mask_bits); 351 352 if (!jack->input_dev) 353 return; 354 355 for (i = 0; i < ARRAY_SIZE(jack->key); i++) { 356 int testbit = SND_JACK_BTN_0 >> i; 357 358 if (jack->type & testbit) 359 input_report_key(jack->input_dev, jack->key[i], 360 status & testbit); 361 } 362 363 for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { 364 int testbit = 1 << i; 365 if (jack->type & testbit) 366 input_report_switch(jack->input_dev, 367 jack_switch_types[i], 368 status & testbit); 369 } 370 371 input_sync(jack->input_dev); 372 373} 374EXPORT_SYMBOL(snd_jack_report); 375