blob: ba8c6aab2be51ce1b9440d282ba5e694f571678e [file] [log] [blame]
/*
* Copyright (C) 2015 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 "peripheral_manager.h"
#include <base/logging.h>
#include <binderwrapper/binder_wrapper.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <hardware/hardware.h>
#include <hardware/peripheral_io.h>
#include "gpio_driver_sysfs.h"
#include "gpio_manager.h"
#include "i2c_driver_i2cdev.h"
#include "i2c_manager.h"
#include "led_driver_sysfs.h"
#include "led_manager.h"
#include "pin_mux_manager.h"
#include "spi_driver_spidev.h"
#include "uart_driver_sysfs.h"
#include "uart_manager.h"
namespace android {
namespace {
// Gpio callbacks
static int RegisterGpioSysfs(const char* name, uint32_t index) {
return GpioManager::GetGpioManager()->RegisterGpioSysfs(name, index);
}
static int SetGpioPinMux(const char* name, const char* source) {
return GpioManager::GetGpioManager()->SetPinMux(name, source);
}
// Spi callbacks
static int RegisterSpiDevBus(const char* name, uint32_t bus, uint32_t cs) {
return SpiManager::GetSpiManager()->RegisterSpiDevBus(name, bus, cs);
}
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);
}
// Uart callbacks
static int RegisterUartBus(const char* name, const char* dev_name) {
return UartManager::GetManager()->RegisterUartDevice(name, dev_name);
}
static int SetUartPinMux(const char* name, const char* source) {
return UartManager::GetManager()->SetPinMux(name, source);
}
// I2c callbacks
static int RegisterI2cDevBus(const char* name, uint32_t bus) {
return I2cManager::GetI2cManager()->RegisterI2cDevBus(name, bus);
}
static int SetI2cPinMux(const char* name, const char* source) {
return I2cManager::GetI2cManager()->SetPinMux(name, source);
}
// Pin Mux callbacks.
static int RegisterPin(const char* name,
int gpio,
pin_mux_callbacks callbacks) {
return PinMuxManager::GetPinMuxManager()->RegisterPin(name, gpio, callbacks);
}
static int RegisterPinGroup(const char* name, char** pins, size_t nr_pins) {
std::set<std::string> pins_set;
for (size_t i = 0; i < nr_pins; i++)
pins_set.emplace(pins[i]);
return PinMuxManager::GetPinMuxManager()->RegisterPinGroup(name, pins_set);
}
static int RegisterSource(const char* name, char** groups, size_t nr_groups) {
std::set<std::string> groups_set;
for (size_t i = 0; i < nr_groups; i++)
groups_set.emplace(groups[i]);
return PinMuxManager::GetPinMuxManager()->RegisterSource(name, groups_set);
}
static int RegisterSimpleSource(const char* name,
const char** pins,
size_t nr_pins) {
std::set<std::string> pins_set;
for (size_t i = 0; i < nr_pins; i++)
pins_set.emplace(pins[i]);
return PinMuxManager::GetPinMuxManager()->RegisterSimpleSource(name,
pins_set);
}
} // namespace
PeripheralManager::PeripheralManager() {}
PeripheralManager::~PeripheralManager() = default;
bool PeripheralManager::Init() {
if (!RegisterDrivers())
return false;
if (!InitHal())
return false;
String8 interface_desc(getInterfaceDescriptor());
return BinderWrapper::Get()->RegisterService(interface_desc.string(), this);
}
Status PeripheralManager::GetClient(const sp<IBinder>& lifeline,
sp<os::IPeripheralManagerClient>* client) {
sp<PeripheralManagerClient> c = new PeripheralManagerClient;
*client = c;
lifeline->linkToDeath(this);
mapping_.emplace(lifeline.get(), c);
VLOG(1) << "client connecting " << mapping_.size();
return Status::ok();
}
void PeripheralManager::binderDied(const wp<IBinder>& who) {
mapping_.erase(who.unsafe_get());
VLOG(1) << "client disconnecting " << mapping_.size();
}
bool PeripheralManager::RegisterDrivers() {
if (!SpiManager::GetSpiManager()->RegisterDriver(
std::unique_ptr<SpiDriverInfoBase>(
new SpiDriverInfo<SpiDriverSpiDev, CharDeviceFactory*>(
nullptr)))) {
LOG(ERROR) << "Failed to load driver: SpiDriverSpiDev";
return false;
}
if (!I2cManager::GetI2cManager()->RegisterDriver(
std::unique_ptr<I2cDriverInfoBase>(
new I2cDriverInfo<I2cDriverI2cDev, CharDeviceFactory*>(
nullptr)))) {
LOG(ERROR) << "Failed to load driver: I2cDriverI2cDev";
return false;
}
if (!GpioManager::GetGpioManager()->RegisterDriver(
std::unique_ptr<GpioDriverInfoBase>(
new GpioDriverInfo<GpioDriverSysfs, void*>(nullptr)))) {
LOG(ERROR) << "Failed to load driver: GpioDriverSysfs";
return false;
}
if (!LedManager::GetLedManager()->RegisterDriver(
std::unique_ptr<LedDriverInfoBase>(
new LedDriverInfo<LedDriverSysfs, std::string*>(nullptr)))) {
LOG(ERROR) << "Failed to load driver: LedDriverSysfs";
return false;
}
if (!UartManager::GetManager()->RegisterDriver(
std::unique_ptr<UartDriverInfoBase>(
new UartDriverInfo<UartDriverSysfs, CharDeviceFactory*>(
nullptr)))) {
LOG(ERROR) << "Failed to load driver: UartDriverSysfs";
return false;
}
return true;
}
bool PeripheralManager::InitHal() {
const hw_module_t* module = nullptr;
if (hw_get_module(PERIPHERAL_IO_HARDWARE_MODULE_ID, &module) != 0) {
LOG(ERROR) << "Failed to load HAL" << module;
return true;
}
const peripheral_io_module_t* peripheral_module =
reinterpret_cast<const peripheral_io_module_t*>(module);
struct peripheral_registration_cb_t callbacks = {
// Gpio
.register_gpio_sysfs = RegisterGpioSysfs,
.set_gpio_pin_mux = SetGpioPinMux,
// Spi
.register_spi_dev_bus = RegisterSpiDevBus,
.set_spi_pin_mux = SetSpiPinMux,
// Led
.register_led_sysfs = RegisterLedSysfs,
// Uart
.register_uart_bus = RegisterUartBus,
.set_uart_pin_mux = SetUartPinMux,
// I2c
.register_i2c_dev_bus = RegisterI2cDevBus,
.set_i2c_pin_mux = SetI2cPinMux,
// Pin Mux
.register_pin = RegisterPin,
.register_pin_group = RegisterPinGroup,
.register_source = RegisterSource,
.register_simple_source = RegisterSimpleSource,
};
peripheral_module->register_devices(peripheral_module, &callbacks);
return true;
}
} // namespace android