diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
| -rw-r--r-- | sound/pci/oxygen/oxygen.c | 107 |
1 files changed, 58 insertions, 49 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 53dff7193f31..c986c5ebf65b 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
| @@ -97,8 +97,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
| 97 | #define GPIO_CLARO_HP 0x0100 | 97 | #define GPIO_CLARO_HP 0x0100 |
| 98 | 98 | ||
| 99 | struct generic_data { | 99 | struct generic_data { |
| 100 | u8 ak4396_ctl2; | 100 | u8 ak4396_regs[4][5]; |
| 101 | u16 saved_wm8785_registers[2]; | 101 | u16 wm8785_regs[1]; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | static void ak4396_write(struct oxygen *chip, unsigned int codec, | 104 | static void ak4396_write(struct oxygen *chip, unsigned int codec, |
| @@ -108,12 +108,24 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec, | |||
| 108 | static const u8 codec_spi_map[4] = { | 108 | static const u8 codec_spi_map[4] = { |
| 109 | 0, 1, 2, 4 | 109 | 0, 1, 2, 4 |
| 110 | }; | 110 | }; |
| 111 | struct generic_data *data = chip->model_data; | ||
| 112 | |||
| 111 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | | 113 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | |
| 112 | OXYGEN_SPI_DATA_LENGTH_2 | | 114 | OXYGEN_SPI_DATA_LENGTH_2 | |
| 113 | OXYGEN_SPI_CLOCK_160 | | 115 | OXYGEN_SPI_CLOCK_160 | |
| 114 | (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | | 116 | (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | |
| 115 | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, | 117 | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, |
| 116 | AK4396_WRITE | (reg << 8) | value); | 118 | AK4396_WRITE | (reg << 8) | value); |
| 119 | data->ak4396_regs[codec][reg] = value; | ||
| 120 | } | ||
| 121 | |||
| 122 | static void ak4396_write_cached(struct oxygen *chip, unsigned int codec, | ||
| 123 | u8 reg, u8 value) | ||
| 124 | { | ||
| 125 | struct generic_data *data = chip->model_data; | ||
| 126 | |||
| 127 | if (value != data->ak4396_regs[codec][reg]) | ||
| 128 | ak4396_write(chip, codec, reg, value); | ||
| 117 | } | 129 | } |
| 118 | 130 | ||
| 119 | static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) | 131 | static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) |
| @@ -126,20 +138,8 @@ static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) | |||
| 126 | (3 << OXYGEN_SPI_CODEC_SHIFT) | | 138 | (3 << OXYGEN_SPI_CODEC_SHIFT) | |
| 127 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, | 139 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, |
| 128 | (reg << 9) | value); | 140 | (reg << 9) | value); |
| 129 | if (reg < ARRAY_SIZE(data->saved_wm8785_registers)) | 141 | if (reg < ARRAY_SIZE(data->wm8785_regs)) |
| 130 | data->saved_wm8785_registers[reg] = value; | 142 | data->wm8785_regs[reg] = value; |
| 131 | } | ||
| 132 | |||
| 133 | static void update_ak4396_volume(struct oxygen *chip) | ||
| 134 | { | ||
| 135 | unsigned int i; | ||
| 136 | |||
| 137 | for (i = 0; i < 4; ++i) { | ||
| 138 | ak4396_write(chip, i, | ||
| 139 | AK4396_LCH_ATT, chip->dac_volume[i * 2]); | ||
| 140 | ak4396_write(chip, i, | ||
| 141 | AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); | ||
| 142 | } | ||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | static void ak4396_registers_init(struct oxygen *chip) | 145 | static void ak4396_registers_init(struct oxygen *chip) |
| @@ -148,21 +148,25 @@ static void ak4396_registers_init(struct oxygen *chip) | |||
| 148 | unsigned int i; | 148 | unsigned int i; |
| 149 | 149 | ||
| 150 | for (i = 0; i < 4; ++i) { | 150 | for (i = 0; i < 4; ++i) { |
| 151 | ak4396_write(chip, i, | 151 | ak4396_write(chip, i, AK4396_CONTROL_1, |
| 152 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | 152 | AK4396_DIF_24_MSB | AK4396_RSTN); |
| 153 | ak4396_write(chip, i, | 153 | ak4396_write(chip, i, AK4396_CONTROL_2, |
| 154 | AK4396_CONTROL_2, data->ak4396_ctl2); | 154 | data->ak4396_regs[0][AK4396_CONTROL_2]); |
| 155 | ak4396_write(chip, i, | 155 | ak4396_write(chip, i, AK4396_CONTROL_3, |
| 156 | AK4396_CONTROL_3, AK4396_PCM); | 156 | AK4396_PCM); |
| 157 | ak4396_write(chip, i, AK4396_LCH_ATT, | ||
| 158 | chip->dac_volume[i * 2]); | ||
| 159 | ak4396_write(chip, i, AK4396_RCH_ATT, | ||
| 160 | chip->dac_volume[i * 2 + 1]); | ||
| 157 | } | 161 | } |
| 158 | update_ak4396_volume(chip); | ||
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | static void ak4396_init(struct oxygen *chip) | 164 | static void ak4396_init(struct oxygen *chip) |
| 162 | { | 165 | { |
| 163 | struct generic_data *data = chip->model_data; | 166 | struct generic_data *data = chip->model_data; |
| 164 | 167 | ||
| 165 | data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; | 168 | data->ak4396_regs[0][AK4396_CONTROL_2] = |
| 169 | AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; | ||
| 166 | ak4396_registers_init(chip); | 170 | ak4396_registers_init(chip); |
| 167 | snd_component_add(chip->card, "AK4396"); | 171 | snd_component_add(chip->card, "AK4396"); |
| 168 | } | 172 | } |
| @@ -179,17 +183,15 @@ static void wm8785_registers_init(struct oxygen *chip) | |||
| 179 | struct generic_data *data = chip->model_data; | 183 | struct generic_data *data = chip->model_data; |
| 180 | 184 | ||
| 181 | wm8785_write(chip, WM8785_R7, 0); | 185 | wm8785_write(chip, WM8785_R7, 0); |
| 182 | wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); | 186 | wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]); |
| 183 | wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]); | ||
| 184 | } | 187 | } |
| 185 | 188 | ||
| 186 | static void wm8785_init(struct oxygen *chip) | 189 | static void wm8785_init(struct oxygen *chip) |
| 187 | { | 190 | { |
| 188 | struct generic_data *data = chip->model_data; | 191 | struct generic_data *data = chip->model_data; |
| 189 | 192 | ||
| 190 | data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | | 193 | data->wm8785_regs[0] = |
| 191 | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; | 194 | WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; |
| 192 | data->saved_wm8785_registers[1] = WM8785_WL_24; | ||
| 193 | wm8785_registers_init(chip); | 195 | wm8785_registers_init(chip); |
| 194 | snd_component_add(chip->card, "WM8785"); | 196 | snd_component_add(chip->card, "WM8785"); |
| 195 | } | 197 | } |
| @@ -270,24 +272,36 @@ static void set_ak4396_params(struct oxygen *chip, | |||
| 270 | unsigned int i; | 272 | unsigned int i; |
| 271 | u8 value; | 273 | u8 value; |
| 272 | 274 | ||
| 273 | value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; | 275 | value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_DFS_MASK; |
| 274 | if (params_rate(params) <= 54000) | 276 | if (params_rate(params) <= 54000) |
| 275 | value |= AK4396_DFS_NORMAL; | 277 | value |= AK4396_DFS_NORMAL; |
| 276 | else if (params_rate(params) <= 108000) | 278 | else if (params_rate(params) <= 108000) |
| 277 | value |= AK4396_DFS_DOUBLE; | 279 | value |= AK4396_DFS_DOUBLE; |
| 278 | else | 280 | else |
| 279 | value |= AK4396_DFS_QUAD; | 281 | value |= AK4396_DFS_QUAD; |
| 280 | data->ak4396_ctl2 = value; | ||
| 281 | 282 | ||
| 282 | msleep(1); /* wait for the new MCLK to become stable */ | 283 | msleep(1); /* wait for the new MCLK to become stable */ |
| 283 | 284 | ||
| 285 | if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { | ||
| 286 | for (i = 0; i < 4; ++i) { | ||
| 287 | ak4396_write(chip, i, AK4396_CONTROL_1, | ||
| 288 | AK4396_DIF_24_MSB); | ||
| 289 | ak4396_write(chip, i, AK4396_CONTROL_2, value); | ||
| 290 | ak4396_write(chip, i, AK4396_CONTROL_1, | ||
| 291 | AK4396_DIF_24_MSB | AK4396_RSTN); | ||
| 292 | } | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 296 | static void update_ak4396_volume(struct oxygen *chip) | ||
| 297 | { | ||
| 298 | unsigned int i; | ||
| 299 | |||
| 284 | for (i = 0; i < 4; ++i) { | 300 | for (i = 0; i < 4; ++i) { |
| 285 | ak4396_write(chip, i, | 301 | ak4396_write_cached(chip, i, AK4396_LCH_ATT, |
| 286 | AK4396_CONTROL_1, AK4396_DIF_24_MSB); | 302 | chip->dac_volume[i * 2]); |
| 287 | ak4396_write(chip, i, | 303 | ak4396_write_cached(chip, i, AK4396_RCH_ATT, |
| 288 | AK4396_CONTROL_2, value); | 304 | chip->dac_volume[i * 2 + 1]); |
| 289 | ak4396_write(chip, i, | ||
| 290 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | ||
| 291 | } | 305 | } |
| 292 | } | 306 | } |
| 293 | 307 | ||
| @@ -297,21 +311,19 @@ static void update_ak4396_mute(struct oxygen *chip) | |||
| 297 | unsigned int i; | 311 | unsigned int i; |
| 298 | u8 value; | 312 | u8 value; |
| 299 | 313 | ||
| 300 | value = data->ak4396_ctl2 & ~AK4396_SMUTE; | 314 | value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; |
| 301 | if (chip->dac_mute) | 315 | if (chip->dac_mute) |
| 302 | value |= AK4396_SMUTE; | 316 | value |= AK4396_SMUTE; |
| 303 | data->ak4396_ctl2 = value; | ||
| 304 | for (i = 0; i < 4; ++i) | 317 | for (i = 0; i < 4; ++i) |
| 305 | ak4396_write(chip, i, AK4396_CONTROL_2, value); | 318 | ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); |
| 306 | } | 319 | } |
| 307 | 320 | ||
| 308 | static void set_wm8785_params(struct oxygen *chip, | 321 | static void set_wm8785_params(struct oxygen *chip, |
| 309 | struct snd_pcm_hw_params *params) | 322 | struct snd_pcm_hw_params *params) |
| 310 | { | 323 | { |
| 324 | struct generic_data *data = chip->model_data; | ||
| 311 | unsigned int value; | 325 | unsigned int value; |
| 312 | 326 | ||
| 313 | wm8785_write(chip, WM8785_R7, 0); | ||
| 314 | |||
| 315 | value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST; | 327 | value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST; |
| 316 | if (params_rate(params) <= 48000) | 328 | if (params_rate(params) <= 48000) |
| 317 | value |= WM8785_OSR_SINGLE; | 329 | value |= WM8785_OSR_SINGLE; |
| @@ -319,13 +331,10 @@ static void set_wm8785_params(struct oxygen *chip, | |||
| 319 | value |= WM8785_OSR_DOUBLE; | 331 | value |= WM8785_OSR_DOUBLE; |
| 320 | else | 332 | else |
| 321 | value |= WM8785_OSR_QUAD; | 333 | value |= WM8785_OSR_QUAD; |
| 322 | wm8785_write(chip, WM8785_R0, value); | 334 | if (value != data->wm8785_regs[0]) { |
| 323 | 335 | wm8785_write(chip, WM8785_R7, 0); | |
| 324 | if (snd_pcm_format_width(params_format(params)) <= 16) | 336 | wm8785_write(chip, WM8785_R0, value); |
| 325 | value = WM8785_WL_16; | 337 | } |
| 326 | else | ||
| 327 | value = WM8785_WL_24; | ||
| 328 | wm8785_write(chip, WM8785_R1, value); | ||
| 329 | } | 338 | } |
| 330 | 339 | ||
| 331 | static void set_ak5385_params(struct oxygen *chip, | 340 | static void set_ak5385_params(struct oxygen *chip, |
