1 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 // System dependencies 31 #include <stdio.h> 32 #include <fcntl.h> 33 #include <media/msm_cam_sensor.h> 34 35 // Camera dependencies 36 #include "HAL3/QCamera3HWI.h" 37 #include "QCameraFlash.h" 38 39 extern "C" { 40 #include "mm_camera_dbg.h" 41 } 42 43 #define STRING_LENGTH_OF_64_BIT_NUMBER 21 44 45 volatile uint32_t gCamHal3LogLevel = 1; 46 47 namespace qcamera { 48 49 /*=========================================================================== 50 * FUNCTION : getInstance 51 * 52 * DESCRIPTION: Get and create the QCameraFlash singleton. 53 * 54 * PARAMETERS : None 55 * 56 * RETURN : None 57 *==========================================================================*/ 58 QCameraFlash& QCameraFlash::getInstance() 59 { 60 static QCameraFlash flashInstance; 61 return flashInstance; 62 } 63 64 /*=========================================================================== 65 * FUNCTION : QCameraFlash 66 * 67 * DESCRIPTION: default constructor of QCameraFlash 68 * 69 * PARAMETERS : None 70 * 71 * RETURN : None 72 *==========================================================================*/ 73 QCameraFlash::QCameraFlash() : m_callbacks(NULL) 74 { 75 memset(&m_flashOn, 0, sizeof(m_flashOn)); 76 memset(&m_cameraOpen, 0, sizeof(m_cameraOpen)); 77 for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) { 78 m_flashFds[pos] = -1; 79 } 80 } 81 82 /*=========================================================================== 83 * FUNCTION : ~QCameraFlash 84 * 85 * DESCRIPTION: deconstructor of QCameraFlash 86 * 87 * PARAMETERS : None 88 * 89 * RETURN : None 90 *==========================================================================*/ 91 QCameraFlash::~QCameraFlash() 92 { 93 for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) { 94 if (m_flashFds[pos] >= 0) 95 { 96 setFlashMode(pos, false); 97 close(m_flashFds[pos]); 98 m_flashFds[pos] = -1; 99 } 100 } 101 } 102 103 /*=========================================================================== 104 * FUNCTION : registerCallbacks 105 * 106 * DESCRIPTION: provide flash module with reference to callbacks to framework 107 * 108 * PARAMETERS : None 109 * 110 * RETURN : None 111 *==========================================================================*/ 112 int32_t QCameraFlash::registerCallbacks( 113 const camera_module_callbacks_t* callbacks) 114 { 115 int32_t retVal = 0; 116 m_callbacks = callbacks; 117 return retVal; 118 } 119 120 /*=========================================================================== 121 * FUNCTION : initFlash 122 * 123 * DESCRIPTION: Reserve and initialize the flash unit associated with a 124 * given camera id. This function is blocking until the 125 * operation completes or fails. Each flash unit can be "inited" 126 * by only one process at a time. 127 * 128 * PARAMETERS : 129 * @camera_id : Camera id of the flash. 130 * 131 * RETURN : 132 * 0 : success 133 * -EBUSY : The flash unit or the resource needed to turn on the 134 * the flash is busy, typically because the flash is 135 * already in use. 136 * -EINVAL : No flash present at camera_id. 137 *==========================================================================*/ 138 int32_t QCameraFlash::initFlash(const int camera_id) 139 { 140 int32_t retVal = 0; 141 bool hasFlash = false; 142 char flashNode[QCAMERA_MAX_FILEPATH_LENGTH]; 143 char flashPath[QCAMERA_MAX_FILEPATH_LENGTH] = "/dev/"; 144 145 if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) { 146 LOGE("Invalid camera id: %d", camera_id); 147 return -EINVAL; 148 } 149 150 QCamera3HardwareInterface::getFlashInfo(camera_id, 151 hasFlash, 152 flashNode); 153 154 strlcat(flashPath, 155 flashNode, 156 sizeof(flashPath)); 157 158 if (!hasFlash) { 159 LOGE("No flash available for camera id: %d", 160 camera_id); 161 retVal = -ENOSYS; 162 } else if (m_cameraOpen[camera_id]) { 163 LOGE("Camera in use for camera id: %d", 164 camera_id); 165 retVal = -EBUSY; 166 } else if (m_flashFds[camera_id] >= 0) { 167 LOGD("Flash is already inited for camera id: %d", 168 camera_id); 169 } else { 170 m_flashFds[camera_id] = open(flashPath, O_RDWR | O_NONBLOCK); 171 172 if (m_flashFds[camera_id] < 0) { 173 LOGE("Unable to open node '%s'", 174 flashPath); 175 retVal = -EBUSY; 176 } else { 177 struct msm_flash_cfg_data_t cfg; 178 struct msm_flash_init_info_t init_info; 179 memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t)); 180 memset(&init_info, 0, sizeof(struct msm_flash_init_info_t)); 181 init_info.flash_driver_type = FLASH_DRIVER_DEFAULT; 182 cfg.cfg.flash_init_info = &init_info; 183 cfg.cfg_type = CFG_FLASH_INIT; 184 retVal = ioctl(m_flashFds[camera_id], 185 VIDIOC_MSM_FLASH_CFG, 186 &cfg); 187 if (retVal < 0) { 188 LOGE("Unable to init flash for camera id: %d", 189 camera_id); 190 close(m_flashFds[camera_id]); 191 m_flashFds[camera_id] = -1; 192 } 193 194 /* wait for PMIC to init */ 195 usleep(5000); 196 } 197 } 198 199 LOGD("X, retVal = %d", retVal); 200 return retVal; 201 } 202 203 /*=========================================================================== 204 * FUNCTION : setFlashMode 205 * 206 * DESCRIPTION: Turn on or off the flash associated with a given handle. 207 * This function is blocking until the operation completes or 208 * fails. 209 * 210 * PARAMETERS : 211 * @camera_id : Camera id of the flash 212 * @on : Whether to turn flash on (true) or off (false) 213 * 214 * RETURN : 215 * 0 : success 216 * -EINVAL : No camera present at camera_id, or it is not inited. 217 * -EALREADY: Flash is already in requested state 218 *==========================================================================*/ 219 int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode) 220 { 221 int32_t retVal = 0; 222 struct msm_flash_cfg_data_t cfg; 223 224 if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) { 225 LOGE("Invalid camera id: %d", camera_id); 226 retVal = -EINVAL; 227 } else if (mode == m_flashOn[camera_id]) { 228 LOGD("flash %d is already in requested state: %d", 229 camera_id, 230 mode); 231 retVal = -EALREADY; 232 } else if (m_flashFds[camera_id] < 0) { 233 LOGE("called for uninited flash: %d", camera_id); 234 retVal = -EINVAL; 235 } else { 236 memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t)); 237 for (int i = 0; i < MAX_LED_TRIGGERS; i++) 238 cfg.flash_current[i] = QCAMERA_TORCH_CURRENT_VALUE; 239 cfg.cfg_type = mode ? CFG_FLASH_LOW: CFG_FLASH_OFF; 240 241 retVal = ioctl(m_flashFds[camera_id], 242 VIDIOC_MSM_FLASH_CFG, 243 &cfg); 244 if (retVal < 0) { 245 LOGE("Unable to change flash mode to %d for camera id: %d", 246 mode, camera_id); 247 } else 248 { 249 m_flashOn[camera_id] = mode; 250 } 251 } 252 return retVal; 253 } 254 255 /*=========================================================================== 256 * FUNCTION : deinitFlash 257 * 258 * DESCRIPTION: Release the flash unit associated with a given camera 259 * position. This function is blocking until the operation 260 * completes or fails. 261 * 262 * PARAMETERS : 263 * @camera_id : Camera id of the flash. 264 * 265 * RETURN : 266 * 0 : success 267 * -EINVAL : No camera present at camera_id or not inited. 268 *==========================================================================*/ 269 int32_t QCameraFlash::deinitFlash(const int camera_id) 270 { 271 int32_t retVal = 0; 272 273 if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) { 274 LOGE("Invalid camera id: %d", camera_id); 275 retVal = -EINVAL; 276 } else if (m_flashFds[camera_id] < 0) { 277 LOGE("called deinitFlash for uninited flash"); 278 retVal = -EINVAL; 279 } else { 280 setFlashMode(camera_id, false); 281 282 struct msm_flash_cfg_data_t cfg; 283 cfg.cfg_type = CFG_FLASH_RELEASE; 284 retVal = ioctl(m_flashFds[camera_id], 285 VIDIOC_MSM_FLASH_CFG, 286 &cfg); 287 if (retVal < 0) { 288 LOGE("Failed to release flash for camera id: %d", 289 camera_id); 290 } 291 292 close(m_flashFds[camera_id]); 293 m_flashFds[camera_id] = -1; 294 } 295 296 return retVal; 297 } 298 299 /*=========================================================================== 300 * FUNCTION : reserveFlashForCamera 301 * 302 * DESCRIPTION: Give control of the flash to the camera, and notify 303 * framework that the flash has become unavailable. 304 * 305 * PARAMETERS : 306 * @camera_id : Camera id of the flash. 307 * 308 * RETURN : 309 * 0 : success 310 * -EINVAL : No camera present at camera_id or not inited. 311 * -ENOSYS : No callback available for torch_mode_status_change. 312 *==========================================================================*/ 313 int32_t QCameraFlash::reserveFlashForCamera(const int camera_id) 314 { 315 int32_t retVal = 0; 316 317 if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) { 318 LOGE("Invalid camera id: %d", camera_id); 319 retVal = -EINVAL; 320 } else if (m_cameraOpen[camera_id]) { 321 LOGD("Flash already reserved for camera id: %d", 322 camera_id); 323 } else { 324 if (m_flashOn[camera_id]) { 325 setFlashMode(camera_id, false); 326 deinitFlash(camera_id); 327 } 328 m_cameraOpen[camera_id] = true; 329 330 bool hasFlash = false; 331 char flashNode[QCAMERA_MAX_FILEPATH_LENGTH]; 332 333 QCamera3HardwareInterface::getFlashInfo(camera_id, 334 hasFlash, 335 flashNode); 336 337 if (m_callbacks == NULL || 338 m_callbacks->torch_mode_status_change == NULL) { 339 LOGE("Callback is not defined!"); 340 retVal = -ENOSYS; 341 } else if (!hasFlash) { 342 LOGD("Suppressing callback " 343 "because no flash exists for camera id: %d", 344 camera_id); 345 } else { 346 char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER]; 347 snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER, 348 "%d", camera_id); 349 m_callbacks->torch_mode_status_change(m_callbacks, 350 cameraIdStr, 351 TORCH_MODE_STATUS_NOT_AVAILABLE); 352 } 353 } 354 355 return retVal; 356 } 357 358 /*=========================================================================== 359 * FUNCTION : releaseFlashFromCamera 360 * 361 * DESCRIPTION: Release control of the flash from the camera, and notify 362 * framework that the flash has become available. 363 * 364 * PARAMETERS : 365 * @camera_id : Camera id of the flash. 366 * 367 * RETURN : 368 * 0 : success 369 * -EINVAL : No camera present at camera_id or not inited. 370 * -ENOSYS : No callback available for torch_mode_status_change. 371 *==========================================================================*/ 372 int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id) 373 { 374 int32_t retVal = 0; 375 376 if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) { 377 LOGE("Invalid camera id: %d", camera_id); 378 retVal = -EINVAL; 379 } else if (!m_cameraOpen[camera_id]) { 380 LOGD("Flash not reserved for camera id: %d", 381 camera_id); 382 } else { 383 m_cameraOpen[camera_id] = false; 384 385 bool hasFlash = false; 386 char flashNode[QCAMERA_MAX_FILEPATH_LENGTH]; 387 388 QCamera3HardwareInterface::getFlashInfo(camera_id, 389 hasFlash, 390 flashNode); 391 392 if (m_callbacks == NULL || 393 m_callbacks->torch_mode_status_change == NULL) { 394 LOGE("Callback is not defined!"); 395 retVal = -ENOSYS; 396 } else if (!hasFlash) { 397 LOGD("Suppressing callback " 398 "because no flash exists for camera id: %d", 399 camera_id); 400 } else { 401 char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER]; 402 snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER, 403 "%d", camera_id); 404 m_callbacks->torch_mode_status_change(m_callbacks, 405 cameraIdStr, 406 TORCH_MODE_STATUS_AVAILABLE_OFF); 407 } 408 } 409 410 return retVal; 411 } 412 413 }; // namespace qcamera 414