11
11
12
12
#include <linux/slab.h>
13
13
#include <linux/export.h>
14
+ #include <linux/sort.h>
14
15
#include <sound/core.h>
15
16
#include "hda_codec.h"
16
17
#include "hda_local.h"
@@ -30,29 +31,30 @@ static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list)
30
31
return 0 ;
31
32
}
32
33
34
+ /* a pair of input pin and its sequence */
35
+ struct auto_out_pin {
36
+ hda_nid_t pin ;
37
+ short seq ;
38
+ };
39
+
40
+ static int compare_seq (const void * ap , const void * bp )
41
+ {
42
+ const struct auto_out_pin * a = ap ;
43
+ const struct auto_out_pin * b = bp ;
44
+ return (int )(a -> seq - b -> seq );
45
+ }
33
46
34
47
/*
35
48
* Sort an associated group of pins according to their sequence numbers.
49
+ * then store it to a pin array.
36
50
*/
37
- static void sort_pins_by_sequence (hda_nid_t * pins , short * sequences ,
51
+ static void sort_pins_by_sequence (hda_nid_t * pins , struct auto_out_pin * list ,
38
52
int num_pins )
39
53
{
40
- int i , j ;
41
- short seq ;
42
- hda_nid_t nid ;
43
-
44
- for (i = 0 ; i < num_pins ; i ++ ) {
45
- for (j = i + 1 ; j < num_pins ; j ++ ) {
46
- if (sequences [i ] > sequences [j ]) {
47
- seq = sequences [i ];
48
- sequences [i ] = sequences [j ];
49
- sequences [j ] = seq ;
50
- nid = pins [i ];
51
- pins [i ] = pins [j ];
52
- pins [j ] = nid ;
53
- }
54
- }
55
- }
54
+ int i ;
55
+ sort (list , num_pins , sizeof (list [0 ]), compare_seq , NULL );
56
+ for (i = 0 ; i < num_pins ; i ++ )
57
+ pins [i ] = list [i ].pin ;
56
58
}
57
59
58
60
@@ -67,21 +69,11 @@ static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid,
67
69
}
68
70
}
69
71
70
- /* sort inputs in the order of AUTO_PIN_* type */
71
- static void sort_autocfg_input_pins (struct auto_pin_cfg * cfg )
72
+ static int compare_input_type (const void * ap , const void * bp )
72
73
{
73
- int i , j ;
74
-
75
- for (i = 0 ; i < cfg -> num_inputs ; i ++ ) {
76
- for (j = i + 1 ; j < cfg -> num_inputs ; j ++ ) {
77
- if (cfg -> inputs [i ].type > cfg -> inputs [j ].type ) {
78
- struct auto_pin_cfg_item tmp ;
79
- tmp = cfg -> inputs [i ];
80
- cfg -> inputs [i ] = cfg -> inputs [j ];
81
- cfg -> inputs [j ] = tmp ;
82
- }
83
- }
84
- }
74
+ const struct auto_pin_cfg_item * a = ap ;
75
+ const struct auto_pin_cfg_item * b = bp ;
76
+ return (int )(a -> type - b -> type );
85
77
}
86
78
87
79
/* Reorder the surround channels
@@ -129,16 +121,16 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
129
121
{
130
122
hda_nid_t nid , end_nid ;
131
123
short seq , assoc_line_out ;
132
- short sequences_line_out [ARRAY_SIZE (cfg -> line_out_pins )];
133
- short sequences_speaker [ARRAY_SIZE (cfg -> speaker_pins )];
134
- short sequences_hp [ARRAY_SIZE (cfg -> hp_pins )];
124
+ struct auto_out_pin line_out [ARRAY_SIZE (cfg -> line_out_pins )];
125
+ struct auto_out_pin speaker_out [ARRAY_SIZE (cfg -> speaker_pins )];
126
+ struct auto_out_pin hp_out [ARRAY_SIZE (cfg -> hp_pins )];
135
127
int i ;
136
128
137
129
memset (cfg , 0 , sizeof (* cfg ));
138
130
139
- memset (sequences_line_out , 0 , sizeof (sequences_line_out ));
140
- memset (sequences_speaker , 0 , sizeof (sequences_speaker ));
141
- memset (sequences_hp , 0 , sizeof (sequences_hp ));
131
+ memset (line_out , 0 , sizeof (line_out ));
132
+ memset (speaker_out , 0 , sizeof (speaker_out ));
133
+ memset (hp_out , 0 , sizeof (hp_out ));
142
134
assoc_line_out = 0 ;
143
135
144
136
end_nid = codec -> start_nid + codec -> num_nodes ;
@@ -184,26 +176,26 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
184
176
continue ;
185
177
if (cfg -> line_outs >= ARRAY_SIZE (cfg -> line_out_pins ))
186
178
continue ;
187
- cfg -> line_out_pins [cfg -> line_outs ] = nid ;
188
- sequences_line_out [cfg -> line_outs ] = seq ;
179
+ line_out [cfg -> line_outs ]. pin = nid ;
180
+ line_out [cfg -> line_outs ]. seq = seq ;
189
181
cfg -> line_outs ++ ;
190
182
break ;
191
183
case AC_JACK_SPEAKER :
192
184
seq = get_defcfg_sequence (def_conf );
193
185
assoc = get_defcfg_association (def_conf );
194
186
if (cfg -> speaker_outs >= ARRAY_SIZE (cfg -> speaker_pins ))
195
187
continue ;
196
- cfg -> speaker_pins [cfg -> speaker_outs ] = nid ;
197
- sequences_speaker [cfg -> speaker_outs ] = (assoc << 4 ) | seq ;
188
+ speaker_out [cfg -> speaker_outs ]. pin = nid ;
189
+ speaker_out [cfg -> speaker_outs ]. seq = (assoc << 4 ) | seq ;
198
190
cfg -> speaker_outs ++ ;
199
191
break ;
200
192
case AC_JACK_HP_OUT :
201
193
seq = get_defcfg_sequence (def_conf );
202
194
assoc = get_defcfg_association (def_conf );
203
195
if (cfg -> hp_outs >= ARRAY_SIZE (cfg -> hp_pins ))
204
196
continue ;
205
- cfg -> hp_pins [cfg -> hp_outs ] = nid ;
206
- sequences_hp [cfg -> hp_outs ] = (assoc << 4 ) | seq ;
197
+ hp_out [cfg -> hp_outs ]. pin = nid ;
198
+ hp_out [cfg -> hp_outs ]. seq = (assoc << 4 ) | seq ;
207
199
cfg -> hp_outs ++ ;
208
200
break ;
209
201
case AC_JACK_MIC_IN :
@@ -248,34 +240,28 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
248
240
int i = 0 ;
249
241
while (i < cfg -> hp_outs ) {
250
242
/* The real HPs should have the sequence 0x0f */
251
- if ((sequences_hp [i ] & 0x0f ) == 0x0f ) {
243
+ if ((hp_out [i ]. seq & 0x0f ) == 0x0f ) {
252
244
i ++ ;
253
245
continue ;
254
246
}
255
247
/* Move it to the line-out table */
256
- cfg -> line_out_pins [cfg -> line_outs ] = cfg -> hp_pins [i ];
257
- sequences_line_out [cfg -> line_outs ] = sequences_hp [i ];
258
- cfg -> line_outs ++ ;
248
+ line_out [cfg -> line_outs ++ ] = hp_out [i ];
259
249
cfg -> hp_outs -- ;
260
- memmove (cfg -> hp_pins + i , cfg -> hp_pins + i + 1 ,
261
- sizeof (cfg -> hp_pins [0 ]) * (cfg -> hp_outs - i ));
262
- memmove (sequences_hp + i , sequences_hp + i + 1 ,
263
- sizeof (sequences_hp [0 ]) * (cfg -> hp_outs - i ));
250
+ memmove (hp_out + i , hp_out + i + 1 ,
251
+ sizeof (hp_out [0 ]) * (cfg -> hp_outs - i ));
264
252
}
265
- memset (cfg -> hp_pins + cfg -> hp_outs , 0 ,
266
- sizeof (hda_nid_t ) * (AUTO_CFG_MAX_OUTS - cfg -> hp_outs ));
253
+ memset (hp_out + cfg -> hp_outs , 0 ,
254
+ sizeof (hp_out [ 0 ] ) * (AUTO_CFG_MAX_OUTS - cfg -> hp_outs ));
267
255
if (!cfg -> hp_outs )
268
256
cfg -> line_out_type = AUTO_PIN_HP_OUT ;
269
257
270
258
}
271
259
272
260
/* sort by sequence */
273
- sort_pins_by_sequence (cfg -> line_out_pins , sequences_line_out ,
274
- cfg -> line_outs );
275
- sort_pins_by_sequence (cfg -> speaker_pins , sequences_speaker ,
261
+ sort_pins_by_sequence (cfg -> line_out_pins , line_out , cfg -> line_outs );
262
+ sort_pins_by_sequence (cfg -> speaker_pins , speaker_out ,
276
263
cfg -> speaker_outs );
277
- sort_pins_by_sequence (cfg -> hp_pins , sequences_hp ,
278
- cfg -> hp_outs );
264
+ sort_pins_by_sequence (cfg -> hp_pins , hp_out , cfg -> hp_outs );
279
265
280
266
/*
281
267
* FIX-UP: if no line-outs are detected, try to use speaker or HP pin
@@ -304,7 +290,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
304
290
reorder_outputs (cfg -> hp_outs , cfg -> hp_pins );
305
291
reorder_outputs (cfg -> speaker_outs , cfg -> speaker_pins );
306
292
307
- sort_autocfg_input_pins (cfg );
293
+ /* sort inputs in the order of AUTO_PIN_* type */
294
+ sort (cfg -> inputs , cfg -> num_inputs , sizeof (cfg -> inputs [0 ]),
295
+ compare_input_type , NULL );
308
296
309
297
/*
310
298
* debug prints of the parsed results
0 commit comments