aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-02-17 03:44:25 -0500
committerTakashi Iwai <tiwai@suse.de>2016-02-23 03:03:07 -0500
commitfe0d128c57bf927a713159f60a18d9f315d4d91d (patch)
treee45587f9521ad620056a59e7073307ccb16c39f1
parent94a573500d48e780e5b23d307d6e6b05e6af7d2a (diff)
ALSA: jack: Allow building the jack layer without input device
Since the recent integration of kctl jack and input jack layers, we can basically build the jack layer even without input devices. That is, the jack layer itself can be built with conditional to enable the input device support or not, while the users may enable always CONFIG_SND_JACK unconditionally. For achieving it, this patch changes the following: - A new Kconfig, CONFIG_SND_JACK_INPUT_DEV, was introduced to indicate whether the jack layer supports the input device, - A few items in snd_jack struct and relevant codes are conditionally built upon CONFIG_SND_JACK_INPUT_DEV, - The users of CONFIG_SND_JACK drop the messy dependency on CONFIG_INPUT. This change also automagically fixes a potential bug in HD-audio driver Arnd reported, where the NULL or uninitialized jack instance is dereferenced. Reported-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/jack.h23
-rw-r--r--sound/core/Kconfig9
-rw-r--r--sound/core/jack.c23
-rw-r--r--sound/pci/Kconfig2
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/soc/Kconfig2
6 files changed, 43 insertions, 18 deletions
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 23bede121c78..1e84bfb553cf 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -72,14 +72,16 @@ enum snd_jack_types {
72#define SND_JACK_SWITCH_TYPES 6 72#define SND_JACK_SWITCH_TYPES 6
73 73
74struct snd_jack { 74struct snd_jack {
75 struct input_dev *input_dev;
76 struct list_head kctl_list; 75 struct list_head kctl_list;
77 struct snd_card *card; 76 struct snd_card *card;
77 const char *id;
78#ifdef CONFIG_SND_JACK_INPUT_DEV
79 struct input_dev *input_dev;
78 int registered; 80 int registered;
79 int type; 81 int type;
80 const char *id;
81 char name[100]; 82 char name[100];
82 unsigned int key[6]; /* Keep in sync with definitions above */ 83 unsigned int key[6]; /* Keep in sync with definitions above */
84#endif /* CONFIG_SND_JACK_INPUT_DEV */
83 void *private_data; 85 void *private_data;
84 void (*private_free)(struct snd_jack *); 86 void (*private_free)(struct snd_jack *);
85}; 87};
@@ -89,10 +91,11 @@ struct snd_jack {
89int snd_jack_new(struct snd_card *card, const char *id, int type, 91int snd_jack_new(struct snd_card *card, const char *id, int type,
90 struct snd_jack **jack, bool initial_kctl, bool phantom_jack); 92 struct snd_jack **jack, bool initial_kctl, bool phantom_jack);
91int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask); 93int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);
94#ifdef CONFIG_SND_JACK_INPUT_DEV
92void snd_jack_set_parent(struct snd_jack *jack, struct device *parent); 95void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
93int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, 96int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
94 int keytype); 97 int keytype);
95 98#endif
96void snd_jack_report(struct snd_jack *jack, int status); 99void snd_jack_report(struct snd_jack *jack, int status);
97 100
98#else 101#else
@@ -107,6 +110,13 @@ static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name
107 return 0; 110 return 0;
108} 111}
109 112
113static inline void snd_jack_report(struct snd_jack *jack, int status)
114{
115}
116
117#endif
118
119#if !defined(CONFIG_SND_JACK) || !defined(CONFIG_SND_JACK_INPUT_DEV)
110static inline void snd_jack_set_parent(struct snd_jack *jack, 120static inline void snd_jack_set_parent(struct snd_jack *jack,
111 struct device *parent) 121 struct device *parent)
112{ 122{
@@ -118,11 +128,6 @@ static inline int snd_jack_set_key(struct snd_jack *jack,
118{ 128{
119 return 0; 129 return 0;
120} 130}
121 131#endif /* !CONFIG_SND_JACK || !CONFIG_SND_JACK_INPUT_DEV */
122static inline void snd_jack_report(struct snd_jack *jack, int status)
123{
124}
125
126#endif
127 132
128#endif 133#endif
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index a2a1e24becc6..6d12ca9bcb80 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -24,12 +24,15 @@ config SND_RAWMIDI
24config SND_COMPRESS_OFFLOAD 24config SND_COMPRESS_OFFLOAD
25 tristate 25 tristate
26 26
27# To be effective this also requires INPUT - users should say:
28# select SND_JACK if INPUT=y || INPUT=SND
29# to avoid having to force INPUT on.
30config SND_JACK 27config SND_JACK
31 bool 28 bool
32 29
30# enable input device support in jack layer
31config SND_JACK_INPUT_DEV
32 bool
33 depends on SND_JACK
34 default y if INPUT=y || INPUT=SND
35
33config SND_SEQUENCER 36config SND_SEQUENCER
34 tristate "Sequencer support" 37 tristate "Sequencer support"
35 select SND_TIMER 38 select SND_TIMER
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 7237acbdcbbc..f652e90efd7e 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -32,6 +32,7 @@ struct snd_jack_kctl {
32 unsigned int mask_bits; /* only masked status bits are reported via kctl */ 32 unsigned int mask_bits; /* only masked status bits are reported via kctl */
33}; 33};
34 34
35#ifdef CONFIG_SND_JACK_INPUT_DEV
35static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { 36static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
36 SW_HEADPHONE_INSERT, 37 SW_HEADPHONE_INSERT,
37 SW_MICROPHONE_INSERT, 38 SW_MICROPHONE_INSERT,
@@ -40,9 +41,11 @@ static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
40 SW_VIDEOOUT_INSERT, 41 SW_VIDEOOUT_INSERT,
41 SW_LINEIN_INSERT, 42 SW_LINEIN_INSERT,
42}; 43};
44#endif /* CONFIG_SND_JACK_INPUT_DEV */
43 45
44static int snd_jack_dev_disconnect(struct snd_device *device) 46static int snd_jack_dev_disconnect(struct snd_device *device)
45{ 47{
48#ifdef CONFIG_SND_JACK_INPUT_DEV
46 struct snd_jack *jack = device->device_data; 49 struct snd_jack *jack = device->device_data;
47 50
48 if (!jack->input_dev) 51 if (!jack->input_dev)
@@ -55,6 +58,7 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
55 else 58 else
56 input_free_device(jack->input_dev); 59 input_free_device(jack->input_dev);
57 jack->input_dev = NULL; 60 jack->input_dev = NULL;
61#endif /* CONFIG_SND_JACK_INPUT_DEV */
58 return 0; 62 return 0;
59} 63}
60 64
@@ -79,6 +83,7 @@ static int snd_jack_dev_free(struct snd_device *device)
79 return 0; 83 return 0;
80} 84}
81 85
86#ifdef CONFIG_SND_JACK_INPUT_DEV
82static int snd_jack_dev_register(struct snd_device *device) 87static int snd_jack_dev_register(struct snd_device *device)
83{ 88{
84 struct snd_jack *jack = device->device_data; 89 struct snd_jack *jack = device->device_data;
@@ -116,6 +121,7 @@ static int snd_jack_dev_register(struct snd_device *device)
116 121
117 return err; 122 return err;
118} 123}
124#endif /* CONFIG_SND_JACK_INPUT_DEV */
119 125
120static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) 126static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
121{ 127{
@@ -209,11 +215,12 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
209 struct snd_jack *jack; 215 struct snd_jack *jack;
210 struct snd_jack_kctl *jack_kctl = NULL; 216 struct snd_jack_kctl *jack_kctl = NULL;
211 int err; 217 int err;
212 int i;
213 static struct snd_device_ops ops = { 218 static struct snd_device_ops ops = {
214 .dev_free = snd_jack_dev_free, 219 .dev_free = snd_jack_dev_free,
220#ifdef CONFIG_SND_JACK_INPUT_DEV
215 .dev_register = snd_jack_dev_register, 221 .dev_register = snd_jack_dev_register,
216 .dev_disconnect = snd_jack_dev_disconnect, 222 .dev_disconnect = snd_jack_dev_disconnect,
223#endif /* CONFIG_SND_JACK_INPUT_DEV */
217 }; 224 };
218 225
219 if (initial_kctl) { 226 if (initial_kctl) {
@@ -230,6 +237,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
230 237
231 /* don't creat input device for phantom jack */ 238 /* don't creat input device for phantom jack */
232 if (!phantom_jack) { 239 if (!phantom_jack) {
240#ifdef CONFIG_SND_JACK_INPUT_DEV
241 int i;
242
233 jack->input_dev = input_allocate_device(); 243 jack->input_dev = input_allocate_device();
234 if (jack->input_dev == NULL) { 244 if (jack->input_dev == NULL) {
235 err = -ENOMEM; 245 err = -ENOMEM;
@@ -245,6 +255,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
245 input_set_capability(jack->input_dev, EV_SW, 255 input_set_capability(jack->input_dev, EV_SW,
246 jack_switch_types[i]); 256 jack_switch_types[i]);
247 257
258#endif /* CONFIG_SND_JACK_INPUT_DEV */
248 } 259 }
249 260
250 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 261 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
@@ -262,13 +273,16 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
262 return 0; 273 return 0;
263 274
264fail_input: 275fail_input:
276#ifdef CONFIG_SND_JACK_INPUT_DEV
265 input_free_device(jack->input_dev); 277 input_free_device(jack->input_dev);
278#endif
266 kfree(jack->id); 279 kfree(jack->id);
267 kfree(jack); 280 kfree(jack);
268 return err; 281 return err;
269} 282}
270EXPORT_SYMBOL(snd_jack_new); 283EXPORT_SYMBOL(snd_jack_new);
271 284
285#ifdef CONFIG_SND_JACK_INPUT_DEV
272/** 286/**
273 * snd_jack_set_parent - Set the parent device for a jack 287 * snd_jack_set_parent - Set the parent device for a jack
274 * 288 *
@@ -326,10 +340,10 @@ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
326 340
327 jack->type |= type; 341 jack->type |= type;
328 jack->key[key] = keytype; 342 jack->key[key] = keytype;
329
330 return 0; 343 return 0;
331} 344}
332EXPORT_SYMBOL(snd_jack_set_key); 345EXPORT_SYMBOL(snd_jack_set_key);
346#endif /* CONFIG_SND_JACK_INPUT_DEV */
333 347
334/** 348/**
335 * snd_jack_report - Report the current status of a jack 349 * snd_jack_report - Report the current status of a jack
@@ -340,7 +354,9 @@ EXPORT_SYMBOL(snd_jack_set_key);
340void snd_jack_report(struct snd_jack *jack, int status) 354void snd_jack_report(struct snd_jack *jack, int status)
341{ 355{
342 struct snd_jack_kctl *jack_kctl; 356 struct snd_jack_kctl *jack_kctl;
357#ifdef CONFIG_SND_JACK_INPUT_DEV
343 int i; 358 int i;
359#endif
344 360
345 if (!jack) 361 if (!jack)
346 return; 362 return;
@@ -349,6 +365,7 @@ void snd_jack_report(struct snd_jack *jack, int status)
349 snd_kctl_jack_report(jack->card, jack_kctl->kctl, 365 snd_kctl_jack_report(jack->card, jack_kctl->kctl,
350 status & jack_kctl->mask_bits); 366 status & jack_kctl->mask_bits);
351 367
368#ifdef CONFIG_SND_JACK_INPUT_DEV
352 if (!jack->input_dev) 369 if (!jack->input_dev)
353 return; 370 return;
354 371
@@ -369,6 +386,6 @@ void snd_jack_report(struct snd_jack *jack, int status)
369 } 386 }
370 387
371 input_sync(jack->input_dev); 388 input_sync(jack->input_dev);
372 389#endif /* CONFIG_SND_JACK_INPUT_DEV */
373} 390}
374EXPORT_SYMBOL(snd_jack_report); 391EXPORT_SYMBOL(snd_jack_report);
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 8f6594a7d37f..32151d8c6bb8 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -866,7 +866,7 @@ config SND_VIRTUOSO
866 select SND_OXYGEN_LIB 866 select SND_OXYGEN_LIB
867 select SND_PCM 867 select SND_PCM
868 select SND_MPU401_UART 868 select SND_MPU401_UART
869 select SND_JACK if INPUT=y || INPUT=SND 869 select SND_JACK
870 help 870 help
871 Say Y here to include support for sound cards based on the 871 Say Y here to include support for sound cards based on the
872 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, DSX, 872 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, DSX,
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index e94cfd5c69f7..bb02c2d48fd5 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -4,7 +4,7 @@ config SND_HDA
4 tristate 4 tristate
5 select SND_PCM 5 select SND_PCM
6 select SND_VMASTER 6 select SND_VMASTER
7 select SND_JACK if INPUT=y || INPUT=SND 7 select SND_JACK
8 select SND_HDA_CORE 8 select SND_HDA_CORE
9 9
10config SND_HDA_INTEL 10config SND_HDA_INTEL
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7ea66ee3653f..182d92efc7c8 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -6,7 +6,7 @@ menuconfig SND_SOC
6 tristate "ALSA for SoC audio support" 6 tristate "ALSA for SoC audio support"
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS 8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK
10 select REGMAP_I2C if I2C 10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER 11 select REGMAP_SPI if SPI_MASTER
12 ---help--- 12 ---help---