diff options
author | Mark Brown <broonie@linaro.org> | 2013-12-11 19:49:22 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-17 06:34:39 -0500 |
commit | 3c43c69537daa044c61965fad24e24ad392c4166 (patch) | |
tree | a0157a0f9230500f6d79bc06db6827c0b535ea9c | |
parent | d733dc0828cfb230171ae7420a6e8c344ec8473a (diff) |
ASoC: arizona: Use async writes
Where possible write to the device asynchronously, allowing better
performance when used with a bus like SPI which supports this by
minimising the need to context switch back to the driver to get the
next bit of data.
Signed-off-by: Mark Brown <broonie@linaro.org>
Tested-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/codecs/arizona.c | 163 |
1 files changed, 89 insertions, 74 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index eb9f5d4d8928..6bfd8031c0c9 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -93,7 +93,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
93 | switch (event) { | 93 | switch (event) { |
94 | case SND_SOC_DAPM_PRE_PMU: | 94 | case SND_SOC_DAPM_PRE_PMU: |
95 | if (!priv->spk_ena && manual_ena) { | 95 | if (!priv->spk_ena && manual_ena) { |
96 | snd_soc_write(codec, 0x4f5, 0x25a); | 96 | regmap_write_async(arizona->regmap, 0x4f5, 0x25a); |
97 | priv->spk_ena_pending = true; | 97 | priv->spk_ena_pending = true; |
98 | } | 98 | } |
99 | break; | 99 | break; |
@@ -105,12 +105,13 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
105 | return -EBUSY; | 105 | return -EBUSY; |
106 | } | 106 | } |
107 | 107 | ||
108 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | 108 | regmap_update_bits_async(arizona->regmap, |
109 | 1 << w->shift, 1 << w->shift); | 109 | ARIZONA_OUTPUT_ENABLES_1, |
110 | 1 << w->shift, 1 << w->shift); | ||
110 | 111 | ||
111 | if (priv->spk_ena_pending) { | 112 | if (priv->spk_ena_pending) { |
112 | msleep(75); | 113 | msleep(75); |
113 | snd_soc_write(codec, 0x4f5, 0xda); | 114 | regmap_write_async(arizona->regmap, 0x4f5, 0xda); |
114 | priv->spk_ena_pending = false; | 115 | priv->spk_ena_pending = false; |
115 | priv->spk_ena++; | 116 | priv->spk_ena++; |
116 | } | 117 | } |
@@ -119,16 +120,19 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
119 | if (manual_ena) { | 120 | if (manual_ena) { |
120 | priv->spk_ena--; | 121 | priv->spk_ena--; |
121 | if (!priv->spk_ena) | 122 | if (!priv->spk_ena) |
122 | snd_soc_write(codec, 0x4f5, 0x25a); | 123 | regmap_write_async(arizona->regmap, |
124 | 0x4f5, 0x25a); | ||
123 | } | 125 | } |
124 | 126 | ||
125 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | 127 | regmap_update_bits_async(arizona->regmap, |
126 | 1 << w->shift, 0); | 128 | ARIZONA_OUTPUT_ENABLES_1, |
129 | 1 << w->shift, 0); | ||
127 | break; | 130 | break; |
128 | case SND_SOC_DAPM_POST_PMD: | 131 | case SND_SOC_DAPM_POST_PMD: |
129 | if (manual_ena) { | 132 | if (manual_ena) { |
130 | if (!priv->spk_ena) | 133 | if (!priv->spk_ena) |
131 | snd_soc_write(codec, 0x4f5, 0x0da); | 134 | regmap_write_async(arizona->regmap, |
135 | 0x4f5, 0x0da); | ||
132 | } | 136 | } |
133 | break; | 137 | break; |
134 | } | 138 | } |
@@ -687,6 +691,7 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
687 | int event) | 691 | int event) |
688 | { | 692 | { |
689 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | 693 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); |
694 | struct arizona *arizona = priv->arizona; | ||
690 | unsigned int mask = 1 << w->shift; | 695 | unsigned int mask = 1 << w->shift; |
691 | unsigned int val; | 696 | unsigned int val; |
692 | 697 | ||
@@ -709,7 +714,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
709 | if (priv->arizona->hpdet_magic) | 714 | if (priv->arizona->hpdet_magic) |
710 | val = 0; | 715 | val = 0; |
711 | 716 | ||
712 | snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val); | 717 | regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, |
718 | mask, val); | ||
713 | 719 | ||
714 | return arizona_out_ev(w, kcontrol, event); | 720 | return arizona_out_ev(w, kcontrol, event); |
715 | } | 721 | } |
@@ -864,6 +870,8 @@ EXPORT_SYMBOL_GPL(arizona_set_sysclk); | |||
864 | static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 870 | static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
865 | { | 871 | { |
866 | struct snd_soc_codec *codec = dai->codec; | 872 | struct snd_soc_codec *codec = dai->codec; |
873 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
874 | struct arizona *arizona = priv->arizona; | ||
867 | int lrclk, bclk, mode, base; | 875 | int lrclk, bclk, mode, base; |
868 | 876 | ||
869 | base = dai->driver->base; | 877 | base = dai->driver->base; |
@@ -920,17 +928,19 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
920 | return -EINVAL; | 928 | return -EINVAL; |
921 | } | 929 | } |
922 | 930 | ||
923 | snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, | 931 | regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL, |
924 | ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR, | 932 | ARIZONA_AIF1_BCLK_INV | |
925 | bclk); | 933 | ARIZONA_AIF1_BCLK_MSTR, |
926 | snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL, | 934 | bclk); |
927 | ARIZONA_AIF1TX_LRCLK_INV | | 935 | regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL, |
928 | ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); | 936 | ARIZONA_AIF1TX_LRCLK_INV | |
929 | snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL, | 937 | ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); |
930 | ARIZONA_AIF1RX_LRCLK_INV | | 938 | regmap_update_bits_async(arizona->regmap, |
931 | ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); | 939 | base + ARIZONA_AIF_RX_PIN_CTRL, |
932 | snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT, | 940 | ARIZONA_AIF1RX_LRCLK_INV | |
933 | ARIZONA_AIF1_FMT_MASK, mode); | 941 | ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); |
942 | regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT, | ||
943 | ARIZONA_AIF1_FMT_MASK, mode); | ||
934 | 944 | ||
935 | return 0; | 945 | return 0; |
936 | } | 946 | } |
@@ -1182,18 +1192,22 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
1182 | if (ret != 0) | 1192 | if (ret != 0) |
1183 | return ret; | 1193 | return ret; |
1184 | 1194 | ||
1185 | snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, | 1195 | regmap_update_bits_async(arizona->regmap, |
1186 | ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); | 1196 | base + ARIZONA_AIF_BCLK_CTRL, |
1187 | snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, | 1197 | ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); |
1188 | ARIZONA_AIF1TX_BCPF_MASK, lrclk); | 1198 | regmap_update_bits_async(arizona->regmap, |
1189 | snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, | 1199 | base + ARIZONA_AIF_TX_BCLK_RATE, |
1190 | ARIZONA_AIF1RX_BCPF_MASK, lrclk); | 1200 | ARIZONA_AIF1TX_BCPF_MASK, lrclk); |
1191 | snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, | 1201 | regmap_update_bits_async(arizona->regmap, |
1192 | ARIZONA_AIF1TX_WL_MASK | | 1202 | base + ARIZONA_AIF_RX_BCLK_RATE, |
1193 | ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); | 1203 | ARIZONA_AIF1RX_BCPF_MASK, lrclk); |
1194 | snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2, | 1204 | regmap_update_bits_async(arizona->regmap, |
1195 | ARIZONA_AIF1RX_WL_MASK | | 1205 | base + ARIZONA_AIF_FRAME_CTRL_1, |
1196 | ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); | 1206 | ARIZONA_AIF1TX_WL_MASK | |
1207 | ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); | ||
1208 | regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2, | ||
1209 | ARIZONA_AIF1RX_WL_MASK | | ||
1210 | ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); | ||
1197 | 1211 | ||
1198 | return 0; | 1212 | return 0; |
1199 | } | 1213 | } |
@@ -1446,31 +1460,31 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
1446 | struct arizona_fll_cfg *cfg, int source, | 1460 | struct arizona_fll_cfg *cfg, int source, |
1447 | bool sync) | 1461 | bool sync) |
1448 | { | 1462 | { |
1449 | regmap_update_bits(arizona->regmap, base + 3, | 1463 | regmap_update_bits_async(arizona->regmap, base + 3, |
1450 | ARIZONA_FLL1_THETA_MASK, cfg->theta); | 1464 | ARIZONA_FLL1_THETA_MASK, cfg->theta); |
1451 | regmap_update_bits(arizona->regmap, base + 4, | 1465 | regmap_update_bits_async(arizona->regmap, base + 4, |
1452 | ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); | 1466 | ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); |
1453 | regmap_update_bits(arizona->regmap, base + 5, | 1467 | regmap_update_bits_async(arizona->regmap, base + 5, |
1454 | ARIZONA_FLL1_FRATIO_MASK, | 1468 | ARIZONA_FLL1_FRATIO_MASK, |
1455 | cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); | 1469 | cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); |
1456 | regmap_update_bits(arizona->regmap, base + 6, | 1470 | regmap_update_bits_async(arizona->regmap, base + 6, |
1457 | ARIZONA_FLL1_CLK_REF_DIV_MASK | | 1471 | ARIZONA_FLL1_CLK_REF_DIV_MASK | |
1458 | ARIZONA_FLL1_CLK_REF_SRC_MASK, | 1472 | ARIZONA_FLL1_CLK_REF_SRC_MASK, |
1459 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | | 1473 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | |
1460 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); | 1474 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); |
1461 | 1475 | ||
1462 | if (sync) | 1476 | if (sync) |
1463 | regmap_update_bits(arizona->regmap, base + 0x7, | 1477 | regmap_update_bits_async(arizona->regmap, base + 0x7, |
1464 | ARIZONA_FLL1_GAIN_MASK, | 1478 | ARIZONA_FLL1_GAIN_MASK, |
1465 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1479 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); |
1466 | else | 1480 | else |
1467 | regmap_update_bits(arizona->regmap, base + 0x9, | 1481 | regmap_update_bits_async(arizona->regmap, base + 0x9, |
1468 | ARIZONA_FLL1_GAIN_MASK, | 1482 | ARIZONA_FLL1_GAIN_MASK, |
1469 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | 1483 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); |
1470 | 1484 | ||
1471 | regmap_update_bits(arizona->regmap, base + 2, | 1485 | regmap_update_bits_async(arizona->regmap, base + 2, |
1472 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, | 1486 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, |
1473 | ARIZONA_FLL1_CTRL_UPD | cfg->n); | 1487 | ARIZONA_FLL1_CTRL_UPD | cfg->n); |
1474 | } | 1488 | } |
1475 | 1489 | ||
1476 | static bool arizona_is_enabled_fll(struct arizona_fll *fll) | 1490 | static bool arizona_is_enabled_fll(struct arizona_fll *fll) |
@@ -1503,9 +1517,9 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1503 | */ | 1517 | */ |
1504 | if (fll->ref_src >= 0 && fll->ref_freq && | 1518 | if (fll->ref_src >= 0 && fll->ref_freq && |
1505 | fll->ref_src != fll->sync_src) { | 1519 | fll->ref_src != fll->sync_src) { |
1506 | regmap_update_bits(arizona->regmap, fll->base + 5, | 1520 | regmap_update_bits_async(arizona->regmap, fll->base + 5, |
1507 | ARIZONA_FLL1_OUTDIV_MASK, | 1521 | ARIZONA_FLL1_OUTDIV_MASK, |
1508 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | 1522 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); |
1509 | 1523 | ||
1510 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, | 1524 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, |
1511 | false); | 1525 | false); |
@@ -1515,15 +1529,15 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1515 | use_sync = true; | 1529 | use_sync = true; |
1516 | } | 1530 | } |
1517 | } else if (fll->sync_src >= 0) { | 1531 | } else if (fll->sync_src >= 0) { |
1518 | regmap_update_bits(arizona->regmap, fll->base + 5, | 1532 | regmap_update_bits_async(arizona->regmap, fll->base + 5, |
1519 | ARIZONA_FLL1_OUTDIV_MASK, | 1533 | ARIZONA_FLL1_OUTDIV_MASK, |
1520 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | 1534 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); |
1521 | 1535 | ||
1522 | arizona_apply_fll(arizona, fll->base, sync, | 1536 | arizona_apply_fll(arizona, fll->base, sync, |
1523 | fll->sync_src, false); | 1537 | fll->sync_src, false); |
1524 | 1538 | ||
1525 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1539 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
1526 | ARIZONA_FLL1_SYNC_ENA, 0); | 1540 | ARIZONA_FLL1_SYNC_ENA, 0); |
1527 | } else { | 1541 | } else { |
1528 | arizona_fll_err(fll, "No clocks provided\n"); | 1542 | arizona_fll_err(fll, "No clocks provided\n"); |
1529 | return; | 1543 | return; |
@@ -1534,11 +1548,12 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1534 | * sync source. | 1548 | * sync source. |
1535 | */ | 1549 | */ |
1536 | if (use_sync && fll->sync_freq > 100000) | 1550 | if (use_sync && fll->sync_freq > 100000) |
1537 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | 1551 | regmap_update_bits_async(arizona->regmap, fll->base + 0x17, |
1538 | ARIZONA_FLL1_SYNC_BW, 0); | 1552 | ARIZONA_FLL1_SYNC_BW, 0); |
1539 | else | 1553 | else |
1540 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | 1554 | regmap_update_bits_async(arizona->regmap, fll->base + 0x17, |
1541 | ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); | 1555 | ARIZONA_FLL1_SYNC_BW, |
1556 | ARIZONA_FLL1_SYNC_BW); | ||
1542 | 1557 | ||
1543 | if (!arizona_is_enabled_fll(fll)) | 1558 | if (!arizona_is_enabled_fll(fll)) |
1544 | pm_runtime_get(arizona->dev); | 1559 | pm_runtime_get(arizona->dev); |
@@ -1546,14 +1561,14 @@ static void arizona_enable_fll(struct arizona_fll *fll, | |||
1546 | /* Clear any pending completions */ | 1561 | /* Clear any pending completions */ |
1547 | try_wait_for_completion(&fll->ok); | 1562 | try_wait_for_completion(&fll->ok); |
1548 | 1563 | ||
1549 | regmap_update_bits(arizona->regmap, fll->base + 1, | 1564 | regmap_update_bits_async(arizona->regmap, fll->base + 1, |
1550 | ARIZONA_FLL1_FREERUN, 0); | 1565 | ARIZONA_FLL1_FREERUN, 0); |
1551 | regmap_update_bits(arizona->regmap, fll->base + 1, | 1566 | regmap_update_bits_async(arizona->regmap, fll->base + 1, |
1552 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | 1567 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); |
1553 | if (use_sync) | 1568 | if (use_sync) |
1554 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1569 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
1555 | ARIZONA_FLL1_SYNC_ENA, | 1570 | ARIZONA_FLL1_SYNC_ENA, |
1556 | ARIZONA_FLL1_SYNC_ENA); | 1571 | ARIZONA_FLL1_SYNC_ENA); |
1557 | 1572 | ||
1558 | ret = wait_for_completion_timeout(&fll->ok, | 1573 | ret = wait_for_completion_timeout(&fll->ok, |
1559 | msecs_to_jiffies(250)); | 1574 | msecs_to_jiffies(250)); |
@@ -1566,8 +1581,8 @@ static void arizona_disable_fll(struct arizona_fll *fll) | |||
1566 | struct arizona *arizona = fll->arizona; | 1581 | struct arizona *arizona = fll->arizona; |
1567 | bool change; | 1582 | bool change; |
1568 | 1583 | ||
1569 | regmap_update_bits(arizona->regmap, fll->base + 1, | 1584 | regmap_update_bits_async(arizona->regmap, fll->base + 1, |
1570 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); | 1585 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); |
1571 | regmap_update_bits_check(arizona->regmap, fll->base + 1, | 1586 | regmap_update_bits_check(arizona->regmap, fll->base + 1, |
1572 | ARIZONA_FLL1_ENA, 0, &change); | 1587 | ARIZONA_FLL1_ENA, 0, &change); |
1573 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1588 | regmap_update_bits(arizona->regmap, fll->base + 0x11, |