From 2aa769db91b51812431099036019cbd6542f7a94 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Fri, 31 Jul 2026 12:49:48 +0300 Subject: [PATCH] sensor: label vendor by part number, not by which probe matched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit detect_superpix_sensor() does not probe a vendor, it probes a register family: 0xFD-paged, 8-bit registers, id at 0x02/0x03. The WillSemi group (OmniVision + SuperPix since 2018-19) ships that same design under both SP and OV/OS part numbers, so the probe matches parts from two brands — but get_sensor_id_i2c() stamped every hit "SuperPix" because the label was attached to the probe rather than to the id it matched. Five of the eight ids this function recognises are OmniVision part numbers, so ipctool emitted self-contradictory output: vendor: SuperPix model: OS04B10 That YAML is what `ipctool upload` ships to the OpenIPC cloud, so each affected camera contributed a wrong vendor/model pairing to the collected hardware data. Set the vendor per matched id instead. The rule: the brand that owns the part number we print — SP numbers are SuperPix, OV/OS numbers are OmniVision — which is the only assignment that keeps the two fields consistent with each other. This also un-comments, legitimately, the override the OS04D10 case already wanted ("Need to overwrite vendor somehow or move this to OV detect function") — with the vendor set inside the probe there is now somewhere to put it that the caller does not clobber. Model strings are deliberately unchanged; see #180 for the separate question of whether 0x2735 should print OV2735 or SP2305. Nothing consumes the sensor vendor field programmatically (getsensoridentity() and getsensorshort() return the model alone, `ipcinfo -v` is the chip vendor), so this is output-only and cannot affect firmware sensor-loading scripts. Co-Authored-By: Claude Opus 4.8 --- src/sensors.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/sensors.c b/src/sensors.c index 4e96ddd..08fd2ba 100644 --- a/src/sensors.c +++ b/src/sensors.c @@ -900,34 +900,44 @@ static int detect_superpix_sensor(sensor_ctx_t *ctx, int fd, if (!res) return false; + // This probe matches a register family (0xFD-paged, id at 0x02/0x03) that + // the WillSemi group ships under both SuperPix (SP) and OmniVision (OV/OS) + // part numbers, so the vendor follows the id we matched, not the probe that + // found it. Every branch sets it; get_sensor_id_i2c() does not override. switch (res) { case 0x140a: + strcpy(ctx->vendor, "SuperPix"); sprintf(ctx->sensor_id, "SP%04x", res); return true; - // Omnivision-SuperPix OV2735 + // OmniVision OV2735. SuperPix ships the same die as SP2305 — identical + // paged register map and the same 0x2735 id, so the two labels cannot be + // told apart by detection alone case 0x2735: + strcpy(ctx->vendor, "OmniVision"); sprintf(ctx->sensor_id, "OV%04x", res); return true; case 0x4308: + strcpy(ctx->vendor, "OmniVision"); sprintf(ctx->sensor_id, "OS04B10"); return true; case 0x5302: - sprintf(ctx->sensor_id, "SP2308"); // or OS02M10 + strcpy(ctx->vendor, "SuperPix"); + sprintf(ctx->sensor_id, "SP2308"); // or OmniVision OS02M10 return true; case 0x5303: + strcpy(ctx->vendor, "OmniVision"); sprintf(ctx->sensor_id, "OS03B10"); return true; case 0x5602: + strcpy(ctx->vendor, "OmniVision"); sprintf(ctx->sensor_id, "OS02G10"); return true; } switch (res2) { - // It's very hard to tell if this is original OmniVision or SuperPix... - // Need to overwrite vendor somehow or move this to OV detect function case 0x530444: + strcpy(ctx->vendor, "OmniVision"); sprintf(ctx->sensor_id, "OS04D10"); - // strcpy(ctx->vendor, "OmniVision"); return true; } @@ -959,6 +969,7 @@ static int detect_superpix_sensor(sensor_ctx_t *ctx, int fd, } if (res) { + strcpy(ctx->vendor, "SuperPix"); sprintf(ctx->sensor_id, "SP%04x", res); } @@ -1130,7 +1141,8 @@ static bool get_sensor_id_i2c(sensor_ctx_t *ctx) { detected = true; } else if (detect_possible_sensors(ctx, fd, detect_superpix_sensor, SENSOR_SUPERPIX)) { - strcpy(ctx->vendor, "SuperPix"); + // vendor is set by the probe itself: this register family carries both + // SuperPix and OmniVision part numbers ctx->reg_width = 1; detected = true; } else if (detect_possible_sensors(ctx, fd, detect_techpoint_adc,