Commit 20406f9b67e6fde4fff4639225c7a0e5ea6eaa9b

Authored by Takashi Iwai

Merge branch 'topic/jack' into for-linus

Showing 2 changed files Side-by-side Diff

include/sound/jack.h
... ... @@ -42,6 +42,11 @@
42 42 SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
43 43 SND_JACK_VIDEOOUT = 0x0010,
44 44 SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
  45 +
  46 + /* Kept separate from switches to facilitate implementation */
  47 + SND_JACK_BTN_0 = 0x4000,
  48 + SND_JACK_BTN_1 = 0x2000,
  49 + SND_JACK_BTN_2 = 0x1000,
45 50 };
46 51  
47 52 struct snd_jack {
... ... @@ -50,6 +55,7 @@
50 55 int type;
51 56 const char *id;
52 57 char name[100];
  58 + unsigned int key[3]; /* Keep in sync with definitions above */
53 59 void *private_data;
54 60 void (*private_free)(struct snd_jack *);
55 61 };
... ... @@ -59,6 +65,8 @@
59 65 int snd_jack_new(struct snd_card *card, const char *id, int type,
60 66 struct snd_jack **jack);
61 67 void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
  68 +int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
  69 + int keytype);
62 70  
63 71 void snd_jack_report(struct snd_jack *jack, int status);
64 72  
... ... @@ -24,7 +24,7 @@
24 24 #include <sound/jack.h>
25 25 #include <sound/core.h>
26 26  
27   -static int jack_types[] = {
  27 +static int jack_switch_types[] = {
28 28 SW_HEADPHONE_INSERT,
29 29 SW_MICROPHONE_INSERT,
30 30 SW_LINEOUT_INSERT,
... ... @@ -56,7 +56,7 @@
56 56 {
57 57 struct snd_jack *jack = device->device_data;
58 58 struct snd_card *card = device->card;
59   - int err;
  59 + int err, i;
60 60  
61 61 snprintf(jack->name, sizeof(jack->name), "%s %s",
62 62 card->shortname, jack->id);
... ... @@ -66,6 +66,19 @@
66 66 if (!jack->input_dev->dev.parent)
67 67 jack->input_dev->dev.parent = snd_card_get_device_link(card);
68 68  
  69 + /* Add capabilities for any keys that are enabled */
  70 + for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
  71 + int testbit = SND_JACK_BTN_0 >> i;
  72 +
  73 + if (!(jack->type & testbit))
  74 + continue;
  75 +
  76 + if (!jack->key[i])
  77 + jack->key[i] = BTN_0 + i;
  78 +
  79 + input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
  80 + }
  81 +
69 82 err = input_register_device(jack->input_dev);
70 83 if (err == 0)
71 84 jack->registered = 1;
72 85  
... ... @@ -113,10 +126,10 @@
113 126  
114 127 jack->type = type;
115 128  
116   - for (i = 0; i < ARRAY_SIZE(jack_types); i++)
  129 + for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++)
117 130 if (type & (1 << i))
118 131 input_set_capability(jack->input_dev, EV_SW,
119   - jack_types[i]);
  132 + jack_switch_types[i]);
120 133  
121 134 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
122 135 if (err < 0)
... ... @@ -152,6 +165,43 @@
152 165 EXPORT_SYMBOL(snd_jack_set_parent);
153 166  
154 167 /**
  168 + * snd_jack_set_key - Set a key mapping on a jack
  169 + *
  170 + * @jack: The jack to configure
  171 + * @type: Jack report type for this key
  172 + * @keytype: Input layer key type to be reported
  173 + *
  174 + * Map a SND_JACK_BTN_ button type to an input layer key, allowing
  175 + * reporting of keys on accessories via the jack abstraction. If no
  176 + * mapping is provided but keys are enabled in the jack type then
  177 + * BTN_n numeric buttons will be reported.
  178 + *
  179 + * Note that this is intended to be use by simple devices with small
  180 + * numbers of keys that can be reported. It is also possible to
  181 + * access the input device directly - devices with complex input
  182 + * capabilities on accessories should consider doing this rather than
  183 + * using this abstraction.
  184 + *
  185 + * This function may only be called prior to registration of the jack.
  186 + */
  187 +int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
  188 + int keytype)
  189 +{
  190 + int key = fls(SND_JACK_BTN_0) - fls(type);
  191 +
  192 + WARN_ON(jack->registered);
  193 +
  194 + if (!keytype || key >= ARRAY_SIZE(jack->key))
  195 + return -EINVAL;
  196 +
  197 + jack->type |= type;
  198 + jack->key[key] = keytype;
  199 +
  200 + return 0;
  201 +}
  202 +EXPORT_SYMBOL(snd_jack_set_key);
  203 +
  204 +/**
155 205 * snd_jack_report - Report the current status of a jack
156 206 *
157 207 * @jack: The jack to report status for
158 208  
... ... @@ -164,10 +214,19 @@
164 214 if (!jack)
165 215 return;
166 216  
167   - for (i = 0; i < ARRAY_SIZE(jack_types); i++) {
  217 + for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
  218 + int testbit = SND_JACK_BTN_0 >> i;
  219 +
  220 + if (jack->type & testbit)
  221 + input_report_key(jack->input_dev, jack->key[i],
  222 + status & testbit);
  223 + }
  224 +
  225 + for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
168 226 int testbit = 1 << i;
169 227 if (jack->type & testbit)
170   - input_report_switch(jack->input_dev, jack_types[i],
  228 + input_report_switch(jack->input_dev,
  229 + jack_switch_types[i],
171 230 status & testbit);
172 231 }
173 232