ALSA: ctxfi - Add subsystem option
[deliverable/linux.git] / sound / pci / ctxfi / ctatc.c
CommitLineData
8cc72361
WYC
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctatc.c
9 *
10 * @Brief
11 * This file contains the implementation of the device resource management
12 * object.
13 *
14 * @Author Liu Chun
15 * @Date Mar 28 2008
16 */
17
18#include "ctatc.h"
19#include "ctpcm.h"
20#include "ctmixer.h"
8cc72361
WYC
21#include "cthardware.h"
22#include "ctsrc.h"
23#include "ctamixer.h"
24#include "ctdaio.h"
b7bbf876 25#include "cttimer.h"
8cc72361
WYC
26#include <linux/delay.h>
27#include <sound/pcm.h>
28#include <sound/control.h>
29#include <sound/asoundef.h>
30
31#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
32#define DAIONUM 7
33#define MAX_MULTI_CHN 8
34
35#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
36 | IEC958_AES0_CON_NOT_COPYRIGHT) \
37 | ((IEC958_AES1_CON_MIXER \
38 | IEC958_AES1_CON_ORIGINAL) << 8) \
39 | (0x10 << 16) \
40 | ((IEC958_AES3_CON_FS_48000) << 24))
41
9470195a
TI
42static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
43 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
44 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
45 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
46 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
09521d2e
TI
47 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
48 "UAA", CTUAA),
9470195a 49 { } /* terminator */
8cc72361
WYC
50};
51
9470195a
TI
52static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
53 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
54 "SB0760", CTSB0760),
55 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
56 "SB0880", CTSB0880),
57 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
58 "SB0880", CTSB0880),
59 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803,
60 "SB0880", CTSB0880),
09521d2e
TI
61 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000,
62 PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX",
63 CTHENDRIX),
9470195a
TI
64 { } /* terminator */
65};
66
67static const char *ct_subsys_name[NUM_CTCARDS] = {
a8f4310b 68 /* 20k1 models */
9470195a
TI
69 [CTSB055X] = "SB055x",
70 [CTSB073X] = "SB073x",
9470195a
TI
71 [CTUAA] = "UAA",
72 [CT20K1_UNKNOWN] = "Unknown",
a8f4310b
TI
73 /* 20k2 models */
74 [CTSB0760] = "SB076x",
9470195a
TI
75 [CTHENDRIX] = "Hendrix",
76 [CTSB0880] = "SB0880",
a8f4310b 77 [CT20K2_UNKNOWN] = "Unknown",
8cc72361
WYC
78};
79
80static struct {
81 int (*create)(struct ct_atc *atc,
82 enum CTALSADEVS device, const char *device_name);
83 int (*destroy)(void *alsa_dev);
84 const char *public_name;
85} alsa_dev_funcs[NUM_CTALSADEVS] = {
86 [FRONT] = { .create = ct_alsa_pcm_create,
87 .destroy = NULL,
88 .public_name = "Front/WaveIn"},
8372d498 89 [SURROUND] = { .create = ct_alsa_pcm_create,
8cc72361 90 .destroy = NULL,
8372d498 91 .public_name = "Surround"},
8cc72361
WYC
92 [CLFE] = { .create = ct_alsa_pcm_create,
93 .destroy = NULL,
94 .public_name = "Center/LFE"},
8372d498 95 [SIDE] = { .create = ct_alsa_pcm_create,
8cc72361 96 .destroy = NULL,
8372d498 97 .public_name = "Side"},
8cc72361
WYC
98 [IEC958] = { .create = ct_alsa_pcm_create,
99 .destroy = NULL,
100 .public_name = "IEC958 Non-audio"},
101
102 [MIXER] = { .create = ct_alsa_mix_create,
103 .destroy = NULL,
104 .public_name = "Mixer"}
105};
106
107typedef int (*create_t)(void *, void **);
108typedef int (*destroy_t)(void *);
109
110static struct {
111 int (*create)(void *hw, void **rmgr);
112 int (*destroy)(void *mgr);
113} rsc_mgr_funcs[NUM_RSCTYP] = {
114 [SRC] = { .create = (create_t)src_mgr_create,
115 .destroy = (destroy_t)src_mgr_destroy },
116 [SRCIMP] = { .create = (create_t)srcimp_mgr_create,
117 .destroy = (destroy_t)srcimp_mgr_destroy },
118 [AMIXER] = { .create = (create_t)amixer_mgr_create,
119 .destroy = (destroy_t)amixer_mgr_destroy },
120 [SUM] = { .create = (create_t)sum_mgr_create,
121 .destroy = (destroy_t)sum_mgr_destroy },
122 [DAIO] = { .create = (create_t)daio_mgr_create,
123 .destroy = (destroy_t)daio_mgr_destroy }
124};
125
126static int
127atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm);
128
129/* *
130 * Only mono and interleaved modes are supported now.
131 * Always allocates a contiguous channel block.
132 * */
133
134static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
135{
8cc72361
WYC
136 struct snd_pcm_runtime *runtime;
137 struct ct_vm *vm;
138
35ebf6e7 139 if (!apcm->substream)
8cc72361
WYC
140 return 0;
141
142 runtime = apcm->substream->runtime;
143 vm = atc->vm;
144
c76157d9 145 apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
8cc72361 146
35ebf6e7 147 if (!apcm->vm_block)
8cc72361
WYC
148 return -ENOENT;
149
150 return 0;
151}
152
153static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
154{
8cc72361
WYC
155 struct ct_vm *vm;
156
35ebf6e7 157 if (!apcm->vm_block)
8cc72361
WYC
158 return;
159
160 vm = atc->vm;
161
8cc72361 162 vm->unmap(vm, apcm->vm_block);
8cc72361
WYC
163
164 apcm->vm_block = NULL;
165}
166
167static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
168{
169 struct ct_vm *vm;
170 void *kvirt_addr;
171 unsigned long phys_addr;
8cc72361 172
8cc72361
WYC
173 vm = atc->vm;
174 kvirt_addr = vm->get_ptp_virt(vm, index);
175 if (kvirt_addr == NULL)
176 phys_addr = (~0UL);
177 else
178 phys_addr = virt_to_phys(kvirt_addr);
179
8cc72361
WYC
180 return phys_addr;
181}
182
183static unsigned int convert_format(snd_pcm_format_t snd_format)
184{
185 switch (snd_format) {
186 case SNDRV_PCM_FORMAT_U8:
8cc72361
WYC
187 return SRC_SF_U8;
188 case SNDRV_PCM_FORMAT_S16_LE:
8cc72361
WYC
189 return SRC_SF_S16;
190 case SNDRV_PCM_FORMAT_S24_3LE:
191 return SRC_SF_S24;
8cc72361
WYC
192 case SNDRV_PCM_FORMAT_S32_LE:
193 return SRC_SF_S32;
d2b9b96c
TI
194 case SNDRV_PCM_FORMAT_FLOAT_LE:
195 return SRC_SF_F32;
8cc72361 196 default:
b3e0afe6 197 printk(KERN_ERR "ctxfi: not recognized snd format is %d \n",
8cc72361
WYC
198 snd_format);
199 return SRC_SF_S16;
200 }
201}
202
203static unsigned int
204atc_get_pitch(unsigned int input_rate, unsigned int output_rate)
205{
514eef9c
TI
206 unsigned int pitch;
207 int b;
8cc72361
WYC
208
209 /* get pitch and convert to fixed-point 8.24 format. */
210 pitch = (input_rate / output_rate) << 24;
211 input_rate %= output_rate;
212 input_rate /= 100;
213 output_rate /= 100;
214 for (b = 31; ((b >= 0) && !(input_rate >> b)); )
215 b--;
216
217 if (b >= 0) {
218 input_rate <<= (31 - b);
219 input_rate /= output_rate;
220 b = 24 - (31 - b);
221 if (b >= 0)
222 input_rate <<= b;
223 else
224 input_rate >>= -b;
225
226 pitch |= input_rate;
227 }
228
229 return pitch;
230}
231
232static int select_rom(unsigned int pitch)
233{
35ebf6e7 234 if (pitch > 0x00428f5c && pitch < 0x01b851ec) {
8cc72361
WYC
235 /* 0.26 <= pitch <= 1.72 */
236 return 1;
35ebf6e7 237 } else if (pitch == 0x01d66666 || pitch == 0x01d66667) {
8cc72361
WYC
238 /* pitch == 1.8375 */
239 return 2;
35ebf6e7 240 } else if (pitch == 0x02000000) {
8cc72361
WYC
241 /* pitch == 2 */
242 return 3;
84ed1a19 243 } else if (pitch <= 0x08000000) {
8cc72361
WYC
244 /* 0 <= pitch <= 8 */
245 return 0;
246 } else {
247 return -ENOENT;
248 }
249}
250
251static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
252{
253 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
254 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
255 struct src_desc desc = {0};
256 struct amixer_desc mix_dsc = {0};
514eef9c
TI
257 struct src *src;
258 struct amixer *amixer;
259 int err;
8cc72361
WYC
260 int n_amixer = apcm->substream->runtime->channels, i = 0;
261 int device = apcm->substream->pcm->device;
514eef9c 262 unsigned int pitch;
8cc72361 263
822fa19b 264 /* first release old resources */
29959a09 265 atc_pcm_release_resources(atc, apcm);
822fa19b 266
8cc72361
WYC
267 /* Get SRC resource */
268 desc.multi = apcm->substream->runtime->channels;
269 desc.msr = atc->msr;
270 desc.mode = MEMRD;
271 err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
272 if (err)
273 goto error1;
274
275 pitch = atc_get_pitch(apcm->substream->runtime->rate,
276 (atc->rsr * atc->msr));
277 src = apcm->src;
278 src->ops->set_pitch(src, pitch);
279 src->ops->set_rom(src, select_rom(pitch));
280 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
281 src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
282
283 /* Get AMIXER resource */
284 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
285 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
35ebf6e7 286 if (!apcm->amixers) {
8cc72361
WYC
287 err = -ENOMEM;
288 goto error1;
289 }
290 mix_dsc.msr = atc->msr;
291 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
292 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
293 (struct amixer **)&apcm->amixers[i]);
294 if (err)
295 goto error1;
296
297 apcm->n_amixer++;
298 }
299
300 /* Set up device virtual mem map */
301 err = ct_map_audio_buffer(atc, apcm);
302 if (err < 0)
303 goto error1;
304
305 /* Connect resources */
306 src = apcm->src;
307 for (i = 0; i < n_amixer; i++) {
308 amixer = apcm->amixers[i];
635c265f 309 mutex_lock(&atc->atc_mutex);
8cc72361
WYC
310 amixer->ops->setup(amixer, &src->rsc,
311 INIT_VOL, atc->pcm[i+device*2]);
635c265f 312 mutex_unlock(&atc->atc_mutex);
8cc72361 313 src = src->ops->next_interleave(src);
35ebf6e7 314 if (!src)
8cc72361
WYC
315 src = apcm->src;
316 }
317
b7bbf876
TI
318 ct_timer_prepare(apcm->timer);
319
8cc72361
WYC
320 return 0;
321
322error1:
323 atc_pcm_release_resources(atc, apcm);
324 return err;
325}
326
327static int
328atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
329{
330 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
331 struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
332 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
333 struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
514eef9c
TI
334 struct srcimp *srcimp;
335 int i;
8cc72361 336
35ebf6e7 337 if (apcm->srcimps) {
8cc72361
WYC
338 for (i = 0; i < apcm->n_srcimp; i++) {
339 srcimp = apcm->srcimps[i];
340 srcimp->ops->unmap(srcimp);
341 srcimp_mgr->put_srcimp(srcimp_mgr, srcimp);
342 apcm->srcimps[i] = NULL;
343 }
344 kfree(apcm->srcimps);
345 apcm->srcimps = NULL;
346 }
347
35ebf6e7 348 if (apcm->srccs) {
8cc72361
WYC
349 for (i = 0; i < apcm->n_srcc; i++) {
350 src_mgr->put_src(src_mgr, apcm->srccs[i]);
351 apcm->srccs[i] = NULL;
352 }
353 kfree(apcm->srccs);
354 apcm->srccs = NULL;
355 }
356
35ebf6e7 357 if (apcm->amixers) {
8cc72361
WYC
358 for (i = 0; i < apcm->n_amixer; i++) {
359 amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]);
360 apcm->amixers[i] = NULL;
361 }
362 kfree(apcm->amixers);
363 apcm->amixers = NULL;
364 }
365
35ebf6e7 366 if (apcm->mono) {
8cc72361
WYC
367 sum_mgr->put_sum(sum_mgr, apcm->mono);
368 apcm->mono = NULL;
369 }
370
35ebf6e7 371 if (apcm->src) {
8cc72361
WYC
372 src_mgr->put_src(src_mgr, apcm->src);
373 apcm->src = NULL;
374 }
375
35ebf6e7 376 if (apcm->vm_block) {
8cc72361
WYC
377 /* Undo device virtual mem map */
378 ct_unmap_audio_buffer(atc, apcm);
379 apcm->vm_block = NULL;
380 }
381
382 return 0;
383}
384
385static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
386{
514eef9c 387 unsigned int max_cisz;
8cc72361
WYC
388 struct src *src = apcm->src;
389
c399f3be
TI
390 if (apcm->started)
391 return 0;
392 apcm->started = 1;
393
8cc72361
WYC
394 max_cisz = src->multi * src->rsc.msr;
395 max_cisz = 0x80 * (max_cisz < 8 ? max_cisz : 8);
396
397 src->ops->set_sa(src, apcm->vm_block->addr);
398 src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
399 src->ops->set_ca(src, apcm->vm_block->addr + max_cisz);
400 src->ops->set_cisz(src, max_cisz);
401
402 src->ops->set_bm(src, 1);
403 src->ops->set_state(src, SRC_STATE_INIT);
404 src->ops->commit_write(src);
405
b7bbf876 406 ct_timer_start(apcm->timer);
8cc72361
WYC
407 return 0;
408}
409
410static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
411{
514eef9c
TI
412 struct src *src;
413 int i;
8cc72361 414
b7bbf876
TI
415 ct_timer_stop(apcm->timer);
416
8cc72361
WYC
417 src = apcm->src;
418 src->ops->set_bm(src, 0);
419 src->ops->set_state(src, SRC_STATE_OFF);
420 src->ops->commit_write(src);
421
35ebf6e7 422 if (apcm->srccs) {
8cc72361
WYC
423 for (i = 0; i < apcm->n_srcc; i++) {
424 src = apcm->srccs[i];
425 src->ops->set_bm(src, 0);
426 src->ops->set_state(src, SRC_STATE_OFF);
427 src->ops->commit_write(src);
428 }
429 }
430
431 apcm->started = 0;
432
433 return 0;
434}
435
436static int
437atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
438{
439 struct src *src = apcm->src;
514eef9c
TI
440 u32 size, max_cisz;
441 int position;
8cc72361 442
5242bc76
TI
443 if (!src)
444 return 0;
8cc72361
WYC
445 position = src->ops->get_ca(src);
446
447 size = apcm->vm_block->size;
448 max_cisz = src->multi * src->rsc.msr;
449 max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
450
451 return (position + size - max_cisz - apcm->vm_block->addr) % size;
452}
453
454struct src_node_conf_t {
455 unsigned int pitch;
456 unsigned int msr:8;
457 unsigned int mix_msr:8;
458 unsigned int imp_msr:8;
459 unsigned int vo:1;
460};
461
462static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
463 struct src_node_conf_t *conf, int *n_srcc)
464{
514eef9c 465 unsigned int pitch;
8cc72361
WYC
466
467 /* get pitch and convert to fixed-point 8.24 format. */
468 pitch = atc_get_pitch((atc->rsr * atc->msr),
469 apcm->substream->runtime->rate);
470 *n_srcc = 0;
471
472 if (1 == atc->msr) {
473 *n_srcc = apcm->substream->runtime->channels;
474 conf[0].pitch = pitch;
475 conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
476 conf[0].vo = 1;
477 } else if (2 == atc->msr) {
478 if (0x8000000 < pitch) {
479 /* Need two-stage SRCs, SRCIMPs and
480 * AMIXERs for converting format */
481 conf[0].pitch = (atc->msr << 24);
482 conf[0].msr = conf[0].mix_msr = 1;
483 conf[0].imp_msr = atc->msr;
484 conf[0].vo = 0;
485 conf[1].pitch = atc_get_pitch(atc->rsr,
486 apcm->substream->runtime->rate);
487 conf[1].msr = conf[1].mix_msr = conf[1].imp_msr = 1;
488 conf[1].vo = 1;
489 *n_srcc = apcm->substream->runtime->channels * 2;
490 } else if (0x1000000 < pitch) {
491 /* Need one-stage SRCs, SRCIMPs and
492 * AMIXERs for converting format */
493 conf[0].pitch = pitch;
494 conf[0].msr = conf[0].mix_msr
495 = conf[0].imp_msr = atc->msr;
496 conf[0].vo = 1;
497 *n_srcc = apcm->substream->runtime->channels;
498 }
499 }
500}
501
502static int
503atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
504{
505 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
506 struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
507 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
508 struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
509 struct src_desc src_dsc = {0};
514eef9c 510 struct src *src;
8cc72361 511 struct srcimp_desc srcimp_dsc = {0};
514eef9c 512 struct srcimp *srcimp;
8cc72361
WYC
513 struct amixer_desc mix_dsc = {0};
514 struct sum_desc sum_dsc = {0};
514eef9c
TI
515 unsigned int pitch;
516 int multi, err, i;
517 int n_srcimp, n_amixer, n_srcc, n_sum;
8cc72361
WYC
518 struct src_node_conf_t src_node_conf[2] = {{0} };
519
822fa19b 520 /* first release old resources */
a5990dc5 521 atc_pcm_release_resources(atc, apcm);
822fa19b 522
8cc72361
WYC
523 /* The numbers of converting SRCs and SRCIMPs should be determined
524 * by pitch value. */
525
526 multi = apcm->substream->runtime->channels;
527
528 /* get pitch and convert to fixed-point 8.24 format. */
529 pitch = atc_get_pitch((atc->rsr * atc->msr),
530 apcm->substream->runtime->rate);
531
532 setup_src_node_conf(atc, apcm, src_node_conf, &n_srcc);
533 n_sum = (1 == multi) ? 1 : 0;
514eef9c
TI
534 n_amixer = n_sum * 2 + n_srcc;
535 n_srcimp = n_srcc;
8cc72361
WYC
536 if ((multi > 1) && (0x8000000 >= pitch)) {
537 /* Need extra AMIXERs and SRCIMPs for special treatment
538 * of interleaved recording of conjugate channels */
539 n_amixer += multi * atc->msr;
540 n_srcimp += multi * atc->msr;
541 } else {
542 n_srcimp += multi;
543 }
544
545 if (n_srcc) {
546 apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL);
35ebf6e7 547 if (!apcm->srccs)
8cc72361
WYC
548 return -ENOMEM;
549 }
550 if (n_amixer) {
551 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
35ebf6e7 552 if (!apcm->amixers) {
8cc72361
WYC
553 err = -ENOMEM;
554 goto error1;
555 }
556 }
557 apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
35ebf6e7 558 if (!apcm->srcimps) {
8cc72361
WYC
559 err = -ENOMEM;
560 goto error1;
561 }
562
563 /* Allocate SRCs for sample rate conversion if needed */
564 src_dsc.multi = 1;
565 src_dsc.mode = ARCRW;
566 for (i = 0, apcm->n_srcc = 0; i < n_srcc; i++) {
567 src_dsc.msr = src_node_conf[i/multi].msr;
568 err = src_mgr->get_src(src_mgr, &src_dsc,
569 (struct src **)&apcm->srccs[i]);
570 if (err)
571 goto error1;
572
573 src = apcm->srccs[i];
574 pitch = src_node_conf[i/multi].pitch;
575 src->ops->set_pitch(src, pitch);
576 src->ops->set_rom(src, select_rom(pitch));
577 src->ops->set_vo(src, src_node_conf[i/multi].vo);
578
579 apcm->n_srcc++;
580 }
581
582 /* Allocate AMIXERs for routing SRCs of conversion if needed */
583 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
584 if (i < (n_sum*2))
585 mix_dsc.msr = atc->msr;
586 else if (i < (n_sum*2+n_srcc))
587 mix_dsc.msr = src_node_conf[(i-n_sum*2)/multi].mix_msr;
588 else
589 mix_dsc.msr = 1;
590
591 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
592 (struct amixer **)&apcm->amixers[i]);
593 if (err)
594 goto error1;
595
596 apcm->n_amixer++;
597 }
598
599 /* Allocate a SUM resource to mix all input channels together */
600 sum_dsc.msr = atc->msr;
601 err = sum_mgr->get_sum(sum_mgr, &sum_dsc, (struct sum **)&apcm->mono);
602 if (err)
603 goto error1;
604
605 pitch = atc_get_pitch((atc->rsr * atc->msr),
606 apcm->substream->runtime->rate);
607 /* Allocate SRCIMP resources */
608 for (i = 0, apcm->n_srcimp = 0; i < n_srcimp; i++) {
609 if (i < (n_srcc))
610 srcimp_dsc.msr = src_node_conf[i/multi].imp_msr;
611 else if (1 == multi)
612 srcimp_dsc.msr = (pitch <= 0x8000000) ? atc->msr : 1;
613 else
614 srcimp_dsc.msr = 1;
615
616 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, &srcimp);
617 if (err)
618 goto error1;
619
620 apcm->srcimps[i] = srcimp;
621 apcm->n_srcimp++;
622 }
623
624 /* Allocate a SRC for writing data to host memory */
625 src_dsc.multi = apcm->substream->runtime->channels;
626 src_dsc.msr = 1;
627 src_dsc.mode = MEMWR;
628 err = src_mgr->get_src(src_mgr, &src_dsc, (struct src **)&apcm->src);
629 if (err)
630 goto error1;
631
632 src = apcm->src;
633 src->ops->set_pitch(src, pitch);
634
635 /* Set up device virtual mem map */
636 err = ct_map_audio_buffer(atc, apcm);
637 if (err < 0)
638 goto error1;
639
640 return 0;
641
642error1:
643 atc_pcm_release_resources(atc, apcm);
644 return err;
645}
646
647static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
648{
514eef9c
TI
649 struct src *src;
650 struct amixer *amixer;
651 struct srcimp *srcimp;
8cc72361 652 struct ct_mixer *mixer = atc->mixer;
514eef9c 653 struct sum *mono;
8cc72361 654 struct rsc *out_ports[8] = {NULL};
514eef9c
TI
655 int err, i, j, n_sum, multi;
656 unsigned int pitch;
8cc72361
WYC
657 int mix_base = 0, imp_base = 0;
658
29959a09 659 atc_pcm_release_resources(atc, apcm);
8cc72361
WYC
660
661 /* Get needed resources. */
662 err = atc_pcm_capture_get_resources(atc, apcm);
663 if (err)
664 return err;
665
666 /* Connect resources */
667 mixer->get_output_ports(mixer, MIX_PCMO_FRONT,
668 &out_ports[0], &out_ports[1]);
669
670 multi = apcm->substream->runtime->channels;
671 if (1 == multi) {
672 mono = apcm->mono;
673 for (i = 0; i < 2; i++) {
674 amixer = apcm->amixers[i];
675 amixer->ops->setup(amixer, out_ports[i],
676 MONO_SUM_SCALE, mono);
677 }
678 out_ports[0] = &mono->rsc;
679 n_sum = 1;
680 mix_base = n_sum * 2;
681 }
682
683 for (i = 0; i < apcm->n_srcc; i++) {
684 src = apcm->srccs[i];
685 srcimp = apcm->srcimps[imp_base+i];
686 amixer = apcm->amixers[mix_base+i];
687 srcimp->ops->map(srcimp, src, out_ports[i%multi]);
688 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
689 out_ports[i%multi] = &amixer->rsc;
690 }
691
692 pitch = atc_get_pitch((atc->rsr * atc->msr),
693 apcm->substream->runtime->rate);
694
695 if ((multi > 1) && (pitch <= 0x8000000)) {
696 /* Special connection for interleaved
697 * recording with conjugate channels */
698 for (i = 0; i < multi; i++) {
699 out_ports[i]->ops->master(out_ports[i]);
700 for (j = 0; j < atc->msr; j++) {
701 amixer = apcm->amixers[apcm->n_srcc+j*multi+i];
702 amixer->ops->set_input(amixer, out_ports[i]);
703 amixer->ops->set_scale(amixer, INIT_VOL);
704 amixer->ops->set_sum(amixer, NULL);
705 amixer->ops->commit_raw_write(amixer);
706 out_ports[i]->ops->next_conj(out_ports[i]);
707
708 srcimp = apcm->srcimps[apcm->n_srcc+j*multi+i];
709 srcimp->ops->map(srcimp, apcm->src,
710 &amixer->rsc);
711 }
712 }
713 } else {
714 for (i = 0; i < multi; i++) {
715 srcimp = apcm->srcimps[apcm->n_srcc+i];
716 srcimp->ops->map(srcimp, apcm->src, out_ports[i]);
717 }
718 }
719
b7bbf876
TI
720 ct_timer_prepare(apcm->timer);
721
8cc72361
WYC
722 return 0;
723}
724
725static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
726{
514eef9c 727 struct src *src;
8cc72361 728 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
514eef9c 729 int i, multi;
8cc72361
WYC
730
731 if (apcm->started)
732 return 0;
733
734 apcm->started = 1;
735 multi = apcm->substream->runtime->channels;
736 /* Set up converting SRCs */
737 for (i = 0; i < apcm->n_srcc; i++) {
738 src = apcm->srccs[i];
739 src->ops->set_pm(src, ((i%multi) != (multi-1)));
740 src_mgr->src_disable(src_mgr, src);
741 }
742
743 /* Set up recording SRC */
744 src = apcm->src;
745 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
746 src->ops->set_sa(src, apcm->vm_block->addr);
747 src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
748 src->ops->set_ca(src, apcm->vm_block->addr);
749 src_mgr->src_disable(src_mgr, src);
750
751 /* Disable relevant SRCs firstly */
752 src_mgr->commit_write(src_mgr);
753
754 /* Enable SRCs respectively */
755 for (i = 0; i < apcm->n_srcc; i++) {
756 src = apcm->srccs[i];
757 src->ops->set_state(src, SRC_STATE_RUN);
758 src->ops->commit_write(src);
759 src_mgr->src_enable_s(src_mgr, src);
760 }
761 src = apcm->src;
762 src->ops->set_bm(src, 1);
763 src->ops->set_state(src, SRC_STATE_RUN);
764 src->ops->commit_write(src);
765 src_mgr->src_enable_s(src_mgr, src);
766
767 /* Enable relevant SRCs synchronously */
768 src_mgr->commit_write(src_mgr);
769
b7bbf876 770 ct_timer_start(apcm->timer);
8cc72361
WYC
771 return 0;
772}
773
774static int
775atc_pcm_capture_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
776{
777 struct src *src = apcm->src;
778
5242bc76
TI
779 if (!src)
780 return 0;
8cc72361
WYC
781 return src->ops->get_ca(src) - apcm->vm_block->addr;
782}
783
784static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
785 struct ct_atc_pcm *apcm)
786{
787 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
788 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
789 struct src_desc desc = {0};
790 struct amixer_desc mix_dsc = {0};
514eef9c
TI
791 struct src *src;
792 int err;
793 int n_amixer = apcm->substream->runtime->channels, i;
794 unsigned int pitch, rsr = atc->pll_rate;
8cc72361 795
822fa19b 796 /* first release old resources */
a5990dc5 797 atc_pcm_release_resources(atc, apcm);
822fa19b 798
8cc72361
WYC
799 /* Get SRC resource */
800 desc.multi = apcm->substream->runtime->channels;
801 desc.msr = 1;
802 while (apcm->substream->runtime->rate > (rsr * desc.msr))
803 desc.msr <<= 1;
804
805 desc.mode = MEMRD;
806 err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
807 if (err)
808 goto error1;
809
810 pitch = atc_get_pitch(apcm->substream->runtime->rate, (rsr * desc.msr));
811 src = apcm->src;
812 src->ops->set_pitch(src, pitch);
813 src->ops->set_rom(src, select_rom(pitch));
814 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
815 src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
816 src->ops->set_bp(src, 1);
817
818 /* Get AMIXER resource */
819 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
820 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
35ebf6e7 821 if (!apcm->amixers) {
8cc72361
WYC
822 err = -ENOMEM;
823 goto error1;
824 }
825 mix_dsc.msr = desc.msr;
826 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
827 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
828 (struct amixer **)&apcm->amixers[i]);
829 if (err)
830 goto error1;
831
832 apcm->n_amixer++;
833 }
834
835 /* Set up device virtual mem map */
836 err = ct_map_audio_buffer(atc, apcm);
837 if (err < 0)
838 goto error1;
839
840 return 0;
841
842error1:
843 atc_pcm_release_resources(atc, apcm);
844 return err;
845}
846
514eef9c
TI
847static int atc_pll_init(struct ct_atc *atc, int rate)
848{
849 struct hw *hw = atc->hw;
850 int err;
851 err = hw->pll_init(hw, rate);
852 atc->pll_rate = err ? 0 : rate;
853 return err;
854}
855
8cc72361
WYC
856static int
857spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
858{
859 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
8cc72361 860 unsigned int rate = apcm->substream->runtime->rate;
514eef9c 861 unsigned int status;
29959a09 862 int err = 0;
514eef9c 863 unsigned char iec958_con_fs;
8cc72361
WYC
864
865 switch (rate) {
866 case 48000:
867 iec958_con_fs = IEC958_AES3_CON_FS_48000;
868 break;
869 case 44100:
870 iec958_con_fs = IEC958_AES3_CON_FS_44100;
871 break;
872 case 32000:
873 iec958_con_fs = IEC958_AES3_CON_FS_32000;
874 break;
875 default:
876 return -ENOENT;
877 }
878
635c265f 879 mutex_lock(&atc->atc_mutex);
8cc72361
WYC
880 dao->ops->get_spos(dao, &status);
881 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
882 status &= ((~IEC958_AES3_CON_FS) << 24);
883 status |= (iec958_con_fs << 24);
884 dao->ops->set_spos(dao, status);
885 dao->ops->commit_write(dao);
886 }
514eef9c
TI
887 if ((rate != atc->pll_rate) && (32000 != rate))
888 err = atc_pll_init(atc, rate);
635c265f 889 mutex_unlock(&atc->atc_mutex);
8cc72361
WYC
890
891 return err;
892}
893
894static int
895spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
896{
514eef9c
TI
897 struct src *src;
898 struct amixer *amixer;
899 struct dao *dao;
900 int err;
901 int i;
8cc72361 902
29959a09 903 atc_pcm_release_resources(atc, apcm);
8cc72361
WYC
904
905 /* Configure SPDIFOO and PLL to passthrough mode;
906 * determine pll_rate. */
907 err = spdif_passthru_playback_setup(atc, apcm);
908 if (err)
909 return err;
910
911 /* Get needed resources. */
912 err = spdif_passthru_playback_get_resources(atc, apcm);
913 if (err)
914 return err;
915
916 /* Connect resources */
917 src = apcm->src;
918 for (i = 0; i < apcm->n_amixer; i++) {
919 amixer = apcm->amixers[i];
920 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
921 src = src->ops->next_interleave(src);
35ebf6e7 922 if (!src)
8cc72361
WYC
923 src = apcm->src;
924 }
925 /* Connect to SPDIFOO */
635c265f 926 mutex_lock(&atc->atc_mutex);
8cc72361
WYC
927 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
928 amixer = apcm->amixers[0];
929 dao->ops->set_left_input(dao, &amixer->rsc);
930 amixer = apcm->amixers[1];
931 dao->ops->set_right_input(dao, &amixer->rsc);
635c265f 932 mutex_unlock(&atc->atc_mutex);
8cc72361 933
b7bbf876
TI
934 ct_timer_prepare(apcm->timer);
935
8cc72361
WYC
936 return 0;
937}
938
939static int atc_select_line_in(struct ct_atc *atc)
940{
941 struct hw *hw = atc->hw;
942 struct ct_mixer *mixer = atc->mixer;
514eef9c 943 struct src *src;
8cc72361
WYC
944
945 if (hw->is_adc_source_selected(hw, ADC_LINEIN))
946 return 0;
947
948 mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
949 mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
950
951 hw->select_adc_source(hw, ADC_LINEIN);
952
953 src = atc->srcs[2];
954 mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
955 src = atc->srcs[3];
956 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
957
958 return 0;
959}
960
961static int atc_select_mic_in(struct ct_atc *atc)
962{
963 struct hw *hw = atc->hw;
964 struct ct_mixer *mixer = atc->mixer;
514eef9c 965 struct src *src;
8cc72361
WYC
966
967 if (hw->is_adc_source_selected(hw, ADC_MICIN))
968 return 0;
969
970 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
971 mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
972
973 hw->select_adc_source(hw, ADC_MICIN);
974
975 src = atc->srcs[2];
976 mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
977 src = atc->srcs[3];
978 mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
979
980 return 0;
981}
982
983static int atc_have_digit_io_switch(struct ct_atc *atc)
984{
985 struct hw *hw = atc->hw;
986
987 return hw->have_digit_io_switch(hw);
988}
989
990static int atc_select_digit_io(struct ct_atc *atc)
991{
992 struct hw *hw = atc->hw;
993
994 if (hw->is_adc_source_selected(hw, ADC_NONE))
995 return 0;
996
997 hw->select_adc_source(hw, ADC_NONE);
998
999 return 0;
1000}
1001
1002static int atc_daio_unmute(struct ct_atc *atc, unsigned char state, int type)
1003{
1004 struct daio_mgr *daio_mgr = atc->rsc_mgrs[DAIO];
1005
1006 if (state)
1007 daio_mgr->daio_enable(daio_mgr, atc->daios[type]);
1008 else
1009 daio_mgr->daio_disable(daio_mgr, atc->daios[type]);
1010
1011 daio_mgr->commit_write(daio_mgr);
1012
1013 return 0;
1014}
1015
1016static int
1017atc_dao_get_status(struct ct_atc *atc, unsigned int *status, int type)
1018{
1019 struct dao *dao = container_of(atc->daios[type], struct dao, daio);
1020 return dao->ops->get_spos(dao, status);
1021}
1022
1023static int
1024atc_dao_set_status(struct ct_atc *atc, unsigned int status, int type)
1025{
1026 struct dao *dao = container_of(atc->daios[type], struct dao, daio);
1027
1028 dao->ops->set_spos(dao, status);
1029 dao->ops->commit_write(dao);
1030 return 0;
1031}
1032
1033static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
1034{
1035 return atc_daio_unmute(atc, state, LINEO1);
1036}
1037
1038static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
1039{
3b04691c 1040 return atc_daio_unmute(atc, state, LINEO2);
8cc72361
WYC
1041}
1042
1043static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
1044{
1045 return atc_daio_unmute(atc, state, LINEO3);
1046}
1047
1048static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
1049{
3b04691c 1050 return atc_daio_unmute(atc, state, LINEO4);
8cc72361
WYC
1051}
1052
1053static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
1054{
1055 return atc_daio_unmute(atc, state, LINEIM);
1056}
1057
1058static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
1059{
1060 return atc_daio_unmute(atc, state, SPDIFOO);
1061}
1062
1063static int atc_spdif_in_unmute(struct ct_atc *atc, unsigned char state)
1064{
1065 return atc_daio_unmute(atc, state, SPDIFIO);
1066}
1067
1068static int atc_spdif_out_get_status(struct ct_atc *atc, unsigned int *status)
1069{
1070 return atc_dao_get_status(atc, status, SPDIFOO);
1071}
1072
1073static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status)
1074{
1075 return atc_dao_set_status(atc, status, SPDIFOO);
1076}
1077
1078static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1079{
8cc72361 1080 struct dao_desc da_dsc = {0};
514eef9c
TI
1081 struct dao *dao;
1082 int err;
8cc72361
WYC
1083 struct ct_mixer *mixer = atc->mixer;
1084 struct rsc *rscs[2] = {NULL};
1085 unsigned int spos = 0;
1086
635c265f 1087 mutex_lock(&atc->atc_mutex);
8cc72361
WYC
1088 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
1089 da_dsc.msr = state ? 1 : atc->msr;
1090 da_dsc.passthru = state ? 1 : 0;
1091 err = dao->ops->reinit(dao, &da_dsc);
1092 if (state) {
1093 spos = IEC958_DEFAULT_CON;
1094 } else {
1095 mixer->get_output_ports(mixer, MIX_SPDIF_OUT,
1096 &rscs[0], &rscs[1]);
1097 dao->ops->set_left_input(dao, rscs[0]);
1098 dao->ops->set_right_input(dao, rscs[1]);
1099 /* Restore PLL to atc->rsr if needed. */
514eef9c
TI
1100 if (atc->pll_rate != atc->rsr)
1101 err = atc_pll_init(atc, atc->rsr);
8cc72361
WYC
1102 }
1103 dao->ops->set_spos(dao, spos);
1104 dao->ops->commit_write(dao);
635c265f 1105 mutex_unlock(&atc->atc_mutex);
8cc72361
WYC
1106
1107 return err;
1108}
1109
29959a09 1110static int atc_release_resources(struct ct_atc *atc)
8cc72361 1111{
29959a09
WYC
1112 int i;
1113 struct daio_mgr *daio_mgr = NULL;
1114 struct dao *dao = NULL;
1115 struct dai *dai = NULL;
1116 struct daio *daio = NULL;
1117 struct sum_mgr *sum_mgr = NULL;
1118 struct src_mgr *src_mgr = NULL;
1119 struct srcimp_mgr *srcimp_mgr = NULL;
1120 struct srcimp *srcimp = NULL;
1121 struct ct_mixer *mixer = NULL;
1122
1123 /* disconnect internal mixer objects */
35ebf6e7 1124 if (atc->mixer) {
8cc72361
WYC
1125 mixer = atc->mixer;
1126 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
1127 mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
1128 mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
1129 mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
1130 mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
1131 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
8cc72361
WYC
1132 }
1133
35ebf6e7 1134 if (atc->daios) {
8cc72361
WYC
1135 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1136 for (i = 0; i < atc->n_daio; i++) {
1137 daio = atc->daios[i];
1138 if (daio->type < LINEIM) {
1139 dao = container_of(daio, struct dao, daio);
1140 dao->ops->clear_left_input(dao);
1141 dao->ops->clear_right_input(dao);
1142 } else {
1143 dai = container_of(daio, struct dai, daio);
1144 /* some thing to do for dai ... */
1145 }
1146 daio_mgr->put_daio(daio_mgr, daio);
1147 }
1148 kfree(atc->daios);
29959a09 1149 atc->daios = NULL;
8cc72361
WYC
1150 }
1151
35ebf6e7 1152 if (atc->pcm) {
8cc72361
WYC
1153 sum_mgr = atc->rsc_mgrs[SUM];
1154 for (i = 0; i < atc->n_pcm; i++)
1155 sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
1156
1157 kfree(atc->pcm);
29959a09 1158 atc->pcm = NULL;
8cc72361
WYC
1159 }
1160
35ebf6e7 1161 if (atc->srcs) {
8cc72361
WYC
1162 src_mgr = atc->rsc_mgrs[SRC];
1163 for (i = 0; i < atc->n_src; i++)
1164 src_mgr->put_src(src_mgr, atc->srcs[i]);
1165
1166 kfree(atc->srcs);
29959a09 1167 atc->srcs = NULL;
8cc72361
WYC
1168 }
1169
35ebf6e7 1170 if (atc->srcimps) {
8cc72361
WYC
1171 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1172 for (i = 0; i < atc->n_srcimp; i++) {
1173 srcimp = atc->srcimps[i];
1174 srcimp->ops->unmap(srcimp);
1175 srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
1176 }
1177 kfree(atc->srcimps);
29959a09
WYC
1178 atc->srcimps = NULL;
1179 }
1180
1181 return 0;
1182}
1183
1184static int ct_atc_destroy(struct ct_atc *atc)
1185{
1186 int i = 0;
1187
35ebf6e7 1188 if (!atc)
29959a09
WYC
1189 return 0;
1190
1191 if (atc->timer) {
1192 ct_timer_free(atc->timer);
1193 atc->timer = NULL;
8cc72361
WYC
1194 }
1195
29959a09
WYC
1196 atc_release_resources(atc);
1197
1198 /* Destroy internal mixer objects */
35ebf6e7 1199 if (atc->mixer)
29959a09
WYC
1200 ct_mixer_destroy(atc->mixer);
1201
8cc72361 1202 for (i = 0; i < NUM_RSCTYP; i++) {
35ebf6e7 1203 if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i])
8cc72361
WYC
1204 rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
1205
1206 }
1207
35ebf6e7 1208 if (atc->hw)
8cc72361
WYC
1209 destroy_hw_obj((struct hw *)atc->hw);
1210
1211 /* Destroy device virtual memory manager object */
35ebf6e7 1212 if (atc->vm) {
8cc72361
WYC
1213 ct_vm_destroy(atc->vm);
1214 atc->vm = NULL;
1215 }
1216
1217 kfree(atc);
1218
1219 return 0;
1220}
1221
1222static int atc_dev_free(struct snd_device *dev)
1223{
1224 struct ct_atc *atc = dev->device_data;
1225 return ct_atc_destroy(atc);
1226}
1227
408bffd0 1228static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
8cc72361 1229{
9470195a
TI
1230 const struct snd_pci_quirk *p;
1231 const struct snd_pci_quirk *list;
408bffd0 1232 u16 vendor_id, device_id;
8cc72361 1233
9470195a
TI
1234 switch (atc->chip_type) {
1235 case ATC20K1:
1236 atc->chip_name = "20K1";
1237 list = subsys_20k1_list;
1238 break;
1239 case ATC20K2:
1240 atc->chip_name = "20K2";
1241 list = subsys_20k2_list;
8cc72361 1242 break;
9470195a
TI
1243 default:
1244 return -ENOENT;
8cc72361 1245 }
408bffd0
TI
1246 if (ssid) {
1247 vendor_id = ssid >> 16;
1248 device_id = ssid & 0xffff;
1249 } else {
1250 vendor_id = atc->pci->subsystem_vendor;
1251 device_id = atc->pci->subsystem_device;
1252 }
1253 p = snd_pci_quirk_lookup_id(vendor_id, device_id, list);
a8f4310b
TI
1254 if (p) {
1255 if (p->value < 0) {
1256 printk(KERN_ERR "ctxfi: "
1257 "Device %04x:%04x is black-listed\n",
408bffd0 1258 vendor_id, device_id);
a8f4310b
TI
1259 return -ENOENT;
1260 }
1261 atc->model = p->value;
1262 } else {
1263 if (atc->chip_type == ATC20K1)
1264 atc->model = CT20K1_UNKNOWN;
1265 else
1266 atc->model = CT20K2_UNKNOWN;
1267 }
9470195a
TI
1268 atc->model_name = ct_subsys_name[atc->model];
1269 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1270 atc->chip_name, atc->model_name,
408bffd0 1271 vendor_id, device_id);
8cc72361
WYC
1272 return 0;
1273}
1274
2a36f67f 1275int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
8cc72361
WYC
1276{
1277 enum CTALSADEVS i;
8cc72361
WYC
1278 int err;
1279
9470195a 1280 alsa_dev_funcs[MIXER].public_name = atc->chip_name;
8cc72361
WYC
1281
1282 for (i = 0; i < NUM_CTALSADEVS; i++) {
35ebf6e7 1283 if (!alsa_dev_funcs[i].create)
8cc72361
WYC
1284 continue;
1285
1286 err = alsa_dev_funcs[i].create(atc, i,
1287 alsa_dev_funcs[i].public_name);
1288 if (err) {
b3e0afe6
TI
1289 printk(KERN_ERR "ctxfi: "
1290 "Creating alsa device %d failed!\n", i);
8cc72361
WYC
1291 return err;
1292 }
1293 }
1294
1295 return 0;
1296}
1297
2a36f67f 1298static int __devinit atc_create_hw_devs(struct ct_atc *atc)
8cc72361 1299{
514eef9c 1300 struct hw *hw;
8cc72361 1301 struct card_conf info = {0};
514eef9c 1302 int i, err;
8cc72361 1303
9470195a 1304 err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw);
8cc72361
WYC
1305 if (err) {
1306 printk(KERN_ERR "Failed to create hw obj!!!\n");
1307 return err;
1308 }
1309 atc->hw = hw;
1310
1311 /* Initialize card hardware. */
1312 info.rsr = atc->rsr;
1313 info.msr = atc->msr;
1314 info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1315 err = hw->card_init(hw, &info);
1316 if (err < 0)
1317 return err;
1318
1319 for (i = 0; i < NUM_RSCTYP; i++) {
35ebf6e7 1320 if (!rsc_mgr_funcs[i].create)
8cc72361
WYC
1321 continue;
1322
1323 err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
1324 if (err) {
b3e0afe6
TI
1325 printk(KERN_ERR "ctxfi: "
1326 "Failed to create rsc_mgr %d!!!\n", i);
8cc72361
WYC
1327 return err;
1328 }
1329 }
1330
1331 return 0;
1332}
1333
29959a09 1334static int atc_get_resources(struct ct_atc *atc)
8cc72361
WYC
1335{
1336 struct daio_desc da_desc = {0};
514eef9c 1337 struct daio_mgr *daio_mgr;
8cc72361 1338 struct src_desc src_dsc = {0};
514eef9c 1339 struct src_mgr *src_mgr;
8cc72361 1340 struct srcimp_desc srcimp_dsc = {0};
514eef9c 1341 struct srcimp_mgr *srcimp_mgr;
8cc72361 1342 struct sum_desc sum_dsc = {0};
514eef9c
TI
1343 struct sum_mgr *sum_mgr;
1344 int err, i;
8cc72361
WYC
1345
1346 atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
35ebf6e7 1347 if (!atc->daios)
8cc72361
WYC
1348 return -ENOMEM;
1349
1350 atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
35ebf6e7 1351 if (!atc->srcs)
8cc72361
WYC
1352 return -ENOMEM;
1353
1354 atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
35ebf6e7 1355 if (!atc->srcimps)
8cc72361
WYC
1356 return -ENOMEM;
1357
1358 atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
35ebf6e7 1359 if (!atc->pcm)
8cc72361
WYC
1360 return -ENOMEM;
1361
1362 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1363 da_desc.msr = atc->msr;
1364 for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
1365 da_desc.type = i;
1366 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1367 (struct daio **)&atc->daios[i]);
1368 if (err) {
b3e0afe6 1369 printk(KERN_ERR "ctxfi: Failed to get DAIO "
8cc72361
WYC
1370 "resource %d!!!\n", i);
1371 return err;
1372 }
1373 atc->n_daio++;
1374 }
9470195a 1375 if (atc->model == CTSB073X)
8cc72361 1376 da_desc.type = SPDIFI1;
9470195a 1377 else
8cc72361 1378 da_desc.type = SPDIFIO;
8cc72361
WYC
1379 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1380 (struct daio **)&atc->daios[i]);
1381 if (err) {
b3e0afe6 1382 printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
8cc72361
WYC
1383 return err;
1384 }
1385 atc->n_daio++;
1386
1387 src_mgr = atc->rsc_mgrs[SRC];
1388 src_dsc.multi = 1;
1389 src_dsc.msr = atc->msr;
1390 src_dsc.mode = ARCRW;
1391 for (i = 0, atc->n_src = 0; i < (2*2); i++) {
1392 err = src_mgr->get_src(src_mgr, &src_dsc,
1393 (struct src **)&atc->srcs[i]);
1394 if (err)
1395 return err;
1396
1397 atc->n_src++;
1398 }
1399
1400 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1401 srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
1402 for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
1403 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1404 (struct srcimp **)&atc->srcimps[i]);
1405 if (err)
1406 return err;
1407
1408 atc->n_srcimp++;
1409 }
1410 srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
1411 for (i = 0; i < (2*1); i++) {
1412 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1413 (struct srcimp **)&atc->srcimps[2*1+i]);
1414 if (err)
1415 return err;
1416
1417 atc->n_srcimp++;
1418 }
1419
1420 sum_mgr = atc->rsc_mgrs[SUM];
1421 sum_dsc.msr = atc->msr;
1422 for (i = 0, atc->n_pcm = 0; i < (2*4); i++) {
1423 err = sum_mgr->get_sum(sum_mgr, &sum_dsc,
1424 (struct sum **)&atc->pcm[i]);
1425 if (err)
1426 return err;
1427
1428 atc->n_pcm++;
1429 }
1430
8cc72361
WYC
1431 return 0;
1432}
1433
29959a09 1434static void
8cc72361
WYC
1435atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
1436 struct src **srcs, struct srcimp **srcimps)
1437{
1438 struct rsc *rscs[2] = {NULL};
514eef9c
TI
1439 struct src *src;
1440 struct srcimp *srcimp;
8cc72361
WYC
1441 int i = 0;
1442
1443 rscs[0] = &dai->daio.rscl;
1444 rscs[1] = &dai->daio.rscr;
1445 for (i = 0; i < 2; i++) {
1446 src = srcs[i];
1447 srcimp = srcimps[i];
1448 srcimp->ops->map(srcimp, src, rscs[i]);
1449 src_mgr->src_disable(src_mgr, src);
1450 }
1451
1452 src_mgr->commit_write(src_mgr); /* Actually disable SRCs */
1453
1454 src = srcs[0];
1455 src->ops->set_pm(src, 1);
1456 for (i = 0; i < 2; i++) {
1457 src = srcs[i];
1458 src->ops->set_state(src, SRC_STATE_RUN);
1459 src->ops->commit_write(src);
1460 src_mgr->src_enable_s(src_mgr, src);
1461 }
1462
1463 dai->ops->set_srt_srcl(dai, &(srcs[0]->rsc));
1464 dai->ops->set_srt_srcr(dai, &(srcs[1]->rsc));
1465
1466 dai->ops->set_enb_src(dai, 1);
1467 dai->ops->set_enb_srt(dai, 1);
1468 dai->ops->commit_write(dai);
1469
1470 src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
1471}
1472
29959a09 1473static void atc_connect_resources(struct ct_atc *atc)
8cc72361 1474{
514eef9c
TI
1475 struct dai *dai;
1476 struct dao *dao;
1477 struct src *src;
1478 struct sum *sum;
1479 struct ct_mixer *mixer;
8cc72361 1480 struct rsc *rscs[2] = {NULL};
514eef9c 1481 int i, j;
8cc72361
WYC
1482
1483 mixer = atc->mixer;
1484
1485 for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) {
1486 mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]);
1487 dao = container_of(atc->daios[j], struct dao, daio);
1488 dao->ops->set_left_input(dao, rscs[0]);
1489 dao->ops->set_right_input(dao, rscs[1]);
1490 }
1491
1492 dai = container_of(atc->daios[LINEIM], struct dai, daio);
1493 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1494 (struct src **)&atc->srcs[2],
1495 (struct srcimp **)&atc->srcimps[2]);
1496 src = atc->srcs[2];
1497 mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
1498 src = atc->srcs[3];
1499 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
1500
1501 dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
1502 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1503 (struct src **)&atc->srcs[0],
1504 (struct srcimp **)&atc->srcimps[0]);
1505
1506 src = atc->srcs[0];
1507 mixer->set_input_left(mixer, MIX_SPDIF_IN, &src->rsc);
1508 src = atc->srcs[1];
1509 mixer->set_input_right(mixer, MIX_SPDIF_IN, &src->rsc);
1510
1511 for (i = MIX_PCMI_FRONT, j = 0; i <= MIX_PCMI_SURROUND; i++, j += 2) {
1512 sum = atc->pcm[j];
1513 mixer->set_input_left(mixer, i, &sum->rsc);
1514 sum = atc->pcm[j+1];
1515 mixer->set_input_right(mixer, i, &sum->rsc);
1516 }
1517}
1518
29959a09
WYC
1519#ifdef CONFIG_PM
1520static int atc_suspend(struct ct_atc *atc, pm_message_t state)
1521{
1522 int i;
1523 struct hw *hw = atc->hw;
1524
1525 snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot);
1526
1527 for (i = FRONT; i < NUM_PCMS; i++) {
1528 if (!atc->pcms[i])
1529 continue;
1530
1531 snd_pcm_suspend_all(atc->pcms[i]);
1532 }
1533
1534 atc_release_resources(atc);
1535
1536 hw->suspend(hw, state);
1537
1538 return 0;
1539}
1540
1541static int atc_hw_resume(struct ct_atc *atc)
1542{
1543 struct hw *hw = atc->hw;
1544 struct card_conf info = {0};
1545
1546 /* Re-initialize card hardware. */
1547 info.rsr = atc->rsr;
1548 info.msr = atc->msr;
1549 info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1550 return hw->resume(hw, &info);
1551}
1552
1553static int atc_resources_resume(struct ct_atc *atc)
1554{
1555 struct ct_mixer *mixer;
1556 int err = 0;
1557
1558 /* Get resources */
1559 err = atc_get_resources(atc);
1560 if (err < 0) {
1561 atc_release_resources(atc);
1562 return err;
1563 }
1564
1565 /* Build topology */
1566 atc_connect_resources(atc);
1567
1568 mixer = atc->mixer;
1569 mixer->resume(mixer);
1570
1571 return 0;
1572}
1573
1574static int atc_resume(struct ct_atc *atc)
1575{
1576 int err = 0;
1577
1578 /* Do hardware resume. */
1579 err = atc_hw_resume(atc);
1580 if (err < 0) {
1581 printk(KERN_ERR "ctxfi: pci_enable_device failed, "
1582 "disabling device\n");
1583 snd_card_disconnect(atc->card);
1584 return err;
1585 }
1586
1587 err = atc_resources_resume(atc);
1588 if (err < 0)
1589 return err;
1590
1591 snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0);
1592
1593 return 0;
1594}
1595#endif
1596
2a36f67f
TI
1597static struct ct_atc atc_preset __devinitdata = {
1598 .map_audio_buffer = ct_map_audio_buffer,
1599 .unmap_audio_buffer = ct_unmap_audio_buffer,
1600 .pcm_playback_prepare = atc_pcm_playback_prepare,
1601 .pcm_release_resources = atc_pcm_release_resources,
1602 .pcm_playback_start = atc_pcm_playback_start,
1603 .pcm_playback_stop = atc_pcm_stop,
1604 .pcm_playback_position = atc_pcm_playback_position,
1605 .pcm_capture_prepare = atc_pcm_capture_prepare,
1606 .pcm_capture_start = atc_pcm_capture_start,
1607 .pcm_capture_stop = atc_pcm_stop,
1608 .pcm_capture_position = atc_pcm_capture_position,
1609 .spdif_passthru_playback_prepare = spdif_passthru_playback_prepare,
1610 .get_ptp_phys = atc_get_ptp_phys,
1611 .select_line_in = atc_select_line_in,
1612 .select_mic_in = atc_select_mic_in,
1613 .select_digit_io = atc_select_digit_io,
1614 .line_front_unmute = atc_line_front_unmute,
1615 .line_surround_unmute = atc_line_surround_unmute,
1616 .line_clfe_unmute = atc_line_clfe_unmute,
1617 .line_rear_unmute = atc_line_rear_unmute,
1618 .line_in_unmute = atc_line_in_unmute,
1619 .spdif_out_unmute = atc_spdif_out_unmute,
1620 .spdif_in_unmute = atc_spdif_in_unmute,
1621 .spdif_out_get_status = atc_spdif_out_get_status,
1622 .spdif_out_set_status = atc_spdif_out_set_status,
1623 .spdif_out_passthru = atc_spdif_out_passthru,
1624 .have_digit_io_switch = atc_have_digit_io_switch,
29959a09
WYC
1625#ifdef CONFIG_PM
1626 .suspend = atc_suspend,
1627 .resume = atc_resume,
1628#endif
2a36f67f 1629};
8cc72361
WYC
1630
1631/**
1632 * ct_atc_create - create and initialize a hardware manager
1633 * @card: corresponding alsa card object
1634 * @pci: corresponding kernel pci device object
1635 * @ratc: return created object address in it
1636 *
1637 * Creates and initializes a hardware manager.
1638 *
1639 * Creates kmallocated ct_atc structure. Initializes hardware.
1640 * Returns 0 if suceeds, or negative error code if fails.
1641 */
1642
2a36f67f 1643int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
9470195a 1644 unsigned int rsr, unsigned int msr,
408bffd0
TI
1645 int chip_type, unsigned int ssid,
1646 struct ct_atc **ratc)
8cc72361 1647{
514eef9c 1648 struct ct_atc *atc;
8cc72361
WYC
1649 static struct snd_device_ops ops = {
1650 .dev_free = atc_dev_free,
1651 };
514eef9c 1652 int err;
8cc72361
WYC
1653
1654 *ratc = NULL;
1655
1656 atc = kzalloc(sizeof(*atc), GFP_KERNEL);
35ebf6e7 1657 if (!atc)
8cc72361
WYC
1658 return -ENOMEM;
1659
2a36f67f
TI
1660 /* Set operations */
1661 *atc = atc_preset;
1662
8cc72361
WYC
1663 atc->card = card;
1664 atc->pci = pci;
1665 atc->rsr = rsr;
1666 atc->msr = msr;
9470195a 1667 atc->chip_type = chip_type;
8cc72361 1668
635c265f 1669 mutex_init(&atc->atc_mutex);
8cc72361
WYC
1670
1671 /* Find card model */
408bffd0 1672 err = atc_identify_card(atc, ssid);
8cc72361
WYC
1673 if (err < 0) {
1674 printk(KERN_ERR "ctatc: Card not recognised\n");
1675 goto error1;
1676 }
1677
1678 /* Set up device virtual memory management object */
1679 err = ct_vm_create(&atc->vm);
1680 if (err < 0)
1681 goto error1;
1682
1683 /* Create all atc hw devices */
1684 err = atc_create_hw_devs(atc);
1685 if (err < 0)
1686 goto error1;
1687
29959a09
WYC
1688 err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
1689 if (err) {
1690 printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
1691 goto error1;
1692 }
1693
8cc72361
WYC
1694 /* Get resources */
1695 err = atc_get_resources(atc);
1696 if (err < 0)
1697 goto error1;
1698
1699 /* Build topology */
1700 atc_connect_resources(atc);
1701
b7bbf876
TI
1702 atc->timer = ct_timer_new(atc);
1703 if (!atc->timer)
1704 goto error1;
1705
8cc72361
WYC
1706 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
1707 if (err < 0)
1708 goto error1;
1709
1710 snd_card_set_dev(card, &pci->dev);
1711
1712 *ratc = atc;
1713 return 0;
1714
1715error1:
1716 ct_atc_destroy(atc);
b3e0afe6 1717 printk(KERN_ERR "ctxfi: Something wrong!!!\n");
8cc72361
WYC
1718 return err;
1719}
This page took 0.142339 seconds and 5 git commands to generate.