diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-05-20 05:59:37 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-05-20 05:59:37 -0400 |
commit | 20406f9b67e6fde4fff4639225c7a0e5ea6eaa9b (patch) | |
tree | f87648beb18ba1fc36e93195d1e1877527563e71 /sound/core | |
parent | 5e8aa85253513b9c1ade8bd71dc341218a752a65 (diff) | |
parent | ebb812cb8df48e299b3d4ab75cbb0042384ef70d (diff) |
Merge branch 'topic/jack' into for-linus
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/jack.c | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/sound/core/jack.c b/sound/core/jack.c index 14b8a4ee690..4902ae56873 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/jack.h> | 24 | #include <sound/jack.h> |
25 | #include <sound/core.h> | 25 | #include <sound/core.h> |
26 | 26 | ||
27 | static int jack_types[] = { | 27 | static int jack_switch_types[] = { |
28 | SW_HEADPHONE_INSERT, | 28 | SW_HEADPHONE_INSERT, |
29 | SW_MICROPHONE_INSERT, | 29 | SW_MICROPHONE_INSERT, |
30 | SW_LINEOUT_INSERT, | 30 | SW_LINEOUT_INSERT, |
@@ -56,7 +56,7 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
56 | { | 56 | { |
57 | struct snd_jack *jack = device->device_data; | 57 | struct snd_jack *jack = device->device_data; |
58 | struct snd_card *card = device->card; | 58 | struct snd_card *card = device->card; |
59 | int err; | 59 | int err, i; |
60 | 60 | ||
61 | snprintf(jack->name, sizeof(jack->name), "%s %s", | 61 | snprintf(jack->name, sizeof(jack->name), "%s %s", |
62 | card->shortname, jack->id); | 62 | card->shortname, jack->id); |
@@ -66,6 +66,19 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
66 | if (!jack->input_dev->dev.parent) | 66 | if (!jack->input_dev->dev.parent) |
67 | jack->input_dev->dev.parent = snd_card_get_device_link(card); | 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 | err = input_register_device(jack->input_dev); | 82 | err = input_register_device(jack->input_dev); |
70 | if (err == 0) | 83 | if (err == 0) |
71 | jack->registered = 1; | 84 | jack->registered = 1; |
@@ -113,10 +126,10 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, | |||
113 | 126 | ||
114 | jack->type = type; | 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 | if (type & (1 << i)) | 130 | if (type & (1 << i)) |
118 | input_set_capability(jack->input_dev, EV_SW, | 131 | input_set_capability(jack->input_dev, EV_SW, |
119 | jack_types[i]); | 132 | jack_switch_types[i]); |
120 | 133 | ||
121 | err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); | 134 | err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); |
122 | if (err < 0) | 135 | if (err < 0) |
@@ -152,6 +165,43 @@ void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) | |||
152 | EXPORT_SYMBOL(snd_jack_set_parent); | 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 | * snd_jack_report - Report the current status of a jack | 205 | * snd_jack_report - Report the current status of a jack |
156 | * | 206 | * |
157 | * @jack: The jack to report status for | 207 | * @jack: The jack to report status for |
@@ -164,10 +214,19 @@ void snd_jack_report(struct snd_jack *jack, int status) | |||
164 | if (!jack) | 214 | if (!jack) |
165 | return; | 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 | int testbit = 1 << i; | 226 | int testbit = 1 << i; |
169 | if (jack->type & testbit) | 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 | status & testbit); | 230 | status & testbit); |
172 | } | 231 | } |
173 | 232 | ||