~ubuntu-branches/ubuntu/precise/alsa-driver/precise

« back to all changes in this revision

Viewing changes to alsa-kernel/pci/asihpi/hpicmn.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2011-02-21 18:06:40 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20110221180640-a8p2yxtvgf7xbxub
Tags: 1.0.24+dfsg-0ubuntu1
* New upstream release
* Refreshed patches:
  - distinguish_kernel_makefile_and_source_dirs.patch
  - debian_dfsg_configure.patch
* debian/control: Update Vcs-bzr field to point to new branch location

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 "hpicmn.h"
 
30
 
 
31
struct hpi_adapters_list {
 
32
        struct hpios_spinlock list_lock;
 
33
        struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
 
34
        u16 gw_num_adapters;
 
35
};
 
36
 
 
37
static struct hpi_adapters_list adapters;
 
38
 
 
39
/**
 
40
* Given an HPI Message that was sent out and a response that was received,
 
41
* validate that the response has the correct fields filled in,
 
42
* i.e ObjectType, Function etc
 
43
**/
 
44
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
 
45
{
 
46
        u16 error = 0;
 
47
 
 
48
        if ((phr->type != HPI_TYPE_RESPONSE)
 
49
                || (phr->object != phm->object)
 
50
                || (phr->function != phm->function))
 
51
                error = HPI_ERROR_INVALID_RESPONSE;
 
52
 
 
53
        return error;
 
54
}
 
55
 
 
56
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
 
57
{
 
58
        u16 retval = 0;
 
59
        /*HPI_ASSERT(pao->wAdapterType); */
 
60
 
 
61
        hpios_alistlock_lock(&adapters);
 
62
 
 
63
        if (pao->index >= HPI_MAX_ADAPTERS) {
 
64
                retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
 
65
                goto unlock;
 
66
        }
 
67
 
 
68
        if (adapters.adapter[pao->index].adapter_type) {
 
69
                {
 
70
                        retval = HPI_DUPLICATE_ADAPTER_NUMBER;
 
71
                        goto unlock;
 
72
                }
 
73
        }
 
74
        adapters.adapter[pao->index] = *pao;
 
75
        hpios_dsplock_init(&adapters.adapter[pao->index]);
 
76
        adapters.gw_num_adapters++;
 
77
 
 
78
unlock:
 
79
        hpios_alistlock_un_lock(&adapters);
 
80
        return retval;
 
81
}
 
82
 
 
83
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
 
84
{
 
85
        memset(pao, 0, sizeof(struct hpi_adapter_obj));
 
86
 
 
87
        hpios_alistlock_lock(&adapters);
 
88
        adapters.gw_num_adapters--;     /* dec the number of adapters */
 
89
        hpios_alistlock_un_lock(&adapters);
 
90
}
 
91
 
 
92
/**
 
93
* FindAdapter returns a pointer to the struct hpi_adapter_obj with
 
94
* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
 
95
*
 
96
*/
 
97
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
 
98
{
 
99
        struct hpi_adapter_obj *pao = NULL;
 
100
 
 
101
        if (adapter_index >= HPI_MAX_ADAPTERS) {
 
102
                HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
 
103
                        adapter_index);
 
104
                return NULL;
 
105
        }
 
106
 
 
107
        pao = &adapters.adapter[adapter_index];
 
108
        if (pao->adapter_type != 0) {
 
109
                /*
 
110
                   HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
 
111
                   wAdapterIndex);
 
112
                 */
 
113
                return pao;
 
114
        } else {
 
115
                /*
 
116
                   HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
 
117
                   wAdapterIndex);
 
118
                 */
 
119
                return NULL;
 
120
        }
 
121
}
 
122
 
 
123
/**
 
124
*
 
125
* wipe an HPI_ADAPTERS_LIST structure.
 
126
*
 
127
**/
 
128
static void wipe_adapter_list(void
 
129
        )
 
130
{
 
131
        memset(&adapters, 0, sizeof(adapters));
 
132
}
 
133
 
 
134
/**
 
135
* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
 
136
* with all adapters in the given HPI_ADAPTERS_LIST.
 
137
*
 
138
*/
 
139
static void subsys_get_adapters(struct hpi_response *phr)
 
140
{
 
141
        /* fill in the response adapter array with the position */
 
142
        /* identified by the adapter number/index of the adapters in */
 
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
 
 
159
        /* for each adapter, place it's type in the position of the array */
 
160
        /* corresponding to it's adapter number */
 
161
        for (i = 0; i < adapters.gw_num_adapters; i++) {
 
162
                pao = &adapters.adapter[i];
 
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
                }
 
168
                phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
 
169
        }
 
170
 
 
171
        phr->u.s.num_adapters = adapters.gw_num_adapters;
 
172
        phr->error = 0; /* the function completed OK; */
 
173
}
 
174
 
 
175
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
 
176
{
 
177
        unsigned int i;
 
178
        int cached = 0;
 
179
        if (!pC)
 
180
                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
 
 
187
                p_master_cache = (u32 *)pC->p_cache;
 
188
                HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
 
189
                        pC->control_count);
 
190
                for (i = 0; i < pC->control_count; i++) {
 
191
                        struct hpi_control_cache_info *info =
 
192
                                (struct hpi_control_cache_info *)
 
193
                                p_master_cache;
 
194
 
 
195
                        if (info->control_type) {
 
196
                                pC->p_info[i] = info;
 
197
                                cached++;
 
198
                        } else
 
199
                                pC->p_info[i] = NULL;
 
200
 
 
201
                        if (info->size_in32bit_words)
 
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
 
 
209
                        HPI_DEBUG_LOG(VERBOSE,
 
210
                                "cached %d, pinfo %p index %d type %d\n",
 
211
                                cached, pC->p_info[i], info->control_index,
 
212
                                info->control_type);
 
213
                }
 
214
                /*
 
215
                   We didn't find anything to cache, so try again later !
 
216
                 */
 
217
                if (!cached)
 
218
                        pC->init = 0;
 
219
        }
 
220
        return pC->init;
 
221
}
 
222
 
 
223
/** Find a control.
 
224
*/
 
225
static short find_control(struct hpi_message *phm,
 
226
        struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
 
227
        u16 *pw_control_index)
 
228
{
 
229
        *pw_control_index = phm->obj_index;
 
230
 
 
231
        if (!control_cache_alloc_check(p_cache)) {
 
232
                HPI_DEBUG_LOG(VERBOSE,
 
233
                        "control_cache_alloc_check() failed. adap%d ci%d\n",
 
234
                        phm->adapter_index, *pw_control_index);
 
235
                return 0;
 
236
        }
 
237
 
 
238
        *pI = p_cache->p_info[*pw_control_index];
 
239
        if (!*pI) {
 
240
                HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
 
241
                        phm->adapter_index, *pw_control_index);
 
242
                return 0;
 
243
        } else {
 
244
                HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
 
245
                        (*pI)->control_type);
 
246
        }
 
247
        return 1;
 
248
}
 
249
 
 
250
/** Used by the kernel driver to figure out if a buffer needs mapping.
 
251
 */
 
252
short 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 */
 
270
#define HPICMN_PAD_OFS_AND_SIZE(m)  {\
 
271
        offsetof(struct hpi_control_cache_pad, m), \
 
272
        sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
 
273
 
 
274
struct pad_ofs_size {
 
275
        unsigned int offset;
 
276
        unsigned int field_size;
 
277
};
 
278
 
 
279
static struct pad_ofs_size pad_desc[] = {
 
280
        HPICMN_PAD_OFS_AND_SIZE(c_channel),     /* HPI_PAD_CHANNEL_NAME */
 
281
        HPICMN_PAD_OFS_AND_SIZE(c_artist),      /* HPI_PAD_ARTIST */
 
282
        HPICMN_PAD_OFS_AND_SIZE(c_title),       /* HPI_PAD_TITLE */
 
283
        HPICMN_PAD_OFS_AND_SIZE(c_comment),     /* HPI_PAD_COMMENT */
 
284
};
 
285
 
 
286
/** CheckControlCache checks the cache and fills the struct hpi_response
 
287
 * accordingly. It returns one if a cache hit occurred, zero otherwise.
 
288
 */
 
289
short hpi_check_control_cache(struct hpi_control_cache *p_cache,
 
290
        struct hpi_message *phm, struct hpi_response *phr)
 
291
{
 
292
        short found = 1;
 
293
        u16 control_index;
 
294
        struct hpi_control_cache_info *pI;
 
295
        struct hpi_control_cache_single *pC;
 
296
        struct hpi_control_cache_pad *p_pad;
 
297
 
 
298
        if (!find_control(phm, p_cache, &pI, &control_index))
 
299
                return 0;
 
300
 
 
301
        phr->error = 0;
 
302
 
 
303
        /* pC is the default cached control strucure. May be cast to
 
304
           something else in the following switch statement.
 
305
         */
 
306
        pC = (struct hpi_control_cache_single *)pI;
 
307
        p_pad = (struct hpi_control_cache_pad *)pI;
 
308
 
 
309
        switch (pI->control_type) {
 
310
 
 
311
        case HPI_CONTROL_METER:
 
312
                if (phm->u.c.attribute == HPI_METER_PEAK) {
 
313
                        phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
 
314
                        phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
 
315
                } else if (phm->u.c.attribute == HPI_METER_RMS) {
 
316
                        phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
 
317
                        phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
 
318
                } else
 
319
                        found = 0;
 
320
                break;
 
321
        case HPI_CONTROL_VOLUME:
 
322
                if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
 
323
                        phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
 
324
                        phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
 
325
                } else
 
326
                        found = 0;
 
327
                break;
 
328
        case HPI_CONTROL_MULTIPLEXER:
 
329
                if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
 
330
                        phr->u.c.param1 = pC->u.x.source_node_type;
 
331
                        phr->u.c.param2 = pC->u.x.source_node_index;
 
332
                } else {
 
333
                        found = 0;
 
334
                }
 
335
                break;
 
336
        case HPI_CONTROL_CHANNEL_MODE:
 
337
                if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
 
338
                        phr->u.c.param1 = pC->u.m.mode;
 
339
                else
 
340
                        found = 0;
 
341
                break;
 
342
        case HPI_CONTROL_LEVEL:
 
343
                if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
 
344
                        phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
 
345
                        phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
 
346
                } else
 
347
                        found = 0;
 
348
                break;
 
349
        case HPI_CONTROL_TUNER:
 
350
                if (phm->u.c.attribute == HPI_TUNER_FREQ)
 
351
                        phr->u.c.param1 = pC->u.t.freq_ink_hz;
 
352
                else if (phm->u.c.attribute == HPI_TUNER_BAND)
 
353
                        phr->u.c.param1 = pC->u.t.band;
 
354
                else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
 
355
                        && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
 
356
                        if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
 
357
                                phr->u.c.param1 = 0;
 
358
                                phr->error =
 
359
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
360
                        } else
 
361
                                phr->u.c.param1 = pC->u.t.level;
 
362
                else
 
363
                        found = 0;
 
364
                break;
 
365
        case HPI_CONTROL_AESEBU_RECEIVER:
 
366
                if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
 
367
                        phr->u.c.param1 = pC->u.aes3rx.error_status;
 
368
                else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
 
369
                        phr->u.c.param1 = pC->u.aes3rx.source;
 
370
                else
 
371
                        found = 0;
 
372
                break;
 
373
        case HPI_CONTROL_AESEBU_TRANSMITTER:
 
374
                if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
 
375
                        phr->u.c.param1 = pC->u.aes3tx.format;
 
376
                else
 
377
                        found = 0;
 
378
                break;
 
379
        case HPI_CONTROL_TONEDETECTOR:
 
380
                if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
 
381
                        phr->u.c.param1 = pC->u.tone.state;
 
382
                else
 
383
                        found = 0;
 
384
                break;
 
385
        case HPI_CONTROL_SILENCEDETECTOR:
 
386
                if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
 
387
                        phr->u.c.param1 = pC->u.silence.state;
 
388
                        phr->u.c.param2 = pC->u.silence.count;
 
389
                } else
 
390
                        found = 0;
 
391
                break;
 
392
        case HPI_CONTROL_MICROPHONE:
 
393
                if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
 
394
                        phr->u.c.param1 = pC->u.phantom_power.state;
 
395
                else
 
396
                        found = 0;
 
397
                break;
 
398
        case HPI_CONTROL_SAMPLECLOCK:
 
399
                if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
 
400
                        phr->u.c.param1 = pC->u.clk.source;
 
401
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
 
402
                        if (pC->u.clk.source_index ==
 
403
                                HPI_ERROR_ILLEGAL_CACHE_VALUE) {
 
404
                                phr->u.c.param1 = 0;
 
405
                                phr->error =
 
406
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
407
                        } else
 
408
                                phr->u.c.param1 = pC->u.clk.source_index;
 
409
                } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
 
410
                        phr->u.c.param1 = pC->u.clk.sample_rate;
 
411
                else
 
412
                        found = 0;
 
413
                break;
 
414
        case HPI_CONTROL_PAD:
 
415
 
 
416
                if (!(p_pad->field_valid_flags & (1 <<
 
417
                                        HPI_CTL_ATTR_INDEX(phm->u.c.
 
418
                                                attribute)))) {
 
419
                        phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
420
                        break;
 
421
                }
 
422
 
 
423
                if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
 
424
                        phr->u.c.param1 = p_pad->pI;
 
425
                else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
 
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 =
 
440
                                        HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
 
441
                                break;
 
442
                        }
 
443
 
 
444
                        pad_string = ((char *)p_pad) + pad_desc[index].offset;
 
445
                        field_size = pad_desc[index].field_size;
 
446
                        /* Ensure null terminator */
 
447
                        pad_string[field_size - 1] = 0;
 
448
 
 
449
                        pad_string_len = strlen(pad_string) + 1;
 
450
 
 
451
                        if (offset > pad_string_len) {
 
452
                                phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
 
453
                                break;
 
454
                        }
 
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
                }
 
469
                break;
 
470
        default:
 
471
                found = 0;
 
472
                break;
 
473
        }
 
474
 
 
475
        if (found)
 
476
                HPI_DEBUG_LOG(VERBOSE,
 
477
                        "cached adap %d, ctl %d, type %d, attr %d\n",
 
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
 
 
486
        if (found)
 
487
                phr->size =
 
488
                        sizeof(struct hpi_response_header) +
 
489
                        sizeof(struct hpi_control_res);
 
490
 
 
491
        return found;
 
492
}
 
493
 
 
494
/** Updates the cache with Set values.
 
495
 
 
496
Only update if no error.
 
497
Volume and Level return the limited values in the response, so use these
 
498
Multiplexer does so use sent values
 
499
*/
 
500
void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
 
501
        struct hpi_message *phm, struct hpi_response *phr)
 
502
{
 
503
        u16 control_index;
 
504
        struct hpi_control_cache_single *pC;
 
505
        struct hpi_control_cache_info *pI;
 
506
 
 
507
        if (phr->error)
 
508
                return;
 
509
 
 
510
        if (!find_control(phm, p_cache, &pI, &control_index))
 
511
                return;
 
512
 
 
513
        /* pC is the default cached control strucure.
 
514
           May be cast to something else in the following switch statement.
 
515
         */
 
516
        pC = (struct hpi_control_cache_single *)pI;
 
517
 
 
518
        switch (pI->control_type) {
 
519
        case HPI_CONTROL_VOLUME:
 
520
                if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
 
521
                        pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
 
522
                        pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
 
523
                }
 
524
                break;
 
525
        case HPI_CONTROL_MULTIPLEXER:
 
526
                /* mux does not return its setting on Set command. */
 
527
                if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
 
528
                        pC->u.x.source_node_type = (u16)phm->u.c.param1;
 
529
                        pC->u.x.source_node_index = (u16)phm->u.c.param2;
 
530
                }
 
531
                break;
 
532
        case HPI_CONTROL_CHANNEL_MODE:
 
533
                /* mode does not return its setting on Set command. */
 
534
                if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
 
535
                        pC->u.m.mode = (u16)phm->u.c.param1;
 
536
                break;
 
537
        case HPI_CONTROL_LEVEL:
 
538
                if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
 
539
                        pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
 
540
                        pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
 
541
                }
 
542
                break;
 
543
        case HPI_CONTROL_MICROPHONE:
 
544
                if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
 
545
                        pC->u.phantom_power.state = (u16)phm->u.c.param1;
 
546
                break;
 
547
        case HPI_CONTROL_AESEBU_TRANSMITTER:
 
548
                if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
 
549
                        pC->u.aes3tx.format = phm->u.c.param1;
 
550
                break;
 
551
        case HPI_CONTROL_AESEBU_RECEIVER:
 
552
                if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
 
553
                        pC->u.aes3rx.source = phm->u.c.param1;
 
554
                break;
 
555
        case HPI_CONTROL_SAMPLECLOCK:
 
556
                if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
 
557
                        pC->u.clk.source = (u16)phm->u.c.param1;
 
558
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
 
559
                        pC->u.clk.source_index = (u16)phm->u.c.param1;
 
560
                else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
 
561
                        pC->u.clk.sample_rate = phm->u.c.param1;
 
562
                break;
 
563
        default:
 
564
                break;
 
565
        }
 
566
}
 
567
 
 
568
struct hpi_control_cache *hpi_alloc_control_cache(const u32
 
569
        number_of_controls, const u32 size_in_bytes,
 
570
        struct hpi_control_cache_info *pDSP_control_buffer)
 
571
{
 
572
        struct hpi_control_cache *p_cache =
 
573
                kmalloc(sizeof(*p_cache), GFP_KERNEL);
 
574
        if (!p_cache)
 
575
                return NULL;
 
576
        p_cache->p_info =
 
577
                kmalloc(sizeof(*p_cache->p_info) * number_of_controls,
 
578
                        GFP_KERNEL);
 
579
        if (!p_cache->p_info) {
 
580
                kfree(p_cache);
 
581
                return NULL;
 
582
        }
 
583
        p_cache->cache_size_in_bytes = size_in_bytes;
 
584
        p_cache->control_count = number_of_controls;
 
585
        p_cache->p_cache =
 
586
                (struct hpi_control_cache_single *)pDSP_control_buffer;
 
587
        p_cache->init = 0;
 
588
        return p_cache;
 
589
}
 
590
 
 
591
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
 
592
{
 
593
        if (p_cache->init) {
 
594
                kfree(p_cache->p_info);
 
595
                p_cache->p_info = NULL;
 
596
                p_cache->init = 0;
 
597
                kfree(p_cache);
 
598
        }
 
599
}
 
600
 
 
601
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
 
602
{
 
603
 
 
604
        switch (phm->function) {
 
605
        case HPI_SUBSYS_OPEN:
 
606
        case HPI_SUBSYS_CLOSE:
 
607
        case HPI_SUBSYS_DRIVER_UNLOAD:
 
608
                phr->error = 0;
 
609
                break;
 
610
        case HPI_SUBSYS_DRIVER_LOAD:
 
611
                wipe_adapter_list();
 
612
                hpios_alistlock_init(&adapters);
 
613
                phr->error = 0;
 
614
                break;
 
615
        case HPI_SUBSYS_GET_INFO:
 
616
                subsys_get_adapters(phr);
 
617
                break;
 
618
        case HPI_SUBSYS_CREATE_ADAPTER:
 
619
        case HPI_SUBSYS_DELETE_ADAPTER:
 
620
                phr->error = 0;
 
621
                break;
 
622
        default:
 
623
                phr->error = HPI_ERROR_INVALID_FUNC;
 
624
                break;
 
625
        }
 
626
}
 
627
 
 
628
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
 
629
{
 
630
        switch (phm->type) {
 
631
        case HPI_TYPE_MESSAGE:
 
632
                switch (phm->object) {
 
633
                case HPI_OBJ_SUBSYSTEM:
 
634
                        subsys_message(phm, phr);
 
635
                        break;
 
636
                }
 
637
                break;
 
638
 
 
639
        default:
 
640
                phr->error = HPI_ERROR_INVALID_TYPE;
 
641
                break;
 
642
        }
 
643
}