diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/pcm512x.txt | 25 | ||||
| -rw-r--r-- | sound/soc/codecs/pcm512x.c | 458 | ||||
| -rw-r--r-- | sound/soc/codecs/pcm512x.h | 44 |
3 files changed, 501 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/sound/pcm512x.txt b/Documentation/devicetree/bindings/sound/pcm512x.txt index 98e0d34915e8..3aae3b41bd8e 100644 --- a/Documentation/devicetree/bindings/sound/pcm512x.txt +++ b/Documentation/devicetree/bindings/sound/pcm512x.txt | |||
| @@ -17,9 +17,16 @@ Required properties: | |||
| 17 | Optional properties: | 17 | Optional properties: |
| 18 | 18 | ||
| 19 | - clocks : A clock specifier for the clock connected as SCLK. If this | 19 | - clocks : A clock specifier for the clock connected as SCLK. If this |
| 20 | is absent the device will be configured to clock from BCLK. | 20 | is absent the device will be configured to clock from BCLK. If pll-in |
| 21 | and pll-out are specified in addition to a clock, the device is | ||
| 22 | configured to accept clock input on a specified gpio pin. | ||
| 21 | 23 | ||
| 22 | Example: | 24 | - pll-in, pll-out : gpio pins used to connect the pll using <1> |
| 25 | through <6>. The device will be configured for clock input on the | ||
| 26 | given pll-in pin and PLL output on the given pll-out pin. An | ||
| 27 | external connection from the pll-out pin to the SCLK pin is assumed. | ||
| 28 | |||
| 29 | Examples: | ||
| 23 | 30 | ||
| 24 | pcm5122: pcm5122@4c { | 31 | pcm5122: pcm5122@4c { |
| 25 | compatible = "ti,pcm5122"; | 32 | compatible = "ti,pcm5122"; |
| @@ -29,3 +36,17 @@ Example: | |||
| 29 | DVDD-supply = <®_1v8>; | 36 | DVDD-supply = <®_1v8>; |
| 30 | CPVDD-supply = <®_3v3>; | 37 | CPVDD-supply = <®_3v3>; |
| 31 | }; | 38 | }; |
| 39 | |||
| 40 | |||
| 41 | pcm5142: pcm5142@4c { | ||
| 42 | compatible = "ti,pcm5142"; | ||
| 43 | reg = <0x4c>; | ||
| 44 | |||
| 45 | AVDD-supply = <®_3v3_analog>; | ||
| 46 | DVDD-supply = <®_1v8>; | ||
| 47 | CPVDD-supply = <®_3v3>; | ||
| 48 | |||
| 49 | clocks = <&sck>; | ||
| 50 | pll-in = <3>; | ||
| 51 | pll-out = <6>; | ||
| 52 | }; | ||
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 526e6b30cdde..66dd036f0141 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
| 22 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
| 23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
| 24 | #include <linux/gcd.h> | ||
| 24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
| 25 | #include <sound/soc-dapm.h> | 26 | #include <sound/soc-dapm.h> |
| 26 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
| @@ -28,6 +29,11 @@ | |||
| 28 | 29 | ||
| 29 | #include "pcm512x.h" | 30 | #include "pcm512x.h" |
| 30 | 31 | ||
| 32 | #define DIV_ROUND_DOWN_ULL(ll, d) \ | ||
| 33 | ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) | ||
| 34 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
| 35 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
| 36 | |||
| 31 | #define PCM512x_NUM_SUPPLIES 3 | 37 | #define PCM512x_NUM_SUPPLIES 3 |
| 32 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { | 38 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { |
| 33 | "AVDD", | 39 | "AVDD", |
| @@ -41,6 +47,13 @@ struct pcm512x_priv { | |||
| 41 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; | 47 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; |
| 42 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; | 48 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; |
| 43 | int fmt; | 49 | int fmt; |
| 50 | int pll_in; | ||
| 51 | int pll_out; | ||
| 52 | int pll_r; | ||
| 53 | int pll_j; | ||
| 54 | int pll_d; | ||
| 55 | int pll_p; | ||
| 56 | unsigned long real_pll; | ||
| 44 | }; | 57 | }; |
| 45 | 58 | ||
| 46 | /* | 59 | /* |
| @@ -92,7 +105,13 @@ static const struct reg_default pcm512x_reg_defaults[] = { | |||
| 92 | { PCM512x_VCOM_CTRL_2, 0x01 }, | 105 | { PCM512x_VCOM_CTRL_2, 0x01 }, |
| 93 | { PCM512x_BCLK_LRCLK_CFG, 0x00 }, | 106 | { PCM512x_BCLK_LRCLK_CFG, 0x00 }, |
| 94 | { PCM512x_MASTER_MODE, 0x7c }, | 107 | { PCM512x_MASTER_MODE, 0x7c }, |
| 108 | { PCM512x_GPIO_PLLIN, 0x00 }, | ||
| 95 | { PCM512x_SYNCHRONIZE, 0x10 }, | 109 | { PCM512x_SYNCHRONIZE, 0x10 }, |
| 110 | { PCM512x_PLL_COEFF_0, 0x00 }, | ||
| 111 | { PCM512x_PLL_COEFF_1, 0x00 }, | ||
| 112 | { PCM512x_PLL_COEFF_2, 0x00 }, | ||
| 113 | { PCM512x_PLL_COEFF_3, 0x00 }, | ||
| 114 | { PCM512x_PLL_COEFF_4, 0x00 }, | ||
| 96 | { PCM512x_DSP_CLKDIV, 0x00 }, | 115 | { PCM512x_DSP_CLKDIV, 0x00 }, |
| 97 | { PCM512x_DAC_CLKDIV, 0x00 }, | 116 | { PCM512x_DAC_CLKDIV, 0x00 }, |
| 98 | { PCM512x_NCP_CLKDIV, 0x00 }, | 117 | { PCM512x_NCP_CLKDIV, 0x00 }, |
| @@ -119,6 +138,7 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
| 119 | case PCM512x_MASTER_MODE: | 138 | case PCM512x_MASTER_MODE: |
| 120 | case PCM512x_PLL_REF: | 139 | case PCM512x_PLL_REF: |
| 121 | case PCM512x_DAC_REF: | 140 | case PCM512x_DAC_REF: |
| 141 | case PCM512x_GPIO_PLLIN: | ||
| 122 | case PCM512x_SYNCHRONIZE: | 142 | case PCM512x_SYNCHRONIZE: |
| 123 | case PCM512x_PLL_COEFF_0: | 143 | case PCM512x_PLL_COEFF_0: |
| 124 | case PCM512x_PLL_COEFF_1: | 144 | case PCM512x_PLL_COEFF_1: |
| @@ -160,6 +180,7 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
| 160 | case PCM512x_RATE_DET_2: | 180 | case PCM512x_RATE_DET_2: |
| 161 | case PCM512x_RATE_DET_3: | 181 | case PCM512x_RATE_DET_3: |
| 162 | case PCM512x_RATE_DET_4: | 182 | case PCM512x_RATE_DET_4: |
| 183 | case PCM512x_CLOCK_STATUS: | ||
| 163 | case PCM512x_ANALOG_MUTE_DET: | 184 | case PCM512x_ANALOG_MUTE_DET: |
| 164 | case PCM512x_GPIN: | 185 | case PCM512x_GPIN: |
| 165 | case PCM512x_DIGITAL_MUTE_DET: | 186 | case PCM512x_DIGITAL_MUTE_DET: |
| @@ -171,6 +192,8 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
| 171 | case PCM512x_VCOM_CTRL_1: | 192 | case PCM512x_VCOM_CTRL_1: |
| 172 | case PCM512x_VCOM_CTRL_2: | 193 | case PCM512x_VCOM_CTRL_2: |
| 173 | case PCM512x_CRAM_CTRL: | 194 | case PCM512x_CRAM_CTRL: |
| 195 | case PCM512x_FLEX_A: | ||
| 196 | case PCM512x_FLEX_B: | ||
| 174 | return true; | 197 | return true; |
| 175 | default: | 198 | default: |
| 176 | /* There are 256 raw register addresses */ | 199 | /* There are 256 raw register addresses */ |
| @@ -187,6 +210,7 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg) | |||
| 187 | case PCM512x_RATE_DET_2: | 210 | case PCM512x_RATE_DET_2: |
| 188 | case PCM512x_RATE_DET_3: | 211 | case PCM512x_RATE_DET_3: |
| 189 | case PCM512x_RATE_DET_4: | 212 | case PCM512x_RATE_DET_4: |
| 213 | case PCM512x_CLOCK_STATUS: | ||
| 190 | case PCM512x_ANALOG_MUTE_DET: | 214 | case PCM512x_ANALOG_MUTE_DET: |
| 191 | case PCM512x_GPIN: | 215 | case PCM512x_GPIN: |
| 192 | case PCM512x_DIGITAL_MUTE_DET: | 216 | case PCM512x_DIGITAL_MUTE_DET: |
| @@ -330,6 +354,38 @@ static const struct snd_pcm_hw_constraint_list constraints_slave = { | |||
| 330 | .list = pcm512x_dai_rates, | 354 | .list = pcm512x_dai_rates, |
| 331 | }; | 355 | }; |
| 332 | 356 | ||
| 357 | static const struct snd_interval pcm512x_dai_ranges_64bpf[] = { | ||
| 358 | { | ||
| 359 | .min = 8000, | ||
| 360 | .max = 195312, | ||
| 361 | }, { | ||
| 362 | .min = 250000, | ||
| 363 | .max = 390625, | ||
| 364 | }, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static struct snd_pcm_hw_constraint_ranges constraints_64bpf = { | ||
| 368 | .count = ARRAY_SIZE(pcm512x_dai_ranges_64bpf), | ||
| 369 | .ranges = pcm512x_dai_ranges_64bpf, | ||
| 370 | }; | ||
| 371 | |||
| 372 | static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params, | ||
| 373 | struct snd_pcm_hw_rule *rule) | ||
| 374 | { | ||
| 375 | struct snd_pcm_hw_constraint_ranges *r = rule->private; | ||
| 376 | int frame_size; | ||
| 377 | |||
| 378 | frame_size = snd_soc_params_to_frame_size(params); | ||
| 379 | if (frame_size < 0) | ||
| 380 | return frame_size; | ||
| 381 | |||
| 382 | if (frame_size != 64) | ||
| 383 | return 0; | ||
| 384 | |||
| 385 | return snd_interval_ranges(hw_param_interval(params, rule->var), | ||
| 386 | r->count, r->ranges, r->mask); | ||
| 387 | } | ||
| 388 | |||
| 333 | static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream, | 389 | static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream, |
| 334 | struct snd_soc_dai *dai) | 390 | struct snd_soc_dai *dai) |
| 335 | { | 391 | { |
| @@ -345,6 +401,14 @@ static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream, | |||
| 345 | return PTR_ERR(pcm512x->sclk); | 401 | return PTR_ERR(pcm512x->sclk); |
| 346 | } | 402 | } |
| 347 | 403 | ||
| 404 | if (pcm512x->pll_out) | ||
| 405 | return snd_pcm_hw_rule_add(substream->runtime, 0, | ||
| 406 | SNDRV_PCM_HW_PARAM_RATE, | ||
| 407 | pcm512x_hw_rule_rate, | ||
| 408 | (void *)&constraints_64bpf, | ||
| 409 | SNDRV_PCM_HW_PARAM_FRAME_BITS, | ||
| 410 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
| 411 | |||
| 348 | constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll), | 412 | constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll), |
| 349 | GFP_KERNEL); | 413 | GFP_KERNEL); |
| 350 | if (!constraints_no_pll) | 414 | if (!constraints_no_pll) |
| @@ -445,12 +509,164 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | |||
| 445 | return 0; | 509 | return 0; |
| 446 | } | 510 | } |
| 447 | 511 | ||
| 512 | static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai, | ||
| 513 | unsigned long bclk_rate) | ||
| 514 | { | ||
| 515 | struct device *dev = dai->dev; | ||
| 516 | unsigned long sck_rate; | ||
| 517 | int pow2; | ||
| 518 | |||
| 519 | /* 64 MHz <= pll_rate <= 100 MHz, VREF mode */ | ||
| 520 | /* 16 MHz <= sck_rate <= 25 MHz, VREF mode */ | ||
| 521 | |||
| 522 | /* select sck_rate as a multiple of bclk_rate but still with | ||
| 523 | * as many factors of 2 as possible, as that makes it easier | ||
| 524 | * to find a fast DAC rate | ||
| 525 | */ | ||
| 526 | pow2 = 1 << fls((25000000 - 16000000) / bclk_rate); | ||
| 527 | for (; pow2; pow2 >>= 1) { | ||
| 528 | sck_rate = rounddown(25000000, bclk_rate * pow2); | ||
| 529 | if (sck_rate >= 16000000) | ||
| 530 | break; | ||
| 531 | } | ||
| 532 | if (!pow2) { | ||
| 533 | dev_err(dev, "Impossible to generate a suitable SCK\n"); | ||
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | dev_dbg(dev, "sck_rate %lu\n", sck_rate); | ||
| 538 | return sck_rate; | ||
| 539 | } | ||
| 540 | |||
| 541 | /* pll_rate = pllin_rate * R * J.D / P | ||
| 542 | * 1 <= R <= 16 | ||
| 543 | * 1 <= J <= 63 | ||
| 544 | * 0 <= D <= 9999 | ||
| 545 | * 1 <= P <= 15 | ||
| 546 | * 64 MHz <= pll_rate <= 100 MHz | ||
| 547 | * if D == 0 | ||
| 548 | * 1 MHz <= pllin_rate / P <= 20 MHz | ||
| 549 | * else if D > 0 | ||
| 550 | * 6.667 MHz <= pllin_rate / P <= 20 MHz | ||
| 551 | * 4 <= J <= 11 | ||
| 552 | * R = 1 | ||
| 553 | */ | ||
| 554 | static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai, | ||
| 555 | unsigned long pllin_rate, | ||
| 556 | unsigned long pll_rate) | ||
| 557 | { | ||
| 558 | struct device *dev = dai->dev; | ||
| 559 | struct snd_soc_codec *codec = dai->codec; | ||
| 560 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
| 561 | unsigned long common; | ||
| 562 | int R, J, D, P; | ||
| 563 | unsigned long K; /* 10000 * J.D */ | ||
| 564 | unsigned long num; | ||
| 565 | unsigned long den; | ||
| 566 | |||
| 567 | common = gcd(pll_rate, pllin_rate); | ||
| 568 | dev_dbg(dev, "pll %lu pllin %lu common %lu\n", | ||
| 569 | pll_rate, pllin_rate, common); | ||
| 570 | num = pll_rate / common; | ||
| 571 | den = pllin_rate / common; | ||
| 572 | |||
| 573 | /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */ | ||
| 574 | if (pllin_rate / den > 20000000 && num < 8) { | ||
| 575 | num *= 20000000 / (pllin_rate / den); | ||
| 576 | den *= 20000000 / (pllin_rate / den); | ||
| 577 | } | ||
| 578 | dev_dbg(dev, "num / den = %lu / %lu\n", num, den); | ||
| 579 | |||
| 580 | P = den; | ||
| 581 | if (den <= 15 && num <= 16 * 63 | ||
| 582 | && 1000000 <= pllin_rate / P && pllin_rate / P <= 20000000) { | ||
| 583 | /* Try the case with D = 0 */ | ||
| 584 | D = 0; | ||
| 585 | /* factor 'num' into J and R, such that R <= 16 and J <= 63 */ | ||
| 586 | for (R = 16; R; R--) { | ||
| 587 | if (num % R) | ||
| 588 | continue; | ||
| 589 | J = num / R; | ||
| 590 | if (J == 0 || J > 63) | ||
| 591 | continue; | ||
| 592 | |||
| 593 | dev_dbg(dev, "R * J / P = %d * %d / %d\n", R, J, P); | ||
| 594 | pcm512x->real_pll = pll_rate; | ||
| 595 | goto done; | ||
| 596 | } | ||
| 597 | /* no luck */ | ||
| 598 | } | ||
| 599 | |||
| 600 | R = 1; | ||
| 601 | |||
| 602 | if (num > 0xffffffffUL / 10000) | ||
| 603 | goto fallback; | ||
| 604 | |||
| 605 | /* Try to find an exact pll_rate using the D > 0 case */ | ||
| 606 | common = gcd(10000 * num, den); | ||
| 607 | num = 10000 * num / common; | ||
| 608 | den /= common; | ||
| 609 | dev_dbg(dev, "num %lu den %lu common %lu\n", num, den, common); | ||
| 610 | |||
| 611 | for (P = den; P <= 15; P++) { | ||
| 612 | if (pllin_rate / P < 6667000 || 200000000 < pllin_rate / P) | ||
| 613 | continue; | ||
| 614 | if (num * P % den) | ||
| 615 | continue; | ||
| 616 | K = num * P / den; | ||
| 617 | /* J == 12 is ok if D == 0 */ | ||
| 618 | if (K < 40000 || K > 120000) | ||
| 619 | continue; | ||
| 620 | |||
| 621 | J = K / 10000; | ||
| 622 | D = K % 10000; | ||
| 623 | dev_dbg(dev, "J.D / P = %d.%04d / %d\n", J, D, P); | ||
| 624 | pcm512x->real_pll = pll_rate; | ||
| 625 | goto done; | ||
| 626 | } | ||
| 627 | |||
| 628 | /* Fall back to an approximate pll_rate */ | ||
| 629 | |||
| 630 | fallback: | ||
| 631 | /* find smallest possible P */ | ||
| 632 | P = DIV_ROUND_UP(pllin_rate, 20000000); | ||
| 633 | if (!P) | ||
| 634 | P = 1; | ||
| 635 | else if (P > 15) { | ||
| 636 | dev_err(dev, "Need a slower clock as pll-input\n"); | ||
| 637 | return -EINVAL; | ||
| 638 | } | ||
| 639 | if (pllin_rate / P < 6667000) { | ||
| 640 | dev_err(dev, "Need a faster clock as pll-input\n"); | ||
| 641 | return -EINVAL; | ||
| 642 | } | ||
| 643 | K = DIV_ROUND_CLOSEST_ULL(10000ULL * pll_rate * P, pllin_rate); | ||
| 644 | if (K < 40000) | ||
| 645 | K = 40000; | ||
| 646 | /* J == 12 is ok if D == 0 */ | ||
| 647 | if (K > 120000) | ||
| 648 | K = 120000; | ||
| 649 | J = K / 10000; | ||
| 650 | D = K % 10000; | ||
| 651 | dev_dbg(dev, "J.D / P ~ %d.%04d / %d\n", J, D, P); | ||
| 652 | pcm512x->real_pll = DIV_ROUND_DOWN_ULL((u64)K * pllin_rate, 10000 * P); | ||
| 653 | |||
| 654 | done: | ||
| 655 | pcm512x->pll_r = R; | ||
| 656 | pcm512x->pll_j = J; | ||
| 657 | pcm512x->pll_d = D; | ||
| 658 | pcm512x->pll_p = P; | ||
| 659 | return 0; | ||
| 660 | } | ||
| 661 | |||
| 448 | static int pcm512x_set_dividers(struct snd_soc_dai *dai, | 662 | static int pcm512x_set_dividers(struct snd_soc_dai *dai, |
| 449 | struct snd_pcm_hw_params *params) | 663 | struct snd_pcm_hw_params *params) |
| 450 | { | 664 | { |
| 451 | struct device *dev = dai->dev; | 665 | struct device *dev = dai->dev; |
| 452 | struct snd_soc_codec *codec = dai->codec; | 666 | struct snd_soc_codec *codec = dai->codec; |
| 453 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | 667 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); |
| 668 | unsigned long pllin_rate = 0; | ||
| 669 | unsigned long pll_rate; | ||
| 454 | unsigned long sck_rate; | 670 | unsigned long sck_rate; |
| 455 | unsigned long mck_rate; | 671 | unsigned long mck_rate; |
| 456 | unsigned long bclk_rate; | 672 | unsigned long bclk_rate; |
| @@ -475,11 +691,74 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, | |||
| 475 | return -EINVAL; | 691 | return -EINVAL; |
| 476 | } | 692 | } |
| 477 | 693 | ||
| 478 | sck_rate = clk_get_rate(pcm512x->sclk); | 694 | if (!pcm512x->pll_out) { |
| 479 | bclk_div = params->rate_den * 64 / lrclk_div; | 695 | sck_rate = clk_get_rate(pcm512x->sclk); |
| 480 | bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div); | 696 | bclk_div = params->rate_den * 64 / lrclk_div; |
| 697 | bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div); | ||
| 481 | 698 | ||
| 482 | mck_rate = sck_rate; | 699 | mck_rate = sck_rate; |
| 700 | } else { | ||
| 701 | ret = snd_soc_params_to_bclk(params); | ||
| 702 | if (ret < 0) { | ||
| 703 | dev_err(dev, "Failed to find suitable BCLK: %d\n", ret); | ||
| 704 | return ret; | ||
| 705 | } | ||
| 706 | if (ret == 0) { | ||
| 707 | dev_err(dev, "No BCLK?\n"); | ||
| 708 | return -EINVAL; | ||
| 709 | } | ||
| 710 | bclk_rate = ret; | ||
| 711 | |||
| 712 | pllin_rate = clk_get_rate(pcm512x->sclk); | ||
| 713 | |||
| 714 | sck_rate = pcm512x_find_sck(dai, bclk_rate); | ||
| 715 | if (!sck_rate) | ||
| 716 | return -EINVAL; | ||
| 717 | pll_rate = 4 * sck_rate; | ||
| 718 | |||
| 719 | ret = pcm512x_find_pll_coeff(dai, pllin_rate, pll_rate); | ||
| 720 | if (ret != 0) | ||
| 721 | return ret; | ||
| 722 | |||
| 723 | ret = regmap_write(pcm512x->regmap, | ||
| 724 | PCM512x_PLL_COEFF_0, pcm512x->pll_p - 1); | ||
| 725 | if (ret != 0) { | ||
| 726 | dev_err(dev, "Failed to write PLL P: %d\n", ret); | ||
| 727 | return ret; | ||
| 728 | } | ||
| 729 | |||
| 730 | ret = regmap_write(pcm512x->regmap, | ||
| 731 | PCM512x_PLL_COEFF_1, pcm512x->pll_j); | ||
| 732 | if (ret != 0) { | ||
| 733 | dev_err(dev, "Failed to write PLL J: %d\n", ret); | ||
| 734 | return ret; | ||
| 735 | } | ||
| 736 | |||
| 737 | ret = regmap_write(pcm512x->regmap, | ||
| 738 | PCM512x_PLL_COEFF_2, pcm512x->pll_d >> 8); | ||
| 739 | if (ret != 0) { | ||
| 740 | dev_err(dev, "Failed to write PLL D msb: %d\n", ret); | ||
| 741 | return ret; | ||
| 742 | } | ||
| 743 | |||
| 744 | ret = regmap_write(pcm512x->regmap, | ||
| 745 | PCM512x_PLL_COEFF_3, pcm512x->pll_d & 0xff); | ||
| 746 | if (ret != 0) { | ||
| 747 | dev_err(dev, "Failed to write PLL D lsb: %d\n", ret); | ||
| 748 | return ret; | ||
| 749 | } | ||
| 750 | |||
| 751 | ret = regmap_write(pcm512x->regmap, | ||
| 752 | PCM512x_PLL_COEFF_4, pcm512x->pll_r - 1); | ||
| 753 | if (ret != 0) { | ||
| 754 | dev_err(dev, "Failed to write PLL R: %d\n", ret); | ||
| 755 | return ret; | ||
| 756 | } | ||
| 757 | |||
| 758 | mck_rate = pcm512x->real_pll; | ||
| 759 | |||
| 760 | bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate); | ||
| 761 | } | ||
| 483 | 762 | ||
| 484 | if (bclk_div > 128) { | 763 | if (bclk_div > 128) { |
| 485 | dev_err(dev, "Failed to find BCLK divider\n"); | 764 | dev_err(dev, "Failed to find BCLK divider\n"); |
| @@ -616,6 +895,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream, | |||
| 616 | struct snd_soc_codec *codec = dai->codec; | 895 | struct snd_soc_codec *codec = dai->codec; |
| 617 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | 896 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); |
| 618 | int alen; | 897 | int alen; |
| 898 | int gpio; | ||
| 619 | int ret; | 899 | int ret; |
| 620 | 900 | ||
| 621 | dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n", | 901 | dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n", |
| @@ -676,26 +956,55 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream, | |||
| 676 | return ret; | 956 | return ret; |
| 677 | } | 957 | } |
| 678 | 958 | ||
| 679 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | 959 | if (pcm512x->pll_out) { |
| 680 | PCM512x_IDFS | PCM512x_IDBK | 960 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11); |
| 681 | | PCM512x_IDSK | PCM512x_IDCH | 961 | if (ret != 0) { |
| 682 | | PCM512x_IDCM | PCM512x_DCAS | 962 | dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret); |
| 683 | | PCM512x_IPLK, | 963 | return ret; |
| 684 | PCM512x_IDFS | PCM512x_IDBK | 964 | } |
| 685 | | PCM512x_IDSK | PCM512x_IDCH | ||
| 686 | | PCM512x_DCAS | PCM512x_IPLK); | ||
| 687 | if (ret != 0) { | ||
| 688 | dev_err(codec->dev, | ||
| 689 | "Failed to ignore auto-clock failures: %d\n", | ||
| 690 | ret); | ||
| 691 | return ret; | ||
| 692 | } | ||
| 693 | 965 | ||
| 694 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | 966 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff); |
| 695 | PCM512x_PLLE, 0); | 967 | if (ret != 0) { |
| 696 | if (ret != 0) { | 968 | dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret); |
| 697 | dev_err(codec->dev, "Failed to disable pll: %d\n", ret); | 969 | return ret; |
| 698 | return ret; | 970 | } |
| 971 | |||
| 972 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
| 973 | PCM512x_IDFS | PCM512x_IDBK | ||
| 974 | | PCM512x_IDSK | PCM512x_IDCH | ||
| 975 | | PCM512x_IDCM | PCM512x_DCAS | ||
| 976 | | PCM512x_IPLK, | ||
| 977 | PCM512x_IDFS | PCM512x_IDBK | ||
| 978 | | PCM512x_IDSK | PCM512x_IDCH | ||
| 979 | | PCM512x_DCAS); | ||
| 980 | if (ret != 0) { | ||
| 981 | dev_err(codec->dev, | ||
| 982 | "Failed to ignore auto-clock failures: %d\n", | ||
| 983 | ret); | ||
| 984 | return ret; | ||
| 985 | } | ||
| 986 | } else { | ||
| 987 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
| 988 | PCM512x_IDFS | PCM512x_IDBK | ||
| 989 | | PCM512x_IDSK | PCM512x_IDCH | ||
| 990 | | PCM512x_IDCM | PCM512x_DCAS | ||
| 991 | | PCM512x_IPLK, | ||
| 992 | PCM512x_IDFS | PCM512x_IDBK | ||
| 993 | | PCM512x_IDSK | PCM512x_IDCH | ||
| 994 | | PCM512x_DCAS | PCM512x_IPLK); | ||
| 995 | if (ret != 0) { | ||
| 996 | dev_err(codec->dev, | ||
| 997 | "Failed to ignore auto-clock failures: %d\n", | ||
| 998 | ret); | ||
| 999 | return ret; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
| 1003 | PCM512x_PLLE, 0); | ||
| 1004 | if (ret != 0) { | ||
| 1005 | dev_err(codec->dev, "Failed to disable pll: %d\n", ret); | ||
| 1006 | return ret; | ||
| 1007 | } | ||
| 699 | } | 1008 | } |
| 700 | 1009 | ||
| 701 | ret = pcm512x_set_dividers(dai, params); | 1010 | ret = pcm512x_set_dividers(dai, params); |
| @@ -709,6 +1018,33 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream, | |||
| 709 | return ret; | 1018 | return ret; |
| 710 | } | 1019 | } |
| 711 | 1020 | ||
| 1021 | if (pcm512x->pll_out) { | ||
| 1022 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF, | ||
| 1023 | PCM512x_SREF, PCM512x_SREF_GPIO); | ||
| 1024 | if (ret != 0) { | ||
| 1025 | dev_err(codec->dev, | ||
| 1026 | "Failed to set gpio as pllref: %d\n", ret); | ||
| 1027 | return ret; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1; | ||
| 1031 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN, | ||
| 1032 | PCM512x_GREF, gpio); | ||
| 1033 | if (ret != 0) { | ||
| 1034 | dev_err(codec->dev, | ||
| 1035 | "Failed to set gpio %d as pllin: %d\n", | ||
| 1036 | pcm512x->pll_in, ret); | ||
| 1037 | return ret; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
| 1041 | PCM512x_PLLE, PCM512x_PLLE); | ||
| 1042 | if (ret != 0) { | ||
| 1043 | dev_err(codec->dev, "Failed to enable pll: %d\n", ret); | ||
| 1044 | return ret; | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | |||
| 712 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG, | 1048 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG, |
| 713 | PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO, | 1049 | PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO, |
| 714 | PCM512x_BCKO | PCM512x_LRKO); | 1050 | PCM512x_BCKO | PCM512x_LRKO); |
| @@ -725,6 +1061,45 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream, | |||
| 725 | return ret; | 1061 | return ret; |
| 726 | } | 1062 | } |
| 727 | 1063 | ||
| 1064 | if (pcm512x->pll_out) { | ||
| 1065 | gpio = PCM512x_G1OE << (pcm512x->pll_out - 1); | ||
| 1066 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
| 1067 | gpio, gpio); | ||
| 1068 | if (ret != 0) { | ||
| 1069 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
| 1070 | pcm512x->pll_out, ret); | ||
| 1071 | return ret; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | gpio = PCM512x_GPIO_OUTPUT_1 + pcm512x->pll_out - 1; | ||
| 1075 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
| 1076 | PCM512x_GxSL, PCM512x_GxSL_PLLCK); | ||
| 1077 | if (ret != 0) { | ||
| 1078 | dev_err(codec->dev, "Failed to output pll on %d: %d\n", | ||
| 1079 | ret, pcm512x->pll_out); | ||
| 1080 | return ret; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | gpio = PCM512x_G1OE << (4 - 1); | ||
| 1084 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
| 1085 | gpio, gpio); | ||
| 1086 | if (ret != 0) { | ||
| 1087 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
| 1088 | 4, ret); | ||
| 1089 | return ret; | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | gpio = PCM512x_GPIO_OUTPUT_1 + 4 - 1; | ||
| 1093 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
| 1094 | PCM512x_GxSL, PCM512x_GxSL_PLLLK); | ||
| 1095 | if (ret != 0) { | ||
| 1096 | dev_err(codec->dev, | ||
| 1097 | "Failed to output pll lock on %d: %d\n", | ||
| 1098 | ret, 4); | ||
| 1099 | return ret; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 728 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, | 1103 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, |
| 729 | PCM512x_RQSY, PCM512x_RQSY_HALT); | 1104 | PCM512x_RQSY, PCM512x_RQSY_HALT); |
| 730 | if (ret != 0) { | 1105 | if (ret != 0) { |
| @@ -815,6 +1190,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
| 815 | { | 1190 | { |
| 816 | struct pcm512x_priv *pcm512x; | 1191 | struct pcm512x_priv *pcm512x; |
| 817 | int i, ret; | 1192 | int i, ret; |
| 1193 | u32 val; | ||
| 818 | 1194 | ||
| 819 | pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); | 1195 | pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); |
| 820 | if (!pcm512x) | 1196 | if (!pcm512x) |
| @@ -892,6 +1268,42 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
| 892 | pm_runtime_enable(dev); | 1268 | pm_runtime_enable(dev); |
| 893 | pm_runtime_idle(dev); | 1269 | pm_runtime_idle(dev); |
| 894 | 1270 | ||
| 1271 | #ifdef CONFIG_OF | ||
| 1272 | if (dev->of_node) { | ||
| 1273 | const struct device_node *np = dev->of_node; | ||
| 1274 | |||
| 1275 | if (of_property_read_u32(np, "pll-in", &val) >= 0) { | ||
| 1276 | if (val > 6) { | ||
| 1277 | dev_err(dev, "Invalid pll-in\n"); | ||
| 1278 | ret = -EINVAL; | ||
| 1279 | goto err_clk; | ||
| 1280 | } | ||
| 1281 | pcm512x->pll_in = val; | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | if (of_property_read_u32(np, "pll-out", &val) >= 0) { | ||
| 1285 | if (val > 6) { | ||
| 1286 | dev_err(dev, "Invalid pll-out\n"); | ||
| 1287 | ret = -EINVAL; | ||
| 1288 | goto err_clk; | ||
| 1289 | } | ||
| 1290 | pcm512x->pll_out = val; | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | if (!pcm512x->pll_in != !pcm512x->pll_out) { | ||
| 1294 | dev_err(dev, | ||
| 1295 | "Error: both pll-in and pll-out, or none\n"); | ||
| 1296 | ret = -EINVAL; | ||
| 1297 | goto err_clk; | ||
| 1298 | } | ||
| 1299 | if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) { | ||
| 1300 | dev_err(dev, "Error: pll-in == pll-out\n"); | ||
| 1301 | ret = -EINVAL; | ||
| 1302 | goto err_clk; | ||
| 1303 | } | ||
| 1304 | } | ||
| 1305 | #endif | ||
| 1306 | |||
| 895 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, | 1307 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, |
| 896 | &pcm512x_dai, 1); | 1308 | &pcm512x_dai, 1); |
| 897 | if (ret != 0) { | 1309 | if (ret != 0) { |
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h index fa538d5aabf2..eba5adc2cdb1 100644 --- a/sound/soc/codecs/pcm512x.h +++ b/sound/soc/codecs/pcm512x.h | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) | 38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) |
| 39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) | 39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) |
| 40 | #define PCM512x_DAC_REF (PCM512x_PAGE_BASE(0) + 14) | 40 | #define PCM512x_DAC_REF (PCM512x_PAGE_BASE(0) + 14) |
| 41 | #define PCM512x_GPIO_PLLIN (PCM512x_PAGE_BASE(0) + 18) | ||
| 41 | #define PCM512x_SYNCHRONIZE (PCM512x_PAGE_BASE(0) + 19) | 42 | #define PCM512x_SYNCHRONIZE (PCM512x_PAGE_BASE(0) + 19) |
| 42 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) | 43 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) |
| 43 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) | 44 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) |
| @@ -79,6 +80,7 @@ | |||
| 79 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) | 80 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) |
| 80 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) | 81 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) |
| 81 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) | 82 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) |
| 83 | #define PCM512x_CLOCK_STATUS (PCM512x_PAGE_BASE(0) + 95) | ||
| 82 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) | 84 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) |
| 83 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) | 85 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) |
| 84 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) | 86 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) |
| @@ -93,7 +95,10 @@ | |||
| 93 | 95 | ||
| 94 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) | 96 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) |
| 95 | 97 | ||
| 96 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1) | 98 | #define PCM512x_FLEX_A (PCM512x_PAGE_BASE(253) + 63) |
| 99 | #define PCM512x_FLEX_B (PCM512x_PAGE_BASE(253) + 64) | ||
| 100 | |||
| 101 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(253) + 64) | ||
| 97 | 102 | ||
| 98 | /* Page 0, Register 1 - reset */ | 103 | /* Page 0, Register 1 - reset */ |
| 99 | #define PCM512x_RSTR (1 << 0) | 104 | #define PCM512x_RSTR (1 << 0) |
| @@ -121,6 +126,14 @@ | |||
| 121 | #define PCM512x_DEMP (1 << 4) | 126 | #define PCM512x_DEMP (1 << 4) |
| 122 | #define PCM512x_DEMP_SHIFT 4 | 127 | #define PCM512x_DEMP_SHIFT 4 |
| 123 | 128 | ||
| 129 | /* Page 0, Register 8 - GPIO output enable */ | ||
| 130 | #define PCM512x_G1OE (1 << 0) | ||
| 131 | #define PCM512x_G2OE (1 << 1) | ||
| 132 | #define PCM512x_G3OE (1 << 2) | ||
| 133 | #define PCM512x_G4OE (1 << 3) | ||
| 134 | #define PCM512x_G5OE (1 << 4) | ||
| 135 | #define PCM512x_G6OE (1 << 5) | ||
| 136 | |||
| 124 | /* Page 0, Register 9 - BCK, LRCLK configuration */ | 137 | /* Page 0, Register 9 - BCK, LRCLK configuration */ |
| 125 | #define PCM512x_LRKO (1 << 0) | 138 | #define PCM512x_LRKO (1 << 0) |
| 126 | #define PCM512x_LRKO_SHIFT 0 | 139 | #define PCM512x_LRKO_SHIFT 0 |
| @@ -150,6 +163,16 @@ | |||
| 150 | #define PCM512x_SDAC_SCK (3 << 4) | 163 | #define PCM512x_SDAC_SCK (3 << 4) |
| 151 | #define PCM512x_SDAC_BCK (4 << 4) | 164 | #define PCM512x_SDAC_BCK (4 << 4) |
| 152 | 165 | ||
| 166 | /* Page 0, Register 18 - GPIO source for PLL */ | ||
| 167 | #define PCM512x_GREF (7 << 0) | ||
| 168 | #define PCM512x_GREF_SHIFT 0 | ||
| 169 | #define PCM512x_GREF_GPIO1 (0 << 0) | ||
| 170 | #define PCM512x_GREF_GPIO2 (1 << 0) | ||
| 171 | #define PCM512x_GREF_GPIO3 (2 << 0) | ||
| 172 | #define PCM512x_GREF_GPIO4 (3 << 0) | ||
| 173 | #define PCM512x_GREF_GPIO5 (4 << 0) | ||
| 174 | #define PCM512x_GREF_GPIO6 (5 << 0) | ||
| 175 | |||
| 153 | /* Page 0, Register 19 - synchronize */ | 176 | /* Page 0, Register 19 - synchronize */ |
| 154 | #define PCM512x_RQSY (1 << 0) | 177 | #define PCM512x_RQSY (1 << 0) |
| 155 | #define PCM512x_RQSY_RESUME (0 << 0) | 178 | #define PCM512x_RQSY_RESUME (0 << 0) |
| @@ -209,6 +232,25 @@ | |||
| 209 | #define PCM512x_AMLE_SHIFT 1 | 232 | #define PCM512x_AMLE_SHIFT 1 |
| 210 | #define PCM512x_AMRE_SHIFT 0 | 233 | #define PCM512x_AMRE_SHIFT 0 |
| 211 | 234 | ||
| 235 | /* Page 0, Register 80-85, GPIO output selection */ | ||
| 236 | #define PCM512x_GxSL (31 << 0) | ||
| 237 | #define PCM512x_GxSL_SHIFT 0 | ||
| 238 | #define PCM512x_GxSL_OFF (0 << 0) | ||
| 239 | #define PCM512x_GxSL_DSP (1 << 0) | ||
| 240 | #define PCM512x_GxSL_REG (2 << 0) | ||
| 241 | #define PCM512x_GxSL_AMUTB (3 << 0) | ||
| 242 | #define PCM512x_GxSL_AMUTL (4 << 0) | ||
| 243 | #define PCM512x_GxSL_AMUTR (5 << 0) | ||
| 244 | #define PCM512x_GxSL_CLKI (6 << 0) | ||
| 245 | #define PCM512x_GxSL_SDOUT (7 << 0) | ||
| 246 | #define PCM512x_GxSL_ANMUL (8 << 0) | ||
| 247 | #define PCM512x_GxSL_ANMUR (9 << 0) | ||
| 248 | #define PCM512x_GxSL_PLLLK (10 << 0) | ||
| 249 | #define PCM512x_GxSL_CPCLK (11 << 0) | ||
| 250 | #define PCM512x_GxSL_UV0_7 (14 << 0) | ||
| 251 | #define PCM512x_GxSL_UV0_3 (15 << 0) | ||
| 252 | #define PCM512x_GxSL_PLLCK (16 << 0) | ||
| 253 | |||
| 212 | /* Page 1, Register 2 - analog volume control */ | 254 | /* Page 1, Register 2 - analog volume control */ |
| 213 | #define PCM512x_RAGN_SHIFT 0 | 255 | #define PCM512x_RAGN_SHIFT 0 |
| 214 | #define PCM512x_LAGN_SHIFT 4 | 256 | #define PCM512x_LAGN_SHIFT 4 |
