From patchwork Mon Feb 14 13:37:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745626 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 419CFC43219 for ; Mon, 14 Feb 2022 13:37:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DBF8210E596; Mon, 14 Feb 2022 13:37:40 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id C78AE10E596 for ; Mon, 14 Feb 2022 13:37:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845856; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PMJPygyk+q6IKiko2o+GbGpYNTzAZFXYDjw6FkGxW+0=; b=Bn4saIg2+yqpIVVNbya7Cs9RMRUCp87nmXLEPaZM9V5qybQJnCLiVfYUWLuSMRw8xw5JT9 RBh3+hh2vGVzBtRrAcmhiHigdwevvOdJv7WgxdlG2EqvC+x7QZytD1sx2Tcmo7M38O3gZQ o7FEtfNCJ7sIBW48Had3DIcQ6CKA8RU= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-277-ido2jc8oPxmJ5yeEOz34qg-1; Mon, 14 Feb 2022 08:37:35 -0500 X-MC-Unique: ido2jc8oPxmJ5yeEOz34qg-1 Received: by mail-wr1-f71.google.com with SMTP id w26-20020adf8bda000000b001e33dbc525cso6880186wra.18 for ; Mon, 14 Feb 2022 05:37:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PMJPygyk+q6IKiko2o+GbGpYNTzAZFXYDjw6FkGxW+0=; b=fR2aXNveDZ/+6yLchSDNNFVRp4pBsvlog6F6hk5hHm+gY0VSW03eU5kcxeKyD1vwoI nQ2GfNlwtEcoiLmzd2ykEDiWQx8bcnGKFf2hKeAsLo118j3+wgR0dGCWFNk/6PnqPKvk Lr5LEcrCp3+ZzY4TjzOpRVk9ILsuixO9m0/68awahJGY6RwQuFSAGV8szH2FesNXtcWF LzBIiHppu/u3b0Wq9XaV6hRB3yS6UDviq1w7xH5rIa1c2OCX3DZkuh2OpSGLYroWplfC osPZczFmaCsz4xb3u470UaIEdRhYilRQC8Zgjt7NpLwm0L7dOW4a9uE4y7jD/AXFQrWY zfXA== X-Gm-Message-State: AOAM533sggo/ZGf9f/zFBKqUZ3WZYruSHrVP+wXdlgTj1YHAeCuWuj0K NEbvx870xkVQoKcU8/1M6ol8GtLcXqu97O8ok6fgfQxLMbb9LXYXybyGsOzMGpGryp/KBdSxu3v RQTAmzDtaSIuz7HHpEb5AmS/EdwnU X-Received: by 2002:a05:600c:d0:: with SMTP id u16mr11405611wmm.102.1644845854447; Mon, 14 Feb 2022 05:37:34 -0800 (PST) X-Google-Smtp-Source: ABdhPJxWrzaW0LQ9WRQkaVll0CUJhsj6kJUqQPxu24pAAdfApfjJNXNN9XDBh1yuBXccEzAh4eXAIw== X-Received: by 2002:a05:600c:d0:: with SMTP id u16mr11405587wmm.102.1644845854167; Mon, 14 Feb 2022 05:37:34 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id y6sm3568918wrd.30.2022.02.14.05.37.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:37:33 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 1/6] drm/format-helper: Add drm_fb_xrgb8888_to_gray8_line() Date: Mon, 14 Feb 2022 14:37:05 +0100 Message-Id: <20220214133710.3278506-2-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, David Airlie , Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Thomas Zimmermann , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Pull the per-line conversion logic into a separate helper function. This will allow to do line-by-line conversion in other helpers that convert to a gray8 format. Suggested-by: Thomas Zimmermann Signed-off-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann Reviewed-by: Andy Shevchenko Reviewed-by: Maxime Ripard --- Changes in v6: - Add Andy Shevchenko's Reviewed-by to patch #1. Changes in v5: - Add Thomas Zimmermann's Reviewed-by to patch #1. Changes in v3: - Add a drm_fb_xrgb8888_to_gray8_line() helper function (Thomas Zimmermann) drivers/gpu/drm/drm_format_helper.c | 31 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 0f28dd2bdd72..b981712623d3 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -464,6 +464,21 @@ void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, } EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010_toio); +static void drm_fb_xrgb8888_to_gray8_line(u8 *dst, const u32 *src, unsigned int pixels) +{ + unsigned int x; + + for (x = 0; x < pixels; x++) { + u8 r = (*src & 0x00ff0000) >> 16; + u8 g = (*src & 0x0000ff00) >> 8; + u8 b = *src & 0x000000ff; + + /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */ + *dst++ = (3 * r + 6 * g + b) / 10; + src++; + } +} + /** * drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale * @dst: 8-bit grayscale destination buffer @@ -484,8 +499,9 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010_toio); void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - unsigned int len = (clip->x2 - clip->x1) * sizeof(u32); - unsigned int x, y; + unsigned int linepixels = clip->x2 - clip->x1; + unsigned int len = linepixels * sizeof(u32); + unsigned int y; void *buf; u8 *dst8; u32 *src32; @@ -508,16 +524,7 @@ void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vad for (y = clip->y1; y < clip->y2; y++) { dst8 = dst; src32 = memcpy(buf, vaddr, len); - for (x = clip->x1; x < clip->x2; x++) { - u8 r = (*src32 & 0x00ff0000) >> 16; - u8 g = (*src32 & 0x0000ff00) >> 8; - u8 b = *src32 & 0x000000ff; - - /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */ - *dst8++ = (3 * r + 6 * g + b) / 10; - src32++; - } - + drm_fb_xrgb8888_to_gray8_line(dst8, src32, linepixels); vaddr += fb->pitches[0]; dst += dst_pitch; } From patchwork Mon Feb 14 13:37:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 70C15C433F5 for ; Mon, 14 Feb 2022 13:37:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 23A5F10E5A2; Mon, 14 Feb 2022 13:37:46 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0A28210E59A for ; Mon, 14 Feb 2022 13:37:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=antMq+QI2lYY33VgrrVvP1GCy1SqAtBXkL1zJR3K1Rc=; b=Je5fmo5j3qKSbyQMt0PhU+rxXbvRGihzn7X26D8xanV7LOTBwvpTitsP2rX0UNq2NS8nT2 UKfeOfJYCYt1iw8kutPsZVmof47IHsQtINnwSOuIcfYmHeU0ncBktC2Vo53gTCTdyIMOk0 YMiAxRhezifgBbI3WZBfNB73PsmFNSU= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-14-6hka7hcqNtyX7rR1uEA8dw-1; Mon, 14 Feb 2022 08:37:37 -0500 X-MC-Unique: 6hka7hcqNtyX7rR1uEA8dw-1 Received: by mail-wm1-f71.google.com with SMTP id 125-20020a1c0283000000b0037bf720e6a8so7143120wmc.8 for ; Mon, 14 Feb 2022 05:37:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=antMq+QI2lYY33VgrrVvP1GCy1SqAtBXkL1zJR3K1Rc=; b=QluIJTvUc8EqNT4/ZbNZg1xTjTv4ks3T2aEaSErMwpPi7O+R/iQL+Yl6YtgR1XULm/ iwNpIGe/fkyyWBg7D+GbTu+IxMK/r9D/2K5EfhMQRFcvTNmKShJYdoalB/5L3+f16/zq majojuFyRxP57HtgEUNdJ3LSFuH63O9lme6157jbFRgRS3apRuUaeqdcaFFRVfowoWDf m9CUegdkZOSZRmZyvgTxzjfyZ+GXK35TS6daXSvDTH1XdNfysNghwGqX7m9NEdv3ypM0 2BI9NfqO7/gyrjmEZWjAbPrHIAH/oyY1AOGX5ZbiWhSo/0ofvFWq1AuqO+cqm7dULoWA xk+A== X-Gm-Message-State: AOAM530OGXX5eVE+l7jVgA0MEoCbxYTiLpPe+yLG8kEwRIjh/0NTusN3 yYuoN3zLdVQMYng8fJfUmZeRFdc/cuOLhGcy+llQd9eixjt/YQtKrzPC5P9QDAfBP0wBWGEUJC8 x41jVh9pciLeF9XmcD4KvTFBXri1P X-Received: by 2002:a05:600c:1990:: with SMTP id t16mr3040407wmq.66.1644845855650; Mon, 14 Feb 2022 05:37:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJwquD1QmlltNMuQ3Y9bdmIMSpLDEUSrCUnMUaYlENoLOViQWZy53+PifJ2LVGmTJ3Aay+RwzA== X-Received: by 2002:a05:600c:1990:: with SMTP id t16mr3040384wmq.66.1644845855416; Mon, 14 Feb 2022 05:37:35 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id y6sm3568918wrd.30.2022.02.14.05.37.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:37:35 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 2/6] drm/format-helper: Add drm_fb_xrgb8888_to_mono_reversed() Date: Mon, 14 Feb 2022 14:37:06 +0100 Message-Id: <20220214133710.3278506-3-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, David Airlie , Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Thomas Zimmermann , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add support to convert from XR24 to reversed monochrome for drivers that control monochromatic display panels, that only have 1 bit per pixel. The function does a line-by-line conversion doing an intermediate step first from XR24 to 8-bit grayscale and then to reversed monochrome. The drm_fb_gray8_to_mono_reversed_line() helper was based on code from drivers/gpu/drm/tiny/repaper.c driver. Signed-off-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann Reviewed-by: Andy Shevchenko Reviewed-by: Maxime Ripard --- Changes in v6: - Add Andy Shevchenko's Reviewed-by to patch #2. Changes in v5: - Use drm_WARN_ON* macros instead of deprecated ones (Thomas Zimmermann) Changes in v4: - Rename end_offset to end_len (Thomas Zimmermann) - Warn once if dst_pitch is not a multiple of 8 (Thomas Zimmermann) - Drop drm_fb_gray8_to_mono_reversed() that's not used (Thomas Zimmermann) - Allocate single buffer for both copy cma memory and gray8 (Thomas Zimmermann) - Add Thomas Zimmermann Reviewed-by tag to patch adding XR24 -> mono helper. Changes in v3: - Also add a drm_fb_xrgb8888_to_mono_reversed() helper (Thomas Zimmermann) - Split lines copy to drm_fb_gray8_to_mono_reversed_line() (Thomas Zimmermann) - Handle case where the source buffer is not aligned to 8 (Thomas Zimmermann) drivers/gpu/drm/drm_format_helper.c | 110 ++++++++++++++++++++++++++++ include/drm/drm_format_helper.h | 4 + 2 files changed, 114 insertions(+) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index b981712623d3..bc0f49773868 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -12,9 +12,11 @@ #include #include +#include #include #include #include +#include #include static unsigned int clip_offset(const struct drm_rect *clip, unsigned int pitch, unsigned int cpp) @@ -591,3 +593,111 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for return -EINVAL; } EXPORT_SYMBOL(drm_fb_blit_toio); + +static void drm_fb_gray8_to_mono_reversed_line(u8 *dst, const u8 *src, unsigned int pixels, + unsigned int start_offset, unsigned int end_len) +{ + unsigned int xb, i; + + for (xb = 0; xb < pixels; xb++) { + unsigned int start = 0, end = 8; + u8 byte = 0x00; + + if (xb == 0 && start_offset) + start = start_offset; + + if (xb == pixels - 1 && end_len) + end = end_len; + + for (i = start; i < end; i++) { + unsigned int x = xb * 8 + i; + + byte >>= 1; + if (src[x] >> 7) + byte |= BIT(7); + } + *dst++ = byte; + } +} + +/** + * drm_fb_xrgb8888_to_mono_reversed - Convert XRGB8888 to reversed monochrome + * @dst: reversed monochrome destination buffer + * @dst_pitch: Number of bytes between two consecutive scanlines within dst + * @src: XRGB8888 source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * + * DRM doesn't have native monochrome support. + * Such drivers can announce the commonly supported XR24 format to userspace + * and use this function to convert to the native format. + * + * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and + * then the result is converted from grayscale to reversed monohrome. + */ +void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const void *vaddr, + const struct drm_framebuffer *fb, const struct drm_rect *clip) +{ + unsigned int linepixels = drm_rect_width(clip); + unsigned int lines = clip->y2 - clip->y1; + unsigned int cpp = fb->format->cpp[0]; + unsigned int len_src32 = linepixels * cpp; + struct drm_device *dev = fb->dev; + unsigned int start_offset, end_len; + unsigned int y; + u8 *mono = dst, *gray8; + u32 *src32; + + if (drm_WARN_ON(dev, fb->format->format != DRM_FORMAT_XRGB8888)) + return; + + /* + * The reversed mono destination buffer contains 1 bit per pixel + * and destination scanlines have to be in multiple of 8 pixels. + */ + if (!dst_pitch) + dst_pitch = DIV_ROUND_UP(linepixels, 8); + + drm_WARN_ONCE(dev, dst_pitch % 8 != 0, "dst_pitch is not a multiple of 8\n"); + + /* + * The cma memory is write-combined so reads are uncached. + * Speed up by fetching one line at a time. + * + * Also, format conversion from XR24 to reversed monochrome + * are done line-by-line but are converted to 8-bit grayscale + * as an intermediate step. + * + * Allocate a buffer to be used for both copying from the cma + * memory and to store the intermediate grayscale line pixels. + */ + src32 = kmalloc(len_src32 + linepixels, GFP_KERNEL); + if (!src32) + return; + + gray8 = (u8 *)src32 + len_src32; + + /* + * For damage handling, it is possible that only parts of the source + * buffer is copied and this could lead to start and end pixels that + * are not aligned to multiple of 8. + * + * Calculate if the start and end pixels are not aligned and set the + * offsets for the reversed mono line conversion function to adjust. + */ + start_offset = clip->x1 % 8; + end_len = clip->x2 % 8; + + vaddr += clip_offset(clip, fb->pitches[0], cpp); + for (y = 0; y < lines; y++) { + src32 = memcpy(src32, vaddr, len_src32); + drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels); + drm_fb_gray8_to_mono_reversed_line(mono, gray8, dst_pitch, + start_offset, end_len); + vaddr += fb->pitches[0]; + mono += dst_pitch; + } + + kfree(src32); +} +EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono_reversed); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index b30ed5de0a33..0b0937c0b2f6 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -43,4 +43,8 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for const void *vmap, const struct drm_framebuffer *fb, const struct drm_rect *rect); +void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const void *src, + const struct drm_framebuffer *fb, + const struct drm_rect *clip); + #endif /* __LINUX_DRM_FORMAT_HELPER_H */ From patchwork Mon Feb 14 13:37:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D8676C433EF for ; Mon, 14 Feb 2022 13:37:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 938D910E59B; Mon, 14 Feb 2022 13:37:45 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7E19410E59B for ; Mon, 14 Feb 2022 13:37:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zT8UIB4ejx/iCdAPs5aq+uQfq4/RufOtdPAXUNDh/Qo=; b=EE9JrJQ/NZWSuNcFtf3uZRY0MwHIUR1r55gyPb7ezeiubz69qtiC508lZ1JzpcF7WY7HG7 p7U898j0F6dPhsDSB2xGtByAtEsFt/vagLbcxfCkvLj29dSAZpY9xgiOYeKuChCN3zcDGF wD8hvDf9ZCo5s+OEbv64UGODCRh02qA= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-278-8NSpNAkrPq6M9Kq0YH2NpQ-1; Mon, 14 Feb 2022 08:37:38 -0500 X-MC-Unique: 8NSpNAkrPq6M9Kq0YH2NpQ-1 Received: by mail-wr1-f71.google.com with SMTP id c9-20020adfa709000000b001dde29c3202so6944602wrd.22 for ; Mon, 14 Feb 2022 05:37:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zT8UIB4ejx/iCdAPs5aq+uQfq4/RufOtdPAXUNDh/Qo=; b=Ku0zzoGyPikp9ZUVkENlfock2ceQZgEH3KRq1AhiEolWTIj7fLzGQvv7RqnNeVw6lg v01JHshsnWNv5GsoWBmJXq+FHSoXgg39HWhoNEcu/jO+NSE2Gk4b50C72WXap9wPyJHI L4AFCu62Pzc8EDKUS6V1KBfXxf/eBHbVTqDihmbWRhqSChchjGhpmn2CBNhZRQ89qL3N WcVDnrho4Kd/edR+oALxjzNB0mXtTnlsR6Aes0y6ZaOQ+UDwoJFawMM/msbz+xWPDjLZ UDVYQzNTEaBGFShXezdzD80u8eg1DJLy/DPrTvki6oe9XbHlO85E+OMVlI6zbzHASQnJ LNqg== X-Gm-Message-State: AOAM532IsS86MZrtBtSTzabTksjTUwWxOf5mnalu0cNw89XYXlJu+MQi ioc1hBNSs+47NZByHHExJl7na8CTsRnhzPezPx9j80Io0d8nd+yI/pJVi24b9nuoVFQ92j3Z382 Wj+HpfSahK30Ci5uZ3KiMweSg4ZAl X-Received: by 2002:a05:600c:3c89:: with SMTP id bg9mr11207777wmb.194.1644845857174; Mon, 14 Feb 2022 05:37:37 -0800 (PST) X-Google-Smtp-Source: ABdhPJz0alarcvws+S5boLmqxxoxGxkAegZ/zQPgpR3cUJbRkIMMUhTDiouYb9Ebx0/4xLh2sIaU4g== X-Received: by 2002:a05:600c:3c89:: with SMTP id bg9mr11207722wmb.194.1644845856653; Mon, 14 Feb 2022 05:37:36 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id y6sm3568918wrd.30.2022.02.14.05.37.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:37:36 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 3/6] drm: Add driver for Solomon SSD130x OLED displays Date: Mon, 14 Feb 2022 14:37:07 +0100 Message-Id: <20220214133710.3278506-4-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-fbdev@vger.kernel.org, David Airlie , Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Thomas Zimmermann , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Thierry Reding , Lee Jones , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This adds a DRM driver for SSD1305, SSD1306, SSD1307 and SSD1309 Solomon OLED display controllers. It's only the core part of the driver and a bus specific driver is needed for each transport interface supported by the display controllers. Signed-off-by: Javier Martinez Canillas Reviewed-by: Maxime Ripard --- Changes in v6: - Just return regmap_bulk_write() in ssd130x_write_data() (Andy Shevchenko) - Remove unnecessary cast in ssd130x_write_cmd() (Andy Shevchenko) - Return ERR_PTR(dev_err_probe(...)) everywhere in probe (Andy Shevchenko) Changes in v5: - Include header (Andy Shevchenko) - Drop parenthesis for command options macros (Andy Shevchenko) - Explain in ssd130x_write_cmd() comment how commands are sent (Andy Shevchenko) - The pwm_*() functions check for NULL already (Andy Shevchenko) - Remove unnecesary blank line (Andy Shevchenko) - Simplify error handling for backlight registration failure (Geert Uytterhoeven) - Don't clear screen on enable, instead send the full buffer (Thomas Zimmermann) Changes in v4: - Rename vbat supply to vcc since is how's labeled in the device (Mark Brown) - Don't make the regulator option since is always needed (Mark Brown) - Add solomon Kconfig source and directory inclusion sorted (Andy Shevchenko) - Use SSD130x instead of SSD130X to denote is not a model name (Andy Shevchenko) - Check if there's a reset pin in the callee and not the caller (Andy Shevchenko) - Define missing commands instead of using magic numbers (Andy Shevchenko) - Use GENMASK() and FIELD_PREP() macros when possible (Andy Shevchenko) - Avoid using ternary operators to ease code readablity (Andy Shevchenko) - Use i++ instead of --i on some for loops (Andy Shevchenko) - Remove redundant blank lines (Andy Shevchenko) - Rename power_off label to out_power_off (Andy Shevchenko) - Use dev_err_probe() even if no -EPROBE_DEFER (Andy Shevchenko) - Don't use plural Authors if there's only one (Andy Shevchenko) Changes in v3: - Move driver from tiny sub-dir to drivers/gpu/drm/solomon (Sam Ravnborg) - Split driver in a bus agnostic core and bus specific (Andy Shevchenko) - Use regmap to access the chip registers (Andy Shevchenko) - Remove unnecessary blank lines (Andy Shevchenko) - Remove unneeded inline specifier in functions (Andy Shevchenko) - Add a comment about always returning a single mode (Andy Shevchenko) - Change write command logic to use do while loop (Andy Shevchenko) - Use "firmware description" instead of "device tree" (Andy Shevchenko) - Use return foo() instead of returning the return value (Andy Shevchenko) - Don't split lines longer than 80 chars if makes less readable (Andy Shevchenko) - Remove redundant else statements in .mode_valid callback (Andy Shevchenko) - Rename powero{n,ff}() functions to power_o{n,ff)() (Andy Shevchenko) - Use dev_err_probe() to prevent spam logs on probe deferral (Andy Shevchenko) - Remove ',' after sentinel terminator in array (Andy Shevchenko) - Fix a bug when doing partial updates (Geert Uytterhoeven) Changes in v2: - Drop patch that was adding a DRM_MODE_CONNECTOR_I2C type. - Invert order of backlight {en,dis}able and display {on,off} (Sam Ravnborg) - Don't clear the screen and turn on display on probe (Sam Ravnborg) - Use backlight_get_brightness() macro to get BL brightness (Sam Ravnborg) - Use dev managed version of devm_backlight_device_register() (Sam Ravnborg) - Use dev_name(dev) for backlight name instead of an array (Sam Ravnborg) - Drop the .get_brightness callback since isn't needed (Sam Ravnborg) - Rename driver to ssd130x since supports a display family (Thomas Zimmermann) - Drop the TINY prefix from the Kconfig symbol (Thomas Zimmermann) - Sort the Kconfig symbol dependencies alphabetically (Thomas Zimmermann) - Rename struct ssd130x_array to struct ssd130x_i2c_msg (Thomas Zimmermann) - Rename struct ssd130x_i2c_msg .type member to .cmd (Thomas Zimmermann) - Use sizeof(*foo) instead of sizeof(struct foo) (Thomas Zimmermann) - Use struct_size() macro to calculate sizeof(*foo) + len (Thomas Zimmermann) - Use kcalloc() instead of kmalloc_array() + memset() (Thomas Zimmermann) - Use shadow plane helpers virtual screen support (Thomas Zimmermann) - Remove unused goto label in ssd1307_fb_blit_rect() (Thomas Zimmermann) - Use drm_set_preferred_mode() inset of manually set (Thomas Zimmermann) - Use shadow plane helpers virtual screen support (Thomas Zimmermann) - Remove unused goto label in ssd1307_fb_blit_rect() (Thomas Zimmermann) - Use drm_set_preferred_mode() inset of manually set (Thomas Zimmermann) - Reorganize code in probe to make it more legible (Thomas Zimmermann) - ssd130x_write_cmd() uses varargs to simplify I2C code (Thomas Zimmermann) - Move regulator/pwm init logic to display pipe enable callback. drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/solomon/Kconfig | 12 + drivers/gpu/drm/solomon/Makefile | 1 + drivers/gpu/drm/solomon/ssd130x.c | 843 ++++++++++++++++++++++++++++++ drivers/gpu/drm/solomon/ssd130x.h | 76 +++ 6 files changed, 935 insertions(+) create mode 100644 drivers/gpu/drm/solomon/Kconfig create mode 100644 drivers/gpu/drm/solomon/Makefile create mode 100644 drivers/gpu/drm/solomon/ssd130x.c create mode 100644 drivers/gpu/drm/solomon/ssd130x.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index dfdd3ec5f793..763355330b17 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -403,6 +403,8 @@ source "drivers/gpu/drm/xlnx/Kconfig" source "drivers/gpu/drm/gud/Kconfig" +source "drivers/gpu/drm/solomon/Kconfig" + source "drivers/gpu/drm/sprd/Kconfig" config DRM_HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 8675c2af7ae1..c2ef5f9fce54 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -132,4 +132,5 @@ obj-$(CONFIG_DRM_TIDSS) += tidss/ obj-y += xlnx/ obj-y += gud/ obj-$(CONFIG_DRM_HYPERV) += hyperv/ +obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig new file mode 100644 index 000000000000..7720a7039e8d --- /dev/null +++ b/drivers/gpu/drm/solomon/Kconfig @@ -0,0 +1,12 @@ +config DRM_SSD130X + tristate "DRM support for Solomon SSD130x OLED displays" + depends on DRM + select BACKLIGHT_CLASS_DEVICE + select DRM_GEM_SHMEM_HELPER + select DRM_KMS_HELPER + help + DRM driver for the SSD1305, SSD1306, SSD1307 and SSD1309 Solomon + OLED controllers. This is only for the core driver, a driver for + the appropriate bus transport in your chip also must be selected. + + If M is selected the module will be called ssd130x. diff --git a/drivers/gpu/drm/solomon/Makefile b/drivers/gpu/drm/solomon/Makefile new file mode 100644 index 000000000000..f685addb19fe --- /dev/null +++ b/drivers/gpu/drm/solomon/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_DRM_SSD130X) += ssd130x.o diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c new file mode 100644 index 000000000000..2fcda1972e1e --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -0,0 +1,843 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130x OLED displays + * + * Copyright 2022 Red Hat Inc. + * Author: Javier Martinez Canillas + * + * Based on drivers/video/fbdev/ssd1307fb.c + * Copyright 2012 Free Electrons + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssd130x.h" + +#define DRIVER_NAME "ssd130x" +#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays" +#define DRIVER_DATE "20220131" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 + +#define SSD130X_DATA 0x40 +#define SSD130X_COMMAND 0x80 + +#define SSD130X_SET_ADDRESS_MODE 0x20 +#define SSD130X_SET_COL_RANGE 0x21 +#define SSD130X_SET_PAGE_RANGE 0x22 +#define SSD130X_CONTRAST 0x81 +#define SSD130X_SET_LOOKUP_TABLE 0x91 +#define SSD130X_CHARGE_PUMP 0x8d +#define SSD130X_SEG_REMAP_ON 0xa1 +#define SSD130X_DISPLAY_OFF 0xae +#define SSD130X_SET_MULTIPLEX_RATIO 0xa8 +#define SSD130X_DISPLAY_ON 0xaf +#define SSD130X_START_PAGE_ADDRESS 0xb0 +#define SSD130X_SET_COM_SCAN_DIR 0xc0 +#define SSD130X_SET_DISPLAY_OFFSET 0xd3 +#define SSD130X_SET_CLOCK_FREQ 0xd5 +#define SSD130X_SET_AREA_COLOR_MODE 0xd8 +#define SSD130X_SET_PRECHARGE_PERIOD 0xd9 +#define SSD130X_SET_COM_PINS_CONFIG 0xda +#define SSD130X_SET_VCOMH 0xdb + +#define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 2) +#define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) +#define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) +#define SSD130X_SET_CLOCK_DIV_SET(val) FIELD_PREP(SSD130X_SET_CLOCK_DIV_MASK, (val)) +#define SSD130X_SET_CLOCK_FREQ_MASK GENMASK(7, 4) +#define SSD130X_SET_CLOCK_FREQ_SET(val) FIELD_PREP(SSD130X_SET_CLOCK_FREQ_MASK, (val)) +#define SSD130X_SET_PRECHARGE_PERIOD1_MASK GENMASK(3, 0) +#define SSD130X_SET_PRECHARGE_PERIOD1_SET(val) FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD1_MASK, (val)) +#define SSD130X_SET_PRECHARGE_PERIOD2_MASK GENMASK(7, 4) +#define SSD130X_SET_PRECHARGE_PERIOD2_SET(val) FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD2_MASK, (val)) +#define SSD130X_SET_COM_PINS_CONFIG1_MASK GENMASK(4, 4) +#define SSD130X_SET_COM_PINS_CONFIG1_SET(val) FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG1_MASK, (!val)) +#define SSD130X_SET_COM_PINS_CONFIG2_MASK GENMASK(5, 5) +#define SSD130X_SET_COM_PINS_CONFIG2_SET(val) FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG2_MASK, (val)) + +#define SSD130X_SET_ADDRESS_MODE_HORIZONTAL 0x00 +#define SSD130X_SET_ADDRESS_MODE_VERTICAL 0x01 +#define SSD130X_SET_ADDRESS_MODE_PAGE 0x02 + +#define SSD130X_SET_AREA_COLOR_MODE_ENABLE 0x1e +#define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER 0x05 + +#define MAX_CONTRAST 255 + +static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm) +{ + return container_of(drm, struct ssd130x_device, drm); +} + +/* + * Helper to write data (SSD130X_DATA) to the device. + */ +static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count) +{ + return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count); +} + +/* + * Helper to write command (SSD130X_COMMAND). The fist variadic argument + * is the command to write and the following are the command options. + * + * Note that the ssd130x protocol requires each command and option to be + * written as a SSD130X_COMMAND device register value. That is why a call + * to regmap_write(..., SSD130X_COMMAND, ...) is done for each argument. + */ +static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, + /* u8 cmd, u8 option, ... */...) +{ + va_list ap; + u8 value; + int ret; + + va_start(ap, count); + + do { + value = va_arg(ap, int); + ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value); + if (ret) + goto out_end; + } while (--count); + +out_end: + va_end(ap); + + return ret; +} + +static int ssd130x_set_col_range(struct ssd130x_device *ssd130x, + u8 col_start, u8 cols) +{ + u8 col_end = col_start + cols - 1; + int ret; + + if (col_start == ssd130x->col_start && col_end == ssd130x->col_end) + return 0; + + ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, col_end); + if (ret < 0) + return ret; + + ssd130x->col_start = col_start; + ssd130x->col_end = col_end; + return 0; +} + +static int ssd130x_set_page_range(struct ssd130x_device *ssd130x, + u8 page_start, u8 pages) +{ + u8 page_end = page_start + pages - 1; + int ret; + + if (page_start == ssd130x->page_start && page_end == ssd130x->page_end) + return 0; + + ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start, page_end); + if (ret < 0) + return ret; + + ssd130x->page_start = page_start; + ssd130x->page_end = page_end; + return 0; +} + +static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x) +{ + struct device *dev = ssd130x->dev; + struct pwm_state pwmstate; + + ssd130x->pwm = pwm_get(dev, NULL); + if (IS_ERR(ssd130x->pwm)) { + dev_err(dev, "Could not get PWM from firmware description!\n"); + return PTR_ERR(ssd130x->pwm); + } + + pwm_init_state(ssd130x->pwm, &pwmstate); + pwm_set_relative_duty_cycle(&pwmstate, 50, 100); + pwm_apply_state(ssd130x->pwm, &pwmstate); + + /* Enable the PWM */ + pwm_enable(ssd130x->pwm); + + dev_dbg(dev, "Using PWM%d with a %lluns period.\n", + ssd130x->pwm->pwm, pwm_get_period(ssd130x->pwm)); + + return 0; +} + +static void ssd130x_reset(struct ssd130x_device *ssd130x) +{ + if (!ssd130x->reset) + return; + + /* Reset the screen */ + gpiod_set_value_cansleep(ssd130x->reset, 1); + udelay(4); + gpiod_set_value_cansleep(ssd130x->reset, 0); + udelay(4); +} + +static int ssd130x_power_on(struct ssd130x_device *ssd130x) +{ + struct device *dev = ssd130x->dev; + int ret; + + ssd130x_reset(ssd130x); + + ret = regulator_enable(ssd130x->vcc_reg); + if (ret) { + dev_err(dev, "Failed to enable VCC: %d\n", ret); + return ret; + } + + if (ssd130x->device_info->need_pwm) { + ret = ssd130x_pwm_enable(ssd130x); + if (ret) { + dev_err(dev, "Failed to enable PWM: %d\n", ret); + regulator_disable(ssd130x->vcc_reg); + return ret; + } + } + + return 0; +} + +static void ssd130x_power_off(struct ssd130x_device *ssd130x) +{ + pwm_disable(ssd130x->pwm); + pwm_put(ssd130x->pwm); + + regulator_disable(ssd130x->vcc_reg); +} + +static int ssd130x_init(struct ssd130x_device *ssd130x) +{ + u32 precharge, dclk, com_invdir, compins, chargepump; + int ret; + + /* Set initial contrast */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast); + if (ret < 0) + return ret; + + /* Set segment re-map */ + if (ssd130x->seg_remap) { + ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SEG_REMAP_ON); + if (ret < 0) + return ret; + } + + /* Set COM direction */ + com_invdir = (SSD130X_SET_COM_SCAN_DIR | + SSD130X_SET_COM_SCAN_DIR_SET(ssd130x->com_invdir)); + ret = ssd130x_write_cmd(ssd130x, 1, com_invdir); + if (ret < 0) + return ret; + + /* Set multiplex ratio value */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + if (ret < 0) + return ret; + + /* set display offset value */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x->com_offset); + if (ret < 0) + return ret; + + /* Set clock frequency */ + dclk = (SSD130X_SET_CLOCK_DIV_SET(ssd130x->dclk_div - 1) | + SSD130X_SET_CLOCK_FREQ_SET(ssd130x->dclk_frq)); + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_CLOCK_FREQ, dclk); + if (ret < 0) + return ret; + + /* Set Area Color Mode ON/OFF & Low Power Display Mode */ + if (ssd130x->area_color_enable || ssd130x->low_power) { + u32 mode = 0; + + if (ssd130x->area_color_enable) + mode |= SSD130X_SET_AREA_COLOR_MODE_ENABLE; + + if (ssd130x->low_power) + mode |= SSD130X_SET_AREA_COLOR_MODE_LOW_POWER; + + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_AREA_COLOR_MODE, mode); + if (ret < 0) + return ret; + } + + /* Set precharge period in number of ticks from the internal clock */ + precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) | + SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep2)); + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge); + if (ret < 0) + return ret; + + /* Set COM pins configuration */ + compins = BIT(1); + compins |= (SSD130X_SET_COM_PINS_CONFIG1_SET(ssd130x->com_seq) | + SSD130X_SET_COM_PINS_CONFIG2_SET(ssd130x->com_lrremap)); + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins); + if (ret < 0) + return ret; + + /* Set VCOMH */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh); + if (ret < 0) + return ret; + + /* Turn on the DC-DC Charge Pump */ + chargepump = BIT(4); + + if (ssd130x->device_info->need_chargepump) + chargepump |= BIT(2); + + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CHARGE_PUMP, chargepump); + if (ret < 0) + return ret; + + /* Set lookup table */ + if (ssd130x->lookup_table_set) { + int i; + + ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); i++) { + u8 val = ssd130x->lookup_table[i]; + + if (val < 31 || val > 63) + dev_warn(ssd130x->dev, + "lookup table index %d value out of range 31 <= %d <= 63\n", + i, val); + ret = ssd130x_write_cmd(ssd130x, 1, val); + if (ret < 0) + return ret; + } + } + + /* Switch to horizontal addressing mode */ + return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE, + SSD130X_SET_ADDRESS_MODE_HORIZONTAL); +} + +static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf, + struct drm_rect *rect) +{ + unsigned int x = rect->x1; + unsigned int y = rect->y1; + unsigned int width = drm_rect_width(rect); + unsigned int height = drm_rect_height(rect); + unsigned int line_length = DIV_ROUND_UP(width, 8); + unsigned int pages = DIV_ROUND_UP(y % 8 + height, 8); + u32 array_idx = 0; + int ret, i, j, k; + u8 *data_array = NULL; + + data_array = kcalloc(width, pages, GFP_KERNEL); + if (!data_array) + return -ENOMEM; + + /* + * The screen is divided in pages, each having a height of 8 + * pixels, and the width of the screen. When sending a byte of + * data to the controller, it gives the 8 bits for the current + * column. I.e, the first byte are the 8 bits of the first + * column, then the 8 bits for the second column, etc. + * + * + * Representation of the screen, assuming it is 5 bits + * wide. Each letter-number combination is a bit that controls + * one pixel. + * + * A0 A1 A2 A3 A4 + * B0 B1 B2 B3 B4 + * C0 C1 C2 C3 C4 + * D0 D1 D2 D3 D4 + * E0 E1 E2 E3 E4 + * F0 F1 F2 F3 F4 + * G0 G1 G2 G3 G4 + * H0 H1 H2 H3 H4 + * + * If you want to update this screen, you need to send 5 bytes: + * (1) A0 B0 C0 D0 E0 F0 G0 H0 + * (2) A1 B1 C1 D1 E1 F1 G1 H1 + * (3) A2 B2 C2 D2 E2 F2 G2 H2 + * (4) A3 B3 C3 D3 E3 F3 G3 H3 + * (5) A4 B4 C4 D4 E4 F4 G4 H4 + */ + + ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); + if (ret < 0) + goto out_free; + + ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages); + if (ret < 0) + goto out_free; + + for (i = y / 8; i < y / 8 + pages; i++) { + int m = 8; + + /* Last page may be partial */ + if (8 * (i + 1) > ssd130x->height) + m = ssd130x->height % 8; + for (j = x; j < x + width; j++) { + u8 data = 0; + + for (k = 0; k < m; k++) { + u8 byte = buf[(8 * i + k) * line_length + j / 8]; + u8 bit = (byte >> (j % 8)) & 1; + + data |= bit << k; + } + data_array[array_idx++] = data; + } + } + + ret = ssd130x_write_data(ssd130x, data_array, width * pages); + +out_free: + kfree(data_array); + return ret; +} + +static void ssd130x_clear_screen(struct ssd130x_device *ssd130x) +{ + u8 *buf = NULL; + struct drm_rect fullscreen = { + .x1 = 0, + .x2 = ssd130x->width, + .y1 = 0, + .y2 = ssd130x->height, + }; + + buf = kcalloc(ssd130x->width, ssd130x->height, GFP_KERNEL); + if (!buf) + return; + + ssd130x_update_rect(ssd130x, buf, &fullscreen); + + kfree(buf); +} + +static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct dma_buf_map *map, + struct drm_rect *rect) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); + void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ + int ret = 0; + u8 *buf = NULL; + + buf = kcalloc(fb->width, fb->height, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + drm_fb_xrgb8888_to_mono_reversed(buf, 0, vmap, fb, rect); + + ssd130x_update_rect(ssd130x, buf, rect); + + kfree(buf); + + return ret; +} + +static int ssd130x_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe, + const struct drm_display_mode *mode) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev); + + if (mode->hdisplay != ssd130x->mode.hdisplay && + mode->vdisplay != ssd130x->mode.vdisplay) + return MODE_ONE_SIZE; + + if (mode->hdisplay != ssd130x->mode.hdisplay) + return MODE_ONE_WIDTH; + + if (mode->vdisplay != ssd130x->mode.vdisplay) + return MODE_ONE_HEIGHT; + + return MODE_OK; +} + +static void ssd130x_display_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_device *drm = &ssd130x->drm; + int idx, ret; + + ret = ssd130x_power_on(ssd130x); + if (ret) + return; + + ret = ssd130x_init(ssd130x); + if (ret) + goto out_power_off; + + if (!drm_dev_enter(drm, &idx)) + goto out_power_off; + + ssd130x_fb_blit_rect(plane_state->fb, &shadow_plane_state->data[0], &plane_state->dst); + + ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON); + + backlight_enable(ssd130x->bl_dev); + + drm_dev_exit(idx); + + return; +out_power_off: + ssd130x_power_off(ssd130x); +} + +static void ssd130x_display_pipe_disable(struct drm_simple_display_pipe *pipe) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev); + struct drm_device *drm = &ssd130x->drm; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + ssd130x_clear_screen(ssd130x); + + backlight_disable(ssd130x->bl_dev); + + ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF); + + ssd130x_power_off(ssd130x); + + drm_dev_exit(idx); +} + +static void ssd130x_display_pipe_update(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *old_plane_state) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev); + struct drm_plane_state *plane_state = pipe->plane.state; + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_device *drm = &ssd130x->drm; + struct drm_rect src_clip, dst_clip; + int idx; + + if (!fb) + return; + + if (!pipe->crtc.state->active) + return; + + if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip)) + return; + + dst_clip = plane_state->dst; + if (!drm_rect_intersect(&dst_clip, &src_clip)) + return; + + if (!drm_dev_enter(drm, &idx)) + return; + + ssd130x_fb_blit_rect(plane_state->fb, &shadow_plane_state->data[0], &dst_clip); + + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs ssd130x_pipe_funcs = { + .mode_valid = ssd130x_display_pipe_mode_valid, + .enable = ssd130x_display_pipe_enable, + .disable = ssd130x_display_pipe_disable, + .update = ssd130x_display_pipe_update, + DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, +}; + +static int ssd130x_connector_get_modes(struct drm_connector *connector) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev); + struct drm_display_mode *mode = &ssd130x->mode; + struct device *dev = ssd130x->dev; + + mode = drm_mode_duplicate(connector->dev, &ssd130x->mode); + if (!mode) { + dev_err(dev, "Failed to duplicated mode\n"); + return 0; + } + + drm_mode_probed_add(connector, mode); + drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay); + + /* There is only a single mode */ + return 1; +} + +static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = { + .get_modes = ssd130x_connector_get_modes, +}; + +static const struct drm_connector_funcs ssd130x_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_mode_config_funcs ssd130x_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static const uint32_t ssd130x_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +DEFINE_DRM_GEM_FOPS(ssd130x_fops); + +static const struct drm_driver ssd130x_drm_driver = { + DRM_GEM_SHMEM_DRIVER_OPS, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, + .fops = &ssd130x_fops, +}; + +static int ssd130x_update_bl(struct backlight_device *bdev) +{ + struct ssd130x_device *ssd130x = bl_get_data(bdev); + int brightness = backlight_get_brightness(bdev); + int ret; + + ssd130x->contrast = brightness; + + ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST); + if (ret < 0) + return ret; + + ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast); + if (ret < 0) + return ret; + + return 0; +} + +static const struct backlight_ops ssd130xfb_bl_ops = { + .update_status = ssd130x_update_bl, +}; + +static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) +{ + struct device *dev = ssd130x->dev; + + if (device_property_read_u32(dev, "solomon,width", &ssd130x->width)) + ssd130x->width = 96; + + if (device_property_read_u32(dev, "solomon,height", &ssd130x->height)) + ssd130x->height = 16; + + if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset)) + ssd130x->page_offset = 1; + + if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_offset)) + ssd130x->col_offset = 0; + + if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_offset)) + ssd130x->com_offset = 0; + + if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->prechargep1)) + ssd130x->prechargep1 = 2; + + if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2)) + ssd130x->prechargep2 = 2; + + if (!device_property_read_u8_array(dev, "solomon,lookup-table", + ssd130x->lookup_table, + ARRAY_SIZE(ssd130x->lookup_table))) + ssd130x->lookup_table_set = 1; + + ssd130x->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap"); + ssd130x->com_seq = device_property_read_bool(dev, "solomon,com-seq"); + ssd130x->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap"); + ssd130x->com_invdir = device_property_read_bool(dev, "solomon,com-invdir"); + ssd130x->area_color_enable = + device_property_read_bool(dev, "solomon,area-color-enable"); + ssd130x->low_power = device_property_read_bool(dev, "solomon,low-power"); + + ssd130x->contrast = 127; + ssd130x->vcomh = ssd130x->device_info->default_vcomh; + + /* Setup display timing */ + if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div)) + ssd130x->dclk_div = ssd130x->device_info->default_dclk_div; + if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq)) + ssd130x->dclk_frq = ssd130x->device_info->default_dclk_frq; +} + +static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) +{ + struct drm_display_mode *mode = &ssd130x->mode; + struct device *dev = ssd130x->dev; + struct drm_device *drm = &ssd130x->drm; + unsigned long max_width, max_height; + int ret; + + ret = drmm_mode_config_init(drm); + if (ret) { + dev_err(dev, "DRM mode config init failed: %d\n", ret); + return ret; + } + + mode->type = DRM_MODE_TYPE_DRIVER; + mode->clock = 1; + mode->hdisplay = mode->htotal = ssd130x->width; + mode->hsync_start = mode->hsync_end = ssd130x->width; + mode->vdisplay = mode->vtotal = ssd130x->height; + mode->vsync_start = mode->vsync_end = ssd130x->height; + mode->width_mm = 27; + mode->height_mm = 27; + + max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH); + max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT); + + drm->mode_config.min_width = mode->hdisplay; + drm->mode_config.max_width = max_width; + drm->mode_config.min_height = mode->vdisplay; + drm->mode_config.max_height = max_height; + drm->mode_config.preferred_depth = 32; + drm->mode_config.funcs = &ssd130x_mode_config_funcs; + + ret = drm_connector_init(drm, &ssd130x->connector, &ssd130x_connector_funcs, + DRM_MODE_CONNECTOR_Unknown); + if (ret) { + dev_err(dev, "DRM connector init failed: %d\n", ret); + return ret; + } + + drm_connector_helper_add(&ssd130x->connector, &ssd130x_connector_helper_funcs); + + ret = drm_simple_display_pipe_init(drm, &ssd130x->pipe, &ssd130x_pipe_funcs, + ssd130x_formats, ARRAY_SIZE(ssd130x_formats), + NULL, &ssd130x->connector); + if (ret) { + dev_err(dev, "DRM simple display pipeline init failed: %d\n", ret); + return ret; + } + + drm_plane_enable_fb_damage_clips(&ssd130x->pipe.plane); + + drm_mode_config_reset(drm); + + return 0; +} + +static int ssd130x_get_resources(struct ssd130x_device *ssd130x) +{ + struct device *dev = ssd130x->dev; + + ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ssd130x->reset)) + return dev_err_probe(dev, PTR_ERR(ssd130x->reset), + "Failed to get reset gpio\n"); + + ssd130x->vcc_reg = devm_regulator_get(dev, "vcc"); + if (IS_ERR(ssd130x->vcc_reg)) + return dev_err_probe(dev, PTR_ERR(ssd130x->vcc_reg), + "Failed to get VCC regulator\n"); + + return 0; +} + +struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) +{ + struct ssd130x_device *ssd130x; + struct backlight_device *bl; + struct drm_device *drm; + int ret; + + ssd130x = devm_drm_dev_alloc(dev, &ssd130x_drm_driver, + struct ssd130x_device, drm); + if (IS_ERR(ssd130x)) + return ERR_PTR(dev_err_probe(dev, PTR_ERR(ssd130x), + "Failed to allocate DRM device\n")); + + drm = &ssd130x->drm; + + ssd130x->dev = dev; + ssd130x->regmap = regmap; + ssd130x->device_info = device_get_match_data(dev); + + ssd130x_parse_properties(ssd130x); + + ret = ssd130x_get_resources(ssd130x); + if (ret) + return ERR_PTR(ret); + + bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x, + &ssd130xfb_bl_ops, NULL); + if (IS_ERR(bl)) + return ERR_PTR(dev_err_probe(dev, PTR_ERR(bl), + "Unable to register backlight device\n")); + + bl->props.brightness = ssd130x->contrast; + bl->props.max_brightness = MAX_CONTRAST; + ssd130x->bl_dev = bl; + + ret = ssd130x_init_modeset(ssd130x); + if (ret) + return ERR_PTR(ret); + + ret = drm_dev_register(drm, 0); + if (ret) + return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n")); + + drm_fbdev_generic_setup(drm, 0); + + return ssd130x; +} +EXPORT_SYMBOL_GPL(ssd130x_probe); + +int ssd130x_remove(struct ssd130x_device *ssd130x) +{ + drm_dev_unplug(&ssd130x->drm); + + return 0; +} +EXPORT_SYMBOL_GPL(ssd130x_remove); + +void ssd130x_shutdown(struct ssd130x_device *ssd130x) +{ + drm_atomic_helper_shutdown(&ssd130x->drm); +} +EXPORT_SYMBOL_GPL(ssd130x_shutdown); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Javier Martinez Canillas "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h new file mode 100644 index 000000000000..cd21cdccb566 --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Header file for: + * DRM driver for Solomon SSD130x OLED displays + * + * Copyright 2022 Red Hat Inc. + * Author: Javier Martinez Canillas + * + * Based on drivers/video/fbdev/ssd1307fb.c + * Copyright 2012 Free Electrons + */ + +#ifndef __SSD1307X_H__ +#define __SSD1307X_H__ + +#include +#include + +#include + +struct ssd130x_deviceinfo { + u32 default_vcomh; + u32 default_dclk_div; + u32 default_dclk_frq; + int need_pwm; + int need_chargepump; +}; + +struct ssd130x_device { + struct drm_device drm; + struct device *dev; + struct drm_simple_display_pipe pipe; + struct drm_display_mode mode; + struct drm_connector connector; + struct i2c_client *client; + + struct regmap *regmap; + + const struct ssd130x_deviceinfo *device_info; + + unsigned area_color_enable : 1; + unsigned com_invdir : 1; + unsigned com_lrremap : 1; + unsigned com_seq : 1; + unsigned lookup_table_set : 1; + unsigned low_power : 1; + unsigned seg_remap : 1; + u32 com_offset; + u32 contrast; + u32 dclk_div; + u32 dclk_frq; + u32 height; + u8 lookup_table[4]; + u32 page_offset; + u32 col_offset; + u32 prechargep1; + u32 prechargep2; + + struct backlight_device *bl_dev; + struct pwm_device *pwm; + struct gpio_desc *reset; + struct regulator *vcc_reg; + u32 vcomh; + u32 width; + /* Cached address ranges */ + u8 col_start; + u8 col_end; + u8 page_start; + u8 page_end; +}; + +struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap); +int ssd130x_remove(struct ssd130x_device *ssd130x); +void ssd130x_shutdown(struct ssd130x_device *ssd130x); + +#endif /* __SSD1307X_H__ */ From patchwork Mon Feb 14 13:37:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 75699C433EF for ; Mon, 14 Feb 2022 13:37:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1F7C810E59A; Mon, 14 Feb 2022 13:37:45 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id DAD4510E59D for ; Mon, 14 Feb 2022 13:37:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=62OmRN0+ZmJkqLoaFDxhy0eO6yAnFd+9Iv9L0ky9wLc=; b=K2QR4j+/XoP5AfLCPwTIu955bvhFjIUId2N2uk4X/T2IeSej9U/YojXpTdpbbhfzHEBY2u 8PT4G0Bx46Cu2xv/QnIHedvaNiy9YMfE3zcCGuUbsbT5LL4lAnTMAHuR4UN6ev/y/qCmCr arVNQwBwEmGMWNjH3ccZCX7IQ36nmmk= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-618-S_yDUpaKM46w0-doF9qZKQ-1; Mon, 14 Feb 2022 08:37:40 -0500 X-MC-Unique: S_yDUpaKM46w0-doF9qZKQ-1 Received: by mail-wr1-f70.google.com with SMTP id c9-20020adfa709000000b001dde29c3202so6944614wrd.22 for ; Mon, 14 Feb 2022 05:37:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=62OmRN0+ZmJkqLoaFDxhy0eO6yAnFd+9Iv9L0ky9wLc=; b=bCfpuFjKTXHuaks/yspn8i+hT95DRPCHn3KcHaTngxZsFsXCx65dx2ag6eAde2x4PO kX9y+lZVyTxTpwsXJFcJ5uR03BHka1qUvhwh8fDooqsI3Mj8I9CIvNrIJeecMduCE8S/ MBMFuIOq6UR2D6Tf2xo60jEAKOluKEmjxglVUEMwbsTSAjvWUsXXUxqzUIIVPm6ucYvs goachCYc6G/1huKBKUAjCzXPKp2dUlTcPbHjXgIZZCjW9uCr+SS8Usj3u6Sm0iFR+d5K X8+ditYNMphh2xLjKksSEqsGmwjLdbOFs4iPLf8L4N0zUZrPQ0baBqBariIrQhGfYNBm B8dA== X-Gm-Message-State: AOAM531ZYv1nv9DOap3Qc7IwHb9oLk0CoRUh0rx9PIlK3DGucrW4JtxA BHEQ+mzHSbmx3Pa7NNd9tS8bMU8sx9LWiGN19/pso7xWBch+5Pdpw1IcukvS1jNSjET4B4PI3nx CRilutKW37dfEs2sEIZ7XqZuY45NQ X-Received: by 2002:a5d:4ac7:: with SMTP id y7mr11632468wrs.521.1644845858008; Mon, 14 Feb 2022 05:37:38 -0800 (PST) X-Google-Smtp-Source: ABdhPJw8VZXr0lt8TjYW2cqobZdRW50wOeVp8oV02mur3StsZ5D0CpVhMx2bj567oRG+kIrVHV4Xmw== X-Received: by 2002:a5d:4ac7:: with SMTP id y7mr11632442wrs.521.1644845857767; Mon, 14 Feb 2022 05:37:37 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id y6sm3568918wrd.30.2022.02.14.05.37.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:37:37 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 4/6] drm/solomon: Add SSD130x OLED displays I2C support Date: Mon, 14 Feb 2022 14:37:08 +0100 Message-Id: <20220214133710.3278506-5-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, David Airlie , Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Thomas Zimmermann , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The ssd130x driver only provides the core support for these devices but it does not have any bus transport logic. Add a driver to interface over I2C. Signed-off-by: Javier Martinez Canillas Reviewed-by: Andy Shevchenko Reviewed-by: Maxime Ripard --- (no changes since v5) Changes in v5: - Add Andy Shevchenko's Reviewed-by tag to patch #4. Changes in v4: - Remove unnecessary casting (Geert Uytterhoeven) - Remove redundant blank lines (Andy Shevchenko) - Remove comma after of_device_id table terminator (Andy Shevchenko) Changes in v3: - Add a separate driver for SSD130X chips I2C support (Andy Shevchenko) drivers/gpu/drm/solomon/Kconfig | 9 ++ drivers/gpu/drm/solomon/Makefile | 1 + drivers/gpu/drm/solomon/ssd130x-i2c.c | 116 ++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 drivers/gpu/drm/solomon/ssd130x-i2c.c diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index 7720a7039e8d..5861c3ab7c45 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -10,3 +10,12 @@ config DRM_SSD130X the appropriate bus transport in your chip also must be selected. If M is selected the module will be called ssd130x. + +config DRM_SSD130X_I2C + tristate "DRM support for Solomon SSD130x OLED displays (I2C bus)" + depends on DRM_SSD130X && I2C + select REGMAP_I2C + help + Say Y here if the SSD130x OLED display is connected via I2C bus. + + If M is selected the module will be called ssd130x-i2c. diff --git a/drivers/gpu/drm/solomon/Makefile b/drivers/gpu/drm/solomon/Makefile index f685addb19fe..4bfc5acb0447 100644 --- a/drivers/gpu/drm/solomon/Makefile +++ b/drivers/gpu/drm/solomon/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_DRM_SSD130X) += ssd130x.o +obj-$(CONFIG_DRM_SSD130X_I2C) += ssd130x-i2c.o diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c new file mode 100644 index 000000000000..3126aeda4ced --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130x OLED displays (I2C bus) + * + * Copyright 2022 Red Hat Inc. + * Author: Javier Martinez Canillas + * + * Based on drivers/video/fbdev/ssd1307fb.c + * Copyright 2012 Free Electrons + */ +#include +#include + +#include "ssd130x.h" + +#define DRIVER_NAME "ssd130x-i2c" +#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)" + +static const struct regmap_config ssd130x_i2c_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int ssd130x_i2c_probe(struct i2c_client *client) +{ + struct ssd130x_device *ssd130x; + struct regmap *regmap; + + regmap = devm_regmap_init_i2c(client, &ssd130x_i2c_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ssd130x = ssd130x_probe(&client->dev, regmap); + if (IS_ERR(ssd130x)) + return PTR_ERR(ssd130x); + + i2c_set_clientdata(client, ssd130x); + + return 0; +} + +static int ssd130x_i2c_remove(struct i2c_client *client) +{ + struct ssd130x_device *ssd130x = i2c_get_clientdata(client); + + return ssd130x_remove(ssd130x); +} + +static void ssd130x_i2c_shutdown(struct i2c_client *client) +{ + struct ssd130x_device *ssd130x = i2c_get_clientdata(client); + + ssd130x_shutdown(ssd130x); +} + +static struct ssd130x_deviceinfo ssd130x_ssd1305_deviceinfo = { + .default_vcomh = 0x34, + .default_dclk_div = 1, + .default_dclk_frq = 7, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1306_deviceinfo = { + .default_vcomh = 0x20, + .default_dclk_div = 1, + .default_dclk_frq = 8, + .need_chargepump = 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1307_deviceinfo = { + .default_vcomh = 0x20, + .default_dclk_div = 2, + .default_dclk_frq = 12, + .need_pwm = 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1309_deviceinfo = { + .default_vcomh = 0x34, + .default_dclk_div = 1, + .default_dclk_frq = 10, +}; + +static const struct of_device_id ssd130x_of_match[] = { + { + .compatible = "solomon,ssd1305fb-i2c", + .data = &ssd130x_ssd1305_deviceinfo, + }, + { + .compatible = "solomon,ssd1306fb-i2c", + .data = &ssd130x_ssd1306_deviceinfo, + }, + { + .compatible = "solomon,ssd1307fb-i2c", + .data = &ssd130x_ssd1307_deviceinfo, + }, + { + .compatible = "solomon,ssd1309fb-i2c", + .data = &ssd130x_ssd1309_deviceinfo, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ssd130x_of_match); + +static struct i2c_driver ssd130x_i2c_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = ssd130x_of_match, + }, + .probe_new = ssd130x_i2c_probe, + .remove = ssd130x_i2c_remove, + .shutdown = ssd130x_i2c_shutdown, +}; +module_i2c_driver(ssd130x_i2c_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Javier Martinez Canillas "); +MODULE_LICENSE("GPL v2"); From patchwork Mon Feb 14 13:39:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745632 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DFF4FC43217 for ; Mon, 14 Feb 2022 13:39:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 105B610E510; Mon, 14 Feb 2022 13:39:26 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id B493E10E4F5 for ; Mon, 14 Feb 2022 13:39:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845963; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q0nJAs/QVKzUPfZInqWn93G2x7vjNHkbBF9qYOiGnWA=; b=BzuYSR8ToOYSGa/ULnUgF5t6PIqflxL07sS2S0uvTpvSvLaMCql9ql8d2NQSgfC8kDEouP aHl8GP5G3fV0RZaqfoc0llmb5TJkciRqwuux8pFQ3sfDLNC20SZARbTEZQgRPhQWLb4OUS 1liYMh5npD2+oPddhezMFPhVH65jpyA= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-43-MVqCRbNwOmK4ix6qJsUvCw-1; Mon, 14 Feb 2022 08:39:22 -0500 X-MC-Unique: MVqCRbNwOmK4ix6qJsUvCw-1 Received: by mail-wr1-f71.google.com with SMTP id v17-20020adf8b51000000b001e336bf3be7so6956353wra.1 for ; Mon, 14 Feb 2022 05:39:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=q0nJAs/QVKzUPfZInqWn93G2x7vjNHkbBF9qYOiGnWA=; b=q8tRHMbPGMISESDOSuCMpvd4dkSYd6rDHaJ6AhqtMTeS7wzJ9nojqkTiN6kBn/Kmno MT8oA7ox9gXuCGTqyYYLrDkiNI8C6osQPwUVA08tNN9p9/nO1A8DE08JxhMy2ZzrNwnO 8symkX888RIjWMhuK/sPyBDdWIN6ZbBu4/zbr+VkuCFgGjwVAQrBpY3W3V2SynsbjMup 2ZK0ZolqgdJcPgahOyJxy04+Hr3VEiTNuXpE2EsZL7j7xoFBJJjS6ukosNzWocS2fnPG h3yuEPW4nsWmcjjP4oL4b083rdPoazn2XPVjVQaVv57eh6uVwifDuPP0VNnBBAdGYSZZ 1vDA== X-Gm-Message-State: AOAM532ryhjSD+isiKYW+56fK0tDgzfgI4DDbymN6SOmTw9CaRrRezds KySl36vbpEncVp2TY3A5vauXnZrOYkeMcBZeYzoK+z9dCRprYvNUfwcnt5tWs/LUIgzQG8dkQP3 xZ6XCGj1GBBniwwgnsR1SfVqyng6x X-Received: by 2002:a5d:4652:: with SMTP id j18mr9457907wrs.600.1644845961574; Mon, 14 Feb 2022 05:39:21 -0800 (PST) X-Google-Smtp-Source: ABdhPJynrCAqmAm2n2lQ+jT84K1ccY7RTWNT1XbLbIiM5V2Tu7Q5FECiZBbqhtjbe/uKekjhMZ/1gA== X-Received: by 2002:a5d:4652:: with SMTP id j18mr9457887wrs.600.1644845961377; Mon, 14 Feb 2022 05:39:21 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id n20sm2108941wmq.42.2022.02.14.05.39.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:39:21 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 5/6] MAINTAINERS: Add entry for Solomon SSD130x OLED displays DRM driver Date: Mon, 14 Feb 2022 14:39:15 +0100 Message-Id: <20220214133915.3278886-1-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To make sure that tools like the get_maintainer.pl script will suggest to Cc me if patches are posted for this driver. Also include the Device Tree binding for the old ssd1307fb fbdev driver since the new DRM driver was made compatible with the existing binding. Signed-off-by: Javier Martinez Canillas Acked-by: Sam Ravnborg Reviewed-by: Andy Shevchenko Acked-by: Maxime Ripard --- (no changes since v5) Changes in v5: - Add Andy Shevchenko's Reviewed-by tag to patch #5. Changes in v3: - Adapt MAINTAINERS entry to point to the new drivers/gpu/drm/solomon directory. Changes in v2: - Add Sam Ravnborg's acked-by to patch adding a MAINTAINERS entry (Sam Ravnborg) MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d03ad8da1f36..05c306986ab0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6102,6 +6102,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/repaper.txt F: drivers/gpu/drm/tiny/repaper.c +DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS +M: Javier Martinez Canillas +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +F: drivers/gpu/drm/solomon/ssd130x* + DRM DRIVER FOR QEMU'S CIRRUS DEVICE M: Dave Airlie M: Gerd Hoffmann From patchwork Mon Feb 14 13:39:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 12745633 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2E8D9C433F5 for ; Mon, 14 Feb 2022 13:39:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 410EF10E5B8; Mon, 14 Feb 2022 13:39:44 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8F36710E5B8 for ; Mon, 14 Feb 2022 13:39:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644845981; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Etof0neSgRXt027GXsgMkq+0wQ1AzPcD2BHFX9AFsyc=; b=bd1v2bS/soZIYMR2fHFdXMHG4K22IGIoMeOCdOOBLqcxQnwz1l5pCZ3TblCtuQr+ncQBdG VZ4VrhnbGExpQk08AcSnw0RtKndrlSL/Yhe03XawdnLNhBM91QB0hL8l7w6voztglSxgcX MBmwUXNgQ5qXA4BkCG0NH067ZxcMc1o= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-618-manWEs5uPhmAnMRP7ww-9w-1; Mon, 14 Feb 2022 08:39:40 -0500 X-MC-Unique: manWEs5uPhmAnMRP7ww-9w-1 Received: by mail-wr1-f69.google.com with SMTP id d13-20020adfa34d000000b001e33a1c56f3so6920892wrb.20 for ; Mon, 14 Feb 2022 05:39:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Etof0neSgRXt027GXsgMkq+0wQ1AzPcD2BHFX9AFsyc=; b=wuLXxNN6jYsBPgCRM+dkLTya2OC4/AST1SfG869ocOFAWIlMtY1I6BAO6GMu7DQR8Y 2E9Cwy0XLRW0c9GUbrGyadd9EXqB2RfMCd/2vuDpjhpLg6BIPRbXK4ypGkqqt17NJjKz bOY45QQ9+/IhdhWjog++kyykPBiSQL7rEesrCTk/ns1KvjVoYR1gjNwI0OAXwbUEiQop ePNjyEYWfW0paYLqmNMDBR99iw+uIphNEIQlMPCGh8IEsTBarbXufgLa66TNT3nkMu5s /YaPW9uGYYdmszG/9MQe1Qp0CZ7D5nUGM4bMWMBLZg1K4UJ6wtLbfqFyYNKK0VPW2MuR 6MNw== X-Gm-Message-State: AOAM531GGkKCEEwmcd7hQrrQozckIaw4ZfR3HLaQlYLSgcZktuJIWdPD RIM3/dEMwzbzG/UeLPPFf1s0FXntVG4crH+H0TvGPaOjaGY3E+dkMQr+LGeDrma+by7nXstvRtt Xi2e7j5/RxNAzEK8PfGixRMZXSxMj X-Received: by 2002:a5d:4411:: with SMTP id z17mr10986767wrq.384.1644845979249; Mon, 14 Feb 2022 05:39:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJx3m0kF1+a4nMfmlEayb8F11MLh6Npr5zmIcoMfkIl8FoBO9TtWTVfjOMLjIXuY3s4cdKK7qA== X-Received: by 2002:a5d:4411:: with SMTP id z17mr10986751wrq.384.1644845979070; Mon, 14 Feb 2022 05:39:39 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id l15sm11826697wmi.29.2022.02.14.05.39.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Feb 2022 05:39:38 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [PATCH v6 6/6] dt-bindings: display: ssd1307fb: Add myself as binding co-maintainer Date: Mon, 14 Feb 2022 14:39:35 +0100 Message-Id: <20220214133935.3278933-1-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220214133710.3278506-1-javierm@redhat.com> References: <20220214133710.3278506-1-javierm@redhat.com> MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=javierm@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-fbdev@vger.kernel.org, Daniel Vetter , Javier Martinez Canillas , dri-devel@lists.freedesktop.org, =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Geert Uytterhoeven , Maxime Ripard , Andy Shevchenko , Sam Ravnborg Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The ssd130x DRM driver also makes use of this Device Tree binding to allow existing users of the fbdev driver to migrate without the need to change their Device Trees. Add myself as another maintainer of the binding, to make sure that I will be on Cc when patches are proposed for it. Suggested-by: Sam Ravnborg Signed-off-by: Javier Martinez Canillas Acked-by: Rob Herring Reviewed-by: Andy Shevchenko Acked-by: Maxime Ripard --- (no changes since v5) Changes in v5: - Add Andy Shevchenko's Reviewed-by tag to patch #6. Changes in v4: - Add Rob Herring Acked-by tag to patch adding as DT binding co-maintainer. Changes in v2: - Add myself as co-maintainer of the ssd1370fb DT binding (Sam Ravnborg). Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml index 2ed2a7d0ca2f..9baafd0c42dd 100644 --- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -8,6 +8,7 @@ title: Solomon SSD1307 OLED Controller Framebuffer maintainers: - Maxime Ripard + - Javier Martinez Canillas properties: compatible: