For testing purposes I have a SGTL5000 wired up to I2S on my Allwinner A20. SGTL5000 needs an external MCLK. It attaches to it like this:
sgtl5000: sgtl5000@a { compatible = "fsl,sgtl5000"; reg = <0x0a>; clocks = <&iis0>;
And in the probe code.... (this should use a name for the clock in the DTS)
sgtl5000->mclk = devm_clk_get(&client->dev, NULL); if (IS_ERR(sgtl5000->mclk)) { ret = PTR_ERR(sgtl5000->mclk); dev_err(&client->dev, "Failed to get mclock: %d\n", ret); /* Defer the probe to see if the clk will be provided later */ if (ret == -ENOENT) return -EPROBE_DEFER; return ret; }
ret = clk_prepare_enable(sgtl5000->mclk); if (ret) return ret;
So the sgtl5000 driver has a handle to the clock. But then the driver implements set_dai_sysclk() to get the rate. And a board specific machine driver like imx-sgtl5000.c is used to set this rate into the sgtl5000 driver.
/* set codec sysclk */ static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
switch (clk_id) { case SGTL5000_SYSCLK: sgtl5000->sysclk = freq; break; default: return -EINVAL; }
return 0; }
Since the sgtl5000 driver has the handle to the clock, can't it just ask the clock for its rate? If it directly asked the clock for its rate it looks like this codec could be bound with simple-audio-card and not need a machine driver.