blob: e4c45cd05f9ec6faf0b0b5776ab3a8dfd537d067 [file] [log] [blame]
Enrico Granata60a818d2019-05-09 09:56:09 -07001// 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
5#include <memory>
6#include <string>
7
Qijiang Fan713061e2021-03-08 15:45:12 +09008#include <base/check.h>
Enrico Granata60a818d2019-05-09 09:56:09 -07009#include <base/logging.h>
10#include <base/strings/stringprintf.h>
11
Harvey Yang9260b662019-08-12 15:48:03 +080012#include "libmems/common_types.h"
Enrico Granata51cdb942019-06-18 16:40:17 -070013#include "libmems/iio_channel_impl.h"
14#include "libmems/iio_device.h"
Enrico Granata60a818d2019-05-09 09:56:09 -070015
Enrico Granata51cdb942019-06-18 16:40:17 -070016namespace libmems {
Enrico Granata60a818d2019-05-09 09:56:09 -070017
Harvey Yang705e40f2020-11-19 15:42:44 +080018IioChannelImpl::IioChannelImpl(iio_channel* channel,
19 int device_id,
20 const char* device_name)
21 : channel_(channel) {
Enrico Granata60a818d2019-05-09 09:56:09 -070022 CHECK(channel_);
Harvey Yang705e40f2020-11-19 15:42:44 +080023
24 log_prefix_ =
25 base::StringPrintf("Device with id: %d and name: %s, channel: %s. ",
26 device_id, device_name, GetId());
Enrico Granata60a818d2019-05-09 09:56:09 -070027}
28
29const char* IioChannelImpl::GetId() const {
30 return iio_channel_get_id(channel_);
31}
32
33bool IioChannelImpl::IsEnabled() const {
34 return iio_channel_is_enabled(channel_);
35}
36
Harvey Yang2c08cf72020-09-24 12:36:23 +080037void IioChannelImpl::SetEnabled(bool en) {
Enrico Granata60a818d2019-05-09 09:56:09 -070038 if (en)
39 iio_channel_enable(channel_);
40 else
41 iio_channel_disable(channel_);
Harvey Yang2c08cf72020-09-24 12:36:23 +080042}
Enrico Granata60a818d2019-05-09 09:56:09 -070043
Harvey Yang2c08cf72020-09-24 12:36:23 +080044bool IioChannelImpl::SetScanElementsEnabled(bool en) {
Enrico Granata60a818d2019-05-09 09:56:09 -070045 if (!iio_channel_is_scan_element(channel_))
46 return true;
47
48 std::string en_attrib_name = base::StringPrintf(
Harvey Yangf0a0b232020-08-29 10:20:31 +080049 "scan_elements/%s_%s_en", iio_channel_is_output(channel_) ? "out" : "in",
50 GetId());
Harvey Yang9260b662019-08-12 15:48:03 +080051 int error = iio_channel_attr_write_bool(channel_, en_attrib_name.c_str(), en);
52 if (error) {
Harvey Yang705e40f2020-11-19 15:42:44 +080053 LOG(WARNING) << log_prefix_ << "Could not write to " << en_attrib_name
Harvey Yang9260b662019-08-12 15:48:03 +080054 << ", error: " << error;
Enrico Granata60a818d2019-05-09 09:56:09 -070055 return false;
56 }
57
58 return true;
59}
60
Harvey Yang96029cb2019-06-03 17:26:14 +080061base::Optional<std::string> IioChannelImpl::ReadStringAttribute(
62 const std::string& name) const {
Harvey Yang9260b662019-08-12 15:48:03 +080063 char data[kReadAttrBufferSize] = {0};
Harvey Yang96029cb2019-06-03 17:26:14 +080064 ssize_t len =
65 iio_channel_attr_read(channel_, name.c_str(), data, sizeof(data));
66 if (len < 0) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +080067 LOG(WARNING) << log_prefix_ << "Attempting to read string attribute "
68 << name << " failed: " << len;
Harvey Yang96029cb2019-06-03 17:26:14 +080069 return base::nullopt;
70 }
71 return std::string(data, len);
72}
73
74base::Optional<int64_t> IioChannelImpl::ReadNumberAttribute(
75 const std::string& name) const {
76 long long val = 0; // NOLINT(runtime/int)
77 int error = iio_channel_attr_read_longlong(channel_, name.c_str(), &val);
78 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +080079 LOG(WARNING) << log_prefix_ << "Attempting to read number attribute "
80 << name << " failed: " << error;
Harvey Yang96029cb2019-06-03 17:26:14 +080081 return base::nullopt;
82 }
83 return val;
84}
85
Harvey Yang705e40f2020-11-19 15:42:44 +080086base::Optional<double> IioChannelImpl::ReadDoubleAttribute(
87 const std::string& name) const {
88 double val = 0;
89 int error = iio_channel_attr_read_double(channel_, name.c_str(), &val);
90 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +080091 LOG(WARNING) << log_prefix_ << "Attempting to read double attribute "
92 << name << " failed: " << error;
Harvey Yang705e40f2020-11-19 15:42:44 +080093 return base::nullopt;
94 }
95 return val;
96}
97
98bool IioChannelImpl::WriteStringAttribute(const std::string& name,
99 const std::string& value) {
100 int error = iio_channel_attr_write_raw(
101 channel_, name.size() > 0 ? name.c_str() : nullptr, value.data(),
102 value.size());
103 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800104 LOG(WARNING) << log_prefix_ << "Attempting to write string attribute "
105 << name << " failed: " << error;
Harvey Yang705e40f2020-11-19 15:42:44 +0800106 return false;
107 }
108 return true;
109}
110
111bool IioChannelImpl::WriteNumberAttribute(const std::string& name,
112 int64_t value) {
113 int error = iio_channel_attr_write_longlong(channel_, name.c_str(), value);
114 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800115 LOG(WARNING) << log_prefix_ << "Attempting to write number attribute "
116 << name << " failed: " << error;
Harvey Yang705e40f2020-11-19 15:42:44 +0800117 return false;
118 }
119 return true;
120}
121
122bool IioChannelImpl::WriteDoubleAttribute(const std::string& name,
123 double value) {
124 int error = iio_channel_attr_write_double(channel_, name.c_str(), value);
125 if (error) {
Harvey Yang3b87b1d2020-12-04 15:38:20 +0800126 LOG(WARNING) << log_prefix_ << "Attempting to write double attribute "
127 << name << " failed: " << error;
Harvey Yang705e40f2020-11-19 15:42:44 +0800128 return false;
129 }
130 return true;
131}
132
Harvey Yang34c54d52020-05-20 13:34:20 +0800133base::Optional<int64_t> IioChannelImpl::Convert(const uint8_t* src) const {
134 const iio_data_format* format = iio_channel_get_data_format(channel_);
135 if (!format) {
Harvey Yang705e40f2020-11-19 15:42:44 +0800136 LOG(WARNING) << log_prefix_ << "Cannot find format.";
Harvey Yang34c54d52020-05-20 13:34:20 +0800137 return base::nullopt;
138 }
139
140 size_t len = format->length;
141 if (len == 0)
142 return 0;
143
Harvey Yang08c058a2020-06-22 18:10:52 +0800144 int64_t value = 0;
Harvey Yang34c54d52020-05-20 13:34:20 +0800145 iio_channel_convert(channel_, &value, src);
146
147 if (format->is_signed && len < CHAR_BIT * sizeof(int64_t)) {
148 int64_t mask = 1LL << (len - 1);
149
150 if (mask & value) {
151 // Doing sign extension
152 value |= (~0LL) << len;
153 }
154 }
155
156 return value;
157}
158
159base::Optional<uint64_t> IioChannelImpl::Length() const {
160 const iio_data_format* format = iio_channel_get_data_format(channel_);
161 if (!format) {
Harvey Yang705e40f2020-11-19 15:42:44 +0800162 LOG(WARNING) << log_prefix_ << "Cannot find format.";
Harvey Yang34c54d52020-05-20 13:34:20 +0800163 return base::nullopt;
164 }
165
166 return format->length;
167}
168
Enrico Granata51cdb942019-06-18 16:40:17 -0700169} // namespace libmems