blob: 6d06f041fa53398a8fd969ada95783a02d1cbcd2 [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
8#include <base/logging.h>
9#include <base/strings/stringprintf.h>
10
Harvey Yang9260b662019-08-12 15:48:03 +080011#include "libmems/common_types.h"
Enrico Granata51cdb942019-06-18 16:40:17 -070012#include "libmems/iio_channel_impl.h"
13#include "libmems/iio_device.h"
Enrico Granata60a818d2019-05-09 09:56:09 -070014
Enrico Granata51cdb942019-06-18 16:40:17 -070015namespace libmems {
Enrico Granata60a818d2019-05-09 09:56:09 -070016
17IioChannelImpl::IioChannelImpl(iio_channel* channel) : channel_(channel) {
18 CHECK(channel_);
19}
20
21const char* IioChannelImpl::GetId() const {
22 return iio_channel_get_id(channel_);
23}
24
25bool IioChannelImpl::IsEnabled() const {
26 return iio_channel_is_enabled(channel_);
27}
28
Harvey Yang2c08cf72020-09-24 12:36:23 +080029void IioChannelImpl::SetEnabled(bool en) {
Enrico Granata60a818d2019-05-09 09:56:09 -070030 if (en)
31 iio_channel_enable(channel_);
32 else
33 iio_channel_disable(channel_);
Harvey Yang2c08cf72020-09-24 12:36:23 +080034}
Enrico Granata60a818d2019-05-09 09:56:09 -070035
Harvey Yang2c08cf72020-09-24 12:36:23 +080036bool IioChannelImpl::SetScanElementsEnabled(bool en) {
Enrico Granata60a818d2019-05-09 09:56:09 -070037 if (!iio_channel_is_scan_element(channel_))
38 return true;
39
40 std::string en_attrib_name = base::StringPrintf(
Harvey Yangf0a0b232020-08-29 10:20:31 +080041 "scan_elements/%s_%s_en", iio_channel_is_output(channel_) ? "out" : "in",
42 GetId());
Harvey Yang9260b662019-08-12 15:48:03 +080043 int error = iio_channel_attr_write_bool(channel_, en_attrib_name.c_str(), en);
44 if (error) {
Enrico Granata60a818d2019-05-09 09:56:09 -070045 LOG(WARNING) << "could not write to " << en_attrib_name
Harvey Yang9260b662019-08-12 15:48:03 +080046 << ", error: " << error;
Enrico Granata60a818d2019-05-09 09:56:09 -070047 return false;
48 }
49
50 return true;
51}
52
Harvey Yang96029cb2019-06-03 17:26:14 +080053base::Optional<std::string> IioChannelImpl::ReadStringAttribute(
54 const std::string& name) const {
Harvey Yang9260b662019-08-12 15:48:03 +080055 char data[kReadAttrBufferSize] = {0};
Harvey Yang96029cb2019-06-03 17:26:14 +080056 ssize_t len =
57 iio_channel_attr_read(channel_, name.c_str(), data, sizeof(data));
58 if (len < 0) {
59 LOG(WARNING) << "Attempting to read attribute " << name
60 << " failed: " << len;
61 return base::nullopt;
62 }
63 return std::string(data, len);
64}
65
66base::Optional<int64_t> IioChannelImpl::ReadNumberAttribute(
67 const std::string& name) const {
68 long long val = 0; // NOLINT(runtime/int)
69 int error = iio_channel_attr_read_longlong(channel_, name.c_str(), &val);
70 if (error) {
71 LOG(WARNING) << "Attempting to read attribute " << name
72 << " failed: " << error;
73 return base::nullopt;
74 }
75 return val;
76}
77
Harvey Yang34c54d52020-05-20 13:34:20 +080078base::Optional<int64_t> IioChannelImpl::Convert(const uint8_t* src) const {
79 const iio_data_format* format = iio_channel_get_data_format(channel_);
80 if (!format) {
81 LOG(WARNING) << "Cannot find format of channel: " << GetId();
82 return base::nullopt;
83 }
84
85 size_t len = format->length;
86 if (len == 0)
87 return 0;
88
Harvey Yang08c058a2020-06-22 18:10:52 +080089 int64_t value = 0;
Harvey Yang34c54d52020-05-20 13:34:20 +080090 iio_channel_convert(channel_, &value, src);
91
92 if (format->is_signed && len < CHAR_BIT * sizeof(int64_t)) {
93 int64_t mask = 1LL << (len - 1);
94
95 if (mask & value) {
96 // Doing sign extension
97 value |= (~0LL) << len;
98 }
99 }
100
101 return value;
102}
103
Harvey Yang9903fc22020-03-16 14:22:53 +0800104base::Optional<double> IioChannelImpl::ReadDoubleAttribute(
105 const std::string& name) const {
106 double val = 0;
107 int error = iio_channel_attr_read_double(channel_, name.c_str(), &val);
108 if (error) {
109 LOG(WARNING) << "Attempting to read attribute " << name
110 << " failed: " << error;
111 return base::nullopt;
112 }
113 return val;
114}
115
116bool IioChannelImpl::WriteStringAttribute(const std::string& name,
117 const std::string& value) {
118 int error = iio_channel_attr_write_raw(
119 channel_, name.size() > 0 ? name.c_str() : nullptr, value.data(),
120 value.size());
121 if (error) {
122 LOG(WARNING) << "Attempting to write attribute " << name
123 << " failed: " << error;
124 return false;
125 }
126 return true;
127}
128
129bool IioChannelImpl::WriteNumberAttribute(const std::string& name,
130 int64_t value) {
131 int error = iio_channel_attr_write_longlong(channel_, name.c_str(), value);
132 if (error) {
133 LOG(WARNING) << "Attempting to write attribute " << name
134 << " failed: " << error;
135 return false;
136 }
137 return true;
138}
139
140bool IioChannelImpl::WriteDoubleAttribute(const std::string& name,
141 double value) {
142 int error = iio_channel_attr_write_double(channel_, name.c_str(), value);
143 if (error) {
144 LOG(WARNING) << "Attempting to write attribute " << name
145 << " failed: " << error;
146 return false;
147 }
148 return true;
149}
150
Harvey Yang34c54d52020-05-20 13:34:20 +0800151base::Optional<uint64_t> IioChannelImpl::Length() const {
152 const iio_data_format* format = iio_channel_get_data_format(channel_);
153 if (!format) {
154 LOG(WARNING) << "Cannot find format of channel: " << GetId();
155 return base::nullopt;
156 }
157
158 return format->length;
159}
160
Enrico Granata51cdb942019-06-18 16:40:17 -0700161} // namespace libmems