0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/errno.h>
0012 #include <linux/device.h>
0013 #include <linux/i2c.h>
0014 #include <linux/delay.h>
0015 #include <linux/regmap.h>
0016 #include <linux/slab.h>
0017 #include <sound/initval.h>
0018 #include <sound/soc.h>
0019 #include <sound/tlv.h>
0020 #include <sound/wm9090.h>
0021
0022 #include "wm9090.h"
0023
0024 static const struct reg_default wm9090_reg_defaults[] = {
0025 { 1, 0x0006 },
0026 { 2, 0x6000 },
0027 { 3, 0x0000 },
0028 { 6, 0x01C0 },
0029 { 22, 0x0003 },
0030 { 23, 0x0003 },
0031 { 24, 0x0083 },
0032 { 25, 0x0083 },
0033 { 26, 0x0083 },
0034 { 27, 0x0083 },
0035 { 28, 0x002D },
0036 { 29, 0x002D },
0037 { 34, 0x0100 },
0038 { 35, 0x0010 },
0039 { 37, 0x0140 },
0040 { 38, 0x0039 },
0041 { 45, 0x0000 },
0042 { 46, 0x0000 },
0043 { 47, 0x0100 },
0044 { 48, 0x0100 },
0045 { 54, 0x0000 },
0046 { 57, 0x000D },
0047 { 70, 0x0000 },
0048 { 71, 0x0000 },
0049 { 72, 0x0000 },
0050 { 73, 0x0000 },
0051 { 74, 0x0000 },
0052 { 75, 0x0000 },
0053 { 76, 0x1F25 },
0054 { 85, 0x054A },
0055 { 87, 0x0000 },
0056 { 96, 0x0100 },
0057 { 98, 0x8640 },
0058 { 99, 0xC000 },
0059 { 100, 0x0200 },
0060 };
0061
0062
0063 struct wm9090_priv {
0064 struct wm9090_platform_data pdata;
0065 struct regmap *regmap;
0066 };
0067
0068 static bool wm9090_volatile(struct device *dev, unsigned int reg)
0069 {
0070 switch (reg) {
0071 case WM9090_SOFTWARE_RESET:
0072 case WM9090_DC_SERVO_0:
0073 case WM9090_DC_SERVO_READBACK_0:
0074 case WM9090_DC_SERVO_READBACK_1:
0075 case WM9090_DC_SERVO_READBACK_2:
0076 return true;
0077
0078 default:
0079 return false;
0080 }
0081 }
0082
0083 static bool wm9090_readable(struct device *dev, unsigned int reg)
0084 {
0085 switch (reg) {
0086 case WM9090_SOFTWARE_RESET:
0087 case WM9090_POWER_MANAGEMENT_1:
0088 case WM9090_POWER_MANAGEMENT_2:
0089 case WM9090_POWER_MANAGEMENT_3:
0090 case WM9090_CLOCKING_1:
0091 case WM9090_IN1_LINE_CONTROL:
0092 case WM9090_IN2_LINE_CONTROL:
0093 case WM9090_IN1_LINE_INPUT_A_VOLUME:
0094 case WM9090_IN1_LINE_INPUT_B_VOLUME:
0095 case WM9090_IN2_LINE_INPUT_A_VOLUME:
0096 case WM9090_IN2_LINE_INPUT_B_VOLUME:
0097 case WM9090_LEFT_OUTPUT_VOLUME:
0098 case WM9090_RIGHT_OUTPUT_VOLUME:
0099 case WM9090_SPKMIXL_ATTENUATION:
0100 case WM9090_SPKOUT_MIXERS:
0101 case WM9090_CLASSD3:
0102 case WM9090_SPEAKER_VOLUME_LEFT:
0103 case WM9090_OUTPUT_MIXER1:
0104 case WM9090_OUTPUT_MIXER2:
0105 case WM9090_OUTPUT_MIXER3:
0106 case WM9090_OUTPUT_MIXER4:
0107 case WM9090_SPEAKER_MIXER:
0108 case WM9090_ANTIPOP2:
0109 case WM9090_WRITE_SEQUENCER_0:
0110 case WM9090_WRITE_SEQUENCER_1:
0111 case WM9090_WRITE_SEQUENCER_2:
0112 case WM9090_WRITE_SEQUENCER_3:
0113 case WM9090_WRITE_SEQUENCER_4:
0114 case WM9090_WRITE_SEQUENCER_5:
0115 case WM9090_CHARGE_PUMP_1:
0116 case WM9090_DC_SERVO_0:
0117 case WM9090_DC_SERVO_1:
0118 case WM9090_DC_SERVO_3:
0119 case WM9090_DC_SERVO_READBACK_0:
0120 case WM9090_DC_SERVO_READBACK_1:
0121 case WM9090_DC_SERVO_READBACK_2:
0122 case WM9090_ANALOGUE_HP_0:
0123 case WM9090_AGC_CONTROL_0:
0124 case WM9090_AGC_CONTROL_1:
0125 case WM9090_AGC_CONTROL_2:
0126 return true;
0127
0128 default:
0129 return false;
0130 }
0131 }
0132
0133 static void wait_for_dc_servo(struct snd_soc_component *component)
0134 {
0135 unsigned int reg;
0136 int count = 0;
0137
0138 dev_dbg(component->dev, "Waiting for DC servo...\n");
0139 do {
0140 count++;
0141 msleep(1);
0142 reg = snd_soc_component_read(component, WM9090_DC_SERVO_READBACK_0);
0143 dev_dbg(component->dev, "DC servo status: %x\n", reg);
0144 } while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
0145 != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
0146
0147 if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
0148 != WM9090_DCS_CAL_COMPLETE_MASK)
0149 dev_err(component->dev, "Timed out waiting for DC Servo\n");
0150 }
0151
0152 static const DECLARE_TLV_DB_RANGE(in_tlv,
0153 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
0154 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
0155 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0)
0156 );
0157 static const DECLARE_TLV_DB_RANGE(mix_tlv,
0158 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
0159 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0)
0160 );
0161 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
0162 static const DECLARE_TLV_DB_RANGE(spkboost_tlv,
0163 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
0164 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0)
0165 );
0166
0167 static const struct snd_kcontrol_new wm9090_controls[] = {
0168 SOC_SINGLE_TLV("IN1A Volume", WM9090_IN1_LINE_INPUT_A_VOLUME, 0, 6, 0,
0169 in_tlv),
0170 SOC_SINGLE("IN1A Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 7, 1, 1),
0171 SOC_SINGLE("IN1A ZC Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 6, 1, 0),
0172
0173 SOC_SINGLE_TLV("IN2A Volume", WM9090_IN2_LINE_INPUT_A_VOLUME, 0, 6, 0,
0174 in_tlv),
0175 SOC_SINGLE("IN2A Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 7, 1, 1),
0176 SOC_SINGLE("IN2A ZC Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 6, 1, 0),
0177
0178 SOC_SINGLE("MIXOUTL Switch", WM9090_OUTPUT_MIXER3, 8, 1, 1),
0179 SOC_SINGLE_TLV("MIXOUTL IN1A Volume", WM9090_OUTPUT_MIXER3, 6, 3, 1,
0180 mix_tlv),
0181 SOC_SINGLE_TLV("MIXOUTL IN2A Volume", WM9090_OUTPUT_MIXER3, 2, 3, 1,
0182 mix_tlv),
0183
0184 SOC_SINGLE("MIXOUTR Switch", WM9090_OUTPUT_MIXER4, 8, 1, 1),
0185 SOC_SINGLE_TLV("MIXOUTR IN1A Volume", WM9090_OUTPUT_MIXER4, 6, 3, 1,
0186 mix_tlv),
0187 SOC_SINGLE_TLV("MIXOUTR IN2A Volume", WM9090_OUTPUT_MIXER4, 2, 3, 1,
0188 mix_tlv),
0189
0190 SOC_SINGLE("SPKMIX Switch", WM9090_SPKMIXL_ATTENUATION, 8, 1, 1),
0191 SOC_SINGLE_TLV("SPKMIX IN1A Volume", WM9090_SPKMIXL_ATTENUATION, 6, 3, 1,
0192 mix_tlv),
0193 SOC_SINGLE_TLV("SPKMIX IN2A Volume", WM9090_SPKMIXL_ATTENUATION, 2, 3, 1,
0194 mix_tlv),
0195
0196 SOC_DOUBLE_R_TLV("Headphone Volume", WM9090_LEFT_OUTPUT_VOLUME,
0197 WM9090_RIGHT_OUTPUT_VOLUME, 0, 63, 0, out_tlv),
0198 SOC_DOUBLE_R("Headphone Switch", WM9090_LEFT_OUTPUT_VOLUME,
0199 WM9090_RIGHT_OUTPUT_VOLUME, 6, 1, 1),
0200 SOC_DOUBLE_R("Headphone ZC Switch", WM9090_LEFT_OUTPUT_VOLUME,
0201 WM9090_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
0202
0203 SOC_SINGLE_TLV("Speaker Volume", WM9090_SPEAKER_VOLUME_LEFT, 0, 63, 0,
0204 out_tlv),
0205 SOC_SINGLE("Speaker Switch", WM9090_SPEAKER_VOLUME_LEFT, 6, 1, 1),
0206 SOC_SINGLE("Speaker ZC Switch", WM9090_SPEAKER_VOLUME_LEFT, 7, 1, 0),
0207 SOC_SINGLE_TLV("Speaker Boost Volume", WM9090_CLASSD3, 3, 7, 0, spkboost_tlv),
0208 };
0209
0210 static const struct snd_kcontrol_new wm9090_in1_se_controls[] = {
0211 SOC_SINGLE_TLV("IN1B Volume", WM9090_IN1_LINE_INPUT_B_VOLUME, 0, 6, 0,
0212 in_tlv),
0213 SOC_SINGLE("IN1B Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 7, 1, 1),
0214 SOC_SINGLE("IN1B ZC Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 6, 1, 0),
0215
0216 SOC_SINGLE_TLV("SPKMIX IN1B Volume", WM9090_SPKMIXL_ATTENUATION, 4, 3, 1,
0217 mix_tlv),
0218 SOC_SINGLE_TLV("MIXOUTL IN1B Volume", WM9090_OUTPUT_MIXER3, 4, 3, 1,
0219 mix_tlv),
0220 SOC_SINGLE_TLV("MIXOUTR IN1B Volume", WM9090_OUTPUT_MIXER4, 4, 3, 1,
0221 mix_tlv),
0222 };
0223
0224 static const struct snd_kcontrol_new wm9090_in2_se_controls[] = {
0225 SOC_SINGLE_TLV("IN2B Volume", WM9090_IN2_LINE_INPUT_B_VOLUME, 0, 6, 0,
0226 in_tlv),
0227 SOC_SINGLE("IN2B Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 7, 1, 1),
0228 SOC_SINGLE("IN2B ZC Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 6, 1, 0),
0229
0230 SOC_SINGLE_TLV("SPKMIX IN2B Volume", WM9090_SPKMIXL_ATTENUATION, 0, 3, 1,
0231 mix_tlv),
0232 SOC_SINGLE_TLV("MIXOUTL IN2B Volume", WM9090_OUTPUT_MIXER3, 0, 3, 1,
0233 mix_tlv),
0234 SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
0235 mix_tlv),
0236 };
0237
0238 static int hp_ev(struct snd_soc_dapm_widget *w,
0239 struct snd_kcontrol *kcontrol, int event)
0240 {
0241 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0242 unsigned int reg = snd_soc_component_read(component, WM9090_ANALOGUE_HP_0);
0243
0244 switch (event) {
0245 case SND_SOC_DAPM_POST_PMU:
0246 snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
0247 WM9090_CP_ENA, WM9090_CP_ENA);
0248
0249 msleep(5);
0250
0251 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
0252 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
0253 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
0254
0255 reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
0256 snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
0257
0258
0259
0260
0261
0262
0263
0264 snd_soc_component_write(component, WM9090_DC_SERVO_0,
0265 WM9090_DCS_ENA_CHAN_0 |
0266 WM9090_DCS_ENA_CHAN_1 |
0267 WM9090_DCS_TRIG_STARTUP_1 |
0268 WM9090_DCS_TRIG_STARTUP_0);
0269 wait_for_dc_servo(component);
0270
0271 reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
0272 WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
0273 snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
0274 break;
0275
0276 case SND_SOC_DAPM_PRE_PMD:
0277 reg &= ~(WM9090_HPOUT1L_RMV_SHORT |
0278 WM9090_HPOUT1L_DLY |
0279 WM9090_HPOUT1L_OUTP |
0280 WM9090_HPOUT1R_RMV_SHORT |
0281 WM9090_HPOUT1R_DLY |
0282 WM9090_HPOUT1R_OUTP);
0283
0284 snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
0285
0286 snd_soc_component_write(component, WM9090_DC_SERVO_0, 0);
0287
0288 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
0289 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
0290 0);
0291
0292 snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
0293 WM9090_CP_ENA, 0);
0294 break;
0295 }
0296
0297 return 0;
0298 }
0299
0300 static const struct snd_kcontrol_new spkmix[] = {
0301 SOC_DAPM_SINGLE("IN1A Switch", WM9090_SPEAKER_MIXER, 6, 1, 0),
0302 SOC_DAPM_SINGLE("IN1B Switch", WM9090_SPEAKER_MIXER, 4, 1, 0),
0303 SOC_DAPM_SINGLE("IN2A Switch", WM9090_SPEAKER_MIXER, 2, 1, 0),
0304 SOC_DAPM_SINGLE("IN2B Switch", WM9090_SPEAKER_MIXER, 0, 1, 0),
0305 };
0306
0307 static const struct snd_kcontrol_new spkout[] = {
0308 SOC_DAPM_SINGLE("Mixer Switch", WM9090_SPKOUT_MIXERS, 4, 1, 0),
0309 };
0310
0311 static const struct snd_kcontrol_new mixoutl[] = {
0312 SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER1, 6, 1, 0),
0313 SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER1, 4, 1, 0),
0314 SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER1, 2, 1, 0),
0315 SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER1, 0, 1, 0),
0316 };
0317
0318 static const struct snd_kcontrol_new mixoutr[] = {
0319 SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER2, 6, 1, 0),
0320 SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER2, 4, 1, 0),
0321 SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER2, 2, 1, 0),
0322 SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER2, 0, 1, 0),
0323 };
0324
0325 static const struct snd_soc_dapm_widget wm9090_dapm_widgets[] = {
0326 SND_SOC_DAPM_INPUT("IN1+"),
0327 SND_SOC_DAPM_INPUT("IN1-"),
0328 SND_SOC_DAPM_INPUT("IN2+"),
0329 SND_SOC_DAPM_INPUT("IN2-"),
0330
0331 SND_SOC_DAPM_SUPPLY("OSC", WM9090_POWER_MANAGEMENT_1, 3, 0, NULL, 0),
0332
0333 SND_SOC_DAPM_PGA("IN1A PGA", WM9090_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
0334 SND_SOC_DAPM_PGA("IN1B PGA", WM9090_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
0335 SND_SOC_DAPM_PGA("IN2A PGA", WM9090_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
0336 SND_SOC_DAPM_PGA("IN2B PGA", WM9090_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
0337
0338 SND_SOC_DAPM_MIXER("SPKMIX", WM9090_POWER_MANAGEMENT_3, 3, 0,
0339 spkmix, ARRAY_SIZE(spkmix)),
0340 SND_SOC_DAPM_MIXER("MIXOUTL", WM9090_POWER_MANAGEMENT_3, 5, 0,
0341 mixoutl, ARRAY_SIZE(mixoutl)),
0342 SND_SOC_DAPM_MIXER("MIXOUTR", WM9090_POWER_MANAGEMENT_3, 4, 0,
0343 mixoutr, ARRAY_SIZE(mixoutr)),
0344
0345 SND_SOC_DAPM_PGA_E("HP PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
0346 hp_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
0347
0348 SND_SOC_DAPM_PGA("SPKPGA", WM9090_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
0349 SND_SOC_DAPM_MIXER("SPKOUT", WM9090_POWER_MANAGEMENT_1, 12, 0,
0350 spkout, ARRAY_SIZE(spkout)),
0351
0352 SND_SOC_DAPM_OUTPUT("HPR"),
0353 SND_SOC_DAPM_OUTPUT("HPL"),
0354 SND_SOC_DAPM_OUTPUT("Speaker"),
0355 };
0356
0357 static const struct snd_soc_dapm_route audio_map[] = {
0358 { "IN1A PGA", NULL, "IN1+" },
0359 { "IN2A PGA", NULL, "IN2+" },
0360
0361 { "SPKMIX", "IN1A Switch", "IN1A PGA" },
0362 { "SPKMIX", "IN2A Switch", "IN2A PGA" },
0363
0364 { "MIXOUTL", "IN1A Switch", "IN1A PGA" },
0365 { "MIXOUTL", "IN2A Switch", "IN2A PGA" },
0366
0367 { "MIXOUTR", "IN1A Switch", "IN1A PGA" },
0368 { "MIXOUTR", "IN2A Switch", "IN2A PGA" },
0369
0370 { "HP PGA", NULL, "OSC" },
0371 { "HP PGA", NULL, "MIXOUTL" },
0372 { "HP PGA", NULL, "MIXOUTR" },
0373
0374 { "HPL", NULL, "HP PGA" },
0375 { "HPR", NULL, "HP PGA" },
0376
0377 { "SPKPGA", NULL, "OSC" },
0378 { "SPKPGA", NULL, "SPKMIX" },
0379
0380 { "SPKOUT", "Mixer Switch", "SPKPGA" },
0381
0382 { "Speaker", NULL, "SPKOUT" },
0383 };
0384
0385 static const struct snd_soc_dapm_route audio_map_in1_se[] = {
0386 { "IN1B PGA", NULL, "IN1-" },
0387
0388 { "SPKMIX", "IN1B Switch", "IN1B PGA" },
0389 { "MIXOUTL", "IN1B Switch", "IN1B PGA" },
0390 { "MIXOUTR", "IN1B Switch", "IN1B PGA" },
0391 };
0392
0393 static const struct snd_soc_dapm_route audio_map_in1_diff[] = {
0394 { "IN1A PGA", NULL, "IN1-" },
0395 };
0396
0397 static const struct snd_soc_dapm_route audio_map_in2_se[] = {
0398 { "IN2B PGA", NULL, "IN2-" },
0399
0400 { "SPKMIX", "IN2B Switch", "IN2B PGA" },
0401 { "MIXOUTL", "IN2B Switch", "IN2B PGA" },
0402 { "MIXOUTR", "IN2B Switch", "IN2B PGA" },
0403 };
0404
0405 static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
0406 { "IN2A PGA", NULL, "IN2-" },
0407 };
0408
0409 static int wm9090_add_controls(struct snd_soc_component *component)
0410 {
0411 struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
0412 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0413 int i;
0414
0415 snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
0416 ARRAY_SIZE(wm9090_dapm_widgets));
0417
0418 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
0419
0420 snd_soc_add_component_controls(component, wm9090_controls,
0421 ARRAY_SIZE(wm9090_controls));
0422
0423 if (wm9090->pdata.lin1_diff) {
0424 snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
0425 ARRAY_SIZE(audio_map_in1_diff));
0426 } else {
0427 snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
0428 ARRAY_SIZE(audio_map_in1_se));
0429 snd_soc_add_component_controls(component, wm9090_in1_se_controls,
0430 ARRAY_SIZE(wm9090_in1_se_controls));
0431 }
0432
0433 if (wm9090->pdata.lin2_diff) {
0434 snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
0435 ARRAY_SIZE(audio_map_in2_diff));
0436 } else {
0437 snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
0438 ARRAY_SIZE(audio_map_in2_se));
0439 snd_soc_add_component_controls(component, wm9090_in2_se_controls,
0440 ARRAY_SIZE(wm9090_in2_se_controls));
0441 }
0442
0443 if (wm9090->pdata.agc_ena) {
0444 for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
0445 snd_soc_component_write(component, WM9090_AGC_CONTROL_0 + i,
0446 wm9090->pdata.agc[i]);
0447 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
0448 WM9090_AGC_ENA, WM9090_AGC_ENA);
0449 } else {
0450 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
0451 WM9090_AGC_ENA, 0);
0452 }
0453
0454 return 0;
0455
0456 }
0457
0458
0459
0460
0461
0462 static int wm9090_set_bias_level(struct snd_soc_component *component,
0463 enum snd_soc_bias_level level)
0464 {
0465 struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
0466
0467 switch (level) {
0468 case SND_SOC_BIAS_ON:
0469 break;
0470
0471 case SND_SOC_BIAS_PREPARE:
0472 snd_soc_component_update_bits(component, WM9090_ANTIPOP2, WM9090_VMID_ENA,
0473 WM9090_VMID_ENA);
0474 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
0475 WM9090_BIAS_ENA |
0476 WM9090_VMID_RES_MASK,
0477 WM9090_BIAS_ENA |
0478 1 << WM9090_VMID_RES_SHIFT);
0479 msleep(1);
0480 break;
0481
0482 case SND_SOC_BIAS_STANDBY:
0483 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0484
0485 regcache_sync(wm9090->regmap);
0486 }
0487
0488
0489
0490
0491
0492 snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
0493 WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
0494 snd_soc_component_update_bits(component, WM9090_ANTIPOP2,
0495 WM9090_VMID_ENA, 0);
0496 break;
0497
0498 case SND_SOC_BIAS_OFF:
0499 break;
0500 }
0501
0502 return 0;
0503 }
0504
0505 static int wm9090_probe(struct snd_soc_component *component)
0506 {
0507
0508
0509
0510 snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_A_VOLUME,
0511 WM9090_IN1_VU | WM9090_IN1A_ZC,
0512 WM9090_IN1_VU | WM9090_IN1A_ZC);
0513 snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_B_VOLUME,
0514 WM9090_IN1_VU | WM9090_IN1B_ZC,
0515 WM9090_IN1_VU | WM9090_IN1B_ZC);
0516 snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_A_VOLUME,
0517 WM9090_IN2_VU | WM9090_IN2A_ZC,
0518 WM9090_IN2_VU | WM9090_IN2A_ZC);
0519 snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_B_VOLUME,
0520 WM9090_IN2_VU | WM9090_IN2B_ZC,
0521 WM9090_IN2_VU | WM9090_IN2B_ZC);
0522 snd_soc_component_update_bits(component, WM9090_SPEAKER_VOLUME_LEFT,
0523 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
0524 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
0525 snd_soc_component_update_bits(component, WM9090_LEFT_OUTPUT_VOLUME,
0526 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
0527 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
0528 snd_soc_component_update_bits(component, WM9090_RIGHT_OUTPUT_VOLUME,
0529 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
0530 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
0531
0532 snd_soc_component_update_bits(component, WM9090_CLOCKING_1,
0533 WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
0534
0535 wm9090_add_controls(component);
0536
0537 return 0;
0538 }
0539
0540 static const struct snd_soc_component_driver soc_component_dev_wm9090 = {
0541 .probe = wm9090_probe,
0542 .set_bias_level = wm9090_set_bias_level,
0543 .suspend_bias_off = 1,
0544 .idle_bias_on = 1,
0545 .use_pmdown_time = 1,
0546 };
0547
0548 static const struct regmap_config wm9090_regmap = {
0549 .reg_bits = 8,
0550 .val_bits = 16,
0551
0552 .max_register = WM9090_MAX_REGISTER,
0553 .volatile_reg = wm9090_volatile,
0554 .readable_reg = wm9090_readable,
0555
0556 .cache_type = REGCACHE_RBTREE,
0557 .reg_defaults = wm9090_reg_defaults,
0558 .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults),
0559 };
0560
0561
0562 static int wm9090_i2c_probe(struct i2c_client *i2c)
0563 {
0564 struct wm9090_priv *wm9090;
0565 unsigned int reg;
0566 int ret;
0567
0568 wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
0569 if (!wm9090)
0570 return -ENOMEM;
0571
0572 wm9090->regmap = devm_regmap_init_i2c(i2c, &wm9090_regmap);
0573 if (IS_ERR(wm9090->regmap)) {
0574 ret = PTR_ERR(wm9090->regmap);
0575 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
0576 return ret;
0577 }
0578
0579 ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®);
0580 if (ret < 0)
0581 return ret;
0582
0583 if (reg != 0x9093) {
0584 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
0585 return -ENODEV;
0586 }
0587
0588 ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
0589 if (ret < 0)
0590 return ret;
0591
0592 if (i2c->dev.platform_data)
0593 memcpy(&wm9090->pdata, i2c->dev.platform_data,
0594 sizeof(wm9090->pdata));
0595
0596 i2c_set_clientdata(i2c, wm9090);
0597
0598 ret = devm_snd_soc_register_component(&i2c->dev,
0599 &soc_component_dev_wm9090, NULL, 0);
0600 if (ret != 0) {
0601 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
0602 return ret;
0603 }
0604
0605 return 0;
0606 }
0607
0608 static const struct i2c_device_id wm9090_id[] = {
0609 { "wm9090", 0 },
0610 { "wm9093", 0 },
0611 { }
0612 };
0613 MODULE_DEVICE_TABLE(i2c, wm9090_id);
0614
0615 static struct i2c_driver wm9090_i2c_driver = {
0616 .driver = {
0617 .name = "wm9090",
0618 },
0619 .probe_new = wm9090_i2c_probe,
0620 .id_table = wm9090_id,
0621 };
0622
0623 module_i2c_driver(wm9090_i2c_driver);
0624
0625 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0626 MODULE_DESCRIPTION("WM9090 ASoC driver");
0627 MODULE_LICENSE("GPL");