blob: 4b7e89080071944c17a5e7ec288efb23cadb9aef [file] [log] [blame]
// Copyright 2017 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.
#include <string.h>
#include <ddk/protocol/i2c.h>
#include <lib/device-protocol/i2c.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include "tas57xx.h"
namespace audio {
namespace gauss {
constexpr float Tas57xx::kMaxGain;
constexpr float Tas57xx::kMinGain;
// static
fbl::unique_ptr<Tas57xx> Tas57xx::Create(i2c_protocol_t *i2c, uint32_t index) {
fbl::AllocChecker ac;
auto ptr = fbl::unique_ptr<Tas57xx>(new (&ac) Tas57xx());
if (!ac.check()) {
return nullptr;
}
memcpy(&ptr->i2c_, i2c, sizeof(*i2c));
return ptr;
}
Tas57xx::~Tas57xx() {}
Tas57xx::Tas57xx() {}
zx_status_t Tas57xx::Reset() { return WriteReg(0x01, 0x01); }
zx_status_t Tas57xx::SetGain(float gain) {
gain = fbl::clamp(gain, kMinGain, kMaxGain);
uint8_t gain_reg = static_cast<uint8_t>(48 - gain * 2);
zx_status_t status;
status = WriteReg(61, gain_reg);
if (status != ZX_OK)
return status;
status = WriteReg(62, gain_reg);
if (status != ZX_OK)
return status;
current_gain_ = gain;
return status;
}
zx_status_t Tas57xx::GetGain(float *gain) {
*gain = current_gain_;
return ZX_OK;
}
bool Tas57xx::ValidGain(float gain) { return (gain <= kMaxGain) && (gain >= kMinGain); }
zx_status_t Tas57xx::Init(uint8_t slot) {
if (slot > 7)
return ZX_ERR_INVALID_ARGS;
zx_status_t status;
status = WriteReg(40, 0x13);
if (status != ZX_OK)
return status;
status = WriteReg(41, static_cast<uint8_t>(1 + 32 * slot));
if (status != ZX_OK)
return status;
return WriteReg(42, 0x22);
}
zx_status_t Tas57xx::Standby() { return WriteReg(0x02, 0x10); }
zx_status_t Tas57xx::ExitStandby() { return WriteReg(0x02, 0x00); }
zx_status_t Tas57xx::WriteReg(uint8_t reg, uint8_t value) {
uint8_t write_buf[2];
write_buf[0] = reg;
write_buf[1] = value;
return i2c_write_sync(&i2c_, write_buf, 2);
}
} // namespace gauss
} // namespace audio