aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/asihpi/hpicmn.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/asihpi/hpicmn.c')
-rw-r--r--sound/pci/asihpi/hpicmn.c496
1 files changed, 278 insertions, 218 deletions
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index dda4f1c6f658..b15a02e91f82 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
31struct hpi_adapters_list { 33struct hpi_adapters_list {
@@ -43,14 +45,24 @@ static struct hpi_adapters_list adapters;
43**/ 45**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) 46u16 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\n", 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\n",
55 phr->object);
56 return HPI_ERROR_INVALID_RESPONSE;
57 }
47 58
48 if ((phr->type != HPI_TYPE_RESPONSE) 59 if (phr->function != phm->function) {
49 || (phr->object != phm->object) 60 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
50 || (phr->function != phm->function)) 61 phr->function);
51 error = HPI_ERROR_INVALID_RESPONSE; 62 return HPI_ERROR_INVALID_RESPONSE;
63 }
52 64
53 return error; 65 return 0;
54} 66}
55 67
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao) 68u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
@@ -66,8 +78,18 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
66 } 78 }
67 79
68 if (adapters.adapter[pao->index].adapter_type) { 80 if (adapters.adapter[pao->index].adapter_type) {
69 { 81 int a;
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER; 82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83 if (!adapters.adapter[a].adapter_type) {
84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n",
86 pao->adapter_type, pao->index, a);
87 pao->index = a;
88 break;
89 }
90 }
91 if (a < 0) {
92 retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock; 93 goto unlock;
72 } 94 }
73 } 95 }
@@ -76,17 +98,22 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
76 adapters.gw_num_adapters++; 98 adapters.gw_num_adapters++;
77 99
78unlock: 100unlock:
79 hpios_alistlock_un_lock(&adapters); 101 hpios_alistlock_unlock(&adapters);
80 return retval; 102 return retval;
81} 103}
82 104
83void hpi_delete_adapter(struct hpi_adapter_obj *pao) 105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{ 106{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj)); 107 if (!pao->adapter_type) {
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return;
110 }
86 111
87 hpios_alistlock_lock(&adapters); 112 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */ 113 if (adapters.adapter[pao->index].adapter_type)
89 hpios_alistlock_un_lock(&adapters); 114 adapters.gw_num_adapters--;
115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116 hpios_alistlock_unlock(&adapters);
90} 117}
91 118
92/** 119/**
@@ -99,7 +126,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
99 struct hpi_adapter_obj *pao = NULL; 126 struct hpi_adapter_obj *pao = NULL;
100 127
101 if (adapter_index >= HPI_MAX_ADAPTERS) { 128 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ", 129 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
103 adapter_index); 130 adapter_index);
104 return NULL; 131 return NULL;
105 } 132 }
@@ -125,51 +152,34 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
125* wipe an HPI_ADAPTERS_LIST structure. 152* wipe an HPI_ADAPTERS_LIST structure.
126* 153*
127**/ 154**/
128static void wipe_adapter_list(void 155static void wipe_adapter_list(void)
129 )
130{ 156{
131 memset(&adapters, 0, sizeof(adapters)); 157 memset(&adapters, 0, sizeof(adapters));
132} 158}
133 159
134/** 160static void subsys_get_adapter(struct hpi_message *phm,
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure 161 struct hpi_response *phr)
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{ 162{
141 /* fill in the response adapter array with the position */ 163 int count = phm->obj_index;
142 /* identified by the adapter number/index of the adapters in */ 164 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
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158 165
159 /* for each adapter, place it's type in the position of the array */ 166 /* find the nCount'th nonzero adapter in array */
160 /* corresponding to it's adapter number */ 167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
161 for (i = 0; i < adapters.gw_num_adapters; i++) { 168 if (adapters.adapter[index].adapter_type) {
162 pao = &adapters.adapter[i]; 169 if (!count)
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) { 170 break;
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER; 171 count--;
165 phr->specific_error = pao->index;
166 return;
167 } 172 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 } 173 }
170 174
171 phr->u.s.num_adapters = adapters.gw_num_adapters; 175 if (index < HPI_MAX_ADAPTERS) {
172 phr->error = 0; /* the function completed OK; */ 176 phr->u.s.adapter_index = adapters.adapter[index].index;
177 phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
178 } else {
179 phr->u.s.adapter_index = 0;
180 phr->u.s.adapter_type = 0;
181 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
182 }
173} 183}
174 184
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) 185static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
@@ -178,67 +188,99 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
178 int cached = 0; 188 int cached = 0;
179 if (!pC) 189 if (!pC)
180 return 0; 190 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count) 191
182 && (pC->cache_size_in_bytes) 192 if (pC->init)
183 ) { 193 return pC->init;
184 u32 *p_master_cache; 194
185 pC->init = 1; 195 if (!pC->p_cache)
186 196 return 0;
187 p_master_cache = (u32 *)pC->p_cache; 197
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n", 198 if (pC->control_count && pC->cache_size_in_bytes) {
199 char *p_master_cache;
200 unsigned int byte_count = 0;
201
202 p_master_cache = (char *)pC->p_cache;
203 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
189 pC->control_count); 204 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) { 205 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info = 206 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *) 207 (struct hpi_control_cache_info *)
193 p_master_cache; 208 &p_master_cache[byte_count];
209
210 if (!info->size_in32bit_words) {
211 if (!i) {
212 HPI_DEBUG_LOG(INFO,
213 "adap %d cache not ready?\n",
214 pC->adap_idx);
215 return 0;
216 }
217 /* The cache is invalid.
218 * Minimum valid entry size is
219 * sizeof(struct hpi_control_cache_info)
220 */
221 HPI_DEBUG_LOG(ERROR,
222 "adap %d zero size cache entry %d\n",
223 pC->adap_idx, i);
224 break;
225 }
194 226
195 if (info->control_type) { 227 if (info->control_type) {
196 pC->p_info[i] = info; 228 pC->p_info[info->control_index] = info;
197 cached++; 229 cached++;
198 } else 230 } else { /* dummy cache entry */
199 pC->p_info[i] = NULL; 231 pC->p_info[info->control_index] = NULL;
232 }
200 233
201 if (info->size_in32bit_words) 234 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 235
209 HPI_DEBUG_LOG(VERBOSE, 236 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n", 237 "cached %d, pinfo %p index %d type %d size %d\n",
211 cached, pC->p_info[i], info->control_index, 238 cached, pC->p_info[info->control_index],
212 info->control_type); 239 info->control_index, info->control_type,
240 info->size_in32bit_words);
241
242 /* quit loop early if whole cache has been scanned.
243 * dwControlCount is the maximum possible entries
244 * but some may be absent from the cache
245 */
246 if (byte_count >= pC->cache_size_in_bytes)
247 break;
248 /* have seen last control index */
249 if (info->control_index == pC->control_count - 1)
250 break;
213 } 251 }
214 /* 252
215 We didn't find anything to cache, so try again later ! 253 if (byte_count != pC->cache_size_in_bytes)
216 */ 254 HPI_DEBUG_LOG(WARNING,
217 if (!cached) 255 "adap %d bytecount %d != cache size %d\n",
218 pC->init = 0; 256 pC->adap_idx, byte_count,
257 pC->cache_size_in_bytes);
258 else
259 HPI_DEBUG_LOG(DEBUG,
260 "adap %d cache good, bytecount == cache size = %d\n",
261 pC->adap_idx, byte_count);
262
263 pC->init = (u16)cached;
219 } 264 }
220 return pC->init; 265 return pC->init;
221} 266}
222 267
223/** Find a control. 268/** Find a control.
224*/ 269*/
225static short find_control(struct hpi_message *phm, 270static short find_control(u16 control_index,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI, 271 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
227 u16 *pw_control_index)
228{ 272{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) { 273 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE, 274 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n", 275 "control_cache_alloc_check() failed %d\n",
234 phm->adapter_index, *pw_control_index); 276 control_index);
235 return 0; 277 return 0;
236 } 278 }
237 279
238 *pI = p_cache->p_info[*pw_control_index]; 280 *pI = p_cache->p_info[control_index];
239 if (!*pI) { 281 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n", 282 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
241 phm->adapter_index, *pw_control_index); 283 control_index);
242 return 0; 284 return 0;
243 } else { 285 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", 286 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
@@ -247,25 +289,6 @@ static short find_control(struct hpi_message *phm,
247 return 1; 289 return 1;
248} 290}
249 291
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */ 292/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\ 293#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \ 294 offsetof(struct hpi_control_cache_pad, m), \
@@ -276,7 +299,7 @@ struct pad_ofs_size {
276 unsigned int field_size; 299 unsigned int field_size;
277}; 300};
278 301
279static struct pad_ofs_size pad_desc[] = { 302static const struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ 303 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ 304 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ 305 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
@@ -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,79 @@ 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 if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
362 if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
363 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
364 phr->u.c.param1 =
365 HPI_BITMASK_ALL_CHANNELS;
366 else
367 phr->u.c.param1 = 0;
368 } else {
369 phr->error =
370 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
371 phr->u.c.param1 = 0;
372 }
373 } else {
326 found = 0; 374 found = 0;
375 }
327 break; 376 break;
328 case HPI_CONTROL_MULTIPLEXER: 377 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 378 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type; 379 phr->u.c.param1 = pC->u.mux.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index; 380 phr->u.c.param2 = pC->u.mux.source_node_index;
332 } else { 381 } else {
333 found = 0; 382 found = 0;
334 } 383 }
335 break; 384 break;
336 case HPI_CONTROL_CHANNEL_MODE: 385 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 386 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode; 387 phr->u.c.param1 = pC->u.mode.mode;
339 else 388 else
340 found = 0; 389 found = 0;
341 break; 390 break;
342 case HPI_CONTROL_LEVEL: 391 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 392 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0]; 393 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]; 394 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
346 } else 395 } else
347 found = 0; 396 found = 0;
348 break; 397 break;
349 case HPI_CONTROL_TUNER: 398 case HPI_CONTROL_TUNER:
350 if (phm->u.c.attribute == HPI_TUNER_FREQ) 399 if (phm->u.c.attribute == HPI_TUNER_FREQ)
351 phr->u.c.param1 = pC->u.t.freq_ink_hz; 400 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
352 else if (phm->u.c.attribute == HPI_TUNER_BAND) 401 else if (phm->u.c.attribute == HPI_TUNER_BAND)
353 phr->u.c.param1 = pC->u.t.band; 402 phr->u.c.param1 = pC->u.tuner.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) 403 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) 404 if (pC->u.tuner.s_level_avg ==
356 if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { 405 HPI_CACHE_INVALID_SHORT) {
357 phr->u.c.param1 = 0; 406 phr->u.cu.tuner.s_level = 0;
358 phr->error = 407 phr->error =
359 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 408 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
360 } else 409 } else
361 phr->u.c.param1 = pC->u.t.level; 410 phr->u.cu.tuner.s_level =
411 pC->u.tuner.s_level_avg;
362 else 412 else
363 found = 0; 413 found = 0;
364 break; 414 break;
@@ -366,7 +416,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) 416 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status; 417 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 418 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source; 419 phr->u.c.param1 = pC->u.aes3rx.format;
370 else 420 else
371 found = 0; 421 found = 0;
372 break; 422 break;
@@ -385,13 +435,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
385 case HPI_CONTROL_SILENCEDETECTOR: 435 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { 436 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state; 437 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else 438 } else
390 found = 0; 439 found = 0;
391 break; 440 break;
392 case HPI_CONTROL_MICROPHONE: 441 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 442 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state; 443 phr->u.c.param1 = pC->u.microphone.phantom_state;
395 else 444 else
396 found = 0; 445 found = 0;
397 break; 446 break;
@@ -400,7 +449,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
400 phr->u.c.param1 = pC->u.clk.source; 449 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { 450 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index == 451 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) { 452 HPI_CACHE_INVALID_UINT16) {
404 phr->u.c.param1 = 0; 453 phr->u.c.param1 = 0;
405 phr->error = 454 phr->error =
406 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 455 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
@@ -411,60 +460,63 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
411 else 460 else
412 found = 0; 461 found = 0;
413 break; 462 break;
414 case HPI_CONTROL_PAD: 463 case HPI_CONTROL_PAD:{
415 464 struct hpi_control_cache_pad *p_pad;
416 if (!(p_pad->field_valid_flags & (1 << 465 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 466
423 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) 467 if (!(p_pad->field_valid_flags & (1 <<
424 phr->u.c.param1 = p_pad->pI; 468 HPI_CTL_ATTR_INDEX(phm->u.c.
425 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) 469 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 = 470 phr->error =
440 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 471 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
441 break; 472 break;
442 } 473 }
443 474
444 pad_string = ((char *)p_pad) + pad_desc[index].offset; 475 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
445 field_size = pad_desc[index].field_size; 476 phr->u.c.param1 = p_pad->pI;
446 /* Ensure null terminator */ 477 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
447 pad_string[field_size - 1] = 0; 478 phr->u.c.param1 = p_pad->pTY;
448 479 else {
449 pad_string_len = strlen(pad_string) + 1; 480 unsigned int index =
450 481 HPI_CTL_ATTR_INDEX(phm->u.c.
451 if (offset > pad_string_len) { 482 attribute) - 1;
452 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; 483 unsigned int offset = phm->u.c.param1;
453 break; 484 unsigned int pad_string_len, field_size;
485 char *pad_string;
486 unsigned int tocopy;
487
488 if (index > ARRAY_SIZE(pad_desc) - 1) {
489 phr->error =
490 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
491 break;
492 }
493
494 pad_string =
495 ((char *)p_pad) +
496 pad_desc[index].offset;
497 field_size = pad_desc[index].field_size;
498 /* Ensure null terminator */
499 pad_string[field_size - 1] = 0;
500
501 pad_string_len = strlen(pad_string) + 1;
502
503 if (offset > pad_string_len) {
504 phr->error =
505 HPI_ERROR_INVALID_CONTROL_VALUE;
506 break;
507 }
508
509 tocopy = pad_string_len - offset;
510 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
511 tocopy = sizeof(phr->u.cu.chars8.
512 sz_data);
513
514 memcpy(phr->u.cu.chars8.sz_data,
515 &pad_string[offset], tocopy);
516
517 phr->u.cu.chars8.remaining_chars =
518 pad_string_len - offset - tocopy;
454 } 519 }
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 } 520 }
469 break; 521 break;
470 default: 522 default:
@@ -472,16 +524,9 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
472 break; 524 break;
473 } 525 }
474 526
475 if (found) 527 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
476 HPI_DEBUG_LOG(VERBOSE, 528 found ? "Cached" : "Uncached", phm->adapter_index,
477 "cached adap %d, ctl %d, type %d, attr %d\n", 529 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 530
486 if (found) 531 if (found)
487 phr->size = 532 phr->size =
@@ -497,18 +542,21 @@ Only update if no error.
497Volume and Level return the limited values in the response, so use these 542Volume and Level return the limited values in the response, so use these
498Multiplexer does so use sent values 543Multiplexer does so use sent values
499*/ 544*/
500void hpi_sync_control_cache(struct hpi_control_cache *p_cache, 545void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
501 struct hpi_message *phm, struct hpi_response *phr) 546 struct hpi_message *phm, struct hpi_response *phr)
502{ 547{
503 u16 control_index;
504 struct hpi_control_cache_single *pC; 548 struct hpi_control_cache_single *pC;
505 struct hpi_control_cache_info *pI; 549 struct hpi_control_cache_info *pI;
506 550
507 if (phr->error) 551 if (phr->error)
508 return; 552 return;
509 553
510 if (!find_control(phm, p_cache, &pI, &control_index)) 554 if (!find_control(phm->obj_index, p_cache, &pI)) {
555 HPI_DEBUG_LOG(VERBOSE,
556 "HPICMN find_control() failed for adap %d\n",
557 phm->adapter_index);
511 return; 558 return;
559 }
512 560
513 /* pC is the default cached control strucure. 561 /* pC is the default cached control strucure.
514 May be cast to something else in the following switch statement. 562 May be cast to something else in the following switch statement.
@@ -518,31 +566,36 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
518 switch (pI->control_type) { 566 switch (pI->control_type) {
519 case HPI_CONTROL_VOLUME: 567 case HPI_CONTROL_VOLUME:
520 if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 568 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
521 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 569 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]; 570 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
571 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
572 if (phm->u.c.param1)
573 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
574 else
575 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
523 } 576 }
524 break; 577 break;
525 case HPI_CONTROL_MULTIPLEXER: 578 case HPI_CONTROL_MULTIPLEXER:
526 /* mux does not return its setting on Set command. */ 579 /* mux does not return its setting on Set command. */
527 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 580 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
528 pC->u.x.source_node_type = (u16)phm->u.c.param1; 581 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
529 pC->u.x.source_node_index = (u16)phm->u.c.param2; 582 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
530 } 583 }
531 break; 584 break;
532 case HPI_CONTROL_CHANNEL_MODE: 585 case HPI_CONTROL_CHANNEL_MODE:
533 /* mode does not return its setting on Set command. */ 586 /* mode does not return its setting on Set command. */
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 587 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1; 588 pC->u.mode.mode = (u16)phm->u.c.param1;
536 break; 589 break;
537 case HPI_CONTROL_LEVEL: 590 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 591 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 592 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]; 593 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
541 } 594 }
542 break; 595 break;
543 case HPI_CONTROL_MICROPHONE: 596 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 597 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1; 598 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
546 break; 599 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER: 600 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) 601 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
@@ -550,7 +603,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
550 break; 603 break;
551 case HPI_CONTROL_AESEBU_RECEIVER: 604 case HPI_CONTROL_AESEBU_RECEIVER:
552 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 605 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
553 pC->u.aes3rx.source = phm->u.c.param1; 606 pC->u.aes3rx.format = phm->u.c.param1;
554 break; 607 break;
555 case HPI_CONTROL_SAMPLECLOCK: 608 case HPI_CONTROL_SAMPLECLOCK:
556 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) 609 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
@@ -565,53 +618,60 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
565 } 618 }
566} 619}
567 620
568struct hpi_control_cache *hpi_alloc_control_cache(const u32 621/** Allocate control cache.
569 number_of_controls, const u32 size_in_bytes, 622
570 struct hpi_control_cache_info *pDSP_control_buffer) 623\return Cache pointer, or NULL if allocation fails.
624*/
625struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
626 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
571{ 627{
572 struct hpi_control_cache *p_cache = 628 struct hpi_control_cache *p_cache =
573 kmalloc(sizeof(*p_cache), GFP_KERNEL); 629 kmalloc(sizeof(*p_cache), GFP_KERNEL);
630 if (!p_cache)
631 return NULL;
632
633 p_cache->p_info =
634 kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
635 if (!p_cache->p_info) {
636 kfree(p_cache);
637 return NULL;
638 }
639 memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
574 p_cache->cache_size_in_bytes = size_in_bytes; 640 p_cache->cache_size_in_bytes = size_in_bytes;
575 p_cache->control_count = number_of_controls; 641 p_cache->control_count = control_count;
576 p_cache->p_cache = 642 p_cache->p_cache = p_dsp_control_buffer;
577 (struct hpi_control_cache_single *)pDSP_control_buffer;
578 p_cache->init = 0; 643 p_cache->init = 0;
579 p_cache->p_info =
580 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
581 GFP_KERNEL);
582 return p_cache; 644 return p_cache;
583} 645}
584 646
585void hpi_free_control_cache(struct hpi_control_cache *p_cache) 647void hpi_free_control_cache(struct hpi_control_cache *p_cache)
586{ 648{
587 if (p_cache->init) { 649 if (p_cache) {
588 kfree(p_cache->p_info); 650 kfree(p_cache->p_info);
589 p_cache->p_info = NULL;
590 p_cache->init = 0;
591 kfree(p_cache); 651 kfree(p_cache);
592 } 652 }
593} 653}
594 654
595static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 655static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
596{ 656{
657 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
597 658
598 switch (phm->function) { 659 switch (phm->function) {
599 case HPI_SUBSYS_OPEN: 660 case HPI_SUBSYS_OPEN:
600 case HPI_SUBSYS_CLOSE: 661 case HPI_SUBSYS_CLOSE:
601 case HPI_SUBSYS_DRIVER_UNLOAD: 662 case HPI_SUBSYS_DRIVER_UNLOAD:
602 phr->error = 0;
603 break; 663 break;
604 case HPI_SUBSYS_DRIVER_LOAD: 664 case HPI_SUBSYS_DRIVER_LOAD:
605 wipe_adapter_list(); 665 wipe_adapter_list();
606 hpios_alistlock_init(&adapters); 666 hpios_alistlock_init(&adapters);
607 phr->error = 0;
608 break; 667 break;
609 case HPI_SUBSYS_GET_INFO: 668 case HPI_SUBSYS_GET_ADAPTER:
610 subsys_get_adapters(phr); 669 subsys_get_adapter(phm, phr);
670 break;
671 case HPI_SUBSYS_GET_NUM_ADAPTERS:
672 phr->u.s.num_adapters = adapters.gw_num_adapters;
611 break; 673 break;
612 case HPI_SUBSYS_CREATE_ADAPTER: 674 case HPI_SUBSYS_CREATE_ADAPTER:
613 case HPI_SUBSYS_DELETE_ADAPTER:
614 phr->error = 0;
615 break; 675 break;
616 default: 676 default:
617 phr->error = HPI_ERROR_INVALID_FUNC; 677 phr->error = HPI_ERROR_INVALID_FUNC;