diff options
Diffstat (limited to 'sound/pci/ca0106/ca0106_mixer.c')
| -rw-r--r-- | sound/pci/ca0106/ca0106_mixer.c | 263 |
1 files changed, 195 insertions, 68 deletions
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 3025ed1b6e1e..ad2888705d2a 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
| @@ -75,6 +75,84 @@ | |||
| 75 | 75 | ||
| 76 | #include "ca0106.h" | 76 | #include "ca0106.h" |
| 77 | 77 | ||
| 78 | static void ca0106_spdif_enable(struct snd_ca0106 *emu) | ||
| 79 | { | ||
| 80 | unsigned int val; | ||
| 81 | |||
| 82 | if (emu->spdif_enable) { | ||
| 83 | /* Digital */ | ||
| 84 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); | ||
| 85 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000); | ||
| 86 | val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000; | ||
| 87 | snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val); | ||
| 88 | val = inl(emu->port + GPIO) & ~0x101; | ||
| 89 | outl(val, emu->port + GPIO); | ||
| 90 | |||
| 91 | } else { | ||
| 92 | /* Analog */ | ||
| 93 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); | ||
| 94 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000); | ||
| 95 | val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000; | ||
| 96 | snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val); | ||
| 97 | val = inl(emu->port + GPIO) | 0x101; | ||
| 98 | outl(val, emu->port + GPIO); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | static void ca0106_set_capture_source(struct snd_ca0106 *emu) | ||
| 103 | { | ||
| 104 | unsigned int val = emu->capture_source; | ||
| 105 | unsigned int source, mask; | ||
| 106 | source = (val << 28) | (val << 24) | (val << 20) | (val << 16); | ||
| 107 | mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff; | ||
| 108 | snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask); | ||
| 109 | } | ||
| 110 | |||
| 111 | static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu, | ||
| 112 | unsigned int val, int force) | ||
| 113 | { | ||
| 114 | unsigned int ngain, ogain; | ||
| 115 | u32 source; | ||
| 116 | |||
| 117 | snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | ||
| 118 | ngain = emu->i2c_capture_volume[val][0]; /* Left */ | ||
| 119 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ | ||
| 120 | if (force || ngain != ogain) | ||
| 121 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff); | ||
| 122 | ngain = emu->i2c_capture_volume[val][1]; /* Right */ | ||
| 123 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */ | ||
| 124 | if (force || ngain != ogain) | ||
| 125 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff); | ||
| 126 | source = 1 << val; | ||
| 127 | snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */ | ||
| 128 | emu->i2c_capture_source = val; | ||
| 129 | } | ||
| 130 | |||
| 131 | static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu) | ||
| 132 | { | ||
| 133 | u32 tmp; | ||
| 134 | |||
| 135 | if (emu->capture_mic_line_in) { | ||
| 136 | /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */ | ||
| 137 | tmp = inl(emu->port+GPIO) & ~0x400; | ||
| 138 | tmp = tmp | 0x400; | ||
| 139 | outl(tmp, emu->port+GPIO); | ||
| 140 | /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */ | ||
| 141 | } else { | ||
| 142 | /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */ | ||
| 143 | tmp = inl(emu->port+GPIO) & ~0x400; | ||
| 144 | outl(tmp, emu->port+GPIO); | ||
| 145 | /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */ | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx) | ||
| 150 | { | ||
| 151 | snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]); | ||
| 152 | } | ||
| 153 | |||
| 154 | /* | ||
| 155 | */ | ||
| 78 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); | 156 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); |
| 79 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); | 157 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); |
| 80 | 158 | ||
| @@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol, | |||
| 95 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 173 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 96 | unsigned int val; | 174 | unsigned int val; |
| 97 | int change = 0; | 175 | int change = 0; |
| 98 | u32 mask; | ||
| 99 | 176 | ||
| 100 | val = !!ucontrol->value.integer.value[0]; | 177 | val = !!ucontrol->value.integer.value[0]; |
| 101 | change = (emu->spdif_enable != val); | 178 | change = (emu->spdif_enable != val); |
| 102 | if (change) { | 179 | if (change) { |
| 103 | emu->spdif_enable = val; | 180 | emu->spdif_enable = val; |
| 104 | if (val) { | 181 | ca0106_spdif_enable(emu); |
| 105 | /* Digital */ | ||
| 106 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); | ||
| 107 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000); | ||
| 108 | snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, | ||
| 109 | snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000); | ||
| 110 | mask = inl(emu->port + GPIO) & ~0x101; | ||
| 111 | outl(mask, emu->port + GPIO); | ||
| 112 | |||
| 113 | } else { | ||
| 114 | /* Analog */ | ||
| 115 | snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); | ||
| 116 | snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000); | ||
| 117 | snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, | ||
| 118 | snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000); | ||
| 119 | mask = inl(emu->port + GPIO) | 0x101; | ||
| 120 | outl(mask, emu->port + GPIO); | ||
| 121 | } | ||
| 122 | } | 182 | } |
| 123 | return change; | 183 | return change; |
| 124 | } | 184 | } |
| @@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol, | |||
| 154 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 214 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 155 | unsigned int val; | 215 | unsigned int val; |
| 156 | int change = 0; | 216 | int change = 0; |
| 157 | u32 mask; | ||
| 158 | u32 source; | ||
| 159 | 217 | ||
| 160 | val = ucontrol->value.enumerated.item[0] ; | 218 | val = ucontrol->value.enumerated.item[0] ; |
| 161 | if (val >= 6) | 219 | if (val >= 6) |
| @@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol, | |||
| 163 | change = (emu->capture_source != val); | 221 | change = (emu->capture_source != val); |
| 164 | if (change) { | 222 | if (change) { |
| 165 | emu->capture_source = val; | 223 | emu->capture_source = val; |
| 166 | source = (val << 28) | (val << 24) | (val << 20) | (val << 16); | 224 | ca0106_set_capture_source(emu); |
| 167 | mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff; | ||
| 168 | snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask); | ||
| 169 | } | 225 | } |
| 170 | return change; | 226 | return change; |
| 171 | } | 227 | } |
| @@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, | |||
| 200 | { | 256 | { |
| 201 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 257 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 202 | unsigned int source_id; | 258 | unsigned int source_id; |
| 203 | unsigned int ngain, ogain; | ||
| 204 | int change = 0; | 259 | int change = 0; |
| 205 | u32 source; | ||
| 206 | /* If the capture source has changed, | 260 | /* If the capture source has changed, |
| 207 | * update the capture volume from the cached value | 261 | * update the capture volume from the cached value |
| 208 | * for the particular source. | 262 | * for the particular source. |
| @@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, | |||
| 212 | return -EINVAL; | 266 | return -EINVAL; |
| 213 | change = (emu->i2c_capture_source != source_id); | 267 | change = (emu->i2c_capture_source != source_id); |
| 214 | if (change) { | 268 | if (change) { |
| 215 | snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | 269 | ca0106_set_i2c_capture_source(emu, source_id, 0); |
| 216 | ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ | ||
| 217 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ | ||
| 218 | if (ngain != ogain) | ||
| 219 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff)); | ||
| 220 | ngain = emu->i2c_capture_volume[source_id][1]; /* Left */ | ||
| 221 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */ | ||
| 222 | if (ngain != ogain) | ||
| 223 | snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); | ||
| 224 | source = 1 << source_id; | ||
| 225 | snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */ | ||
| 226 | emu->i2c_capture_source = source_id; | ||
| 227 | } | 270 | } |
| 228 | return change; | 271 | return change; |
| 229 | } | 272 | } |
| @@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol, | |||
| 271 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 314 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 272 | unsigned int val; | 315 | unsigned int val; |
| 273 | int change = 0; | 316 | int change = 0; |
| 274 | u32 tmp; | ||
| 275 | 317 | ||
| 276 | val = ucontrol->value.enumerated.item[0] ; | 318 | val = ucontrol->value.enumerated.item[0] ; |
| 277 | if (val > 1) | 319 | if (val > 1) |
| @@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol, | |||
| 279 | change = (emu->capture_mic_line_in != val); | 321 | change = (emu->capture_mic_line_in != val); |
| 280 | if (change) { | 322 | if (change) { |
| 281 | emu->capture_mic_line_in = val; | 323 | emu->capture_mic_line_in = val; |
| 282 | if (val) { | 324 | ca0106_set_capture_mic_line_in(emu); |
| 283 | //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | ||
| 284 | tmp = inl(emu->port+GPIO) & ~0x400; | ||
| 285 | tmp = tmp | 0x400; | ||
| 286 | outl(tmp, emu->port+GPIO); | ||
| 287 | //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); | ||
| 288 | } else { | ||
| 289 | //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ | ||
| 290 | tmp = inl(emu->port+GPIO) & ~0x400; | ||
| 291 | outl(tmp, emu->port+GPIO); | ||
| 292 | //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); | ||
| 293 | } | ||
| 294 | } | 325 | } |
| 295 | return change; | 326 | return change; |
| 296 | } | 327 | } |
| @@ -322,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol, | |||
| 322 | return 0; | 353 | return 0; |
| 323 | } | 354 | } |
| 324 | 355 | ||
| 325 | static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol, | 356 | static void decode_spdif_bits(unsigned char *status, unsigned int bits) |
| 357 | { | ||
| 358 | status[0] = (bits >> 0) & 0xff; | ||
| 359 | status[1] = (bits >> 8) & 0xff; | ||
| 360 | status[2] = (bits >> 16) & 0xff; | ||
| 361 | status[3] = (bits >> 24) & 0xff; | ||
| 362 | } | ||
| 363 | |||
| 364 | static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol, | ||
| 326 | struct snd_ctl_elem_value *ucontrol) | 365 | struct snd_ctl_elem_value *ucontrol) |
| 327 | { | 366 | { |
| 328 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 367 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 329 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 368 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
| 330 | 369 | ||
| 331 | ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; | 370 | decode_spdif_bits(ucontrol->value.iec958.status, |
| 332 | ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; | 371 | emu->spdif_bits[idx]); |
| 333 | ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; | 372 | return 0; |
| 334 | ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; | 373 | } |
| 374 | |||
| 375 | static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol, | ||
| 376 | struct snd_ctl_elem_value *ucontrol) | ||
| 377 | { | ||
| 378 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | ||
| 379 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
| 380 | |||
| 381 | decode_spdif_bits(ucontrol->value.iec958.status, | ||
| 382 | emu->spdif_str_bits[idx]); | ||
| 335 | return 0; | 383 | return 0; |
| 336 | } | 384 | } |
| 337 | 385 | ||
| @@ -345,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol, | |||
| 345 | return 0; | 393 | return 0; |
| 346 | } | 394 | } |
| 347 | 395 | ||
| 348 | static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol, | 396 | static unsigned int encode_spdif_bits(unsigned char *status) |
| 397 | { | ||
| 398 | return ((unsigned int)status[0] << 0) | | ||
| 399 | ((unsigned int)status[1] << 8) | | ||
| 400 | ((unsigned int)status[2] << 16) | | ||
| 401 | ((unsigned int)status[3] << 24); | ||
| 402 | } | ||
| 403 | |||
| 404 | static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol, | ||
| 349 | struct snd_ctl_elem_value *ucontrol) | 405 | struct snd_ctl_elem_value *ucontrol) |
| 350 | { | 406 | { |
| 351 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | 407 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); |
| 352 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 408 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
| 353 | int change; | ||
| 354 | unsigned int val; | 409 | unsigned int val; |
| 355 | 410 | ||
| 356 | val = (ucontrol->value.iec958.status[0] << 0) | | 411 | val = encode_spdif_bits(ucontrol->value.iec958.status); |
| 357 | (ucontrol->value.iec958.status[1] << 8) | | 412 | if (val != emu->spdif_bits[idx]) { |
| 358 | (ucontrol->value.iec958.status[2] << 16) | | ||
| 359 | (ucontrol->value.iec958.status[3] << 24); | ||
| 360 | change = val != emu->spdif_bits[idx]; | ||
| 361 | if (change) { | ||
| 362 | snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val); | ||
| 363 | emu->spdif_bits[idx] = val; | 413 | emu->spdif_bits[idx] = val; |
| 414 | /* FIXME: this isn't safe, but needed to keep the compatibility | ||
| 415 | * with older alsa-lib config | ||
| 416 | */ | ||
| 417 | emu->spdif_str_bits[idx] = val; | ||
| 418 | ca0106_set_spdif_bits(emu, idx); | ||
| 419 | return 1; | ||
| 364 | } | 420 | } |
| 365 | return change; | 421 | return 0; |
| 422 | } | ||
| 423 | |||
| 424 | static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol, | ||
| 425 | struct snd_ctl_elem_value *ucontrol) | ||
| 426 | { | ||
| 427 | struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); | ||
| 428 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
| 429 | unsigned int val; | ||
| 430 | |||
| 431 | val = encode_spdif_bits(ucontrol->value.iec958.status); | ||
| 432 | if (val != emu->spdif_str_bits[idx]) { | ||
| 433 | emu->spdif_str_bits[idx] = val; | ||
| 434 | ca0106_set_spdif_bits(emu, idx); | ||
| 435 | return 1; | ||
| 436 | } | ||
| 437 | return 0; | ||
| 366 | } | 438 | } |
| 367 | 439 | ||
| 368 | static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol, | 440 | static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol, |
| @@ -573,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { | |||
| 573 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 645 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
| 574 | .count = 4, | 646 | .count = 4, |
| 575 | .info = snd_ca0106_spdif_info, | 647 | .info = snd_ca0106_spdif_info, |
| 576 | .get = snd_ca0106_spdif_get, | 648 | .get = snd_ca0106_spdif_get_default, |
| 577 | .put = snd_ca0106_spdif_put | 649 | .put = snd_ca0106_spdif_put_default |
| 650 | }, | ||
| 651 | { | ||
| 652 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
| 653 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), | ||
| 654 | .count = 4, | ||
| 655 | .info = snd_ca0106_spdif_info, | ||
| 656 | .get = snd_ca0106_spdif_get_stream, | ||
| 657 | .put = snd_ca0106_spdif_put_stream | ||
| 578 | }, | 658 | }, |
| 579 | }; | 659 | }; |
| 580 | 660 | ||
| @@ -773,3 +853,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) | |||
| 773 | return 0; | 853 | return 0; |
| 774 | } | 854 | } |
| 775 | 855 | ||
| 856 | #ifdef CONFIG_PM | ||
| 857 | struct ca0106_vol_tbl { | ||
| 858 | unsigned int channel_id; | ||
| 859 | unsigned int reg; | ||
| 860 | }; | ||
| 861 | |||
| 862 | static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = { | ||
| 863 | { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 }, | ||
| 864 | { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 }, | ||
| 865 | { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 }, | ||
| 866 | { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 }, | ||
| 867 | { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 }, | ||
| 868 | { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 }, | ||
| 869 | { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 }, | ||
| 870 | { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 }, | ||
| 871 | { 1, CAPTURE_CONTROL }, | ||
| 872 | }; | ||
| 873 | |||
| 874 | void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip) | ||
| 875 | { | ||
| 876 | int i; | ||
| 877 | |||
| 878 | /* save volumes */ | ||
| 879 | for (i = 0; i < NUM_SAVED_VOLUMES; i++) | ||
| 880 | chip->saved_vol[i] = | ||
| 881 | snd_ca0106_ptr_read(chip, saved_volumes[i].reg, | ||
| 882 | saved_volumes[i].channel_id); | ||
| 883 | } | ||
| 884 | |||
| 885 | void snd_ca0106_mixer_resume(struct snd_ca0106 *chip) | ||
| 886 | { | ||
| 887 | int i; | ||
| 888 | |||
| 889 | for (i = 0; i < NUM_SAVED_VOLUMES; i++) | ||
| 890 | snd_ca0106_ptr_write(chip, saved_volumes[i].reg, | ||
| 891 | saved_volumes[i].channel_id, | ||
| 892 | chip->saved_vol[i]); | ||
| 893 | |||
| 894 | ca0106_spdif_enable(chip); | ||
| 895 | ca0106_set_capture_source(chip); | ||
| 896 | ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1); | ||
| 897 | for (i = 0; i < 4; i++) | ||
| 898 | ca0106_set_spdif_bits(chip, i); | ||
| 899 | if (chip->details->i2c_adc) | ||
| 900 | ca0106_set_capture_mic_line_in(chip); | ||
| 901 | } | ||
| 902 | #endif /* CONFIG_PM */ | ||
