diff options
Diffstat (limited to 'arch')
23 files changed, 378 insertions, 100 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 947070fdd35..35e2712fce9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -116,6 +116,7 @@ config SANDBOX imply VIRTIO_SANDBOX imply VIRTIO_BLK imply VIRTIO_NET + imply DM_SOUND config SH bool "SuperH architecture" diff --git a/arch/arm/dts/exynos5250-smdk5250.dts b/arch/arm/dts/exynos5250-smdk5250.dts index 8b695442b1a..e542a790761 100644 --- a/arch/arm/dts/exynos5250-smdk5250.dts +++ b/arch/arm/dts/exynos5250-smdk5250.dts @@ -60,9 +60,26 @@ }; i2c@12C70000 { - soundcodec@1a { + wm8994: soundcodec@1a { reg = <0x1a>; - compatible = "wolfson,wm8994-codec"; + u-boot,i2c-offset-len = <2>; + compatible = "wolfson,wm8994"; + #sound-dai-cells = <1>; + }; + }; + + sound { + compatible = "google,smdk5250-audio-wm8994"; + + samsung,model = "SMDK5250-I2S-WM8994"; + samsung,audio-codec = <&wm8994>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&wm8994 0>; }; }; diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 29c13c1257e..7587dc0ff24 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -40,7 +40,6 @@ mmc3 = "/mmc@12230000"; serial0 = "/serial@12C30000"; console = "/serial@12C30000"; - i2s = "/sound@3830000"; }; memory { @@ -88,7 +87,7 @@ ro-boot { label = "u-boot"; - reg = <0x6000 0x9a000>; + reg = <0x6000 0xb0000>; read-only; type = "blob boot,dtb"; required; @@ -214,9 +213,10 @@ }; }; - soundcodec@22 { - reg = <0x22>; - compatible = "maxim,max98095-codec"; + max98095: codec@11 { + compatible = "maxim,max98095"; + reg = <0x11>; + #sound-dai-cells = <1>; }; }; @@ -273,9 +273,20 @@ }; }; - sound@3830000 { - samsung,codec-type = "max98095"; + sound { + compatible = "google,snow-audio-max98095"; + + samsung,model = "Snow-I2S-MAX98095"; + samsung,audio-codec = <&max98095>; codec-enable-gpio = <&gpx1 7 GPIO_ACTIVE_HIGH>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98095 0>; + }; }; sound@12d60000 { diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts index 7633d36874f..191e12af6a1 100644 --- a/arch/arm/dts/exynos5250-spring.dts +++ b/arch/arm/dts/exynos5250-spring.dts @@ -34,7 +34,6 @@ mmc0 = "/mmc@12200000"; serial0 = "/serial@12C30000"; console = "/serial@12C30000"; - i2s = "/sound@3830000"; }; memory { @@ -639,10 +638,27 @@ }; }; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98088-codec"; + max98095: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98095"; + #sound-dai-cells = <1>; }; + + sound { + compatible = "google,spring-audio-max98095"; + + samsung,model = "Spring-I2S-MAX98095"; + samsung,audio-codec = <&max98095>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98095 0>; + }; + }; + }; #include "cros-ec-keyboard.dtsi" diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index 502c687802e..66c5b6dca95 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -78,9 +78,12 @@ #size-cells = <0>; }; - sound@3830000 { - compatible = "samsung,exynos-sound"; - reg = <0x3830000 0x50>; + i2s0: i2s@3830000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0x03830000 0x100>; + samsung,idma-addr = <0x03000000>; + #clock-cells = <1>; + #sound-dai-cells = <1>; samsung,i2s-epll-clock-frequency = <192000000>; samsung,i2s-sampling-rate = <48000>; samsung,i2s-bits-per-sample = <16>; @@ -90,9 +93,11 @@ samsung,i2s-id = <0>; }; - sound@12d60000 { - compatible = "samsung,exynos-sound"; + i2s1: i2s@12d60000 { + compatible = "samsung,s5pv210-i2s"; reg = <0x12d60000 0x20>; + #clock-cells = <1>; + #sound-dai-cells = <1>; samsung,i2s-epll-clock-frequency = <192000000>; samsung,i2s-sampling-rate = <48000>; samsung,i2s-bits-per-sample = <16>; diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts index c86f9d9035d..4a96a18110a 100644 --- a/arch/arm/dts/exynos5420-peach-pit.dts +++ b/arch/arm/dts/exynos5420-peach-pit.dts @@ -67,12 +67,28 @@ }; }; + sound { + compatible = "google,peach-audio-max98090"; + + samsung,model = "PEACH-I2S-MAX98090"; + samsung,audio-codec = <&max98090>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98090 0>; + }; + }; + i2c@12CD0000 { /* i2c7 */ clock-frequency = <100000>; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98090-codec"; - }; + max98090: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98090"; + #sound-dai-cells = <1>; + }; edp-lvds-bridge@48 { compatible = "parade,ps8625"; diff --git a/arch/arm/dts/exynos5420-smdk5420.dts b/arch/arm/dts/exynos5420-smdk5420.dts index cab5ddb61fa..7a5da674fbe 100644 --- a/arch/arm/dts/exynos5420-smdk5420.dts +++ b/arch/arm/dts/exynos5420-smdk5420.dts @@ -82,9 +82,26 @@ }; i2c@12C70000 { - soundcodec@1a { + wm8994: soundcodec@1a { reg = <0x1a>; - compatible = "wolfson,wm8994-codec"; + u-boot,i2c-offset-len = <2>; + compatible = "wolfson,wm8994"; + #sound-dai-cells = <1>; + }; + }; + + sound { + compatible = "samsung,smdk5420-audio-wm8994"; + + samsung,model = "Snow-I2S-MAX98095"; + samsung,audio-codec = <&wm8994>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&wm8994 0>; }; }; diff --git a/arch/arm/dts/exynos54xx.dtsi b/arch/arm/dts/exynos54xx.dtsi index 09bef56e6c2..221da8b4850 100644 --- a/arch/arm/dts/exynos54xx.dtsi +++ b/arch/arm/dts/exynos54xx.dtsi @@ -104,6 +104,20 @@ interrupts = <0 203 0>; }; + i2s0: i2s@3830000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0x03830000 0x100>; + #sound-dai-cells = <1>; + samsung,idma-addr = <0x03000000>; + samsung,i2s-epll-clock-frequency = <192000000>; + samsung,i2s-sampling-rate = <48000>; + samsung,i2s-bits-per-sample = <16>; + samsung,i2s-channels = <2>; + samsung,i2s-lr-clk-framesize = <256>; + samsung,i2s-bit-clk-framesize = <32>; + samsung,i2s-id = <0>; + }; + mmc@12200000 { samsung,bus-width = <8>; samsung,timing = <1 3 3>; diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts index 7498519d6c6..63c0b186e42 100644 --- a/arch/arm/dts/exynos5800-peach-pi.dts +++ b/arch/arm/dts/exynos5800-peach-pi.dts @@ -79,12 +79,28 @@ }; }; + sound { + compatible = "google,peach-audio-max98090"; + + samsung,model = "PEACH-I2S-MAX98090"; + samsung,audio-codec = <&max98090>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98090 0>; + }; + }; + i2c@12CD0000 { /* i2c7 */ clock-frequency = <100000>; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98090-codec"; - }; + max98090: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98090"; + #sound-dai-cells = <1>; + }; }; sound@3830000 { diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 6a3cd44b5d3..73aa4cdad32 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -345,7 +345,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral) int i; struct clk_bit_info *info; - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) info = exynos542x_bit_info; else info = exynos5_bit_info; @@ -557,7 +557,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) unsigned long clock_get_periph_rate(int peripheral) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos542x_get_periph_rate(peripheral); return exynos5_get_periph_rate(peripheral); } else { @@ -1317,6 +1317,19 @@ int exynos5_set_epll_clk(unsigned long rate) return 0; } +static int exynos5420_set_i2s_clk_source(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + + setbits_le32(&clk->src_top6, EXYNOS5420_CLK_SRC_MOUT_EPLL); + clrsetbits_le32(&clk->src_mau, EXYNOS5420_AUDIO0_SEL_MASK, + (EXYNOS5420_CLK_SRC_SCLK_EPLL)); + setbits_le32(EXYNOS5_AUDIOSS_BASE, 1 << 0); + + return 0; +} + int exynos5_set_i2s_clk_source(unsigned int i2s_id) { struct exynos5_clock *clk = @@ -1575,7 +1588,7 @@ static unsigned long exynos4_get_i2c_clk(void) unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos542x_get_pll_clk(pllreg); return exynos5_get_pll_clk(pllreg); } else if (cpu_is_exynos4()) { @@ -1691,7 +1704,7 @@ void set_mmc_clk(int dev_index, unsigned int div) div -= 1; if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_set_mmc_clk(dev_index, div); else exynos5_set_mmc_clk(dev_index, div); @@ -1739,7 +1752,7 @@ void set_mipi_clk(void) int set_spi_clk(int periph_id, unsigned int rate) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_set_spi_clk(periph_id, rate); return exynos5_set_spi_clk(periph_id, rate); } @@ -1758,8 +1771,12 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, int set_i2s_clk_source(unsigned int i2s_id) { - if (cpu_is_exynos5()) - return exynos5_set_i2s_clk_source(i2s_id); + if (cpu_is_exynos5()) { + if (proid_is_exynos542x()) + return exynos5420_set_i2s_clk_source(); + else + return exynos5_set_i2s_clk_source(i2s_id); + } return 0; } diff --git a/arch/arm/mach-exynos/clock_init_exynos5.c b/arch/arm/mach-exynos/clock_init_exynos5.c index e63ef645239..1cb8d391e7c 100644 --- a/arch/arm/mach-exynos/clock_init_exynos5.c +++ b/arch/arm/mach-exynos/clock_init_exynos5.c @@ -968,7 +968,7 @@ static void exynos5420_system_clock_init(void) void system_clock_init(void) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_system_clock_init(); else exynos5250_system_clock_init(); diff --git a/arch/arm/mach-exynos/common_setup.h b/arch/arm/mach-exynos/common_setup.h index 2829fb269ed..4e3702b9285 100644 --- a/arch/arm/mach-exynos/common_setup.h +++ b/arch/arm/mach-exynos/common_setup.h @@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void) CACHE_TAG_RAM_LATENCY_2_CYCLES | CACHE_DATA_RAM_LATENCY_2_CYCLES; - if (proid_is_exynos5420() || proid_is_exynos5422()) { + if (proid_is_exynos542x()) { val |= CACHE_ECC_AND_PARITY | CACHE_TAG_RAM_LATENCY_3_CYCLES | CACHE_DATA_RAM_LATENCY_3_CYCLES; @@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void) { uint32_t val; - if (proid_is_exynos5420() || proid_is_exynos5422()) { + if (proid_is_exynos542x()) { mrc_l2_aux_ctlr(val); val |= CACHE_ENABLE_FORCE_L2_LOGIC | CACHE_DISABLE_CLEAN_EVICT; diff --git a/arch/arm/mach-exynos/include/mach/clock.h b/arch/arm/mach-exynos/include/mach/clock.h index edf62bdf853..e4c706adeac 100644 --- a/arch/arm/mach-exynos/include/mach/clock.h +++ b/arch/arm/mach-exynos/include/mach/clock.h @@ -1370,10 +1370,13 @@ struct set_epll_con_val { #define AUDIO_1_RATIO_MASK 0x0f #define AUDIO0_SEL_MASK 0xf +#define EXYNOS5420_AUDIO0_SEL_MASK (0x3 << 28) #define AUDIO1_SEL_MASK 0xf #define CLK_SRC_SCLK_EPLL 0x7 +#define EXYNOS5420_CLK_SRC_SCLK_EPLL (0x6 << 28) #define CLK_SRC_MOUT_EPLL (1<<12) +#define EXYNOS5420_CLK_SRC_MOUT_EPLL BIT(20) #define AUDIO_CLKMUX_ASS (1<<0) /* CON0 bit-fields */ diff --git a/arch/arm/mach-exynos/include/mach/cpu.h b/arch/arm/mach-exynos/include/mach/cpu.h index aeb3755fe6b..766edeeb298 100644 --- a/arch/arm/mach-exynos/include/mach/cpu.h +++ b/arch/arm/mach-exynos/include/mach/cpu.h @@ -268,6 +268,8 @@ IS_EXYNOS_TYPE(exynos5250, 0x5250) IS_EXYNOS_TYPE(exynos5420, 0x5420) IS_EXYNOS_TYPE(exynos5422, 0x5422) +#define proid_is_exynos542x() (proid_is_exynos5420() || proid_is_exynos5422()) + #define SAMSUNG_BASE(device, base) \ static inline unsigned long __attribute__((no_instrument_function)) \ samsung_get_base_##device(void) \ @@ -277,7 +279,7 @@ static inline unsigned long __attribute__((no_instrument_function)) \ return EXYNOS4X12_##base; \ return EXYNOS4_##base; \ } else if (cpu_is_exynos5()) { \ - if (proid_is_exynos5420() || proid_is_exynos5422()) \ + if (proid_is_exynos542x()) \ return EXYNOS5420_##base; \ return EXYNOS5_##base; \ } \ diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h index 272e00bae8f..f9975d7919f 100644 --- a/arch/arm/mach-exynos/include/mach/gpio.h +++ b/arch/arm/mach-exynos/include/mach/gpio.h @@ -1397,7 +1397,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = { static inline struct gpio_info *get_gpio_data(void) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_gpio_data; else return exynos5_gpio_data; @@ -1414,7 +1414,7 @@ static inline struct gpio_info *get_gpio_data(void) static inline unsigned int get_bank_num(void) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return EXYNOS5420_GPIO_NUM_PARTS; else return EXYNOS5_GPIO_NUM_PARTS; diff --git a/arch/arm/mach-exynos/pinmux.c b/arch/arm/mach-exynos/pinmux.c index f6743ca0f6e..b24f1bb8f4f 100644 --- a/arch/arm/mach-exynos/pinmux.c +++ b/arch/arm/mach-exynos/pinmux.c @@ -378,6 +378,20 @@ static void exynos5_i2s_config(int peripheral) } } +static void exynos5420_i2s_config(int peripheral) +{ + int i; + + switch (peripheral) { + case PERIPH_ID_I2S0: + for (i = 0; i < 5; i++) + gpio_cfg_pin(EXYNOS5420_GPIO_Z0 + i, + S5P_GPIO_FUNC(0x02)); + break; + } +} + + void exynos5_spi_config(int peripheral) { int cfg = 0, pin = 0, i; @@ -550,6 +564,9 @@ static int exynos5420_pinmux_config(int peripheral, int flags) case PERIPH_ID_I2C10: exynos5420_i2c_config(peripheral); break; + case PERIPH_ID_I2S0: + exynos5420_i2s_config(peripheral); + break; case PERIPH_ID_PWM0: gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_FUNC(2)); break; @@ -863,7 +880,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags) int exynos_pinmux_config(int peripheral, int flags) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_pinmux_config(peripheral, flags); else if (proid_is_exynos5250()) return exynos5_pinmux_config(peripheral, flags); diff --git a/arch/arm/mach-exynos/power.c b/arch/arm/mach-exynos/power.c index 63c410aceff..f2a6c00dd62 100644 --- a/arch/arm/mach-exynos/power.c +++ b/arch/arm/mach-exynos/power.c @@ -124,7 +124,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable) void set_usbdrd_phy_ctrl(unsigned int enable) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_set_usbdev_phy_ctrl(enable); else exynos5_set_usbdrd_phy_ctrl(enable); diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c index c7a8d945492..f668f5379a4 100644 --- a/arch/sandbox/cpu/sdl.c +++ b/arch/sandbox/cpu/sdl.c @@ -4,13 +4,24 @@ */ #include <errno.h> +#include <unistd.h> #include <linux/input.h> #include <SDL/SDL.h> -#include <sound.h> #include <asm/state.h> -enum { - SAMPLE_RATE = 22050, +/** + * struct buf_info - a data buffer holding audio data + * + * @pos: Current position playing in audio buffer + * @size: Size of data in audio buffer (0=empty) + * @alloced: Allocated size of audio buffer (max size it can hold) + * @data: Audio data + */ +struct buf_info { + uint pos; + uint size; + uint alloced; + uint8_t *data; }; static struct sdl_info { @@ -20,12 +31,12 @@ static struct sdl_info { int depth; int pitch; uint frequency; - uint audio_pos; - uint audio_size; uint sample_rate; - uint8_t *audio_data; bool audio_active; bool inited; + int cur_buf; + struct buf_info buf[2]; + bool running; } sdl; static void sandbox_sdl_poll_events(void) @@ -243,24 +254,37 @@ int sandbox_sdl_key_pressed(int keycode) void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len) { + struct buf_info *buf; int avail; + int i; - avail = sdl.audio_size - sdl.audio_pos; - if (avail < len) - len = avail; - - SDL_MixAudio(stream, sdl.audio_data + sdl.audio_pos, len, - SDL_MIX_MAXVOLUME); - sdl.audio_pos += len; - - /* Loop if we are at the end */ - if (sdl.audio_pos == sdl.audio_size) - sdl.audio_pos = 0; + for (i = 0; i < 2; i++) { + buf = &sdl.buf[sdl.cur_buf]; + avail = buf->size - buf->pos; + if (avail <= 0) { + sdl.cur_buf = 1 - sdl.cur_buf; + continue; + } + if (avail > len) + avail = len; + + SDL_MixAudio(stream, buf->data + buf->pos, avail, + SDL_MIX_MAXVOLUME); + buf->pos += avail; + len -= avail; + + /* Move to next buffer if we are at the end */ + if (buf->pos == buf->size) + buf->size = 0; + else + break; + } } -int sandbox_sdl_sound_init(void) +int sandbox_sdl_sound_init(int rate, int channels) { SDL_AudioSpec wanted; + int i; if (sandbox_sdl_ensure_init()) return -1; @@ -269,20 +293,27 @@ int sandbox_sdl_sound_init(void) return 0; /* Set the audio format */ - wanted.freq = SAMPLE_RATE; + wanted.freq = rate; wanted.format = AUDIO_S16; - wanted.channels = 1; /* 1 = mono, 2 = stereo */ + wanted.channels = channels; wanted.samples = 1024; /* Good low-latency value for callback */ wanted.callback = sandbox_sdl_fill_audio; wanted.userdata = NULL; - sdl.audio_size = sizeof(uint16_t) * wanted.freq; - sdl.audio_data = malloc(sdl.audio_size); - if (!sdl.audio_data) { - printf("%s: Out of memory\n", __func__); - return -1; + for (i = 0; i < 2; i++) { + struct buf_info *buf = &sdl.buf[i]; + + buf->alloced = sizeof(uint16_t) * wanted.freq * wanted.channels; + buf->data = malloc(buf->alloced); + if (!buf->data) { + printf("%s: Out of memory\n", __func__); + if (i == 1) + free(sdl.buf[0].data); + return -1; + } + buf->pos = 0; + buf->size = 0; } - sdl.audio_pos = 0; if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { printf("Unable to initialize SDL audio: %s\n", SDL_GetError()); @@ -296,33 +327,50 @@ int sandbox_sdl_sound_init(void) } sdl.audio_active = true; sdl.sample_rate = wanted.freq; + sdl.cur_buf = 0; + sdl.running = 0; return 0; err: - free(sdl.audio_data); + for (i = 0; i < 2; i++) + free(sdl.buf[i].data); return -1; } -int sandbox_sdl_sound_start(uint frequency) +int sandbox_sdl_sound_play(const void *data, uint size) { + struct buf_info *buf; + if (!sdl.audio_active) - return -1; - sdl.frequency = frequency; - sound_create_square_wave(sdl.sample_rate, - (unsigned short *)sdl.audio_data, - sdl.audio_size, frequency); - sdl.audio_pos = 0; - SDL_PauseAudio(0); + return 0; + + buf = &sdl.buf[0]; + if (buf->size) + buf = &sdl.buf[1]; + while (buf->size) + usleep(1000); + + if (size > buf->alloced) + return -E2BIG; + + memcpy(buf->data, data, size); + buf->size = size; + buf->pos = 0; + if (!sdl.running) { + SDL_PauseAudio(0); + sdl.running = 1; + } return 0; } int sandbox_sdl_sound_stop(void) { - if (!sdl.audio_active) - return -1; - SDL_PauseAudio(1); + if (sdl.running) { + SDL_PauseAudio(1); + sdl.running = 0; + } return 0; } diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index ce3c88c221d..ae3189ec8cf 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -18,6 +18,11 @@ stdout-path = "/serial"; }; + audio: audio-codec { + compatible = "sandbox,audio-codec"; + #sound-dai-cells = <1>; + }; + cros_ec: cros-ec { reg = <0 0>; u-boot,dm-pre-reloc; @@ -127,6 +132,11 @@ }; }; + i2s: i2s { + compatible = "sandbox,i2s"; + #sound-dai-cells = <1>; + }; + lcd { u-boot,dm-pre-reloc; compatible = "sandbox,lcd-sdl"; @@ -190,6 +200,17 @@ compatible = "sandbox,reset"; }; + sound { + compatible = "sandbox,sound"; + cpu { + sound-dai = <&i2s 0>; + }; + + codec { + sound-dai = <&audio 0>; + }; + }; + spi@0 { u-boot,dm-pre-reloc; #address-cells = <1>; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 6b1c2692baa..3790b4c5208 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -42,6 +42,11 @@ osd0 = "/osd"; }; + audio: audio-codec { + compatible = "sandbox,audio-codec"; + #sound-dai-cells = <1>; + }; + cros_ec: cros-ec { reg = <0 0>; compatible = "google,cros-ec-sandbox"; @@ -82,6 +87,8 @@ test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>, <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>, <&gpio_b 9 0xc 3 2 1>; + int-value = <1234>; + uint-value = <(-1234)>; }; junk { @@ -373,6 +380,11 @@ u-boot,dm-pre-reloc; }; + i2s: i2s { + compatible = "sandbox,i2s"; + #sound-dai-cells = <1>; + }; + misc-test { compatible = "sandbox,misc_sandbox"; }; @@ -528,6 +540,17 @@ compatible = "sandbox,smem"; }; + sound { + compatible = "sandbox,sound"; + cpu { + sound-dai = <&i2s 0>; + }; + + codec { + sound-dai = <&audio 0>; + }; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h index 1c4380c592a..1027b59e732 100644 --- a/arch/sandbox/include/asm/sdl.h +++ b/arch/sandbox/include/asm/sdl.h @@ -54,12 +54,12 @@ int sandbox_sdl_scan_keys(int key[], int max_keys); int sandbox_sdl_key_pressed(int keycode); /** - * sandbox_sdl_sound_start() - start playing a sound + * sandbox_sdl_sound_play() - Play a sound * - * @frequency: Frequency of sounds in Hertz - * @return 0 if OK, -ENODEV if no sound is available + * @data: Data to play (typically 16-bit) + * @count: Number of bytes in data */ -int sandbox_sdl_sound_start(uint frequency); +int sandbox_sdl_sound_play(const void *data, uint count); /** * sandbox_sdl_sound_stop() - stop playing a sound @@ -71,9 +71,11 @@ int sandbox_sdl_sound_stop(void); /** * sandbox_sdl_sound_init() - set up the sound system * + * @rate: Sample rate to use + * @channels: Number of channels to use (1=mono, 2=stereo) * @return 0 if OK, -ENODEV if no sound is available */ -int sandbox_sdl_sound_init(void); +int sandbox_sdl_sound_init(int rate, int channels); #else static inline int sandbox_sdl_init_display(int width, int height, @@ -102,12 +104,17 @@ static inline int sandbox_sdl_sound_start(uint frequency) return -ENODEV; } +int sandbox_sdl_sound_play(const void *data, uint count) +{ + return -ENODEV; +} + static inline int sandbox_sdl_sound_stop(void) { return -ENODEV; } -static inline int sandbox_sdl_sound_init(void) +int sandbox_sdl_sound_init(int rate, int channels) { return -ENODEV; } diff --git a/arch/sandbox/include/asm/sound.h b/arch/sandbox/include/asm/sound.h deleted file mode 100644 index a6015b0f60f..00000000000 --- a/arch/sandbox/include/asm/sound.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2013 Google, Inc - */ - -#ifndef __SANDBOX_SOUND_H -#define __SANDBOX_SOUND_H - -int sound_play(unsigned int msec, unsigned int frequency); - -int sound_init(const void *blob); - -#endif diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 5e818392959..74f96188220 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -121,4 +121,44 @@ int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp, */ void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask); +/** + * sandbox_get_codec_params() - Read back codec parameters + * + * This reads back the parameters set by audio_codec_set_params() for the + * sandbox audio driver. Arguments are as for that function. + */ +void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep, + int *mclk_freqp, int *bits_per_samplep, + uint *channelsp); + +/** + * sandbox_get_i2s_sum() - Read back the sum of the audio data so far + * + * This data is provided to the sandbox driver by the I2S tx_data() method. + * + * @dev: Device to check + * @return sum of audio data + */ +int sandbox_get_i2s_sum(struct udevice *dev); + +/** + * sandbox_get_setup_called() - Returns the number of times setup(*) was called + * + * This is used in the sound test + * + * @dev: Device to check + * @return call count for the setup() method + */ +int sandbox_get_setup_called(struct udevice *dev); + +/** + * sandbox_get_sound_sum() - Read back the sum of the sound data so far + * + * This data is provided to the sandbox driver by the sound play() method. + * + * @dev: Device to check + * @return sum of audio data + */ +int sandbox_get_sound_sum(struct udevice *dev); + #endif |