blob: 4235866f25373899f55abaa3483fdfe8c56072e7 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_COMMON_AML_AUDIO_H_
#define SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_COMMON_AML_AUDIO_H_
#include <zircon/device/audio.h>
namespace metadata {
static constexpr uint32_t kMaxNumberOfLanes = 4;
static constexpr uint32_t kMaxAmlConfigString = 32;
enum class AmlVersion : uint32_t {
kS905D2G = 1, // Also works with T931G.
kS905D3G = 2,
kA5 = 3,
kA1 = 4,
kA311D = 5,
};
enum class AmlAudioBlock : uint32_t {
TDMIN_A,
TDMIN_B,
TDMIN_C,
TDMOUT_A,
TDMOUT_B,
TDMOUT_C,
PDMIN,
PDMIN_VAD,
};
enum class AmlBus : uint32_t {
TDM_A = 1,
TDM_B = 2,
TDM_C = 3,
};
enum class AmlTdmclk : uint32_t {
CLK_A = 0,
CLK_B = 1,
CLK_C = 2,
CLK_D = 3,
CLK_E = 4,
CLK_F = 5,
};
enum class AmlTdmMclkPad : uint32_t {
MCLK_PAD_0 = 0,
MCLK_PAD_1 = 1,
MCLK_PAD_2 = 2,
};
enum class AmlTdmSclkPad : uint32_t {
SCLK_PAD_0 = 0,
SCLK_PAD_1 = 1,
SCLK_PAD_2 = 2,
};
enum class AmlTdmDatPad : uint32_t {
TDM_D4 = 4,
TDM_D5 = 5,
TDM_D8 = 8,
TDM_D9 = 9,
TDM_D10 = 10,
TDM_D11 = 11,
};
struct AmlLoopbackConfig {
// If Enable Loopback, select source for TDMIN_LB.
// e.g.
// tdminlb_src = TDMOUT_B.
//
// [Data Flow as follow]:
// `==>` : Play data flow.
// `-->` : Loopback data flow.
//
// | (To Codec or BT)
// |
// +--------+ +-------+ +--------+ | +----------+
// | player | ==> |FRDDR_*| ==> |TDMOUT_B| ========0======+=> |PAD to Pin|
// +--------+ +-------+ +--------+ | | +----------+
// (reflow) | |
// | |
// | |
// datalb v |
// +--------+ +-------+ +--------+ +--------+ |
// | record | <-- |TODDR_*| <-- |LOOPBACK| <-- |TDMIN_LB| |
// +--------+ +-------+ +--------+ +--------+ |
// ^ |
// | +---------+ |
// -------|PDM/TDMIN|
// datain +---------+
//
AmlAudioBlock datain_src;
uint8_t datain_chnum;
uint32_t datain_chmask;
AmlAudioBlock datalb_src;
uint8_t datalb_chnum;
uint32_t datalb_chmask;
};
static constexpr uint32_t kMaxNumberOfChannelsInRingBuffer = 64;
static constexpr uint32_t kMaxNumberOfCodecs = 8;
static constexpr uint32_t kMaxNumberOfExternalDelays = 8;
enum class CodecType : uint32_t {
Tas27xx,
Tas5782,
Tas58xx,
Tas5720,
Tas5707,
};
// Same as //sdk/fidl/fuchsia.hardware.audio/dai_format.fidl
enum class DaiType : uint32_t {
I2s,
StereoLeftJustified,
Tdm1,
Tdm2,
Tdm3,
};
enum class SampleFormat : uint32_t {
PcmSigned, // Default for zeroed out metadata.
PcmUnsigned,
PcmFloat,
};
struct ExternalDelay {
uint32_t frequency;
int64_t nsecs;
};
struct FrequencyRange {
uint32_t min_frequency;
uint32_t max_frequency;
};
struct RingBuffer {
uint8_t number_of_channels;
uint8_t bytes_per_sample; // If not specified (set to 0), then 2 bytes.
FrequencyRange frequency_ranges[kMaxNumberOfChannelsInRingBuffer]; // Optional.
};
struct Dai {
DaiType type;
uint8_t number_of_channels; // If not specified (set to 0), then 2 for stereo types like I2S.
SampleFormat sample_format; // Defaults to PcmSigned.
uint8_t bits_per_sample; // If not specified (set to 0), then 16 bits.
uint8_t bits_per_slot; // If not specified (set to 0), then 32 bits.
bool sclk_on_raising; // Invert the usual clocking out on falling edge.
};
struct Codecs {
uint8_t number_of_codecs;
CodecType types[kMaxNumberOfCodecs];
float delta_gains[kMaxNumberOfCodecs];
uint32_t number_of_external_delays;
ExternalDelay external_delays[kMaxNumberOfExternalDelays];
// Channels to enable in each codec as a bitmask of the channels in the DAI.
// The least significant bit correspond to the left most channel in the DAI.
uint8_t channels_to_use_bitmask[kMaxNumberOfCodecs];
// Defines mapping between ring buffer channels and codecs using them.
// Used for stopping codecs corresponding to the ring buffer channels to use bitmask.
// Each ring buffer channel to use is represented as a bit, the least significant bit
// corresponds to index 0.
uint64_t ring_buffer_channels_to_use_bitmask[kMaxNumberOfCodecs];
};
struct AmlConfig {
char manufacturer[kMaxAmlConfigString];
char product_name[kMaxAmlConfigString];
bool is_input;
bool is_loopback;
AmlLoopbackConfig loopback;
// If false, it will use HIFI_PLL by default.
// If true, it will use MP0_PLL
bool is_custom_tdm_src_clk_sel;
// If false, it will use same suffix channel by default.
// e.g.
// TDMOUT_A -> MCLK_A -> SCLK_A -> LRCLK_A
// TDMOUT_B -> MCLK_B -> SCLK_B -> LRCLK_B
// TDMOUT_C -> MCLK_C -> SCLK_C -> LRCLK_C
// If true, select the channel you want.
// e.g.
// TDMOUT_A -> MCLK_C -> SCLK_C -> LRCLK_C
//
bool is_custom_tdm_clk_sel;
AmlTdmclk tdm_clk_sel;
// If false, it will use MCLK_PAD_0 by default.
// TDMOUT_A/B/C -> MCLK_PAD_0
// If true, according to board layout design (which pin you used?)
// then select the right mclk_pad.
// e.g.
// TDMOUT_A -> MCLK_PAD_2
//
bool is_custom_tdm_mpad_sel;
AmlTdmMclkPad mpad_sel;
// If false, it will use same suffix channel by default.
// TDMOUT_A -> SCLK_PAD_0 -> LRCLK_PAD_0
// TDMOUT_B -> SCLK_PAD_1 -> LRCLK_PAD_1
// TDMOUT_C -> SCLK_PAD_2 -> LRCLK_PAD_2
// If true, according to board layout design (which pins you used?)
// then select the right sclk_pad, lrclk_pad.
// e.g.
// TDMOUT_A -> SCLK_PAD_2, LRCLK_PAD_2
//
bool is_custom_tdm_spad_sel;
AmlTdmSclkPad spad_sel;
// dpad_mask: support 8x data lane out select.
// bit[7:0] : lane0 ~ lane7.
// each lane can choose one of tmd_out(32 channel).
// e.g. use 4 lane (tdmoutb)
// Note: tdm_d2/d3 -> pin function
//
// - / LANE_0 -> tdm_d2 -> GPIOC_0 -> codec sdin_0
// |d| / LANE_1 -> tdm_d3 -> GPIOC_1 -> codec sdin_1
// |a| =>
// |t| \ LANE_2 -> tdm_d4 -> GPIOC_5 -> codec sdin_2
// |a| \ LANE_3 -> tdm_d5 -> GPIOC_6 -> codec sdin_3
// -
//
uint8_t dpad_mask;
AmlTdmDatPad dpad_sel[kMaxNumberOfLanes];
uint32_t mClockDivFactor;
uint32_t sClockDivFactor;
audio_stream_unique_id_t unique_id;
uint32_t swaps; // Configures routing, one channel per nibble.
// Lanes is a AMLogic specific concept allowing routing to different input/outputs, for instance
// 2 lanes can be used to send audio to 2 different DAI interfaces. What bits are enabled in
// lanes_enable_mask defines what is read/write from/to the ring buffer and routed to each lane.
uint32_t lanes_enable_mask[kMaxNumberOfLanes];
AmlBus bus;
AmlVersion version;
RingBuffer ring_buffer;
Dai dai;
Codecs codecs;
// Configures L+R mixing, one bit per channel pair.
uint8_t mix_mask;
};
struct AmlPdmConfig {
char manufacturer[kMaxAmlConfigString];
char product_name[kMaxAmlConfigString];
uint8_t number_of_channels; // Total number of channels in the ring buffer.
AmlVersion version;
uint32_t sysClockDivFactor;
uint32_t dClockDivFactor;
};
} // namespace metadata
#endif // SRC_DEVICES_LIB_AMLOGIC_INCLUDE_SOC_AML_COMMON_AML_AUDIO_H_