aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-12-11 19:49:22 -0500
committerMark Brown <broonie@linaro.org>2013-12-17 06:34:39 -0500
commit3c43c69537daa044c61965fad24e24ad392c4166 (patch)
treea0157a0f9230500f6d79bc06db6827c0b535ea9c
parentd733dc0828cfb230171ae7420a6e8c344ec8473a (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.c163
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);
864static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 870static 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
1476static bool arizona_is_enabled_fll(struct arizona_fll *fll) 1490static 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,