static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct prodigy_hifi_spec *spec = ice->spec; int ch, change = 0; mutex_lock(&ice->gpio_mutex); for (ch = 0; ch < 2; ch++) { if (ucontrol->value.integer.value[ch] != spec->master[ch]) { spec->master[ch] = ucontrol->value.integer.value[ch]; wm_set_vol(ice, WM_DAC_ATTEN_L + ch, spec->vol[2 + ch], spec->master[ch]); wm8766_set_vol(ice, WM8766_LDA1 + ch, spec->vol[0 + ch], spec->master[ch]); wm8766_set_vol(ice, WM8766_LDA2 + ch, spec->vol[4 + ch], spec->master[ch]); wm8766_set_vol(ice, WM8766_LDA3 + ch, spec->vol[6 + ch], spec->master[ch]); change = 1; } } mutex_unlock(&ice->gpio_mutex); return change; }
static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct prodigy_hifi_spec *spec = ice->spec; int i, idx, change = 0; mutex_lock(&ice->gpio_mutex); for (i = 0; i < 2; i++) { if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) { idx = WM_DAC_ATTEN_L + i; spec->vol[2 + i] &= WM_VOL_MUTE; spec->vol[2 + i] |= ucontrol->value.integer.value[i]; wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]); change = 1; } } mutex_unlock(&ice->gpio_mutex); return change; }
static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int ch, change = 0; snd_ice1712_save_gpio_status(ice); for (ch = 0; ch < 2; ch++) { if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) { int dac; ice->spec.phase28.master[ch] &= WM_VOL_MUTE; ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch]; for (dac = 0; dac < ice->num_total_dacs; dac += 2) wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, ice->spec.phase28.vol[dac + ch], ice->spec.phase28.master[ch]); change = 1; } } snd_ice1712_restore_gpio_status(ice); return change; }
static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int i, idx, ofs, voices; int change = 0; voices = kcontrol->private_value >> 8; ofs = kcontrol->private_value & 0xff; snd_ice1712_save_gpio_status(ice); for (i = 0; i < voices; i++) { idx = WM_DAC_ATTEN + ofs + i; if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) { ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE; ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i]; wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i], ice->spec.phase28.master[i]); change = 1; } } snd_ice1712_restore_gpio_status(ice); return change; }
static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int change = 0, i; snd_ice1712_save_gpio_status(ice); for (i = 0; i < 2; i++) { int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1; if (ucontrol->value.integer.value[i] != val) { int dac; ice->spec.phase28.master[i] &= ~WM_VOL_MUTE; ice->spec.phase28.master[i] |= ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; for (dac = 0; dac < ice->num_total_dacs; dac += 2) wm_set_vol(ice, WM_DAC_ATTEN + dac + i, ice->spec.phase28.vol[dac + i], ice->spec.phase28.master[i]); change = 1; } } snd_ice1712_restore_gpio_status(ice); return change; }
static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int change = 0, voices, ofs, i; voices = kcontrol->private_value >> 8; ofs = kcontrol->private_value & 0xFF; snd_ice1712_save_gpio_status(ice); for (i = 0; i < voices; i++) { int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; if (ucontrol->value.integer.value[i] != val) { ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE; ice->spec.phase28.vol[ofs + i] |= ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i], ice->spec.phase28.master[i]); change = 1; } } snd_ice1712_restore_gpio_status(ice); return change; }
static int __devinit phase28_init(struct snd_ice1712 *ice) { static const unsigned short wm_inits_phase28[] = { /* These come first to reduce init pop noise */ 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ 0x18, 0x000, /* All power-up */ 0x16, 0x122, /* I2S, normal polarity, 24bit */ 0x17, 0x022, /* 256fs, slave mode */ 0x00, 0, /* DAC1 analog mute */ 0x01, 0, /* DAC2 analog mute */ 0x02, 0, /* DAC3 analog mute */ 0x03, 0, /* DAC4 analog mute */ 0x04, 0, /* DAC5 analog mute */ 0x05, 0, /* DAC6 analog mute */ 0x06, 0, /* DAC7 analog mute */ 0x07, 0, /* DAC8 analog mute */ 0x08, 0x100, /* master analog mute */ 0x09, 0xff, /* DAC1 digital full */ 0x0a, 0xff, /* DAC2 digital full */ 0x0b, 0xff, /* DAC3 digital full */ 0x0c, 0xff, /* DAC4 digital full */ 0x0d, 0xff, /* DAC5 digital full */ 0x0e, 0xff, /* DAC6 digital full */ 0x0f, 0xff, /* DAC7 digital full */ 0x10, 0xff, /* DAC8 digital full */ 0x11, 0x1ff, /* master digital full */ 0x12, 0x000, /* phase normal */ 0x13, 0x090, /* unmute DAC L/R */ 0x14, 0x000, /* all unmute */ 0x15, 0x000, /* no deemphasis, no ZFLG */ 0x19, 0x000, /* -12dB ADC/L */ 0x1a, 0x000, /* -12dB ADC/R */ (unsigned short)-1 }; unsigned int tmp; struct snd_akm4xxx *ak; const unsigned short *p; int i; ice->num_total_dacs = 8; ice->num_total_adcs = 2; // Initialize analog chips ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (!ak) return -ENOMEM; ice->akm_codecs = 1; snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ /* reset the wm codec as the SPI mode */ snd_ice1712_save_gpio_status(ice); snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL)); tmp = snd_ice1712_gpio_read(ice); tmp &= ~PHASE28_WM_RESET; snd_ice1712_gpio_write(ice, tmp); udelay(1); tmp |= PHASE28_WM_CS; snd_ice1712_gpio_write(ice, tmp); udelay(1); tmp |= PHASE28_WM_RESET; snd_ice1712_gpio_write(ice, tmp); udelay(1); p = wm_inits_phase28; for (; *p != (unsigned short)-1; p += 2) wm_put(ice, p[0], p[1]); snd_ice1712_restore_gpio_status(ice); ice->spec.phase28.master[0] = WM_VOL_MUTE; ice->spec.phase28.master[1] = WM_VOL_MUTE; for (i = 0; i < ice->num_total_dacs; i++) { ice->spec.phase28.vol[i] = WM_VOL_MUTE; wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]); } return 0; }