blob: 463e99c6a48a4858e9ec1faf56e90a0a58c62516 [file] [log] [blame]
Harvey Yang9260b662019-08-12 15:48:03 +08001// Copyright 2019 The Chromium OS 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#include <string>
5
Qijiang Fan713061e2021-03-08 15:45:12 +09006#include <base/check.h>
Harvey Yang9260b662019-08-12 15:48:03 +08007#include <base/files/file_util.h>
8#include <base/logging.h>
9#include <base/strings/stringprintf.h>
10
11#include "libmems/common_types.h"
12#include "libmems/iio_channel.h"
13#include "libmems/iio_context_impl.h"
14#include "libmems/iio_device_trigger_impl.h"
15
16namespace {
17
18constexpr char kAddTrigger[] = "add_trigger";
19
20} // namespace
21
22namespace libmems {
23
24base::Optional<int> IioDeviceTriggerImpl::GetIdFromString(const char* id_str) {
25 size_t id_len = strlen(id_str);
26 if (id_len == strlen(kIioSysfsTrigger) &&
27 strncmp(id_str, kIioSysfsTrigger, id_len) == 0) {
28 return -1;
29 }
30
31 return IioDevice::GetIdAfterPrefix(id_str, kTriggerIdPrefix);
32}
33
34std::string IioDeviceTriggerImpl::GetStringFromId(int id) {
35 if (id == -1)
36 return std::string(kIioSysfsTrigger);
37 return base::StringPrintf("trigger%d", id);
38}
39
40IioDeviceTriggerImpl::IioDeviceTriggerImpl(IioContextImpl* ctx, iio_device* dev)
41 : IioDevice(), context_(ctx), trigger_(dev) {
42 CHECK(context_);
43 CHECK(trigger_);
Harvey Yang3b87b1d2020-12-04 15:38:20 +080044
45 log_prefix_ = base::StringPrintf("Trigger with id: %d and name: %s. ",
46 GetId(), (GetName() ? GetName() : "null"));
Harvey Yang9260b662019-08-12 15:48:03 +080047}
48
49IioContext* IioDeviceTriggerImpl::GetContext() const {
50 return context_;
51}
52
53const char* IioDeviceTriggerImpl::GetName() const {
54 return iio_device_get_name(trigger_);
55}
56
57int IioDeviceTriggerImpl::GetId() const {
58 const char* id_str = iio_device_get_id(trigger_);
59
60 auto id = GetIdFromString(id_str);
61 DCHECK(id.has_value());
62 return id.value();
63}
64
65base::FilePath IioDeviceTriggerImpl::GetPath() const {
66 int id = GetId();
67 std::string id_str = std::string(kIioSysfsTrigger);
68 if (id >= 0)
69 id_str = GetStringFromId(id);
70
Harvey Yang36779e92020-08-26 10:46:15 +080071 auto path = base::FilePath(kSysDevString).Append(id_str);
Harvey Yang9260b662019-08-12 15:48:03 +080072 CHECK(base::DirectoryExists(path));
73 return path;
74}
75
76base::Optional<std::string> IioDeviceTriggerImpl::ReadStringAttribute(
77 const std::string& name) const {
78 char data[kReadAttrBufferSize] = {0};
79 ssize_t len =
80 iio_device_attr_read(trigger_, name.c_str(), data, sizeof(data));
81 if (len < 0) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +080082 LOG(WARNING) << log_prefix_ << "Attempting to read string attribute "
83 << name << " failed: " << len;
Harvey Yang9260b662019-08-12 15:48:03 +080084 return base::nullopt;
85 }
86 return std::string(data, len);
87}
88
89base::Optional<int64_t> IioDeviceTriggerImpl::ReadNumberAttribute(
90 const std::string& name) const {
91 long long val = 0; // NOLINT(runtime/int)
92 int error = iio_device_attr_read_longlong(trigger_, name.c_str(), &val);
93 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +080094 LOG(WARNING) << log_prefix_ << "Attempting to read number attribute "
95 << name << " failed: " << error;
Harvey Yang9260b662019-08-12 15:48:03 +080096 return base::nullopt;
97 }
98 return val;
99}
100
Harvey Yang0c0039a2020-12-02 14:45:59 +0800101base::Optional<double> IioDeviceTriggerImpl::ReadDoubleAttribute(
102 const std::string& name) const {
103 double val = 0;
104 int error = iio_device_attr_read_double(trigger_, name.c_str(), &val);
105 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800106 LOG(WARNING) << log_prefix_ << "Attempting to read double attribute "
107 << name << " failed: " << error;
Harvey Yang0c0039a2020-12-02 14:45:59 +0800108 return base::nullopt;
109 }
110 return val;
111}
112
Harvey Yang9260b662019-08-12 15:48:03 +0800113bool IioDeviceTriggerImpl::WriteNumberAttribute(const std::string& name,
114 int64_t value) {
115 int id = GetId();
116 if ((id == -1 && name.compare(kAddTrigger) != 0) ||
Harvey Yang0c0039a2020-12-02 14:45:59 +0800117 (id != -1 && name.compare(kSamplingFrequencyAttr) != 0)) {
Harvey Yang9260b662019-08-12 15:48:03 +0800118 return false;
Harvey Yang0c0039a2020-12-02 14:45:59 +0800119 }
Harvey Yang9260b662019-08-12 15:48:03 +0800120
121 int error = iio_device_attr_write_longlong(trigger_, name.c_str(), value);
122 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800123 LOG(WARNING) << log_prefix_ << "Attempting to write number attribute "
124 << name << " failed: " << error;
Harvey Yang9260b662019-08-12 15:48:03 +0800125 return false;
126 }
127 return true;
128}
129
Harvey Yang0c0039a2020-12-02 14:45:59 +0800130bool IioDeviceTriggerImpl::WriteDoubleAttribute(const std::string& name,
131 double value) {
132 int id = GetId();
133 if ((id == -1 && name.compare(kAddTrigger) != 0) ||
134 (id != -1 && name.compare(kSamplingFrequencyAttr) != 0)) {
135 return false;
136 }
137
138 int error = iio_device_attr_write_double(trigger_, name.c_str(), value);
139 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800140 LOG(WARNING) << log_prefix_ << "Attempting to write double attribute "
141 << name << " failed: " << error;
Harvey Yang0c0039a2020-12-02 14:45:59 +0800142 return false;
143 }
144 return true;
145}
146
Harvey Yang9260b662019-08-12 15:48:03 +0800147} // namespace libmems