| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DA7213 ALSA SoC Codec Driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> |
|---|
| 7 | 8 | * Based on DA9055 ALSA SoC codec driver. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 10 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 11 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 12 | | - * option) any later version. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/acpi.h> |
|---|
| .. | .. |
|---|
| 23 | 19 | #include <linux/module.h> |
|---|
| 24 | 20 | #include <sound/pcm.h> |
|---|
| 25 | 21 | #include <sound/pcm_params.h> |
|---|
| 22 | +#include <linux/pm_runtime.h> |
|---|
| 26 | 23 | #include <sound/soc.h> |
|---|
| 27 | 24 | #include <sound/initval.h> |
|---|
| 28 | 25 | #include <sound/tlv.h> |
|---|
| .. | .. |
|---|
| 208 | 205 | /* Select middle 8 bits for read back from data register */ |
|---|
| 209 | 206 | snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL, |
|---|
| 210 | 207 | reg_val | DA7213_ALC_DATA_MIDDLE); |
|---|
| 211 | | - mid_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA); |
|---|
| 208 | + mid_data = snd_soc_component_read(component, DA7213_ALC_CIC_OP_LVL_DATA); |
|---|
| 212 | 209 | |
|---|
| 213 | 210 | /* Select top 8 bits for read back from data register */ |
|---|
| 214 | 211 | snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL, |
|---|
| 215 | 212 | reg_val | DA7213_ALC_DATA_TOP); |
|---|
| 216 | | - top_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA); |
|---|
| 213 | + top_data = snd_soc_component_read(component, DA7213_ALC_CIC_OP_LVL_DATA); |
|---|
| 217 | 214 | |
|---|
| 218 | 215 | sum += ((mid_data << 8) | (top_data << 16)); |
|---|
| 219 | 216 | } |
|---|
| .. | .. |
|---|
| 262 | 259 | snd_soc_component_update_bits(component, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN, |
|---|
| 263 | 260 | DA7213_ALC_AUTO_CALIB_EN); |
|---|
| 264 | 261 | do { |
|---|
| 265 | | - alc_ctrl1 = snd_soc_component_read32(component, DA7213_ALC_CTRL1); |
|---|
| 262 | + alc_ctrl1 = snd_soc_component_read(component, DA7213_ALC_CTRL1); |
|---|
| 266 | 263 | } while (alc_ctrl1 & DA7213_ALC_AUTO_CALIB_EN); |
|---|
| 267 | 264 | |
|---|
| 268 | 265 | /* If auto calibration fails, fall back to digital gain only mode */ |
|---|
| .. | .. |
|---|
| 289 | 286 | u8 mic_1_ctrl, mic_2_ctrl; |
|---|
| 290 | 287 | |
|---|
| 291 | 288 | /* Save current values from ADC control registers */ |
|---|
| 292 | | - adc_l_ctrl = snd_soc_component_read32(component, DA7213_ADC_L_CTRL); |
|---|
| 293 | | - adc_r_ctrl = snd_soc_component_read32(component, DA7213_ADC_R_CTRL); |
|---|
| 289 | + adc_l_ctrl = snd_soc_component_read(component, DA7213_ADC_L_CTRL); |
|---|
| 290 | + adc_r_ctrl = snd_soc_component_read(component, DA7213_ADC_R_CTRL); |
|---|
| 294 | 291 | |
|---|
| 295 | 292 | /* Save current values from MIXIN_L/R_SELECT registers */ |
|---|
| 296 | | - mixin_l_sel = snd_soc_component_read32(component, DA7213_MIXIN_L_SELECT); |
|---|
| 297 | | - mixin_r_sel = snd_soc_component_read32(component, DA7213_MIXIN_R_SELECT); |
|---|
| 293 | + mixin_l_sel = snd_soc_component_read(component, DA7213_MIXIN_L_SELECT); |
|---|
| 294 | + mixin_r_sel = snd_soc_component_read(component, DA7213_MIXIN_R_SELECT); |
|---|
| 298 | 295 | |
|---|
| 299 | 296 | /* Save current values from MIC control registers */ |
|---|
| 300 | | - mic_1_ctrl = snd_soc_component_read32(component, DA7213_MIC_1_CTRL); |
|---|
| 301 | | - mic_2_ctrl = snd_soc_component_read32(component, DA7213_MIC_2_CTRL); |
|---|
| 297 | + mic_1_ctrl = snd_soc_component_read(component, DA7213_MIC_1_CTRL); |
|---|
| 298 | + mic_2_ctrl = snd_soc_component_read(component, DA7213_MIC_2_CTRL); |
|---|
| 302 | 299 | |
|---|
| 303 | 300 | /* Enable ADC Left and Right */ |
|---|
| 304 | 301 | snd_soc_component_update_bits(component, DA7213_ADC_L_CTRL, DA7213_ADC_EN, |
|---|
| .. | .. |
|---|
| 754 | 751 | DA7213_PC_FREERUN_MASK, 0); |
|---|
| 755 | 752 | |
|---|
| 756 | 753 | /* If SRM not enabled then nothing more to do */ |
|---|
| 757 | | - pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL); |
|---|
| 754 | + pll_ctrl = snd_soc_component_read(component, DA7213_PLL_CTRL); |
|---|
| 758 | 755 | if (!(pll_ctrl & DA7213_PLL_SRM_EN)) |
|---|
| 759 | 756 | return 0; |
|---|
| 760 | 757 | |
|---|
| .. | .. |
|---|
| 767 | 764 | |
|---|
| 768 | 765 | /* Check SRM has locked */ |
|---|
| 769 | 766 | do { |
|---|
| 770 | | - pll_status = snd_soc_component_read32(component, DA7213_PLL_STATUS); |
|---|
| 767 | + pll_status = snd_soc_component_read(component, DA7213_PLL_STATUS); |
|---|
| 771 | 768 | if (pll_status & DA7219_PLL_SRM_LOCK) { |
|---|
| 772 | 769 | srm_lock = true; |
|---|
| 773 | 770 | } else { |
|---|
| .. | .. |
|---|
| 782 | 779 | return 0; |
|---|
| 783 | 780 | case SND_SOC_DAPM_POST_PMD: |
|---|
| 784 | 781 | /* Revert 32KHz PLL lock udpates if applied previously */ |
|---|
| 785 | | - pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL); |
|---|
| 782 | + pll_ctrl = snd_soc_component_read(component, DA7213_PLL_CTRL); |
|---|
| 786 | 783 | if (pll_ctrl & DA7213_PLL_32K_MODE) { |
|---|
| 787 | 784 | snd_soc_component_write(component, 0xF0, 0x8B); |
|---|
| 788 | 785 | snd_soc_component_write(component, 0xF2, 0x01); |
|---|
| .. | .. |
|---|
| 810 | 807 | */ |
|---|
| 811 | 808 | |
|---|
| 812 | 809 | static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = { |
|---|
| 810 | + /* |
|---|
| 811 | + * Power Supply |
|---|
| 812 | + */ |
|---|
| 813 | + SND_SOC_DAPM_REGULATOR_SUPPLY("VDDMIC", 0, 0), |
|---|
| 814 | + |
|---|
| 813 | 815 | /* |
|---|
| 814 | 816 | * Input & Output |
|---|
| 815 | 817 | */ |
|---|
| .. | .. |
|---|
| 936 | 938 | /* Dest Connecting Widget source */ |
|---|
| 937 | 939 | |
|---|
| 938 | 940 | /* Input path */ |
|---|
| 941 | + {"Mic Bias 1", NULL, "VDDMIC"}, |
|---|
| 942 | + {"Mic Bias 2", NULL, "VDDMIC"}, |
|---|
| 943 | + |
|---|
| 939 | 944 | {"MIC1", NULL, "Mic Bias 1"}, |
|---|
| 940 | 945 | {"MIC2", NULL, "Mic Bias 2"}, |
|---|
| 941 | 946 | |
|---|
| .. | .. |
|---|
| 1151 | 1156 | struct snd_soc_dai *dai) |
|---|
| 1152 | 1157 | { |
|---|
| 1153 | 1158 | struct snd_soc_component *component = dai->component; |
|---|
| 1159 | + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1154 | 1160 | u8 dai_ctrl = 0; |
|---|
| 1155 | 1161 | u8 fs; |
|---|
| 1156 | 1162 | |
|---|
| .. | .. |
|---|
| 1176 | 1182 | switch (params_rate(params)) { |
|---|
| 1177 | 1183 | case 8000: |
|---|
| 1178 | 1184 | fs = DA7213_SR_8000; |
|---|
| 1185 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1179 | 1186 | break; |
|---|
| 1180 | 1187 | case 11025: |
|---|
| 1181 | 1188 | fs = DA7213_SR_11025; |
|---|
| 1189 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; |
|---|
| 1182 | 1190 | break; |
|---|
| 1183 | 1191 | case 12000: |
|---|
| 1184 | 1192 | fs = DA7213_SR_12000; |
|---|
| 1193 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1185 | 1194 | break; |
|---|
| 1186 | 1195 | case 16000: |
|---|
| 1187 | 1196 | fs = DA7213_SR_16000; |
|---|
| 1197 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1188 | 1198 | break; |
|---|
| 1189 | 1199 | case 22050: |
|---|
| 1190 | 1200 | fs = DA7213_SR_22050; |
|---|
| 1201 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; |
|---|
| 1191 | 1202 | break; |
|---|
| 1192 | 1203 | case 32000: |
|---|
| 1193 | 1204 | fs = DA7213_SR_32000; |
|---|
| 1205 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1194 | 1206 | break; |
|---|
| 1195 | 1207 | case 44100: |
|---|
| 1196 | 1208 | fs = DA7213_SR_44100; |
|---|
| 1209 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; |
|---|
| 1197 | 1210 | break; |
|---|
| 1198 | 1211 | case 48000: |
|---|
| 1199 | 1212 | fs = DA7213_SR_48000; |
|---|
| 1213 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1200 | 1214 | break; |
|---|
| 1201 | 1215 | case 88200: |
|---|
| 1202 | 1216 | fs = DA7213_SR_88200; |
|---|
| 1217 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; |
|---|
| 1203 | 1218 | break; |
|---|
| 1204 | 1219 | case 96000: |
|---|
| 1205 | 1220 | fs = DA7213_SR_96000; |
|---|
| 1221 | + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; |
|---|
| 1206 | 1222 | break; |
|---|
| 1207 | 1223 | default: |
|---|
| 1208 | 1224 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1305 | 1321 | /* By default only 64 BCLK per WCLK is supported */ |
|---|
| 1306 | 1322 | dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64; |
|---|
| 1307 | 1323 | |
|---|
| 1308 | | - snd_soc_component_write(component, DA7213_DAI_CLK_MODE, dai_clk_mode); |
|---|
| 1324 | + snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE, |
|---|
| 1325 | + DA7213_DAI_BCLKS_PER_WCLK_MASK | |
|---|
| 1326 | + DA7213_DAI_CLK_POL_MASK | DA7213_DAI_WCLK_POL_MASK, |
|---|
| 1327 | + dai_clk_mode); |
|---|
| 1309 | 1328 | snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK, |
|---|
| 1310 | 1329 | dai_ctrl); |
|---|
| 1311 | 1330 | snd_soc_component_write(component, DA7213_DAI_OFFSET, dai_offset); |
|---|
| .. | .. |
|---|
| 1313 | 1332 | return 0; |
|---|
| 1314 | 1333 | } |
|---|
| 1315 | 1334 | |
|---|
| 1316 | | -static int da7213_mute(struct snd_soc_dai *dai, int mute) |
|---|
| 1335 | +static int da7213_mute(struct snd_soc_dai *dai, int mute, int direction) |
|---|
| 1317 | 1336 | { |
|---|
| 1318 | 1337 | struct snd_soc_component *component = dai->component; |
|---|
| 1319 | 1338 | |
|---|
| .. | .. |
|---|
| 1335 | 1354 | #define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
|---|
| 1336 | 1355 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
|---|
| 1337 | 1356 | |
|---|
| 1338 | | -static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
|---|
| 1339 | | - int clk_id, unsigned int freq, int dir) |
|---|
| 1357 | +static int da7213_set_component_sysclk(struct snd_soc_component *component, |
|---|
| 1358 | + int clk_id, int source, |
|---|
| 1359 | + unsigned int freq, int dir) |
|---|
| 1340 | 1360 | { |
|---|
| 1341 | | - struct snd_soc_component *component = codec_dai->component; |
|---|
| 1342 | 1361 | struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1343 | 1362 | int ret = 0; |
|---|
| 1344 | 1363 | |
|---|
| .. | .. |
|---|
| 1346 | 1365 | return 0; |
|---|
| 1347 | 1366 | |
|---|
| 1348 | 1367 | if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) { |
|---|
| 1349 | | - dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", |
|---|
| 1368 | + dev_err(component->dev, "Unsupported MCLK value %d\n", |
|---|
| 1350 | 1369 | freq); |
|---|
| 1351 | 1370 | return -EINVAL; |
|---|
| 1352 | 1371 | } |
|---|
| .. | .. |
|---|
| 1362 | 1381 | DA7213_PLL_MCLK_SQR_EN); |
|---|
| 1363 | 1382 | break; |
|---|
| 1364 | 1383 | default: |
|---|
| 1365 | | - dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); |
|---|
| 1384 | + dev_err(component->dev, "Unknown clock source %d\n", clk_id); |
|---|
| 1366 | 1385 | return -EINVAL; |
|---|
| 1367 | 1386 | } |
|---|
| 1368 | 1387 | |
|---|
| .. | .. |
|---|
| 1372 | 1391 | freq = clk_round_rate(da7213->mclk, freq); |
|---|
| 1373 | 1392 | ret = clk_set_rate(da7213->mclk, freq); |
|---|
| 1374 | 1393 | if (ret) { |
|---|
| 1375 | | - dev_err(codec_dai->dev, "Failed to set clock rate %d\n", |
|---|
| 1394 | + dev_err(component->dev, "Failed to set clock rate %d\n", |
|---|
| 1376 | 1395 | freq); |
|---|
| 1377 | 1396 | return ret; |
|---|
| 1378 | 1397 | } |
|---|
| .. | .. |
|---|
| 1384 | 1403 | } |
|---|
| 1385 | 1404 | |
|---|
| 1386 | 1405 | /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */ |
|---|
| 1387 | | -static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, |
|---|
| 1388 | | - int source, unsigned int fref, unsigned int fout) |
|---|
| 1406 | +static int _da7213_set_component_pll(struct snd_soc_component *component, |
|---|
| 1407 | + int pll_id, int source, |
|---|
| 1408 | + unsigned int fref, unsigned int fout) |
|---|
| 1389 | 1409 | { |
|---|
| 1390 | | - struct snd_soc_component *component = codec_dai->component; |
|---|
| 1391 | 1410 | struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1392 | 1411 | |
|---|
| 1393 | 1412 | u8 pll_ctrl, indiv_bits, indiv; |
|---|
| .. | .. |
|---|
| 1495 | 1514 | return 0; |
|---|
| 1496 | 1515 | } |
|---|
| 1497 | 1516 | |
|---|
| 1517 | +static int da7213_set_component_pll(struct snd_soc_component *component, |
|---|
| 1518 | + int pll_id, int source, |
|---|
| 1519 | + unsigned int fref, unsigned int fout) |
|---|
| 1520 | +{ |
|---|
| 1521 | + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1522 | + da7213->fixed_clk_auto_pll = false; |
|---|
| 1523 | + |
|---|
| 1524 | + return _da7213_set_component_pll(component, pll_id, source, fref, fout); |
|---|
| 1525 | +} |
|---|
| 1526 | + |
|---|
| 1498 | 1527 | /* DAI operations */ |
|---|
| 1499 | 1528 | static const struct snd_soc_dai_ops da7213_dai_ops = { |
|---|
| 1500 | 1529 | .hw_params = da7213_hw_params, |
|---|
| 1501 | 1530 | .set_fmt = da7213_set_dai_fmt, |
|---|
| 1502 | | - .set_sysclk = da7213_set_dai_sysclk, |
|---|
| 1503 | | - .set_pll = da7213_set_dai_pll, |
|---|
| 1504 | | - .digital_mute = da7213_mute, |
|---|
| 1531 | + .mute_stream = da7213_mute, |
|---|
| 1532 | + .no_capture_mute = 1, |
|---|
| 1505 | 1533 | }; |
|---|
| 1506 | 1534 | |
|---|
| 1507 | 1535 | static struct snd_soc_dai_driver da7213_dai = { |
|---|
| .. | .. |
|---|
| 1526 | 1554 | .symmetric_rates = 1, |
|---|
| 1527 | 1555 | }; |
|---|
| 1528 | 1556 | |
|---|
| 1557 | +static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable) |
|---|
| 1558 | +{ |
|---|
| 1559 | + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1560 | + int mode; |
|---|
| 1561 | + |
|---|
| 1562 | + if (!da7213->fixed_clk_auto_pll) |
|---|
| 1563 | + return 0; |
|---|
| 1564 | + |
|---|
| 1565 | + da7213->mclk_rate = clk_get_rate(da7213->mclk); |
|---|
| 1566 | + |
|---|
| 1567 | + if (enable) { |
|---|
| 1568 | + /* Slave mode needs SRM for non-harmonic frequencies */ |
|---|
| 1569 | + if (da7213->master) |
|---|
| 1570 | + mode = DA7213_SYSCLK_PLL; |
|---|
| 1571 | + else |
|---|
| 1572 | + mode = DA7213_SYSCLK_PLL_SRM; |
|---|
| 1573 | + |
|---|
| 1574 | + /* PLL is not required for harmonic frequencies */ |
|---|
| 1575 | + switch (da7213->out_rate) { |
|---|
| 1576 | + case DA7213_PLL_FREQ_OUT_90316800: |
|---|
| 1577 | + if (da7213->mclk_rate == 11289600 || |
|---|
| 1578 | + da7213->mclk_rate == 22579200 || |
|---|
| 1579 | + da7213->mclk_rate == 45158400) |
|---|
| 1580 | + mode = DA7213_SYSCLK_MCLK; |
|---|
| 1581 | + break; |
|---|
| 1582 | + case DA7213_PLL_FREQ_OUT_98304000: |
|---|
| 1583 | + if (da7213->mclk_rate == 12288000 || |
|---|
| 1584 | + da7213->mclk_rate == 24576000 || |
|---|
| 1585 | + da7213->mclk_rate == 49152000) |
|---|
| 1586 | + mode = DA7213_SYSCLK_MCLK; |
|---|
| 1587 | + |
|---|
| 1588 | + break; |
|---|
| 1589 | + default: |
|---|
| 1590 | + return -1; |
|---|
| 1591 | + } |
|---|
| 1592 | + } else { |
|---|
| 1593 | + /* Disable PLL in standby */ |
|---|
| 1594 | + mode = DA7213_SYSCLK_MCLK; |
|---|
| 1595 | + } |
|---|
| 1596 | + |
|---|
| 1597 | + return _da7213_set_component_pll(component, 0, mode, |
|---|
| 1598 | + da7213->mclk_rate, da7213->out_rate); |
|---|
| 1599 | +} |
|---|
| 1600 | + |
|---|
| 1529 | 1601 | static int da7213_set_bias_level(struct snd_soc_component *component, |
|---|
| 1530 | 1602 | enum snd_soc_bias_level level) |
|---|
| 1531 | 1603 | { |
|---|
| .. | .. |
|---|
| 1545 | 1617 | "Failed to enable mclk\n"); |
|---|
| 1546 | 1618 | return ret; |
|---|
| 1547 | 1619 | } |
|---|
| 1620 | + |
|---|
| 1621 | + da7213_set_auto_pll(component, true); |
|---|
| 1548 | 1622 | } |
|---|
| 1549 | 1623 | } |
|---|
| 1550 | 1624 | break; |
|---|
| .. | .. |
|---|
| 1556 | 1630 | DA7213_VMID_EN | DA7213_BIAS_EN); |
|---|
| 1557 | 1631 | } else { |
|---|
| 1558 | 1632 | /* Remove MCLK */ |
|---|
| 1559 | | - if (da7213->mclk) |
|---|
| 1633 | + if (da7213->mclk) { |
|---|
| 1634 | + da7213_set_auto_pll(component, false); |
|---|
| 1560 | 1635 | clk_disable_unprepare(da7213->mclk); |
|---|
| 1636 | + } |
|---|
| 1561 | 1637 | } |
|---|
| 1562 | 1638 | break; |
|---|
| 1563 | 1639 | case SND_SOC_BIAS_OFF: |
|---|
| .. | .. |
|---|
| 1572 | 1648 | #if defined(CONFIG_OF) |
|---|
| 1573 | 1649 | /* DT */ |
|---|
| 1574 | 1650 | static const struct of_device_id da7213_of_match[] = { |
|---|
| 1651 | + { .compatible = "dlg,da7212", }, |
|---|
| 1575 | 1652 | { .compatible = "dlg,da7213", }, |
|---|
| 1576 | 1653 | { } |
|---|
| 1577 | 1654 | }; |
|---|
| .. | .. |
|---|
| 1686 | 1763 | return pdata; |
|---|
| 1687 | 1764 | } |
|---|
| 1688 | 1765 | |
|---|
| 1689 | | - |
|---|
| 1690 | 1766 | static int da7213_probe(struct snd_soc_component *component) |
|---|
| 1691 | 1767 | { |
|---|
| 1692 | 1768 | struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); |
|---|
| 1769 | + |
|---|
| 1770 | + pm_runtime_get_sync(component->dev); |
|---|
| 1693 | 1771 | |
|---|
| 1694 | 1772 | /* Default to using ALC auto offset calibration mode. */ |
|---|
| 1695 | 1773 | snd_soc_component_update_bits(component, DA7213_ALC_CTRL1, |
|---|
| .. | .. |
|---|
| 1811 | 1889 | DA7213_DMIC_CLK_RATE_MASK, dmic_cfg); |
|---|
| 1812 | 1890 | } |
|---|
| 1813 | 1891 | |
|---|
| 1892 | + pm_runtime_put_sync(component->dev); |
|---|
| 1893 | + |
|---|
| 1814 | 1894 | /* Check if MCLK provided */ |
|---|
| 1815 | 1895 | da7213->mclk = devm_clk_get(component->dev, "mclk"); |
|---|
| 1816 | 1896 | if (IS_ERR(da7213->mclk)) { |
|---|
| .. | .. |
|---|
| 1818 | 1898 | return PTR_ERR(da7213->mclk); |
|---|
| 1819 | 1899 | else |
|---|
| 1820 | 1900 | da7213->mclk = NULL; |
|---|
| 1901 | + } else { |
|---|
| 1902 | + /* Do automatic PLL handling assuming fixed clock until |
|---|
| 1903 | + * set_pll() has been called. This makes the codec usable |
|---|
| 1904 | + * with the simple-audio-card driver. */ |
|---|
| 1905 | + da7213->fixed_clk_auto_pll = true; |
|---|
| 1821 | 1906 | } |
|---|
| 1822 | 1907 | |
|---|
| 1823 | 1908 | return 0; |
|---|
| .. | .. |
|---|
| 1832 | 1917 | .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), |
|---|
| 1833 | 1918 | .dapm_routes = da7213_audio_map, |
|---|
| 1834 | 1919 | .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), |
|---|
| 1920 | + .set_sysclk = da7213_set_component_sysclk, |
|---|
| 1921 | + .set_pll = da7213_set_component_pll, |
|---|
| 1835 | 1922 | .idle_bias_on = 1, |
|---|
| 1836 | 1923 | .use_pmdown_time = 1, |
|---|
| 1837 | 1924 | .endianness = 1, |
|---|
| .. | .. |
|---|
| 1848 | 1935 | .cache_type = REGCACHE_RBTREE, |
|---|
| 1849 | 1936 | }; |
|---|
| 1850 | 1937 | |
|---|
| 1938 | +static void da7213_power_off(void *data) |
|---|
| 1939 | +{ |
|---|
| 1940 | + struct da7213_priv *da7213 = data; |
|---|
| 1941 | + regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies); |
|---|
| 1942 | +} |
|---|
| 1943 | + |
|---|
| 1944 | +static const char *da7213_supply_names[DA7213_NUM_SUPPLIES] = { |
|---|
| 1945 | + [DA7213_SUPPLY_VDDA] = "VDDA", |
|---|
| 1946 | + [DA7213_SUPPLY_VDDIO] = "VDDIO", |
|---|
| 1947 | +}; |
|---|
| 1948 | + |
|---|
| 1851 | 1949 | static int da7213_i2c_probe(struct i2c_client *i2c, |
|---|
| 1852 | 1950 | const struct i2c_device_id *id) |
|---|
| 1853 | 1951 | { |
|---|
| 1854 | 1952 | struct da7213_priv *da7213; |
|---|
| 1855 | | - int ret; |
|---|
| 1953 | + int i, ret; |
|---|
| 1856 | 1954 | |
|---|
| 1857 | 1955 | da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL); |
|---|
| 1858 | 1956 | if (!da7213) |
|---|
| .. | .. |
|---|
| 1860 | 1958 | |
|---|
| 1861 | 1959 | i2c_set_clientdata(i2c, da7213); |
|---|
| 1862 | 1960 | |
|---|
| 1961 | + /* Get required supplies */ |
|---|
| 1962 | + for (i = 0; i < DA7213_NUM_SUPPLIES; ++i) |
|---|
| 1963 | + da7213->supplies[i].supply = da7213_supply_names[i]; |
|---|
| 1964 | + |
|---|
| 1965 | + ret = devm_regulator_bulk_get(&i2c->dev, DA7213_NUM_SUPPLIES, |
|---|
| 1966 | + da7213->supplies); |
|---|
| 1967 | + if (ret) { |
|---|
| 1968 | + dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret); |
|---|
| 1969 | + return ret; |
|---|
| 1970 | + } |
|---|
| 1971 | + |
|---|
| 1972 | + ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies); |
|---|
| 1973 | + if (ret < 0) |
|---|
| 1974 | + return ret; |
|---|
| 1975 | + |
|---|
| 1976 | + ret = devm_add_action_or_reset(&i2c->dev, da7213_power_off, da7213); |
|---|
| 1977 | + if (ret < 0) |
|---|
| 1978 | + return ret; |
|---|
| 1979 | + |
|---|
| 1863 | 1980 | da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config); |
|---|
| 1864 | 1981 | if (IS_ERR(da7213->regmap)) { |
|---|
| 1865 | 1982 | ret = PTR_ERR(da7213->regmap); |
|---|
| 1866 | 1983 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
|---|
| 1867 | 1984 | return ret; |
|---|
| 1868 | 1985 | } |
|---|
| 1986 | + |
|---|
| 1987 | + pm_runtime_set_autosuspend_delay(&i2c->dev, 100); |
|---|
| 1988 | + pm_runtime_use_autosuspend(&i2c->dev); |
|---|
| 1989 | + pm_runtime_set_active(&i2c->dev); |
|---|
| 1990 | + pm_runtime_enable(&i2c->dev); |
|---|
| 1869 | 1991 | |
|---|
| 1870 | 1992 | ret = devm_snd_soc_register_component(&i2c->dev, |
|---|
| 1871 | 1993 | &soc_component_dev_da7213, &da7213_dai, 1); |
|---|
| .. | .. |
|---|
| 1875 | 1997 | } |
|---|
| 1876 | 1998 | return ret; |
|---|
| 1877 | 1999 | } |
|---|
| 2000 | + |
|---|
| 2001 | +static int __maybe_unused da7213_runtime_suspend(struct device *dev) |
|---|
| 2002 | +{ |
|---|
| 2003 | + struct da7213_priv *da7213 = dev_get_drvdata(dev); |
|---|
| 2004 | + |
|---|
| 2005 | + regcache_cache_only(da7213->regmap, true); |
|---|
| 2006 | + regcache_mark_dirty(da7213->regmap); |
|---|
| 2007 | + regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies); |
|---|
| 2008 | + |
|---|
| 2009 | + return 0; |
|---|
| 2010 | +} |
|---|
| 2011 | + |
|---|
| 2012 | +static int __maybe_unused da7213_runtime_resume(struct device *dev) |
|---|
| 2013 | +{ |
|---|
| 2014 | + struct da7213_priv *da7213 = dev_get_drvdata(dev); |
|---|
| 2015 | + int ret; |
|---|
| 2016 | + |
|---|
| 2017 | + ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies); |
|---|
| 2018 | + if (ret < 0) |
|---|
| 2019 | + return ret; |
|---|
| 2020 | + regcache_cache_only(da7213->regmap, false); |
|---|
| 2021 | + regcache_sync(da7213->regmap); |
|---|
| 2022 | + return 0; |
|---|
| 2023 | +} |
|---|
| 2024 | + |
|---|
| 2025 | +static const struct dev_pm_ops da7213_pm = { |
|---|
| 2026 | + SET_RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL) |
|---|
| 2027 | +}; |
|---|
| 1878 | 2028 | |
|---|
| 1879 | 2029 | static const struct i2c_device_id da7213_i2c_id[] = { |
|---|
| 1880 | 2030 | { "da7213", 0 }, |
|---|
| .. | .. |
|---|
| 1888 | 2038 | .name = "da7213", |
|---|
| 1889 | 2039 | .of_match_table = of_match_ptr(da7213_of_match), |
|---|
| 1890 | 2040 | .acpi_match_table = ACPI_PTR(da7213_acpi_match), |
|---|
| 2041 | + .pm = &da7213_pm, |
|---|
| 1891 | 2042 | }, |
|---|
| 1892 | 2043 | .probe = da7213_i2c_probe, |
|---|
| 1893 | 2044 | .id_table = da7213_i2c_id, |
|---|