From 075140ea8bf1405057c072a84ccf4e0d3f2c76f5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:50:37 +0100 Subject: ALSA: oxygen: support for period wakeup disabling Allow disabling period wakeup interrupts for all PCM streams. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_pcm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sound/pci/oxygen/oxygen_pcm.c') diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 814667442eb0..60e4aa00c042 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -530,7 +533,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream) oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); - chip->interrupt_mask |= channel_mask; + if (substream->runtime->no_period_wakeup) + chip->interrupt_mask &= ~channel_mask; + else + chip->interrupt_mask |= channel_mask; oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); spin_unlock_irq(&chip->reg_lock); return 0; -- cgit v1.2.3 From 1f4d7be7293aecd5f8469a46f606f62f0f05d84c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 15:59:38 +0100 Subject: ALSA: oxygen: allow different number of PCM and mixer channels For cards like the Xonar HDAV1.3, differentiate between the number of PCM channels that can be played and the number of channels whose volume can be adjusted. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 8 +++++--- sound/pci/oxygen/oxygen.h | 3 ++- sound/pci/oxygen/oxygen_mixer.c | 8 ++++---- sound/pci/oxygen/oxygen_pcm.c | 2 +- sound/pci/oxygen/xonar_cs43xx.c | 3 ++- sound/pci/oxygen/xonar_pcm179x.c | 13 +++++++++---- sound/pci/oxygen/xonar_wm87x6.c | 3 ++- 7 files changed, 25 insertions(+), 15 deletions(-) (limited to 'sound/pci/oxygen/oxygen_pcm.c') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index dc47977becae..fe7ed4fc9f46 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -185,7 +185,7 @@ static void ak4396_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; - data->dacs = chip->model.dac_channels / 2; + data->dacs = chip->model.dac_channels_pcm / 2; data->ak4396_regs[0][AK4396_CONTROL_2] = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; ak4396_registers_init(chip); @@ -583,7 +583,8 @@ static const struct oxygen_model model_generic = { CAPTURE_1_FROM_SPDIF | CAPTURE_2_FROM_AC97_1 | AC97_CD_INPUT, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 0, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI | @@ -643,7 +644,8 @@ static int __devinit get_oxygen_model(struct oxygen *chip, PLAYBACK_1_TO_SPDIF; if (id->driver_data == MODEL_FANTASIA) chip->model.device_config |= CAPTURE_0_FROM_I2S_1; - chip->model.dac_channels = 2; + chip->model.dac_channels_pcm = 2; + chip->model.dac_channels_mixer = 2; break; } if (id->driver_data == MODEL_MERIDIAN || diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index b8fbc15b89a3..3d9535c2debb 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -100,7 +100,8 @@ struct oxygen_model { unsigned long private_data; size_t model_data_size; unsigned int device_config; - u8 dac_channels; + u8 dac_channels_pcm; + u8 dac_channels_mixer; u8 dac_volume_min; u8 dac_volume_max; u8 misc_flags; diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 605e84b9e1ec..242c1cac69b8 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl, struct oxygen *chip = ctl->private_data; info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = chip->model.dac_channels; + info->count = chip->model.dac_channels_mixer; info->value.integer.min = chip->model.dac_volume_min; info->value.integer.max = chip->model.dac_volume_max; return 0; @@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl, unsigned int i; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model.dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels_mixer; ++i) value->value.integer.value[i] = chip->dac_volume[i]; mutex_unlock(&chip->mutex); return 0; @@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl, changed = 0; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model.dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels_mixer; ++i) if (value->value.integer.value[i] != chip->dac_volume[i]) { chip->dac_volume[i] = value->value.integer.value[i]; changed = 1; @@ -1022,7 +1022,7 @@ static int add_controls(struct oxygen *chip, continue; } if (!strcmp(template.name, "Stereo Upmixing") && - chip->model.dac_channels == 2) + chip->model.dac_channels_pcm == 2) continue; if (!strcmp(template.name, "Mic Source Capture Enum") && !(chip->model.device_config & AC97_FMIC_SWITCH)) diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 60e4aa00c042..dc3c68f76df4 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -143,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->hw.rate_min = 44100; break; case PCM_MULTICH: - runtime->hw.channels_max = chip->model.dac_channels; + runtime->hw.channels_max = chip->model.dac_channels_pcm; break; } if (chip->model.pcm_hardware_filter) diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index de32895b3172..a25197ca39a1 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -426,7 +426,8 @@ static const struct oxygen_model model_xonar_d1 = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | AC97_FMIC_SWITCH, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 127 - 60, .dac_volume_max = 127, .function_flags = OXYGEN_FUNCTION_2WIRE, diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index bf357c01afd2..b55149e9be81 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1094,7 +1094,8 @@ static const struct oxygen_model model_xonar_d2 = { MIDI_OUTPUT | MIDI_INPUT | AC97_CD_INPUT, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, @@ -1127,7 +1128,8 @@ static const struct oxygen_model model_xonar_hdav = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, @@ -1157,7 +1159,8 @@ static const struct oxygen_model model_xonar_st = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | AC97_FMIC_SWITCH, - .dac_channels = 2, + .dac_channels_pcm = 2, + .dac_channels_mixer = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, @@ -1187,6 +1190,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, break; case GPIO_DB_H6: chip->model.shortname = "Xonar HDAV1.3+H6"; + chip->model.dac_channels_mixer = 8; chip->model.private_data = 1; break; } @@ -1200,7 +1204,8 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, break; case GPIO_DB_H6: chip->model.shortname = "Xonar ST+H6"; - chip->model.dac_channels = 8; + chip->model.dac_channels_pcm = 8; + chip->model.dac_channels_mixer = 8; chip->model.private_data = 1; break; } diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 1705d1e93115..da92cc24eed2 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1135,7 +1135,8 @@ static const struct oxygen_model model_xonar_ds = { .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_1, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI, -- cgit v1.2.3 From 5b8bf2a54fb13e40519ee846ce27bc8a2d7a7878 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:14:52 +0100 Subject: ALSA: oxygen: simplify model-specific MCLK handling Replace the get_i2s_mclk callback with tables of MCLK values. This simplifies the MCLK-handling code in both the framework and the model- specific drivers. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 3 +- sound/pci/oxygen/oxygen.h | 10 +++-- sound/pci/oxygen/oxygen_lib.c | 36 ++++++++++++------ sound/pci/oxygen/oxygen_pcm.c | 39 +++++++++++-------- sound/pci/oxygen/oxygen_regs.h | 8 ++-- sound/pci/oxygen/xonar_cs43xx.c | 3 +- sound/pci/oxygen/xonar_pcm179x.c | 82 ++++++++++++---------------------------- sound/pci/oxygen/xonar_wm87x6.c | 3 +- 8 files changed, 89 insertions(+), 95 deletions(-) (limited to 'sound/pci/oxygen/oxygen_pcm.c') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index fe7ed4fc9f46..784d500c700f 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -568,7 +568,6 @@ static const struct oxygen_model model_generic = { .mixer_init = generic_wm8785_mixer_init, .cleanup = generic_cleanup, .resume = generic_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_ak4396_params, .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, @@ -589,6 +588,8 @@ static const struct oxygen_model model_generic = { .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 70eff3747158..2c5fb9edcb11 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -16,6 +16,10 @@ #define PCM_AC97 5 #define PCM_COUNT 6 +#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \ + (MCLK_##f_double << 2) | \ + (MCLK_##f_quad << 4)) + #define OXYGEN_IO_SIZE 0x100 #define OXYGEN_EEPROM_ID 0x434d /* "CM" */ @@ -81,8 +85,6 @@ struct oxygen_model { void (*resume)(struct oxygen *chip); void (*pcm_hardware_filter)(unsigned int channel, struct snd_pcm_hardware *hardware); - unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel, - struct snd_pcm_hw_params *hw_params); void (*set_dac_params)(struct oxygen *chip, struct snd_pcm_hw_params *params); void (*set_adc_params)(struct oxygen *chip, @@ -105,6 +107,8 @@ struct oxygen_model { u8 dac_volume_max; u8 misc_flags; u8 function_flags; + u8 dac_mclks; + u8 adc_mclks; u16 dac_i2s_format; u16 adc_i2s_format; }; @@ -171,8 +175,6 @@ void oxygen_update_spdif_source(struct oxygen *chip); /* oxygen_pcm.c */ int oxygen_pcm_init(struct oxygen *chip); -unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel, - struct snd_pcm_hw_params *hw_params); /* oxygen_io.c */ diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index c44c91e6fb18..77e1f0805633 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -414,28 +414,40 @@ static void oxygen_init(struct oxygen *chip) (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_RATE_48000 | chip->model.dac_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.dac_i2s_format | + OXYGEN_I2S_MCLK(chip->model.dac_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_RATE_48000 | chip->model.adc_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.adc_i2s_format | + OXYGEN_I2S_MCLK(chip->model.adc_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_RATE_48000 | chip->model.adc_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.adc_i2s_format | + OXYGEN_I2S_MCLK(chip->model.adc_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index dc3c68f76df4..d5533e34ece9 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -274,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params) } } -unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, - unsigned int channel, - struct snd_pcm_hw_params *hw_params) -{ - if (params_rate(hw_params) <= 96000) - return OXYGEN_I2S_MCLK_256; - else - return OXYGEN_I2S_MCLK_128; -} -EXPORT_SYMBOL(oxygen_default_i2s_mclk); - static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) { if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) @@ -344,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream, return 0; } +static u16 get_mclk(struct oxygen *chip, unsigned int channel, + struct snd_pcm_hw_params *params) +{ + unsigned int mclks, shift; + + if (channel == PCM_MULTICH) + mclks = chip->model.dac_mclks; + else + mclks = chip->model.adc_mclks; + + if (params_rate(params) <= 48000) + shift = 0; + else if (params_rate(params) <= 96000) + shift = 2; + else + shift = 4; + + return OXYGEN_I2S_MCLK(mclks >> shift); +} + static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -360,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, OXYGEN_REC_FORMAT_A_MASK); oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, oxygen_rate(hw_params) | - chip->model.get_i2s_mclk(chip, PCM_A, hw_params) | chip->model.adc_i2s_format | + get_mclk(chip, PCM_A, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -396,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, if (!is_ac97) oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, oxygen_rate(hw_params) | - chip->model.get_i2s_mclk(chip, PCM_B, - hw_params) | chip->model.adc_i2s_format | + get_mclk(chip, PCM_B, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -479,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream, oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, oxygen_rate(hw_params) | chip->model.dac_i2s_format | - chip->model.get_i2s_mclk(chip, PCM_MULTICH, - hw_params) | + get_mclk(chip, PCM_MULTICH, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h index 331d3d96fa21..63dc7a0ab555 100644 --- a/sound/pci/oxygen/oxygen_regs.h +++ b/sound/pci/oxygen/oxygen_regs.h @@ -139,9 +139,11 @@ #define OXYGEN_I2S_FORMAT_I2S 0x0000 #define OXYGEN_I2S_FORMAT_LJUST 0x0008 #define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */ -#define OXYGEN_I2S_MCLK_128 0x0000 -#define OXYGEN_I2S_MCLK_256 0x0010 -#define OXYGEN_I2S_MCLK_512 0x0020 +#define OXYGEN_I2S_MCLK_SHIFT 4 +#define MCLK_128 0 +#define MCLK_256 1 +#define MCLK_512 2 +#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT) #define OXYGEN_I2S_BITS_MASK 0x00c0 #define OXYGEN_I2S_BITS_16 0x0000 #define OXYGEN_I2S_BITS_20 0x0040 diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index a25197ca39a1..b651938f3248 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -412,7 +412,6 @@ static const struct oxygen_model model_xonar_d1 = { .cleanup = xonar_d1_cleanup, .suspend = xonar_d1_suspend, .resume = xonar_d1_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_cs43xx_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_cs43xx_volume, @@ -431,6 +430,8 @@ static const struct oxygen_model model_xonar_d1 = { .dac_volume_min = 127 - 60, .dac_volume_max = 127, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index e15ecee2ccf7..9787193f6ed3 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -335,10 +335,6 @@ static void pcm1796_init(struct oxygen *chip) data->h6 ? PCM1796_OS_64 : PCM1796_OS_128; pcm1796_registers_init(chip); data->current_rate = 48000; - if (!data->h6) - oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_I2S_MCLK_512, - OXYGEN_I2S_MCLK_MASK); } static void xonar_d2_init(struct oxygen *chip) @@ -476,7 +472,7 @@ static void xonar_st_init(struct oxygen *chip) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | - (data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512) | + OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); @@ -560,26 +556,6 @@ static void xonar_st_resume(struct oxygen *chip) xonar_stx_resume(chip); } -static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate) -{ - struct xonar_pcm179x *data = chip->model_data; - - if (rate <= 48000) - return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512; - else - return OXYGEN_I2S_MCLK_128; -} - -static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip, - unsigned int channel, - struct snd_pcm_hw_params *params) -{ - if (channel == PCM_MULTICH) - return mclk_from_rate(chip, params_rate(params)); - else - return oxygen_default_i2s_mclk(chip, channel, params); -} - static void update_pcm1796_oversampling(struct oxygen *chip) { struct xonar_pcm179x *data = chip->model_data; @@ -640,45 +616,32 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) switch (rate) { case 32000: - if (data->h6) - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; - break; - case 44100: - if (data->h6) - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; - break; - default: /* 48000 */ - if (data->h6) - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; - break; case 64000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_32000; break; + case 44100: case 88200: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; - break; - case 96000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; - break; case 176400: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_44100; break; + default: + case 48000: + case 96000: case 192000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_48000; break; } - oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, - OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); - if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_256) + + if (rate <= 96000 && (rate > 48000 || data->h6)) { + rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256); reg = CS2000_REF_CLK_DIV_1; - else + } else { + rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512); reg = CS2000_REF_CLK_DIV_2; + } + + oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, + OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); msleep(3); /* PLL lock delay */ } @@ -1047,7 +1010,6 @@ static const struct oxygen_model model_xonar_d2 = { .cleanup = xonar_d2_cleanup, .suspend = xonar_d2_suspend, .resume = xonar_d2_resume, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_pcm1796_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1069,6 +1031,8 @@ static const struct oxygen_model model_xonar_d2 = { .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1082,7 +1046,6 @@ static const struct oxygen_model model_xonar_hdav = { .suspend = xonar_hdav_suspend, .resume = xonar_hdav_resume, .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_hdav_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1102,6 +1065,8 @@ static const struct oxygen_model model_xonar_hdav = { .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1114,7 +1079,6 @@ static const struct oxygen_model model_xonar_st = { .cleanup = xonar_st_cleanup, .suspend = xonar_st_suspend, .resume = xonar_st_resume, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_st_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1132,6 +1096,8 @@ static const struct oxygen_model model_xonar_st = { .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1159,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, case GPIO_DB_H6: chip->model.shortname = "Xonar HDAV1.3+H6"; chip->model.dac_channels_mixer = 8; + chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); break; } break; @@ -1174,6 +1141,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, chip->model.control_filter = xonar_st_h6_control_filter; chip->model.dac_channels_pcm = 8; chip->model.dac_channels_mixer = 8; + chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); break; } break; diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index da92cc24eed2..4f9657084603 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1122,7 +1122,6 @@ static const struct oxygen_model model_xonar_ds = { .suspend = xonar_ds_suspend, .resume = xonar_ds_resume, .pcm_hardware_filter = wm8776_adc_hardware_filter, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_wm87x6_dac_params, .set_adc_params = set_wm8776_adc_params, .update_dac_volume = update_wm87x6_volume, @@ -1140,6 +1139,8 @@ static const struct oxygen_model model_xonar_ds = { .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit v1.2.3