From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f178.google.com (mail-qt1-f178.google.com [209.85.160.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0449F3B19B2 for ; Wed, 29 Jul 2026 05:31:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785303083; cv=none; b=aUOzPhuzEkhFio2htibqGS5moRSi853658p6OfxXxxhmnwP1xIy4DQYzNJI4QQ7spH8v9XWhz2JAaTHU6dJ6bFETRlcvuC5DClCeCnX6nahCxELO94iBjDG06OrDIsF/HE4nyQWseyvhvc6UrP0O8l6iJMtiw7SlxvS4t0vPGNY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785303083; c=relaxed/simple; bh=XbMzXpsUe7cRIU+U8toE8WBnmuOLBoKIZtInOMrn9NA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QN51REJfObsAZ17aRnHTvEDRxGFOQtAaFrUV/rSdLmVvTihGJKPxFfrVVZB7DsNSrCPbzJJrZ1h0Cl/fOfM+Ite321KzC3ShrYGVkXPdEG7P10MFv+HEl5xv2jhKDokdxHafYb40hNP2qZ872MzWvssvWUzWWa8THpaZx5mUmIw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=h5HnbCjl; arc=none smtp.client-ip=209.85.160.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h5HnbCjl" Received: by mail-qt1-f178.google.com with SMTP id d75a77b69052e-51bfa429aa6so10308941cf.0 for ; Tue, 28 Jul 2026 22:31:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785303078; x=1785907878; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=A63ysZ+YgReIu06v3k8w/vOA2fjDEAUGCMr8WX2T8BU=; b=h5HnbCjlIURPfbArQVJReMVDSSm7Wmru0ppPSNaUZeAM3TU8813HWW27zeDeGd7H8I ifpFjB39cKOtGehdmJolt8P84STT+ipYbcowNyQVxCtXaFgf9J0QXpCUDgcvAXPYOshu oOOSA6ffG3477cd659sgsYoMHqbi/ZJWP2WedT/bCd77azmduHUMW0LGE0HGcpVuc9Fr ZJpqe3pUQq50YTHDcj+JMTYeosmJ3P2fMbx+ZHj04ZxQ63UfsdkHV6H17xZREgwW0J3y 7x6Ghtzq3jutEFvPWL90akHal9UWf1gLjdnYcfX/B5Jzsk/THUc3AgAs7zb6nTLizLzD KOJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785303078; x=1785907878; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=A63ysZ+YgReIu06v3k8w/vOA2fjDEAUGCMr8WX2T8BU=; b=dMlH13SGRqD0zKi6MaP+V9wTLMmslWfF8VP5rarJT8n/tWDsQ1RJvCCPHt5Wq/5MXp lv0gItvezTlvh5fy3Okd18LNsJ3SFQuKb1N0025ajksdWFTcqFuixVX/KQLUPFolXvHB A0CE1Weey6M8aRnwOIgIagXEKg3dfJwSC8VwaAhBziQB7xrXkWF0djHYuZsDBMqS+ZLv hbcD7U38mOYstN5k50m+Pvt0O3r4bHlDhzRyNIThIqEOLMs3+pZyNOCmiGfVUsjbrB2r ugZcD+oy4owivo0mQvpw7C64ITfXC5osDhbMB3JwvomlEuJ4S7zMrMTDlnCUqsu9JOG2 TbRw== X-Forwarded-Encrypted: i=1; AHgh+Roinb8mnBbk6n4vAIZUMlAaBLJ563xt6xqQJVZNfVXKxpPstJd9IN7rNGJthu7bFbvVR+qCshGkYZkPQ+I=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+WBBA9EssE3PnMhDfNwEmeIF6ySR2e4kbuVLN+z6rShd6/dYP mguDHiWJmrPn/EuA6cjnkk1pAImjScb5ajRKLhHaqlpPGy9IVa5VfwaW X-Gm-Gg: AR+sD11s4b1cOYgr7/QMgaItsMomg98oU2Z+c8G75MPSNM6hTREg0ceEcnr/L7zepIy pg2QsQ5YgkUcamiKZf+5g67PrzO8MuBgG23fnwJ8iRRGYjy7f1iUvzAwcwSltw6etI+uJUiXKiL e8ZP/WSOZiIrjPH0XpUfhegipfwU11fOqcJn0LxMvyKN4r9ENL9Ukr2sSGreH5jP696/6kC1aVD Tw688pwC8qkpIbjq7z4ZZa/RilfjOJgIH1yIWM1EY0YmIqBZqBDiKxsgd9LDq4lc+BXYk3PwRKI XXMycnM1dTb/E2IUhxnpgJIV6G01NAlb+ZEOceRDVGR8HcWUn1Qcd8Kpw1ysFwbAyAKnmAFnbhg Uee9jT6XsXqvQ8xabM3YtnNwhlbhCTAAfdA6oeNnfEVlzpd/5HXYlmtgVZTa81ZEgp2phVWV5dX s7l+iTqgH2lAUWYgs7Ja60YwtYASb4JzkclNSfDdpiRkOe/ek7UGCbkAjCpfZ4+hasARqnRg== X-Received: by 2002:ac8:5fd3:0:b0:527:6dc7:5c36 with SMTP id d75a77b69052e-52b2ae07ce8mr5991571cf.33.1785303077994; Tue, 28 Jul 2026 22:31:17 -0700 (PDT) Received: from thinker ([65.195.2.74]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-529e2b1a1ddsm12592861cf.5.2026.07.28.22.31.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Jul 2026 22:31:17 -0700 (PDT) From: Amit Barzilai To: Javier Martinez Canillas , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Amit Barzilai Subject: [PATCH 1/2] drm/ssd130x: Scale ssd133x per-channel contrast by brightness on init Date: Wed, 29 Jul 2026 08:30:53 +0300 Message-ID: <20260729053054.29374-2-amit.barzilai22@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260729053054.29374-1-amit.barzilai22@gmail.com> References: <20260729053054.29374-1-amit.barzilai22@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit ssd133x_init() wrote the SSD133X_CONTRAST_A/B/C commands with magic hex values (0x91/0x50/0x7d). These are a per-channel white-balance calibration: the A/B/C channels drive sub-pixels whose OLED materials differ in luminous efficiency, so the values set the white point at full brightness. Extract them into ssd133x_set_contrast(), which scales each channel by a requested brightness via ssd130x_scale_contrast(), instead of writing the calibration unconditionally. This makes the sequence readable, avoids repetition, and is a prerequisite for wiring up an ssd133x backlight controller that dims while preserving the white point. Note this changes the ssd133x power-on brightness. Previously the init wrote the calibration unscaled and ignored ssd130x->contrast, so the panel always booted at full brightness. It now scales by the shared default contrast of 127, i.e. half of MAX_CONTRAST (255). This is intentional and matches ssd130x, whose contrast register also defaults to 127 (mid-scale), so all families now power on at ~50% and report props.brightness = 127 / max_brightness = 255 to userspace. Assisted-by: Claude:claude-fable-5 Signed-off-by: Amit Barzilai --- drivers/gpu/drm/solomon/ssd130x.c | 43 ++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 0940eae7a2e4..f49e5245b216 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -140,6 +141,11 @@ #define SSD133X_SET_PRECHARGE_VOLTAGE 0xbb #define SSD133X_SET_VCOMH_VOLTAGE 0xbe +/* ssd133x A/B/C channel contrast at full brightness (white balance) */ +#define SSD133X_DEFAULT_CONTRAST_A 0x91 +#define SSD133X_DEFAULT_CONTRAST_B 0x50 +#define SSD133X_DEFAULT_CONTRAST_C 0x7d + #define MAX_CONTRAST 255 const struct ssd130x_deviceinfo ssd130x_variants[] = { @@ -582,12 +588,37 @@ static int ssd132x_init(struct ssd130x_device *ssd130x) return ssd130x_run_cmd_seq(ssd130x, cmds); } -static int ssd133x_init(struct ssd130x_device *ssd130x) +/* Scale a channel's white-balance calibration contrast by the requested brightness */ +static u8 ssd130x_scale_contrast(u8 calibration, u32 brightness) +{ + return DIV_ROUND_CLOSEST(calibration * brightness, MAX_CONTRAST); +} + +/* + * The A/B/C contrast channels drive sub-pixels whose OLED materials differ + * in luminous efficiency, so the per-channel values are a white-balance + * calibration. Scale them by the requested brightness instead of + * overwriting them, to keep the white point while dimming. + */ +static int ssd133x_set_contrast(struct ssd130x_device *ssd130x, u32 brightness) { const u8 cmds[] = { - 2, SSD133X_CONTRAST_A, 0x91, - 2, SSD133X_CONTRAST_B, 0x50, - 2, SSD133X_CONTRAST_C, 0x7d, + 2, SSD133X_CONTRAST_A, + ssd130x_scale_contrast(SSD133X_DEFAULT_CONTRAST_A, brightness), + 2, SSD133X_CONTRAST_B, + ssd130x_scale_contrast(SSD133X_DEFAULT_CONTRAST_B, brightness), + 2, SSD133X_CONTRAST_C, + ssd130x_scale_contrast(SSD133X_DEFAULT_CONTRAST_C, brightness), + 0, + }; + + return ssd130x_run_cmd_seq(ssd130x, cmds); +} + +static int ssd133x_init(struct ssd130x_device *ssd130x) +{ + int ret; + const u8 cmds[] = { 2, SSD133X_SET_MASTER_CURRENT, 0x06, 3, SSD133X_SET_COL_RANGE, 0x00, ssd130x->width - 1, 3, SSD133X_SET_ROW_RANGE, 0x00, ssd130x->height - 1, @@ -614,6 +645,10 @@ static int ssd133x_init(struct ssd130x_device *ssd130x) 0, }; + ret = ssd133x_set_contrast(ssd130x, ssd130x->contrast); + if (ret < 0) + return ret; + return ssd130x_run_cmd_seq(ssd130x, cmds); } -- 2.55.0