Loading include/sound/cs46xx.h +4 −0 Original line number Diff line number Diff line Loading @@ -1723,6 +1723,10 @@ struct snd_cs46xx { struct snd_cs46xx_pcm *playback_pcm; unsigned int play_ctl; #endif #ifdef CONFIG_PM u32 *saved_regs; #endif }; int snd_cs46xx_create(struct snd_card *card, Loading include/sound/cs46xx_dsp_spos.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ struct dsp_scb_descriptor { char scb_name[DSP_MAX_SCB_NAME]; u32 address; int index; u32 *data; struct dsp_scb_descriptor * sub_list_ptr; struct dsp_scb_descriptor * next_scb_ptr; Loading @@ -127,6 +128,7 @@ struct dsp_task_descriptor { int size; u32 address; int index; u32 *data; }; struct dsp_pcm_channel_descriptor { Loading sound/pci/cs46xx/cs46xx_lib.c +62 −15 Original line number Diff line number Diff line Loading @@ -2897,6 +2897,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) } #endif #ifdef CONFIG_PM kfree(chip->saved_regs); #endif pci_disable_device(chip->pci); kfree(chip); return 0; Loading Loading @@ -3140,6 +3144,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) /* * start and load DSP */ static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) { unsigned int tmp; snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); tmp = snd_cs46xx_peek(chip, BA1_PFIE); tmp &= ~0x0000f03f; snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ tmp = snd_cs46xx_peek(chip, BA1_CIE); tmp &= ~0x0000003f; tmp |= 0x00000001; snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ } int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) { unsigned int tmp; Loading Loading @@ -3214,19 +3235,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) snd_cs46xx_proc_start(chip); /* * Enable interrupts on the part. */ snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); tmp = snd_cs46xx_peek(chip, BA1_PFIE); tmp &= ~0x0000f03f; snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ tmp = snd_cs46xx_peek(chip, BA1_CIE); tmp &= ~0x0000003f; tmp |= 0x00000001; snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ cs46xx_enable_stream_irqs(chip); #ifndef CONFIG_SND_CS46XX_NEW_DSP /* set the attenuation to 0dB */ Loading Loading @@ -3665,11 +3674,19 @@ static struct cs_card_type __devinitdata cards[] = { * APM support */ #ifdef CONFIG_PM static unsigned int saved_regs[] = { BA0_ACOSV, BA0_ASER_FADDR, BA0_ASER_MASTER, BA1_PVOL, BA1_CVOL, }; int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; int amp_saved; int i, amp_saved; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->in_suspend = 1; Loading @@ -3680,6 +3697,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); /* save some registers */ for (i = 0; i < ARRAY_SIZE(saved_regs); i++) chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); amp_saved = chip->amplifier; /* turn off amp */ chip->amplifier_ctrl(chip, -chip->amplifier); Loading @@ -3698,7 +3719,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; int amp_saved; int i, amp_saved; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); Loading @@ -3716,6 +3737,16 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_cs46xx_chip_init(chip); snd_cs46xx_reset(chip); #ifdef CONFIG_SND_CS46XX_NEW_DSP cs46xx_dsp_resume(chip); /* restore some registers */ for (i = 0; i < ARRAY_SIZE(saved_regs); i++) snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); #else snd_cs46xx_download_image(chip); #endif #if 0 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, chip->ac97_general_purpose); Loading @@ -3730,6 +3761,13 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); /* reset playback/capture */ snd_cs46xx_set_play_sample_rate(chip, 8000); snd_cs46xx_set_capture_sample_rate(chip, 8000); snd_cs46xx_proc_start(chip); cs46xx_enable_stream_irqs(chip); if (amp_saved) chip->amplifier_ctrl(chip, 1); /* turn amp on */ else Loading Loading @@ -3896,6 +3934,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card, snd_cs46xx_proc_init(card, chip); #ifdef CONFIG_PM chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * ARRAY_SIZE(saved_regs), GFP_KERNEL); if (!chip->saved_regs) { snd_cs46xx_free(chip); return -ENOMEM; } #endif chip->active_ctrl(chip, -1); /* disable CLKRUN */ snd_card_set_dev(card, &pci->dev); Loading sound/pci/cs46xx/cs46xx_lib.h +3 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,9 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); #ifdef CONFIG_PM int cs46xx_dsp_resume(struct snd_cs46xx * chip); #endif struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type); #ifdef CONFIG_PROC_FS Loading sound/pci/cs46xx/dsp_spos.c +126 −44 Original line number Diff line number Diff line Loading @@ -306,55 +306,38 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) mutex_unlock(&chip->spos_mutex); } int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) static int dsp_load_parameter(struct snd_cs46xx *chip, struct dsp_segment_desc *parameter) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER); struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE); u32 doffset, dsize; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); return -ENOMEM; } snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name); if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing parameter area\n"); snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } if (parameter == NULL) { if (!parameter) { snd_printdd("dsp_spos: module got no parameter segment\n"); } else { if (ins->nmodules > 0) { snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n"); return 0; } doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); dsize = parameter->size * 4; snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n", snd_printdd("dsp_spos: " "downloading parameter data to chip (%08x-%08x)\n", doffset,doffset + dsize); if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n"); snd_printk(KERN_ERR "dsp_spos: " "failed to download parameter data to DSP\n"); return -EINVAL; } return 0; } if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } static int dsp_load_sample(struct snd_cs46xx *chip, struct dsp_segment_desc *sample) { u32 doffset, dsize; if (sample == NULL) { if (!sample) { snd_printdd("dsp_spos: module got no sample segment\n"); } else { if (ins->nmodules > 0) { snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n"); return 0; } doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); Loading @@ -367,8 +350,42 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); return -EINVAL; } return 0; } int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); u32 doffset, dsize; int err; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); return -ENOMEM; } snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name); if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing parameter area\n"); snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } err = dsp_load_parameter(chip, get_segment_desc(module, SEGTYPE_SP_PARAMETER)); if (err < 0) return err; if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } err = dsp_load_sample(chip, get_segment_desc(module, SEGTYPE_SP_SAMPLE)); if (err < 0) return err; if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing code area\n"); Loading Loading @@ -986,7 +1003,10 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) return NULL; } if (name) strcpy(ins->tasks[ins->ntask].task_name, name); else strcpy(ins->tasks[ins->ntask].task_name, "(NULL)"); ins->tasks[ins->ntask].address = dest; ins->tasks[ins->ntask].size = size; Loading @@ -995,6 +1015,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) desc = (ins->tasks + ins->ntask); ins->ntask++; if (name) add_symbol (chip,name,dest,SYMBOL_PARAMETER); return desc; } Loading @@ -1006,6 +1027,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 desc = _map_scb (chip,name,dest); if (desc) { desc->data = scb_data; _dsp_create_scb(chip,scb_data,dest); } else { snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); Loading @@ -1023,6 +1045,7 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da desc = _map_task_tree (chip,name,dest,size); if (desc) { desc->data = task_data; _dsp_create_task_tree(chip,task_data,dest,size); } else { snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); Loading Loading @@ -1320,8 +1343,10 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) 0x0000ffff }; /* dirty hack ... */ _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); if (!cs46xx_dsp_create_task_tree(chip, NULL, (u32 *)&mix2_ostream_spb, WRITE_BACK_SPB, 2)) goto _fail_end; } /* input sample converter */ Loading Loading @@ -1622,7 +1647,6 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, return 0; } static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; Loading Loading @@ -1894,3 +1918,61 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) return 0; } #ifdef CONFIG_PM int cs46xx_dsp_resume(struct snd_cs46xx * chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; int i, err; /* clear parameter, sample and code areas */ snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE); for (i = 0; i < ins->nmodules; i++) { struct dsp_module_desc *module = &ins->modules[i]; struct dsp_segment_desc *seg; u32 doffset, dsize; seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER); err = dsp_load_parameter(chip, seg); if (err < 0) return err; seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE); err = dsp_load_sample(chip, seg); if (err < 0) return err; seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM); if (!seg) continue; doffset = seg->offset * 4 + module->load_address * 4 + DSP_CODE_BYTE_OFFSET; dsize = seg->size * 4; err = snd_cs46xx_download(chip, ins->code.data + module->load_address, doffset, dsize); if (err < 0) return err; } for (i = 0; i < ins->ntask; i++) { struct dsp_task_descriptor *t = &ins->tasks[i]; _dsp_create_task_tree(chip, t->data, t->address, t->size); } for (i = 0; i < ins->nscb; i++) { struct dsp_scb_descriptor *s = &ins->scbs[i]; if (s->deleted) continue; _dsp_create_scb(chip, s->data, s->address); } return 0; } #endif Loading
include/sound/cs46xx.h +4 −0 Original line number Diff line number Diff line Loading @@ -1723,6 +1723,10 @@ struct snd_cs46xx { struct snd_cs46xx_pcm *playback_pcm; unsigned int play_ctl; #endif #ifdef CONFIG_PM u32 *saved_regs; #endif }; int snd_cs46xx_create(struct snd_card *card, Loading
include/sound/cs46xx_dsp_spos.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ struct dsp_scb_descriptor { char scb_name[DSP_MAX_SCB_NAME]; u32 address; int index; u32 *data; struct dsp_scb_descriptor * sub_list_ptr; struct dsp_scb_descriptor * next_scb_ptr; Loading @@ -127,6 +128,7 @@ struct dsp_task_descriptor { int size; u32 address; int index; u32 *data; }; struct dsp_pcm_channel_descriptor { Loading
sound/pci/cs46xx/cs46xx_lib.c +62 −15 Original line number Diff line number Diff line Loading @@ -2897,6 +2897,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) } #endif #ifdef CONFIG_PM kfree(chip->saved_regs); #endif pci_disable_device(chip->pci); kfree(chip); return 0; Loading Loading @@ -3140,6 +3144,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) /* * start and load DSP */ static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) { unsigned int tmp; snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); tmp = snd_cs46xx_peek(chip, BA1_PFIE); tmp &= ~0x0000f03f; snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ tmp = snd_cs46xx_peek(chip, BA1_CIE); tmp &= ~0x0000003f; tmp |= 0x00000001; snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ } int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) { unsigned int tmp; Loading Loading @@ -3214,19 +3235,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) snd_cs46xx_proc_start(chip); /* * Enable interrupts on the part. */ snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); tmp = snd_cs46xx_peek(chip, BA1_PFIE); tmp &= ~0x0000f03f; snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ tmp = snd_cs46xx_peek(chip, BA1_CIE); tmp &= ~0x0000003f; tmp |= 0x00000001; snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ cs46xx_enable_stream_irqs(chip); #ifndef CONFIG_SND_CS46XX_NEW_DSP /* set the attenuation to 0dB */ Loading Loading @@ -3665,11 +3674,19 @@ static struct cs_card_type __devinitdata cards[] = { * APM support */ #ifdef CONFIG_PM static unsigned int saved_regs[] = { BA0_ACOSV, BA0_ASER_FADDR, BA0_ASER_MASTER, BA1_PVOL, BA1_CVOL, }; int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; int amp_saved; int i, amp_saved; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->in_suspend = 1; Loading @@ -3680,6 +3697,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); /* save some registers */ for (i = 0; i < ARRAY_SIZE(saved_regs); i++) chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); amp_saved = chip->amplifier; /* turn off amp */ chip->amplifier_ctrl(chip, -chip->amplifier); Loading @@ -3698,7 +3719,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; int amp_saved; int i, amp_saved; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); Loading @@ -3716,6 +3737,16 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_cs46xx_chip_init(chip); snd_cs46xx_reset(chip); #ifdef CONFIG_SND_CS46XX_NEW_DSP cs46xx_dsp_resume(chip); /* restore some registers */ for (i = 0; i < ARRAY_SIZE(saved_regs); i++) snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); #else snd_cs46xx_download_image(chip); #endif #if 0 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, chip->ac97_general_purpose); Loading @@ -3730,6 +3761,13 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); /* reset playback/capture */ snd_cs46xx_set_play_sample_rate(chip, 8000); snd_cs46xx_set_capture_sample_rate(chip, 8000); snd_cs46xx_proc_start(chip); cs46xx_enable_stream_irqs(chip); if (amp_saved) chip->amplifier_ctrl(chip, 1); /* turn amp on */ else Loading Loading @@ -3896,6 +3934,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card, snd_cs46xx_proc_init(card, chip); #ifdef CONFIG_PM chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * ARRAY_SIZE(saved_regs), GFP_KERNEL); if (!chip->saved_regs) { snd_cs46xx_free(chip); return -ENOMEM; } #endif chip->active_ctrl(chip, -1); /* disable CLKRUN */ snd_card_set_dev(card, &pci->dev); Loading
sound/pci/cs46xx/cs46xx_lib.h +3 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,9 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); #ifdef CONFIG_PM int cs46xx_dsp_resume(struct snd_cs46xx * chip); #endif struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type); #ifdef CONFIG_PROC_FS Loading
sound/pci/cs46xx/dsp_spos.c +126 −44 Original line number Diff line number Diff line Loading @@ -306,55 +306,38 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) mutex_unlock(&chip->spos_mutex); } int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) static int dsp_load_parameter(struct snd_cs46xx *chip, struct dsp_segment_desc *parameter) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER); struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE); u32 doffset, dsize; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); return -ENOMEM; } snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name); if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing parameter area\n"); snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } if (parameter == NULL) { if (!parameter) { snd_printdd("dsp_spos: module got no parameter segment\n"); } else { if (ins->nmodules > 0) { snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n"); return 0; } doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); dsize = parameter->size * 4; snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n", snd_printdd("dsp_spos: " "downloading parameter data to chip (%08x-%08x)\n", doffset,doffset + dsize); if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n"); snd_printk(KERN_ERR "dsp_spos: " "failed to download parameter data to DSP\n"); return -EINVAL; } return 0; } if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } static int dsp_load_sample(struct snd_cs46xx *chip, struct dsp_segment_desc *sample) { u32 doffset, dsize; if (sample == NULL) { if (!sample) { snd_printdd("dsp_spos: module got no sample segment\n"); } else { if (ins->nmodules > 0) { snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n"); return 0; } doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); Loading @@ -367,8 +350,42 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); return -EINVAL; } return 0; } int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); u32 doffset, dsize; int err; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); return -ENOMEM; } snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name); if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing parameter area\n"); snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } err = dsp_load_parameter(chip, get_segment_desc(module, SEGTYPE_SP_PARAMETER)); if (err < 0) return err; if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } err = dsp_load_sample(chip, get_segment_desc(module, SEGTYPE_SP_SAMPLE)); if (err < 0) return err; if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing code area\n"); Loading Loading @@ -986,7 +1003,10 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) return NULL; } if (name) strcpy(ins->tasks[ins->ntask].task_name, name); else strcpy(ins->tasks[ins->ntask].task_name, "(NULL)"); ins->tasks[ins->ntask].address = dest; ins->tasks[ins->ntask].size = size; Loading @@ -995,6 +1015,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) desc = (ins->tasks + ins->ntask); ins->ntask++; if (name) add_symbol (chip,name,dest,SYMBOL_PARAMETER); return desc; } Loading @@ -1006,6 +1027,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 desc = _map_scb (chip,name,dest); if (desc) { desc->data = scb_data; _dsp_create_scb(chip,scb_data,dest); } else { snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); Loading @@ -1023,6 +1045,7 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da desc = _map_task_tree (chip,name,dest,size); if (desc) { desc->data = task_data; _dsp_create_task_tree(chip,task_data,dest,size); } else { snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); Loading Loading @@ -1320,8 +1343,10 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) 0x0000ffff }; /* dirty hack ... */ _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); if (!cs46xx_dsp_create_task_tree(chip, NULL, (u32 *)&mix2_ostream_spb, WRITE_BACK_SPB, 2)) goto _fail_end; } /* input sample converter */ Loading Loading @@ -1622,7 +1647,6 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, return 0; } static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; Loading Loading @@ -1894,3 +1918,61 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) return 0; } #ifdef CONFIG_PM int cs46xx_dsp_resume(struct snd_cs46xx * chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; int i, err; /* clear parameter, sample and code areas */ snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE); for (i = 0; i < ins->nmodules; i++) { struct dsp_module_desc *module = &ins->modules[i]; struct dsp_segment_desc *seg; u32 doffset, dsize; seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER); err = dsp_load_parameter(chip, seg); if (err < 0) return err; seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE); err = dsp_load_sample(chip, seg); if (err < 0) return err; seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM); if (!seg) continue; doffset = seg->offset * 4 + module->load_address * 4 + DSP_CODE_BYTE_OFFSET; dsize = seg->size * 4; err = snd_cs46xx_download(chip, ins->code.data + module->load_address, doffset, dsize); if (err < 0) return err; } for (i = 0; i < ins->ntask; i++) { struct dsp_task_descriptor *t = &ins->tasks[i]; _dsp_create_task_tree(chip, t->data, t->address, t->size); } for (i = 0; i < ins->nscb; i++) { struct dsp_scb_descriptor *s = &ins->scbs[i]; if (s->deleted) continue; _dsp_create_scb(chip, s->data, s->address); } return 0; } #endif