void update_hpvol() { unsigned short val; DECLARE_WM8994(codec); // don't affect headphone amplifier volume // when not on heapdhones or if call is active if (!is_path(HEADPHONES) || (wm8994->codec_state & CALL_ACTIVE)) return; bypass_write_hook = true; // we don't need the Volume Update flag when sending the first volume val = (WM8994_HPOUT1L_MUTE_N | hplvol); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val); // this time we write the right volume plus the Volume Update flag. //This way, both volume are set at the same time val = (WM8994_HPOUT1_VU | WM8994_HPOUT1R_MUTE_N | hprvol); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val); bypass_write_hook = false; }
static int wm8994_device_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } ret = wm8994_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK, WM8994_NUM_IRQ_REGS * 2, &wm8994->irq_masks_cur); if (ret < 0) dev_err(dev, "Failed to restore interrupt masks: %d\n", ret); ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, &wm8994->ldo_regs); if (ret < 0) dev_err(dev, "Failed to restore LDO registers: %d\n", ret); ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2, &wm8994->gpio_regs); if (ret < 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); return 0; }
static int wm8994_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; /* We may have lied to the PM core about suspending */ if (!wm8994->suspended) return 0; ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } ret = wm8994_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK, WM8994_NUM_IRQ_REGS * 2, &wm8994->irq_masks_cur); if (ret < 0) dev_err(dev, "Failed to restore interrupt masks: %d\n", ret); ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, &wm8994->ldo_regs); if (ret < 0) dev_err(dev, "Failed to restore LDO registers: %d\n", ret); ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2, &wm8994->gpio_regs); if (ret < 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); wm8994->suspended = false; return 0; }
static void set_headphones(void) { unsigned int val; /* get current headphones level value and force setting it, soundlevel mod will be handled on wm8994.c */ val = wm8994_read(soundlevel_codec, WM8994_LEFT_OUTPUT_VOLUME); wm8994_write(soundlevel_codec, WM8994_LEFT_OUTPUT_VOLUME, val); val = wm8994_read(soundlevel_codec, WM8994_RIGHT_OUTPUT_VOLUME); wm8994_write(soundlevel_codec, WM8994_RIGHT_OUTPUT_VOLUME, val | WM8994_HPOUT1_VU); /* Set the update flag to actually apply the new setting */ }
static void set_speaker(void) { unsigned int val; /* get current headphones level value and force setting it, soundlevel mod will be handled on wm8994.c */ val = wm8994_read(soundlevel_codec, WM8994_SPEAKER_VOLUME_LEFT); wm8994_write(soundlevel_codec, WM8994_SPEAKER_VOLUME_LEFT, val); val = wm8994_read(soundlevel_codec, WM8994_SPEAKER_VOLUME_RIGHT); wm8994_write(soundlevel_codec, WM8994_SPEAKER_VOLUME_RIGHT, val | WM8994_SPKOUT_VU); /* Set the update flag to actually apply the new setting */ }
void write_hpvol(unsigned short l, unsigned short r) { unsigned short val; // we don't need the Volume Update flag when sending the first volume val = (WM8994_HPOUT1L_MUTE_N | l); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val); // this time we write the right volume plus the Volume Update flag. // This way, both volume are set at the same time val = (WM8994_HPOUT1_VU | WM8994_HPOUT1R_MUTE_N | r); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val); }
static int wm8994_device_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret, i; set_mclk(1); /* We may have lied to the PM core about suspending */ if (!wm8994->suspended) return 0; ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Write register at a time as we use the cache on the CPU so store * it in native endian. */ for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { ret = wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK + i, wm8994->irq_masks_cur[i]); if (ret < 0) dev_err(dev, "Failed to restore interrupt masks: %d\n", ret); } ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, &wm8994->ldo_regs); if (ret < 0) dev_err(dev, "Failed to restore LDO registers: %d\n", ret); ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2, &wm8994->gpio_regs); if (ret < 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); /* Disable LDO pulldowns while the device is active */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD, 0); wm8994->suspended = false; return 0; }
/** * wm8994_set_bits: Set the value of a bitfield in a WM8994 register * * @wm8994: Device to write to. * @reg: Register to write to. * @mask: Mask of bits to set. * @val: Value to set (unshifted) */ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, unsigned short mask, unsigned short val) { int ret; u16 r; mutex_lock(&wm8994->io_lock); ret = wm8994_read(wm8994, reg, 2, &r); if (ret < 0) goto out; r = be16_to_cpu(r); r &= ~mask; r |= val; r = cpu_to_be16(r); ret = wm8994_write(wm8994, reg, 2, &r); out: mutex_unlock(&wm8994->io_lock); return ret; }
void update_osr128(bool with_mute) { unsigned short val; val = osr128_get_value(wm8994_read(codec, WM8994_OVERSAMPLING)); bypass_write_hook = true; wm8994_write(codec, WM8994_OVERSAMPLING, val); bypass_write_hook = false; }
void update_fm_radio_headset_restore_freqs(bool with_mute) { unsigned short val; DECLARE_WM8994(codec); bypass_write_extension = true; // apply only when FM radio is active if (wm8994->fmradio_path == FMR_OFF) return; if (with_mute) { wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, WM8994_AIF2DAC_MUTE | WM8994_AIF2DAC_MUTERATE | WM8994_AIF2DAC_UNMUTE_RAMP | WM8994_AIF2DAC_DEEMP_MASK); msleep(180); } if (fm_radio_headset_restore_bass) { // disable Sidetone high-pass filter // was designed for voice and not FM radio wm8994_write(codec, WM8994_SIDETONE, 0x0000); // disable 4FS ultrasonic mode and // restore the hi-fi <4Hz hi pass filter wm8994_write(codec, WM8994_AIF2_ADC_FILTERS, WM8994_AIF2ADCL_HPF | WM8994_AIF2ADCR_HPF); } else { // default settings in GT-I9000 Froyo XXJPX kernel sources wm8994_write(codec, WM8994_SIDETONE, 0x01c0); wm8994_write(codec, WM8994_AIF2_ADC_FILTERS, 0xF800); } if (fm_radio_headset_restore_highs) { val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1); val &= ~(WM8994_AIF2DAC_DEEMP_MASK); wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val); } else { wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0036); } // un-mute if (with_mute) { val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1); val &= ~(WM8994_AIF2DAC_MUTE_MASK); wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val); } bypass_write_extension = false; }
/** * wm8994_bulk_write: Write multiple WM8994 registers * * @wm8994: Device to write to * @reg: First register * @count: Number of registers * @buf: Buffer to write from. Data must be big-endian formatted. */ int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, int count, const u16 *buf) { int ret; mutex_lock(&wm8994->io_lock); ret = wm8994_write(wm8994, reg, count * 2, buf); mutex_unlock(&wm8994->io_lock); return ret; }
void update_volume() { unsigned short val; /* check this later */ bypass_write_hook = true; if (volume_left > 62) volume_left = 62; if (volume_right > 62) volume_right = 62; val = (WM8994_HPOUT1L_MUTE_N | volume_left); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec_, WM8994_LEFT_OUTPUT_VOLUME, val); val = (WM8994_HPOUT1_VU | WM8994_HPOUT1R_MUTE_N | volume_right); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec_, WM8994_RIGHT_OUTPUT_VOLUME, val); bypass_write_hook = false; }
int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, unsigned short val) { int ret; mutex_lock(&wm8994->io_lock); ret = wm8994_write(wm8994, reg, 2, &val); mutex_unlock(&wm8994->io_lock); return ret; }
void update_fm_radio_headset_restore_freqs(bool with_mute) { unsigned short val; // apply only when FM radio is active DECLARE_WM8994(codec_) if (wm8994->fmradio_path == FMR_OFF) return; if (with_mute) { wm8994_write(codec_, WM8994_AIF2_DAC_FILTERS_1, 0x236); msleep(180); } if (fm_radio_headset_restore_bass) { // disable Sidetone high-pass filter designed for voice and not FM radio // Sidetone(621H): 0000 ST_HPF_CUT=000, ST_HPF=0, ST2_SEL=0, ST1_SEL=0 wm8994_write(codec_, WM8994_SIDETONE, 0x0000); // disable 4FS ultrasonic mode and restore the hi-fi <4Hz hi pass filter // AIF2 ADC Filters(510H): 1800 AIF2ADC_4FS=0, AIF2ADC_HPF_CUT=00, AIF2ADCL_HPF=1, AIF2ADCR_HPF=1 wm8994_write(codec_, WM8994_AIF2_ADC_FILTERS, 0x1800); } else { // default settings in GT-I9000 Froyo XXJPX kernel sources wm8994_write(codec_, WM8994_SIDETONE, 0x01c0); wm8994_write(codec_, WM8994_AIF2_ADC_FILTERS, 0xF800); } if (fm_radio_headset_restore_highs) { val = wm8994_read(codec_, WM8994_AIF2_DAC_FILTERS_1); val &= ~(WM8994_AIF2DAC_DEEMP_MASK); wm8994_write(codec_, WM8994_AIF2_DAC_FILTERS_1, val); } else wm8994_write(codec_, WM8994_AIF2_DAC_FILTERS_1, 0x0036); // un-mute if (with_mute) { val = wm8994_read(codec_, WM8994_AIF2_DAC_FILTERS_1); val &= ~(WM8994_AIF2DAC_MUTE_MASK); wm8994_write(codec_, WM8994_AIF2_DAC_FILTERS_1, val); } }
void update_hpvol() { unsigned short val; bypass_write_hook = true; // hard limit to 62 because 63 introduces distortions if (hplvol > 62) hplvol = 62; if (hprvol > 62) hprvol = 62; // we don't need the Volume Update flag when sending the first volume val = (WM8994_HPOUT1L_MUTE_N | hplvol); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val); // this time we write the right volume plus the Volume Update flag. //This way, both volume are set at the same time val = (WM8994_HPOUT1_VU | WM8994_HPOUT1R_MUTE_N | hprvol); val |= WM8994_HPOUT1L_ZC; wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val); bypass_write_hook = false; }
/** * wm8994_reg_write: Write a single WM8994 register. * * @wm8994: Device to write to. * @reg: Register to write to. * @val: Value to write. */ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, unsigned short val) { int ret; mutex_lock(&wm8994->io_lock); #if 1 dev_vdbg(wm8994->dev, "wm8994_reg_write ADRESS is %x, VALUE is %x\n", reg, val); #else printk("wm8994_reg_write ADRESS is %x, VALUE is %x\n", reg, val); #endif ret = wm8994_write(wm8994, reg, 2, &val); mutex_unlock(&wm8994->io_lock); return ret; }
void update_fm_radio_headset_normalize_gain() { if (fm_radio_headset_normalize_gain) { // Bumped volume, change with Zero Cross wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_3_4_VOLUME, 0x52); wm8994_write(codec_, WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, 0x152); wm8994_write(codec_, WM8994_AIF2_DRC_2, 0x0840); wm8994_write(codec_, WM8994_AIF2_DRC_3, 0x2408); wm8994_write(codec_, WM8994_AIF2_DRC_4, 0x0082); wm8994_write(codec_, WM8994_AIF2_DRC_5, 0x0100); wm8994_write(codec_, WM8994_AIF2_DRC_1, 0x019C); } else { // Original volume, change with Zero Cross wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_3_4_VOLUME, 0x4B); wm8994_write(codec_, WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, 0x14B); wm8994_write(codec_, WM8994_AIF2_DRC_2, 0x0840); wm8994_write(codec_, WM8994_AIF2_DRC_3, 0x2400); wm8994_write(codec_, WM8994_AIF2_DRC_4, 0x0000); wm8994_write(codec_, WM8994_AIF2_DRC_5, 0x0000); wm8994_write(codec_, WM8994_AIF2_DRC_1, 0x019C); } }
void update_recording_preset() { switch (recording_preset) { case 0: { // Original: // IN1L_VOL1=11000 (+19.5 dB) wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x0118); // DRC disabled wm8994_write(codec_, WM8994_AIF1_DRC1_1, 0x0080); break; } case 2: { // High sensitivy: Original - 4.5 dB, IN1L_VOL1=10101 (+15 dB) wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x0115); // DRC Input: -6dB, Ouptut -3.75dB // Above knee 1/8, Below knee 1/2 // Max gain 24 / Min gain -12 wm8994_write(codec_, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec_, WM8994_AIF1_DRC1_2, 0x0426); wm8994_write(codec_, WM8994_AIF1_DRC1_3, 0x0019); wm8994_write(codec_, WM8994_AIF1_DRC1_4, 0x0105); break; } case 3: { // Concert: Original - 36 dB IN1L_VOL1=00000 (-16.5 dB) wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x0100); // DRC Input: -4.5dB, Ouptut -6.75dB // Above knee 1/4, Below knee 1/2 // Max gain 18 / Min gain -12 wm8994_write(codec_, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec_, WM8994_AIF1_DRC1_2, 0x0845); wm8994_write(codec_, WM8994_AIF1_DRC1_3, 0x0011); wm8994_write(codec_, WM8994_AIF1_DRC1_4, 0x00C9); break; } default: { // make sure recording_preset is the default: 4 recording_preset = 1; // Balanced: Original - 16.5 dB, IN1L_VOL1=01101 (+3 dB) wm8994_write(codec_, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x054D); // DRC Input: -13.5dB, Ouptut -9dB // Above knee 1/8, Below knee 1/2 // Max gain 12 / Min gain -12 wm8994_write(codec_, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec_, WM8994_AIF1_DRC1_2, 0x0844); wm8994_write(codec_, WM8994_AIF1_DRC1_3, 0x0019); wm8994_write(codec_, WM8994_AIF1_DRC1_4, 0x024C); break; } } }
void update_speaker_tuning(bool with_mute) { DECLARE_WM8994(codec); if (!(is_path(SPEAKER) || (wm8994->codec_state & CALL_ACTIVE))) return; printk("We are on speaker!\n"); if (speaker_tuning) { // DRC settings wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0010); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x00EB); // hardware EQ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_1, 0x041D); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_2, 0x4C00); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_A, 0x0FE3); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_B, 0x0403); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_PG, 0x0074); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_A, 0x1F03); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_B, 0xF0F9); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_C, 0x040A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_PG, 0x03DA); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_A, 0x1ED2); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_B, 0xF11A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_C, 0x040A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_PG, 0x045D); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_4_A, 0x0E76); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_4_B, 0xFCE4); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_4_C, 0x040A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_4_PG, 0x330D); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_5_A, 0xFC8F); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_5_B, 0x0400); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_5_PG, 0x323C); // Speaker Boost tuning wm8994_write(codec, WM8994_CLASSD, 0x0170); } else { // DRC settings wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0028); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x0186); // hardware EQ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_1, 0x0019); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_2, 0x6280); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_A, 0x0FC3); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_B, 0x03FD); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_PG, 0x00F4); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_A, 0x1F30); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_B, 0xF0CD); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_C, 0x040A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_PG, 0x032C); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_A, 0x1C52); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_B, 0xF379); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_C, 0x040A); wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_PG, 0x0DC1); wm8994_write(codec, WM8994_CLASSD, 0x0170); // Speaker Boost tuning wm8994_write(codec, WM8994_CLASSD, 0x0168); } }
void update_recording_preset(bool with_mute) { if (!is_path(MAIN_MICROPHONE)) return; switch (recording_preset) { case 0: // Original: // On Galaxy S: IN1L_VOL1=11000 (+19.5 dB) // On Nexus S: variable value wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1L_VU | origin_recgain); wm8994_write(codec, WM8994_INPUT_MIXER_3, origin_recgain_mixer); // DRC disabled wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x0080); break; case 2: // High sensitivy: // Original - 4.5 dB, IN1L_VOL1=10101 (+15 dB) wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x0115); wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x30); // DRC Input: -6dB, Ouptut -3.75dB // Above knee 1/8, Below knee 1/2 // Max gain 24 / Min gain -12 wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec, WM8994_AIF1_DRC1_2, 0x0426); wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0019); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x0105); break; case 3: // Concert new: IN1L_VOL1=10110 (+4.5 dB) // +30dB input mixer gain deactivated wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x010F); wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x20); // DRC Input: -4.5dB, Ouptut -6.75dB // Above knee 1/4, Below knee 1/2 // Max gain 24 / Min gain -12 wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec, WM8994_AIF1_DRC1_2, 0x0846); wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0011); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x00C9); break; case 4: // ULTRA LOUD: // Original - 36 dB - 30 dB IN1L_VOL1=00000 (-16.5 dB) // +30dB input mixer gain deactivated wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x0100); wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x20); // DRC Input: -7.5dB, Ouptut -6dB // Above knee 1/8, Below knee 1/4 // Max gain 36 / Min gain -12 wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec, WM8994_AIF1_DRC1_2, 0x0847); wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x001A); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x00C9); break; default: // make sure recording_preset is the default recording_preset = 1; // New Balanced: Original - 16.5 dB // IN1L_VOL1=01101 (+27 dB) // +30dB input mixer gain deactivated wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, 0x055D); wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x20); // DRC Input: -18.5dB, Ouptut -9dB // Above knee 1/8, Below knee 1/2 // Max gain 18 / Min gain -12 wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x009A); wm8994_write(codec, WM8994_AIF1_DRC1_2, 0x0845); wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0019); wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x030C); break; } }
void update_fm_radio_headset_normalize_gain(bool with_mute) { DECLARE_WM8994(codec); bypass_write_hook = true; // apply only when FM radio is active if (wm8994->fmradio_path == FMR_OFF) return; if (fm_radio_headset_normalize_gain) { // Bumped volume, change with Zero Cross wm8994_write(codec, WM8994_LEFT_LINE_INPUT_3_4_VOLUME, 0x52); wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, 0x152); wm8994_write(codec, WM8994_AIF2_DRC_2, 0x0840); wm8994_write(codec, WM8994_AIF2_DRC_3, 0x2408); wm8994_write(codec, WM8994_AIF2_DRC_4, 0x0082); wm8994_write(codec, WM8994_AIF2_DRC_5, 0x0100); wm8994_write(codec, WM8994_AIF2_DRC_1, 0x019C); } else { // Original volume, change with Zero Cross wm8994_write(codec, WM8994_LEFT_LINE_INPUT_3_4_VOLUME, 0x4B); wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, 0x14B); wm8994_write(codec, WM8994_AIF2_DRC_2, 0x0840); wm8994_write(codec, WM8994_AIF2_DRC_3, 0x2400); wm8994_write(codec, WM8994_AIF2_DRC_4, 0x0000); wm8994_write(codec, WM8994_AIF2_DRC_5, 0x0000); wm8994_write(codec, WM8994_AIF2_DRC_1, 0x019C); } bypass_write_hook = false; }