| /* |
| * 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 |