diff options
-rw-r--r-- | src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 2ebf2788..53b2f23a 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -501,12 +501,35 @@ int UVCCameraData::init(MediaDevice *media) video_->bufferReady.connect(this, &UVCCameraData::bufferReady); + properties_.set(properties::Model, utils::toAscii(media->model())); + /* - * \todo Find a way to tell internal and external UVC cameras apart. - * Until then, treat all UVC cameras as external. + * Derive the location from the device removable attribute in sysfs. + * Non-removable devices are assumed to be front as we lack detailed + * location information, and removable device are considered external. + * + * The sysfs removable attribute is derived from the ACPI _UPC attribute + * if available, or from the USB hub descriptors otherwise. ACPI data + * may not be very reliable, and the USB hub descriptors may not be + * accurate on DT-based platforms. A heuristic may need to be + * implemented later if too many devices end up being miscategorized. + * + * \todo Find a way to tell front and back devices apart. This could + * come from the ACPI _PLD, but that may be even more unreliable than + * the _UPC. */ - properties_.set(properties::Location, properties::CameraLocationExternal); - properties_.set(properties::Model, utils::toAscii(media->model())); + properties::LocationEnum location = properties::CameraLocationExternal; + std::ifstream file(video_->devicePath() + "/../removable"); + if (file.is_open()) { + std::string value; + std::getline(file, value); + file.close(); + + if (value == "fixed") + location = properties::CameraLocationFront; + } + + properties_.set(properties::Location, location); /* * Get the current format in order to initialize the sensor array |