/* This struct is used to save the context */ struct wm9090_priv { struct wm9090_platform_data pdata; struct regmap *regmap;
};
staticbool wm9090_volatile(struct device *dev, unsignedint reg)
{ switch (reg) { case WM9090_SOFTWARE_RESET: case WM9090_DC_SERVO_0: case WM9090_DC_SERVO_READBACK_0: case WM9090_DC_SERVO_READBACK_1: case WM9090_DC_SERVO_READBACK_2: returntrue;
default: returnfalse;
}
}
staticbool wm9090_readable(struct device *dev, unsignedint reg)
{ switch (reg) { case WM9090_SOFTWARE_RESET: case WM9090_POWER_MANAGEMENT_1: case WM9090_POWER_MANAGEMENT_2: case WM9090_POWER_MANAGEMENT_3: case WM9090_CLOCKING_1: case WM9090_IN1_LINE_CONTROL: case WM9090_IN2_LINE_CONTROL: case WM9090_IN1_LINE_INPUT_A_VOLUME: case WM9090_IN1_LINE_INPUT_B_VOLUME: case WM9090_IN2_LINE_INPUT_A_VOLUME: case WM9090_IN2_LINE_INPUT_B_VOLUME: case WM9090_LEFT_OUTPUT_VOLUME: case WM9090_RIGHT_OUTPUT_VOLUME: case WM9090_SPKMIXL_ATTENUATION: case WM9090_SPKOUT_MIXERS: case WM9090_CLASSD3: case WM9090_SPEAKER_VOLUME_LEFT: case WM9090_OUTPUT_MIXER1: case WM9090_OUTPUT_MIXER2: case WM9090_OUTPUT_MIXER3: case WM9090_OUTPUT_MIXER4: case WM9090_SPEAKER_MIXER: case WM9090_ANTIPOP2: case WM9090_WRITE_SEQUENCER_0: case WM9090_WRITE_SEQUENCER_1: case WM9090_WRITE_SEQUENCER_2: case WM9090_WRITE_SEQUENCER_3: case WM9090_WRITE_SEQUENCER_4: case WM9090_WRITE_SEQUENCER_5: case WM9090_CHARGE_PUMP_1: case WM9090_DC_SERVO_0: case WM9090_DC_SERVO_1: case WM9090_DC_SERVO_3: case WM9090_DC_SERVO_READBACK_0: case WM9090_DC_SERVO_READBACK_1: case WM9090_DC_SERVO_READBACK_2: case WM9090_ANALOGUE_HP_0: case WM9090_AGC_CONTROL_0: case WM9090_AGC_CONTROL_1: case WM9090_AGC_CONTROL_2: returntrue;
/* Start the DC servo. We don't currently use the * ability to save the state since we don't have full * control of the analogue paths and they can change * DC offsets; see the WM8904 driver for an example of * doing so.
*/
snd_soc_component_write(component, WM9090_DC_SERVO_0,
WM9090_DCS_ENA_CHAN_0 |
WM9090_DCS_ENA_CHAN_1 |
WM9090_DCS_TRIG_STARTUP_1 |
WM9090_DCS_TRIG_STARTUP_0);
wait_for_dc_servo(component);
if (wm9090->pdata.agc_ena) { for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
snd_soc_component_write(component, WM9090_AGC_CONTROL_0 + i,
wm9090->pdata.agc[i]);
snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
WM9090_AGC_ENA, WM9090_AGC_ENA);
} else {
snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
WM9090_AGC_ENA, 0);
}
return 0;
}
/* * The machine driver should call this from their set_bias_level; if there * isn't one then this can just be set as the set_bias_level function.
*/ staticint wm9090_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level)
{ struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
case SND_SOC_BIAS_STANDBY: if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { /* Restore the register cache */
regcache_sync(wm9090->regmap);
}
/* We keep VMID off during standby since the combination of * ground referenced outputs and class D speaker mean that * latency is not an issue.
*/
snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
snd_soc_component_update_bits(component, WM9090_ANTIPOP2,
WM9090_VMID_ENA, 0); break;
case SND_SOC_BIAS_OFF: break;
}
return 0;
}
staticint wm9090_probe(struct snd_soc_component *component)
{ /* Configure some defaults; they will be written out when we * bring the bias up.
*/
snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_A_VOLUME,
WM9090_IN1_VU | WM9090_IN1A_ZC,
WM9090_IN1_VU | WM9090_IN1A_ZC);
snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_B_VOLUME,
WM9090_IN1_VU | WM9090_IN1B_ZC,
WM9090_IN1_VU | WM9090_IN1B_ZC);
snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_A_VOLUME,
WM9090_IN2_VU | WM9090_IN2A_ZC,
WM9090_IN2_VU | WM9090_IN2A_ZC);
snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_B_VOLUME,
WM9090_IN2_VU | WM9090_IN2B_ZC,
WM9090_IN2_VU | WM9090_IN2B_ZC);
snd_soc_component_update_bits(component, WM9090_SPEAKER_VOLUME_LEFT,
WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
snd_soc_component_update_bits(component, WM9090_LEFT_OUTPUT_VOLUME,
WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
snd_soc_component_update_bits(component, WM9090_RIGHT_OUTPUT_VOLUME,
WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.