linux/sound/pci/ctxfi/ctatc.c
<<
>>
Prefs
   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"
  21#include "cthardware.h"
  22#include "ctsrc.h"
  23#include "ctamixer.h"
  24#include "ctdaio.h"
  25#include "cttimer.h"
  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
  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),
  47        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
  48                           "UAA", CTUAA),
  49        { } /* terminator */
  50};
  51
  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),
  61        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000,
  62                           PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX",
  63                           CTHENDRIX),
  64        { } /* terminator */
  65};
  66
  67static const char *ct_subsys_name[NUM_CTCARDS] = {
  68        /* 20k1 models */
  69        [CTSB055X]      = "SB055x",
  70        [CTSB073X]      = "SB073x",
  71        [CTUAA]         = "UAA",
  72        [CT20K1_UNKNOWN] = "Unknown",
  73        /* 20k2 models */
  74        [CTSB0760]      = "SB076x",
  75        [CTHENDRIX]     = "Hendrix",
  76        [CTSB0880]      = "SB0880",
  77        [CT20K2_UNKNOWN] = "Unknown",
  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"},
  89        [SURROUND]      = { .create = ct_alsa_pcm_create,
  90                            .destroy = NULL,
  91                            .public_name = "Surround"},
  92        [CLFE]          = { .create = ct_alsa_pcm_create,
  93                            .destroy = NULL,
  94                            .public_name = "Center/LFE"},
  95        [SIDE]          = { .create = ct_alsa_pcm_create,
  96                            .destroy = NULL,
  97                            .public_name = "Side"},
  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{
 136        struct snd_pcm_runtime *runtime;
 137        struct ct_vm *vm;
 138
 139        if (!apcm->substream)
 140                return 0;
 141
 142        runtime = apcm->substream->runtime;
 143        vm = atc->vm;
 144
 145        apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
 146
 147        if (!apcm->vm_block)
 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{
 155        struct ct_vm *vm;
 156
 157        if (!apcm->vm_block)
 158                return;
 159
 160        vm = atc->vm;
 161
 162        vm->unmap(vm, apcm->vm_block);
 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;
 172
 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
 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:
 187                return SRC_SF_U8;
 188        case SNDRV_PCM_FORMAT_S16_LE:
 189                return SRC_SF_S16;
 190        case SNDRV_PCM_FORMAT_S24_3LE:
 191                return SRC_SF_S24;
 192        case SNDRV_PCM_FORMAT_S32_LE:
 193                return SRC_SF_S32;
 194        case SNDRV_PCM_FORMAT_FLOAT_LE:
 195                return SRC_SF_F32;
 196        default:
 197                printk(KERN_ERR "ctxfi: not recognized snd format is %d \n",
 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{
 206        unsigned int pitch;
 207        int b;
 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{
 234        if (pitch > 0x00428f5c && pitch < 0x01b851ec) {
 235                /* 0.26 <= pitch <= 1.72 */
 236                return 1;
 237        } else if (pitch == 0x01d66666 || pitch == 0x01d66667) {
 238                /* pitch == 1.8375 */
 239                return 2;
 240        } else if (pitch == 0x02000000) {
 241                /* pitch == 2 */
 242                return 3;
 243        } else if (pitch >= 0x0 && pitch <= 0x08000000) {
 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};
 257        struct src *src;
 258        struct amixer *amixer;
 259        int err;
 260        int n_amixer = apcm->substream->runtime->channels, i = 0;
 261        int device = apcm->substream->pcm->device;
 262        unsigned int pitch;
 263
 264        /* first release old resources */
 265        atc_pcm_release_resources(atc, apcm);
 266
 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);
 286        if (!apcm->amixers) {
 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];
 309                mutex_lock(&atc->atc_mutex);
 310                amixer->ops->setup(amixer, &src->rsc,
 311                                        INIT_VOL, atc->pcm[i+device*2]);
 312                mutex_unlock(&atc->atc_mutex);
 313                src = src->ops->next_interleave(src);
 314                if (!src)
 315                        src = apcm->src;
 316        }
 317
 318        ct_timer_prepare(apcm->timer);
 319
 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];
 334        struct srcimp *srcimp;
 335        int i;
 336
 337        if (apcm->srcimps) {
 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
 348        if (apcm->srccs) {
 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
 357        if (apcm->amixers) {
 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
 366        if (apcm->mono) {
 367                sum_mgr->put_sum(sum_mgr, apcm->mono);
 368                apcm->mono = NULL;
 369        }
 370
 371        if (apcm->src) {
 372                src_mgr->put_src(src_mgr, apcm->src);
 373                apcm->src = NULL;
 374        }
 375
 376        if (apcm->vm_block) {
 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{
 387        unsigned int max_cisz;
 388        struct src *src = apcm->src;
 389
 390        if (apcm->started)
 391                return 0;
 392        apcm->started = 1;
 393
 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
 406        ct_timer_start(apcm->timer);
 407        return 0;
 408}
 409
 410static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
 411{
 412        struct src *src;
 413        int i;
 414
 415        ct_timer_stop(apcm->timer);
 416
 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
 422        if (apcm->srccs) {
 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;
 440        u32 size, max_cisz;
 441        int position;
 442
 443        if (!src)
 444                return 0;
 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{
 465        unsigned int pitch;
 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};
 510        struct src *src;
 511        struct srcimp_desc srcimp_dsc = {0};
 512        struct srcimp *srcimp;
 513        struct amixer_desc mix_dsc = {0};
 514        struct sum_desc sum_dsc = {0};
 515        unsigned int pitch;
 516        int multi, err, i;
 517        int n_srcimp, n_amixer, n_srcc, n_sum;
 518        struct src_node_conf_t src_node_conf[2] = {{0} };
 519
 520        /* first release old resources */
 521        atc_pcm_release_resources(atc, apcm);
 522
 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;
 534        n_amixer = n_sum * 2 + n_srcc;
 535        n_srcimp = n_srcc;
 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);
 547                if (!apcm->srccs)
 548                        return -ENOMEM;
 549        }
 550        if (n_amixer) {
 551                apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
 552                if (!apcm->amixers) {
 553                        err = -ENOMEM;
 554                        goto error1;
 555                }
 556        }
 557        apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
 558        if (!apcm->srcimps) {
 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{
 649        struct src *src;
 650        struct amixer *amixer;
 651        struct srcimp *srcimp;
 652        struct ct_mixer *mixer = atc->mixer;
 653        struct sum *mono;
 654        struct rsc *out_ports[8] = {NULL};
 655        int err, i, j, n_sum, multi;
 656        unsigned int pitch;
 657        int mix_base = 0, imp_base = 0;
 658
 659        atc_pcm_release_resources(atc, apcm);
 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
 720        ct_timer_prepare(apcm->timer);
 721
 722        return 0;
 723}
 724
 725static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
 726{
 727        struct src *src;
 728        struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
 729        int i, multi;
 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
 770        ct_timer_start(apcm->timer);
 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
 779        if (!src)
 780                return 0;
 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};
 791        struct src *src;
 792        int err;
 793        int n_amixer = apcm->substream->runtime->channels, i;
 794        unsigned int pitch, rsr = atc->pll_rate;
 795
 796        /* first release old resources */
 797        atc_pcm_release_resources(atc, apcm);
 798
 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);
 821        if (!apcm->amixers) {
 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
 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
 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);
 860        unsigned int rate = apcm->substream->runtime->rate;
 861        unsigned int status;
 862        int err = 0;
 863        unsigned char iec958_con_fs;
 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
 879        mutex_lock(&atc->atc_mutex);
 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        }
 887        if ((rate != atc->pll_rate) && (32000 != rate))
 888                err = atc_pll_init(atc, rate);
 889        mutex_unlock(&atc->atc_mutex);
 890
 891        return err;
 892}
 893
 894static int
 895spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
 896{
 897        struct src *src;
 898        struct amixer *amixer;
 899        struct dao *dao;
 900        int err;
 901        int i;
 902
 903        atc_pcm_release_resources(atc, apcm);
 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);
 922                if (!src)
 923                        src = apcm->src;
 924        }
 925        /* Connect to SPDIFOO */
 926        mutex_lock(&atc->atc_mutex);
 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);
 932        mutex_unlock(&atc->atc_mutex);
 933
 934        ct_timer_prepare(apcm->timer);
 935
 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;
 943        struct src *src;
 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;
 965        struct src *src;
 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{
1040        return atc_daio_unmute(atc, state, LINEO2);
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{
1050        return atc_daio_unmute(atc, state, LINEO4);
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{
1080        struct dao_desc da_dsc = {0};
1081        struct dao *dao;
1082        int err;
1083        struct ct_mixer *mixer = atc->mixer;
1084        struct rsc *rscs[2] = {NULL};
1085        unsigned int spos = 0;
1086
1087        mutex_lock(&atc->atc_mutex);
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. */
1100                if (atc->pll_rate != atc->rsr)
1101                        err = atc_pll_init(atc, atc->rsr);
1102        }
1103        dao->ops->set_spos(dao, spos);
1104        dao->ops->commit_write(dao);
1105        mutex_unlock(&atc->atc_mutex);
1106
1107        return err;
1108}
1109
1110static int atc_release_resources(struct ct_atc *atc)
1111{
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 */
1124        if (atc->mixer) {
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);
1132        }
1133
1134        if (atc->daios) {
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);
1149                atc->daios = NULL;
1150        }
1151
1152        if (atc->pcm) {
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);
1158                atc->pcm = NULL;
1159        }
1160
1161        if (atc->srcs) {
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);
1167                atc->srcs = NULL;
1168        }
1169
1170        if (atc->srcimps) {
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);
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
1188        if (!atc)
1189                return 0;
1190
1191        if (atc->timer) {
1192                ct_timer_free(atc->timer);
1193                atc->timer = NULL;
1194        }
1195
1196        atc_release_resources(atc);
1197
1198        /* Destroy internal mixer objects */
1199        if (atc->mixer)
1200                ct_mixer_destroy(atc->mixer);
1201
1202        for (i = 0; i < NUM_RSCTYP; i++) {
1203                if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i])
1204                        rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
1205
1206        }
1207
1208        if (atc->hw)
1209                destroy_hw_obj((struct hw *)atc->hw);
1210
1211        /* Destroy device virtual memory manager object */
1212        if (atc->vm) {
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
1228static int __devinit atc_identify_card(struct ct_atc *atc)
1229{
1230        const struct snd_pci_quirk *p;
1231        const struct snd_pci_quirk *list;
1232
1233        switch (atc->chip_type) {
1234        case ATC20K1:
1235                atc->chip_name = "20K1";
1236                list = subsys_20k1_list;
1237                break;
1238        case ATC20K2:
1239                atc->chip_name = "20K2";
1240                list = subsys_20k2_list;
1241                break;
1242        default:
1243                return -ENOENT;
1244        }
1245        p = snd_pci_quirk_lookup(atc->pci, list);
1246        if (p) {
1247                if (p->value < 0) {
1248                        printk(KERN_ERR "ctxfi: "
1249                               "Device %04x:%04x is black-listed\n",
1250                               atc->pci->subsystem_vendor,
1251                               atc->pci->subsystem_device);
1252                        return -ENOENT;
1253                }
1254                atc->model = p->value;
1255        } else {
1256                if (atc->chip_type == ATC20K1)
1257                        atc->model = CT20K1_UNKNOWN;
1258                else
1259                        atc->model = CT20K2_UNKNOWN;
1260        }
1261        atc->model_name = ct_subsys_name[atc->model];
1262        snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1263                   atc->chip_name, atc->model_name,
1264                   atc->pci->subsystem_vendor,
1265                   atc->pci->subsystem_device);
1266        return 0;
1267}
1268
1269int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
1270{
1271        enum CTALSADEVS i;
1272        int err;
1273
1274        alsa_dev_funcs[MIXER].public_name = atc->chip_name;
1275
1276        for (i = 0; i < NUM_CTALSADEVS; i++) {
1277                if (!alsa_dev_funcs[i].create)
1278                        continue;
1279
1280                err = alsa_dev_funcs[i].create(atc, i,
1281                                alsa_dev_funcs[i].public_name);
1282                if (err) {
1283                        printk(KERN_ERR "ctxfi: "
1284                               "Creating alsa device %d failed!\n", i);
1285                        return err;
1286                }
1287        }
1288
1289        return 0;
1290}
1291
1292static int __devinit atc_create_hw_devs(struct ct_atc *atc)
1293{
1294        struct hw *hw;
1295        struct card_conf info = {0};
1296        int i, err;
1297
1298        err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw);
1299        if (err) {
1300                printk(KERN_ERR "Failed to create hw obj!!!\n");
1301                return err;
1302        }
1303        atc->hw = hw;
1304
1305        /* Initialize card hardware. */
1306        info.rsr = atc->rsr;
1307        info.msr = atc->msr;
1308        info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1309        err = hw->card_init(hw, &info);
1310        if (err < 0)
1311                return err;
1312
1313        for (i = 0; i < NUM_RSCTYP; i++) {
1314                if (!rsc_mgr_funcs[i].create)
1315                        continue;
1316
1317                err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
1318                if (err) {
1319                        printk(KERN_ERR "ctxfi: "
1320                               "Failed to create rsc_mgr %d!!!\n", i);
1321                        return err;
1322                }
1323        }
1324
1325        return 0;
1326}
1327
1328static int atc_get_resources(struct ct_atc *atc)
1329{
1330        struct daio_desc da_desc = {0};
1331        struct daio_mgr *daio_mgr;
1332        struct src_desc src_dsc = {0};
1333        struct src_mgr *src_mgr;
1334        struct srcimp_desc srcimp_dsc = {0};
1335        struct srcimp_mgr *srcimp_mgr;
1336        struct sum_desc sum_dsc = {0};
1337        struct sum_mgr *sum_mgr;
1338        int err, i;
1339
1340        atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
1341        if (!atc->daios)
1342                return -ENOMEM;
1343
1344        atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1345        if (!atc->srcs)
1346                return -ENOMEM;
1347
1348        atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1349        if (!atc->srcimps)
1350                return -ENOMEM;
1351
1352        atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
1353        if (!atc->pcm)
1354                return -ENOMEM;
1355
1356        daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1357        da_desc.msr = atc->msr;
1358        for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
1359                da_desc.type = i;
1360                err = daio_mgr->get_daio(daio_mgr, &da_desc,
1361                                        (struct daio **)&atc->daios[i]);
1362                if (err) {
1363                        printk(KERN_ERR "ctxfi: Failed to get DAIO "
1364                                        "resource %d!!!\n", i);
1365                        return err;
1366                }
1367                atc->n_daio++;
1368        }
1369        if (atc->model == CTSB073X)
1370                da_desc.type = SPDIFI1;
1371        else
1372                da_desc.type = SPDIFIO;
1373        err = daio_mgr->get_daio(daio_mgr, &da_desc,
1374                                (struct daio **)&atc->daios[i]);
1375        if (err) {
1376                printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
1377                return err;
1378        }
1379        atc->n_daio++;
1380
1381        src_mgr = atc->rsc_mgrs[SRC];
1382        src_dsc.multi = 1;
1383        src_dsc.msr = atc->msr;
1384        src_dsc.mode = ARCRW;
1385        for (i = 0, atc->n_src = 0; i < (2*2); i++) {
1386                err = src_mgr->get_src(src_mgr, &src_dsc,
1387                                        (struct src **)&atc->srcs[i]);
1388                if (err)
1389                        return err;
1390
1391                atc->n_src++;
1392        }
1393
1394        srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1395        srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
1396        for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
1397                err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1398                                        (struct srcimp **)&atc->srcimps[i]);
1399                if (err)
1400                        return err;
1401
1402                atc->n_srcimp++;
1403        }
1404        srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
1405        for (i = 0; i < (2*1); i++) {
1406                err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1407                                (struct srcimp **)&atc->srcimps[2*1+i]);
1408                if (err)
1409                        return err;
1410
1411                atc->n_srcimp++;
1412        }
1413
1414        sum_mgr = atc->rsc_mgrs[SUM];
1415        sum_dsc.msr = atc->msr;
1416        for (i = 0, atc->n_pcm = 0; i < (2*4); i++) {
1417                err = sum_mgr->get_sum(sum_mgr, &sum_dsc,
1418                                        (struct sum **)&atc->pcm[i]);
1419                if (err)
1420                        return err;
1421
1422                atc->n_pcm++;
1423        }
1424
1425        return 0;
1426}
1427
1428static void
1429atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
1430                struct src **srcs, struct srcimp **srcimps)
1431{
1432        struct rsc *rscs[2] = {NULL};
1433        struct src *src;
1434        struct srcimp *srcimp;
1435        int i = 0;
1436
1437        rscs[0] = &dai->daio.rscl;
1438        rscs[1] = &dai->daio.rscr;
1439        for (i = 0; i < 2; i++) {
1440                src = srcs[i];
1441                srcimp = srcimps[i];
1442                srcimp->ops->map(srcimp, src, rscs[i]);
1443                src_mgr->src_disable(src_mgr, src);
1444        }
1445
1446        src_mgr->commit_write(src_mgr); /* Actually disable SRCs */
1447
1448        src = srcs[0];
1449        src->ops->set_pm(src, 1);
1450        for (i = 0; i < 2; i++) {
1451                src = srcs[i];
1452                src->ops->set_state(src, SRC_STATE_RUN);
1453                src->ops->commit_write(src);
1454                src_mgr->src_enable_s(src_mgr, src);
1455        }
1456
1457        dai->ops->set_srt_srcl(dai, &(srcs[0]->rsc));
1458        dai->ops->set_srt_srcr(dai, &(srcs[1]->rsc));
1459
1460        dai->ops->set_enb_src(dai, 1);
1461        dai->ops->set_enb_srt(dai, 1);
1462        dai->ops->commit_write(dai);
1463
1464        src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
1465}
1466
1467static void atc_connect_resources(struct ct_atc *atc)
1468{
1469        struct dai *dai;
1470        struct dao *dao;
1471        struct src *src;
1472        struct sum *sum;
1473        struct ct_mixer *mixer;
1474        struct rsc *rscs[2] = {NULL};
1475        int i, j;
1476
1477        mixer = atc->mixer;
1478
1479        for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) {
1480                mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]);
1481                dao = container_of(atc->daios[j], struct dao, daio);
1482                dao->ops->set_left_input(dao, rscs[0]);
1483                dao->ops->set_right_input(dao, rscs[1]);
1484        }
1485
1486        dai = container_of(atc->daios[LINEIM], struct dai, daio);
1487        atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1488                        (struct src **)&atc->srcs[2],
1489                        (struct srcimp **)&atc->srcimps[2]);
1490        src = atc->srcs[2];
1491        mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
1492        src = atc->srcs[3];
1493        mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
1494
1495        dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
1496        atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1497                        (struct src **)&atc->srcs[0],
1498                        (struct srcimp **)&atc->srcimps[0]);
1499
1500        src = atc->srcs[0];
1501        mixer->set_input_left(mixer, MIX_SPDIF_IN, &src->rsc);
1502        src = atc->srcs[1];
1503        mixer->set_input_right(mixer, MIX_SPDIF_IN, &src->rsc);
1504
1505        for (i = MIX_PCMI_FRONT, j = 0; i <= MIX_PCMI_SURROUND; i++, j += 2) {
1506                sum = atc->pcm[j];
1507                mixer->set_input_left(mixer, i, &sum->rsc);
1508                sum = atc->pcm[j+1];
1509                mixer->set_input_right(mixer, i, &sum->rsc);
1510        }
1511}
1512
1513#ifdef CONFIG_PM
1514static int atc_suspend(struct ct_atc *atc, pm_message_t state)
1515{
1516        int i;
1517        struct hw *hw = atc->hw;
1518
1519        snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot);
1520
1521        for (i = FRONT; i < NUM_PCMS; i++) {
1522                if (!atc->pcms[i])
1523                        continue;
1524
1525                snd_pcm_suspend_all(atc->pcms[i]);
1526        }
1527
1528        atc_release_resources(atc);
1529
1530        hw->suspend(hw, state);
1531
1532        return 0;
1533}
1534
1535static int atc_hw_resume(struct ct_atc *atc)
1536{
1537        struct hw *hw = atc->hw;
1538        struct card_conf info = {0};
1539
1540        /* Re-initialize card hardware. */
1541        info.rsr = atc->rsr;
1542        info.msr = atc->msr;
1543        info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1544        return hw->resume(hw, &info);
1545}
1546
1547static int atc_resources_resume(struct ct_atc *atc)
1548{
1549        struct ct_mixer *mixer;
1550        int err = 0;
1551
1552        /* Get resources */
1553        err = atc_get_resources(atc);
1554        if (err < 0) {
1555                atc_release_resources(atc);
1556                return err;
1557        }
1558
1559        /* Build topology */
1560        atc_connect_resources(atc);
1561
1562        mixer = atc->mixer;
1563        mixer->resume(mixer);
1564
1565        return 0;
1566}
1567
1568static int atc_resume(struct ct_atc *atc)
1569{
1570        int err = 0;
1571
1572        /* Do hardware resume. */
1573        err = atc_hw_resume(atc);
1574        if (err < 0) {
1575                printk(KERN_ERR "ctxfi: pci_enable_device failed, "
1576                       "disabling device\n");
1577                snd_card_disconnect(atc->card);
1578                return err;
1579        }
1580
1581        err = atc_resources_resume(atc);
1582        if (err < 0)
1583                return err;
1584
1585        snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0);
1586
1587        return 0;
1588}
1589#endif
1590
1591static struct ct_atc atc_preset __devinitdata = {
1592        .map_audio_buffer = ct_map_audio_buffer,
1593        .unmap_audio_buffer = ct_unmap_audio_buffer,
1594        .pcm_playback_prepare = atc_pcm_playback_prepare,
1595        .pcm_release_resources = atc_pcm_release_resources,
1596        .pcm_playback_start = atc_pcm_playback_start,
1597        .pcm_playback_stop = atc_pcm_stop,
1598        .pcm_playback_position = atc_pcm_playback_position,
1599        .pcm_capture_prepare = atc_pcm_capture_prepare,
1600        .pcm_capture_start = atc_pcm_capture_start,
1601        .pcm_capture_stop = atc_pcm_stop,
1602        .pcm_capture_position = atc_pcm_capture_position,
1603        .spdif_passthru_playback_prepare = spdif_passthru_playback_prepare,
1604        .get_ptp_phys = atc_get_ptp_phys,
1605        .select_line_in = atc_select_line_in,
1606        .select_mic_in = atc_select_mic_in,
1607        .select_digit_io = atc_select_digit_io,
1608        .line_front_unmute = atc_line_front_unmute,
1609        .line_surround_unmute = atc_line_surround_unmute,
1610        .line_clfe_unmute = atc_line_clfe_unmute,
1611        .line_rear_unmute = atc_line_rear_unmute,
1612        .line_in_unmute = atc_line_in_unmute,
1613        .spdif_out_unmute = atc_spdif_out_unmute,
1614        .spdif_in_unmute = atc_spdif_in_unmute,
1615        .spdif_out_get_status = atc_spdif_out_get_status,
1616        .spdif_out_set_status = atc_spdif_out_set_status,
1617        .spdif_out_passthru = atc_spdif_out_passthru,
1618        .have_digit_io_switch = atc_have_digit_io_switch,
1619#ifdef CONFIG_PM
1620        .suspend = atc_suspend,
1621        .resume = atc_resume,
1622#endif
1623};
1624
1625/**
1626 *  ct_atc_create - create and initialize a hardware manager
1627 *  @card: corresponding alsa card object
1628 *  @pci: corresponding kernel pci device object
1629 *  @ratc: return created object address in it
1630 *
1631 *  Creates and initializes a hardware manager.
1632 *
1633 *  Creates kmallocated ct_atc structure. Initializes hardware.
1634 *  Returns 0 if suceeds, or negative error code if fails.
1635 */
1636
1637int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1638                            unsigned int rsr, unsigned int msr,
1639                            int chip_type, struct ct_atc **ratc)
1640{
1641        struct ct_atc *atc;
1642        static struct snd_device_ops ops = {
1643                .dev_free = atc_dev_free,
1644        };
1645        int err;
1646
1647        *ratc = NULL;
1648
1649        atc = kzalloc(sizeof(*atc), GFP_KERNEL);
1650        if (!atc)
1651                return -ENOMEM;
1652
1653        /* Set operations */
1654        *atc = atc_preset;
1655
1656        atc->card = card;
1657        atc->pci = pci;
1658        atc->rsr = rsr;
1659        atc->msr = msr;
1660        atc->chip_type = chip_type;
1661
1662        mutex_init(&atc->atc_mutex);
1663
1664        /* Find card model */
1665        err = atc_identify_card(atc);
1666        if (err < 0) {
1667                printk(KERN_ERR "ctatc: Card not recognised\n");
1668                goto error1;
1669        }
1670
1671        /* Set up device virtual memory management object */
1672        err = ct_vm_create(&atc->vm);
1673        if (err < 0)
1674                goto error1;
1675
1676        /* Create all atc hw devices */
1677        err = atc_create_hw_devs(atc);
1678        if (err < 0)
1679                goto error1;
1680
1681        err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
1682        if (err) {
1683                printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
1684                goto error1;
1685        }
1686
1687        /* Get resources */
1688        err = atc_get_resources(atc);
1689        if (err < 0)
1690                goto error1;
1691
1692        /* Build topology */
1693        atc_connect_resources(atc);
1694
1695        atc->timer = ct_timer_new(atc);
1696        if (!atc->timer)
1697                goto error1;
1698
1699        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
1700        if (err < 0)
1701                goto error1;
1702
1703        snd_card_set_dev(card, &pci->dev);
1704
1705        *ratc = atc;
1706        return 0;
1707
1708error1:
1709        ct_atc_destroy(atc);
1710        printk(KERN_ERR "ctxfi: Something wrong!!!\n");
1711        return err;
1712}
1713