1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string.h>
6 
7 #include <ddk/protocol/i2c.h>
8 #include <ddk/protocol/i2c-lib.h>
9 #include <fbl/algorithm.h>
10 #include <fbl/alloc_checker.h>
11 
12 
13 #include "tas57xx.h"
14 
15 namespace audio {
16 namespace gauss {
17 
18 constexpr float Tas57xx::kMaxGain;
19 constexpr float Tas57xx::kMinGain;
20 
21 // static
Create(i2c_protocol_t * i2c,uint32_t index)22 fbl::unique_ptr<Tas57xx> Tas57xx::Create(i2c_protocol_t *i2c, uint32_t index) {
23     fbl::AllocChecker ac;
24 
25     auto ptr = fbl::unique_ptr<Tas57xx>(new (&ac) Tas57xx());
26     if (!ac.check()) {
27         return nullptr;
28     }
29 
30     memcpy(&ptr->i2c_, i2c, sizeof(*i2c));
31 
32     return ptr;
33 }
~Tas57xx()34 Tas57xx::~Tas57xx() {}
35 
Tas57xx()36 Tas57xx::Tas57xx() {}
37 
Reset()38 zx_status_t Tas57xx::Reset(){
39     return WriteReg(0x01, 0x01);
40 }
41 
SetGain(float gain)42 zx_status_t Tas57xx::SetGain(float gain) {
43     gain = fbl::clamp(gain, kMinGain, kMaxGain);
44 
45     uint8_t gain_reg = static_cast<uint8_t>( 48 - gain*2);
46 
47     zx_status_t status;
48     status = WriteReg(61,gain_reg);
49     if (status != ZX_OK) return status;
50     status = WriteReg(62,gain_reg);
51     if (status != ZX_OK) return status;
52     current_gain_ = gain;
53     return status;
54 }
55 
GetGain(float * gain)56 zx_status_t Tas57xx::GetGain(float *gain) {
57     *gain = current_gain_;
58     return ZX_OK;
59 }
60 
ValidGain(float gain)61 bool Tas57xx::ValidGain(float gain) {
62     return (gain <= kMaxGain) && (gain >= kMinGain);
63 }
64 
Init(uint8_t slot)65 zx_status_t Tas57xx::Init(uint8_t slot) {
66     if (slot > 7)
67         return ZX_ERR_INVALID_ARGS;
68     zx_status_t status;
69     status = WriteReg(40, 0x13);
70     if (status != ZX_OK) return status;
71     status = WriteReg(41, static_cast<uint8_t>(1 + 32*slot));
72     if (status != ZX_OK) return status;
73     return WriteReg(42, 0x22);
74 }
75 
Standby()76 zx_status_t Tas57xx::Standby() {
77     return WriteReg(0x02, 0x10);
78 }
79 
ExitStandby()80 zx_status_t Tas57xx::ExitStandby() {
81     return WriteReg(0x02, 0x00);
82 }
83 
WriteReg(uint8_t reg,uint8_t value)84 zx_status_t Tas57xx::WriteReg(uint8_t reg, uint8_t value) {
85     uint8_t write_buf[2];
86     write_buf[0] = reg;
87     write_buf[1] = value;
88     return i2c_write_sync(&i2c_, write_buf, 2);
89 }
90 } //namespace gauss
91 } //namespace audio
92