13 #include <linux/module.h>
16 #include <linux/slab.h>
33 #define WM8350_OUTn_0dB 0x39
35 #define WM8350_RAMP_NONE 0
36 #define WM8350_RAMP_UP 1
37 #define WM8350_RAMP_DOWN 2
42 static const char *supply_names[] = {
82 int left_complete = 0, right_complete = 0;
91 if (val < out1->left_vol) {
115 if (val < out1->right_vol) {
134 if (!left_complete || !right_complete)
137 return left_complete & right_complete;
143 static inline int wm8350_out2_ramp_step(
struct snd_soc_codec *codec)
145 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
147 struct wm8350 *wm8350 = wm8350_data->
wm8350;
148 int left_complete = 0, right_complete = 0;
156 if (val < out2->left_vol) {
180 if (val < out2->right_vol) {
199 if (!left_complete || !right_complete)
202 return left_complete & right_complete;
216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
218 *out2 = &wm8350_data->
out2;
219 int i, out1_complete, out2_complete;
226 for (i = 0; i <= 63; i++) {
227 out1_complete = 1, out2_complete = 1;
229 out1_complete = wm8350_out1_ramp_step(codec);
231 out2_complete = wm8350_out2_ramp_step(codec);
234 if (out1_complete && out2_complete)
263 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
269 out = &wm8350_data->
out1;
273 out = &wm8350_data->
out2;
304 static int wm8350_put_volsw_2r_vu(
struct snd_kcontrol *kcontrol,
308 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
313 unsigned int reg = mc->
reg;
321 out = &wm8350_priv->
out1;
324 out = &wm8350_priv->
out2;
347 static int wm8350_get_volsw_2r(
struct snd_kcontrol *kcontrol,
351 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
356 unsigned int reg = mc->
reg;
377 static const char *wm8350_deemp[] = {
"None",
"32kHz",
"44.1kHz",
"48kHz" };
378 static const char *wm8350_pol[] = {
"Normal",
"Inv R",
"Inv L",
"Inv L & R" };
379 static const char *wm8350_dacmutem[] = {
"Normal",
"Soft" };
380 static const char *wm8350_dacmutes[] = {
"Fast",
"Slow" };
381 static const char *wm8350_adcfilter[] = {
"None",
"High Pass" };
382 static const char *wm8350_adchp[] = {
"44.1kHz",
"8kHz",
"16kHz",
"32kHz" };
383 static const char *wm8350_lr[] = {
"Left",
"Right" };
385 static const struct soc_enum wm8350_enum[] = {
402 static const unsigned int capture_sd_tlv[] = {
409 SOC_ENUM(
"Playback Deemphasis", wm8350_enum[0]),
410 SOC_ENUM(
"Playback DAC Inversion", wm8350_enum[1]),
414 0, 255, 0, wm8350_get_volsw_2r,
415 wm8350_put_volsw_2r_vu, dac_pcm_tlv),
416 SOC_ENUM(
"Playback PCM Mute Function", wm8350_enum[2]),
417 SOC_ENUM(
"Playback PCM Mute Speed", wm8350_enum[3]),
418 SOC_ENUM(
"Capture PCM Filter", wm8350_enum[4]),
419 SOC_ENUM(
"Capture PCM HP Filter", wm8350_enum[5]),
420 SOC_ENUM(
"Capture ADC Inversion", wm8350_enum[6]),
424 0, 255, 0, wm8350_get_volsw_2r,
425 wm8350_put_volsw_2r_vu, adc_pcm_tlv),
428 8, 4, 15, 1, capture_sd_tlv),
432 2, 63, 0, wm8350_get_volsw_2r,
433 wm8350_put_volsw_2r_vu, pre_amp_tlv),
441 5, 7, 0, out_mix_tlv),
444 9, 7, 0, out_mix_tlv),
447 1, 7, 0, out_mix_tlv),
450 5, 7, 0, out_mix_tlv),
453 13, 7, 0, out_mix_tlv),
460 1, 7, 0, out_mix_tlv),
464 2, 63, 0, wm8350_get_volsw_2r,
465 wm8350_put_volsw_2r_vu, out_pga_tlv),
472 2, 63, 0, wm8350_get_volsw_2r,
473 wm8350_put_volsw_2r_vu, out_pga_tlv),
478 5, 7, 0, out_mix_tlv),
610 7, 0, &wm8350_right_capt_mixer_controls[0],
611 ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
614 6, 0, &wm8350_left_capt_mixer_controls[0],
618 &wm8350_out4_mixer_controls[0],
622 &wm8350_out3_mixer_controls[0],
626 &wm8350_right_play_mixer_controls[0],
627 ARRAY_SIZE(wm8350_right_play_mixer_controls)),
630 &wm8350_left_play_mixer_controls[0],
634 &wm8350_left_mic_mixer_controls[0],
638 &wm8350_right_mic_mixer_controls[0],
645 &wm8350_beep_switch_controls),
659 &wm8350_out4_capture_controls),
681 {
"Left Playback Mixer",
"Playback Switch",
"Left DAC"},
682 {
"Left Playback Mixer",
"Left Bypass Switch",
"IN3L PGA"},
683 {
"Left Playback Mixer",
"Right Playback Switch",
"Right DAC"},
684 {
"Left Playback Mixer",
"Left Sidetone Switch",
"Left Mic Mixer"},
685 {
"Left Playback Mixer",
"Right Sidetone Switch",
"Right Mic Mixer"},
688 {
"Right Playback Mixer",
"Playback Switch",
"Right DAC"},
689 {
"Right Playback Mixer",
"Right Bypass Switch",
"IN3R PGA"},
690 {
"Right Playback Mixer",
"Left Playback Switch",
"Left DAC"},
691 {
"Right Playback Mixer",
"Left Sidetone Switch",
"Left Mic Mixer"},
692 {
"Right Playback Mixer",
"Right Sidetone Switch",
"Right Mic Mixer"},
695 {
"Out4 Mixer",
"Right Playback Switch",
"Right DAC"},
696 {
"Out4 Mixer",
"Left Playback Switch",
"Left DAC"},
697 {
"Out4 Mixer",
"Right Capture Switch",
"Right Capture Mixer"},
698 {
"Out4 Mixer",
"Out3 Playback Switch",
"Out3 Mixer"},
699 {
"Out4 Mixer",
"Right Mixer Switch",
"Right Playback Mixer"},
700 {
"Out4 Mixer",
"Left Mixer Switch",
"Left Playback Mixer"},
701 {
"OUT4",
NULL,
"Out4 Mixer"},
704 {
"Out3 Mixer",
"Left Playback Switch",
"Left DAC"},
705 {
"Out3 Mixer",
"Left Capture Switch",
"Left Capture Mixer"},
706 {
"Out3 Mixer",
"Left Mixer Switch",
"Left Playback Mixer"},
707 {
"Out3 Mixer",
"Out4 Playback Switch",
"Out4 Mixer"},
708 {
"OUT3",
NULL,
"Out3 Mixer"},
711 {
"Right Out2 PGA",
NULL,
"Right Playback Mixer"},
712 {
"Left Out2 PGA",
NULL,
"Left Playback Mixer"},
713 {
"OUT2L",
NULL,
"Left Out2 PGA"},
714 {
"OUT2R",
NULL,
"Right Out2 PGA"},
717 {
"Right Out1 PGA",
NULL,
"Right Playback Mixer"},
718 {
"Left Out1 PGA",
NULL,
"Left Playback Mixer"},
719 {
"OUT1L",
NULL,
"Left Out1 PGA"},
720 {
"OUT1R",
NULL,
"Right Out1 PGA"},
723 {
"Left ADC",
NULL,
"Left Capture Mixer"},
724 {
"Right ADC",
NULL,
"Right Capture Mixer"},
727 {
"Left Capture Mixer",
"L2 Capture Volume",
"IN2L"},
728 {
"Left Capture Mixer",
"L3 Capture Volume",
"IN3L PGA"},
729 {
"Left Capture Mixer",
"PGA Capture Switch",
"Left Mic Mixer"},
730 {
"Left Capture Mixer",
NULL,
"Out4 Capture Channel"},
733 {
"Right Capture Mixer",
"L2 Capture Volume",
"IN2R"},
734 {
"Right Capture Mixer",
"L3 Capture Volume",
"IN3R PGA"},
735 {
"Right Capture Mixer",
"PGA Capture Switch",
"Right Mic Mixer"},
736 {
"Right Capture Mixer",
NULL,
"Out4 Capture Channel"},
739 {
"IN3L PGA",
NULL,
"IN3L"},
740 {
"IN3R PGA",
NULL,
"IN3R"},
743 {
"Left Mic Mixer",
"INN Capture Switch",
"IN1LN"},
744 {
"Left Mic Mixer",
"INP Capture Switch",
"IN1LP"},
745 {
"Left Mic Mixer",
"IN2 Capture Switch",
"IN2L"},
748 {
"Right Mic Mixer",
"INN Capture Switch",
"IN1RN"},
749 {
"Right Mic Mixer",
"INP Capture Switch",
"IN1RP"},
750 {
"Right Mic Mixer",
"IN2 Capture Switch",
"IN2R"},
753 {
"Out4 Capture Channel",
NULL,
"Out4 Mixer"},
756 {
"Beep",
NULL,
"IN3R PGA"},
759 static int wm8350_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
760 int clk_id,
unsigned int freq,
int dir)
763 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
764 struct wm8350 *wm8350 = wm8350_data->
wm8350;
795 static int wm8350_set_clkdiv(
struct snd_soc_dai *codec_dai,
int div_id,
int div)
843 static int wm8350_set_dai_fmt(
struct snd_soc_dai *codec_dai,
unsigned int fmt)
917 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
918 struct wm8350 *wm8350 = wm8350_data->
wm8350;
979 #define FIXED_FLL_SIZE ((1 << 16) * 10)
985 unsigned int t1,
t2,
K, Nmod;
987 if (output >= 2815250 && output <= 3125000)
989 else if (output >= 5625000 && output <= 6250000)
991 else if (output >= 11250000 && output <= 12500000)
993 else if (output >= 22500000 && output <= 25000000)
1005 t1 = output * (1 << (fll_div->
div + 1));
1006 t2 = input * fll_div->
ratio;
1008 fll_div->
n = t1 /
t2;
1014 K = Kpart & 0xFFFFFFFF;
1029 static int wm8350_set_fll(
struct snd_soc_dai *codec_dai,
1030 int pll_id,
int source,
unsigned int freq_in,
1031 unsigned int freq_out)
1034 struct wm8350_data *
priv = snd_soc_codec_get_drvdata(codec);
1035 struct wm8350 *wm8350 = priv->
wm8350;
1047 if (freq_out == 0 || freq_in == 0)
1054 "FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
1062 fll_1 | (
fll_div.div << 8) | 0x50);
1083 static int wm8350_set_bias_level(
struct snd_soc_codec *codec,
1086 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1087 struct wm8350 *wm8350 = priv->
wm8350;
1089 wm8350->
codec.platform_data;
1260 static void wm8350_hp_work(
struct wm8350_data *priv,
1264 struct wm8350 *wm8350 = priv->
wm8350;
1278 static void wm8350_hpl_work(
struct work_struct *work)
1280 struct wm8350_data *priv =
1286 static void wm8350_hpr_work(
struct work_struct *work)
1288 struct wm8350_data *priv =
1296 struct wm8350_data *priv =
data;
1297 struct wm8350 *wm8350 = priv->
wm8350;
1299 #ifndef CONFIG_SND_SOC_WM8350_MODULE
1300 trace_snd_soc_jack_irq(
"WM8350 HPL");
1303 if (device_may_wakeup(wm8350->
dev))
1311 static irqreturn_t wm8350_hpr_jack_handler(
int irq,
void *data)
1313 struct wm8350_data *priv =
data;
1314 struct wm8350 *wm8350 = priv->
wm8350;
1316 #ifndef CONFIG_SND_SOC_WM8350_MODULE
1317 trace_snd_soc_jack_irq(
"WM8350 HPR");
1320 if (device_may_wakeup(wm8350->
dev))
1342 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1343 struct wm8350 *wm8350 = priv->
wm8350;
1349 priv->
hpl.jack = jack;
1356 priv->
hpr.jack = jack;
1376 wm8350_hpl_jack_handler(0, priv);
1379 wm8350_hpr_jack_handler(0, priv);
1387 static irqreturn_t wm8350_mic_handler(
int irq,
void *data)
1389 struct wm8350_data *priv =
data;
1390 struct wm8350 *wm8350 = priv->
wm8350;
1394 #ifndef CONFIG_SND_SOC_WM8350_MODULE
1395 trace_snd_soc_jack_irq(
"WM8350 mic");
1400 report |= priv->
mic.short_report;
1402 report |= priv->
mic.report;
1405 priv->
mic.report | priv->
mic.short_report);
1423 int detect_report,
int short_report)
1425 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1426 struct wm8350 *wm8350 = priv->
wm8350;
1428 priv->
mic.jack = jack;
1429 priv->
mic.report = detect_report;
1430 priv->
mic.short_report = short_report;
1432 if (detect_report || short_report) {
1445 #define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1447 #define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1448 SNDRV_PCM_FMTBIT_S20_3LE |\
1449 SNDRV_PCM_FMTBIT_S24_LE)
1452 .hw_params = wm8350_pcm_hw_params,
1453 .digital_mute = wm8350_mute,
1454 .set_fmt = wm8350_set_dai_fmt,
1455 .set_sysclk = wm8350_set_dai_sysclk,
1456 .set_pll = wm8350_set_fll,
1457 .set_clkdiv = wm8350_set_clkdiv,
1461 .name =
"wm8350-hifi",
1463 .stream_name =
"Playback",
1470 .stream_name =
"Capture",
1476 .ops = &wm8350_dai_ops,
1481 struct wm8350 *wm8350 = dev_get_platdata(codec->
dev);
1482 struct wm8350_data *
priv;
1487 if (wm8350->
codec.platform_data ==
NULL) {
1488 dev_err(codec->
dev,
"No audio platform data supplied\n");
1496 snd_soc_codec_set_drvdata(codec, priv);
1500 for (i = 0; i <
ARRAY_SIZE(supply_names); i++)
1501 priv->
supplies[i].supply = supply_names[i];
1565 wm8350_hpl_jack_handler, 0,
"Left jack detect",
1568 wm8350_hpr_jack_handler, 0,
"Right jack detect",
1571 wm8350_mic_handler, 0,
"Microphone short", priv);
1573 wm8350_mic_handler, 0,
"Microphone detect", priv);
1583 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1584 struct wm8350 *wm8350 = dev_get_platdata(codec->
dev);
1616 .probe = wm8350_codec_probe,
1617 .remove = wm8350_codec_remove,
1618 .suspend = wm8350_suspend,
1619 .resume = wm8350_resume,
1620 .set_bias_level = wm8350_set_bias_level,
1622 .controls = wm8350_snd_controls,
1623 .num_controls =
ARRAY_SIZE(wm8350_snd_controls),
1624 .dapm_widgets = wm8350_dapm_widgets,
1625 .num_dapm_widgets =
ARRAY_SIZE(wm8350_dapm_widgets),
1626 .dapm_routes = wm8350_dapm_routes,
1627 .num_dapm_routes =
ARRAY_SIZE(wm8350_dapm_routes),
1644 .name =
"wm8350-codec",
1647 .probe = wm8350_probe,