Loading sound/pci/ctxfi/ctatc.c +152 −54 Original line number Diff line number Diff line Loading @@ -46,8 +46,6 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000, "UAA", CTUAA), SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE, "Unknown", CT20K1_UNKNOWN), { } /* terminator */ }; Loading @@ -67,13 +65,16 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { }; static const char *ct_subsys_name[NUM_CTCARDS] = { /* 20k1 models */ [CTSB055X] = "SB055x", [CTSB073X] = "SB073x", [CTSB0760] = "SB076x", [CTUAA] = "UAA", [CT20K1_UNKNOWN] = "Unknown", /* 20k2 models */ [CTSB0760] = "SB076x", [CTHENDRIX] = "Hendrix", [CTSB0880] = "SB0880", [CT20K2_UNKNOWN] = "Unknown", }; static struct { Loading Loading @@ -260,13 +261,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int device = apcm->substream->pcm->device; unsigned int pitch; if (NULL != apcm->src) { /* Prepared pcm playback */ return 0; } /* first release old resources */ atc->pcm_release_resources(atc, apcm); atc_pcm_release_resources(atc, apcm); /* Get SRC resource */ desc.multi = apcm->substream->runtime->channels; Loading Loading @@ -660,10 +656,7 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) unsigned int pitch; int mix_base = 0, imp_base = 0; if (NULL != apcm->src) { /* Prepared pcm capture */ return 0; } atc_pcm_release_resources(atc, apcm); /* Get needed resources. */ err = atc_pcm_capture_get_resources(atc, apcm); Loading Loading @@ -866,7 +859,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); unsigned int rate = apcm->substream->runtime->rate; unsigned int status; int err; int err = 0; unsigned char iec958_con_fs; switch (rate) { Loading Loading @@ -907,8 +900,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int err; int i; if (NULL != apcm->src) return 0; atc_pcm_release_resources(atc, apcm); /* Configure SPDIFOO and PLL to passthrough mode; * determine pll_rate. */ Loading Loading @@ -1115,32 +1107,20 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) return err; } static int ct_atc_destroy(struct ct_atc *atc) static int atc_release_resources(struct ct_atc *atc) { struct daio_mgr *daio_mgr; struct dao *dao; struct dai *dai; struct daio *daio; struct sum_mgr *sum_mgr; struct src_mgr *src_mgr; struct srcimp_mgr *srcimp_mgr; struct srcimp *srcimp; struct ct_mixer *mixer; int i = 0; if (NULL == atc) return 0; if (atc->timer) { ct_timer_free(atc->timer); atc->timer = NULL; } /* Stop hardware and disable all interrupts */ if (NULL != atc->hw) ((struct hw *)atc->hw)->card_stop(atc->hw); /* Destroy internal mixer objects */ int i; struct daio_mgr *daio_mgr = NULL; struct dao *dao = NULL; struct dai *dai = NULL; struct daio *daio = NULL; struct sum_mgr *sum_mgr = NULL; struct src_mgr *src_mgr = NULL; struct srcimp_mgr *srcimp_mgr = NULL; struct srcimp *srcimp = NULL; struct ct_mixer *mixer = NULL; /* disconnect internal mixer objects */ if (NULL != atc->mixer) { mixer = atc->mixer; mixer->set_input_left(mixer, MIX_LINE_IN, NULL); Loading @@ -1149,7 +1129,6 @@ static int ct_atc_destroy(struct ct_atc *atc) mixer->set_input_right(mixer, MIX_MIC_IN, NULL); mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL); mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); ct_mixer_destroy(atc->mixer); } if (NULL != atc->daios) { Loading @@ -1167,6 +1146,7 @@ static int ct_atc_destroy(struct ct_atc *atc) daio_mgr->put_daio(daio_mgr, daio); } kfree(atc->daios); atc->daios = NULL; } if (NULL != atc->pcm) { Loading @@ -1175,6 +1155,7 @@ static int ct_atc_destroy(struct ct_atc *atc) sum_mgr->put_sum(sum_mgr, atc->pcm[i]); kfree(atc->pcm); atc->pcm = NULL; } if (NULL != atc->srcs) { Loading @@ -1183,6 +1164,7 @@ static int ct_atc_destroy(struct ct_atc *atc) src_mgr->put_src(src_mgr, atc->srcs[i]); kfree(atc->srcs); atc->srcs = NULL; } if (NULL != atc->srcimps) { Loading @@ -1193,8 +1175,30 @@ static int ct_atc_destroy(struct ct_atc *atc) srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); } kfree(atc->srcimps); atc->srcimps = NULL; } return 0; } static int ct_atc_destroy(struct ct_atc *atc) { int i = 0; if (NULL == atc) return 0; if (atc->timer) { ct_timer_free(atc->timer); atc->timer = NULL; } atc_release_resources(atc); /* Destroy internal mixer objects */ if (NULL != atc->mixer) ct_mixer_destroy(atc->mixer); for (i = 0; i < NUM_RSCTYP; i++) { if ((NULL != rsc_mgr_funcs[i].destroy) && (NULL != atc->rsc_mgrs[i])) Loading Loading @@ -1240,9 +1244,21 @@ static int __devinit atc_identify_card(struct ct_atc *atc) return -ENOENT; } p = snd_pci_quirk_lookup(atc->pci, list); if (!p) if (p) { if (p->value < 0) { printk(KERN_ERR "ctxfi: " "Device %04x:%04x is black-listed\n", atc->pci->subsystem_vendor, atc->pci->subsystem_device); return -ENOENT; } atc->model = p->value; } else { if (atc->chip_type == ATC20K1) atc->model = CT20K1_UNKNOWN; else atc->model = CT20K2_UNKNOWN; } atc->model_name = ct_subsys_name[atc->model]; snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", atc->chip_name, atc->model_name, Loading Loading @@ -1310,7 +1326,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) return 0; } static int __devinit atc_get_resources(struct ct_atc *atc) static int atc_get_resources(struct ct_atc *atc) { struct daio_desc da_desc = {0}; struct daio_mgr *daio_mgr; Loading Loading @@ -1407,16 +1423,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc) atc->n_pcm++; } err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); if (err) { printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); return err; } return 0; } static void __devinit static void atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, struct src **srcs, struct srcimp **srcimps) { Loading Loading @@ -1455,7 +1465,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ } static void __devinit atc_connect_resources(struct ct_atc *atc) static void atc_connect_resources(struct ct_atc *atc) { struct dai *dai; struct dao *dao; Loading Loading @@ -1501,6 +1511,84 @@ static void __devinit atc_connect_resources(struct ct_atc *atc) } } #ifdef CONFIG_PM static int atc_suspend(struct ct_atc *atc, pm_message_t state) { int i; struct hw *hw = atc->hw; snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot); for (i = FRONT; i < NUM_PCMS; i++) { if (!atc->pcms[i]) continue; snd_pcm_suspend_all(atc->pcms[i]); } atc_release_resources(atc); hw->suspend(hw, state); return 0; } static int atc_hw_resume(struct ct_atc *atc) { struct hw *hw = atc->hw; struct card_conf info = {0}; /* Re-initialize card hardware. */ info.rsr = atc->rsr; info.msr = atc->msr; info.vm_pgt_phys = atc_get_ptp_phys(atc, 0); return hw->resume(hw, &info); } static int atc_resources_resume(struct ct_atc *atc) { struct ct_mixer *mixer; int err = 0; /* Get resources */ err = atc_get_resources(atc); if (err < 0) { atc_release_resources(atc); return err; } /* Build topology */ atc_connect_resources(atc); mixer = atc->mixer; mixer->resume(mixer); return 0; } static int atc_resume(struct ct_atc *atc) { int err = 0; /* Do hardware resume. */ err = atc_hw_resume(atc); if (err < 0) { printk(KERN_ERR "ctxfi: pci_enable_device failed, " "disabling device\n"); snd_card_disconnect(atc->card); return err; } err = atc_resources_resume(atc); if (err < 0) return err; snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0); return 0; } #endif static struct ct_atc atc_preset __devinitdata = { .map_audio_buffer = ct_map_audio_buffer, .unmap_audio_buffer = ct_unmap_audio_buffer, Loading Loading @@ -1529,6 +1617,10 @@ static struct ct_atc atc_preset __devinitdata = { .spdif_out_set_status = atc_spdif_out_set_status, .spdif_out_passthru = atc_spdif_out_passthru, .have_digit_io_switch = atc_have_digit_io_switch, #ifdef CONFIG_PM .suspend = atc_suspend, .resume = atc_resume, #endif }; /** Loading Loading @@ -1587,6 +1679,12 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, if (err < 0) goto error1; err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); if (err) { printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); goto error1; } /* Get resources */ err = atc_get_resources(atc); if (err < 0) Loading sound/pci/ctxfi/ctatc.h +7 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,13 @@ struct ct_atc { unsigned char n_pcm; struct ct_timer *timer; #ifdef CONFIG_PM int (*suspend)(struct ct_atc *atc, pm_message_t state); int (*resume)(struct ct_atc *atc); #define NUM_PCMS (NUM_CTALSADEVS - 1) struct snd_pcm *pcms[NUM_PCMS]; #endif }; Loading sound/pci/ctxfi/cthardware.h +7 −0 Original line number Diff line number Diff line Loading @@ -30,13 +30,16 @@ enum CHIPTYP { enum CTCARDS { /* 20k1 models */ CTSB055X, CT20K1_MODEL_FIRST = CTSB055X, CTSB073X, CTUAA, CT20K1_UNKNOWN, /* 20k2 models */ CTSB0760, CT20K2_MODEL_FIRST = CTSB0760, CTHENDRIX, CTSB0880, CT20K2_UNKNOWN, NUM_CTCARDS /* This should always be the last */ }; Loading @@ -61,6 +64,10 @@ struct hw { int (*card_init)(struct hw *hw, struct card_conf *info); int (*card_stop)(struct hw *hw); int (*pll_init)(struct hw *hw, unsigned int rsr); #ifdef CONFIG_PM int (*suspend)(struct hw *hw, pm_message_t state); int (*resume)(struct hw *hw, struct card_conf *info); #endif int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); int (*select_adc_source)(struct hw *hw, enum ADCSRC source); int (*have_digit_io_switch)(struct hw *hw); Loading sound/pci/ctxfi/cthw20k1.c +66 −17 Original line number Diff line number Diff line Loading @@ -1911,21 +1911,27 @@ static int hw_card_start(struct hw *hw) goto error1; } if (!hw->io_base) { err = pci_request_regions(pci, "XFi"); if (err < 0) goto error1; if (hw->model == CTUAA) hw->io_base = pci_resource_start(pci, 5); else hw->io_base = pci_resource_start(pci, 0); } /* Switch to X-Fi mode from UAA mode if neeeded */ if (hw->model == CTUAA) { err = uaa_to_xfi(pci); if (err) goto error2; hw->io_base = pci_resource_start(pci, 5); } else { hw->io_base = pci_resource_start(pci, 0); } if (hw->irq < 0) { err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, "ctxfi", hw); if (err < 0) { Loading @@ -1933,6 +1939,7 @@ static int hw_card_start(struct hw *hw) goto error2; } hw->irq = pci->irq; } pci_set_master(pci); Loading @@ -1948,6 +1955,15 @@ static int hw_card_start(struct hw *hw) static int hw_card_stop(struct hw *hw) { unsigned int data; /* disable transport bus master and queueing of request */ hw_write_20kx(hw, TRNCTL, 0x00); /* disable pll */ data = hw_read_20kx(hw, PLLCTL); hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12)))); /* TODO: Disable interrupt and so on... */ if (hw->irq >= 0) synchronize_irq(hw->irq); Loading Loading @@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) struct trn_conf trn_info = {0}; /* Get PCI io port base address and do Hendrix switch if needed. */ if (!hw->io_base) { err = hw_card_start(hw); if (err) return err; } /* PLL init */ err = hw_pll_init(hw, info->rsr); Loading Loading @@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } #ifdef CONFIG_PM static int hw_suspend(struct hw *hw, pm_message_t state) { struct pci_dev *pci = hw->pci; hw_card_stop(hw); if (hw->model == CTUAA) { /* Switch to UAA config space. */ pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); } pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } static int hw_resume(struct hw *hw, struct card_conf *info) { struct pci_dev *pci = hw->pci; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); /* Re-initialize card hardware. */ return hw_card_init(hw, info); } #endif static u32 hw_read_20kx(struct hw *hw, u32 reg) { u32 value; Loading Loading @@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, #ifdef CONFIG_PM .suspend = hw_suspend, .resume = hw_resume, #endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, Loading sound/pci/ctxfi/cthw20k2.c +52 −13 Original line number Diff line number Diff line Loading @@ -1860,6 +1860,7 @@ static int hw_card_start(struct hw *hw) goto error1; } if (!hw->io_base) { err = pci_request_regions(pci, "XFi"); if (err < 0) goto error1; Loading @@ -1871,6 +1872,7 @@ static int hw_card_start(struct hw *hw) err = -ENOENT; goto error2; } } /* Switch to 20k2 mode from UAA mode. */ gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL); Loading Loading @@ -1901,6 +1903,15 @@ static int hw_card_start(struct hw *hw) static int hw_card_stop(struct hw *hw) { unsigned int data; /* disable transport bus master and queueing of request */ hw_write_20kx(hw, TRANSPORT_CTL, 0x00); /* disable pll */ data = hw_read_20kx(hw, PLL_ENB); hw_write_20kx(hw, PLL_ENB, (data & (~0x07))); /* TODO: Disable interrupt and so on... */ return 0; } Loading Loading @@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) /* Get PCI io port/memory base address and * do 20kx core switch if needed. */ if (!hw->io_base) { err = hw_card_start(hw); if (err) return err; } /* PLL init */ err = hw_pll_init(hw, info->rsr); Loading Loading @@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } #ifdef CONFIG_PM static int hw_suspend(struct hw *hw, pm_message_t state) { struct pci_dev *pci = hw->pci; hw_card_stop(hw); pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } static int hw_resume(struct hw *hw, struct card_conf *info) { struct pci_dev *pci = hw->pci; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); /* Re-initialize card hardware. */ return hw_card_init(hw, info); } #endif static u32 hw_read_20kx(struct hw *hw, u32 reg) { return readl((void *)(hw->mem_base + reg)); Loading @@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, #ifdef CONFIG_PM .suspend = hw_suspend, .resume = hw_resume, #endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, Loading Loading
sound/pci/ctxfi/ctatc.c +152 −54 Original line number Diff line number Diff line Loading @@ -46,8 +46,6 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000, "UAA", CTUAA), SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE, "Unknown", CT20K1_UNKNOWN), { } /* terminator */ }; Loading @@ -67,13 +65,16 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = { }; static const char *ct_subsys_name[NUM_CTCARDS] = { /* 20k1 models */ [CTSB055X] = "SB055x", [CTSB073X] = "SB073x", [CTSB0760] = "SB076x", [CTUAA] = "UAA", [CT20K1_UNKNOWN] = "Unknown", /* 20k2 models */ [CTSB0760] = "SB076x", [CTHENDRIX] = "Hendrix", [CTSB0880] = "SB0880", [CT20K2_UNKNOWN] = "Unknown", }; static struct { Loading Loading @@ -260,13 +261,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int device = apcm->substream->pcm->device; unsigned int pitch; if (NULL != apcm->src) { /* Prepared pcm playback */ return 0; } /* first release old resources */ atc->pcm_release_resources(atc, apcm); atc_pcm_release_resources(atc, apcm); /* Get SRC resource */ desc.multi = apcm->substream->runtime->channels; Loading Loading @@ -660,10 +656,7 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) unsigned int pitch; int mix_base = 0, imp_base = 0; if (NULL != apcm->src) { /* Prepared pcm capture */ return 0; } atc_pcm_release_resources(atc, apcm); /* Get needed resources. */ err = atc_pcm_capture_get_resources(atc, apcm); Loading Loading @@ -866,7 +859,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); unsigned int rate = apcm->substream->runtime->rate; unsigned int status; int err; int err = 0; unsigned char iec958_con_fs; switch (rate) { Loading Loading @@ -907,8 +900,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int err; int i; if (NULL != apcm->src) return 0; atc_pcm_release_resources(atc, apcm); /* Configure SPDIFOO and PLL to passthrough mode; * determine pll_rate. */ Loading Loading @@ -1115,32 +1107,20 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) return err; } static int ct_atc_destroy(struct ct_atc *atc) static int atc_release_resources(struct ct_atc *atc) { struct daio_mgr *daio_mgr; struct dao *dao; struct dai *dai; struct daio *daio; struct sum_mgr *sum_mgr; struct src_mgr *src_mgr; struct srcimp_mgr *srcimp_mgr; struct srcimp *srcimp; struct ct_mixer *mixer; int i = 0; if (NULL == atc) return 0; if (atc->timer) { ct_timer_free(atc->timer); atc->timer = NULL; } /* Stop hardware and disable all interrupts */ if (NULL != atc->hw) ((struct hw *)atc->hw)->card_stop(atc->hw); /* Destroy internal mixer objects */ int i; struct daio_mgr *daio_mgr = NULL; struct dao *dao = NULL; struct dai *dai = NULL; struct daio *daio = NULL; struct sum_mgr *sum_mgr = NULL; struct src_mgr *src_mgr = NULL; struct srcimp_mgr *srcimp_mgr = NULL; struct srcimp *srcimp = NULL; struct ct_mixer *mixer = NULL; /* disconnect internal mixer objects */ if (NULL != atc->mixer) { mixer = atc->mixer; mixer->set_input_left(mixer, MIX_LINE_IN, NULL); Loading @@ -1149,7 +1129,6 @@ static int ct_atc_destroy(struct ct_atc *atc) mixer->set_input_right(mixer, MIX_MIC_IN, NULL); mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL); mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); ct_mixer_destroy(atc->mixer); } if (NULL != atc->daios) { Loading @@ -1167,6 +1146,7 @@ static int ct_atc_destroy(struct ct_atc *atc) daio_mgr->put_daio(daio_mgr, daio); } kfree(atc->daios); atc->daios = NULL; } if (NULL != atc->pcm) { Loading @@ -1175,6 +1155,7 @@ static int ct_atc_destroy(struct ct_atc *atc) sum_mgr->put_sum(sum_mgr, atc->pcm[i]); kfree(atc->pcm); atc->pcm = NULL; } if (NULL != atc->srcs) { Loading @@ -1183,6 +1164,7 @@ static int ct_atc_destroy(struct ct_atc *atc) src_mgr->put_src(src_mgr, atc->srcs[i]); kfree(atc->srcs); atc->srcs = NULL; } if (NULL != atc->srcimps) { Loading @@ -1193,8 +1175,30 @@ static int ct_atc_destroy(struct ct_atc *atc) srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); } kfree(atc->srcimps); atc->srcimps = NULL; } return 0; } static int ct_atc_destroy(struct ct_atc *atc) { int i = 0; if (NULL == atc) return 0; if (atc->timer) { ct_timer_free(atc->timer); atc->timer = NULL; } atc_release_resources(atc); /* Destroy internal mixer objects */ if (NULL != atc->mixer) ct_mixer_destroy(atc->mixer); for (i = 0; i < NUM_RSCTYP; i++) { if ((NULL != rsc_mgr_funcs[i].destroy) && (NULL != atc->rsc_mgrs[i])) Loading Loading @@ -1240,9 +1244,21 @@ static int __devinit atc_identify_card(struct ct_atc *atc) return -ENOENT; } p = snd_pci_quirk_lookup(atc->pci, list); if (!p) if (p) { if (p->value < 0) { printk(KERN_ERR "ctxfi: " "Device %04x:%04x is black-listed\n", atc->pci->subsystem_vendor, atc->pci->subsystem_device); return -ENOENT; } atc->model = p->value; } else { if (atc->chip_type == ATC20K1) atc->model = CT20K1_UNKNOWN; else atc->model = CT20K2_UNKNOWN; } atc->model_name = ct_subsys_name[atc->model]; snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", atc->chip_name, atc->model_name, Loading Loading @@ -1310,7 +1326,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc) return 0; } static int __devinit atc_get_resources(struct ct_atc *atc) static int atc_get_resources(struct ct_atc *atc) { struct daio_desc da_desc = {0}; struct daio_mgr *daio_mgr; Loading Loading @@ -1407,16 +1423,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc) atc->n_pcm++; } err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); if (err) { printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); return err; } return 0; } static void __devinit static void atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, struct src **srcs, struct srcimp **srcimps) { Loading Loading @@ -1455,7 +1465,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ } static void __devinit atc_connect_resources(struct ct_atc *atc) static void atc_connect_resources(struct ct_atc *atc) { struct dai *dai; struct dao *dao; Loading Loading @@ -1501,6 +1511,84 @@ static void __devinit atc_connect_resources(struct ct_atc *atc) } } #ifdef CONFIG_PM static int atc_suspend(struct ct_atc *atc, pm_message_t state) { int i; struct hw *hw = atc->hw; snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot); for (i = FRONT; i < NUM_PCMS; i++) { if (!atc->pcms[i]) continue; snd_pcm_suspend_all(atc->pcms[i]); } atc_release_resources(atc); hw->suspend(hw, state); return 0; } static int atc_hw_resume(struct ct_atc *atc) { struct hw *hw = atc->hw; struct card_conf info = {0}; /* Re-initialize card hardware. */ info.rsr = atc->rsr; info.msr = atc->msr; info.vm_pgt_phys = atc_get_ptp_phys(atc, 0); return hw->resume(hw, &info); } static int atc_resources_resume(struct ct_atc *atc) { struct ct_mixer *mixer; int err = 0; /* Get resources */ err = atc_get_resources(atc); if (err < 0) { atc_release_resources(atc); return err; } /* Build topology */ atc_connect_resources(atc); mixer = atc->mixer; mixer->resume(mixer); return 0; } static int atc_resume(struct ct_atc *atc) { int err = 0; /* Do hardware resume. */ err = atc_hw_resume(atc); if (err < 0) { printk(KERN_ERR "ctxfi: pci_enable_device failed, " "disabling device\n"); snd_card_disconnect(atc->card); return err; } err = atc_resources_resume(atc); if (err < 0) return err; snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0); return 0; } #endif static struct ct_atc atc_preset __devinitdata = { .map_audio_buffer = ct_map_audio_buffer, .unmap_audio_buffer = ct_unmap_audio_buffer, Loading Loading @@ -1529,6 +1617,10 @@ static struct ct_atc atc_preset __devinitdata = { .spdif_out_set_status = atc_spdif_out_set_status, .spdif_out_passthru = atc_spdif_out_passthru, .have_digit_io_switch = atc_have_digit_io_switch, #ifdef CONFIG_PM .suspend = atc_suspend, .resume = atc_resume, #endif }; /** Loading Loading @@ -1587,6 +1679,12 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, if (err < 0) goto error1; err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer); if (err) { printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n"); goto error1; } /* Get resources */ err = atc_get_resources(atc); if (err < 0) Loading
sound/pci/ctxfi/ctatc.h +7 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,13 @@ struct ct_atc { unsigned char n_pcm; struct ct_timer *timer; #ifdef CONFIG_PM int (*suspend)(struct ct_atc *atc, pm_message_t state); int (*resume)(struct ct_atc *atc); #define NUM_PCMS (NUM_CTALSADEVS - 1) struct snd_pcm *pcms[NUM_PCMS]; #endif }; Loading
sound/pci/ctxfi/cthardware.h +7 −0 Original line number Diff line number Diff line Loading @@ -30,13 +30,16 @@ enum CHIPTYP { enum CTCARDS { /* 20k1 models */ CTSB055X, CT20K1_MODEL_FIRST = CTSB055X, CTSB073X, CTUAA, CT20K1_UNKNOWN, /* 20k2 models */ CTSB0760, CT20K2_MODEL_FIRST = CTSB0760, CTHENDRIX, CTSB0880, CT20K2_UNKNOWN, NUM_CTCARDS /* This should always be the last */ }; Loading @@ -61,6 +64,10 @@ struct hw { int (*card_init)(struct hw *hw, struct card_conf *info); int (*card_stop)(struct hw *hw); int (*pll_init)(struct hw *hw, unsigned int rsr); #ifdef CONFIG_PM int (*suspend)(struct hw *hw, pm_message_t state); int (*resume)(struct hw *hw, struct card_conf *info); #endif int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); int (*select_adc_source)(struct hw *hw, enum ADCSRC source); int (*have_digit_io_switch)(struct hw *hw); Loading
sound/pci/ctxfi/cthw20k1.c +66 −17 Original line number Diff line number Diff line Loading @@ -1911,21 +1911,27 @@ static int hw_card_start(struct hw *hw) goto error1; } if (!hw->io_base) { err = pci_request_regions(pci, "XFi"); if (err < 0) goto error1; if (hw->model == CTUAA) hw->io_base = pci_resource_start(pci, 5); else hw->io_base = pci_resource_start(pci, 0); } /* Switch to X-Fi mode from UAA mode if neeeded */ if (hw->model == CTUAA) { err = uaa_to_xfi(pci); if (err) goto error2; hw->io_base = pci_resource_start(pci, 5); } else { hw->io_base = pci_resource_start(pci, 0); } if (hw->irq < 0) { err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, "ctxfi", hw); if (err < 0) { Loading @@ -1933,6 +1939,7 @@ static int hw_card_start(struct hw *hw) goto error2; } hw->irq = pci->irq; } pci_set_master(pci); Loading @@ -1948,6 +1955,15 @@ static int hw_card_start(struct hw *hw) static int hw_card_stop(struct hw *hw) { unsigned int data; /* disable transport bus master and queueing of request */ hw_write_20kx(hw, TRNCTL, 0x00); /* disable pll */ data = hw_read_20kx(hw, PLLCTL); hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12)))); /* TODO: Disable interrupt and so on... */ if (hw->irq >= 0) synchronize_irq(hw->irq); Loading Loading @@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) struct trn_conf trn_info = {0}; /* Get PCI io port base address and do Hendrix switch if needed. */ if (!hw->io_base) { err = hw_card_start(hw); if (err) return err; } /* PLL init */ err = hw_pll_init(hw, info->rsr); Loading Loading @@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } #ifdef CONFIG_PM static int hw_suspend(struct hw *hw, pm_message_t state) { struct pci_dev *pci = hw->pci; hw_card_stop(hw); if (hw->model == CTUAA) { /* Switch to UAA config space. */ pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0); } pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } static int hw_resume(struct hw *hw, struct card_conf *info) { struct pci_dev *pci = hw->pci; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); /* Re-initialize card hardware. */ return hw_card_init(hw, info); } #endif static u32 hw_read_20kx(struct hw *hw, u32 reg) { u32 value; Loading Loading @@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, #ifdef CONFIG_PM .suspend = hw_suspend, .resume = hw_resume, #endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, Loading
sound/pci/ctxfi/cthw20k2.c +52 −13 Original line number Diff line number Diff line Loading @@ -1860,6 +1860,7 @@ static int hw_card_start(struct hw *hw) goto error1; } if (!hw->io_base) { err = pci_request_regions(pci, "XFi"); if (err < 0) goto error1; Loading @@ -1871,6 +1872,7 @@ static int hw_card_start(struct hw *hw) err = -ENOENT; goto error2; } } /* Switch to 20k2 mode from UAA mode. */ gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL); Loading Loading @@ -1901,6 +1903,15 @@ static int hw_card_start(struct hw *hw) static int hw_card_stop(struct hw *hw) { unsigned int data; /* disable transport bus master and queueing of request */ hw_write_20kx(hw, TRANSPORT_CTL, 0x00); /* disable pll */ data = hw_read_20kx(hw, PLL_ENB); hw_write_20kx(hw, PLL_ENB, (data & (~0x07))); /* TODO: Disable interrupt and so on... */ return 0; } Loading Loading @@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) /* Get PCI io port/memory base address and * do 20kx core switch if needed. */ if (!hw->io_base) { err = hw_card_start(hw); if (err) return err; } /* PLL init */ err = hw_pll_init(hw, info->rsr); Loading Loading @@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) return 0; } #ifdef CONFIG_PM static int hw_suspend(struct hw *hw, pm_message_t state) { struct pci_dev *pci = hw->pci; hw_card_stop(hw); pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } static int hw_resume(struct hw *hw, struct card_conf *info) { struct pci_dev *pci = hw->pci; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); /* Re-initialize card hardware. */ return hw_card_init(hw, info); } #endif static u32 hw_read_20kx(struct hw *hw, u32 reg) { return readl((void *)(hw->mem_base + reg)); Loading @@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = { .is_adc_source_selected = hw_is_adc_input_selected, .select_adc_source = hw_adc_input_select, .have_digit_io_switch = hw_have_digit_io_switch, #ifdef CONFIG_PM .suspend = hw_suspend, .resume = hw_resume, #endif .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, Loading