.. | .. |
---|
| 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, |
---|