diff options
Diffstat (limited to 'sound/pci/asihpi/hpicmn.c')
-rw-r--r-- | sound/pci/asihpi/hpicmn.c | 406 |
1 files changed, 221 insertions, 185 deletions
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index d67f4d3db911..793236ef0a54 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -26,6 +26,8 @@ | |||
26 | 26 | ||
27 | #include "hpi_internal.h" | 27 | #include "hpi_internal.h" |
28 | #include "hpidebug.h" | 28 | #include "hpidebug.h" |
29 | #include "hpimsginit.h" | ||
30 | |||
29 | #include "hpicmn.h" | 31 | #include "hpicmn.h" |
30 | 32 | ||
31 | struct hpi_adapters_list { | 33 | struct hpi_adapters_list { |
@@ -43,14 +45,22 @@ static struct hpi_adapters_list adapters; | |||
43 | **/ | 45 | **/ |
44 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) | 46 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) |
45 | { | 47 | { |
46 | u16 error = 0; | 48 | if (phr->type != HPI_TYPE_RESPONSE) { |
49 | HPI_DEBUG_LOG(ERROR, "header type %d invalid", phr->type); | ||
50 | return HPI_ERROR_INVALID_RESPONSE; | ||
51 | } | ||
52 | |||
53 | if (phr->object != phm->object) { | ||
54 | HPI_DEBUG_LOG(ERROR, "header object %d invalid", phr->object); | ||
55 | return HPI_ERROR_INVALID_RESPONSE; | ||
56 | } | ||
47 | 57 | ||
48 | if ((phr->type != HPI_TYPE_RESPONSE) | 58 | if (phr->function != phm->function) { |
49 | || (phr->object != phm->object) | 59 | HPI_DEBUG_LOG(ERROR, "header type %d invalid", phr->function); |
50 | || (phr->function != phm->function)) | 60 | return HPI_ERROR_INVALID_RESPONSE; |
51 | error = HPI_ERROR_INVALID_RESPONSE; | 61 | } |
52 | 62 | ||
53 | return error; | 63 | return 0; |
54 | } | 64 | } |
55 | 65 | ||
56 | u16 hpi_add_adapter(struct hpi_adapter_obj *pao) | 66 | u16 hpi_add_adapter(struct hpi_adapter_obj *pao) |
@@ -76,17 +86,22 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao) | |||
76 | adapters.gw_num_adapters++; | 86 | adapters.gw_num_adapters++; |
77 | 87 | ||
78 | unlock: | 88 | unlock: |
79 | hpios_alistlock_un_lock(&adapters); | 89 | hpios_alistlock_unlock(&adapters); |
80 | return retval; | 90 | return retval; |
81 | } | 91 | } |
82 | 92 | ||
83 | void hpi_delete_adapter(struct hpi_adapter_obj *pao) | 93 | void hpi_delete_adapter(struct hpi_adapter_obj *pao) |
84 | { | 94 | { |
85 | memset(pao, 0, sizeof(struct hpi_adapter_obj)); | 95 | if (!pao->adapter_type) { |
96 | HPI_DEBUG_LOG(ERROR, "removing null adapter?\n"); | ||
97 | return; | ||
98 | } | ||
86 | 99 | ||
87 | hpios_alistlock_lock(&adapters); | 100 | hpios_alistlock_lock(&adapters); |
88 | adapters.gw_num_adapters--; /* dec the number of adapters */ | 101 | if (adapters.adapter[pao->index].adapter_type) |
89 | hpios_alistlock_un_lock(&adapters); | 102 | adapters.gw_num_adapters--; |
103 | memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0])); | ||
104 | hpios_alistlock_unlock(&adapters); | ||
90 | } | 105 | } |
91 | 106 | ||
92 | /** | 107 | /** |
@@ -125,51 +140,35 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index) | |||
125 | * wipe an HPI_ADAPTERS_LIST structure. | 140 | * wipe an HPI_ADAPTERS_LIST structure. |
126 | * | 141 | * |
127 | **/ | 142 | **/ |
128 | static void wipe_adapter_list(void | 143 | static void wipe_adapter_list(void) |
129 | ) | ||
130 | { | 144 | { |
131 | memset(&adapters, 0, sizeof(adapters)); | 145 | memset(&adapters, 0, sizeof(adapters)); |
132 | } | 146 | } |
133 | 147 | ||
134 | /** | 148 | static void subsys_get_adapter(struct hpi_message *phm, |
135 | * SubSysGetAdapters fills awAdapterList in an struct hpi_response structure | 149 | struct hpi_response *phr) |
136 | * with all adapters in the given HPI_ADAPTERS_LIST. | ||
137 | * | ||
138 | */ | ||
139 | static void subsys_get_adapters(struct hpi_response *phr) | ||
140 | { | 150 | { |
141 | /* fill in the response adapter array with the position */ | 151 | int count = phm->obj_index; |
142 | /* identified by the adapter number/index of the adapters in */ | 152 | u16 index = 0; |
143 | /* this HPI */ | ||
144 | /* i.e. if we have an A120 with it's jumper set to */ | ||
145 | /* Adapter Number 2 then put an Adapter type A120 in the */ | ||
146 | /* array in position 1 */ | ||
147 | /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */ | ||
148 | |||
149 | /* input: NONE */ | ||
150 | /* output: wNumAdapters */ | ||
151 | /* awAdapter[] */ | ||
152 | /* */ | ||
153 | |||
154 | short i; | ||
155 | struct hpi_adapter_obj *pao = NULL; | ||
156 | 153 | ||
157 | HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n"); | 154 | /* find the nCount'th nonzero adapter in array */ |
158 | 155 | for (index = 0; index < HPI_MAX_ADAPTERS; index++) { | |
159 | /* for each adapter, place it's type in the position of the array */ | 156 | if (adapters.adapter[index].adapter_type) { |
160 | /* corresponding to it's adapter number */ | 157 | if (count == 0) |
161 | for (i = 0; i < adapters.gw_num_adapters; i++) { | 158 | break; |
162 | pao = &adapters.adapter[i]; | 159 | count--; |
163 | if (phr->u.s.aw_adapter_list[pao->index] != 0) { | ||
164 | phr->error = HPI_DUPLICATE_ADAPTER_NUMBER; | ||
165 | phr->specific_error = pao->index; | ||
166 | return; | ||
167 | } | 160 | } |
168 | phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type; | ||
169 | } | 161 | } |
170 | 162 | ||
171 | phr->u.s.num_adapters = adapters.gw_num_adapters; | 163 | if (index < HPI_MAX_ADAPTERS) { |
172 | phr->error = 0; /* the function completed OK; */ | 164 | phr->u.s.adapter_index = adapters.adapter[index].index; |
165 | phr->u.s.aw_adapter_list[0] = | ||
166 | adapters.adapter[index].adapter_type; | ||
167 | } else { | ||
168 | phr->u.s.adapter_index = 0; | ||
169 | phr->u.s.aw_adapter_list[0] = 0; | ||
170 | phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER; | ||
171 | } | ||
173 | } | 172 | } |
174 | 173 | ||
175 | static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) | 174 | static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) |
@@ -178,67 +177,88 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) | |||
178 | int cached = 0; | 177 | int cached = 0; |
179 | if (!pC) | 178 | if (!pC) |
180 | return 0; | 179 | return 0; |
181 | if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count) | ||
182 | && (pC->cache_size_in_bytes) | ||
183 | ) { | ||
184 | u32 *p_master_cache; | ||
185 | pC->init = 1; | ||
186 | 180 | ||
187 | p_master_cache = (u32 *)pC->p_cache; | 181 | if (pC->init) |
188 | HPI_DEBUG_LOG(VERBOSE, "check %d controls\n", | 182 | return pC->init; |
183 | |||
184 | if (!pC->p_cache) | ||
185 | return 0; | ||
186 | |||
187 | if (pC->control_count && pC->cache_size_in_bytes) { | ||
188 | char *p_master_cache; | ||
189 | unsigned int byte_count = 0; | ||
190 | |||
191 | p_master_cache = (char *)pC->p_cache; | ||
192 | HPI_DEBUG_LOG(DEBUG, "check %d controls\n", | ||
189 | pC->control_count); | 193 | pC->control_count); |
190 | for (i = 0; i < pC->control_count; i++) { | 194 | for (i = 0; i < pC->control_count; i++) { |
191 | struct hpi_control_cache_info *info = | 195 | struct hpi_control_cache_info *info = |
192 | (struct hpi_control_cache_info *) | 196 | (struct hpi_control_cache_info *) |
193 | p_master_cache; | 197 | &p_master_cache[byte_count]; |
198 | |||
199 | if (!info->size_in32bit_words) { | ||
200 | /* ? This is a severe error, the cache is probably | ||
201 | corrupted. Minimum valid entry size is | ||
202 | sizeof(struct hpi_control_cache_info) */ | ||
203 | HPI_DEBUG_LOG(ERROR, | ||
204 | "zero size cache entry %d\n", i); | ||
205 | break; | ||
206 | } | ||
194 | 207 | ||
195 | if (info->control_type) { | 208 | if (info->control_type) { |
196 | pC->p_info[i] = info; | 209 | pC->p_info[info->control_index] = info; |
197 | cached++; | 210 | cached++; |
198 | } else | 211 | } else /* dummy cache entry */ |
199 | pC->p_info[i] = NULL; | 212 | pC->p_info[info->control_index] = NULL; |
200 | 213 | ||
201 | if (info->size_in32bit_words) | 214 | byte_count += info->size_in32bit_words * 4; |
202 | p_master_cache += info->size_in32bit_words; | ||
203 | else | ||
204 | p_master_cache += | ||
205 | sizeof(struct | ||
206 | hpi_control_cache_single) / | ||
207 | sizeof(u32); | ||
208 | 215 | ||
209 | HPI_DEBUG_LOG(VERBOSE, | 216 | HPI_DEBUG_LOG(VERBOSE, |
210 | "cached %d, pinfo %p index %d type %d\n", | 217 | "cached %d, pinfo %p index %d type %d size %d\n", |
211 | cached, pC->p_info[i], info->control_index, | 218 | cached, pC->p_info[info->control_index], |
212 | info->control_type); | 219 | info->control_index, info->control_type, |
220 | info->size_in32bit_words); | ||
221 | |||
222 | /* quit loop early if whole cache has been scanned. */ | ||
223 | /* pC->dwControlCount is the maximum possible entries, */ | ||
224 | /* but some may not be in the cache at all */ | ||
225 | if (byte_count >= pC->cache_size_in_bytes) | ||
226 | break; | ||
227 | /* have seen last control index */ | ||
228 | if (info->control_index == pC->control_count - 1) | ||
229 | break; | ||
213 | } | 230 | } |
214 | /* | 231 | |
215 | We didn't find anything to cache, so try again later ! | 232 | if (byte_count != pC->cache_size_in_bytes) |
216 | */ | 233 | HPI_DEBUG_LOG(WARNING, |
217 | if (!cached) | 234 | "bytecount %d != cache size %d", byte_count, |
218 | pC->init = 0; | 235 | pC->cache_size_in_bytes); |
236 | else | ||
237 | HPI_DEBUG_LOG(DEBUG, | ||
238 | "cache good. bytecount == cache size = %d", | ||
239 | byte_count); | ||
240 | |||
241 | pC->init = cached; | ||
219 | } | 242 | } |
220 | return pC->init; | 243 | return pC->init; |
221 | } | 244 | } |
222 | 245 | ||
223 | /** Find a control. | 246 | /** Find a control. |
224 | */ | 247 | */ |
225 | static short find_control(struct hpi_message *phm, | 248 | static short find_control(u16 control_index, |
226 | struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI, | 249 | struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI) |
227 | u16 *pw_control_index) | ||
228 | { | 250 | { |
229 | *pw_control_index = phm->obj_index; | ||
230 | |||
231 | if (!control_cache_alloc_check(p_cache)) { | 251 | if (!control_cache_alloc_check(p_cache)) { |
232 | HPI_DEBUG_LOG(VERBOSE, | 252 | HPI_DEBUG_LOG(VERBOSE, |
233 | "control_cache_alloc_check() failed. adap%d ci%d\n", | 253 | "control_cache_alloc_check() failed %d\n", |
234 | phm->adapter_index, *pw_control_index); | 254 | control_index); |
235 | return 0; | 255 | return 0; |
236 | } | 256 | } |
237 | 257 | ||
238 | *pI = p_cache->p_info[*pw_control_index]; | 258 | *pI = p_cache->p_info[control_index]; |
239 | if (!*pI) { | 259 | if (!*pI) { |
240 | HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n", | 260 | HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n", |
241 | phm->adapter_index, *pw_control_index); | 261 | control_index); |
242 | return 0; | 262 | return 0; |
243 | } else { | 263 | } else { |
244 | HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", | 264 | HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", |
@@ -257,11 +277,14 @@ short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache, | |||
257 | if ((phm->function == HPI_CONTROL_GET_STATE) | 277 | if ((phm->function == HPI_CONTROL_GET_STATE) |
258 | && (phm->object == HPI_OBJ_CONTROLEX) | 278 | && (phm->object == HPI_OBJ_CONTROLEX) |
259 | ) { | 279 | ) { |
260 | u16 control_index; | ||
261 | struct hpi_control_cache_info *pI; | 280 | struct hpi_control_cache_info *pI; |
262 | 281 | ||
263 | if (!find_control(phm, p_cache, &pI, &control_index)) | 282 | if (!find_control(phm->obj_index, p_cache, &pI)) { |
283 | HPI_DEBUG_LOG(VERBOSE, | ||
284 | "HPICMN find_control() failed for adap %d\n", | ||
285 | phm->adapter_index); | ||
264 | return 0; | 286 | return 0; |
287 | } | ||
265 | } | 288 | } |
266 | return 0; | 289 | return 0; |
267 | } | 290 | } |
@@ -290,13 +313,16 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
290 | struct hpi_message *phm, struct hpi_response *phr) | 313 | struct hpi_message *phm, struct hpi_response *phr) |
291 | { | 314 | { |
292 | short found = 1; | 315 | short found = 1; |
293 | u16 control_index; | ||
294 | struct hpi_control_cache_info *pI; | 316 | struct hpi_control_cache_info *pI; |
295 | struct hpi_control_cache_single *pC; | 317 | struct hpi_control_cache_single *pC; |
296 | struct hpi_control_cache_pad *p_pad; | 318 | struct hpi_control_cache_pad *p_pad; |
297 | 319 | ||
298 | if (!find_control(phm, p_cache, &pI, &control_index)) | 320 | if (!find_control(phm->obj_index, p_cache, &pI)) { |
321 | HPI_DEBUG_LOG(VERBOSE, | ||
322 | "HPICMN find_control() failed for adap %d\n", | ||
323 | phm->adapter_index); | ||
299 | return 0; | 324 | return 0; |
325 | } | ||
300 | 326 | ||
301 | phr->error = 0; | 327 | phr->error = 0; |
302 | 328 | ||
@@ -310,55 +336,66 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
310 | 336 | ||
311 | case HPI_CONTROL_METER: | 337 | case HPI_CONTROL_METER: |
312 | if (phm->u.c.attribute == HPI_METER_PEAK) { | 338 | if (phm->u.c.attribute == HPI_METER_PEAK) { |
313 | phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0]; | 339 | phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0]; |
314 | phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1]; | 340 | phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1]; |
315 | } else if (phm->u.c.attribute == HPI_METER_RMS) { | 341 | } else if (phm->u.c.attribute == HPI_METER_RMS) { |
316 | phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0]; | 342 | if (pC->u.meter.an_logRMS[0] == |
317 | phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1]; | 343 | HPI_CACHE_INVALID_SHORT) { |
344 | phr->error = | ||
345 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | ||
346 | phr->u.c.an_log_value[0] = HPI_METER_MINIMUM; | ||
347 | phr->u.c.an_log_value[1] = HPI_METER_MINIMUM; | ||
348 | } else { | ||
349 | phr->u.c.an_log_value[0] = | ||
350 | pC->u.meter.an_logRMS[0]; | ||
351 | phr->u.c.an_log_value[1] = | ||
352 | pC->u.meter.an_logRMS[1]; | ||
353 | } | ||
318 | } else | 354 | } else |
319 | found = 0; | 355 | found = 0; |
320 | break; | 356 | break; |
321 | case HPI_CONTROL_VOLUME: | 357 | case HPI_CONTROL_VOLUME: |
322 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { | 358 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { |
323 | phr->u.c.an_log_value[0] = pC->u.v.an_log[0]; | 359 | phr->u.c.an_log_value[0] = pC->u.vol.an_log[0]; |
324 | phr->u.c.an_log_value[1] = pC->u.v.an_log[1]; | 360 | phr->u.c.an_log_value[1] = pC->u.vol.an_log[1]; |
325 | } else | 361 | } else |
326 | found = 0; | 362 | found = 0; |
327 | break; | 363 | break; |
328 | case HPI_CONTROL_MULTIPLEXER: | 364 | case HPI_CONTROL_MULTIPLEXER: |
329 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { | 365 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { |
330 | phr->u.c.param1 = pC->u.x.source_node_type; | 366 | phr->u.c.param1 = pC->u.mux.source_node_type; |
331 | phr->u.c.param2 = pC->u.x.source_node_index; | 367 | phr->u.c.param2 = pC->u.mux.source_node_index; |
332 | } else { | 368 | } else { |
333 | found = 0; | 369 | found = 0; |
334 | } | 370 | } |
335 | break; | 371 | break; |
336 | case HPI_CONTROL_CHANNEL_MODE: | 372 | case HPI_CONTROL_CHANNEL_MODE: |
337 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) | 373 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) |
338 | phr->u.c.param1 = pC->u.m.mode; | 374 | phr->u.c.param1 = pC->u.mode.mode; |
339 | else | 375 | else |
340 | found = 0; | 376 | found = 0; |
341 | break; | 377 | break; |
342 | case HPI_CONTROL_LEVEL: | 378 | case HPI_CONTROL_LEVEL: |
343 | if (phm->u.c.attribute == HPI_LEVEL_GAIN) { | 379 | if (phm->u.c.attribute == HPI_LEVEL_GAIN) { |
344 | phr->u.c.an_log_value[0] = pC->u.l.an_log[0]; | 380 | phr->u.c.an_log_value[0] = pC->u.level.an_log[0]; |
345 | phr->u.c.an_log_value[1] = pC->u.l.an_log[1]; | 381 | phr->u.c.an_log_value[1] = pC->u.level.an_log[1]; |
346 | } else | 382 | } else |
347 | found = 0; | 383 | found = 0; |
348 | break; | 384 | break; |
349 | case HPI_CONTROL_TUNER: | 385 | case HPI_CONTROL_TUNER: |
350 | if (phm->u.c.attribute == HPI_TUNER_FREQ) | 386 | if (phm->u.c.attribute == HPI_TUNER_FREQ) |
351 | phr->u.c.param1 = pC->u.t.freq_ink_hz; | 387 | phr->u.c.param1 = pC->u.tuner.freq_ink_hz; |
352 | else if (phm->u.c.attribute == HPI_TUNER_BAND) | 388 | else if (phm->u.c.attribute == HPI_TUNER_BAND) |
353 | phr->u.c.param1 = pC->u.t.band; | 389 | phr->u.c.param1 = pC->u.tuner.band; |
354 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) | 390 | else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG) |
355 | && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) | 391 | if (pC->u.tuner.s_level_avg == |
356 | if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { | 392 | HPI_CACHE_INVALID_SHORT) { |
357 | phr->u.c.param1 = 0; | 393 | phr->u.cu.tuner.s_level = 0; |
358 | phr->error = | 394 | phr->error = |
359 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | 395 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; |
360 | } else | 396 | } else |
361 | phr->u.c.param1 = pC->u.t.level; | 397 | phr->u.cu.tuner.s_level = |
398 | pC->u.tuner.s_level_avg; | ||
362 | else | 399 | else |
363 | found = 0; | 400 | found = 0; |
364 | break; | 401 | break; |
@@ -366,7 +403,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
366 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) | 403 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) |
367 | phr->u.c.param1 = pC->u.aes3rx.error_status; | 404 | phr->u.c.param1 = pC->u.aes3rx.error_status; |
368 | else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) | 405 | else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) |
369 | phr->u.c.param1 = pC->u.aes3rx.source; | 406 | phr->u.c.param1 = pC->u.aes3rx.format; |
370 | else | 407 | else |
371 | found = 0; | 408 | found = 0; |
372 | break; | 409 | break; |
@@ -385,13 +422,13 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
385 | case HPI_CONTROL_SILENCEDETECTOR: | 422 | case HPI_CONTROL_SILENCEDETECTOR: |
386 | if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { | 423 | if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { |
387 | phr->u.c.param1 = pC->u.silence.state; | 424 | phr->u.c.param1 = pC->u.silence.state; |
388 | phr->u.c.param2 = pC->u.silence.count; | 425 | /*? phr->u.c.dwParam2 = pC->u.silence.dwCount; */ |
389 | } else | 426 | } else |
390 | found = 0; | 427 | found = 0; |
391 | break; | 428 | break; |
392 | case HPI_CONTROL_MICROPHONE: | 429 | case HPI_CONTROL_MICROPHONE: |
393 | if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) | 430 | if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) |
394 | phr->u.c.param1 = pC->u.phantom_power.state; | 431 | phr->u.c.param1 = pC->u.microphone.phantom_state; |
395 | else | 432 | else |
396 | found = 0; | 433 | found = 0; |
397 | break; | 434 | break; |
@@ -400,7 +437,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
400 | phr->u.c.param1 = pC->u.clk.source; | 437 | phr->u.c.param1 = pC->u.clk.source; |
401 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { | 438 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { |
402 | if (pC->u.clk.source_index == | 439 | if (pC->u.clk.source_index == |
403 | HPI_ERROR_ILLEGAL_CACHE_VALUE) { | 440 | HPI_CACHE_INVALID_UINT16) { |
404 | phr->u.c.param1 = 0; | 441 | phr->u.c.param1 = 0; |
405 | phr->error = | 442 | phr->error = |
406 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | 443 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; |
@@ -411,60 +448,63 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
411 | else | 448 | else |
412 | found = 0; | 449 | found = 0; |
413 | break; | 450 | break; |
414 | case HPI_CONTROL_PAD: | 451 | case HPI_CONTROL_PAD:{ |
415 | 452 | struct hpi_control_cache_pad *p_pad; | |
416 | if (!(p_pad->field_valid_flags & (1 << | 453 | p_pad = (struct hpi_control_cache_pad *)pI; |
417 | HPI_CTL_ATTR_INDEX(phm->u.c. | ||
418 | attribute)))) { | ||
419 | phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | ||
420 | break; | ||
421 | } | ||
422 | 454 | ||
423 | if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) | 455 | if (!(p_pad->field_valid_flags & (1 << |
424 | phr->u.c.param1 = p_pad->pI; | 456 | HPI_CTL_ATTR_INDEX(phm->u.c. |
425 | else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) | 457 | attribute)))) { |
426 | phr->u.c.param1 = p_pad->pTY; | ||
427 | else { | ||
428 | unsigned int index = | ||
429 | HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1; | ||
430 | unsigned int offset = phm->u.c.param1; | ||
431 | unsigned int pad_string_len, field_size; | ||
432 | char *pad_string; | ||
433 | unsigned int tocopy; | ||
434 | |||
435 | HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n", | ||
436 | phm->u.c.attribute); | ||
437 | |||
438 | if (index > ARRAY_SIZE(pad_desc) - 1) { | ||
439 | phr->error = | 458 | phr->error = |
440 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | 459 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; |
441 | break; | 460 | break; |
442 | } | 461 | } |
443 | 462 | ||
444 | pad_string = ((char *)p_pad) + pad_desc[index].offset; | 463 | if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) |
445 | field_size = pad_desc[index].field_size; | 464 | phr->u.c.param1 = p_pad->pI; |
446 | /* Ensure null terminator */ | 465 | else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) |
447 | pad_string[field_size - 1] = 0; | 466 | phr->u.c.param1 = p_pad->pTY; |
448 | 467 | else { | |
449 | pad_string_len = strlen(pad_string) + 1; | 468 | unsigned int index = |
450 | 469 | HPI_CTL_ATTR_INDEX(phm->u.c. | |
451 | if (offset > pad_string_len) { | 470 | attribute) - 1; |
452 | phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; | 471 | unsigned int offset = phm->u.c.param1; |
453 | break; | 472 | unsigned int pad_string_len, field_size; |
473 | char *pad_string; | ||
474 | unsigned int tocopy; | ||
475 | |||
476 | if (index > ARRAY_SIZE(pad_desc) - 1) { | ||
477 | phr->error = | ||
478 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | ||
479 | break; | ||
480 | } | ||
481 | |||
482 | pad_string = | ||
483 | ((char *)p_pad) + | ||
484 | pad_desc[index].offset; | ||
485 | field_size = pad_desc[index].field_size; | ||
486 | /* Ensure null terminator */ | ||
487 | pad_string[field_size - 1] = 0; | ||
488 | |||
489 | pad_string_len = strlen(pad_string) + 1; | ||
490 | |||
491 | if (offset > pad_string_len) { | ||
492 | phr->error = | ||
493 | HPI_ERROR_INVALID_CONTROL_VALUE; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | tocopy = pad_string_len - offset; | ||
498 | if (tocopy > sizeof(phr->u.cu.chars8.sz_data)) | ||
499 | tocopy = sizeof(phr->u.cu.chars8. | ||
500 | sz_data); | ||
501 | |||
502 | memcpy(phr->u.cu.chars8.sz_data, | ||
503 | &pad_string[offset], tocopy); | ||
504 | |||
505 | phr->u.cu.chars8.remaining_chars = | ||
506 | pad_string_len - offset - tocopy; | ||
454 | } | 507 | } |
455 | |||
456 | tocopy = pad_string_len - offset; | ||
457 | if (tocopy > sizeof(phr->u.cu.chars8.sz_data)) | ||
458 | tocopy = sizeof(phr->u.cu.chars8.sz_data); | ||
459 | |||
460 | HPI_DEBUG_LOG(VERBOSE, | ||
461 | "PADS memcpy(%d), offset %d \n", tocopy, | ||
462 | offset); | ||
463 | memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset], | ||
464 | tocopy); | ||
465 | |||
466 | phr->u.cu.chars8.remaining_chars = | ||
467 | pad_string_len - offset - tocopy; | ||
468 | } | 508 | } |
469 | break; | 509 | break; |
470 | default: | 510 | default: |
@@ -472,16 +512,9 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
472 | break; | 512 | break; |
473 | } | 513 | } |
474 | 514 | ||
475 | if (found) | 515 | HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n", |
476 | HPI_DEBUG_LOG(VERBOSE, | 516 | found ? "Cached" : "Uncached", phm->adapter_index, |
477 | "cached adap %d, ctl %d, type %d, attr %d\n", | 517 | pI->control_index, pI->control_type, phm->u.c.attribute); |
478 | phm->adapter_index, pI->control_index, | ||
479 | pI->control_type, phm->u.c.attribute); | ||
480 | else | ||
481 | HPI_DEBUG_LOG(VERBOSE, | ||
482 | "uncached adap %d, ctl %d, ctl type %d\n", | ||
483 | phm->adapter_index, pI->control_index, | ||
484 | pI->control_type); | ||
485 | 518 | ||
486 | if (found) | 519 | if (found) |
487 | phr->size = | 520 | phr->size = |
@@ -497,18 +530,21 @@ Only update if no error. | |||
497 | Volume and Level return the limited values in the response, so use these | 530 | Volume and Level return the limited values in the response, so use these |
498 | Multiplexer does so use sent values | 531 | Multiplexer does so use sent values |
499 | */ | 532 | */ |
500 | void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | 533 | void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, |
501 | struct hpi_message *phm, struct hpi_response *phr) | 534 | struct hpi_message *phm, struct hpi_response *phr) |
502 | { | 535 | { |
503 | u16 control_index; | ||
504 | struct hpi_control_cache_single *pC; | 536 | struct hpi_control_cache_single *pC; |
505 | struct hpi_control_cache_info *pI; | 537 | struct hpi_control_cache_info *pI; |
506 | 538 | ||
507 | if (phr->error) | 539 | if (phr->error) |
508 | return; | 540 | return; |
509 | 541 | ||
510 | if (!find_control(phm, p_cache, &pI, &control_index)) | 542 | if (!find_control(phm->obj_index, p_cache, &pI)) { |
543 | HPI_DEBUG_LOG(VERBOSE, | ||
544 | "HPICMN find_control() failed for adap %d\n", | ||
545 | phm->adapter_index); | ||
511 | return; | 546 | return; |
547 | } | ||
512 | 548 | ||
513 | /* pC is the default cached control strucure. | 549 | /* pC is the default cached control strucure. |
514 | May be cast to something else in the following switch statement. | 550 | May be cast to something else in the following switch statement. |
@@ -518,31 +554,31 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
518 | switch (pI->control_type) { | 554 | switch (pI->control_type) { |
519 | case HPI_CONTROL_VOLUME: | 555 | case HPI_CONTROL_VOLUME: |
520 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { | 556 | if (phm->u.c.attribute == HPI_VOLUME_GAIN) { |
521 | pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; | 557 | pC->u.vol.an_log[0] = phr->u.c.an_log_value[0]; |
522 | pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; | 558 | pC->u.vol.an_log[1] = phr->u.c.an_log_value[1]; |
523 | } | 559 | } |
524 | break; | 560 | break; |
525 | case HPI_CONTROL_MULTIPLEXER: | 561 | case HPI_CONTROL_MULTIPLEXER: |
526 | /* mux does not return its setting on Set command. */ | 562 | /* mux does not return its setting on Set command. */ |
527 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { | 563 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { |
528 | pC->u.x.source_node_type = (u16)phm->u.c.param1; | 564 | pC->u.mux.source_node_type = (u16)phm->u.c.param1; |
529 | pC->u.x.source_node_index = (u16)phm->u.c.param2; | 565 | pC->u.mux.source_node_index = (u16)phm->u.c.param2; |
530 | } | 566 | } |
531 | break; | 567 | break; |
532 | case HPI_CONTROL_CHANNEL_MODE: | 568 | case HPI_CONTROL_CHANNEL_MODE: |
533 | /* mode does not return its setting on Set command. */ | 569 | /* mode does not return its setting on Set command. */ |
534 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) | 570 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) |
535 | pC->u.m.mode = (u16)phm->u.c.param1; | 571 | pC->u.mode.mode = (u16)phm->u.c.param1; |
536 | break; | 572 | break; |
537 | case HPI_CONTROL_LEVEL: | 573 | case HPI_CONTROL_LEVEL: |
538 | if (phm->u.c.attribute == HPI_LEVEL_GAIN) { | 574 | if (phm->u.c.attribute == HPI_LEVEL_GAIN) { |
539 | pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; | 575 | pC->u.vol.an_log[0] = phr->u.c.an_log_value[0]; |
540 | pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; | 576 | pC->u.vol.an_log[1] = phr->u.c.an_log_value[1]; |
541 | } | 577 | } |
542 | break; | 578 | break; |
543 | case HPI_CONTROL_MICROPHONE: | 579 | case HPI_CONTROL_MICROPHONE: |
544 | if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) | 580 | if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) |
545 | pC->u.phantom_power.state = (u16)phm->u.c.param1; | 581 | pC->u.microphone.phantom_state = (u16)phm->u.c.param1; |
546 | break; | 582 | break; |
547 | case HPI_CONTROL_AESEBU_TRANSMITTER: | 583 | case HPI_CONTROL_AESEBU_TRANSMITTER: |
548 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) | 584 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) |
@@ -550,7 +586,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
550 | break; | 586 | break; |
551 | case HPI_CONTROL_AESEBU_RECEIVER: | 587 | case HPI_CONTROL_AESEBU_RECEIVER: |
552 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) | 588 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) |
553 | pC->u.aes3rx.source = phm->u.c.param1; | 589 | pC->u.aes3rx.format = phm->u.c.param1; |
554 | break; | 590 | break; |
555 | case HPI_CONTROL_SAMPLECLOCK: | 591 | case HPI_CONTROL_SAMPLECLOCK: |
556 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) | 592 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) |
@@ -566,8 +602,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
566 | } | 602 | } |
567 | 603 | ||
568 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 | 604 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 |
569 | number_of_controls, const u32 size_in_bytes, | 605 | number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer) |
570 | struct hpi_control_cache_info *pDSP_control_buffer) | ||
571 | { | 606 | { |
572 | struct hpi_control_cache *p_cache = | 607 | struct hpi_control_cache *p_cache = |
573 | kmalloc(sizeof(*p_cache), GFP_KERNEL); | 608 | kmalloc(sizeof(*p_cache), GFP_KERNEL); |
@@ -590,7 +625,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 | |||
590 | 625 | ||
591 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) | 626 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) |
592 | { | 627 | { |
593 | if (p_cache->init) { | 628 | if (p_cache) { |
594 | kfree(p_cache->p_info); | 629 | kfree(p_cache->p_info); |
595 | p_cache->p_info = NULL; | 630 | p_cache->p_info = NULL; |
596 | p_cache->init = 0; | 631 | p_cache->init = 0; |
@@ -600,24 +635,25 @@ void hpi_free_control_cache(struct hpi_control_cache *p_cache) | |||
600 | 635 | ||
601 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | 636 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) |
602 | { | 637 | { |
638 | hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0); | ||
603 | 639 | ||
604 | switch (phm->function) { | 640 | switch (phm->function) { |
605 | case HPI_SUBSYS_OPEN: | 641 | case HPI_SUBSYS_OPEN: |
606 | case HPI_SUBSYS_CLOSE: | 642 | case HPI_SUBSYS_CLOSE: |
607 | case HPI_SUBSYS_DRIVER_UNLOAD: | 643 | case HPI_SUBSYS_DRIVER_UNLOAD: |
608 | phr->error = 0; | ||
609 | break; | 644 | break; |
610 | case HPI_SUBSYS_DRIVER_LOAD: | 645 | case HPI_SUBSYS_DRIVER_LOAD: |
611 | wipe_adapter_list(); | 646 | wipe_adapter_list(); |
612 | hpios_alistlock_init(&adapters); | 647 | hpios_alistlock_init(&adapters); |
613 | phr->error = 0; | ||
614 | break; | 648 | break; |
615 | case HPI_SUBSYS_GET_INFO: | 649 | case HPI_SUBSYS_GET_ADAPTER: |
616 | subsys_get_adapters(phr); | 650 | subsys_get_adapter(phm, phr); |
651 | break; | ||
652 | case HPI_SUBSYS_GET_NUM_ADAPTERS: | ||
653 | phr->u.s.num_adapters = adapters.gw_num_adapters; | ||
617 | break; | 654 | break; |
618 | case HPI_SUBSYS_CREATE_ADAPTER: | 655 | case HPI_SUBSYS_CREATE_ADAPTER: |
619 | case HPI_SUBSYS_DELETE_ADAPTER: | 656 | case HPI_SUBSYS_DELETE_ADAPTER: |
620 | phr->error = 0; | ||
621 | break; | 657 | break; |
622 | default: | 658 | default: |
623 | phr->error = HPI_ERROR_INVALID_FUNC; | 659 | phr->error = HPI_ERROR_INVALID_FUNC; |