Loading sound/pci/oxygen/hifier.c +5 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ static const struct oxygen_model model_hifier = { .init = hifier_init, .control_filter = hifier_control_filter, .cleanup = hifier_cleanup, .resume = hifier_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_cs5340_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -186,6 +187,10 @@ static struct pci_driver hifier_driver = { .id_table = hifier_ids, .probe = hifier_probe, .remove = __devexit_p(oxygen_pci_remove), #ifdef CONFIG_PM .suspend = oxygen_pci_suspend, .resume = oxygen_pci_resume, #endif }; static int __init alsa_card_hifier_init(void) Loading sound/pci/oxygen/oxygen.c +12 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,12 @@ static void generic_cleanup(struct oxygen *chip) { } static void generic_resume(struct oxygen *chip) { ak4396_registers_init(chip); wm8785_registers_init(chip); } static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { Loading Loading @@ -278,6 +284,7 @@ static const struct oxygen_model model_generic = { .owner = THIS_MODULE, .init = generic_init, .cleanup = generic_cleanup, .resume = generic_resume, .set_dac_params = set_ak4396_params, .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -305,6 +312,7 @@ static const struct oxygen_model model_meridian = { .owner = THIS_MODULE, .init = meridian_init, .cleanup = generic_cleanup, .resume = ak4396_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_ak5385_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -353,6 +361,10 @@ static struct pci_driver oxygen_driver = { .id_table = oxygen_ids, .probe = generic_oxygen_probe, .remove = __devexit_p(oxygen_pci_remove), #ifdef CONFIG_PM .suspend = oxygen_pci_suspend, .resume = oxygen_pci_resume, #endif }; static int __init alsa_card_oxygen_init(void) Loading sound/pci/oxygen/oxygen.h +6 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ struct oxygen_model { int (*control_filter)(struct snd_kcontrol_new *template); int (*mixer_init)(struct oxygen *chip); void (*cleanup)(struct oxygen *chip); void (*suspend)(struct oxygen *chip); void (*resume)(struct oxygen *chip); void (*pcm_hardware_filter)(unsigned int channel, struct snd_pcm_hardware *hardware); void (*set_dac_params)(struct oxygen *chip, Loading Loading @@ -125,6 +127,10 @@ struct oxygen_model { int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, const struct oxygen_model *model); void oxygen_pci_remove(struct pci_dev *pci); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); int oxygen_pci_resume(struct pci_dev *pci); #endif /* oxygen_mixer.c */ Loading sound/pci/oxygen/oxygen_lib.c +100 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_SPDIF_LOCK_MASK | OXYGEN_SPDIF_RATE_MASK); oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits); oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | OXYGEN_2WIRE_INTERRUPT_MASK | OXYGEN_2WIRE_SPEED_STANDARD); oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK); oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0); oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0); Loading Loading @@ -534,3 +538,99 @@ void oxygen_pci_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } EXPORT_SYMBOL(oxygen_pci_remove); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct oxygen *chip = card->private_data; unsigned int i, saved_interrupt_mask; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); for (i = 0; i < PCM_COUNT; ++i) if (chip->streams[i]) snd_pcm_suspend(chip->streams[i]); if (chip->model->suspend) chip->model->suspend(chip); spin_lock_irq(&chip->reg_lock); saved_interrupt_mask = chip->interrupt_mask; chip->interrupt_mask = 0; oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); spin_unlock_irq(&chip->reg_lock); synchronize_irq(chip->irq); flush_scheduled_work(); chip->interrupt_mask = saved_interrupt_mask; pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } EXPORT_SYMBOL(oxygen_pci_suspend); static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = { 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff, 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000 }; static const u32 ac97_registers_to_restore[2][0x40 / 32] = { { 0x18284fa2, 0x03060000 }, { 0x00007fa6, 0x00200000 } }; static inline int is_bit_set(const u32 *bitmap, unsigned int bit) { return bitmap[bit / 32] & (1 << (bit & 31)); } static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec) { unsigned int i; oxygen_write_ac97(chip, codec, AC97_RESET, 0); msleep(1); for (i = 1; i < 0x40; ++i) if (is_bit_set(ac97_registers_to_restore[codec], i)) oxygen_write_ac97(chip, codec, i * 2, chip->saved_ac97_registers[codec][i]); } int oxygen_pci_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct oxygen *chip = card->private_data; unsigned int i; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); if (pci_enable_device(pci) < 0) { snd_printk(KERN_ERR "cannot reenable device"); snd_card_disconnect(card); return -EIO; } pci_set_master(pci); oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); for (i = 0; i < OXYGEN_IO_SIZE; ++i) if (is_bit_set(registers_to_restore, i)) oxygen_write8(chip, i, chip->saved_registers._8[i]); if (chip->has_ac97_0) oxygen_restore_ac97(chip, 0); if (chip->has_ac97_1) oxygen_restore_ac97(chip, 1); if (chip->model->resume) chip->model->resume(chip); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } EXPORT_SYMBOL(oxygen_pci_resume); #endif /* CONFIG_PM */ sound/pci/oxygen/oxygen_pcm.c +1 −0 Original line number Diff line number Diff line Loading @@ -517,6 +517,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_SUSPEND: pausing = 0; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: Loading Loading
sound/pci/oxygen/hifier.c +5 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ static const struct oxygen_model model_hifier = { .init = hifier_init, .control_filter = hifier_control_filter, .cleanup = hifier_cleanup, .resume = hifier_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_cs5340_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -186,6 +187,10 @@ static struct pci_driver hifier_driver = { .id_table = hifier_ids, .probe = hifier_probe, .remove = __devexit_p(oxygen_pci_remove), #ifdef CONFIG_PM .suspend = oxygen_pci_suspend, .resume = oxygen_pci_resume, #endif }; static int __init alsa_card_hifier_init(void) Loading
sound/pci/oxygen/oxygen.c +12 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,12 @@ static void generic_cleanup(struct oxygen *chip) { } static void generic_resume(struct oxygen *chip) { ak4396_registers_init(chip); wm8785_registers_init(chip); } static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { Loading Loading @@ -278,6 +284,7 @@ static const struct oxygen_model model_generic = { .owner = THIS_MODULE, .init = generic_init, .cleanup = generic_cleanup, .resume = generic_resume, .set_dac_params = set_ak4396_params, .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -305,6 +312,7 @@ static const struct oxygen_model model_meridian = { .owner = THIS_MODULE, .init = meridian_init, .cleanup = generic_cleanup, .resume = ak4396_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_ak5385_params, .update_dac_volume = update_ak4396_volume, Loading Loading @@ -353,6 +361,10 @@ static struct pci_driver oxygen_driver = { .id_table = oxygen_ids, .probe = generic_oxygen_probe, .remove = __devexit_p(oxygen_pci_remove), #ifdef CONFIG_PM .suspend = oxygen_pci_suspend, .resume = oxygen_pci_resume, #endif }; static int __init alsa_card_oxygen_init(void) Loading
sound/pci/oxygen/oxygen.h +6 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ struct oxygen_model { int (*control_filter)(struct snd_kcontrol_new *template); int (*mixer_init)(struct oxygen *chip); void (*cleanup)(struct oxygen *chip); void (*suspend)(struct oxygen *chip); void (*resume)(struct oxygen *chip); void (*pcm_hardware_filter)(unsigned int channel, struct snd_pcm_hardware *hardware); void (*set_dac_params)(struct oxygen *chip, Loading Loading @@ -125,6 +127,10 @@ struct oxygen_model { int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, const struct oxygen_model *model); void oxygen_pci_remove(struct pci_dev *pci); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); int oxygen_pci_resume(struct pci_dev *pci); #endif /* oxygen_mixer.c */ Loading
sound/pci/oxygen/oxygen_lib.c +100 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_SPDIF_LOCK_MASK | OXYGEN_SPDIF_RATE_MASK); oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits); oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | OXYGEN_2WIRE_INTERRUPT_MASK | OXYGEN_2WIRE_SPEED_STANDARD); oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK); oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0); oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0); Loading Loading @@ -534,3 +538,99 @@ void oxygen_pci_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } EXPORT_SYMBOL(oxygen_pci_remove); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct oxygen *chip = card->private_data; unsigned int i, saved_interrupt_mask; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); for (i = 0; i < PCM_COUNT; ++i) if (chip->streams[i]) snd_pcm_suspend(chip->streams[i]); if (chip->model->suspend) chip->model->suspend(chip); spin_lock_irq(&chip->reg_lock); saved_interrupt_mask = chip->interrupt_mask; chip->interrupt_mask = 0; oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); spin_unlock_irq(&chip->reg_lock); synchronize_irq(chip->irq); flush_scheduled_work(); chip->interrupt_mask = saved_interrupt_mask; pci_disable_device(pci); pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } EXPORT_SYMBOL(oxygen_pci_suspend); static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = { 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff, 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000 }; static const u32 ac97_registers_to_restore[2][0x40 / 32] = { { 0x18284fa2, 0x03060000 }, { 0x00007fa6, 0x00200000 } }; static inline int is_bit_set(const u32 *bitmap, unsigned int bit) { return bitmap[bit / 32] & (1 << (bit & 31)); } static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec) { unsigned int i; oxygen_write_ac97(chip, codec, AC97_RESET, 0); msleep(1); for (i = 1; i < 0x40; ++i) if (is_bit_set(ac97_registers_to_restore[codec], i)) oxygen_write_ac97(chip, codec, i * 2, chip->saved_ac97_registers[codec][i]); } int oxygen_pci_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct oxygen *chip = card->private_data; unsigned int i; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); if (pci_enable_device(pci) < 0) { snd_printk(KERN_ERR "cannot reenable device"); snd_card_disconnect(card); return -EIO; } pci_set_master(pci); oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); for (i = 0; i < OXYGEN_IO_SIZE; ++i) if (is_bit_set(registers_to_restore, i)) oxygen_write8(chip, i, chip->saved_registers._8[i]); if (chip->has_ac97_0) oxygen_restore_ac97(chip, 0); if (chip->has_ac97_1) oxygen_restore_ac97(chip, 1); if (chip->model->resume) chip->model->resume(chip); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } EXPORT_SYMBOL(oxygen_pci_resume); #endif /* CONFIG_PM */
sound/pci/oxygen/oxygen_pcm.c +1 −0 Original line number Diff line number Diff line Loading @@ -517,6 +517,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_SUSPEND: pausing = 0; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: Loading