From 2ca471379b471dc0d31459974d7cc4b54c824956 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 16 Feb 2019 20:24:55 -0700 Subject: sound: Add support for Intel HDA The Intel High-definition Audio is a newer-generation audio system which provides for transfer of a large number of audio stream, each containing up to 16 channels. Add support for HDA as a library which can be used by other drivers. U-Boot currently uses only two channels (stereo). Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/dt-bindings/sound/azalia.h | 44 ++++++++++++++++ include/hda_codec.h | 103 +++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 include/dt-bindings/sound/azalia.h create mode 100644 include/hda_codec.h (limited to 'include') diff --git a/include/dt-bindings/sound/azalia.h b/include/dt-bindings/sound/azalia.h new file mode 100644 index 0000000000..10ace3ef56 --- /dev/null +++ b/include/dt-bindings/sound/azalia.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Intel HDA audio codec config. This is a mechanicm to configure codecs when + * using Intel HDA audio. + * + * Copyright 2018 Google LLC + * Written by Simon Glass + */ + +#ifndef __AZALIA_H +#define __AZALIA_H + +#define AZALIA_CODEC_SHIFT 28 +#define AZALIA_NID_SHIFT 20 +#define AZALIA_VERB_SHIFT 8 + +/* Supported opcodes */ +#define AZALIA_OPCODE_CONFIG_DEFAULT 0x71c +#define AZALIA_OPCODE_IMPL_ID 0x720 +#define AZALIA_OPCODE_READ_PARAM 0xf00 + +#define AZALIA_PARAM_VENDOR_ID 0 + +/* Generate the register value to write a particular byte of a 32-bit value */ +#define AZALIA_SET_BYTE(codec, nid, opcode, val, byte) \ + ((codec) << AZALIA_CODEC_SHIFT | \ + (nid) << AZALIA_NID_SHIFT | \ + ((opcode) + (byte)) << AZALIA_VERB_SHIFT | \ + (((val) >> ((byte) * 8)) & 0xff)) + +/* Generate the register value to write all bytes of a 32-bit value */ +#define AZALIA_WORD(codec, nid, opcode, val) \ + (AZALIA_SET_BYTE(codec, nid, opcode, val, 0) | \ + AZALIA_SET_BYTE(codec, nid, opcode, val, 1) | \ + AZALIA_SET_BYTE(codec, nid, opcode, val, 2) | \ + AZALIA_SET_BYTE(codec, nid, opcode, val, 3)) + +#define AZALIA_PIN_CFG(codec, nid, val) \ + AZALIA_WORD(codec, nid, AZALIA_OPCODE_CONFIG_DEFAULT, val) + +#define AZALIA_SUBVENDOR(codec, val) \ + AZALIA_WORD(codec, 1, AZALIA_OPCODE_IMPL_ID, val) + +#endif /* __AZALIA_H */ diff --git a/include/hda_codec.h b/include/hda_codec.h new file mode 100644 index 0000000000..56de571f0f --- /dev/null +++ b/include/hda_codec.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for Intel High-Definition Audio codec + * + * Copyright 2018 Google LLC + * + * Taken from coreboot file of the same name + */ + +#ifndef __HDA_CODEC_H_ +#define __HDA_CODEC_H_ + +struct hda_regs; + +/** + * struct hda_codec_priv - Private data required by the HDA codec + * + * @regs: HDA registers + * @beep_nid: Node ID of beep node (>0) + */ +struct hda_codec_priv { + struct hda_regs *regs; + uint beep_nid; +}; + +/** + * hda_wait_for_ready() - Wait for the codec to indicate it is ready + * + * @regs: HDA registers + * @return 0 if OK -ETIMEDOUT if codec did not respond in time + */ +int hda_wait_for_ready(struct hda_regs *regs); + +/** + * hda_wait_for_valid() - Wait for the codec to accept the last command + * + * @regs: HDA registers + * @return 0 if OK -ETIMEDOUT if codec did not respond in time + */ +int hda_wait_for_valid(struct hda_regs *regs); + +/** + * hda_codec_detect() - Detect which codecs are present + * + * @regs: HDA registers + * @return bit mask of active codecs (0 if none) + * @return 0 if OK, -ve on error + */ +int hda_codec_detect(struct hda_regs *regs); + +/** + * hda_codecs_init() - Init all codecs + * + * @dev: Sound device + * @regs: HDA registers + * @codec_mask: Mask of codecs to init (bits 3:0) + * @return 0 if OK, -ve on error + */ +int hda_codecs_init(struct udevice *dev, struct hda_regs *regs, u32 codec_mask); + +/** + * hda_codec_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 hda_codec_start_beep(struct udevice *dev, int frequency_hz); + +/** + * hda_codec_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 hda_codec_stop_beep(struct udevice *dev); + +/** + * hda_codec_init() - Set up the HDA codec base address + * + * This should be called at the start of the probe() method. + * + * @dev: Sound device + * @return 0 if OK, -ve on error + */ +int hda_codec_init(struct udevice *dev); + +/** + * hda_codec_finish_init() - Finish setting up the HDA codec base address + * + * This should be called at the end of the probe() method. + * + * @dev: Sound device + * @return 0 if OK, -ve on error + */ +int hda_codec_finish_init(struct udevice *dev); + +#endif /* __HDA_CODEC_H_ */ -- cgit v1.2.3