blob: 821324574291d4a2cae62fba7a603e318611c852 [file] [log] [blame]
Mike Frysinger3a446f22022-09-08 07:37:141// Copyright 2021 The ChromiumOS Authors
Andrew McRae485619fb2021-05-09 03:46:402// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/*
6 * Device access interface common functions.
7 */
Evan Benn4c908a22021-09-15 05:28:348
Andrew McRae4b3e5342021-05-31 00:57:589#include "hps/dev.h"
Evan Benn4c908a22021-09-15 05:28:3410
hschama3c61bd2022-03-17 06:06:2111#include <optional>
12
Evan Benn4c908a22021-09-15 05:28:3413#include "base/logging.h"
Evan Benn67b14822021-11-01 04:18:2514#include <base/strings/stringprintf.h>
Andrew McRae4b3e5342021-05-31 00:57:5815#include "hps/hps_reg.h"
Evan Benn4c908a22021-09-15 05:28:3416#include "hps/utils.h"
Andrew McRae485619fb2021-05-09 03:46:4017
18namespace hps {
Evan Benn49c4e6d2021-12-23 03:22:5719namespace {
20
21class WakeLockNoOpImpl : public WakeLock {
22 public:
23 WakeLockNoOpImpl() = default;
24 ~WakeLockNoOpImpl() override = default;
Dan Callaghan57d13162022-07-27 07:38:2625 bool supports_power_management() override { return false; }
Evan Benn49c4e6d2021-12-23 03:22:5726};
27
28} // namespace
Andrew McRae485619fb2021-05-09 03:46:4029
Evan Benn12e9e2d2021-09-21 03:18:4130bool DevInterface::Read(uint8_t cmd, uint8_t* data, size_t len) {
31 if (this->ReadDevice(cmd, data, len)) {
Evan Benn67b14822021-11-01 04:18:2532 VLOG(2) << base::StringPrintf("Read: cmd: 0x%x len: %zd OK", cmd, len);
Evan Benn12e9e2d2021-09-21 03:18:4133 return true;
34 }
Evan Benn67b14822021-11-01 04:18:2535 VLOG(2) << base::StringPrintf("Read: cmd: 0x%x len: %zd FAILED", cmd, len);
Evan Benn12e9e2d2021-09-21 03:18:4136 return false;
37}
38
39bool DevInterface::Write(uint8_t cmd, const uint8_t* data, size_t len) {
40 if (this->WriteDevice(cmd, data, len)) {
Evan Benn67b14822021-11-01 04:18:2541 VLOG(2) << base::StringPrintf("Write: cmd: 0x%x len: %zd OK", cmd, len);
Evan Benn12e9e2d2021-09-21 03:18:4142 return true;
43 }
Evan Benn67b14822021-11-01 04:18:2544 VLOG(2) << base::StringPrintf("Write: cmd: 0x%x len: %zd FAILED", cmd, len);
Evan Benn12e9e2d2021-09-21 03:18:4145 return false;
46}
47
Andrew McRae485619fb2021-05-09 03:46:4048/*
49 * Read 1 register.
50 * Returns value read, or -1 for error.
51 */
Evan Benn054a7302021-11-26 04:27:0652std::optional<uint16_t> DevInterface::ReadReg(HpsReg r) {
Dan Callaghan655597d2022-08-31 05:22:0853 auto reg = HpsRegInfo(r);
Andrew McRae485619fb2021-05-09 03:46:4054 uint8_t res[2];
55
Dan Callaghanaff49952022-07-26 07:26:3456 if (this->ReadDevice(I2cReg(r), res, sizeof(res))) {
57 uint16_t ret = static_cast<uint16_t>(res[0] << 8) | res[1];
Dan Callaghan655597d2022-08-31 05:22:0858 VLOG(2) << base::StringPrintf("ReadReg: %s : 0x%.4x OK", reg->name, ret);
Dan Callaghanaff49952022-07-26 07:26:3459 return ret;
60 } else {
Dan Callaghan655597d2022-08-31 05:22:0861 VLOG(2) << "ReadReg: " << reg->name << " FAILED";
Dan Callaghanaff49952022-07-26 07:26:3462 return std::nullopt;
Andrew McRae485619fb2021-05-09 03:46:4063 }
Andrew McRae485619fb2021-05-09 03:46:4064}
65
Dan Callaghan26bcf142022-08-31 05:45:5666std::optional<std::string> DevInterface::ReadStringReg(HpsReg r, size_t len) {
67 auto reg = HpsRegInfo(r);
68 std::string ret(len, '\0');
69
70 if (this->ReadDevice(I2cReg(r), reinterpret_cast<uint8_t*>(ret.data()),
71 static_cast<unsigned int>(ret.size()))) {
72 auto terminator = ret.find('\0');
73 if (terminator != std::string::npos) {
74 ret.resize(terminator);
75 }
76 VLOG(2) << base::StringPrintf("ReadReg: %s (%zu bytes) OK", reg->name,
77 ret.size());
78 return ret;
79 } else {
80 VLOG(2) << "ReadStringReg: " << reg->name << " FAILED";
81 return std::nullopt;
82 }
83}
84
Andrew McRae485619fb2021-05-09 03:46:4085/*
86 * Write 1 register.
87 * Returns false on failure.
88 */
Evan Benn3168af12021-09-20 00:03:3189bool DevInterface::WriteReg(HpsReg r, uint16_t data) {
Dan Callaghan655597d2022-08-31 05:22:0890 auto reg = HpsRegInfo(r);
Andrew McRae485619fb2021-05-09 03:46:4091 uint8_t buf[2];
Evan Bennfaf6f922021-08-19 00:54:2192
Andrew McRae485619fb2021-05-09 03:46:4093 buf[0] = data >> 8;
94 buf[1] = data & 0xFF;
Evan Bennfaf6f922021-08-19 00:54:2195
96 if (this->WriteDevice(I2cReg(r), buf, sizeof(buf))) {
Dan Callaghan655597d2022-08-31 05:22:0897 VLOG(2) << base::StringPrintf("WriteReg: %s : 0x%.4x OK", reg->name, data);
Evan Bennfaf6f922021-08-19 00:54:2198 return true;
99 } else {
Dan Callaghan655597d2022-08-31 05:22:08100 VLOG(2) << base::StringPrintf("WriteReg: %s : 0x%.4x FAILED", reg->name,
101 data);
Evan Bennfaf6f922021-08-19 00:54:21102 return false;
Andrew McRae485619fb2021-05-09 03:46:40103 }
Andrew McRae485619fb2021-05-09 03:46:40104}
Evan Bennfaf6f922021-08-19 00:54:21105
Andrew McRae95669e62021-07-01 08:15:24106/*
107 * Return the maximum download block size (in bytes).
108 * Default is 256 bytes.
109 */
110size_t DevInterface::BlockSizeBytes() {
111 return 256;
112}
Andrew McRae485619fb2021-05-09 03:46:40113
Evan Benn49c4e6d2021-12-23 03:22:57114std::unique_ptr<WakeLock> DevInterface::CreateWakeLock() {
115 return std::make_unique<WakeLockNoOpImpl>();
116}
117
Andrew McRae485619fb2021-05-09 03:46:40118} // namespace hps