~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to sound/pci/asihpi/hpicmn.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 
 
3
    AudioScience HPI driver
 
4
    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of version 2 of the GNU General Public License as
 
8
    published by the Free Software Foundation;
 
9
 
 
10
    This program is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this program; if not, write to the Free Software
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
\file hpicmn.c
 
20
 
 
21
 Common functions used by hpixxxx.c modules
 
22
 
 
23
(C) Copyright AudioScience Inc. 1998-2003
 
24
*******************************************************************************/
 
25
#define SOURCEFILE_NAME "hpicmn.c"
 
26
 
 
27
#include "hpi_internal.h"
 
28
#include "hpidebug.h"
 
29
#include "hpimsginit.h"
 
30
 
 
31
#include "hpicmn.h"
 
32
 
 
33
struct hpi_adapters_list {
 
34
        struct hpios_spinlock list_lock;
 
35
        struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
 
36
        u16 gw_num_adapters;
 
37
};
 
38
 
 
39
static struct hpi_adapters_list adapters;
 
40
 
 
41
/**
 
42
* Given an HPI Message that was sent out and a response that was received,
 
43
* validate that the response has the correct fields filled in,
 
44
* i.e ObjectType, Function etc
 
45
**/
 
46
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
 
47
{
 
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
        }
 
58
 
 
59
        if (phr->function != phm->function) {
 
60
                HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
 
61
                        phr->function);
 
62
                return HPI_ERROR_INVALID_RESPONSE;
 
63
        }
 
64
 
 
65
        return 0;
 
66
}
 
67
 
 
68
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
 
69
{
 
70
        u16 retval = 0;
 
71
        /*HPI_ASSERT(pao->wAdapterType); */
 
72
 
 
73
        hpios_alistlock_lock(&adapters);
 
74
 
 
75
        if (pao->index >= HPI_MAX_ADAPTERS) {
 
76
                retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
 
77
                goto unlock;
 
78
        }
 
79
 
 
80
        if (adapters.adapter[pao->index].adapter_type) {
 
81
                int a;
 
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;
 
93
                        goto unlock;
 
94
                }
 
95
        }
 
96
        adapters.adapter[pao->index] = *pao;
 
97
        hpios_dsplock_init(&adapters.adapter[pao->index]);
 
98
        adapters.gw_num_adapters++;
 
99
 
 
100
unlock:
 
101
        hpios_alistlock_unlock(&adapters);
 
102
        return retval;
 
103
}
 
104
 
 
105
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
 
106
{
 
107
        if (!pao->adapter_type) {
 
108
                HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
 
109
                return;
 
110
        }
 
111
 
 
112
        hpios_alistlock_lock(&adapters);
 
113
        if (adapters.adapter[pao->index].adapter_type)
 
114
                adapters.gw_num_adapters--;
 
115
        memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
 
116
        hpios_alistlock_unlock(&adapters);
 
117
}
 
118
 
 
119
/**
 
120
* FindAdapter returns a pointer to the struct hpi_adapter_obj with
 
121
* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
 
122
*
 
123
*/
 
124
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
 
125
{
 
126
        struct hpi_adapter_obj *pao = NULL;
 
127
 
 
128
        if (adapter_index >= HPI_MAX_ADAPTERS) {
 
129
                HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
 
130
                        adapter_index);
 
131
                return NULL;
 
132
        }
 
133
 
 
134
        pao = &adapters.adapter[adapter_index];
 
135
        if (pao->adapter_type != 0) {
 
136
                /*
 
137
                   HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
 
138
                   wAdapterIndex);
 
139
                 */
 
140
                return pao;
 
141
        } else {
 
142
                /*
 
143
                   HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
 
144
                   wAdapterIndex);
 
145
                 */
 
146
                return NULL;
 
147
        }
 
148
}
 
149
 
 
150
/**
 
151
*
 
152
* wipe an HPI_ADAPTERS_LIST structure.
 
153
*
 
154
**/
 
155
static void wipe_adapter_list(void)
 
156
{
 
157
        memset(&adapters, 0, sizeof(adapters));
 
158
}
 
159
 
 
160
static void subsys_get_adapter(struct hpi_message *phm,
 
161
        struct hpi_response *phr)
 
162
{
 
163
        int count = phm->obj_index;
 
164
        u16 index = 0;
 
165
 
 
166
        /* find the nCount'th nonzero adapter in array */
 
167
        for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
 
168
                if (adapters.adapter[index].adapter_type) {
 
169
                        if (!count)
 
170
                                break;
 
171
                        count--;
 
172
                }
 
173
        }
 
174
 
 
175
        if (index < HPI_MAX_ADAPTERS) {
 
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
        }
 
183
}
 
184
 
 
185
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
 
186
{
 
187
        unsigned int i;
 
188
        int cached = 0;
 
189
        if (!pC)
 
190
                return 0;
 
191
 
 
192
        if (pC->init)
 
193
                return pC->init;
 
194
 
 
195
        if (!pC->p_cache)
 
196
                return 0;
 
197
 
 
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",
 
204
                        pC->control_count);
 
205
                for (i = 0; i < pC->control_count; i++) {
 
206
                        struct hpi_control_cache_info *info =
 
207
                                (struct hpi_control_cache_info *)
 
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
                        }
 
226
 
 
227
                        if (info->control_type) {
 
228
                                pC->p_info[info->control_index] = info;
 
229
                                cached++;
 
230
                        } else {        /* dummy cache entry */
 
231
                                pC->p_info[info->control_index] = NULL;
 
232
                        }
 
233
 
 
234
                        byte_count += info->size_in32bit_words * 4;
 
235
 
 
236
                        HPI_DEBUG_LOG(VERBOSE,
 
237
                                "cached %d, pinfo %p index %d type %d size %d\n",
 
238
                                cached, pC->p_info[info->control_index],
 
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;
 
251
                }
 
252
 
 
253
                if (byte_count != pC->cache_size_in_bytes)
 
254
                        HPI_DEBUG_LOG(WARNING,
 
255
                                "adap %d bytecount %d != cache size %d\n",
 
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;
 
264
        }
 
265
        return pC->init;
 
266
}
 
267
 
 
268
/** Find a control.
 
269
*/
 
270
static short find_control(u16 control_index,
 
271
        struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
 
272
{
 
273
        if (!control_cache_alloc_check(p_cache)) {
 
274
                HPI_DEBUG_LOG(VERBOSE,
 
275
                        "control_cache_alloc_check() failed %d\n",
 
276
                        control_index);
 
277
                return 0;
 
278
        }
 
279
 
 
280
        *pI = p_cache->p_info[control_index];
 
281
        if (!*pI) {
 
282
                HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
 
283
                        control_index);
 
284
                return 0;
 
285
        } else {
 
286
                HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
 
287
                        (*pI)->control_type);
 
288
        }
 
289
        return 1;
 
290
}
 
291
 
 
292
/* allow unified treatment of several string fields within struct */
 
293
#define HPICMN_PAD_OFS_AND_SIZE(m)  {\
 
294
        offsetof(struct hpi_control_cache_pad, m), \
 
295
        sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
 
296
 
 
297
struct pad_ofs_size {
 
298
        unsigned int offset;
 
299
        unsigned int field_size;
 
300
};
 
301
 
 
302
static const struct pad_ofs_size pad_desc[] = {
 
303
        HPICMN_PAD_OFS_AND_SIZE(c_channel),     /* HPI_PAD_CHANNEL_NAME */
 
304
        HPICMN_PAD_OFS_AND_SIZE(c_artist),      /* HPI_PAD_ARTIST */
 
305
        HPICMN_PAD_OFS_AND_SIZE(c_title),       /* HPI_PAD_TITLE */
 
306
        HPICMN_PAD_OFS_AND_SIZE(c_comment),     /* HPI_PAD_COMMENT */
 
307
};
 
308
 
 
309
/** CheckControlCache checks the cache and fills the struct hpi_response
 
310
 * accordingly. It returns one if a cache hit occurred, zero otherwise.
 
311
 */
 
312
short hpi_check_control_cache(struct hpi_control_cache *p_cache,
 
313
        struct hpi_message *phm, struct hpi_response *phr)
 
314
{
 
315
        short found = 1;
 
316
        struct hpi_control_cache_info *pI;
 
317
        struct hpi_control_cache_single *pC;
 
318
        size_t response_size;
 
319
        if (!find_control(phm->obj_index, p_cache, &pI)) {
 
320
                HPI_DEBUG_LOG(VERBOSE,
 
321
                        "HPICMN find_control() failed for adap %d\n",
 
322
                        phm->adapter_index);
 
323
                return 0;
 
324
        }
 
325
 
 
326
        phr->error = 0;
 
327
 
 
328
        /* set the default response size */
 
329
        response_size =
 
330
                sizeof(struct hpi_response_header) +
 
331
                sizeof(struct hpi_control_res);
 
332
 
 
333
        /* pC is the default cached control strucure. May be cast to
 
334
           something else in the following switch statement.
 
335
         */
 
336
        pC = (struct hpi_control_cache_single *)pI;
 
337
 
 
338
        switch (pI->control_type) {
 
339
 
 
340
        case HPI_CONTROL_METER:
 
341
                if (phm->u.c.attribute == HPI_METER_PEAK) {
 
342
                        phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
 
343
                        phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
 
344
                } else if (phm->u.c.attribute == HPI_METER_RMS) {
 
345
                        if (pC->u.meter.an_logRMS[0] ==
 
346
                                HPI_CACHE_INVALID_SHORT) {
 
347
                                phr->error =
 
348
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
349
                                phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
 
350
                                phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
 
351
                        } else {
 
352
                                phr->u.c.an_log_value[0] =
 
353
                                        pC->u.meter.an_logRMS[0];
 
354
                                phr->u.c.an_log_value[1] =
 
355
                                        pC->u.meter.an_logRMS[1];
 
356
                        }
 
357
                } else
 
358
                        found = 0;
 
359
                break;
 
360
        case HPI_CONTROL_VOLUME:
 
361
                if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
 
362
                        phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
 
363
                        phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
 
364
                } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
 
365
                        if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
 
366
                                if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
 
367
                                        phr->u.c.param1 =
 
368
                                                HPI_BITMASK_ALL_CHANNELS;
 
369
                                else
 
370
                                        phr->u.c.param1 = 0;
 
371
                        } else {
 
372
                                phr->error =
 
373
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
374
                                phr->u.c.param1 = 0;
 
375
                        }
 
376
                } else {
 
377
                        found = 0;
 
378
                }
 
379
                break;
 
380
        case HPI_CONTROL_MULTIPLEXER:
 
381
                if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
 
382
                        phr->u.c.param1 = pC->u.mux.source_node_type;
 
383
                        phr->u.c.param2 = pC->u.mux.source_node_index;
 
384
                } else {
 
385
                        found = 0;
 
386
                }
 
387
                break;
 
388
        case HPI_CONTROL_CHANNEL_MODE:
 
389
                if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
 
390
                        phr->u.c.param1 = pC->u.mode.mode;
 
391
                else
 
392
                        found = 0;
 
393
                break;
 
394
        case HPI_CONTROL_LEVEL:
 
395
                if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
 
396
                        phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
 
397
                        phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
 
398
                } else
 
399
                        found = 0;
 
400
                break;
 
401
        case HPI_CONTROL_TUNER:
 
402
                if (phm->u.c.attribute == HPI_TUNER_FREQ)
 
403
                        phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
 
404
                else if (phm->u.c.attribute == HPI_TUNER_BAND)
 
405
                        phr->u.c.param1 = pC->u.tuner.band;
 
406
                else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
 
407
                        if (pC->u.tuner.s_level_avg ==
 
408
                                HPI_CACHE_INVALID_SHORT) {
 
409
                                phr->u.cu.tuner.s_level = 0;
 
410
                                phr->error =
 
411
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
412
                        } else
 
413
                                phr->u.cu.tuner.s_level =
 
414
                                        pC->u.tuner.s_level_avg;
 
415
                else
 
416
                        found = 0;
 
417
                break;
 
418
        case HPI_CONTROL_AESEBU_RECEIVER:
 
419
                if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
 
420
                        phr->u.c.param1 = pC->u.aes3rx.error_status;
 
421
                else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
 
422
                        phr->u.c.param1 = pC->u.aes3rx.format;
 
423
                else
 
424
                        found = 0;
 
425
                break;
 
426
        case HPI_CONTROL_AESEBU_TRANSMITTER:
 
427
                if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
 
428
                        phr->u.c.param1 = pC->u.aes3tx.format;
 
429
                else
 
430
                        found = 0;
 
431
                break;
 
432
        case HPI_CONTROL_TONEDETECTOR:
 
433
                if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
 
434
                        phr->u.c.param1 = pC->u.tone.state;
 
435
                else
 
436
                        found = 0;
 
437
                break;
 
438
        case HPI_CONTROL_SILENCEDETECTOR:
 
439
                if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
 
440
                        phr->u.c.param1 = pC->u.silence.state;
 
441
                } else
 
442
                        found = 0;
 
443
                break;
 
444
        case HPI_CONTROL_MICROPHONE:
 
445
                if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
 
446
                        phr->u.c.param1 = pC->u.microphone.phantom_state;
 
447
                else
 
448
                        found = 0;
 
449
                break;
 
450
        case HPI_CONTROL_SAMPLECLOCK:
 
451
                if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
 
452
                        phr->u.c.param1 = pC->u.clk.source;
 
453
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
 
454
                        if (pC->u.clk.source_index ==
 
455
                                HPI_CACHE_INVALID_UINT16) {
 
456
                                phr->u.c.param1 = 0;
 
457
                                phr->error =
 
458
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
459
                        } else
 
460
                                phr->u.c.param1 = pC->u.clk.source_index;
 
461
                } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
 
462
                        phr->u.c.param1 = pC->u.clk.sample_rate;
 
463
                else
 
464
                        found = 0;
 
465
                break;
 
466
        case HPI_CONTROL_PAD:{
 
467
                        struct hpi_control_cache_pad *p_pad;
 
468
                        p_pad = (struct hpi_control_cache_pad *)pI;
 
469
 
 
470
                        if (!(p_pad->field_valid_flags & (1 <<
 
471
                                                HPI_CTL_ATTR_INDEX(phm->u.c.
 
472
                                                        attribute)))) {
 
473
                                phr->error =
 
474
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
475
                                break;
 
476
                        }
 
477
 
 
478
                        if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
 
479
                                phr->u.c.param1 = p_pad->pI;
 
480
                        else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
 
481
                                phr->u.c.param1 = p_pad->pTY;
 
482
                        else {
 
483
                                unsigned int index =
 
484
                                        HPI_CTL_ATTR_INDEX(phm->u.c.
 
485
                                        attribute) - 1;
 
486
                                unsigned int offset = phm->u.c.param1;
 
487
                                unsigned int pad_string_len, field_size;
 
488
                                char *pad_string;
 
489
                                unsigned int tocopy;
 
490
 
 
491
                                if (index > ARRAY_SIZE(pad_desc) - 1) {
 
492
                                        phr->error =
 
493
                                                HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
494
                                        break;
 
495
                                }
 
496
 
 
497
                                pad_string =
 
498
                                        ((char *)p_pad) +
 
499
                                        pad_desc[index].offset;
 
500
                                field_size = pad_desc[index].field_size;
 
501
                                /* Ensure null terminator */
 
502
                                pad_string[field_size - 1] = 0;
 
503
 
 
504
                                pad_string_len = strlen(pad_string) + 1;
 
505
 
 
506
                                if (offset > pad_string_len) {
 
507
                                        phr->error =
 
508
                                                HPI_ERROR_INVALID_CONTROL_VALUE;
 
509
                                        break;
 
510
                                }
 
511
 
 
512
                                tocopy = pad_string_len - offset;
 
513
                                if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
 
514
                                        tocopy = sizeof(phr->u.cu.chars8.
 
515
                                                sz_data);
 
516
 
 
517
                                memcpy(phr->u.cu.chars8.sz_data,
 
518
                                        &pad_string[offset], tocopy);
 
519
 
 
520
                                phr->u.cu.chars8.remaining_chars =
 
521
                                        pad_string_len - offset - tocopy;
 
522
                        }
 
523
                }
 
524
                break;
 
525
        default:
 
526
                found = 0;
 
527
                break;
 
528
        }
 
529
 
 
530
        HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
 
531
                found ? "Cached" : "Uncached", phm->adapter_index,
 
532
                pI->control_index, pI->control_type, phm->u.c.attribute);
 
533
 
 
534
        if (found)
 
535
                phr->size = (u16)response_size;
 
536
 
 
537
        return found;
 
538
}
 
539
 
 
540
/** Updates the cache with Set values.
 
541
 
 
542
Only update if no error.
 
543
Volume and Level return the limited values in the response, so use these
 
544
Multiplexer does so use sent values
 
545
*/
 
546
void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
 
547
        struct hpi_message *phm, struct hpi_response *phr)
 
548
{
 
549
        struct hpi_control_cache_single *pC;
 
550
        struct hpi_control_cache_info *pI;
 
551
 
 
552
        if (phr->error)
 
553
                return;
 
554
 
 
555
        if (!find_control(phm->obj_index, p_cache, &pI)) {
 
556
                HPI_DEBUG_LOG(VERBOSE,
 
557
                        "HPICMN find_control() failed for adap %d\n",
 
558
                        phm->adapter_index);
 
559
                return;
 
560
        }
 
561
 
 
562
        /* pC is the default cached control strucure.
 
563
           May be cast to something else in the following switch statement.
 
564
         */
 
565
        pC = (struct hpi_control_cache_single *)pI;
 
566
 
 
567
        switch (pI->control_type) {
 
568
        case HPI_CONTROL_VOLUME:
 
569
                if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
 
570
                        pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
 
571
                        pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
 
572
                } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
 
573
                        if (phm->u.c.param1)
 
574
                                pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
 
575
                        else
 
576
                                pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
 
577
                }
 
578
                break;
 
579
        case HPI_CONTROL_MULTIPLEXER:
 
580
                /* mux does not return its setting on Set command. */
 
581
                if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
 
582
                        pC->u.mux.source_node_type = (u16)phm->u.c.param1;
 
583
                        pC->u.mux.source_node_index = (u16)phm->u.c.param2;
 
584
                }
 
585
                break;
 
586
        case HPI_CONTROL_CHANNEL_MODE:
 
587
                /* mode does not return its setting on Set command. */
 
588
                if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
 
589
                        pC->u.mode.mode = (u16)phm->u.c.param1;
 
590
                break;
 
591
        case HPI_CONTROL_LEVEL:
 
592
                if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
 
593
                        pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
 
594
                        pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
 
595
                }
 
596
                break;
 
597
        case HPI_CONTROL_MICROPHONE:
 
598
                if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
 
599
                        pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
 
600
                break;
 
601
        case HPI_CONTROL_AESEBU_TRANSMITTER:
 
602
                if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
 
603
                        pC->u.aes3tx.format = phm->u.c.param1;
 
604
                break;
 
605
        case HPI_CONTROL_AESEBU_RECEIVER:
 
606
                if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
 
607
                        pC->u.aes3rx.format = phm->u.c.param1;
 
608
                break;
 
609
        case HPI_CONTROL_SAMPLECLOCK:
 
610
                if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
 
611
                        pC->u.clk.source = (u16)phm->u.c.param1;
 
612
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
 
613
                        pC->u.clk.source_index = (u16)phm->u.c.param1;
 
614
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
 
615
                        pC->u.clk.sample_rate = phm->u.c.param1;
 
616
                break;
 
617
        default:
 
618
                break;
 
619
        }
 
620
}
 
621
 
 
622
/** Allocate control cache.
 
623
 
 
624
\return Cache pointer, or NULL if allocation fails.
 
625
*/
 
626
struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
 
627
        const u32 size_in_bytes, u8 *p_dsp_control_buffer)
 
628
{
 
629
        struct hpi_control_cache *p_cache =
 
630
                kmalloc(sizeof(*p_cache), GFP_KERNEL);
 
631
        if (!p_cache)
 
632
                return NULL;
 
633
 
 
634
        p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count,
 
635
                                  GFP_KERNEL);
 
636
        if (!p_cache->p_info) {
 
637
                kfree(p_cache);
 
638
                return NULL;
 
639
        }
 
640
        p_cache->cache_size_in_bytes = size_in_bytes;
 
641
        p_cache->control_count = control_count;
 
642
        p_cache->p_cache = p_dsp_control_buffer;
 
643
        p_cache->init = 0;
 
644
        return p_cache;
 
645
}
 
646
 
 
647
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
 
648
{
 
649
        if (p_cache) {
 
650
                kfree(p_cache->p_info);
 
651
                kfree(p_cache);
 
652
        }
 
653
}
 
654
 
 
655
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
 
656
{
 
657
        hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
 
658
 
 
659
        switch (phm->function) {
 
660
        case HPI_SUBSYS_OPEN:
 
661
        case HPI_SUBSYS_CLOSE:
 
662
        case HPI_SUBSYS_DRIVER_UNLOAD:
 
663
                break;
 
664
        case HPI_SUBSYS_DRIVER_LOAD:
 
665
                wipe_adapter_list();
 
666
                hpios_alistlock_init(&adapters);
 
667
                break;
 
668
        case HPI_SUBSYS_GET_ADAPTER:
 
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;
 
673
                break;
 
674
        case HPI_SUBSYS_CREATE_ADAPTER:
 
675
                break;
 
676
        default:
 
677
                phr->error = HPI_ERROR_INVALID_FUNC;
 
678
                break;
 
679
        }
 
680
}
 
681
 
 
682
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
 
683
{
 
684
        switch (phm->type) {
 
685
        case HPI_TYPE_REQUEST:
 
686
                switch (phm->object) {
 
687
                case HPI_OBJ_SUBSYSTEM:
 
688
                        subsys_message(phm, phr);
 
689
                        break;
 
690
                }
 
691
                break;
 
692
 
 
693
        default:
 
694
                phr->error = HPI_ERROR_INVALID_TYPE;
 
695
                break;
 
696
        }
 
697
}