0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/regmap.h>
0011 #include <linux/reset.h>
0012 #include <sound/pcm.h>
0013 #include <sound/soc.h>
0014
0015 #define DRV_NAME "evea"
0016 #define EVEA_RATES SNDRV_PCM_RATE_48000
0017 #define EVEA_FORMATS SNDRV_PCM_FMTBIT_S32_LE
0018
0019 #define AADCPOW(n) (0x0078 + 0x04 * (n))
0020 #define AADCPOW_AADC_POWD BIT(0)
0021 #define ALINSW1 0x0088
0022 #define ALINSW1_SEL1_SHIFT 3
0023 #define AHPOUTPOW 0x0098
0024 #define AHPOUTPOW_HP_ON BIT(4)
0025 #define ALINEPOW 0x009c
0026 #define ALINEPOW_LIN2_POWD BIT(3)
0027 #define ALINEPOW_LIN1_POWD BIT(4)
0028 #define ALO1OUTPOW 0x00a8
0029 #define ALO1OUTPOW_LO1_ON BIT(4)
0030 #define ALO2OUTPOW 0x00ac
0031 #define ALO2OUTPOW_ADAC2_MUTE BIT(0)
0032 #define ALO2OUTPOW_LO2_ON BIT(4)
0033 #define AANAPOW 0x00b8
0034 #define AANAPOW_A_POWD BIT(4)
0035 #define ADACSEQ1(n) (0x0144 + 0x40 * (n))
0036 #define ADACSEQ1_MMUTE BIT(1)
0037 #define ADACSEQ2(n) (0x0160 + 0x40 * (n))
0038 #define ADACSEQ2_ADACIN_FIX BIT(0)
0039 #define ADAC1ODC 0x0200
0040 #define ADAC1ODC_HP_DIS_RES_MASK GENMASK(2, 1)
0041 #define ADAC1ODC_HP_DIS_RES_OFF (0x0 << 1)
0042 #define ADAC1ODC_HP_DIS_RES_ON (0x3 << 1)
0043 #define ADAC1ODC_ADAC_RAMPCLT_MASK GENMASK(8, 7)
0044 #define ADAC1ODC_ADAC_RAMPCLT_NORMAL (0x0 << 7)
0045 #define ADAC1ODC_ADAC_RAMPCLT_REDUCE (0x1 << 7)
0046
0047 struct evea_priv {
0048 struct clk *clk, *clk_exiv;
0049 struct reset_control *rst, *rst_exiv, *rst_adamv;
0050 struct regmap *regmap;
0051
0052 int switch_lin;
0053 int switch_lo;
0054 int switch_hp;
0055 };
0056
0057 static const char * const linsw1_sel1_text[] = {
0058 "LIN1", "LIN2", "LIN3"
0059 };
0060
0061 static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
0062 ALINSW1, ALINSW1_SEL1_SHIFT,
0063 linsw1_sel1_text);
0064
0065 static const struct snd_kcontrol_new linesw1_mux[] = {
0066 SOC_DAPM_ENUM("Line In 1 Source", linsw1_sel1_enum),
0067 };
0068
0069 static const struct snd_soc_dapm_widget evea_widgets[] = {
0070 SND_SOC_DAPM_ADC("ADC", NULL, SND_SOC_NOPM, 0, 0),
0071 SND_SOC_DAPM_MUX("Line In 1 Mux", SND_SOC_NOPM, 0, 0, linesw1_mux),
0072 SND_SOC_DAPM_INPUT("LIN1_LP"),
0073 SND_SOC_DAPM_INPUT("LIN1_RP"),
0074 SND_SOC_DAPM_INPUT("LIN2_LP"),
0075 SND_SOC_DAPM_INPUT("LIN2_RP"),
0076 SND_SOC_DAPM_INPUT("LIN3_LP"),
0077 SND_SOC_DAPM_INPUT("LIN3_RP"),
0078
0079 SND_SOC_DAPM_DAC("DAC HP", NULL, SND_SOC_NOPM, 0, 0),
0080 SND_SOC_DAPM_DAC("DAC LO1", NULL, SND_SOC_NOPM, 0, 0),
0081 SND_SOC_DAPM_DAC("DAC LO2", NULL, SND_SOC_NOPM, 0, 0),
0082 SND_SOC_DAPM_OUTPUT("HP1_L"),
0083 SND_SOC_DAPM_OUTPUT("HP1_R"),
0084 SND_SOC_DAPM_OUTPUT("LO2_L"),
0085 SND_SOC_DAPM_OUTPUT("LO2_R"),
0086 };
0087
0088 static const struct snd_soc_dapm_route evea_routes[] = {
0089 { "Line In 1", NULL, "ADC" },
0090 { "ADC", NULL, "Line In 1 Mux" },
0091 { "Line In 1 Mux", "LIN1", "LIN1_LP" },
0092 { "Line In 1 Mux", "LIN1", "LIN1_RP" },
0093 { "Line In 1 Mux", "LIN2", "LIN2_LP" },
0094 { "Line In 1 Mux", "LIN2", "LIN2_RP" },
0095 { "Line In 1 Mux", "LIN3", "LIN3_LP" },
0096 { "Line In 1 Mux", "LIN3", "LIN3_RP" },
0097
0098 { "DAC HP", NULL, "Headphone 1" },
0099 { "DAC LO1", NULL, "Line Out 1" },
0100 { "DAC LO2", NULL, "Line Out 2" },
0101 { "HP1_L", NULL, "DAC HP" },
0102 { "HP1_R", NULL, "DAC HP" },
0103 { "LO2_L", NULL, "DAC LO2" },
0104 { "LO2_R", NULL, "DAC LO2" },
0105 };
0106
0107 static void evea_set_power_state_on(struct evea_priv *evea)
0108 {
0109 struct regmap *map = evea->regmap;
0110
0111 regmap_update_bits(map, AANAPOW, AANAPOW_A_POWD,
0112 AANAPOW_A_POWD);
0113
0114 regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
0115 ADAC1ODC_HP_DIS_RES_ON);
0116
0117 regmap_update_bits(map, ADAC1ODC, ADAC1ODC_ADAC_RAMPCLT_MASK,
0118 ADAC1ODC_ADAC_RAMPCLT_REDUCE);
0119
0120 regmap_update_bits(map, ADACSEQ2(0), ADACSEQ2_ADACIN_FIX, 0);
0121 regmap_update_bits(map, ADACSEQ2(1), ADACSEQ2_ADACIN_FIX, 0);
0122 regmap_update_bits(map, ADACSEQ2(2), ADACSEQ2_ADACIN_FIX, 0);
0123 }
0124
0125 static void evea_set_power_state_off(struct evea_priv *evea)
0126 {
0127 struct regmap *map = evea->regmap;
0128
0129 regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
0130 ADAC1ODC_HP_DIS_RES_ON);
0131
0132 regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
0133 ADACSEQ1_MMUTE);
0134 regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
0135 ADACSEQ1_MMUTE);
0136 regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
0137 ADACSEQ1_MMUTE);
0138
0139 regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
0140 regmap_update_bits(map, ALO2OUTPOW, ALO2OUTPOW_LO2_ON, 0);
0141 regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
0142 }
0143
0144 static int evea_update_switch_lin(struct evea_priv *evea)
0145 {
0146 struct regmap *map = evea->regmap;
0147
0148 if (evea->switch_lin) {
0149 regmap_update_bits(map, ALINEPOW,
0150 ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD,
0151 ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD);
0152
0153 regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD,
0154 AADCPOW_AADC_POWD);
0155 regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD,
0156 AADCPOW_AADC_POWD);
0157 } else {
0158 regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD, 0);
0159 regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD, 0);
0160
0161 regmap_update_bits(map, ALINEPOW,
0162 ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD, 0);
0163 }
0164
0165 return 0;
0166 }
0167
0168 static int evea_update_switch_lo(struct evea_priv *evea)
0169 {
0170 struct regmap *map = evea->regmap;
0171
0172 if (evea->switch_lo) {
0173 regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, 0);
0174 regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, 0);
0175
0176 regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON,
0177 ALO1OUTPOW_LO1_ON);
0178 regmap_update_bits(map, ALO2OUTPOW,
0179 ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
0180 ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON);
0181 } else {
0182 regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE,
0183 ADACSEQ1_MMUTE);
0184 regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE,
0185 ADACSEQ1_MMUTE);
0186
0187 regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0);
0188 regmap_update_bits(map, ALO2OUTPOW,
0189 ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON,
0190 0);
0191 }
0192
0193 return 0;
0194 }
0195
0196 static int evea_update_switch_hp(struct evea_priv *evea)
0197 {
0198 struct regmap *map = evea->regmap;
0199
0200 if (evea->switch_hp) {
0201 regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, 0);
0202
0203 regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON,
0204 AHPOUTPOW_HP_ON);
0205
0206 regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
0207 ADAC1ODC_HP_DIS_RES_OFF);
0208 } else {
0209 regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK,
0210 ADAC1ODC_HP_DIS_RES_ON);
0211
0212 regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE,
0213 ADACSEQ1_MMUTE);
0214
0215 regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0);
0216 }
0217
0218 return 0;
0219 }
0220
0221 static void evea_update_switch_all(struct evea_priv *evea)
0222 {
0223 evea_update_switch_lin(evea);
0224 evea_update_switch_lo(evea);
0225 evea_update_switch_hp(evea);
0226 }
0227
0228 static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
0229 struct snd_ctl_elem_value *ucontrol)
0230 {
0231 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0232 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0233
0234 ucontrol->value.integer.value[0] = evea->switch_lin;
0235
0236 return 0;
0237 }
0238
0239 static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
0240 struct snd_ctl_elem_value *ucontrol)
0241 {
0242 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0243 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0244
0245 if (evea->switch_lin == ucontrol->value.integer.value[0])
0246 return 0;
0247
0248 evea->switch_lin = ucontrol->value.integer.value[0];
0249
0250 return evea_update_switch_lin(evea);
0251 }
0252
0253 static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
0254 struct snd_ctl_elem_value *ucontrol)
0255 {
0256 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0257 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0258
0259 ucontrol->value.integer.value[0] = evea->switch_lo;
0260
0261 return 0;
0262 }
0263
0264 static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
0265 struct snd_ctl_elem_value *ucontrol)
0266 {
0267 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0268 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0269
0270 if (evea->switch_lo == ucontrol->value.integer.value[0])
0271 return 0;
0272
0273 evea->switch_lo = ucontrol->value.integer.value[0];
0274
0275 return evea_update_switch_lo(evea);
0276 }
0277
0278 static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
0279 struct snd_ctl_elem_value *ucontrol)
0280 {
0281 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0282 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0283
0284 ucontrol->value.integer.value[0] = evea->switch_hp;
0285
0286 return 0;
0287 }
0288
0289 static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
0290 struct snd_ctl_elem_value *ucontrol)
0291 {
0292 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0293 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0294
0295 if (evea->switch_hp == ucontrol->value.integer.value[0])
0296 return 0;
0297
0298 evea->switch_hp = ucontrol->value.integer.value[0];
0299
0300 return evea_update_switch_hp(evea);
0301 }
0302
0303 static const struct snd_kcontrol_new evea_controls[] = {
0304 SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
0305 evea_get_switch_lin, evea_set_switch_lin),
0306 SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
0307 evea_get_switch_lo, evea_set_switch_lo),
0308 SOC_SINGLE_BOOL_EXT("Headphone Playback Switch", 0,
0309 evea_get_switch_hp, evea_set_switch_hp),
0310 };
0311
0312 static int evea_codec_probe(struct snd_soc_component *component)
0313 {
0314 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0315
0316 evea->switch_lin = 1;
0317 evea->switch_lo = 1;
0318 evea->switch_hp = 1;
0319
0320 evea_set_power_state_on(evea);
0321 evea_update_switch_all(evea);
0322
0323 return 0;
0324 }
0325
0326 static int evea_codec_suspend(struct snd_soc_component *component)
0327 {
0328 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0329
0330 evea_set_power_state_off(evea);
0331
0332 reset_control_assert(evea->rst_adamv);
0333 reset_control_assert(evea->rst_exiv);
0334 reset_control_assert(evea->rst);
0335
0336 clk_disable_unprepare(evea->clk_exiv);
0337 clk_disable_unprepare(evea->clk);
0338
0339 return 0;
0340 }
0341
0342 static int evea_codec_resume(struct snd_soc_component *component)
0343 {
0344 struct evea_priv *evea = snd_soc_component_get_drvdata(component);
0345 int ret;
0346
0347 ret = clk_prepare_enable(evea->clk);
0348 if (ret)
0349 return ret;
0350
0351 ret = clk_prepare_enable(evea->clk_exiv);
0352 if (ret)
0353 goto err_out_clock;
0354
0355 ret = reset_control_deassert(evea->rst);
0356 if (ret)
0357 goto err_out_clock_exiv;
0358
0359 ret = reset_control_deassert(evea->rst_exiv);
0360 if (ret)
0361 goto err_out_reset;
0362
0363 ret = reset_control_deassert(evea->rst_adamv);
0364 if (ret)
0365 goto err_out_reset_exiv;
0366
0367 evea_set_power_state_on(evea);
0368 evea_update_switch_all(evea);
0369
0370 return 0;
0371
0372 err_out_reset_exiv:
0373 reset_control_assert(evea->rst_exiv);
0374
0375 err_out_reset:
0376 reset_control_assert(evea->rst);
0377
0378 err_out_clock_exiv:
0379 clk_disable_unprepare(evea->clk_exiv);
0380
0381 err_out_clock:
0382 clk_disable_unprepare(evea->clk);
0383
0384 return ret;
0385 }
0386
0387 static struct snd_soc_component_driver soc_codec_evea = {
0388 .probe = evea_codec_probe,
0389 .suspend = evea_codec_suspend,
0390 .resume = evea_codec_resume,
0391 .dapm_widgets = evea_widgets,
0392 .num_dapm_widgets = ARRAY_SIZE(evea_widgets),
0393 .dapm_routes = evea_routes,
0394 .num_dapm_routes = ARRAY_SIZE(evea_routes),
0395 .controls = evea_controls,
0396 .num_controls = ARRAY_SIZE(evea_controls),
0397 .idle_bias_on = 1,
0398 .use_pmdown_time = 1,
0399 .endianness = 1,
0400 };
0401
0402 static struct snd_soc_dai_driver soc_dai_evea[] = {
0403 {
0404 .name = DRV_NAME "-line1",
0405 .playback = {
0406 .stream_name = "Line Out 1",
0407 .formats = EVEA_FORMATS,
0408 .rates = EVEA_RATES,
0409 .channels_min = 2,
0410 .channels_max = 2,
0411 },
0412 .capture = {
0413 .stream_name = "Line In 1",
0414 .formats = EVEA_FORMATS,
0415 .rates = EVEA_RATES,
0416 .channels_min = 2,
0417 .channels_max = 2,
0418 },
0419 },
0420 {
0421 .name = DRV_NAME "-hp1",
0422 .playback = {
0423 .stream_name = "Headphone 1",
0424 .formats = EVEA_FORMATS,
0425 .rates = EVEA_RATES,
0426 .channels_min = 2,
0427 .channels_max = 2,
0428 },
0429 },
0430 {
0431 .name = DRV_NAME "-lo2",
0432 .playback = {
0433 .stream_name = "Line Out 2",
0434 .formats = EVEA_FORMATS,
0435 .rates = EVEA_RATES,
0436 .channels_min = 2,
0437 .channels_max = 2,
0438 },
0439 },
0440 };
0441
0442 static const struct regmap_config evea_regmap_config = {
0443 .reg_bits = 32,
0444 .reg_stride = 4,
0445 .val_bits = 32,
0446 .max_register = 0xffc,
0447 .cache_type = REGCACHE_NONE,
0448 };
0449
0450 static int evea_probe(struct platform_device *pdev)
0451 {
0452 struct evea_priv *evea;
0453 void __iomem *preg;
0454 int ret;
0455
0456 evea = devm_kzalloc(&pdev->dev, sizeof(struct evea_priv), GFP_KERNEL);
0457 if (!evea)
0458 return -ENOMEM;
0459
0460 evea->clk = devm_clk_get(&pdev->dev, "evea");
0461 if (IS_ERR(evea->clk))
0462 return PTR_ERR(evea->clk);
0463
0464 evea->clk_exiv = devm_clk_get(&pdev->dev, "exiv");
0465 if (IS_ERR(evea->clk_exiv))
0466 return PTR_ERR(evea->clk_exiv);
0467
0468 evea->rst = devm_reset_control_get_shared(&pdev->dev, "evea");
0469 if (IS_ERR(evea->rst))
0470 return PTR_ERR(evea->rst);
0471
0472 evea->rst_exiv = devm_reset_control_get_shared(&pdev->dev, "exiv");
0473 if (IS_ERR(evea->rst_exiv))
0474 return PTR_ERR(evea->rst_exiv);
0475
0476 preg = devm_platform_ioremap_resource(pdev, 0);
0477 if (IS_ERR(preg))
0478 return PTR_ERR(preg);
0479
0480 evea->regmap = devm_regmap_init_mmio(&pdev->dev, preg,
0481 &evea_regmap_config);
0482 if (IS_ERR(evea->regmap))
0483 return PTR_ERR(evea->regmap);
0484
0485 ret = clk_prepare_enable(evea->clk);
0486 if (ret)
0487 return ret;
0488
0489 ret = clk_prepare_enable(evea->clk_exiv);
0490 if (ret)
0491 goto err_out_clock;
0492
0493 ret = reset_control_deassert(evea->rst);
0494 if (ret)
0495 goto err_out_clock_exiv;
0496
0497 ret = reset_control_deassert(evea->rst_exiv);
0498 if (ret)
0499 goto err_out_reset;
0500
0501
0502 evea->rst_adamv = devm_reset_control_get_shared(&pdev->dev, "adamv");
0503 if (IS_ERR(evea->rst_adamv)) {
0504 ret = PTR_ERR(evea->rst_adamv);
0505 goto err_out_reset_exiv;
0506 }
0507
0508 ret = reset_control_deassert(evea->rst_adamv);
0509 if (ret)
0510 goto err_out_reset_exiv;
0511
0512 platform_set_drvdata(pdev, evea);
0513
0514 ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_evea,
0515 soc_dai_evea, ARRAY_SIZE(soc_dai_evea));
0516 if (ret)
0517 goto err_out_reset_adamv;
0518
0519 return 0;
0520
0521 err_out_reset_adamv:
0522 reset_control_assert(evea->rst_adamv);
0523
0524 err_out_reset_exiv:
0525 reset_control_assert(evea->rst_exiv);
0526
0527 err_out_reset:
0528 reset_control_assert(evea->rst);
0529
0530 err_out_clock_exiv:
0531 clk_disable_unprepare(evea->clk_exiv);
0532
0533 err_out_clock:
0534 clk_disable_unprepare(evea->clk);
0535
0536 return ret;
0537 }
0538
0539 static int evea_remove(struct platform_device *pdev)
0540 {
0541 struct evea_priv *evea = platform_get_drvdata(pdev);
0542
0543 reset_control_assert(evea->rst_adamv);
0544 reset_control_assert(evea->rst_exiv);
0545 reset_control_assert(evea->rst);
0546
0547 clk_disable_unprepare(evea->clk_exiv);
0548 clk_disable_unprepare(evea->clk);
0549
0550 return 0;
0551 }
0552
0553 static const struct of_device_id evea_of_match[] __maybe_unused = {
0554 { .compatible = "socionext,uniphier-evea", },
0555 {}
0556 };
0557 MODULE_DEVICE_TABLE(of, evea_of_match);
0558
0559 static struct platform_driver evea_codec_driver = {
0560 .driver = {
0561 .name = DRV_NAME,
0562 .of_match_table = of_match_ptr(evea_of_match),
0563 },
0564 .probe = evea_probe,
0565 .remove = evea_remove,
0566 };
0567 module_platform_driver(evea_codec_driver);
0568
0569 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
0570 MODULE_DESCRIPTION("UniPhier EVEA codec driver");
0571 MODULE_LICENSE("GPL v2");