diff options
| -rw-r--r-- | include/sound/jack.h | 8 | ||||
| -rw-r--r-- | sound/core/jack.c | 60 |
2 files changed, 67 insertions, 1 deletions
diff --git a/include/sound/jack.h b/include/sound/jack.h index f236e426a706..d90b9fa32707 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h | |||
| @@ -42,6 +42,11 @@ enum snd_jack_types { | |||
| 42 | SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ | 42 | SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ |
| 43 | SND_JACK_VIDEOOUT = 0x0010, | 43 | SND_JACK_VIDEOOUT = 0x0010, |
| 44 | SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, | 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 | struct snd_jack { | 52 | struct snd_jack { |
| @@ -50,6 +55,7 @@ struct snd_jack { | |||
| 50 | int type; | 55 | int type; |
| 51 | const char *id; | 56 | const char *id; |
| 52 | char name[100]; | 57 | char name[100]; |
| 58 | unsigned int key[3]; /* Keep in sync with definitions above */ | ||
| 53 | void *private_data; | 59 | void *private_data; |
| 54 | void (*private_free)(struct snd_jack *); | 60 | void (*private_free)(struct snd_jack *); |
| 55 | }; | 61 | }; |
| @@ -59,6 +65,8 @@ struct snd_jack { | |||
| 59 | int snd_jack_new(struct snd_card *card, const char *id, int type, | 65 | int snd_jack_new(struct snd_card *card, const char *id, int type, |
| 60 | struct snd_jack **jack); | 66 | struct snd_jack **jack); |
| 61 | void snd_jack_set_parent(struct snd_jack *jack, struct device *parent); | 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 | void snd_jack_report(struct snd_jack *jack, int status); | 71 | void snd_jack_report(struct snd_jack *jack, int status); |
| 64 | 72 | ||
diff --git a/sound/core/jack.c b/sound/core/jack.c index f6f091f2b382..3813e7b04d05 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
| @@ -55,7 +55,7 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
| 55 | { | 55 | { |
| 56 | struct snd_jack *jack = device->device_data; | 56 | struct snd_jack *jack = device->device_data; |
| 57 | struct snd_card *card = device->card; | 57 | struct snd_card *card = device->card; |
| 58 | int err; | 58 | int err, i; |
| 59 | 59 | ||
| 60 | snprintf(jack->name, sizeof(jack->name), "%s %s", | 60 | snprintf(jack->name, sizeof(jack->name), "%s %s", |
| 61 | card->shortname, jack->id); | 61 | card->shortname, jack->id); |
| @@ -65,6 +65,19 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
| 65 | if (!jack->input_dev->dev.parent) | 65 | if (!jack->input_dev->dev.parent) |
| 66 | jack->input_dev->dev.parent = snd_card_get_device_link(card); | 66 | jack->input_dev->dev.parent = snd_card_get_device_link(card); |
| 67 | 67 | ||
| 68 | /* Add capabilities for any keys that are enabled */ | ||
| 69 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { | ||
| 70 | int testbit = SND_JACK_BTN_0 >> i; | ||
| 71 | |||
| 72 | if (!(jack->type & testbit)) | ||
| 73 | continue; | ||
| 74 | |||
| 75 | if (!jack->key[i]) | ||
| 76 | jack->key[i] = BTN_0 + i; | ||
| 77 | |||
| 78 | input_set_capability(jack->input_dev, EV_KEY, jack->key[i]); | ||
| 79 | } | ||
| 80 | |||
| 68 | err = input_register_device(jack->input_dev); | 81 | err = input_register_device(jack->input_dev); |
| 69 | if (err == 0) | 82 | if (err == 0) |
| 70 | jack->registered = 1; | 83 | jack->registered = 1; |
| @@ -151,6 +164,43 @@ void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) | |||
| 151 | EXPORT_SYMBOL(snd_jack_set_parent); | 164 | EXPORT_SYMBOL(snd_jack_set_parent); |
| 152 | 165 | ||
| 153 | /** | 166 | /** |
| 167 | * snd_jack_set_key - Set a key mapping on a jack | ||
| 168 | * | ||
| 169 | * @jack: The jack to configure | ||
| 170 | * @type: Jack report type for this key | ||
| 171 | * @keytype: Input layer key type to be reported | ||
| 172 | * | ||
| 173 | * Map a SND_JACK_BTN_ button type to an input layer key, allowing | ||
| 174 | * reporting of keys on accessories via the jack abstraction. If no | ||
| 175 | * mapping is provided but keys are enabled in the jack type then | ||
| 176 | * BTN_n numeric buttons will be reported. | ||
| 177 | * | ||
| 178 | * Note that this is intended to be use by simple devices with small | ||
| 179 | * numbers of keys that can be reported. It is also possible to | ||
| 180 | * access the input device directly - devices with complex input | ||
| 181 | * capabilities on accessories should consider doing this rather than | ||
| 182 | * using this abstraction. | ||
| 183 | * | ||
| 184 | * This function may only be called prior to registration of the jack. | ||
| 185 | */ | ||
| 186 | int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, | ||
| 187 | int keytype) | ||
| 188 | { | ||
| 189 | int key = fls(SND_JACK_BTN_0) - fls(type); | ||
| 190 | |||
| 191 | WARN_ON(jack->registered); | ||
| 192 | |||
| 193 | if (!keytype || key >= ARRAY_SIZE(jack->key)) | ||
| 194 | return -EINVAL; | ||
| 195 | |||
| 196 | jack->type |= type; | ||
| 197 | jack->key[key] = keytype; | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | EXPORT_SYMBOL(snd_jack_set_key); | ||
| 202 | |||
| 203 | /** | ||
| 154 | * snd_jack_report - Report the current status of a jack | 204 | * snd_jack_report - Report the current status of a jack |
| 155 | * | 205 | * |
| 156 | * @jack: The jack to report status for | 206 | * @jack: The jack to report status for |
| @@ -163,6 +213,14 @@ void snd_jack_report(struct snd_jack *jack, int status) | |||
| 163 | if (!jack) | 213 | if (!jack) |
| 164 | return; | 214 | return; |
| 165 | 215 | ||
| 216 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { | ||
| 217 | int testbit = SND_JACK_BTN_0 >> i; | ||
| 218 | |||
| 219 | if (jack->type & testbit) | ||
| 220 | input_report_key(jack->input_dev, jack->key[i], | ||
| 221 | status & testbit); | ||
| 222 | } | ||
| 223 | |||
| 166 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { | 224 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { |
| 167 | int testbit = 1 << i; | 225 | int testbit = 1 << i; |
| 168 | if (jack->type & testbit) | 226 | if (jack->type & testbit) |
