[audio][mt8167s] Convert mt8167s drivers to composite
mt8167-tdm-input and mt8167-tdm-output now use composite protocol
to access I2C and GPIO.
TEST: "audio record" and "audio play" on cleo
Change-Id: Idf0a7a74b52b127eb796a61e7be68d6defe3c192
diff --git a/zircon/system/dev/audio/mt8167-tdm-input/BUILD.gn b/zircon/system/dev/audio/mt8167-tdm-input/BUILD.gn
index 1e02347..944167e 100644
--- a/zircon/system/dev/audio/mt8167-tdm-input/BUILD.gn
+++ b/zircon/system/dev/audio/mt8167-tdm-input/BUILD.gn
@@ -8,7 +8,7 @@
"tlv320adc.cpp",
]
deps = [
- "$zx/system/banjo/ddk-protocol-clock",
+ "$zx/system/banjo/ddk-protocol-composite",
"$zx/system/banjo/ddk-protocol-gpio",
"$zx/system/banjo/ddk-protocol-i2c",
"$zx/system/banjo/ddk-protocol-platform-device",
diff --git a/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.cpp b/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.cpp
index 6e8012b..b037f45 100644
--- a/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.cpp
+++ b/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.cpp
@@ -11,11 +11,19 @@
#include <ddk/debug.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
+#include <ddk/protocol/composite.h>
#include <soc/mt8167/mt8167-clk-regs.h>
namespace audio {
namespace mt8167 {
+enum {
+ COMPONENT_PDEV,
+ COMPONENT_I2C,
+ COMPONENT_GPIO,
+ COMPONENT_COUNT,
+};
+
// Expects 2 mics.
constexpr size_t kNumberOfChannels = 2;
constexpr size_t kMinSampleRate = 8000;
@@ -25,7 +33,7 @@
kMaxSampleRate * 2 * kNumberOfChannels, PAGE_SIZE);
Mt8167AudioStreamIn::Mt8167AudioStreamIn(zx_device_t* parent)
- : SimpleAudioStream(parent, true /* is input */), pdev_(parent) {
+ : SimpleAudioStream(parent, true /* is input */) {
}
zx_status_t Mt8167AudioStreamIn::Init() {
@@ -60,31 +68,40 @@
}
zx_status_t Mt8167AudioStreamIn::InitPdev() {
+ composite_protocol_t composite;
+
+ auto status = device_get_protocol(parent(), ZX_PROTOCOL_COMPOSITE, &composite);
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "Could not get composite protocol\n");
+ return status;
+ }
+
+ zx_device_t* components[COMPONENT_COUNT];
+ size_t actual;
+ composite_get_components(&composite, components, countof(components), &actual);
+ if (actual != countof(components)) {
+ zxlogf(ERROR, "could not get components\n");
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+
+ pdev_ = components[COMPONENT_PDEV];
if (!pdev_.is_valid()) {
return ZX_ERR_NO_RESOURCES;
}
- for (unsigned i = 0; i < kClockCount; i++) {
- clks_[i] = pdev_.GetClk(i);
- if (!clks_[i].is_valid()) {
- zxlogf(ERROR, "%s failed to allocate clk\n", __FUNCTION__);
- return ZX_ERR_NO_RESOURCES;
- }
- }
-
- codec_reset_ = pdev_.GetGpio(0);
+ codec_reset_ = components[COMPONENT_GPIO];
if (!codec_reset_.is_valid()) {
zxlogf(ERROR, "%s failed to allocate gpio\n", __FUNCTION__);
return ZX_ERR_NO_RESOURCES;
}
- codec_ = Tlv320adc::Create(pdev_, 0); // ADC for TDM in.
+ codec_ = Tlv320adc::Create(components[COMPONENT_I2C], 0); // ADC for TDM in.
if (!codec_) {
zxlogf(ERROR, "%s could not get Tlv320adc\n", __func__);
return ZX_ERR_NO_RESOURCES;
}
- zx_status_t status = pdev_.GetBti(0, &bti_);
+ status = pdev_.GetBti(0, &bti_);
if (status != ZX_OK) {
zxlogf(ERROR, "%s could not obtain bti %d\n", __func__, status);
return status;
@@ -125,10 +142,6 @@
mt_audio_->SetBuffer(pinned_ring_buffer_.region(0).phys_addr,
pinned_ring_buffer_.region(0).size);
- // Disables aud1 clk gating: 0 is the index, board_mt8167::kClkRgAud1.
- clks_[kClkRgAud1].Enable();
- // Disables aud2 clk gating: 1 is the index, board_mt8167::kClkRgAud2.
- clks_[kClkRgAud2].Enable();
return ZX_OK;
}
@@ -280,7 +293,8 @@
};
// clang-format off
-ZIRCON_DRIVER_BEGIN(mt8167_audio_in, mt_audio_in_driver_ops, "zircon", "0.1", 3)
+ZIRCON_DRIVER_BEGIN(mt8167_audio_in, mt_audio_in_driver_ops, "zircon", "0.1", 4)
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_COMPOSITE),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_MEDIATEK),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_MEDIATEK_8167S_REF),
BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_MEDIATEK_AUDIO_IN),
diff --git a/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.h b/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.h
index dbe13de..a33186d 100644
--- a/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.h
+++ b/zircon/system/dev/audio/mt8167-tdm-input/audio-stream-in.h
@@ -35,12 +35,6 @@
zx_status_t InitPost() override;
private:
- enum {
- kClkRgAud1,
- kClkRgAud2,
- kClockCount,
- };
-
friend class SimpleAudioStream;
friend class fbl::RefPtr<Mt8167AudioStreamIn>;
@@ -55,7 +49,6 @@
uint32_t us_per_notification_ = 0;
fbl::RefPtr<dispatcher::Timer> notify_timer_;
ddk::PDev pdev_ TA_GUARDED(domain_->token());
- ddk::ClockProtocolClient clks_[kClockCount];
std::unique_ptr<Tlv320adc> codec_;
zx::vmo ring_buffer_vmo_ TA_GUARDED(domain_->token());
fzl::PinnedVmo pinned_ring_buffer_ TA_GUARDED(domain_->token());
diff --git a/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.cpp b/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.cpp
index d3c2ced..a0ac035 100644
--- a/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.cpp
+++ b/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.cpp
@@ -17,13 +17,7 @@
constexpr float Tlv320adc::kMaxGain;
constexpr float Tlv320adc::kMinGain;
-std::unique_ptr<Tlv320adc> Tlv320adc::Create(ddk::PDev pdev, uint32_t i2c_index) {
- auto i2c = pdev.GetI2c(i2c_index);
- if (!i2c.is_valid()) {
- zxlogf(ERROR, "%s failed to allocate i2c\n", __func__);
- return nullptr;
- }
-
+std::unique_ptr<Tlv320adc> Tlv320adc::Create(const ddk::I2cChannel& i2c, uint32_t i2c_index) {
fbl::AllocChecker ac;
auto ptr = std::unique_ptr<Tlv320adc>(new (&ac) Tlv320adc(i2c));
if (!ac.check()) {
diff --git a/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.h b/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.h
index f1188d6..d084c60 100644
--- a/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.h
+++ b/zircon/system/dev/audio/mt8167-tdm-input/tlv320adc.h
@@ -8,14 +8,14 @@
#include <ddk/debug.h>
#include <ddk/protocol/i2c.h>
-#include <ddktl/pdev.h>
+#include <ddktl/i2c-channel.h>
namespace audio {
namespace mt8167 {
class Tlv320adc {
public:
- static std::unique_ptr<Tlv320adc> Create(ddk::PDev pdev, uint32_t i2c_index);
+ static std::unique_ptr<Tlv320adc> Create(const ddk::I2cChannel& i2c, uint32_t i2c_index);
explicit Tlv320adc(const ddk::I2cChannel& i2c)
: i2c_(i2c) {}
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/BUILD.gn b/zircon/system/dev/audio/mt8167-tdm-output/BUILD.gn
index e593b4f..fbcf042 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/BUILD.gn
+++ b/zircon/system/dev/audio/mt8167-tdm-output/BUILD.gn
@@ -9,7 +9,7 @@
"tas5805.cpp",
]
deps = [
- "$zx/system/banjo/ddk-protocol-clock",
+ "$zx/system/banjo/ddk-protocol-composite",
"$zx/system/banjo/ddk-protocol-gpio",
"$zx/system/banjo/ddk-protocol-i2c",
"$zx/system/banjo/ddk-protocol-platform-device",
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.cpp b/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.cpp
index a4b2932..94a8383 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.cpp
+++ b/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.cpp
@@ -13,6 +13,7 @@
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddktl/metadata/audio.h>
+#include <ddk/protocol/composite.h>
#include <soc/mt8167/mt8167-clk-regs.h>
#include "tas5782.h"
@@ -21,6 +22,15 @@
namespace audio {
namespace mt8167 {
+enum {
+ COMPONENT_PDEV,
+ COMPONENT_I2C,
+ COMPONENT_RESET_GPIO, // This is optional
+ COMPONENT_MUTE_GPIO, // This is optional
+ COMPONENT_COUNT,
+};
+
+
// Expects L+R.
constexpr size_t kNumberOfChannels = 2;
// Calculate ring buffer size for 1 second of 16-bit, 48kHz.
@@ -32,37 +42,51 @@
}
zx_status_t Mt8167AudioStreamOut::InitPdev() {
+ composite_protocol_t composite;
+
+ auto status = device_get_protocol(parent(), ZX_PROTOCOL_COMPOSITE, &composite);
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "Could not get composite protocol\n");
+ return status;
+ }
+
+ zx_device_t* components[COMPONENT_COUNT] = {};
+ size_t actual;
+ composite_get_components(&composite, components, countof(components), &actual);
+ // Only PDEV and I2C components are required.
+ if (actual < 2) {
+ zxlogf(ERROR, "could not get components\n");
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+
+ pdev_ = components[COMPONENT_PDEV];
if (!pdev_.is_valid()) {
return ZX_ERR_NO_RESOURCES;
}
- size_t actual = 0;
metadata::Codec codec;
- zx_status_t status = device_get_metadata(parent(), DEVICE_METADATA_PRIVATE, &codec,
- sizeof(metadata::Codec), &actual);
+ status = device_get_metadata(parent(), DEVICE_METADATA_PRIVATE, &codec, sizeof(metadata::Codec),
+ &actual);
if (status != ZX_OK || sizeof(metadata::Codec) != actual) {
zxlogf(ERROR, "%s device_get_metadata failed %d\n", __FILE__, status);
return status;
}
- clk_ = pdev_.GetClk(0);
- if (!clk_.is_valid()) {
- zxlogf(ERROR, "%s failed to allocate clk\n", __FUNCTION__);
- return ZX_ERR_NO_RESOURCES;
- }
- clk_.Enable(); // board_mt8167::kClkRgAud1, disables clk gating.
-
// TODO(andresoportus): Move GPIO control to codecs?
// Not all codecs have these GPIOs.
- codec_reset_ = pdev_.GetGpio(0);
- codec_mute_ = pdev_.GetGpio(1);
+ if (components[COMPONENT_RESET_GPIO]) {
+ codec_reset_ = components[COMPONENT_RESET_GPIO];
+ }
+ if (components[COMPONENT_MUTE_GPIO]) {
+ codec_mute_ = components[COMPONENT_MUTE_GPIO];
+ }
if (codec == metadata::Codec::Tas5782) {
zxlogf(INFO, "audio: using TAS5782 codec\n");
- codec_ = Tas5782::Create(pdev_, 0);
+ codec_ = Tas5782::Create(components[COMPONENT_I2C], 0);
} else if (codec == metadata::Codec::Tas5805) {
zxlogf(INFO, "audio: using TAS5805 codec\n");
- codec_ = Tas5805::Create(pdev_, 0);
+ codec_ = Tas5805::Create(components[COMPONENT_I2C], 0);
} else {
zxlogf(ERROR, "%s could not get codec\n", __FUNCTION__);
return ZX_ERR_NO_RESOURCES;
@@ -328,7 +352,8 @@
};
// clang-format off
-ZIRCON_DRIVER_BEGIN(mt8167_audio_out, mt_audio_out_driver_ops, "zircon", "0.1", 3)
+ZIRCON_DRIVER_BEGIN(mt8167_audio_out, mt_audio_out_driver_ops, "zircon", "0.1", 4)
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_COMPOSITE),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_MEDIATEK),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_MEDIATEK_8167S_REF),
BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_MEDIATEK_AUDIO_OUT),
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.h b/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.h
index d879c1f..1ed52df 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.h
+++ b/zircon/system/dev/audio/mt8167-tdm-output/audio-stream-out.h
@@ -60,7 +60,6 @@
uint32_t us_per_notification_ = 0;
fbl::RefPtr<dispatcher::Timer> notify_timer_;
ddk::PDev pdev_ TA_GUARDED(domain_->token());
- ddk::ClockProtocolClient clk_;
std::unique_ptr<Codec> codec_;
zx::vmo ring_buffer_vmo_ TA_GUARDED(domain_->token());
fzl::PinnedVmo pinned_ring_buffer_ TA_GUARDED(domain_->token());
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/tas5782.cpp b/zircon/system/dev/audio/mt8167-tdm-output/tas5782.cpp
index b292a4e..865a3ae 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/tas5782.cpp
+++ b/zircon/system/dev/audio/mt8167-tdm-output/tas5782.cpp
@@ -19,13 +19,7 @@
constexpr float Tas5782::kMaxGain;
constexpr float Tas5782::kMinGain;
-std::unique_ptr<Tas5782> Tas5782::Create(ddk::PDev pdev, uint32_t i2c_index) {
- auto i2c = pdev.GetI2c(i2c_index);
- if (!i2c.is_valid()) {
- zxlogf(ERROR, "%s failed to allocate i2c\n", __func__);
- return nullptr;
- }
-
+std::unique_ptr<Tas5782> Tas5782::Create(ddk::I2cChannel i2c, uint32_t i2c_index) {
fbl::AllocChecker ac;
auto ptr = std::unique_ptr<Tas5782>(new (&ac) Tas5782(i2c));
if (!ac.check()) {
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/tas5782.h b/zircon/system/dev/audio/mt8167-tdm-output/tas5782.h
index e107025..f70dbf0 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/tas5782.h
+++ b/zircon/system/dev/audio/mt8167-tdm-output/tas5782.h
@@ -8,7 +8,7 @@
#include <ddk/debug.h>
#include <ddk/protocol/i2c.h>
-#include <ddktl/pdev.h>
+#include <ddktl/i2c-channel.h>
#include "codec.h"
@@ -17,7 +17,7 @@
class Tas5782 final : public Codec {
public:
- static std::unique_ptr<Tas5782> Create(ddk::PDev pdev, uint32_t i2c_index);
+ static std::unique_ptr<Tas5782> Create(ddk::I2cChannel i2c, uint32_t i2c_index);
explicit Tas5782(const ddk::I2cChannel& i2c)
: i2c_(i2c) {}
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/tas5805.cpp b/zircon/system/dev/audio/mt8167-tdm-output/tas5805.cpp
index 83235cf..b748606 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/tas5805.cpp
+++ b/zircon/system/dev/audio/mt8167-tdm-output/tas5805.cpp
@@ -34,13 +34,7 @@
namespace audio {
namespace mt8167 {
-std::unique_ptr<Tas5805> Tas5805::Create(ddk::PDev pdev, uint32_t i2c_index) {
- auto i2c = pdev.GetI2c(i2c_index);
- if (!i2c.is_valid()) {
- zxlogf(ERROR, "%s failed to allocate i2c\n", __func__);
- return nullptr;
- }
-
+std::unique_ptr<Tas5805> Tas5805::Create(ddk::I2cChannel i2c, uint32_t i2c_index) {
fbl::AllocChecker ac;
auto ptr = std::unique_ptr<Tas5805>(new (&ac) Tas5805(i2c));
if (!ac.check()) {
diff --git a/zircon/system/dev/audio/mt8167-tdm-output/tas5805.h b/zircon/system/dev/audio/mt8167-tdm-output/tas5805.h
index d8ada96..eecad1a 100644
--- a/zircon/system/dev/audio/mt8167-tdm-output/tas5805.h
+++ b/zircon/system/dev/audio/mt8167-tdm-output/tas5805.h
@@ -8,7 +8,7 @@
#include <ddk/debug.h>
#include <ddk/protocol/i2c.h>
-#include <ddktl/pdev.h>
+#include <ddktl/i2c-channel.h>
#include "codec.h"
@@ -17,7 +17,7 @@
class Tas5805 final : public Codec {
public:
- static std::unique_ptr<Tas5805> Create(ddk::PDev pdev, uint32_t i2c_index);
+ static std::unique_ptr<Tas5805> Create(ddk::I2cChannel i2c, uint32_t i2c_index);
explicit Tas5805(const ddk::I2cChannel& i2c)
: i2c_(i2c) {}
diff --git a/zircon/system/dev/board/mt8167s_ref/BUILD.gn b/zircon/system/dev/board/mt8167s_ref/BUILD.gn
index 7678c6ab..a218b5e 100644
--- a/zircon/system/dev/board/mt8167s_ref/BUILD.gn
+++ b/zircon/system/dev/board/mt8167s_ref/BUILD.gn
@@ -24,6 +24,7 @@
"mt8167.cpp",
]
deps = [
+ "$zx/system/banjo/ddk-protocol-clockimpl",
"$zx/system/banjo/ddk-protocol-gpio",
"$zx/system/banjo/ddk-protocol-gpioimpl",
"$zx/system/banjo/ddk-protocol-platform-bus",
diff --git a/zircon/system/dev/board/mt8167s_ref/mt8167-audio.cpp b/zircon/system/dev/board/mt8167s_ref/mt8167-audio.cpp
index 45eca05..fb9f50e 100644
--- a/zircon/system/dev/board/mt8167s_ref/mt8167-audio.cpp
+++ b/zircon/system/dev/board/mt8167s_ref/mt8167-audio.cpp
@@ -4,12 +4,14 @@
#include <limits.h>
+#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/gpio.h>
#include <ddktl/metadata/audio.h>
+#include <ddktl/protocol/clockimpl.h>
#include <fbl/algorithm.h>
#include <hwreg/bitfields.h>
#include <soc/mt8167/mt8167-clk.h>
@@ -38,6 +40,75 @@
DEF_FIELD(18, 16, status);
};
+constexpr zx_bind_inst_t root_match[] = {
+ BI_MATCH(),
+};
+static const zx_bind_inst_t in_i2c_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
+ BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 1),
+ BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x1B),
+};
+static const zx_bind_inst_t mt8167s_out_i2c_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
+ BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 2),
+ BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x48),
+};
+static const zx_bind_inst_t cleo_out_i2c_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_I2C),
+ BI_ABORT_IF(NE, BIND_I2C_BUS_ID, 2),
+ BI_MATCH_IF(EQ, BIND_I2C_ADDRESS, 0x2C),
+};
+static const device_component_part_t in_i2c_component[] = {
+ { fbl::count_of(root_match), root_match },
+ { fbl::count_of(in_i2c_match), in_i2c_match },
+};
+static const device_component_part_t mt8167s_out_i2c_component[] = {
+ { fbl::count_of(root_match), root_match },
+ { fbl::count_of(mt8167s_out_i2c_match), mt8167s_out_i2c_match },
+};
+static const device_component_part_t cleo_out_i2c_component[] = {
+ { fbl::count_of(root_match), root_match },
+ { fbl::count_of(cleo_out_i2c_match), cleo_out_i2c_match },
+};
+
+static const zx_bind_inst_t in_gpio_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
+ BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO24_EINT24),
+};
+static const zx_bind_inst_t mt8167s_out_reset_gpio_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
+ BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO107_MSDC1_DAT1),
+};
+static const zx_bind_inst_t mt8167s_out_mute_gpio_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
+ BI_MATCH_IF(EQ, BIND_GPIO_PIN, MT8167_GPIO108_MSDC1_DAT2),
+};
+static const device_component_part_t in_gpio_component[] = {
+ { countof(root_match), root_match },
+ { countof(in_gpio_match), in_gpio_match },
+};
+static const device_component_part_t mt8167s_out_reset_gpio_component[] = {
+ { countof(root_match), root_match },
+ { countof(mt8167s_out_reset_gpio_match), mt8167s_out_reset_gpio_match },
+};
+static const device_component_part_t mt8167s_out_mute_gpio_component[] = {
+ { countof(root_match), root_match },
+ { countof(mt8167s_out_mute_gpio_match), mt8167s_out_mute_gpio_match },
+};
+
+static const device_component_t in_components[] = {
+ { countof(in_i2c_component), in_i2c_component },
+ { countof(in_gpio_component), in_gpio_component },
+};
+static const device_component_t mt8167s_ref_out_components[] = {
+ { countof(mt8167s_out_i2c_component), mt8167s_out_i2c_component },
+ { countof(mt8167s_out_reset_gpio_component), mt8167s_out_reset_gpio_component },
+ { countof(mt8167s_out_mute_gpio_component), mt8167s_out_mute_gpio_component },
+};
+static const device_component_t cleo_out_components[] = {
+ { countof(cleo_out_i2c_component), cleo_out_i2c_component },
+};
+
zx_status_t Mt8167::AudioInit() {
if (board_info_.pid != PDEV_PID_MEDIATEK_8167S_REF &&
board_info_.pid != PDEV_PID_CLEO) {
@@ -60,10 +131,6 @@
.length = MT8167_PLL_SIZE,
},
};
- static constexpr pbus_clk_t clks[] = {
- {.clk = board_mt8167::kClkRgAud1},
- {.clk = board_mt8167::kClkRgAud2},
- };
static constexpr pbus_bti_t btis_out[] = {
{
@@ -72,23 +139,12 @@
},
};
- constexpr pbus_gpio_t gpios_in[] = {
- {
- .gpio = MT8167_GPIO24_EINT24, // ~ADC_RESET.
- },
- };
static constexpr pbus_bti_t btis_in[] = {
{
.iommu_index = 0,
.bti_id = BTI_AUDIO_IN,
},
};
- static constexpr pbus_i2c_channel_t i2cs_in[] = {
- {
- .bus_id = 1,
- .address = 0x1B,
- },
- };
metadata::Codec out_codec = metadata::Codec::Tas5782; // Default to PDEV_PID_MEDIATEK_8167S_REF.
if (board_info_.pid == PDEV_PID_CLEO) {
@@ -109,50 +165,11 @@
dev_out.did = PDEV_DID_MEDIATEK_AUDIO_OUT;
dev_out.mmio_list = mmios;
dev_out.mmio_count = countof(mmios);
- dev_out.clk_list = clks;
- dev_out.clk_count = countof(clks);
dev_out.bti_list = btis_out;
dev_out.bti_count = countof(btis_out);
dev_out.metadata_list = out_metadata;
dev_out.metadata_count = countof(out_metadata);
- pbus_gpio_t mt8167s_ref_gpios_out[] = {
- {
- .gpio = MT8167_GPIO107_MSDC1_DAT1, // ~AMP_RESET.
- },
- {
- .gpio = MT8167_GPIO108_MSDC1_DAT2, // ~AMP_MUTE.
- },
- };
- // No reset/mute on Cleo.
- if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
- dev_out.gpio_list = mt8167s_ref_gpios_out;
- dev_out.gpio_count = countof(mt8167s_ref_gpios_out);
- } else {
- dev_out.gpio_list = nullptr;
- dev_out.gpio_count = 0;
- }
-
- pbus_i2c_channel_t mt8167s_ref_i2cs_out[] = {
- {
- .bus_id = 2,
- .address = 0x48,
- },
- };
- pbus_i2c_channel_t cleo_i2cs_out[] = {
- {
- .bus_id = 2,
- .address = 0x2C,
- },
- };
- if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
- dev_out.i2c_channel_list = mt8167s_ref_i2cs_out;
- dev_out.i2c_channel_count = countof(mt8167s_ref_i2cs_out);
- } else {
- dev_out.i2c_channel_list = cleo_i2cs_out;
- dev_out.i2c_channel_count = countof(cleo_i2cs_out);
- }
-
pbus_dev_t dev_in = {};
dev_in.name = "mt8167-audio-in";
dev_in.vid = PDEV_VID_MEDIATEK;
@@ -160,14 +177,8 @@
dev_in.did = PDEV_DID_MEDIATEK_AUDIO_IN;
dev_in.mmio_list = mmios;
dev_in.mmio_count = countof(mmios);
- dev_in.clk_list = clks;
- dev_in.clk_count = countof(clks);
- dev_in.gpio_list = gpios_in;
- dev_in.gpio_count = countof(gpios_in);
dev_in.bti_list = btis_in;
dev_in.bti_count = countof(btis_in);
- dev_in.i2c_channel_list = i2cs_in;
- dev_in.i2c_channel_count = countof(i2cs_in);
// Output pin assignments.
// Datasheet has 2 numberings for I2S engines: I2S[0-3] (used in GPIOs) and I2S[1-4] (other
@@ -227,14 +238,30 @@
pmic.set_WACS2_WRITE(1).set_WACS2_ADR(kDigLdoCon11 >> 1).set_WACS2_WDATA(kVcn18Enable);
pmic.WriteTo(&(*pmic_mmio));
- status = pbus_.DeviceAdd(&dev_out);
+ // Enable clocks. These are needed by both the input and output drivers, so enable them here
+ // instead of in those drivers.
+ ddk::ClockImplProtocolClient clock = parent();
+ if (!clock.is_valid()) {
+ zxlogf(ERROR, "%s: could not get CLOCK_IMPL protocol\n", __func__);
+ return ZX_ERR_INTERNAL;
+ }
+ clock.Enable(kClkRgAud1);
+ clock.Enable(kClkRgAud2);
+
+ if (board_info_.pid == PDEV_PID_MEDIATEK_8167S_REF) {
+ status = pbus_.CompositeDeviceAdd(&dev_out, mt8167s_ref_out_components,
+ countof(mt8167s_ref_out_components), UINT32_MAX);
+ } else {
+ status = pbus_.CompositeDeviceAdd(&dev_out, cleo_out_components,
+ countof(cleo_out_components), UINT32_MAX);
+ }
if (status != ZX_OK) {
- zxlogf(ERROR, "%s: pbus_.DeviceAdd failed %d\n", __FUNCTION__, status);
+ zxlogf(ERROR, "%s: pbus_.CompositeDeviceAdd failed %d\n", __FUNCTION__, status);
return status;
}
- status = pbus_.DeviceAdd(&dev_in);
+ status = pbus_.CompositeDeviceAdd(&dev_in, in_components, countof(in_components), UINT32_MAX);
if (status != ZX_OK) {
- zxlogf(ERROR, "%s: pbus_.DeviceAdd failed %d\n", __FUNCTION__, status);
+ zxlogf(ERROR, "%s: pbus_.CompositeDeviceAdd failed %d\n", __FUNCTION__, status);
return status;
}
return ZX_OK;
diff --git a/zircon/system/dev/board/mt8167s_ref/mt8167-gpio.cpp b/zircon/system/dev/board/mt8167s_ref/mt8167-gpio.cpp
index 01dc639..e6181045 100644
--- a/zircon/system/dev/board/mt8167s_ref/mt8167-gpio.cpp
+++ b/zircon/system/dev/board/mt8167s_ref/mt8167-gpio.cpp
@@ -8,6 +8,7 @@
#include <ddk/metadata/gpio.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform/bus.h>
+#include <soc/mt8167/mt8167-gpio.h>
#include <soc/mt8167/mt8167-hw.h>
#include "mt8167.h"
@@ -46,6 +47,11 @@
// For touch screen driver
{ MT8167_GPIO_TOUCH_INT },
{ MT8167_GPIO_TOUCH_RST },
+ // For mt8167s audio out
+ { MT8167_GPIO107_MSDC1_DAT1 },
+ { MT8167_GPIO108_MSDC1_DAT2 },
+ // For audio in
+ { MT8167_GPIO24_EINT24 },
};
const pbus_metadata_t cleo_gpio_metadata[] = {
diff --git a/zircon/system/dev/board/mt8167s_ref/mt8167-i2c.cpp b/zircon/system/dev/board/mt8167s_ref/mt8167-i2c.cpp
index 2e734de..a3a81fb 100644
--- a/zircon/system/dev/board/mt8167s_ref/mt8167-i2c.cpp
+++ b/zircon/system/dev/board/mt8167s_ref/mt8167-i2c.cpp
@@ -104,6 +104,30 @@
.pid = 0,
.did = 0,
},
+ // For mt8167s_ref audio out
+ {
+ .bus_id = 2,
+ .address = 0x48,
+ .vid = 0,
+ .pid = 0,
+ .did = 0,
+ },
+ // For cleo audio out
+ {
+ .bus_id = 2,
+ .address = 0x2C,
+ .vid = 0,
+ .pid = 0,
+ .did = 0,
+ },
+ // For audio in
+ {
+ .bus_id = 1,
+ .address = 0x1B,
+ .vid = 0,
+ .pid = 0,
+ .did = 0,
+ },
};
const pbus_metadata_t cleo_i2c_metadata[] = {