1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include "dev/fbdev_driver.h" 16#include "charger_log.h" 17 18#include "securec.h" 19#include <cstdio> 20#include <cstdlib> 21#include <cstring> 22#include <fcntl.h> 23#include <memory> 24#include <sys/ioctl.h> 25#include <sys/mman.h> 26#include <sys/types.h> 27#include <unistd.h> 28 29namespace OHOS { 30namespace PowerMgr { 31FbdevDriver::~FbdevDriver() 32{ 33 ReleaseFb(&buff_); 34} 35 36bool FbdevDriver::Init() 37{ 38 if (devPath_.empty()) { 39 BATTERY_HILOGE(FEATURE_CHARGING, "dev path is empty, init failed, check whether SetDevPath correctly called"); 40 return false; 41 } 42 int fd = open(devPath_.c_str(), O_RDWR | O_CLOEXEC); 43 if (fd < 0) { 44 BATTERY_HILOGE(FEATURE_CHARGING, "cannot open fb0"); 45 return false; 46 } 47 48 (void)FbPowerContrl(fd, false); 49 (void)FbPowerContrl(fd, true); 50 51 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo_) < 0) { 52 BATTERY_HILOGE(FEATURE_CHARGING, "failed to get fb0 info"); 53 close(fd); 54 return false; 55 } 56 57 if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo_) < 0) { 58 BATTERY_HILOGE(FEATURE_CHARGING, "failed to get fb0 info"); 59 close(fd); 60 return false; 61 } 62 63 buff_.width = vinfo_.xres; 64 buff_.height = vinfo_.yres; 65 buff_.size = finfo_.line_length * vinfo_.yres; 66 buff_.vaddr = mmap(nullptr, finfo_.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 67 if (buff_.vaddr == MAP_FAILED) { 68 BATTERY_HILOGE(FEATURE_CHARGING, "failed to mmap framebuffer"); 69 close(fd); 70 return false; 71 } 72 (void)memset_s(buff_.vaddr, finfo_.smem_len, 0, finfo_.smem_len); 73 fd_ = fd; 74 return true; 75} 76 77void FbdevDriver::Flip(const uint8_t* buf) 78{ 79 if (fd_ < 0 || memcpy_s(buff_.vaddr, buff_.size, buf, buff_.size) != EOK) { 80 return; 81 } 82 if (ioctl(fd_, FBIOPAN_DISPLAY, &vinfo_) < 0) { 83 BATTERY_HILOGE(FEATURE_CHARGING, "failed to display fb0!"); 84 } 85} 86 87void FbdevDriver::GetDisplayInfo(DisplayInfo& dsInfo) 88{ 89 dsInfo.width = static_cast<int>(vinfo_.xres); 90 dsInfo.height = static_cast<int>(vinfo_.yres); 91 dsInfo.rowBytes = finfo_.line_length; 92 dsInfo.pixelBytes = vinfo_.bits_per_pixel / 8; // 8: byte bit len 93} 94 95void FbdevDriver::Blank(bool blank) 96{ 97 FbPowerContrl(fd_, !blank); 98 if (blankHook_ != nullptr) { 99 blankHook_(fd_, blank); 100 } 101} 102 103void FbdevDriver::Exit() 104{ 105 ReleaseFb(&buff_); 106} 107 108void FbdevDriver::SetDevPath(const std::string& devPath) 109{ 110 devPath_ = devPath; 111} 112 113void FbdevDriver::RegisterBlankHook(FbBlankHook blankHook) 114{ 115 blankHook_ = blankHook; 116} 117 118void FbdevDriver::ReleaseFb(const struct FbBufferObject* fbo) 119{ 120 /* 121 * When fd_ isn't less than 0, then fbo->vaddr is valid and can by safely munmap. 122 * this can be guaranteed by FbdevDriver::Init. 123 */ 124 if (fd_ < 0) { 125 return; 126 } 127 munmap(fbo->vaddr, fbo->size); 128 close(fd_); 129 fd_ = -1; 130} 131 132bool FbdevDriver::FbPowerContrl(int fd, bool powerOn) 133{ 134 if (fd < 0) { 135 return false; 136 } 137 if (ioctl(fd, FBIOBLANK, powerOn ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN) < 0) { 138 BATTERY_HILOGE(FEATURE_CHARGING, "failed to set fb0, %{public}s", strerror(errno)); 139 return false; 140 } 141 return true; 142} 143} // namespace PowerMgr 144} // namespace OHOS 145