summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Suvorov <oleksandr.suvorov@toradex.com>2019-09-02 18:31:53 +0300
committerOleksandr Suvorov <oleksandr.suvorov@toradex.com>2019-09-09 14:56:07 +0300
commitd26e03d1e61da1ba12f0fb84d5ee13a8810c0d59 (patch)
treed2bee3aae78acd8856f7deaa3cccb3ecd166cedd
parente90330d60bd7c0af068c43ae19374f46d6cdd7a0 (diff)
ASoC: sgtl5000: add helpers to calculate mclk
Calculate SYS_MCLK using sample rate or SYS_FS. These helpers allow to simplify a code to set up external system clock for different sample rates. Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
-rw-r--r--sound/soc/codecs/sgtl5000.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 8a9f435..cfbe6e6 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -397,4 +397,48 @@
#define SGTL5000_SYSCLK 0x00
#define SGTL5000_LRCLK 0x01
+/* Convert sample rate and SYS_FS frequencies to external SYS_MCLK */
+
+static inline int sgtl5000_sys_fs_to_mclk(int sys_fs) {
+ int mul[] = { 256, 384, 512 };
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ int mclk = sys_fs * mul[i];
+ /* minimum freq for sync mode is 8 MHz */
+ if (mclk > 8000000) {
+ /* maximum freq for sync mode is 27 MHz */
+ if (mclk > 27000000)
+ return -EINVAL;
+ /* return as minimum mclk as possible to save power */
+ return mclk;
+ }
+ }
+ /* srate too small */
+ return -EINVAL;
+}
+
+static inline int sgtl5000_srate_to_sys_fs(int srate) {
+ /* Supported SYS_FS frequencies */
+ static const int sys_fs[] = { 32000, 44100, 48000, 96000, 0 };
+ int i = 0;
+
+ while (sys_fs[i] > 0) {
+ if (!(sys_fs[i] % srate))
+ return sys_fs[i];
+ i++;
+ }
+ /* srate is not compatible with any SYS_FS */
+ return -EINVAL;
+}
+
+static inline int sgtl5000_srate_to_mclk(int srate) {
+ int sys_fs = sgtl5000_srate_to_sys_fs(srate);
+
+ if (IS_ERR_VALUE(sys_fs))
+ return sys_fs;
+
+ return sgtl5000_sys_fs_to_mclk(sys_fs);
+}
+
#endif