blob: 3a0b997ae91b572becf56771f7d891a95e678f12 [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
Enrico Granata51cdb942019-06-18 16:40:17 -07005#ifndef LIBMEMS_IIO_DEVICE_H_
6#define LIBMEMS_IIO_DEVICE_H_
Enrico Granata60a818d2019-05-09 09:56:09 -07007
8#include <iio.h>
9
Gwendal Grignoua1446472020-06-30 18:00:05 -070010#include <memory>
Enrico Granata60a818d2019-05-09 09:56:09 -070011#include <string>
Harvey Yangc0d19d82019-07-01 12:17:34 +080012#include <vector>
Enrico Granata60a818d2019-05-09 09:56:09 -070013
Harvey Yang34c54d52020-05-20 13:34:20 +080014#include <base/containers/flat_map.h>
Enrico Granata60a818d2019-05-09 09:56:09 -070015#include <base/files/file_path.h>
16#include <base/macros.h>
17#include <base/optional.h>
Harvey Yang98ff1b32020-10-28 14:45:35 +080018#include <base/time/time.h>
Enrico Granata60a818d2019-05-09 09:56:09 -070019
Enrico Granata51cdb942019-06-18 16:40:17 -070020#include "libmems/export.h"
21
22namespace libmems {
Enrico Granata60a818d2019-05-09 09:56:09 -070023
24class IioContext;
25class IioChannel;
26
27// The IioDevice represents a single IIO device, such as a gyroscope.
28// It offers facilities to read and write attributes on the device, as well as
29// configure channels, trigger and buffer for a sensor.
Enrico Granata51cdb942019-06-18 16:40:17 -070030class LIBMEMS_EXPORT IioDevice {
Enrico Granata60a818d2019-05-09 09:56:09 -070031 public:
Harvey Yang9f48d812020-06-30 16:24:30 +080032 // first is channel index; second is the channel's value
33 using IioSample = base::flat_map<int32_t, int64_t>;
Harvey Yang34c54d52020-05-20 13:34:20 +080034
Gwendal Grignoua1446472020-06-30 18:00:05 -070035 virtual ~IioDevice();
Enrico Granata60a818d2019-05-09 09:56:09 -070036
37 // Returns the IIO context that contains this device.
38 virtual IioContext* GetContext() const = 0;
39
40 // Returns the value of the 'name' attribute of this device.
41 // It is allowed to return an empty string.
42 virtual const char* GetName() const = 0;
43
Harvey Yang9260b662019-08-12 15:48:03 +080044 // Returns the unique IIO identifier of this device/trigger.
45 // Return id greater or equal to 0 if it's a device.
46 // Return id be -1 if it's iio_sysfs_trigger, greater or equal to 0 if it's a
47 // trigger.
48 virtual int GetId() const = 0;
Enrico Granata60a818d2019-05-09 09:56:09 -070049
50 // This call is used to enable setting UNIX permissions and ownership on the
51 // attributes of a sensor. It should not be used as a replacement for the
52 // read/write attribute accessors below.
53 virtual base::FilePath GetPath() const = 0;
54
55 // Reads the |name| attribute of this device and returns the value
56 // as a string. It will return base::nullopt if the attribute cannot
57 // be read.
58 virtual base::Optional<std::string> ReadStringAttribute(
59 const std::string& name) const = 0;
60
61 // Reads the |name| attribute of this device and returns the value
62 // as a signed number. It will return base::nullopt if the attribute
63 // cannot be read or is not a valid number.
64 virtual base::Optional<int64_t> ReadNumberAttribute(
65 const std::string& name) const = 0;
66
Enrico Granatad2e57f42019-07-31 10:46:03 -070067 // Reads the |name| attribute of this device and returns the value
68 // as a double precision floating point. It will return base::nullopt
69 // if the attribute cannot be read or is not a valid number.
70 virtual base::Optional<double> ReadDoubleAttribute(
71 const std::string& name) const = 0;
72
Enrico Granata60a818d2019-05-09 09:56:09 -070073 // Writes the string |value| to the attribute |name| of this device. Returns
74 // false if an error occurs.
75 virtual bool WriteStringAttribute(const std::string& name,
76 const std::string& value) = 0;
77
78 // Writes the number |value| to the attribute |name| of this device. Returns
79 // false if an error occurs.
Enrico Granatad2e57f42019-07-31 10:46:03 -070080 virtual bool WriteNumberAttribute(const std::string& name, int64_t value) = 0;
81
82 // Writes the floating point |value| to the attribute |name| of this device.
83 // Returns false if an error occurs.
84 virtual bool WriteDoubleAttribute(const std::string& name, double value) = 0;
Enrico Granata60a818d2019-05-09 09:56:09 -070085
Harvey Yangcbfe75e2021-01-21 09:35:25 +080086 // Returns true if this device has a fifo queue for samples.
87 virtual bool HasFifo() const = 0;
88
Enrico Granata60a818d2019-05-09 09:56:09 -070089 // Returns true if this device represents a single sensor, vs. a device
90 // representing all available cros_ec sensors on the system, as defined
91 // before 3.18 kernel.
92 bool IsSingleSensor() const;
93
94 // Returns the iio_device object underlying this object, if any is available.
95 // Returns nullptr if no iio_device exists, e.g. a mock object.
96 virtual iio_device* GetUnderlyingIioDevice() const = 0;
97
98 // Sets |trigger| as the IIO trigger device for this device. It is expected
99 // that |trigger| is owned by the same IIO context as this device.
100 virtual bool SetTrigger(IioDevice* trigger_device) = 0;
101
102 // Returns the IIO trigger device for this device, or nullptr if this device
103 // has no trigger, or the trigger can't be found.
104 virtual IioDevice* GetTrigger() = 0;
105
Harvey Yangee5a26d2021-03-23 17:19:27 +0800106 // Returns the IIO hrtimer trigger device for this device, or nullptr if there
107 // is no such hrtimer trigger device.
108 virtual IioDevice* GetHrtimer() = 0;
109
Harvey Yangb0c30962019-09-17 15:00:25 +0800110 // Returns all channels belonging to this device.
Gwendal Grignoua1446472020-06-30 18:00:05 -0700111 std::vector<IioChannel*> GetAllChannels();
Harvey Yangb0c30962019-09-17 15:00:25 +0800112
Harvey Yang2c08cf72020-09-24 12:36:23 +0800113 // Enables all channels belonging to this device.
114 void EnableAllChannels();
115
Harvey Yang9f48d812020-06-30 16:24:30 +0800116 // Finds the IIO channel |index| as the index in this device and returns it.
117 // It will return nullptr if no such channel can be found.
Gwendal Grignoua1446472020-06-30 18:00:05 -0700118 IioChannel* GetChannel(int32_t index);
Harvey Yang9f48d812020-06-30 16:24:30 +0800119
Harvey Yangb0c30962019-09-17 15:00:25 +0800120 // Finds the IIO channel |name| as id or name for this device and returns it.
121 // It will return nullptr if no such channel can be found.
Gwendal Grignoua1446472020-06-30 18:00:05 -0700122 IioChannel* GetChannel(const std::string& name);
Enrico Granata60a818d2019-05-09 09:56:09 -0700123
Harvey Yangc0d19d82019-07-01 12:17:34 +0800124 // Returns the sample size in this device.
125 // Returns base::nullopt on failure.
126 virtual base::Optional<size_t> GetSampleSize() const = 0;
127
Enrico Granata60a818d2019-05-09 09:56:09 -0700128 // Enables the IIO buffer on this device and configures it to return
Harvey Yange8b301b2020-05-19 14:43:03 +0800129 // |num| samples on access. This buffer's lifetime can exceed that of the
130 // IioContext, and that it's caller responsibility to know when to let go of
131 // the buffer with DisableBuffer if at all.
132 // It should not be used along with GetBufferFd or ReadEvent.
133 // Returns false on failure.
Enrico Granata60a818d2019-05-09 09:56:09 -0700134 virtual bool EnableBuffer(size_t num) = 0;
135
136 // Disables the IIO buffer on this device. Returns false on failure.
137 virtual bool DisableBuffer() = 0;
138
139 // Returns true if the IIO buffer is enabled for this device.
140 // If it is enabled, it sets |num| to the number of samples.
141 virtual bool IsBufferEnabled(size_t* num = nullptr) const = 0;
142
Harvey Yangdf365182021-01-16 23:43:45 +0800143 // Creates the IIO buffer if it doesn't exist.
144 // Returns false if the IIO buffer is already created.
145 // Returns false on buffer not created.
146 // The buffer's lifetime is managed by the client, which will be disabled when
147 // FreeBuffer is called or the IioDevice along with the IioContext gets
148 // destroyed. It should not be used along with EnableBuffer.
149 virtual bool CreateBuffer() = 0;
150
151 // Gets the file descriptor to poll for samples if the IIO buffer is created
152 // by CreateBuffer.
153 // Returns base::nullopt on failure.
Harvey Yange8b301b2020-05-19 14:43:03 +0800154 // The buffer's lifetime is managed by the IioDevice, which will be disabled
155 // when the IioDevice along with the IioContext gets destroyed. It should not
156 // be used along with EnableBuffer.
157 virtual base::Optional<int32_t> GetBufferFd() = 0;
158
Harvey Yangdf365182021-01-16 23:43:45 +0800159 // Reads & returns one sample if the IIO buffer is created by CreateBuffer.
Harvey Yang34c54d52020-05-20 13:34:20 +0800160 // Returns base::nullopt on failure.
Harvey Yange8b301b2020-05-19 14:43:03 +0800161 // The buffer's lifetime is managed by the IioDevice, which will be disabled
162 // when the IioDevice along with the IioContext gets destroyed. It should not
163 // be used along with EnableBuffer.
Harvey Yang34c54d52020-05-20 13:34:20 +0800164 virtual base::Optional<IioSample> ReadSample() = 0;
Harvey Yangc0d19d82019-07-01 12:17:34 +0800165
Harvey Yangdf365182021-01-16 23:43:45 +0800166 // Frees the IIO buffer created by CreateBuffer if it exists. It should not be
167 // used along with EnableBuffer.
168 virtual void FreeBuffer() = 0;
169
Harvey Yang98ff1b32020-10-28 14:45:35 +0800170 bool GetMinMaxFrequency(double* min_freq, double* max_freq);
171
Enrico Granata60a818d2019-05-09 09:56:09 -0700172 protected:
Gwendal Grignoua1446472020-06-30 18:00:05 -0700173 struct ChannelData {
174 std::string chn_id;
175 std::unique_ptr<IioChannel> chn;
176 };
Enrico Granata60a818d2019-05-09 09:56:09 -0700177
Harvey Yang9260b662019-08-12 15:48:03 +0800178 static base::Optional<int> GetIdAfterPrefix(const char* id_str,
179 const char* prefix);
180
Gwendal Grignoua1446472020-06-30 18:00:05 -0700181 IioDevice() = default;
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900182 IioDevice(const IioDevice&) = delete;
183 IioDevice& operator=(const IioDevice&) = delete;
Gwendal Grignoua1446472020-06-30 18:00:05 -0700184
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900185 std::vector<ChannelData> channels_;
Enrico Granata60a818d2019-05-09 09:56:09 -0700186};
187
Enrico Granata51cdb942019-06-18 16:40:17 -0700188} // namespace libmems
Enrico Granata60a818d2019-05-09 09:56:09 -0700189
Enrico Granata51cdb942019-06-18 16:40:17 -0700190#endif // LIBMEMS_IIO_DEVICE_H_