--- zzzz-none-000/linux-3.10.107/sound/pci/ice1712/ice1712.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/sound/pci/ice1712/ice1712.c 2021-02-04 17:41:59.000000000 +0000 @@ -105,7 +105,7 @@ MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); -static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = { +static const struct pci_device_id snd_ice1712_ids[] = { { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ { 0, } }; @@ -394,7 +394,7 @@ err = snd_cs8427_create(ice->i2c, addr, (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427); if (err < 0) { - snd_printk(KERN_ERR "CS8427 initialization failed\n"); + dev_err(ice->card->dev, "CS8427 initialization failed\n"); return err; } ice->spdif.ops.open = open_cs8427; @@ -467,7 +467,7 @@ u16 pbkstatus; struct snd_pcm_substream *substream; pbkstatus = inw(ICEDS(ice, INTSTAT)); - /* printk(KERN_DEBUG "pbkstatus = 0x%x\n", pbkstatus); */ + /* dev_dbg(ice->card->dev, "pbkstatus = 0x%x\n", pbkstatus); */ for (idx = 0; idx < 6; idx++) { if ((pbkstatus & (3 << (idx * 2))) == 0) continue; @@ -620,10 +620,9 @@ { struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - u32 period_size, buf_size, rate, tmp, chn; + u32 period_size, rate, tmp, chn; period_size = snd_pcm_lib_period_bytes(substream) - 1; - buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; tmp = 0x0064; if (snd_pcm_format_width(runtime->format) == 16) tmp &= ~0x04; @@ -881,13 +880,11 @@ .pointer = snd_ice1712_capture_pointer, }; -static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; int err; - if (rpcm) - *rpcm = NULL; err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm); if (err < 0) return err; @@ -903,21 +900,17 @@ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(ice->pci), 64*1024, 64*1024); - if (rpcm) - *rpcm = pcm; - - printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n"); + dev_warn(ice->card->dev, + "Consumer PCM code does not work well at the moment --jk\n"); return 0; } -static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; int err; - if (rpcm) - *rpcm = NULL; err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm); if (err < 0) return err; @@ -932,9 +925,6 @@ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(ice->pci), 64*1024, 128*1024); - if (rpcm) - *rpcm = pcm; - return 0; } @@ -1050,6 +1040,8 @@ old = inb(ICEMT(ice, RATE)); if (!force && old == val) goto __out; + + ice->cur_rate = rate; outb(val, ICEMT(ice, RATE)); spin_unlock_irqrestore(&ice->reg_lock, flags); @@ -1258,13 +1250,11 @@ .pointer = snd_ice1712_capture_pro_pointer, }; -static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) +static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; int err; - if (rpcm) - *rpcm = NULL; err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm); if (err < 0) return err; @@ -1280,8 +1270,6 @@ snd_dma_pci_data(ice->pci), 256*1024, 256*1024); ice->pcm_pro = pcm; - if (rpcm) - *rpcm = pcm; if (ice->cs8427) { /* assign channels to iec958 */ @@ -1292,10 +1280,7 @@ return err; } - err = snd_ice1712_build_pro_mixer(ice); - if (err < 0) - return err; - return 0; + return snd_ice1712_build_pro_mixer(ice); } /* @@ -1539,12 +1524,12 @@ ac97.private_free = snd_ice1712_mixer_free_ac97; err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); if (err < 0) - printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); + dev_warn(ice->card->dev, + "cannot initialize ac97 for consumer, skipped\n"); else { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice)); - if (err < 0) - return err; - return 0; + return snd_ctl_add(ice->card, + snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, + ice)); } } @@ -1557,7 +1542,8 @@ ac97.private_free = snd_ice1712_mixer_free_ac97; err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); if (err < 0) - printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); + dev_warn(ice->card->dev, + "cannot initialize pro ac97, skipped\n"); else return 0; } @@ -1834,13 +1820,7 @@ "96000", /* 12: 7 */ "IEC958 Input", /* 13: -- */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 14; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 14, texts); } static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, @@ -1925,13 +1905,7 @@ "96000", /* 12: 7 */ /* "IEC958 Input", 13: -- */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 13; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 13, texts); } static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol, @@ -2052,15 +2026,8 @@ "IEC958 In L", "IEC958 In R", /* 9-10 */ "Digital Mixer", /* 11 - optional */ }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = - snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + int num_items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol, @@ -2337,7 +2304,8 @@ pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device); ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device); if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) { - printk(KERN_ERR "ice1712: No valid ID is found\n"); + dev_err(ice->card->dev, + "No valid ID is found\n"); return -ENXIO; } } @@ -2345,21 +2313,22 @@ for (tbl = card_tables; *tbl; tbl++) { for (c = *tbl; c->subvendor; c++) { if (modelname && c->model && !strcmp(modelname, c->model)) { - printk(KERN_INFO "ice1712: Using board model %s\n", c->name); + dev_info(ice->card->dev, + "Using board model %s\n", c->name); ice->eeprom.subvendor = c->subvendor; } else if (c->subvendor != ice->eeprom.subvendor) continue; if (!c->eeprom_size || !c->eeprom_data) goto found; /* if the EEPROM is given by the driver, use it */ - snd_printdd("using the defined eeprom..\n"); + dev_dbg(ice->card->dev, "using the defined eeprom..\n"); ice->eeprom.version = 1; ice->eeprom.size = c->eeprom_size + 6; memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size); goto read_skipped; } } - printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", + dev_warn(ice->card->dev, "No matching model found for ID 0x%x\n", ice->eeprom.subvendor); found: @@ -2367,12 +2336,13 @@ if (ice->eeprom.size < 6) ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */ else if (ice->eeprom.size > 32) { - snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size); + dev_err(ice->card->dev, + "invalid EEPROM (size = %i)\n", ice->eeprom.size); return -EIO; } ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05); if (ice->eeprom.version != 1) { - snd_printk(KERN_ERR "invalid EEPROM version %i\n", + dev_err(ice->card->dev, "invalid EEPROM version %i\n", ice->eeprom.version); /* return -EIO; */ } @@ -2433,6 +2403,13 @@ snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0); } snd_ice1712_set_pro_rate(ice, 48000, 1); + /* unmask used interrupts */ + outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? + ICE1712_IRQ_MPU2 : 0) | + ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? + ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0), + ICEREG(ice, IRQMASK)); + outb(0x00, ICEMT(ice, IRQ)); return 0; } @@ -2501,11 +2478,8 @@ err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice)); if (err < 0) return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); - if (err < 0) - return err; - - return 0; + return snd_ctl_add(ice->card, + snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); } static int snd_ice1712_free(struct snd_ice1712 *ice) @@ -2513,7 +2487,7 @@ if (!ice->port) goto __hw_end; /* mask all interrupts */ - outb(0xc0, ICEMT(ice, IRQ)); + outb(ICE1712_MULTI_CAPTURE | ICE1712_MULTI_PLAYBACK, ICEMT(ice, IRQ)); outb(0xff, ICEREG(ice, IRQMASK)); /* --- */ __hw_end: @@ -2556,9 +2530,10 @@ if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || - pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { - snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); + if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { + dev_err(card->dev, + "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; } @@ -2594,6 +2569,7 @@ ice->pci = pci; ice->irq = -1; pci_set_master(pci); + /* disable legacy emulation */ pci_write_config_word(ice->pci, 0x40, 0x807f); pci_write_config_word(ice->pci, 0x42, 0x0006); snd_ice1712_proc_init(ice); @@ -2614,7 +2590,7 @@ if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED, KBUILD_MODNAME, ice)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); snd_ice1712_free(ice); return -EIO; } @@ -2630,22 +2606,12 @@ return -EIO; } - /* unmask used interrupts */ - outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? - ICE1712_IRQ_MPU2 : 0) | - ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? - ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0), - ICEREG(ice, IRQMASK)); - outb(0x00, ICEMT(ice, IRQ)); - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); if (err < 0) { snd_ice1712_free(ice); return err; } - snd_card_set_dev(card, &pci->dev); - *r_ice1712 = ice; return 0; } @@ -2675,7 +2641,8 @@ return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + 0, &card); if (err < 0) return err; @@ -2710,14 +2677,14 @@ c = &no_matched; __found: - err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL); + err = snd_ice1712_pcm_profi(ice, pcm_dev++); if (err < 0) { snd_card_free(card); return err; } if (ice_has_con_ac97(ice)) { - err = snd_ice1712_pcm(ice, pcm_dev++, NULL); + err = snd_ice1712_pcm(ice, pcm_dev++); if (err < 0) { snd_card_free(card); return err; @@ -2745,7 +2712,7 @@ } if (ice_has_con_ac97(ice)) { - err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); + err = snd_ice1712_pcm_ds(ice, pcm_dev++); if (err < 0) { snd_card_free(card); return err; @@ -2812,14 +2779,95 @@ if (ice->card_info && ice->card_info->chip_exit) ice->card_info->chip_exit(ice); snd_card_free(card); - pci_set_drvdata(pci, NULL); } +#ifdef CONFIG_PM_SLEEP +static int snd_ice1712_suspend(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct snd_ice1712 *ice = card->private_data; + + if (!ice->pm_suspend_enabled) + return 0; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + + snd_pcm_suspend_all(ice->pcm); + snd_pcm_suspend_all(ice->pcm_pro); + snd_pcm_suspend_all(ice->pcm_ds); + snd_ac97_suspend(ice->ac97); + + spin_lock_irq(&ice->reg_lock); + ice->pm_saved_is_spdif_master = is_spdif_master(ice); + ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT)); + ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03)); + spin_unlock_irq(&ice->reg_lock); + + if (ice->pm_suspend) + ice->pm_suspend(ice); + return 0; +} + +static int snd_ice1712_resume(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct snd_ice1712 *ice = card->private_data; + int rate; + + if (!ice->pm_suspend_enabled) + return 0; + + if (ice->cur_rate) + rate = ice->cur_rate; + else + rate = PRO_RATE_DEFAULT; + + if (snd_ice1712_chip_init(ice) < 0) { + snd_card_disconnect(card); + return -EIO; + } + + ice->cur_rate = rate; + + if (ice->pm_resume) + ice->pm_resume(ice); + + if (ice->pm_saved_is_spdif_master) { + /* switching to external clock via SPDIF */ + spin_lock_irq(&ice->reg_lock); + outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER, + ICEMT(ice, RATE)); + spin_unlock_irq(&ice->reg_lock); + snd_ice1712_set_input_clock_source(ice, 1); + } else { + /* internal on-card clock */ + snd_ice1712_set_pro_rate(ice, rate, 1); + snd_ice1712_set_input_clock_source(ice, 0); + } + + outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); + outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); + + snd_ac97_resume(ice->ac97); + + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} + +static SIMPLE_DEV_PM_OPS(snd_ice1712_pm, snd_ice1712_suspend, snd_ice1712_resume); +#define SND_VT1712_PM_OPS &snd_ice1712_pm +#else +#define SND_VT1712_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + static struct pci_driver ice1712_driver = { .name = KBUILD_MODNAME, .id_table = snd_ice1712_ids, .probe = snd_ice1712_probe, .remove = snd_ice1712_remove, + .driver = { + .pm = SND_VT1712_PM_OPS, + }, }; module_pci_driver(ice1712_driver);