@@ -61,6 +61,7 @@ struct pcm3168a_priv {
struct clk *scki;
struct gpio_desc *gpio_rst;
unsigned long sysclk;
+ bool adc_fc, dac_fc; // Force clock consumer mode
struct pcm3168a_io_params io_params[2];
struct snd_soc_dai_driver dai_drv[2];
@@ -479,6 +480,12 @@ static int pcm3168a_hw_params(struct
snd_pcm_substream *substream,
ms = 0;
}
+ // Force clock consumer mode if needed
+ if (pcm3168a->adc_fc && dai->id == PCM3168A_DAI_ADC)
+ ms = 0;
+ if (pcm3168a->dac_fc && dai->id == PCM3168A_DAI_DAC)
+ ms = 0;
+
format = io_params->format;
Scenario is that DAC's clock pins are tied to ADC's clock pins, with codec acting as clock producer for the I2S bus, and the CPU has a single pair of I2S clock pins used for both playback and capture. Both DAI links will have codec acting as a clock producer, but we need to configure the codec so that only one of ADC/DAC drives the lines. Add DT options to support this configuration. adc-force-cons/dac-force-cons cause MSAD/MSDA to be set to 0b000. if (io_params->slot_width) @@ -757,6 +764,13 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) pcm3168a->sysclk = clk_get_rate(pcm3168a->scki); + if (dev->of_node) { + pcm3168a->adc_fc = of_property_read_bool(dev->of_node, + "adc-force-cons"); + pcm3168a->dac_fc = of_property_read_bool(dev->of_node, + "dac-force-cons"); + } + for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++) pcm3168a->supplies[i].supply = pcm3168a_supply_names[i]; Signed-off-by: Stephen Gordon <gordoste@iinet.net.au>