summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Thomson <Adam.Thomson.Opensource@diasemi.com>2019-03-19 13:49:31 -0400
committerMark Brown <broonie@kernel.org>2019-03-21 10:50:17 -0400
commitd90ba6c8b53e541913a181638c353cf7a0856256 (patch)
tree681c1ff5bf7027128e4926aaf0845e3e1effb0ff
parent41d176d3ec147f499614adc773080f244d47e3cd (diff)
ASoC: da7219: Expose BCLK and WCLK control through CCF
For the purposes of platforms which use the codec as DAI clock master for the CPU and other codec devices, there is the need to not only expose the clock gating of BCLK and WCLK but also the ability to set those rates without going through the ASoC APIs. To make this possible, the previous CCF implementation in the driver has been extended to separate BCLK and WCLK out. WCLK is the parent clock to BCLK, and is also the clock gate for both. BCLK in HW is a factor/multiplier of WCLK so derives from whatever SR is chosen for WCLK, hence the need to make it a child of WCLK for the purposes of CCF. Enabling/disabling either BCLK or WCLK will result in clocks being ungated/gated accordingly. To simplify matters, these clocks can only be configured if the codec is set as master, otherwise CCF control is disallowed. Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/da7219.h8
-rw-r--r--sound/soc/codecs/da7219.c523
-rw-r--r--sound/soc/codecs/da7219.h6
3 files changed, 407 insertions, 130 deletions
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
index 1bfcb16f2d10..4a36954c86c5 100644
--- a/include/sound/da7219.h
+++ b/include/sound/da7219.h
@@ -33,10 +33,16 @@ enum da7219_mic_amp_in_sel {
33 33
34struct da7219_aad_pdata; 34struct da7219_aad_pdata;
35 35
36enum da7219_dai_clks {
37 DA7219_DAI_WCLK_IDX = 0,
38 DA7219_DAI_BCLK_IDX,
39 DA7219_DAI_NUM_CLKS,
40};
41
36struct da7219_pdata { 42struct da7219_pdata {
37 bool wakeup_source; 43 bool wakeup_source;
38 44
39 const char *dai_clks_name; 45 const char *dai_clk_names[DA7219_DAI_NUM_CLKS];
40 46
41 /* Mic */ 47 /* Mic */
42 enum da7219_micbias_voltage micbias_lvl; 48 enum da7219_micbias_voltage micbias_lvl;
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 121a8190f93e..5f5fa3416af3 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -797,6 +797,7 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
797{ 797{
798 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 798 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
799 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 799 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
800 struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX];
800 u8 pll_ctrl, pll_status; 801 u8 pll_ctrl, pll_status;
801 int i = 0, ret; 802 int i = 0, ret;
802 bool srm_lock = false; 803 bool srm_lock = false;
@@ -805,11 +806,11 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
805 case SND_SOC_DAPM_PRE_PMU: 806 case SND_SOC_DAPM_PRE_PMU:
806 if (da7219->master) { 807 if (da7219->master) {
807 /* Enable DAI clks for master mode */ 808 /* Enable DAI clks for master mode */
808 if (da7219->dai_clks) { 809 if (bclk) {
809 ret = clk_prepare_enable(da7219->dai_clks); 810 ret = clk_prepare_enable(bclk);
810 if (ret) { 811 if (ret) {
811 dev_err(component->dev, 812 dev_err(component->dev,
812 "Failed to enable dai_clks\n"); 813 "Failed to enable DAI clks\n");
813 return ret; 814 return ret;
814 } 815 }
815 } else { 816 } else {
@@ -852,8 +853,8 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
852 853
853 /* Disable DAI clks if in master mode */ 854 /* Disable DAI clks if in master mode */
854 if (da7219->master) { 855 if (da7219->master) {
855 if (da7219->dai_clks) 856 if (bclk)
856 clk_disable_unprepare(da7219->dai_clks); 857 clk_disable_unprepare(bclk);
857 else 858 else
858 snd_soc_component_update_bits(component, 859 snd_soc_component_update_bits(component,
859 DA7219_DAI_CLK_MODE, 860 DA7219_DAI_CLK_MODE,
@@ -1385,17 +1386,50 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1385 return 0; 1386 return 0;
1386} 1387}
1387 1388
1389static int da7219_set_bclks_per_wclk(struct snd_soc_component *component,
1390 unsigned long factor)
1391{
1392 u8 bclks_per_wclk;
1393
1394 switch (factor) {
1395 case 32:
1396 bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
1397 break;
1398 case 64:
1399 bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
1400 break;
1401 case 128:
1402 bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
1403 break;
1404 case 256:
1405 bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
1406 break;
1407 default:
1408 return -EINVAL;
1409 }
1410
1411 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
1412 DA7219_DAI_BCLKS_PER_WCLK_MASK,
1413 bclks_per_wclk);
1414
1415 return 0;
1416}
1417
1388static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai, 1418static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
1389 unsigned int tx_mask, unsigned int rx_mask, 1419 unsigned int tx_mask, unsigned int rx_mask,
1390 int slots, int slot_width) 1420 int slots, int slot_width)
1391{ 1421{
1392 struct snd_soc_component *component = dai->component; 1422 struct snd_soc_component *component = dai->component;
1393 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 1423 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1424 struct clk *wclk = da7219->dai_clks[DA7219_DAI_WCLK_IDX];
1425 struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX];
1394 unsigned int ch_mask; 1426 unsigned int ch_mask;
1395 u8 dai_bclks_per_wclk, slot_offset; 1427 unsigned long sr, bclk_rate;
1428 u8 slot_offset;
1396 u16 offset; 1429 u16 offset;
1397 __le16 dai_offset; 1430 __le16 dai_offset;
1398 u32 frame_size; 1431 u32 frame_size;
1432 int ret;
1399 1433
1400 /* No channels enabled so disable TDM */ 1434 /* No channels enabled so disable TDM */
1401 if (!tx_mask) { 1435 if (!tx_mask) {
@@ -1432,28 +1466,26 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
1432 */ 1466 */
1433 if (da7219->master) { 1467 if (da7219->master) {
1434 frame_size = slots * slot_width; 1468 frame_size = slots * slot_width;
1435 switch (frame_size) {
1436 case 32:
1437 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
1438 break;
1439 case 64:
1440 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
1441 break;
1442 case 128:
1443 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
1444 break;
1445 case 256:
1446 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
1447 break;
1448 default:
1449 dev_err(component->dev, "Invalid frame size %d\n",
1450 frame_size);
1451 return -EINVAL;
1452 }
1453 1469
1454 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, 1470 if (bclk) {
1455 DA7219_DAI_BCLKS_PER_WCLK_MASK, 1471 sr = clk_get_rate(wclk);
1456 dai_bclks_per_wclk); 1472 bclk_rate = sr * frame_size;
1473 ret = clk_set_rate(bclk, bclk_rate);
1474 if (ret) {
1475 dev_err(component->dev,
1476 "Failed to set TDM BCLK rate %lu: %d\n",
1477 bclk_rate, ret);
1478 return ret;
1479 }
1480 } else {
1481 ret = da7219_set_bclks_per_wclk(component, frame_size);
1482 if (ret) {
1483 dev_err(component->dev,
1484 "Failed to set TDM BCLKs per WCLK %d: %d\n",
1485 frame_size, ret);
1486 return ret;
1487 }
1488 }
1457 } 1489 }
1458 1490
1459 dai_offset = cpu_to_le16(offset); 1491 dai_offset = cpu_to_le16(offset);
@@ -1471,44 +1503,12 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
1471 return 0; 1503 return 0;
1472} 1504}
1473 1505
1474static int da7219_hw_params(struct snd_pcm_substream *substream, 1506static int da7219_set_sr(struct snd_soc_component *component,
1475 struct snd_pcm_hw_params *params, 1507 unsigned long rate)
1476 struct snd_soc_dai *dai)
1477{ 1508{
1478 struct snd_soc_component *component = dai->component; 1509 u8 fs;
1479 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1480 u8 dai_ctrl = 0, dai_bclks_per_wclk = 0, fs;
1481 unsigned int channels;
1482 int word_len = params_width(params);
1483 int frame_size;
1484
1485 switch (word_len) {
1486 case 16:
1487 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE;
1488 break;
1489 case 20:
1490 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE;
1491 break;
1492 case 24:
1493 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE;
1494 break;
1495 case 32:
1496 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE;
1497 break;
1498 default:
1499 return -EINVAL;
1500 }
1501
1502 channels = params_channels(params);
1503 if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
1504 dev_err(component->dev,
1505 "Invalid number of channels, only 1 to %d supported\n",
1506 DA7219_DAI_CH_NUM_MAX);
1507 return -EINVAL;
1508 }
1509 dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT;
1510 1510
1511 switch (params_rate(params)) { 1511 switch (rate) {
1512 case 8000: 1512 case 8000:
1513 fs = DA7219_SR_8000; 1513 fs = DA7219_SR_8000;
1514 break; 1514 break;
@@ -1546,28 +1546,103 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
1546 return -EINVAL; 1546 return -EINVAL;
1547 } 1547 }
1548 1548
1549 snd_soc_component_write(component, DA7219_SR, fs);
1550
1551 return 0;
1552}
1553
1554static int da7219_hw_params(struct snd_pcm_substream *substream,
1555 struct snd_pcm_hw_params *params,
1556 struct snd_soc_dai *dai)
1557{
1558 struct snd_soc_component *component = dai->component;
1559 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1560 struct clk *wclk = da7219->dai_clks[DA7219_DAI_WCLK_IDX];
1561 struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX];
1562 u8 dai_ctrl = 0;
1563 unsigned int channels;
1564 unsigned long sr, bclk_rate;
1565 int word_len = params_width(params);
1566 int frame_size, ret;
1567
1568 switch (word_len) {
1569 case 16:
1570 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE;
1571 break;
1572 case 20:
1573 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE;
1574 break;
1575 case 24:
1576 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE;
1577 break;
1578 case 32:
1579 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE;
1580 break;
1581 default:
1582 return -EINVAL;
1583 }
1584
1585 channels = params_channels(params);
1586 if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
1587 dev_err(component->dev,
1588 "Invalid number of channels, only 1 to %d supported\n",
1589 DA7219_DAI_CH_NUM_MAX);
1590 return -EINVAL;
1591 }
1592 dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT;
1593
1594 sr = params_rate(params);
1595 if (da7219->master && wclk) {
1596 ret = clk_set_rate(wclk, sr);
1597 if (ret) {
1598 dev_err(component->dev,
1599 "Failed to set WCLK SR %lu: %d\n", sr, ret);
1600 return ret;
1601 }
1602 } else {
1603 ret = da7219_set_sr(component, sr);
1604 if (ret) {
1605 dev_err(component->dev,
1606 "Failed to set SR %lu: %d\n", sr, ret);
1607 return ret;
1608 }
1609 }
1610
1549 /* 1611 /*
1550 * If we're master, then we have a limited set of BCLK rates we 1612 * If we're master, then we have a limited set of BCLK rates we
1551 * support. For slave mode this isn't the case and the codec can detect 1613 * support. For slave mode this isn't the case and the codec can detect
1552 * the BCLK rate automatically. 1614 * the BCLK rate automatically.
1553 */ 1615 */
1554 if (da7219->master && !da7219->tdm_en) { 1616 if (da7219->master && !da7219->tdm_en) {
1555 frame_size = word_len * 2; 1617 if ((word_len * DA7219_DAI_CH_NUM_MAX) <= 32)
1556 if (frame_size <= 32) 1618 frame_size = 32;
1557 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
1558 else 1619 else
1559 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64; 1620 frame_size = 64;
1560 1621
1561 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, 1622 if (bclk) {
1562 DA7219_DAI_BCLKS_PER_WCLK_MASK, 1623 bclk_rate = frame_size * sr;
1563 dai_bclks_per_wclk); 1624 ret = clk_set_rate(bclk, bclk_rate);
1625 if (ret) {
1626 dev_err(component->dev,
1627 "Failed to set BCLK rate %lu: %d\n",
1628 bclk_rate, ret);
1629 return ret;
1630 }
1631 } else {
1632 ret = da7219_set_bclks_per_wclk(component, frame_size);
1633 if (ret) {
1634 dev_err(component->dev,
1635 "Failed to set BCLKs per WCLK %d: %d\n",
1636 frame_size, ret);
1637 return ret;
1638 }
1639 }
1564 } 1640 }
1565 1641
1566 snd_soc_component_update_bits(component, DA7219_DAI_CTRL, 1642 snd_soc_component_update_bits(component, DA7219_DAI_CTRL,
1567 DA7219_DAI_WORD_LENGTH_MASK | 1643 DA7219_DAI_WORD_LENGTH_MASK |
1568 DA7219_DAI_CH_NUM_MASK, 1644 DA7219_DAI_CH_NUM_MASK,
1569 dai_ctrl); 1645 dai_ctrl);
1570 snd_soc_component_write(component, DA7219_SR, fs);
1571 1646
1572 return 0; 1647 return 0;
1573} 1648}
@@ -1672,11 +1747,14 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_component *compone
1672 1747
1673 pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source"); 1748 pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source");
1674 1749
1675 pdata->dai_clks_name = "da7219-dai-clks"; 1750 pdata->dai_clk_names[DA7219_DAI_WCLK_IDX] = "da7219-dai-wclk";
1676 if (device_property_read_string(dev, "clock-output-names", 1751 pdata->dai_clk_names[DA7219_DAI_BCLK_IDX] = "da7219-dai-bclk";
1677 &pdata->dai_clks_name)) 1752 if (device_property_read_string_array(dev, "clock-output-names",
1678 dev_warn(dev, "Using default clk name: %s\n", 1753 pdata->dai_clk_names,
1679 pdata->dai_clks_name); 1754 DA7219_DAI_NUM_CLKS) < 0)
1755 dev_warn(dev, "Using default DAI clk names: %s, %s\n",
1756 pdata->dai_clk_names[DA7219_DAI_WCLK_IDX],
1757 pdata->dai_clk_names[DA7219_DAI_BCLK_IDX]);
1680 1758
1681 if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) 1759 if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0)
1682 pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); 1760 pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32);
@@ -1793,12 +1871,16 @@ static int da7219_handle_supplies(struct snd_soc_component *component)
1793} 1871}
1794 1872
1795#ifdef CONFIG_COMMON_CLK 1873#ifdef CONFIG_COMMON_CLK
1796static int da7219_dai_clks_prepare(struct clk_hw *hw) 1874static int da7219_wclk_prepare(struct clk_hw *hw)
1797{ 1875{
1798 struct da7219_priv *da7219 = 1876 struct da7219_priv *da7219 =
1799 container_of(hw, struct da7219_priv, dai_clks_hw); 1877 container_of(hw, struct da7219_priv,
1878 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
1800 struct snd_soc_component *component = da7219->component; 1879 struct snd_soc_component *component = da7219->component;
1801 1880
1881 if (!da7219->master)
1882 return -EINVAL;
1883
1802 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, 1884 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
1803 DA7219_DAI_CLK_EN_MASK, 1885 DA7219_DAI_CLK_EN_MASK,
1804 DA7219_DAI_CLK_EN_MASK); 1886 DA7219_DAI_CLK_EN_MASK);
@@ -1806,36 +1888,48 @@ static int da7219_dai_clks_prepare(struct clk_hw *hw)
1806 return 0; 1888 return 0;
1807} 1889}
1808 1890
1809static void da7219_dai_clks_unprepare(struct clk_hw *hw) 1891static void da7219_wclk_unprepare(struct clk_hw *hw)
1810{ 1892{
1811 struct da7219_priv *da7219 = 1893 struct da7219_priv *da7219 =
1812 container_of(hw, struct da7219_priv, dai_clks_hw); 1894 container_of(hw, struct da7219_priv,
1895 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
1813 struct snd_soc_component *component = da7219->component; 1896 struct snd_soc_component *component = da7219->component;
1814 1897
1898 if (!da7219->master)
1899 return;
1900
1815 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, 1901 snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
1816 DA7219_DAI_CLK_EN_MASK, 0); 1902 DA7219_DAI_CLK_EN_MASK, 0);
1817} 1903}
1818 1904
1819static int da7219_dai_clks_is_prepared(struct clk_hw *hw) 1905static int da7219_wclk_is_prepared(struct clk_hw *hw)
1820{ 1906{
1821 struct da7219_priv *da7219 = 1907 struct da7219_priv *da7219 =
1822 container_of(hw, struct da7219_priv, dai_clks_hw); 1908 container_of(hw, struct da7219_priv,
1909 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
1823 struct snd_soc_component *component = da7219->component; 1910 struct snd_soc_component *component = da7219->component;
1824 u8 clk_reg; 1911 u8 clk_reg;
1825 1912
1913 if (!da7219->master)
1914 return -EINVAL;
1915
1826 clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE); 1916 clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE);
1827 1917
1828 return !!(clk_reg & DA7219_DAI_CLK_EN_MASK); 1918 return !!(clk_reg & DA7219_DAI_CLK_EN_MASK);
1829} 1919}
1830 1920
1831static unsigned long da7219_dai_clks_recalc_rate(struct clk_hw *hw, 1921static unsigned long da7219_wclk_recalc_rate(struct clk_hw *hw,
1832 unsigned long parent_rate) 1922 unsigned long parent_rate)
1833{ 1923{
1834 struct da7219_priv *da7219 = 1924 struct da7219_priv *da7219 =
1835 container_of(hw, struct da7219_priv, dai_clks_hw); 1925 container_of(hw, struct da7219_priv,
1926 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
1836 struct snd_soc_component *component = da7219->component; 1927 struct snd_soc_component *component = da7219->component;
1837 u8 fs = snd_soc_component_read32(component, DA7219_SR); 1928 u8 fs = snd_soc_component_read32(component, DA7219_SR);
1838 1929
1930 if (!da7219->master)
1931 return 0;
1932
1839 switch (fs & DA7219_SR_MASK) { 1933 switch (fs & DA7219_SR_MASK) {
1840 case DA7219_SR_8000: 1934 case DA7219_SR_8000:
1841 return 8000; 1935 return 8000;
@@ -1864,11 +1958,151 @@ static unsigned long da7219_dai_clks_recalc_rate(struct clk_hw *hw,
1864 } 1958 }
1865} 1959}
1866 1960
1867static const struct clk_ops da7219_dai_clks_ops = { 1961static long da7219_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
1868 .prepare = da7219_dai_clks_prepare, 1962 unsigned long *parent_rate)
1869 .unprepare = da7219_dai_clks_unprepare, 1963{
1870 .is_prepared = da7219_dai_clks_is_prepared, 1964 struct da7219_priv *da7219 =
1871 .recalc_rate = da7219_dai_clks_recalc_rate, 1965 container_of(hw, struct da7219_priv,
1966 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
1967
1968 if (!da7219->master)
1969 return -EINVAL;
1970
1971 if (rate < 11025)
1972 return 8000;
1973 else if (rate < 12000)
1974 return 11025;
1975 else if (rate < 16000)
1976 return 12000;
1977 else if (rate < 22050)
1978 return 16000;
1979 else if (rate < 24000)
1980 return 22050;
1981 else if (rate < 32000)
1982 return 24000;
1983 else if (rate < 44100)
1984 return 32000;
1985 else if (rate < 48000)
1986 return 44100;
1987 else if (rate < 88200)
1988 return 48000;
1989 else if (rate < 96000)
1990 return 88200;
1991 else
1992 return 96000;
1993}
1994
1995static int da7219_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
1996 unsigned long parent_rate)
1997{
1998 struct da7219_priv *da7219 =
1999 container_of(hw, struct da7219_priv,
2000 dai_clks_hw[DA7219_DAI_WCLK_IDX]);
2001 struct snd_soc_component *component = da7219->component;
2002
2003 if (!da7219->master)
2004 return -EINVAL;
2005
2006 return da7219_set_sr(component, rate);
2007}
2008
2009static unsigned long da7219_bclk_recalc_rate(struct clk_hw *hw,
2010 unsigned long parent_rate)
2011{
2012 struct da7219_priv *da7219 =
2013 container_of(hw, struct da7219_priv,
2014 dai_clks_hw[DA7219_DAI_BCLK_IDX]);
2015 struct snd_soc_component *component = da7219->component;
2016 u8 bclks_per_wclk = snd_soc_component_read32(component,
2017 DA7219_DAI_CLK_MODE);
2018
2019 if (!da7219->master)
2020 return 0;
2021
2022 switch (bclks_per_wclk & DA7219_DAI_BCLKS_PER_WCLK_MASK) {
2023 case DA7219_DAI_BCLKS_PER_WCLK_32:
2024 return parent_rate * 32;
2025 case DA7219_DAI_BCLKS_PER_WCLK_64:
2026 return parent_rate * 64;
2027 case DA7219_DAI_BCLKS_PER_WCLK_128:
2028 return parent_rate * 128;
2029 case DA7219_DAI_BCLKS_PER_WCLK_256:
2030 return parent_rate * 256;
2031 default:
2032 return 0;
2033 }
2034}
2035
2036static unsigned long da7219_bclk_get_factor(unsigned long rate,
2037 unsigned long parent_rate)
2038{
2039 unsigned long factor;
2040
2041 factor = rate / parent_rate;
2042 if (factor < 64)
2043 return 32;
2044 else if (factor < 128)
2045 return 64;
2046 else if (factor < 256)
2047 return 128;
2048 else
2049 return 256;
2050}
2051
2052static long da7219_bclk_round_rate(struct clk_hw *hw, unsigned long rate,
2053 unsigned long *parent_rate)
2054{
2055 struct da7219_priv *da7219 =
2056 container_of(hw, struct da7219_priv,
2057 dai_clks_hw[DA7219_DAI_BCLK_IDX]);
2058 unsigned long factor;
2059
2060 if (!*parent_rate || !da7219->master)
2061 return -EINVAL;
2062
2063 /*
2064 * We don't allow changing the parent rate as some BCLK rates can be
2065 * derived from multiple parent WCLK rates (BCLK rates are set as a
2066 * multiplier of WCLK in HW). We just do some rounding down based on the
2067 * parent WCLK rate set and find the appropriate multiplier of BCLK to
2068 * get the rounded down BCLK value.
2069 */
2070 factor = da7219_bclk_get_factor(rate, *parent_rate);
2071
2072 return *parent_rate * factor;
2073}
2074
2075static int da7219_bclk_set_rate(struct clk_hw *hw, unsigned long rate,
2076 unsigned long parent_rate)
2077{
2078 struct da7219_priv *da7219 =
2079 container_of(hw, struct da7219_priv,
2080 dai_clks_hw[DA7219_DAI_BCLK_IDX]);
2081 struct snd_soc_component *component = da7219->component;
2082 unsigned long factor;
2083
2084 if (!da7219->master)
2085 return -EINVAL;
2086
2087 factor = da7219_bclk_get_factor(rate, parent_rate);
2088
2089 return da7219_set_bclks_per_wclk(component, factor);
2090}
2091
2092static const struct clk_ops da7219_dai_clk_ops[DA7219_DAI_NUM_CLKS] = {
2093 [DA7219_DAI_WCLK_IDX] = {
2094 .prepare = da7219_wclk_prepare,
2095 .unprepare = da7219_wclk_unprepare,
2096 .is_prepared = da7219_wclk_is_prepared,
2097 .recalc_rate = da7219_wclk_recalc_rate,
2098 .round_rate = da7219_wclk_round_rate,
2099 .set_rate = da7219_wclk_set_rate,
2100 },
2101 [DA7219_DAI_BCLK_IDX] = {
2102 .recalc_rate = da7219_bclk_recalc_rate,
2103 .round_rate = da7219_bclk_round_rate,
2104 .set_rate = da7219_bclk_set_rate,
2105 },
1872}; 2106};
1873 2107
1874static int da7219_register_dai_clks(struct snd_soc_component *component) 2108static int da7219_register_dai_clks(struct snd_soc_component *component)
@@ -1876,47 +2110,81 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)
1876 struct device *dev = component->dev; 2110 struct device *dev = component->dev;
1877 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 2111 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1878 struct da7219_pdata *pdata = da7219->pdata; 2112 struct da7219_pdata *pdata = da7219->pdata;
1879 struct clk_init_data init = {};
1880 struct clk *dai_clks;
1881 struct clk_lookup *dai_clks_lookup;
1882 const char *parent_name; 2113 const char *parent_name;
2114 int i, ret;
1883 2115
1884 if (da7219->mclk) { 2116 for (i = 0; i < DA7219_DAI_NUM_CLKS; ++i) {
1885 parent_name = __clk_get_name(da7219->mclk); 2117 struct clk_init_data init = {};
1886 init.parent_names = &parent_name; 2118 struct clk *dai_clk;
1887 init.num_parents = 1; 2119 struct clk_lookup *dai_clk_lookup;
1888 } else { 2120 struct clk_hw *dai_clk_hw = &da7219->dai_clks_hw[i];
1889 init.parent_names = NULL;
1890 init.num_parents = 0;
1891 }
1892 2121
1893 init.name = pdata->dai_clks_name; 2122 switch (i) {
1894 init.ops = &da7219_dai_clks_ops; 2123 case DA7219_DAI_WCLK_IDX:
1895 init.flags = CLK_GET_RATE_NOCACHE; 2124 /*
1896 da7219->dai_clks_hw.init = &init; 2125 * If we can, make MCLK the parent of WCLK to ensure
2126 * it's enabled as required.
2127 */
2128 if (da7219->mclk) {
2129 parent_name = __clk_get_name(da7219->mclk);
2130 init.parent_names = &parent_name;
2131 init.num_parents = 1;
2132 } else {
2133 init.parent_names = NULL;
2134 init.num_parents = 0;
2135 }
2136 break;
2137 case DA7219_DAI_BCLK_IDX:
2138 /* Make WCLK the parent of BCLK */
2139 parent_name = __clk_get_name(da7219->dai_clks[DA7219_DAI_WCLK_IDX]);
2140 init.parent_names = &parent_name;
2141 init.num_parents = 1;
2142 break;
2143 default:
2144 dev_err(dev, "Invalid clock index\n");
2145 ret = -EINVAL;
2146 goto err;
2147 }
1897 2148
1898 dai_clks = devm_clk_register(dev, &da7219->dai_clks_hw); 2149 init.name = pdata->dai_clk_names[i];
1899 if (IS_ERR(dai_clks)) { 2150 init.ops = &da7219_dai_clk_ops[i];
1900 dev_warn(dev, "Failed to register DAI clocks: %ld\n", 2151 init.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
1901 PTR_ERR(dai_clks)); 2152 dai_clk_hw->init = &init;
1902 return PTR_ERR(dai_clks); 2153
1903 } 2154 dai_clk = devm_clk_register(dev, dai_clk_hw);
1904 da7219->dai_clks = dai_clks; 2155 if (IS_ERR(dai_clk)) {
2156 dev_warn(dev, "Failed to register %s: %ld\n",
2157 init.name, PTR_ERR(dai_clk));
2158 ret = PTR_ERR(dai_clk);
2159 goto err;
2160 }
2161 da7219->dai_clks[i] = dai_clk;
1905 2162
1906 /* If we're using DT, then register as provider accordingly */ 2163 /* If we're using DT, then register as provider accordingly */
1907 if (dev->of_node) { 2164 if (dev->of_node) {
1908 devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, 2165 devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
1909 &da7219->dai_clks_hw); 2166 dai_clk_hw);
1910 } else { 2167 } else {
1911 dai_clks_lookup = clkdev_create(dai_clks, pdata->dai_clks_name, 2168 dai_clk_lookup = clkdev_create(dai_clk, init.name,
1912 "%s", dev_name(dev)); 2169 "%s", dev_name(dev));
1913 if (!dai_clks_lookup) 2170 if (!dai_clk_lookup) {
1914 return -ENOMEM; 2171 ret = -ENOMEM;
1915 else 2172 goto err;
1916 da7219->dai_clks_lookup = dai_clks_lookup; 2173 } else {
2174 da7219->dai_clks_lookup[i] = dai_clk_lookup;
2175 }
2176 }
1917 } 2177 }
1918 2178
1919 return 0; 2179 return 0;
2180
2181err:
2182 do {
2183 if (da7219->dai_clks_lookup[i])
2184 clkdev_drop(da7219->dai_clks_lookup[i]);
2185 } while (i-- > 0);
2186
2187 return ret;
1920} 2188}
1921#else 2189#else
1922static inline int da7219_register_dai_clks(struct snd_soc_component *component) 2190static inline int da7219_register_dai_clks(struct snd_soc_component *component)
@@ -2080,12 +2348,15 @@ err_disable_reg:
2080static void da7219_remove(struct snd_soc_component *component) 2348static void da7219_remove(struct snd_soc_component *component)
2081{ 2349{
2082 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 2350 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
2351 int i;
2083 2352
2084 da7219_aad_exit(component); 2353 da7219_aad_exit(component);
2085 2354
2086#ifdef CONFIG_COMMON_CLK 2355#ifdef CONFIG_COMMON_CLK
2087 if (da7219->dai_clks_lookup) 2356 for (i = DA7219_DAI_NUM_CLKS - 1; i >= 0; --i) {
2088 clkdev_drop(da7219->dai_clks_lookup); 2357 if (da7219->dai_clks_lookup[i])
2358 clkdev_drop(da7219->dai_clks_lookup[i]);
2359 }
2089#endif 2360#endif
2090 2361
2091 /* Supplies */ 2362 /* Supplies */
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index 018819c631fb..f3b180bc986f 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -820,10 +820,10 @@ struct da7219_priv {
820 struct mutex pll_lock; 820 struct mutex pll_lock;
821 821
822#ifdef CONFIG_COMMON_CLK 822#ifdef CONFIG_COMMON_CLK
823 struct clk_hw dai_clks_hw; 823 struct clk_hw dai_clks_hw[DA7219_DAI_NUM_CLKS];
824#endif 824#endif
825 struct clk_lookup *dai_clks_lookup; 825 struct clk_lookup *dai_clks_lookup[DA7219_DAI_NUM_CLKS];
826 struct clk *dai_clks; 826 struct clk *dai_clks[DA7219_DAI_NUM_CLKS];
827 827
828 struct clk *mclk; 828 struct clk *mclk;
829 unsigned int mclk_rate; 829 unsigned int mclk_rate;