sound: Add uclass operations for beeping

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 <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/drivers/sound/sandbox.c b/drivers/sound/sandbox.c
index b0b07f3..6005231 100644
--- a/drivers/sound/sandbox.c
+++ b/drivers/sound/sandbox.c
@@ -24,7 +24,9 @@
 
 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 @@
 	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 @@
 	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 @@
 };
 
 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[] = {