From patchwork Sun Feb 17 03:24:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1043579 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="laT3vyjh"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 442CSX0Fbvz9s3x for ; Sun, 17 Feb 2019 14:40:27 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 8F37DC21EEB; Sun, 17 Feb 2019 03:34:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id BD499C21F05; Sun, 17 Feb 2019 03:28:36 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6447FC21E29; Sun, 17 Feb 2019 03:26:22 +0000 (UTC) Received: from mail-it1-f197.google.com (mail-it1-f197.google.com [209.85.166.197]) by lists.denx.de (Postfix) with ESMTPS id 2739FC21F18 for ; Sun, 17 Feb 2019 03:26:16 +0000 (UTC) Received: by mail-it1-f197.google.com with SMTP id v12so14786961itv.9 for ; Sat, 16 Feb 2019 19:26:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=nWnU4jbQqvGQM+RdrQr2V/eWOwLOc8K0HR76elArPcY=; b=laT3vyjhD2bXDmwCDFEEEy+NZGx9et5ldJfpZQ79vdebMlIdZ/hFEKRXSLdceJ6UsM yTRdRrOhe/n2+GsmO0jxx38wwCyon255iCQmgO1jE8e12oP9bBrQeS9KnK0EOHtfrJ60 DicN5Extre5b9+IhnzoieCd8YDpJHUxa+s1EM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=nWnU4jbQqvGQM+RdrQr2V/eWOwLOc8K0HR76elArPcY=; b=tNVffoTqM1ITyb84oOMlpCoEKZvnB6u4SHg82XX2mtGQQDF9GsUKcAI7bkISNCxApe Y/MakH5HOi5m/fDe3LrX2khtLqpwL+B8agHUdI8fXsxQzreBIHjZMIpehFHKEI3mfaV5 fZD8vnBLE4l5sle94HbKzh1FS+hqiyJCYySTUvUhU0EaanVAf3sGNqArYrtszqYSoJzM zmz3euhsLx1/wcZYQuwMEEd8rzB1AFtbyMPXMUizZDSh9gZqQddlh/0F+W7iGWgmu6Gw LJ7wFAWGES62LAsMEPZk6lbImzu8J6OaTKzX6A5m6TUVLDjuCnsWp70GIMOLfdRD1WHW I8vA== X-Gm-Message-State: AHQUAuaJ80+Jebsci3fOsZQxasmzaBvIztKFzydoxvWgitd11XOWLWRq 96ieOb/T0v2u+V74D61W4PD7BFtDOwLLBX6Y X-Google-Smtp-Source: AHgI3IbrgU4PLfMazBJBZsejNK5ikrgr2hg3Z/qRb8XJwWVNn3VN/J9Wefk4ZoSLq8KzUfnoBC+q0exCZ2WOyfDP X-Received: by 2002:a24:2782:: with SMTP id g124mr10421461ita.26.1550373975132; Sat, 16 Feb 2019 19:26:15 -0800 (PST) Date: Sat, 16 Feb 2019 20:24:54 -0700 In-Reply-To: <20190217032507.124320-1-sjg@chromium.org> Message-Id: <20190217032507.124320-22-sjg@chromium.org> Mime-Version: 1.0 References: <20190217032507.124320-1-sjg@chromium.org> X-Mailer: git-send-email 2.21.0.rc0.258.g878e2cd30e-goog From: Simon Glass To: U-Boot Mailing List Subject: [U-Boot] [PATCH v2 21/34] sound: Add uclass operations for beeping X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Some audio codecs such as Intel HDA do not need to use digital data to play sounds, but instead have a way to emit beeps. Add this interface as an option. If the beep interface is not supported, then the sound uclass falls back to the I2S interface. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Changes in v2: None arch/sandbox/include/asm/test.h | 16 ++++++++++++ drivers/sound/sandbox.c | 46 ++++++++++++++++++++++++++++++--- drivers/sound/sound-uclass.c | 34 +++++++++++++++++++++++- include/sound.h | 44 +++++++++++++++++++++++++++++++ test/dm/sound.c | 21 +++++++++++++++ 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index ce00ba51e47..fc52f47f821 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -161,6 +161,22 @@ int sandbox_get_setup_called(struct udevice *dev); */ int sandbox_get_sound_sum(struct udevice *dev); +/** + * sandbox_set_allow_beep() - Set whether the 'beep' interface is supported + * + * @dev: Device to update + * @allow: true to allow the start_beep() method, false to disallow it + */ +void sandbox_set_allow_beep(struct udevice *dev, bool allow); + +/** + * sandbox_get_beep_frequency() - Get the frequency of the current beep + * + * @dev: Device to check + * @return frequency of beep, if there is an active beep, else 0 + */ +int sandbox_get_beep_frequency(struct udevice *dev); + /** * sandbox_get_pch_spi_protect() - Get the PCI SPI protection status * diff --git a/drivers/sound/sandbox.c b/drivers/sound/sandbox.c index b0b07f3239b..600523160f0 100644 --- a/drivers/sound/sandbox.c +++ b/drivers/sound/sandbox.c @@ -24,7 +24,9 @@ struct sandbox_i2s_priv { struct sandbox_sound_priv { int setup_called; - int sum; /* Use to sum the provided audio data */ + int sum; /* Use to sum the provided audio data */ + bool allow_beep; /* true to allow the start_beep() interface */ + int frequency_hz; /* Beep frequency if active, else 0 */ }; void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep, @@ -61,6 +63,20 @@ int sandbox_get_sound_sum(struct udevice *dev) return priv->sum; } +void sandbox_set_allow_beep(struct udevice *dev, bool allow) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + priv->allow_beep = allow; +} + +int sandbox_get_beep_frequency(struct udevice *dev) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + return priv->frequency_hz; +} + static int sandbox_codec_set_params(struct udevice *dev, int interface, int rate, int mclk_freq, int bits_per_sample, uint channels) @@ -128,6 +144,28 @@ static int sandbox_sound_play(struct udevice *dev, void *data, uint data_size) return i2s_tx_data(uc_priv->i2s, data, data_size); } +int sandbox_sound_start_beep(struct udevice *dev, int frequency_hz) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + if (!priv->allow_beep) + return -ENOSYS; + priv->frequency_hz = frequency_hz; + + return 0; +} + +int sandbox_sound_stop_beep(struct udevice *dev) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + if (!priv->allow_beep) + return -ENOSYS; + priv->frequency_hz = 0; + + return 0; +} + static int sandbox_sound_probe(struct udevice *dev) { return sound_find_codec_i2s(dev); @@ -169,8 +207,10 @@ U_BOOT_DRIVER(sandbox_i2s) = { }; static const struct sound_ops sandbox_sound_ops = { - .setup = sandbox_sound_setup, - .play = sandbox_sound_play, + .setup = sandbox_sound_setup, + .play = sandbox_sound_play, + .start_beep = sandbox_sound_start_beep, + .stop_beep = sandbox_sound_stop_beep, }; static const struct udevice_id sandbox_sound_ids[] = { diff --git a/drivers/sound/sound-uclass.c b/drivers/sound/sound-uclass.c index 067660623b2..d49f29bcd5b 100644 --- a/drivers/sound/sound-uclass.c +++ b/drivers/sound/sound-uclass.c @@ -31,10 +31,30 @@ int sound_play(struct udevice *dev, void *data, uint data_size) return ops->play(dev, data, data_size); } +int sound_start_beep(struct udevice *dev, int frequency_hz) +{ + struct sound_ops *ops = sound_get_ops(dev); + + if (!ops->start_beep) + return -ENOSYS; + + return ops->start_beep(dev, frequency_hz); +} + +int sound_stop_beep(struct udevice *dev) +{ + struct sound_ops *ops = sound_get_ops(dev); + + if (!ops->stop_beep) + return -ENOSYS; + + return ops->stop_beep(dev); +} + int sound_beep(struct udevice *dev, int msecs, int frequency_hz) { struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); - struct i2s_uc_priv *i2s_uc_priv = dev_get_uclass_priv(uc_priv->i2s); + struct i2s_uc_priv *i2s_uc_priv; unsigned short *data; uint data_size; int ret; @@ -43,7 +63,19 @@ int sound_beep(struct udevice *dev, int msecs, int frequency_hz) if (ret && ret != -EALREADY) return ret; + /* Try using the beep interface if available */ + ret = sound_start_beep(dev, frequency_hz); + if (ret != -ENOSYS) { + if (ret) + return ret; + mdelay(msecs); + ret = sound_stop_beep(dev); + + return ret; + } + /* Buffer length computation */ + i2s_uc_priv = dev_get_uclass_priv(uc_priv->i2s); data_size = i2s_uc_priv->samplingrate * i2s_uc_priv->channels; data_size *= (i2s_uc_priv->bitspersample / SOUND_BITS_IN_BYTE); data = malloc(data_size); diff --git a/include/sound.h b/include/sound.h index 7d528c479ef..47de9fa3ed3 100644 --- a/include/sound.h +++ b/include/sound.h @@ -67,6 +67,28 @@ struct sound_ops { * @return 0 if OK, -ve on error */ int (*play)(struct udevice *dev, void *data, uint data_size); + + /** + * start_beep() - Start beeping (optional) + * + * This tells the sound hardware to start a beep. It will continue until + * stopped by sound_stop_beep(). + * + * @dev: Sound device + * @frequency_hz: Beep frequency in hertz + * @return if OK, -ENOSYS if not supported, -ve on error + */ + int (*start_beep)(struct udevice *dev, int frequency_hz); + + /** + * stop_beep() - Stop beeping (optional) + * + * This tells the sound hardware to stop a previously started beep. + * + * @dev: Sound device + * @return if OK, -ve on error + */ + int (*stop_beep)(struct udevice *dev); }; #define sound_get_ops(dev) ((struct sound_ops *)(dev)->driver->ops) @@ -86,6 +108,28 @@ int sound_setup(struct udevice *dev); */ int sound_beep(struct udevice *dev, int msecs, int frequency_hz); +/** + * sound_start_beep() - Start beeping + * + * This tells the sound hardware to start a beep. It will continue until stopped + * by sound_stop_beep(). + * + * @dev: Sound device + * @frequency_hz: Beep frequency in hertz + * @return if OK, -ve on error + */ +int sound_start_beep(struct udevice *dev, int frequency_hz); + +/** + * sound_stop_beep() - Stop beeping + * + * This tells the sound hardware to stop a previously started beep. + * + * @dev: Sound device + * @return if OK, -ve on error + */ +int sound_stop_beep(struct udevice *dev); + /** * sound_find_codec_i2s() - Called by sound drivers to locate codec and i2s * diff --git a/test/dm/sound.c b/test/dm/sound.c index 7d0b36e7a56..3767abbd1c7 100644 --- a/test/dm/sound.c +++ b/test/dm/sound.c @@ -32,3 +32,24 @@ static int dm_test_sound(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_sound, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test of the 'start beep' operations */ +static int dm_test_sound_beep(struct unit_test_state *uts) +{ + struct udevice *dev; + + /* check probe success */ + ut_assertok(uclass_first_device_err(UCLASS_SOUND, &dev)); + ut_asserteq(-ENOSYS, sound_start_beep(dev, 100)); + ut_asserteq(0, sandbox_get_beep_frequency(dev)); + + sandbox_set_allow_beep(dev, true); + ut_asserteq(0, sound_start_beep(dev, 100)); + ut_asserteq(100, sandbox_get_beep_frequency(dev)); + + ut_asserteq(0, sound_stop_beep(dev)); + ut_asserteq(0, sandbox_get_beep_frequency(dev)); + + return 0; +} +DM_TEST(dm_test_sound_beep, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);