aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/arizona.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/arizona.c')
-rw-r--r--sound/soc/codecs/arizona.c325
1 files changed, 208 insertions, 117 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e4295fee8f13..29e198f57d4c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -53,6 +53,14 @@
53#define ARIZONA_AIF_RX_ENABLES 0x1A 53#define ARIZONA_AIF_RX_ENABLES 0x1A
54#define ARIZONA_AIF_FORCE_WRITE 0x1B 54#define ARIZONA_AIF_FORCE_WRITE 0x1B
55 55
56#define ARIZONA_FLL_VCO_CORNER 141900000
57#define ARIZONA_FLL_MAX_FREF 13500000
58#define ARIZONA_FLL_MIN_FVCO 90000000
59#define ARIZONA_FLL_MAX_FRATIO 16
60#define ARIZONA_FLL_MAX_REFDIV 8
61#define ARIZONA_FLL_MIN_OUTDIV 2
62#define ARIZONA_FLL_MAX_OUTDIV 7
63
56#define arizona_fll_err(_fll, fmt, ...) \ 64#define arizona_fll_err(_fll, fmt, ...) \
57 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 65 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58#define arizona_fll_warn(_fll, fmt, ...) \ 66#define arizona_fll_warn(_fll, fmt, ...) \
@@ -542,67 +550,76 @@ static const char *arizona_vol_ramp_text[] = {
542 "15ms/6dB", "30ms/6dB", 550 "15ms/6dB", "30ms/6dB",
543}; 551};
544 552
545const struct soc_enum arizona_in_vd_ramp = 553SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
546 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 554 ARIZONA_INPUT_VOLUME_RAMP,
547 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 555 ARIZONA_IN_VD_RAMP_SHIFT,
556 arizona_vol_ramp_text);
548EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); 557EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
549 558
550const struct soc_enum arizona_in_vi_ramp = 559SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
551 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 560 ARIZONA_INPUT_VOLUME_RAMP,
552 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 561 ARIZONA_IN_VI_RAMP_SHIFT,
562 arizona_vol_ramp_text);
553EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); 563EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
554 564
555const struct soc_enum arizona_out_vd_ramp = 565SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
556 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 566 ARIZONA_OUTPUT_VOLUME_RAMP,
557 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 567 ARIZONA_OUT_VD_RAMP_SHIFT,
568 arizona_vol_ramp_text);
558EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); 569EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
559 570
560const struct soc_enum arizona_out_vi_ramp = 571SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
561 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 572 ARIZONA_OUTPUT_VOLUME_RAMP,
562 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 573 ARIZONA_OUT_VI_RAMP_SHIFT,
574 arizona_vol_ramp_text);
563EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); 575EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
564 576
565static const char *arizona_lhpf_mode_text[] = { 577static const char *arizona_lhpf_mode_text[] = {
566 "Low-pass", "High-pass" 578 "Low-pass", "High-pass"
567}; 579};
568 580
569const struct soc_enum arizona_lhpf1_mode = 581SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
570 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, 582 ARIZONA_HPLPF1_1,
571 arizona_lhpf_mode_text); 583 ARIZONA_LHPF1_MODE_SHIFT,
584 arizona_lhpf_mode_text);
572EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); 585EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
573 586
574const struct soc_enum arizona_lhpf2_mode = 587SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
575 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, 588 ARIZONA_HPLPF2_1,
576 arizona_lhpf_mode_text); 589 ARIZONA_LHPF2_MODE_SHIFT,
590 arizona_lhpf_mode_text);
577EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); 591EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
578 592
579const struct soc_enum arizona_lhpf3_mode = 593SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
580 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, 594 ARIZONA_HPLPF3_1,
581 arizona_lhpf_mode_text); 595 ARIZONA_LHPF3_MODE_SHIFT,
596 arizona_lhpf_mode_text);
582EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 597EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
583 598
584const struct soc_enum arizona_lhpf4_mode = 599SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
585 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, 600 ARIZONA_HPLPF4_1,
586 arizona_lhpf_mode_text); 601 ARIZONA_LHPF4_MODE_SHIFT,
602 arizona_lhpf_mode_text);
587EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 603EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
588 604
589static const char *arizona_ng_hold_text[] = { 605static const char *arizona_ng_hold_text[] = {
590 "30ms", "120ms", "250ms", "500ms", 606 "30ms", "120ms", "250ms", "500ms",
591}; 607};
592 608
593const struct soc_enum arizona_ng_hold = 609SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
594 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, 610 ARIZONA_NOISE_GATE_CONTROL,
595 4, arizona_ng_hold_text); 611 ARIZONA_NGATE_HOLD_SHIFT,
612 arizona_ng_hold_text);
596EXPORT_SYMBOL_GPL(arizona_ng_hold); 613EXPORT_SYMBOL_GPL(arizona_ng_hold);
597 614
598static const char * const arizona_in_hpf_cut_text[] = { 615static const char * const arizona_in_hpf_cut_text[] = {
599 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" 616 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
600}; 617};
601 618
602const struct soc_enum arizona_in_hpf_cut_enum = 619SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
603 SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT, 620 ARIZONA_HPF_CONTROL,
604 ARRAY_SIZE(arizona_in_hpf_cut_text), 621 ARIZONA_IN_HPF_CUT_SHIFT,
605 arizona_in_hpf_cut_text); 622 arizona_in_hpf_cut_text);
606EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); 623EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
607 624
608static const char * const arizona_in_dmic_osr_text[] = { 625static const char * const arizona_in_dmic_osr_text[] = {
@@ -1377,74 +1394,147 @@ struct arizona_fll_cfg {
1377 int gain; 1394 int gain;
1378}; 1395};
1379 1396
1380static int arizona_calc_fll(struct arizona_fll *fll, 1397static int arizona_validate_fll(struct arizona_fll *fll,
1381 struct arizona_fll_cfg *cfg, 1398 unsigned int Fref,
1382 unsigned int Fref, 1399 unsigned int Fout)
1383 unsigned int Fout)
1384{ 1400{
1385 unsigned int target, div, gcd_fll; 1401 unsigned int Fvco_min;
1386 int i, ratio; 1402
1403 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
1404 arizona_fll_err(fll,
1405 "Can't scale %dMHz in to <=13.5MHz\n",
1406 Fref);
1407 return -EINVAL;
1408 }
1387 1409
1388 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); 1410 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
1411 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
1412 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1413 Fout);
1414 return -EINVAL;
1415 }
1416
1417 return 0;
1418}
1419
1420static int arizona_find_fratio(unsigned int Fref, int *fratio)
1421{
1422 int i;
1423
1424 /* Find an appropriate FLL_FRATIO */
1425 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1426 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1427 if (fratio)
1428 *fratio = fll_fratios[i].fratio;
1429 return fll_fratios[i].ratio;
1430 }
1431 }
1432
1433 return -EINVAL;
1434}
1435
1436static int arizona_calc_fratio(struct arizona_fll *fll,
1437 struct arizona_fll_cfg *cfg,
1438 unsigned int target,
1439 unsigned int Fref, bool sync)
1440{
1441 int init_ratio, ratio;
1442 int refdiv, div;
1389 1443
1390 /* Fref must be <=13.5MHz */ 1444 /* Fref must be <=13.5MHz, find initial refdiv */
1391 div = 1; 1445 div = 1;
1392 cfg->refdiv = 0; 1446 cfg->refdiv = 0;
1393 while ((Fref / div) > 13500000) { 1447 while (Fref > ARIZONA_FLL_MAX_FREF) {
1394 div *= 2; 1448 div *= 2;
1449 Fref /= 2;
1395 cfg->refdiv++; 1450 cfg->refdiv++;
1396 1451
1397 if (div > 8) { 1452 if (div > ARIZONA_FLL_MAX_REFDIV)
1398 arizona_fll_err(fll,
1399 "Can't scale %dMHz in to <=13.5MHz\n",
1400 Fref);
1401 return -EINVAL; 1453 return -EINVAL;
1454 }
1455
1456 /* Find an appropriate FLL_FRATIO */
1457 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
1458 if (init_ratio < 0) {
1459 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1460 Fref);
1461 return init_ratio;
1462 }
1463
1464 switch (fll->arizona->type) {
1465 case WM5110:
1466 if (fll->arizona->rev < 3 || sync)
1467 return init_ratio;
1468 break;
1469 default:
1470 return init_ratio;
1471 }
1472
1473 cfg->fratio = init_ratio - 1;
1474
1475 /* Adjust FRATIO/refdiv to avoid integer mode if possible */
1476 refdiv = cfg->refdiv;
1477
1478 while (div <= ARIZONA_FLL_MAX_REFDIV) {
1479 for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
1480 ratio++) {
1481 if (target % (ratio * Fref)) {
1482 cfg->refdiv = refdiv;
1483 cfg->fratio = ratio - 1;
1484 return ratio;
1485 }
1402 } 1486 }
1487
1488 for (ratio = init_ratio - 1; ratio >= 0; ratio--) {
1489 if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) <
1490 Fref)
1491 break;
1492
1493 if (target % (ratio * Fref)) {
1494 cfg->refdiv = refdiv;
1495 cfg->fratio = ratio - 1;
1496 return ratio;
1497 }
1498 }
1499
1500 div *= 2;
1501 Fref /= 2;
1502 refdiv++;
1503 init_ratio = arizona_find_fratio(Fref, NULL);
1403 } 1504 }
1404 1505
1405 /* Apply the division for our remaining calculations */ 1506 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
1406 Fref /= div; 1507 return cfg->fratio + 1;
1508}
1509
1510static int arizona_calc_fll(struct arizona_fll *fll,
1511 struct arizona_fll_cfg *cfg,
1512 unsigned int Fref, bool sync)
1513{
1514 unsigned int target, div, gcd_fll;
1515 int i, ratio;
1516
1517 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
1407 1518
1408 /* Fvco should be over the targt; don't check the upper bound */ 1519 /* Fvco should be over the targt; don't check the upper bound */
1409 div = 1; 1520 div = ARIZONA_FLL_MIN_OUTDIV;
1410 while (Fout * div < 90000000 * fll->vco_mult) { 1521 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
1411 div++; 1522 div++;
1412 if (div > 7) { 1523 if (div > ARIZONA_FLL_MAX_OUTDIV)
1413 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1414 Fout);
1415 return -EINVAL; 1524 return -EINVAL;
1416 }
1417 } 1525 }
1418 target = Fout * div / fll->vco_mult; 1526 target = fll->fout * div / fll->vco_mult;
1419 cfg->outdiv = div; 1527 cfg->outdiv = div;
1420 1528
1421 arizona_fll_dbg(fll, "Fvco=%dHz\n", target); 1529 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1422 1530
1423 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1531 /* Find an appropriate FLL_FRATIO and refdiv */
1424 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1532 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
1425 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1533 if (ratio < 0)
1426 cfg->fratio = fll_fratios[i].fratio; 1534 return ratio;
1427 ratio = fll_fratios[i].ratio;
1428 break;
1429 }
1430 }
1431 if (i == ARRAY_SIZE(fll_fratios)) {
1432 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1433 Fref);
1434 return -EINVAL;
1435 }
1436 1535
1437 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { 1536 /* Apply the division for our remaining calculations */
1438 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { 1537 Fref = Fref / (1 << cfg->refdiv);
1439 cfg->gain = fll_gains[i].gain;
1440 break;
1441 }
1442 }
1443 if (i == ARRAY_SIZE(fll_gains)) {
1444 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1445 Fref);
1446 return -EINVAL;
1447 }
1448 1538
1449 cfg->n = target / (ratio * Fref); 1539 cfg->n = target / (ratio * Fref);
1450 1540
@@ -1469,6 +1559,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
1469 cfg->lambda >>= 1; 1559 cfg->lambda >>= 1;
1470 } 1560 }
1471 1561
1562 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1563 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1564 cfg->gain = fll_gains[i].gain;
1565 break;
1566 }
1567 }
1568 if (i == ARRAY_SIZE(fll_gains)) {
1569 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1570 Fref);
1571 return -EINVAL;
1572 }
1573
1472 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 1574 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1473 cfg->n, cfg->theta, cfg->lambda); 1575 cfg->n, cfg->theta, cfg->lambda);
1474 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1576 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
@@ -1496,14 +1598,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1496 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1598 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1497 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1599 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1498 1600
1499 if (sync) 1601 if (sync) {
1500 regmap_update_bits_async(arizona->regmap, base + 0x7, 1602 regmap_update_bits(arizona->regmap, base + 0x7,
1501 ARIZONA_FLL1_GAIN_MASK, 1603 ARIZONA_FLL1_GAIN_MASK,
1502 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1604 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1503 else 1605 } else {
1504 regmap_update_bits_async(arizona->regmap, base + 0x9, 1606 regmap_update_bits(arizona->regmap, base + 0x5,
1505 ARIZONA_FLL1_GAIN_MASK, 1607 ARIZONA_FLL1_OUTDIV_MASK,
1506 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1608 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1609 regmap_update_bits(arizona->regmap, base + 0x9,
1610 ARIZONA_FLL1_GAIN_MASK,
1611 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1612 }
1507 1613
1508 regmap_update_bits_async(arizona->regmap, base + 2, 1614 regmap_update_bits_async(arizona->regmap, base + 2,
1509 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1615 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
@@ -1526,13 +1632,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1526 return reg & ARIZONA_FLL1_ENA; 1632 return reg & ARIZONA_FLL1_ENA;
1527} 1633}
1528 1634
1529static void arizona_enable_fll(struct arizona_fll *fll, 1635static void arizona_enable_fll(struct arizona_fll *fll)
1530 struct arizona_fll_cfg *ref,
1531 struct arizona_fll_cfg *sync)
1532{ 1636{
1533 struct arizona *arizona = fll->arizona; 1637 struct arizona *arizona = fll->arizona;
1534 int ret; 1638 int ret;
1535 bool use_sync = false; 1639 bool use_sync = false;
1640 struct arizona_fll_cfg cfg;
1536 1641
1537 /* 1642 /*
1538 * If we have both REFCLK and SYNCCLK then enable both, 1643 * If we have both REFCLK and SYNCCLK then enable both,
@@ -1540,23 +1645,21 @@ static void arizona_enable_fll(struct arizona_fll *fll,
1540 */ 1645 */
1541 if (fll->ref_src >= 0 && fll->ref_freq && 1646 if (fll->ref_src >= 0 && fll->ref_freq &&
1542 fll->ref_src != fll->sync_src) { 1647 fll->ref_src != fll->sync_src) {
1543 regmap_update_bits_async(arizona->regmap, fll->base + 5, 1648 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
1544 ARIZONA_FLL1_OUTDIV_MASK,
1545 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1546 1649
1547 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, 1650 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
1548 false); 1651 false);
1549 if (fll->sync_src >= 0) { 1652 if (fll->sync_src >= 0) {
1550 arizona_apply_fll(arizona, fll->base + 0x10, sync, 1653 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
1654
1655 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
1551 fll->sync_src, true); 1656 fll->sync_src, true);
1552 use_sync = true; 1657 use_sync = true;
1553 } 1658 }
1554 } else if (fll->sync_src >= 0) { 1659 } else if (fll->sync_src >= 0) {
1555 regmap_update_bits_async(arizona->regmap, fll->base + 5, 1660 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
1556 ARIZONA_FLL1_OUTDIV_MASK,
1557 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1558 1661
1559 arizona_apply_fll(arizona, fll->base, sync, 1662 arizona_apply_fll(arizona, fll->base, &cfg,
1560 fll->sync_src, false); 1663 fll->sync_src, false);
1561 1664
1562 regmap_update_bits_async(arizona->regmap, fll->base + 0x11, 1665 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
@@ -1618,32 +1721,22 @@ static void arizona_disable_fll(struct arizona_fll *fll)
1618int arizona_set_fll_refclk(struct arizona_fll *fll, int source, 1721int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1619 unsigned int Fref, unsigned int Fout) 1722 unsigned int Fref, unsigned int Fout)
1620{ 1723{
1621 struct arizona_fll_cfg ref, sync;
1622 int ret; 1724 int ret;
1623 1725
1624 if (fll->ref_src == source && fll->ref_freq == Fref) 1726 if (fll->ref_src == source && fll->ref_freq == Fref)
1625 return 0; 1727 return 0;
1626 1728
1627 if (fll->fout) { 1729 if (fll->fout && Fref > 0) {
1628 if (Fref > 0) { 1730 ret = arizona_validate_fll(fll, Fref, fll->fout);
1629 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); 1731 if (ret != 0)
1630 if (ret != 0) 1732 return ret;
1631 return ret;
1632 }
1633
1634 if (fll->sync_src >= 0) {
1635 ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1636 fll->fout);
1637 if (ret != 0)
1638 return ret;
1639 }
1640 } 1733 }
1641 1734
1642 fll->ref_src = source; 1735 fll->ref_src = source;
1643 fll->ref_freq = Fref; 1736 fll->ref_freq = Fref;
1644 1737
1645 if (fll->fout && Fref > 0) { 1738 if (fll->fout && Fref > 0) {
1646 arizona_enable_fll(fll, &ref, &sync); 1739 arizona_enable_fll(fll);
1647 } 1740 }
1648 1741
1649 return 0; 1742 return 0;
@@ -1653,7 +1746,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1653int arizona_set_fll(struct arizona_fll *fll, int source, 1746int arizona_set_fll(struct arizona_fll *fll, int source,
1654 unsigned int Fref, unsigned int Fout) 1747 unsigned int Fref, unsigned int Fout)
1655{ 1748{
1656 struct arizona_fll_cfg ref, sync;
1657 int ret; 1749 int ret;
1658 1750
1659 if (fll->sync_src == source && 1751 if (fll->sync_src == source &&
@@ -1662,13 +1754,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1662 1754
1663 if (Fout) { 1755 if (Fout) {
1664 if (fll->ref_src >= 0) { 1756 if (fll->ref_src >= 0) {
1665 ret = arizona_calc_fll(fll, &ref, fll->ref_freq, 1757 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
1666 Fout);
1667 if (ret != 0) 1758 if (ret != 0)
1668 return ret; 1759 return ret;
1669 } 1760 }
1670 1761
1671 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1762 ret = arizona_validate_fll(fll, Fref, Fout);
1672 if (ret != 0) 1763 if (ret != 0)
1673 return ret; 1764 return ret;
1674 } 1765 }
@@ -1678,7 +1769,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
1678 fll->fout = Fout; 1769 fll->fout = Fout;
1679 1770
1680 if (Fout) { 1771 if (Fout) {
1681 arizona_enable_fll(fll, &ref, &sync); 1772 arizona_enable_fll(fll);
1682 } else { 1773 } else {
1683 arizona_disable_fll(fll); 1774 arizona_disable_fll(fll);
1684 } 1775 }