sound: Move Samsung-specific code into its own file
authorSimon Glass <sjg@chromium.org>
Thu, 27 Feb 2014 20:26:20 +0000 (13:26 -0700)
committerSimon Glass <sjg@chromium.org>
Tue, 18 Mar 2014 02:05:49 +0000 (20:05 -0600)
The i2s code is in fact Samsung-specific, but there might be other
implementation. Move this code into its own file. This makes it slightly
more obviously how to adjust the code to support another SoC, when someone
takes this task on.

Also drop non-FDT support, since it isn't used on Exynos 5.

Tested-by: Che-Liang Chiou <clchiou@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/sound/Makefile
drivers/sound/sound-i2s.c [new file with mode: 0644]
drivers/sound/sound.c
include/configs/exynos5250-dt.h
include/sound.h

index 3793f8af9bf70e36b350b696b73e8cfafbc0468c..981ed614b126bfcc0395acaa87eb20b8707b9510 100644 (file)
@@ -6,7 +6,7 @@
 #
 
 obj-$(CONFIG_SOUND)    += sound.o
-obj-$(CONFIG_I2S)      += samsung-i2s.o
+obj-$(CONFIG_I2S)      += sound-i2s.o
 obj-$(CONFIG_I2S_SAMSUNG)      += samsung-i2s.o
 obj-$(CONFIG_SOUND_SANDBOX)    += sandbox.o
 obj-$(CONFIG_SOUND_WM8994)     += wm8994.o
diff --git a/drivers/sound/sound-i2s.c b/drivers/sound/sound-i2s.c
new file mode 100644 (file)
index 0000000..749bbbd
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * R. Chandrasekar <rcsekar@samsung.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <malloc.h>
+#include <common.h>
+#include <asm/io.h>
+#include <libfdt.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <i2s.h>
+#include <sound.h>
+#include <asm/arch/sound.h>
+#include "wm8994.h"
+#include "max98095.h"
+
+/* defines */
+#define SOUND_400_HZ 400
+#define SOUND_BITS_IN_BYTE 8
+
+static struct i2stx_info g_i2stx_pri;
+
+/*
+ * get_sound_i2s_values gets values for i2s parameters
+ *
+ * @param i2stx_info   i2s transmitter transfer param structure
+ * @param blob         FDT blob if enabled else NULL
+ */
+static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
+{
+       int node;
+       int error = 0;
+       int base;
+
+       node = fdt_path_offset(blob, "i2s");
+       if (node <= 0) {
+               debug("EXYNOS_SOUND: No node for sound in device tree\n");
+               return -1;
+       }
+
+       /*
+        * Get the pre-defined sound specific values from FDT.
+        * All of these are expected to be correct otherwise
+        * wrong register values in i2s setup parameters
+        * may result in no sound play.
+        */
+       base = fdtdec_get_addr(blob, node, "reg");
+       if (base == FDT_ADDR_T_NONE) {
+               debug("%s: Missing  i2s base\n", __func__);
+               return -1;
+       }
+       i2s->base_address = base;
+
+       i2s->audio_pll_clk = fdtdec_get_int(blob,
+                               node, "samsung,i2s-epll-clock-frequency", -1);
+       error |= i2s->audio_pll_clk;
+       debug("audio_pll_clk = %d\n", i2s->audio_pll_clk);
+       i2s->samplingrate = fdtdec_get_int(blob,
+                               node, "samsung,i2s-sampling-rate", -1);
+       error |= i2s->samplingrate;
+       debug("samplingrate = %d\n", i2s->samplingrate);
+       i2s->bitspersample = fdtdec_get_int(blob,
+                               node, "samsung,i2s-bits-per-sample", -1);
+       error |= i2s->bitspersample;
+       debug("bitspersample = %d\n", i2s->bitspersample);
+       i2s->channels = fdtdec_get_int(blob,
+                       node, "samsung,i2s-channels", -1);
+       error |= i2s->channels;
+       debug("channels = %d\n", i2s->channels);
+       i2s->rfs = fdtdec_get_int(blob,
+                               node, "samsung,i2s-lr-clk-framesize", -1);
+       error |= i2s->rfs;
+       debug("rfs = %d\n", i2s->rfs);
+       i2s->bfs = fdtdec_get_int(blob,
+                               node, "samsung,i2s-bit-clk-framesize", -1);
+       error |= i2s->bfs;
+       debug("bfs = %d\n", i2s->bfs);
+
+       i2s->id = fdtdec_get_int(blob, node, "samsung,i2s-id", -1);
+       error |= i2s->id;
+       debug("id = %d\n", i2s->id);
+
+       if (error == -1) {
+               debug("fail to get sound i2s node properties\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * Init codec
+ *
+ * @param blob          FDT blob
+ * @param pi2s_tx      i2s parameters required by codec
+ * @return              int value, 0 for success
+ */
+static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
+{
+       int ret;
+       const char *codectype;
+       int node;
+
+       /* Get the node from FDT for sound */
+       node = fdt_path_offset(blob, "i2s");
+       if (node <= 0) {
+               debug("EXYNOS_SOUND: No node for sound in device tree\n");
+               debug("node = %d\n", node);
+               return -1;
+       }
+
+       /*
+        * Get the pre-defined sound codec specific values from FDT.
+        * All of these are expected to be correct otherwise sound
+        * can not be played
+        */
+       codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL);
+       debug("device = %s\n", codectype);
+       if (!strcmp(codectype, "wm8994")) {
+               /* Check the codec type and initialise the same */
+               ret = wm8994_init(blob, pi2s_tx->id + 1,
+                                 pi2s_tx->samplingrate,
+                                 (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                                 pi2s_tx->bitspersample, pi2s_tx->channels);
+       } else if (!strcmp(codectype, "max98095")) {
+               ret = max98095_init(blob, pi2s_tx->id + 1,
+                                   pi2s_tx->samplingrate,
+                                   (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                                   pi2s_tx->bitspersample);
+       } else {
+               debug("%s: Unknown codec type %s\n", __func__, codectype);
+               return -1;
+       }
+
+       if (ret) {
+               debug("%s: Codec init failed\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+int sound_init(const void *blob)
+{
+       int ret;
+       struct i2stx_info *pi2s_tx = &g_i2stx_pri;
+
+       /* Get the I2S Values */
+       if (get_sound_i2s_values(pi2s_tx, blob) < 0) {
+               debug(" FDT I2S values failed\n");
+               return -1;
+       }
+
+       if (codec_init(blob, pi2s_tx) < 0) {
+               debug(" Codec init failed\n");
+               return -1;
+       }
+
+       ret = i2s_tx_init(pi2s_tx);
+       if (ret) {
+               debug("%s: Failed to init i2c transmit: ret=%d\n", __func__,
+                     ret);
+               return ret;
+       }
+
+
+       return ret;
+}
+
+int sound_play(uint32_t msec, uint32_t frequency)
+{
+       unsigned int *data;
+       unsigned long data_size;
+       unsigned int ret = 0;
+
+       /*Buffer length computation */
+       data_size = g_i2stx_pri.samplingrate * g_i2stx_pri.channels;
+       data_size *= (g_i2stx_pri.bitspersample / SOUND_BITS_IN_BYTE);
+       data = malloc(data_size);
+
+       if (data == NULL) {
+               debug("%s: malloc failed\n", __func__);
+               return -1;
+       }
+
+       sound_create_square_wave((unsigned short *)data,
+                                data_size / sizeof(unsigned short),
+                                frequency);
+
+       while (msec >= 1000) {
+               ret = i2s_transfer_tx_data(&g_i2stx_pri, data,
+                                          (data_size / sizeof(int)));
+               msec -= 1000;
+       }
+       if (msec) {
+               unsigned long size =
+                       (data_size * msec) / (sizeof(int) * 1000);
+
+               ret = i2s_transfer_tx_data(&g_i2stx_pri, data, size);
+       }
+
+       free(data);
+
+       return ret;
+}
index 9b8ce5a9efb752c78466f2b461385e448a49e2f9..9dda2dba822aa8bc0a4aaf504130f1bfaddfc530 100644 (file)
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <malloc.h>
 #include <common.h>
-#include <asm/io.h>
-#include <libfdt.h>
-#include <fdtdec.h>
-#include <i2c.h>
-#include <i2s.h>
 #include <sound.h>
-#include <asm/arch/sound.h>
-#include "wm8994.h"
-#include "max98095.h"
 
-/* defines */
-#define SOUND_400_HZ 400
-#define SOUND_BITS_IN_BYTE 8
-
-static struct i2stx_info g_i2stx_pri;
-
-/*
- * get_sound_i2s_values gets values for i2s parameters
- *
- * @param i2stx_info   i2s transmitter transfer param structure
- * @param blob         FDT blob if enabled else NULL
- */
-static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob)
-{
-#ifdef CONFIG_OF_CONTROL
-       int node;
-       int error = 0;
-       int base;
-
-       node = fdt_path_offset(blob, "i2s");
-       if (node <= 0) {
-               debug("EXYNOS_SOUND: No node for sound in device tree\n");
-               return -1;
-       }
-
-       /*
-        * Get the pre-defined sound specific values from FDT.
-        * All of these are expected to be correct otherwise
-        * wrong register values in i2s setup parameters
-        * may result in no sound play.
-        */
-       base = fdtdec_get_addr(blob, node, "reg");
-       if (base == FDT_ADDR_T_NONE) {
-               debug("%s: Missing  i2s base\n", __func__);
-               return -1;
-       }
-       i2s->base_address = base;
-
-       i2s->audio_pll_clk = fdtdec_get_int(blob,
-                               node, "samsung,i2s-epll-clock-frequency", -1);
-       error |= i2s->audio_pll_clk;
-       debug("audio_pll_clk = %d\n", i2s->audio_pll_clk);
-       i2s->samplingrate = fdtdec_get_int(blob,
-                               node, "samsung,i2s-sampling-rate", -1);
-       error |= i2s->samplingrate;
-       debug("samplingrate = %d\n", i2s->samplingrate);
-       i2s->bitspersample = fdtdec_get_int(blob,
-                               node, "samsung,i2s-bits-per-sample", -1);
-       error |= i2s->bitspersample;
-       debug("bitspersample = %d\n", i2s->bitspersample);
-       i2s->channels = fdtdec_get_int(blob,
-                       node, "samsung,i2s-channels", -1);
-       error |= i2s->channels;
-       debug("channels = %d\n", i2s->channels);
-       i2s->rfs = fdtdec_get_int(blob,
-                               node, "samsung,i2s-lr-clk-framesize", -1);
-       error |= i2s->rfs;
-       debug("rfs = %d\n", i2s->rfs);
-       i2s->bfs = fdtdec_get_int(blob,
-                               node, "samsung,i2s-bit-clk-framesize", -1);
-       error |= i2s->bfs;
-       debug("bfs = %d\n", i2s->bfs);
-
-       i2s->id = fdtdec_get_int(blob, node, "samsung,i2s-id", -1);
-       error |= i2s->id;
-       debug("id = %d\n", i2s->id);
-
-       if (error == -1) {
-               debug("fail to get sound i2s node properties\n");
-               return -1;
-       }
-#else
-       i2s->base_address = samsung_get_base_i2s();
-       i2s->audio_pll_clk = I2S_PLL_CLK;
-       i2s->samplingrate = I2S_SAMPLING_RATE;
-       i2s->bitspersample = I2S_BITS_PER_SAMPLE;
-       i2s->channels = I2S_CHANNELS;
-       i2s->rfs = I2S_RFS;
-       i2s->bfs = I2S_BFS;
-       i2s->id = 0;
-#endif
-       return 0;
-}
-
-/*
- * Init codec
- *
- * @param blob          FDT blob
- * @param pi2s_tx      i2s parameters required by codec
- * @return              int value, 0 for success
- */
-static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
-{
-       int ret;
-       const char *codectype;
-#ifdef CONFIG_OF_CONTROL
-       int node;
-
-       /* Get the node from FDT for sound */
-       node = fdt_path_offset(blob, "i2s");
-       if (node <= 0) {
-               debug("EXYNOS_SOUND: No node for sound in device tree\n");
-               debug("node = %d\n", node);
-               return -1;
-       }
-
-       /*
-        * Get the pre-defined sound codec specific values from FDT.
-        * All of these are expected to be correct otherwise sound
-        * can not be played
-        */
-       codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL);
-       debug("device = %s\n", codectype);
-#else
-       codectype =  AUDIO_CODEC;
-#endif
-       if (!strcmp(codectype, "wm8994")) {
-               /* Check the codec type and initialise the same */
-               ret = wm8994_init(blob, pi2s_tx->id + 1,
-                                 pi2s_tx->samplingrate,
-                                 (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-                                 pi2s_tx->bitspersample, pi2s_tx->channels);
-       } else if (!strcmp(codectype, "max98095")) {
-               ret = max98095_init(blob, pi2s_tx->id + 1,
-                                   pi2s_tx->samplingrate,
-                                   (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
-                                   pi2s_tx->bitspersample);
-       } else {
-               debug("%s: Unknown codec type %s\n", __func__, codectype);
-               return -1;
-       }
-
-       if (ret) {
-               debug("%s: Codec init failed\n", __func__);
-               return -1;
-       }
-
-       return 0;
-}
-
-int sound_init(const void *blob)
-{
-       int ret;
-       struct i2stx_info *pi2s_tx = &g_i2stx_pri;
-
-       /* Get the I2S Values */
-       if (get_sound_i2s_values(pi2s_tx, blob) < 0) {
-               debug(" FDT I2S values failed\n");
-               return -1;
-       }
-
-       if (codec_init(blob, pi2s_tx) < 0) {
-               debug(" Codec init failed\n");
-               return -1;
-       }
-
-       ret = i2s_tx_init(pi2s_tx);
-       if (ret) {
-               debug("%s: Failed to init i2c transmit: ret=%d\n", __func__,
-                     ret);
-               return ret;
-       }
-
-
-       return ret;
-}
-
-/*
- * Generates square wave sound data for 1 second
- *
- * @param data          data buffer pointer
- * @param size          size of the buffer
- * @param freq          frequency of the wave
- */
-static void sound_prepare_buffer(unsigned short *data, int size, uint32_t freq)
+void sound_create_square_wave(unsigned short *data, int size, uint32_t freq)
 {
        const int sample = 48000;
        const unsigned short amplitude = 16000; /* between 1 and 32767 */
@@ -218,39 +35,3 @@ static void sound_prepare_buffer(unsigned short *data, int size, uint32_t freq)
                }
        }
 }
-
-int sound_play(uint32_t msec, uint32_t frequency)
-{
-       unsigned int *data;
-       unsigned long data_size;
-       unsigned int ret = 0;
-
-       /*Buffer length computation */
-       data_size = g_i2stx_pri.samplingrate * g_i2stx_pri.channels;
-       data_size *= (g_i2stx_pri.bitspersample / SOUND_BITS_IN_BYTE);
-       data = malloc(data_size);
-
-       if (data == NULL) {
-               debug("%s: malloc failed\n", __func__);
-               return -1;
-       }
-
-       sound_prepare_buffer((unsigned short *)data,
-                            data_size / sizeof(unsigned short), frequency);
-
-       while (msec >= 1000) {
-               ret = i2s_transfer_tx_data(&g_i2stx_pri, data,
-                                          (data_size / sizeof(int)));
-               msec -= 1000;
-       }
-       if (msec) {
-               unsigned long size =
-                       (data_size * msec) / (sizeof(int) * 1000);
-
-               ret = i2s_transfer_tx_data(&g_i2stx_pri, data, size);
-       }
-
-       free(data);
-
-       return ret;
-}
index 615df64dc17a0e0b2406ee65d825fd228ff7dada..b7ff47236b7fa6fe7efa8d0bd40965acca15a4d3 100644 (file)
@@ -51,6 +51,7 @@
 #define CONFIG_CMD_SOUND
 #ifdef CONFIG_CMD_SOUND
 #define CONFIG_SOUND
+#define CONFIG_I2S_SAMSUNG
 #define CONFIG_I2S
 #define CONFIG_SOUND_MAX98095
 #define CONFIG_SOUND_WM8994
index a06ab853869faef2137c18e290c2c0308bd625c7..155e1b40e28a1c91e9a6f8b228b46a12ff3c30c0 100644 (file)
@@ -29,6 +29,15 @@ struct sound_codec_info {
        enum en_sound_codec codec_type;
 };
 
+/*
+ * Generates square wave sound data for 1 second
+ *
+ * @param data          data buffer pointer
+ * @param size          size of the buffer
+ * @param freq          frequency of the wave
+ */
+void sound_create_square_wave(unsigned short *data, int size, uint32_t freq);
+
 /*
  * Initialises audio sub system
  * @param blob Pointer of device tree node or NULL if none.