aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Campbell <leecam@google.com>2016-03-02 17:43:08 -0800
committerLee Campbell <leecam@google.com>2016-03-03 20:06:29 +0000
commitcee92931cbe24efa9348d14a126bf70f811091c3 (patch)
tree4226f923c7c9473b71977aab9f7d12c660bff55d
parentf866d3a310074b5e7e5ca491d676a562d7d3bde2 (diff)
downloadperipheralmanager-cee92931cbe24efa9348d14a126bf70f811091c3.tar.gz
Adding bare bones SPI driver
Add support for a spidev driver. Ioctls are not wired up yet. BUG: 26779252 Change-Id: I8d81d685077798ae96e73d0061b8f44c94d30310
-rw-r--r--daemon/Android.mk2
-rw-r--r--daemon/peripheral_manager.cc2
-rw-r--r--daemon/spi_driver.h70
-rw-r--r--daemon/spi_driver_spidev.cc99
-rw-r--r--daemon/spi_driver_spidev.h60
5 files changed, 232 insertions, 1 deletions
diff --git a/daemon/Android.mk b/daemon/Android.mk
index 3689d38..c3dac65 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -76,6 +76,7 @@ LOCAL_SRC_FILES := \
peripheral_manager.cc \
peripheral_manager_client.cc \
pin_mux_manager.cc \
+ spi_driver_spidev.cc \
include $(BUILD_STATIC_LIBRARY)
@@ -97,6 +98,7 @@ LOCAL_SRC_FILES := \
gpio_driver_sysfs.cc \
gpio_manager.cc \
pin_mux_manager.cc \
+ spi_driver_spidev.cc \
include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/daemon/peripheral_manager.cc b/daemon/peripheral_manager.cc
index 758b48b..cf7476e 100644
--- a/daemon/peripheral_manager.cc
+++ b/daemon/peripheral_manager.cc
@@ -110,7 +110,7 @@ bool PeripheralManager::RegisterDrivers() {
bool PeripheralManager::InitHal() {
const hw_module_t* module = nullptr;
if (hw_get_module(PERIPHERAL_IO_HARDWARE_MODULE_ID, &module) != 0) {
- LOG(INFO) << "Failed to load HAL" << module;
+ LOG(ERROR) << "Failed to load HAL" << module;
return false;
}
diff --git a/daemon/spi_driver.h b/daemon/spi_driver.h
new file mode 100644
index 0000000..6d7bb65
--- /dev/null
+++ b/daemon/spi_driver.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DRIVER_H_
+#define SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DRIVER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include <base/macros.h>
+
+namespace android {
+
+class SpiDriverInterface {
+ public:
+ SpiDriverInterface() {}
+ virtual ~SpiDriverInterface() {}
+
+ // TODO(leecam): Init should have generic params.
+ virtual bool Init(uint32_t bus_id, uint32_t cs) = 0;
+ virtual bool Transfer(const void* tx_data, void* rx_data, size_t len) = 0;
+ virtual bool SetFrequency(uint32_t speed_hz) = 0;
+ virtual bool SetMode(int mode) = 0;
+ virtual bool SetBitJustification(bool lsb_first) = 0;
+ virtual bool SetBitsPerWord(uint32_t bits_per_word) = 0;
+};
+
+class SpiDriverInfoBase {
+ public:
+ SpiDriverInfoBase() {}
+ virtual ~SpiDriverInfoBase() {}
+
+ virtual std::string Compat() = 0;
+ virtual std::unique_ptr<SpiDriverInterface> Probe() = 0;
+};
+
+template <class T, class PARAM>
+class SpiDriverInfo : public SpiDriverInfoBase {
+ public:
+ SpiDriverInfo(PARAM param) : param_(param) {}
+ ~SpiDriverInfo() override {}
+
+ std::string Compat() override { return T::Compat(); }
+
+ std::unique_ptr<SpiDriverInterface> Probe() override {
+ return std::unique_ptr<SpiDriverInterface>(new T(param_));
+ }
+
+ private:
+ PARAM param_;
+};
+
+} // namespace android
+
+#endif // SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DRIVER_H_
diff --git a/daemon/spi_driver_spidev.cc b/daemon/spi_driver_spidev.cc
new file mode 100644
index 0000000..9d8d3b0
--- /dev/null
+++ b/daemon/spi_driver_spidev.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "spi_driver_spidev.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
+#include <string>
+
+#include <base/logging.h>
+
+namespace android {
+namespace {
+
+const char kSpiDevPath[] = "/dev/spidev";
+
+} // namespace
+
+SpiDriverSpiDev::SpiDriverSpiDev(CharDeviceFactory* char_device_factory)
+ : fd_(-1), char_device_factory_(char_device_factory) {}
+
+SpiDriverSpiDev::~SpiDriverSpiDev() {
+ if (fd_ >= 0 && char_interface_ != nullptr) {
+ char_interface_->Close(fd_);
+ }
+}
+
+bool SpiDriverSpiDev::Init(uint32_t bus_id, uint32_t cs) {
+ if (fd_ >= 0) {
+ return false;
+ }
+
+ // Get a char device. If char_device_factory_ is set
+ // then this is a unittest and the char device is provided
+ // by the test. Otherwise create a normal CharDevice.
+ if (!char_device_factory_) {
+ char_interface_.reset(new CharDevice());
+ } else {
+ char_interface_ = char_device_factory_->NewCharDevice();
+ }
+
+ std::string path =
+ kSpiDevPath + std::to_string(bus_id) + "." + std::to_string(cs);
+
+ int fd = char_interface_->Open(path.c_str(), O_RDWR);
+ if (fd < 0)
+ return false;
+
+ fd_ = fd;
+ return true;
+}
+
+// TODO(leecam): Wire up these IOCTLs once the client code lands.
+bool SpiDriverSpiDev::Transfer(const void* tx_data, void* rx_data, size_t len) {
+ LOG(INFO) << "SPI Transfer";
+ return true;
+}
+
+bool SpiDriverSpiDev::SetFrequency(uint32_t speed_hz) {
+ if (fd_ < 0)
+ return false;
+ // Get the max speed and ensure speed_hz is less than it.
+ uint32_t max_speed = 0;
+ if (char_interface_->Ioctl(fd_, SPI_IOC_RD_MAX_SPEED_HZ, &max_speed) != 0)
+ return false;
+ if (speed_hz > max_speed)
+ speed_hz = max_speed;
+
+ speed_hz_ = speed_hz;
+ return true;
+}
+
+bool SpiDriverSpiDev::SetMode(int mode) {
+ return true;
+}
+
+bool SpiDriverSpiDev::SetBitJustification(bool lsb_first) {
+ return true;
+}
+
+bool SpiDriverSpiDev::SetBitsPerWord(uint32_t bits_per_word) {
+ return true;
+}
+
+} // namespace android \ No newline at end of file
diff --git a/daemon/spi_driver_spidev.h b/daemon/spi_driver_spidev.h
new file mode 100644
index 0000000..f422ac3
--- /dev/null
+++ b/daemon/spi_driver_spidev.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DRIVER_SPIDEV_H_
+#define SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DRIVER_SPIDEV_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include <base/macros.h>
+
+#include "char_device.h"
+#include "spi_driver.h"
+
+namespace android {
+
+class SpiDriverSpiDev : public SpiDriverInterface {
+ public:
+ SpiDriverSpiDev(CharDeviceFactory* char_device_factory);
+ ~SpiDriverSpiDev();
+
+ static std::string Compat() { return "SPIDEV"; }
+
+ bool Init(uint32_t bus_id, uint32_t cs) override;
+ bool Transfer(const void* tx_data, void* rx_data, size_t len) override;
+ bool SetFrequency(uint32_t speed_hz) override;
+ bool SetMode(int mode) override;
+ bool SetBitJustification(bool lsb_first) override;
+ bool SetBitsPerWord(uint32_t bits_per_word) override;
+
+ private:
+ int fd_;
+ uint32_t bits_per_word_;
+ uint32_t speed_hz_;
+ std::unique_ptr<CharDeviceInterface> char_interface_;
+
+ // Used for unit testing and is null in production.
+ // Ownership is in the test and outlives this class.
+ CharDeviceFactory* char_device_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SpiDriverSpiDev);
+};
+
+} // namespace android
+
+#endif // SYSTEM_PERIPHERALMANAGER_DAEMON_SPI_DEVICE_H_