From: Peter Rosin
Using the PLL in master mode requires using an external connection
between one of the GPIO pins (configured as PLL/4 output) and the
SCK pin. It also requires the external clock to be fed to some other
GPIO pin instead of the SCK pin.
This is described for the PCM5122 chip in the answers to the forum post
"PCM5122 DAC as I2S master troubles with PLL mode" at the TI E2E
community pages (1). The clocking functionality is also much better
described in the datasheet for the chip PCM5242, which seems to be
register compatible with PCM512x and PCM514x (which both have severely
lacking datasheets).
(1) http://e2e.ti.com/support/data_converters/audio_converters/f/64/t/267830
Signed-off-by: Peter Rosin
---
.../devicetree/bindings/sound/pcm512x.txt | 25 +-
sound/soc/codecs/pcm512x.c | 458 +++-
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:
Optional properties:
- clocks : A clock specifier for the clock connected as SCLK. If this
-is absent the device will be configured to clock from BCLK.
+is absent the device will be configured to clock from BCLK. If pll-in
+and pll-out are specified in addition to a clock, the device is
+configured to accept clock input on a specified gpio pin.
-Example:
+ - pll-in, pll-out : gpio pins used to connect the pll using <1>
+through <6>. The device will be configured for clock input on the
+given pll-in pin and PLL output on the given pll-out pin. An
+external connection from the pll-out pin to the SCLK pin is assumed.
+
+Examples:
pcm5122: pcm5122@4c {
compatible = "ti,pcm5122";
@@ -29,3 +36,17 @@ Example:
DVDD-supply = <®_1v8>;
CPVDD-supply = <®_3v3>;
};
+
+
+ pcm5142: pcm5142@4c {
+ compatible = "ti,pcm5142";
+ reg = <0x4c>;
+
+ AVDD-supply = <®_3v3_analog>;
+ DVDD-supply = <®_1v8>;
+ CPVDD-supply = <®_3v3>;
+
+ clocks = <&sck>;
+ pll-in = <3>;
+ pll-out = <6>;
+ };
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 124388809d48..f0c7ec2a2f31 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -28,6 +29,11 @@
#include "pcm512x.h"
+#define DIV_ROUND_DOWN_ULL(ll, d) \
+ ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; })
+#define DIV_ROUND_CLOSEST_ULL(ll, d) \
+ ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
+
#define PCM512x_NUM_SUPPLIES 3
static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
"AVDD",
@@ -41,6 +47,13 @@ struct pcm512x_priv {
struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
int fmt;
+ int pll_in;
+ int pll_out;
+ int pll_r;
+ int pll_j;
+ int pll_d;
+ int pll_p;
+ unsigned long real_pll;
};
/*
@@ -92,7 +105,13 @@ static const struct reg_default pcm512x_reg_defaults[] = {
{ PCM512x_VCOM_CTRL_2, 0x01 },
{ PCM512x_BCLK_LRCLK_CFG,0x00 },
{ PCM512x_MASTER_MODE, 0x7c },
+ { PCM512x_GPIO_PLLIN,0x00 },
{ PCM512x_SYNCHRONIZE, 0x10 },
+ { PCM512x_PLL_COEFF_0, 0x00 },
+ { PCM512x_PLL_COEFF_1, 0x00 },
+ { PCM512x_PLL_COEFF_2, 0x00 },
+ { PCM512x_PLL_COEFF_3, 0x00 },
+ { PCM512x_PLL_COEFF_4, 0x00 },
{ PCM512x_DSP_CLKDIV,0x00 },
{ PCM512x_DAC_CLKDIV,0x00 },
{ PCM512x_NCP_CLKDIV,0x00 },
@@ -119,6 +138,7 @@ static bool pcm512x_readable(struct device *dev, unsigned
int reg)
case PCM512x_MASTER_MODE:
case PCM512x_PLL_REF:
case PCM512x_DAC_REF:
+ case PCM512x_GPIO_PLLIN:
case PCM512x_SYNCHRONIZE:
case PCM512x_PLL_COEFF_0:
case PCM512x_PLL_COEFF_1:
@@ -160,6 +180,7 @@ static bool pcm512x_readable(struct device *dev, unsigned
int reg)
case PCM512x_RATE_DET_2:
case PCM512x_RATE_DET_3:
case PCM512x_RATE_DET_4:
+ case PCM512x_CLOCK_STATUS:
case PCM512x_ANALOG_MUTE_DET:
case PCM512x_GPIN:
case PCM512x_DIGITAL_MUTE_DET:
@@ -171,6 +192,8 @@ static bool pcm512x_readable(struct device *dev, unsigned
int reg)
case PCM512x_VCOM_CTRL_1:
case PCM512x_VCOM_CTRL_2:
case P