diff options
author | Lee Campbell <leecam@google.com> | 2016-03-15 13:05:40 -0700 |
---|---|---|
committer | Lee Campbell <leecam@google.com> | 2016-03-15 13:05:40 -0700 |
commit | 8deeb0f6d253ec82c51c91c426d8f3c3a623d7c2 (patch) | |
tree | cf63231f915efac280c5cf99f34245b6c93344d2 | |
parent | 7d12dacad6018701dac2b1a1b3e378d295ffe544 (diff) | |
download | peripheralmanager-8deeb0f6d253ec82c51c91c426d8f3c3a623d7c2.tar.gz |
Implement the LED driver and HAL
Hooked up the LED driver and wired up the
HAL calls.
Still missing Pin muxing for LEDs
BUG: 27556738
Change-Id: Ief334b3e66e7357cb2de8a2b6ccf553394bf2b77
TEST: Toggled LEDs on dragonboard
-rw-r--r-- | client/led_impl.cc | 4 | ||||
-rw-r--r-- | daemon/Android.mk | 2 | ||||
-rw-r--r-- | daemon/led_driver.h | 2 | ||||
-rw-r--r-- | daemon/led_driver_sysfs.cc | 106 | ||||
-rw-r--r-- | daemon/led_driver_sysfs.h | 51 | ||||
-rw-r--r-- | daemon/led_manager.cc | 5 | ||||
-rw-r--r-- | daemon/led_manager.h | 4 | ||||
-rw-r--r-- | daemon/peripheral_manager.cc | 16 | ||||
-rw-r--r-- | example/led_example.cc | 3 | ||||
-rw-r--r-- | hal/hardware/peripheral_io.h | 3 |
10 files changed, 187 insertions, 9 deletions
diff --git a/client/led_impl.cc b/client/led_impl.cc index d964a80..164cf2b 100644 --- a/client/led_impl.cc +++ b/client/led_impl.cc @@ -30,7 +30,7 @@ LedImpl::~LedImpl() { int LedImpl::GetBrightness(uint32_t* brightness) { int val; Status status = client_->LedGetBrightness(name_, &val); - if (!status.isOk()) + if (status.isOk()) *brightness = static_cast<uint32_t>(val); return status.serviceSpecificErrorCode(); @@ -39,7 +39,7 @@ int LedImpl::GetBrightness(uint32_t* brightness) { int LedImpl::GetMaxBrightness(uint32_t* max_brightness) { int val; Status status = client_->LedGetMaxBrightness(name_, &val); - if (!status.isOk()) + if (status.isOk()) *max_brightness = static_cast<uint32_t>(val); return status.serviceSpecificErrorCode(); diff --git a/daemon/Android.mk b/daemon/Android.mk index 91001cc..15bc1ef 100644 --- a/daemon/Android.mk +++ b/daemon/Android.mk @@ -74,6 +74,7 @@ LOCAL_SRC_FILES := \ char_device.cc \ gpio_driver_sysfs.cc \ gpio_manager.cc \ + led_driver_sysfs.cc \ led_manager.cc \ peripheral_manager.cc \ peripheral_manager_client.cc \ @@ -101,6 +102,7 @@ LOCAL_SRC_FILES := \ char_device.cc \ gpio_driver_sysfs.cc \ gpio_manager.cc \ + led_driver_sysfs.cc \ led_manager.cc \ pin_mux_manager.cc \ spi_driver_spidev.cc \ diff --git a/daemon/led_driver.h b/daemon/led_driver.h index 5848554..4dfc042 100644 --- a/daemon/led_driver.h +++ b/daemon/led_driver.h @@ -32,7 +32,7 @@ class LedDriverInterface { virtual ~LedDriverInterface() {} // TODO(leecam): Init should have generic params. - virtual bool Init(std::string name) = 0; + virtual bool Init(const std::string& name) = 0; virtual bool SetBrightness(uint32_t val) = 0; diff --git a/daemon/led_driver_sysfs.cc b/daemon/led_driver_sysfs.cc new file mode 100644 index 0000000..b4e4d85 --- /dev/null +++ b/daemon/led_driver_sysfs.cc @@ -0,0 +1,106 @@ +/* + * 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 "led_driver_sysfs.h" + +#include <fcntl.h> +#include <string> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <base/logging.h> + +namespace android { +namespace { + +const char kSysfsLedPathPrefix[] = "/sys/class/leds/"; +const char kMaxBrightnessFilename[] = "max_brightness"; +const char kBrightnessFilename[] = "brightness"; + +} // namespace + +LedDriverSysfs::LedDriverSysfs(void* arg) : fd_(-1) {} + +LedDriverSysfs::~LedDriverSysfs() { + if (fd_ >= 0) { + close(fd_); + } +} + +bool LedDriverSysfs::Init(const std::string& name) { + LOG(INFO) << "Opening " << name; + std::string path = kSysfsLedPathPrefix + name; + + int fd = open(path.c_str(), O_RDONLY); + if (fd < 0) { + PLOG(WARNING) << "Failed to open " << path; + return false; + } + + fd_ = fd; + return true; +} + +bool LedDriverSysfs::SetBrightness(uint32_t val) { + return WriteToFile(kBrightnessFilename, std::to_string(val)); +} + +bool LedDriverSysfs::GetBrightness(uint32_t* val) { + std::string str_val; + if (!ReadFromFile(kBrightnessFilename, &str_val)) + return false; + *val = std::stoi(str_val); + return true; +} + +bool LedDriverSysfs::GetMaxBrightness(uint32_t* val) { + std::string str_val; + if (!ReadFromFile(kMaxBrightnessFilename, &str_val)) + return false; + *val = std::stoi(str_val); + return true; +} + +bool LedDriverSysfs::ReadFromFile(const std::string& file, std::string* value) { + int fd = openat(fd_, file.c_str(), O_RDONLY); + if (fd < 0) + return false; + char tmp_buf[16] = ""; + ssize_t bytes = read(fd, tmp_buf, sizeof(tmp_buf)); + close(fd); + if (bytes < 0) + return false; + value->assign(tmp_buf, bytes); + return true; +} + +bool LedDriverSysfs::WriteToFile(const std::string& file, + const std::string& value) { + int fd = openat(fd_, file.c_str(), O_RDWR); + if (fd < 0) + return false; + + ssize_t bytes = write(fd, value.c_str(), value.size()); + close(fd); + if (bytes < 0) + return false; + if ((size_t)bytes != value.size()) + return false; + return true; +} + +} // namespace android
\ No newline at end of file diff --git a/daemon/led_driver_sysfs.h b/daemon/led_driver_sysfs.h new file mode 100644 index 0000000..0d5ade0 --- /dev/null +++ b/daemon/led_driver_sysfs.h @@ -0,0 +1,51 @@ +/* + * 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_LED_DRIVER_SYSFS_H_ +#define SYSTEM_PERIPHERALMANAGER_DAEMON_LED_DRIVER_SYSFS_H_ + +#include <stdint.h> + +#include <base/macros.h> + +#include "led_driver.h" + +namespace android { + +class LedDriverSysfs : public LedDriverInterface { + public: + LedDriverSysfs(void* arg); + ~LedDriverSysfs(); + + static std::string Compat() { return "LEDSYSFS"; } + + bool Init(const std::string& name) override; + bool SetBrightness(uint32_t val) override; + bool GetBrightness(uint32_t* val) override; + bool GetMaxBrightness(uint32_t* val) override; + + private: + bool ReadFromFile(const std::string& file, std::string* value); + bool WriteToFile(const std::string& file, const std::string& value); + + int fd_; + + DISALLOW_COPY_AND_ASSIGN(LedDriverSysfs); +}; + +} // namespace android + +#endif // SYSTEM_PERIPHERALMANAGER_DAEMON_LED_DRIVER_SYSFS_H_ diff --git a/daemon/led_manager.cc b/daemon/led_manager.cc index 949a995..f8173ad 100644 --- a/daemon/led_manager.cc +++ b/daemon/led_manager.cc @@ -41,7 +41,8 @@ bool LedManager::RegisterDriver( return true; } -bool LedManager::RegisterLedSysfs(const std::string& name, const std::string& led_name) { +bool LedManager::RegisterLedSysfs(const std::string& name, + const std::string& led_name) { if (leds_.count(name)) return false; leds_[name].name = led_name; @@ -74,7 +75,7 @@ std::unique_ptr<Led> LedManager::OpenLed(const std::string& name) { // Set pin mux if (!led_it->second.mux.empty()) { - //TODO(leecam): Enable pin muxing + // TODO(leecam): Enable pin muxing } if (!driver->Init(led_it->second.name)) { diff --git a/daemon/led_manager.h b/daemon/led_manager.h index 874f848..2a9710b 100644 --- a/daemon/led_manager.h +++ b/daemon/led_manager.h @@ -47,9 +47,7 @@ class Led { led_->driver_.reset(); } - bool SetBrightness(uint32_t val) { - return led_->driver_->SetBrightness(val); - } + bool SetBrightness(uint32_t val) { return led_->driver_->SetBrightness(val); } bool GetBrightness(uint32_t* val) { return led_->driver_->GetBrightness(val); diff --git a/daemon/peripheral_manager.cc b/daemon/peripheral_manager.cc index 2a1e038..04915da 100644 --- a/daemon/peripheral_manager.cc +++ b/daemon/peripheral_manager.cc @@ -23,6 +23,8 @@ #include "gpio_driver_sysfs.h" #include "gpio_manager.h" +#include "led_driver_sysfs.h" +#include "led_manager.h" #include "pin_mux_manager.h" #include "spi_driver_spidev.h" @@ -47,6 +49,11 @@ static int SetSpiPinMux(const char* name, const char* source) { return SpiManager::GetSpiManager()->SetPinMux(name, source); } +// Led callbacks +static int RegisterLedSysfs(const char* name, const char* sysfs_name) { + return LedManager::GetLedManager()->RegisterLedSysfs(name, sysfs_name); +} + // Pin Mux callbacks. static int RegisterPin(const char* name, int gpio, @@ -126,6 +133,12 @@ bool PeripheralManager::RegisterDrivers() { LOG(ERROR) << "Failed to load driver: GpioDriverSysfs"; return false; } + if (!LedManager::GetLedManager()->RegisterDriver( + std::unique_ptr<LedDriverInfoBase>( + new LedDriverInfo<LedDriverSysfs, void*>(nullptr)))) { + LOG(ERROR) << "Failed to load driver: LedDriverSysfs"; + return false; + } return true; } @@ -148,6 +161,9 @@ bool PeripheralManager::InitHal() { .register_spi_dev_bus = RegisterSpiDevBus, .set_spi_pin_mux = SetSpiPinMux, + // Led + .register_led_sysfs = RegisterLedSysfs, + // Pin Mux .register_pin = RegisterPin, .register_pin_group = RegisterPinGroup, diff --git a/example/led_example.cc b/example/led_example.cc index 70a374d..ab5c7b3 100644 --- a/example/led_example.cc +++ b/example/led_example.cc @@ -80,7 +80,8 @@ int main(int argc, char* argv[]) { } if (brightness != 0) { - LOG(ERROR) << "Failed to turn the LED off, led is at: " << brightness; + LOG(ERROR) << "Failed to turn the LED off, led is at: " + << std::to_string(brightness); } // Release the LED diff --git a/hal/hardware/peripheral_io.h b/hal/hardware/peripheral_io.h index 78c6e4e..ae2aa26 100644 --- a/hal/hardware/peripheral_io.h +++ b/hal/hardware/peripheral_io.h @@ -64,6 +64,9 @@ typedef struct peripheral_registration_cb_t { int (*register_spi_dev_bus)(const char* name, uint32_t bus, uint32_t cs); int (*set_spi_pin_mux)(const char* name, const char* source); + // Led functions + int (*register_led_sysfs)(const char* name, const char* sysfs_name); + } peripheral_registration_cb_t; typedef struct peripheral_io_module_t peripheral_io_module_t; |