From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 140D5C433EF for ; Wed, 9 Feb 2022 09:39:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235040AbiBIJjF (ORCPT ); Wed, 9 Feb 2022 04:39:05 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:57612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232209AbiBIJgL (ORCPT ); Wed, 9 Feb 2022 04:36:11 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 867E2E015277 for ; Wed, 9 Feb 2022 01:36:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399301; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X6Mi9ajTPAaH4GRgHowugsZMJXzFkvUakKFgNQa4uWk=; b=UzYHMU5DNyQRp6CriqcGL3xuPiPxHELVczzlIxkoQLLLMqIOO3ZPoH5oNZARa546kR4Q/O 5bbTNZP84rDXEIZKHdw6833wqBo2mpek+BNTpwb0J2CX17GxA7jvzeI3Z/suAp9u9QdzbZ 80IcQ+5wKOd6o4JvxW0o+s4YYAp8Xeg= 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-517-4xWy6QLdP1K6uCtLj9N9zA-1; Wed, 09 Feb 2022 04:03:27 -0500 X-MC-Unique: 4xWy6QLdP1K6uCtLj9N9zA-1 Received: by mail-wr1-f69.google.com with SMTP id w7-20020adfbac7000000b001d6f75e4faeso846741wrg.7 for ; Wed, 09 Feb 2022 01:03:27 -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=X6Mi9ajTPAaH4GRgHowugsZMJXzFkvUakKFgNQa4uWk=; b=Gex56tEs9QddmEoQEFNZHF2qxvTgiIB1ZzclmQSb8TOfg6jMwBb2HNCSA7PO7Mie57 mjM4T5levTzvsETie9OyTvFiTYgHwfZOTvrQvHpMmFGh/9iR70nJrFySJZTLnsfM7gxI XB8lmNvzecjE/0IqvqOS9was0tPcfLkJdqOpvrA+0Kx1Ub+nvNOTppDuLlJzarB+LSy8 VpFMG7g11/mX18SVGraRSH304O2MGS/o2x15aHA+erGvN9qohsu/mJWVztZCysMncmA+ VdT0ETBlqR1msfYRsnGqvVW5FvpkVo8nrClrqj32ETEa6zuR7hfZ2aswnPuHuqPeh0pJ 4gFg== X-Gm-Message-State: AOAM532PmPf8IOg/XeYjYmR78uxKpJTyetxIoHJ/24E2QgsXBfOBRLzD gsyaNYQl/ZxkDGS5sl2gJTHditf84MIMlSNQUwOdptgKXOWYy5y+sKP3+iVoL18Cqf95FOlZULK 1rtcBtym2s4ufpEJALT39j/ujZvIxR+XHHsjM+LkT4kAUGdi5nbOUfcExsxqe7eKZp4ImPX5iax Y= X-Received: by 2002:a5d:6549:: with SMTP id z9mr1223155wrv.420.1644397406207; Wed, 09 Feb 2022 01:03:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJxyAoxcw7jgi7SZI0lZuE3Ts1yz6KYfW12uWxaTagcv05Vtrjuw9CQlAfWSnk+ZHtktaUn1mg== X-Received: by 2002:a5d:6549:: with SMTP id z9mr1223114wrv.420.1644397405788; Wed, 09 Feb 2022 01:03:25 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id z1sm4058866wmk.32.2022.02.09.01.03.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:03:25 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Thomas Zimmermann , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , Maxime Ripard , Geert Uytterhoeven , linux-fbdev@vger.kernel.org, Daniel Vetter , Sam Ravnborg , dri-devel@lists.freedesktop.org, Javier Martinez Canillas , Daniel Vetter , David Airlie , Maarten Lankhorst , Maxime Ripard Subject: [PATCH v3 1/7] drm/format-helper: Add drm_fb_xrgb8888_to_gray8_line() Date: Wed, 9 Feb 2022 10:03:08 +0100 Message-Id: <20220209090314.2511959-2-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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_form= at_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); =20 +static void drm_fb_xrgb8888_to_gray8_line(u8 *dst, const u32 *src, unsigne= d int pixels) +{ + unsigned int x; + + for (x =3D 0; x < pixels; x++) { + u8 r =3D (*src & 0x00ff0000) >> 16; + u8 g =3D (*src & 0x0000ff00) >> 8; + u8 b =3D *src & 0x000000ff; + + /* ITU BT.601: Y =3D 0.299 R + 0.587 G + 0.114 B */ + *dst++ =3D (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 voi= d *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - unsigned int len =3D (clip->x2 - clip->x1) * sizeof(u32); - unsigned int x, y; + unsigned int linepixels =3D clip->x2 - clip->x1; + unsigned int len =3D 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 =3D clip->y1; y < clip->y2; y++) { dst8 =3D dst; src32 =3D memcpy(buf, vaddr, len); - for (x =3D clip->x1; x < clip->x2; x++) { - u8 r =3D (*src32 & 0x00ff0000) >> 16; - u8 g =3D (*src32 & 0x0000ff00) >> 8; - u8 b =3D *src32 & 0x000000ff; - - /* ITU BT.601: Y =3D 0.299 R + 0.587 G + 0.114 B */ - *dst8++ =3D (3 * r + 6 * g + b) / 10; - src32++; - } - + drm_fb_xrgb8888_to_gray8_line(dst8, src32, linepixels); vaddr +=3D fb->pitches[0]; dst +=3D dst_pitch; } --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AF44C433F5 for ; Wed, 9 Feb 2022 09:39:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235468AbiBIJjK (ORCPT ); Wed, 9 Feb 2022 04:39:10 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:40532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237462AbiBIJcH (ORCPT ); Wed, 9 Feb 2022 04:32:07 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 208A7E05044E for ; Wed, 9 Feb 2022 01:32:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399072; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zdxWJO9LAQS3hXjCTfCOj6rfJd8h7iT29/43rVI8FJc=; b=RYcTnQwSIIBqyacgVFIa8/KdbgIJe6l1vv6DnFZYFa0VGa5jom6WJ+AJo7akmpmc6XBMft tcwOj5V8S3651HdUlPHrKHZnbgsnP4FVJ1d3W28pUebzPAsrjM4ChcHlp1dNvDRZJco/OR LthbqN83qjsMRrG9BTDlqtUJKUMXMBk= 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-581-FYmYteauOMijEAhJMuFgnA-1; Wed, 09 Feb 2022 04:03:29 -0500 X-MC-Unique: FYmYteauOMijEAhJMuFgnA-1 Received: by mail-wr1-f71.google.com with SMTP id k20-20020adfc714000000b001e305cd1597so821872wrg.19 for ; Wed, 09 Feb 2022 01:03:28 -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=zdxWJO9LAQS3hXjCTfCOj6rfJd8h7iT29/43rVI8FJc=; b=KQR2xZFx51qcds7Ev1+Fkg+xPeZ+eI5ax3lagvIJ8HjLDP8p0nXiYeC9CggKSSyuJ7 SakrS76hOjfABUNpQFlgKg+u/p7uQA2LZV6Pwen9U8ceCiXMO8Sr7c6aiaatilzzsw6p AEq9dzKtY7IMSJZt0CCv2gmpxqXXNRQlDBFI4Y7ehSxZD/jJ0h0NqEH6xeVBRQuSTSu6 7FLaYjLweE7gQ5OMau6XNG/GAZO9GW6BwttrvvExSbw4F1Zjt0rsqnyXCmUv7KDVO8WT lktVJcCQ8UjvxXk4TotKHOA/4wa7sqAjR3rL8V4iCXNccVGlpneT0bRdRyk8glcaF/op 1FLw== X-Gm-Message-State: AOAM533Zv3SKKd1GhSlwNasCl2vpPlCVBEoqzKNoRpWETIDBe9hL2RVO cTqNtzDxfd52X4dnfUO+NByd5Q+gzq6AjrMU8VOzqy7MqfncihL1kKTSpITuutdLyO3mUNygtVQ kfnQcjSdGlZ7HBPKATUtuEOpbzutWZ+lmD53H97JLBm/uJvLC4DOvjiyPzwfuK07h3A7v/yNw+W 4= X-Received: by 2002:adf:d213:: with SMTP id j19mr1278406wrh.202.1644397407786; Wed, 09 Feb 2022 01:03:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJw4LX0O5Ay6A6QNCHdwHnoLg8BJ5NtECzXAPXBhnUZbYo9/mfvXWUJmoCBk7U2Ko8fALs42UA== X-Received: by 2002:adf:d213:: with SMTP id j19mr1278375wrh.202.1644397407504; Wed, 09 Feb 2022 01:03:27 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id z1sm4058866wmk.32.2022.02.09.01.03.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:03:27 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Thomas Zimmermann , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , Maxime Ripard , Geert Uytterhoeven , linux-fbdev@vger.kernel.org, Daniel Vetter , Sam Ravnborg , dri-devel@lists.freedesktop.org, Javier Martinez Canillas , Daniel Vetter , David Airlie , Maarten Lankhorst , Maxime Ripard Subject: [PATCH v3 2/7] drm/format-helper: Add drm_fb_{xrgb8888,gray8}_to_mono_reversed() Date: Wed, 9 Feb 2022 10:03:09 +0100 Message-Id: <20220209090314.2511959-3-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support to convert XR24 and 8-bit grayscale to reversed monochrome for drivers that control monochromatic panels, that only have 1 bit per pixel. The drm_fb_gray8_to_mono_reversed() helper was based on the function that does the same in the drivers/gpu/drm/tiny/repaper.c driver. Signed-off-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann --- 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 Zimmerma= nn) - Handle case where the source buffer is not aligned to 8 (Thomas Zimmerman= n) drivers/gpu/drm/drm_format_helper.c | 157 ++++++++++++++++++++++++++++ include/drm/drm_format_helper.h | 8 ++ 2 files changed, 165 insertions(+) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_form= at_helper.c index b981712623d3..19710342c0de 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -591,3 +591,160 @@ 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, uns= igned int pixels, + unsigned int start_offset, unsigned int end_offset) +{ + unsigned int xb, i; + + for (xb =3D 0; xb < pixels; xb++) { + unsigned int start =3D 0, end =3D 8; + u8 byte =3D 0x00; + + if (xb =3D=3D 0 && start_offset) + start =3D start_offset; + + if (xb =3D=3D pixels - 1 && end_offset) + end =3D end_offset; + + for (i =3D start; i < end; i++) { + unsigned int x =3D xb * 8 + i; + + byte >>=3D 1; + if (src[x] >> 7) + byte |=3D BIT(7); + } + *dst++ =3D byte; + } +} + +/** + * drm_fb_gray8_to_mono_reversed - Convert grayscale to reversed monochrome + * @dst: reversed monochrome destination buffer + * @dst_pitch: Number of bytes between two consecutive scanlines within dst + * @src: 8-bit grayscale source buffer + * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy + * + * DRM doesn't have native monochrome or grayscale support. + * Such drivers can announce the commonly supported XR24 format to userspa= ce + * and use drm_fb_xrgb8888_to_gray8() to convert to grayscale and then this + * helper function to convert to the native format. + */ +void drm_fb_gray8_to_mono_reversed(void *dst, unsigned int dst_pitch, cons= t void *vaddr, + const struct drm_framebuffer *fb, + const struct drm_rect *clip) +{ + + unsigned int linepixels =3D drm_rect_width(clip); + unsigned int lines =3D drm_rect_height(clip); + unsigned int start_offset, end_offset; + unsigned int y; + const u8 *gray8 =3D vaddr; + u8 *mono =3D dst; + + /* + * 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 =3D DIV_ROUND_UP(linepixels, 8); + + /* + * 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 =3D clip->x1 % 8; + end_offset =3D clip->x2 % 8; + + for (y =3D 0; y < lines; y++) { + drm_fb_gray8_to_mono_reversed_line(mono, gray8, dst_pitch, + start_offset, end_offset); + gray8 +=3D fb->pitches[0]; + mono +=3D dst_pitch; + } +} + +/** + * drm_fb_xrgb8888_to_mono_reversed - Convert XRGB8888 to reversed monochr= ome + * @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 userspa= ce + * and use this function to convert to the native format. + * + * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale a= nd + * then the result is converted from grayscale to reversed monohrome. + */ +void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, c= onst void *vaddr, + const struct drm_framebuffer *fb, const struct drm_rect *clip) +{ + unsigned int linepixels =3D drm_rect_width(clip); + unsigned int lines =3D clip->y2 - clip->y1; + unsigned int cpp =3D fb->format->cpp[0]; + unsigned int len_src32 =3D linepixels * cpp; + unsigned int start_offset, end_offset; + unsigned int y; + u8 *mono =3D dst, *gray8; + u32 *src32; + + if (WARN_ON(fb->format->format !=3D 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 =3D DIV_ROUND_UP(linepixels, 8); + + /* + * The cma memory is write-combined so reads are uncached. + * Speed up by fetching one line at a time. + */ + src32 =3D kmalloc(len_src32, GFP_KERNEL); + if (!src32) + return; + + /* + * Copies are done line-by-line, allocate an intermediate + * buffer to copy the gray8 lines and then convert to mono. + */ + gray8 =3D kmalloc(linepixels, GFP_KERNEL); + if (!gray8) + goto free_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 =3D clip->x1 % 8; + end_offset =3D clip->x2 % 8; + + vaddr +=3D clip_offset(clip, fb->pitches[0], cpp); + for (y =3D 0; y < lines; y++) { + src32 =3D 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_offset); + vaddr +=3D fb->pitches[0]; + mono +=3D dst_pitch; + } + + kfree(gray8); +free_src32: + kfree(src32); +} +EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono_reversed); diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helpe= r.h index b30ed5de0a33..6638da9e9774 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -43,4 +43,12 @@ 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); =20 +void drm_fb_gray8_to_mono_reversed(void *dst, unsigned int dst_pitch, cons= t void *src, + const struct drm_framebuffer *fb, + const struct drm_rect *clip); + +void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, c= onst void *src, + const struct drm_framebuffer *fb, + const struct drm_rect *clip); + #endif /* __LINUX_DRM_FORMAT_HELPER_H */ --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63923C433F5 for ; Wed, 9 Feb 2022 09:09:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233113AbiBIJJQ (ORCPT ); Wed, 9 Feb 2022 04:09:16 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:46548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230425AbiBIJJN (ORCPT ); Wed, 9 Feb 2022 04:09:13 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3D20EE0754EE for ; Wed, 9 Feb 2022 01:09:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644397439; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r1b7Bf0CVql46bfS8nFUUPEriioGV0kBypsdQVsEfh4=; b=HZp40L770lDCQB70xzy2MhDFj7/rMTg0v3DViLsOEJuWtQJqUbWqlhkYyni4n3fbDbWWwM ei3XGJASPnQCzmfBY3gAkc1XmS3LQZjfNVX07Ej9gll8j2U9iW0XAe9C/L39kGghhS0XC8 tcDAwfGyQG/zNS/wEF1kWcwt1XbMNZQ= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-266-f8AaSx9-O4ihs2kpEqezHQ-1; Wed, 09 Feb 2022 04:03:31 -0500 X-MC-Unique: f8AaSx9-O4ihs2kpEqezHQ-1 Received: by mail-wm1-f69.google.com with SMTP id v185-20020a1cacc2000000b0034906580813so2351856wme.1 for ; Wed, 09 Feb 2022 01:03:31 -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=r1b7Bf0CVql46bfS8nFUUPEriioGV0kBypsdQVsEfh4=; b=aMPbLIGX3OFT+J1VBtx8atPWi4YGPIqND96K00x8zqk8dlo1tjMBUrSsjyFNxFb5h3 NWxy8edFn5mxudWRQt8pZtefwo+iURGzKrTwr0SkD7KwmCZMNCd+NuLvEMOPtoj4YwAO FNOgpuffIVvyvaq2W4jKMku+yp8lZ8q2RGVWDmB0vtPTyShcXE7e99NEui9YYph+fcKW LkXt+AfnMv/uQ11tjm6G8LzXLAaKYpm2TW00y75C4OTVLXzEaC2R+JOx/FJyqxXBV1de 8DOchS8OAACHz9qvcxViU7diFpu9bHJCDTtiD+e9cgxGJIPIHv+GNd1E7Uta6Ps+15DR U35A== X-Gm-Message-State: AOAM533RodkTSjMS9POwKqhb6rNi/eDCJUsDSAISMsu4bg+kAIztpx23 R8ixohrB9dhypBNecL+h7VzGkgRUzzjc8xW0dBHvw20CJWH/avRSSrUOE4IAOrEtWQ0wAl7lBeh K6TrBjVdpCuhB8Ny9pL+q5y8BEMIEeSYXI3RMDmJnnAmYT5+yOvf9WSY+lcTWT2FfG465KNVf6j 0= X-Received: by 2002:a5d:5985:: with SMTP id n5mr1298033wri.238.1644397409922; Wed, 09 Feb 2022 01:03:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJwAHnrZmcBzwCz4xzqz4k4l60NnNnoiIBc8I5MrcUIhoaVtBSyy0tFerkmoa7MjLKxbwyFrnQ== X-Received: by 2002:a5d:5985:: with SMTP id n5mr1297949wri.238.1644397409064; Wed, 09 Feb 2022 01:03:29 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id z1sm4058866wmk.32.2022.02.09.01.03.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:03:28 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Thomas Zimmermann , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , Maxime Ripard , Geert Uytterhoeven , linux-fbdev@vger.kernel.org, Daniel Vetter , Sam Ravnborg , dri-devel@lists.freedesktop.org, Javier Martinez Canillas , Daniel Vetter , David Airlie , Lee Jones , Liam Girdwood , Maarten Lankhorst , Mark Brown , Maxime Ripard , Thierry Reding , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-pwm@vger.kernel.org Subject: [PATCH v3 3/7] drm: Add driver for Solomon SSD130X OLED displays Date: Wed, 9 Feb 2022 10:03:10 +0100 Message-Id: <20220209090314.2511959-4-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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 Shevc= henko) - 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 Shevchen= ko) - 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 Zimmerma= nn) - 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 Zimmerman= n) - 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 | 823 ++++++++++++++++++++++++++++++ drivers/gpu/drm/solomon/ssd130x.h | 76 +++ 6 files changed, 915 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..c423c920c027 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -405,6 +405,8 @@ source "drivers/gpu/drm/gud/Kconfig" =20 source "drivers/gpu/drm/sprd/Kconfig" =20 +source "drivers/gpu/drm/solomon/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 8675c2af7ae1..a07b777e778a 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -133,3 +133,4 @@ obj-y +=3D xlnx/ obj-y +=3D gud/ obj-$(CONFIG_DRM_HYPERV) +=3D hyperv/ obj-$(CONFIG_DRM_SPRD) +=3D sprd/ +obj-y +=3D solomon/ diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kcon= fig new file mode 100644 index 000000000000..c969c358a4a7 --- /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/Mak= efile new file mode 100644 index 000000000000..f685addb19fe --- /dev/null +++ b/drivers/gpu/drm/solomon/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_DRM_SSD130X) +=3D ssd130x.o diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ss= d130x.c new file mode 100644 index 000000000000..79943f2e73a2 --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -0,0 +1,823 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130X OLED displays + * + * Copyright 2022 Red Hat Inc. + * Authors: 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 "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_ADDRESS_MODE_HORIZONTAL (0x00) +#define SSD130X_SET_ADDRESS_MODE_VERTICAL (0x01) +#define SSD130X_SET_ADDRESS_MODE_PAGE (0x02) +#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_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 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) +{ + int ret; + + ret =3D regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count); + if (ret) + return ret; + + return 0; +} + +/* + * Helper to write command (SSD130X_COMMAND). The fist variadic argument + * is the command to write and the following are the command options. + */ +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 =3D va_arg(ap, int); + ret =3D regmap_write(ssd130x->regmap, SSD130X_COMMAND, (u8)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 =3D col_start + cols - 1; + int ret; + + if (col_start =3D=3D ssd130x->col_start && col_end =3D=3D ssd130x->col_en= d) + return 0; + + ret =3D ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, c= ol_end); + if (ret < 0) + return ret; + + ssd130x->col_start =3D col_start; + ssd130x->col_end =3D col_end; + return 0; +} + +static int ssd130x_set_page_range(struct ssd130x_device *ssd130x, + u8 page_start, u8 pages) +{ + u8 page_end =3D page_start + pages - 1; + int ret; + + if (page_start =3D=3D ssd130x->page_start && page_end =3D=3D ssd130x->pag= e_end) + return 0; + + ret =3D ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start,= page_end); + if (ret < 0) + return ret; + + ssd130x->page_start =3D page_start; + ssd130x->page_end =3D page_end; + return 0; +} + +static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x) +{ + struct device *dev =3D ssd130x->dev; + struct pwm_state pwmstate; + + ssd130x->pwm =3D 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) +{ + /* 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 =3D ssd130x->dev; + int ret; + + if (ssd130x->reset) + ssd130x_reset(ssd130x); + + if (ssd130x->vbat_reg) { + ret =3D regulator_enable(ssd130x->vbat_reg); + if (ret) { + dev_err(dev, "Failed to enable VBAT: %d\n", ret); + return ret; + } + } + + if (ssd130x->device_info->need_pwm) { + ret =3D ssd130x_pwm_enable(ssd130x); + if (ret) { + dev_err(dev, "Failed to enable PWM: %d\n", ret); + if (ssd130x->vbat_reg) + regulator_disable(ssd130x->vbat_reg); + return ret; + } + } + + return 0; +} + +static void ssd130x_power_off(struct ssd130x_device *ssd130x) +{ + if (ssd130x->device_info->need_pwm) { + pwm_disable(ssd130x->pwm); + pwm_put(ssd130x->pwm); + } + + if (ssd130x->vbat_reg) + regulator_disable(ssd130x->vbat_reg); +} + +static int ssd130x_init(struct ssd130x_device *ssd130x) +{ + u32 precharge, dclk, com_invdir, compins, chargepump; + int ret; + + /* Set initial contrast */ + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast= ); + if (ret < 0) + return ret; + + /* Set segment re-map */ + if (ssd130x->seg_remap) { + ret =3D ssd130x_write_cmd(ssd130x, 1, SSD130X_SEG_REMAP_ON); + if (ret < 0) + return ret; + } + + /* Set COM direction */ + com_invdir =3D 0xc0 | ssd130x->com_invdir << 3; + ret =3D ssd130x_write_cmd(ssd130x, 1, com_invdir); + if (ret < 0) + return ret; + + /* Set multiplex ratio value */ + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130= x->height - 1); + if (ret < 0) + return ret; + + /* set display offset value */ + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x= ->com_offset); + if (ret < 0) + return ret; + + /* Set clock frequency */ + dclk =3D ((ssd130x->dclk_div - 1) & 0xf) | (ssd130x->dclk_frq & 0xf) << 4; + ret =3D 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 =3D ((ssd130x->area_color_enable ? 0x30 : 0) | + (ssd130x->low_power ? 5 : 0)); + + ret =3D 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 =3D (ssd130x->prechargep1 & 0xf) | (ssd130x->prechargep2 & 0xf)= << 4; + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, prech= arge); + if (ret < 0) + return ret; + + /* Set COM pins configuration */ + compins =3D 0x02 | !ssd130x->com_seq << 4 | ssd130x->com_lrremap << 5; + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compin= s); + if (ret < 0) + return ret; + + + /* Set VCOMH */ + ret =3D ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh); + if (ret < 0) + return ret; + + /* Turn on the DC-DC Charge Pump */ + chargepump =3D BIT(4) | (ssd130x->device_info->need_chargepump ? BIT(2) := 0); + ret =3D 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 =3D ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE); + if (ret < 0) + return ret; + + for (i =3D 0; i < ARRAY_SIZE(ssd130x->lookup_table); ++i) { + u8 val =3D ssd130x->lookup_table[i]; + + if (val < 31 || val > 63) + dev_warn(ssd130x->dev, + "lookup table index %d value out of range 31 <=3D %d <=3D 63\n", + i, val); + ret =3D 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 =3D rect->x1; + unsigned int y =3D rect->y1; + unsigned int width =3D drm_rect_width(rect); + unsigned int height =3D drm_rect_height(rect); + unsigned int line_length =3D DIV_ROUND_UP(width, 8); + unsigned int pages =3D DIV_ROUND_UP(y % 8 + height, 8); + u32 array_idx =3D 0; + int ret, i, j, k; + u8 *data_array =3D NULL; + + data_array =3D 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 =3D ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); + if (ret < 0) + goto out_free; + + ret =3D ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pag= es); + if (ret < 0) + goto out_free; + + for (i =3D y / 8; i < y / 8 + pages; i++) { + int m =3D 8; + + /* Last page may be partial */ + if (8 * (i + 1) > ssd130x->height) + m =3D ssd130x->height % 8; + for (j =3D x; j < x + width; j++) { + u8 data =3D 0; + + for (k =3D 0; k < m; k++) { + u8 byte =3D buf[(8 * i + k) * line_length + j / 8]; + u8 bit =3D (byte >> (j % 8)) & 1; + + data |=3D bit << k; + } + data_array[array_idx++] =3D data; + } + } + + ret =3D 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 =3D NULL; + + struct drm_rect fullscreen =3D { + .x1 =3D 0, + .x2 =3D ssd130x->width, + .y1 =3D 0, + .y2 =3D ssd130x->height, + }; + + buf =3D 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 d= ma_buf_map *map, + struct drm_rect *rect) +{ + struct ssd130x_device *ssd130x =3D drm_to_ssd130x(fb->dev); + void *vmap =3D map->vaddr; /* TODO: Use mapping abstraction properly */ + int ret =3D 0; + u8 *buf =3D NULL; + + buf =3D 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 =3D drm_to_ssd130x(pipe->crtc.dev); + + if (mode->hdisplay !=3D ssd130x->mode.hdisplay && + mode->vdisplay !=3D ssd130x->mode.vdisplay) + return MODE_ONE_SIZE; + + if (mode->hdisplay !=3D ssd130x->mode.hdisplay) + return MODE_ONE_WIDTH; + + if (mode->vdisplay !=3D ssd130x->mode.vdisplay) + return MODE_ONE_HEIGHT; + + return MODE_OK; +} + +static void ssd130x_display_pipe_enable(struct drm_simple_display_pipe *pi= pe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + struct ssd130x_device *ssd130x =3D drm_to_ssd130x(pipe->crtc.dev); + struct drm_device *drm =3D &ssd130x->drm; + int idx, ret; + + ret =3D ssd130x_power_on(ssd130x); + if (ret) + return; + + ret =3D ssd130x_init(ssd130x); + if (ret) + goto power_off; + + if (!drm_dev_enter(drm, &idx)) + goto power_off; + + ssd130x_clear_screen(ssd130x); + + ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON); + + backlight_enable(ssd130x->bl_dev); + + drm_dev_exit(idx); + + return; +power_off: + ssd130x_power_off(ssd130x); +} + +static void ssd130x_display_pipe_disable(struct drm_simple_display_pipe *p= ipe) +{ + struct ssd130x_device *ssd130x =3D drm_to_ssd130x(pipe->crtc.dev); + struct drm_device *drm =3D &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 *pi= pe, + struct drm_plane_state *old_plane_state) +{ + struct ssd130x_device *ssd130x =3D drm_to_ssd130x(pipe->crtc.dev); + struct drm_plane_state *plane_state =3D pipe->plane.state; + struct drm_shadow_plane_state *shadow_plane_state =3D to_drm_shadow_plane= _state(plane_state); + struct drm_framebuffer *fb =3D plane_state->fb; + struct drm_device *drm =3D &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_c= lip)) + return; + + dst_clip =3D 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 =3D { + .mode_valid =3D ssd130x_display_pipe_mode_valid, + .enable =3D ssd130x_display_pipe_enable, + .disable =3D ssd130x_display_pipe_disable, + .update =3D 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 =3D drm_to_ssd130x(connector->dev); + struct drm_display_mode *mode =3D &ssd130x->mode; + struct device *dev =3D ssd130x->dev; + + mode =3D 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_fu= ncs =3D { + .get_modes =3D ssd130x_connector_get_modes, +}; + +static const struct drm_connector_funcs ssd130x_connector_funcs =3D { + .reset =3D drm_atomic_helper_connector_reset, + .fill_modes =3D drm_helper_probe_single_connector_modes, + .destroy =3D drm_connector_cleanup, + .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_mode_config_funcs ssd130x_mode_config_funcs =3D { + .fb_create =3D drm_gem_fb_create_with_dirty, + .atomic_check =3D drm_atomic_helper_check, + .atomic_commit =3D drm_atomic_helper_commit, +}; + +static const uint32_t ssd130x_formats[] =3D { + DRM_FORMAT_XRGB8888, +}; + +DEFINE_DRM_GEM_FOPS(ssd130x_fops); + +static const struct drm_driver ssd130x_drm_driver =3D { + DRM_GEM_SHMEM_DRIVER_OPS, + .name =3D DRIVER_NAME, + .desc =3D DRIVER_DESC, + .date =3D DRIVER_DATE, + .major =3D DRIVER_MAJOR, + .minor =3D DRIVER_MINOR, + .driver_features =3D DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, + .fops =3D &ssd130x_fops, +}; + +static int ssd130x_update_bl(struct backlight_device *bdev) +{ + struct ssd130x_device *ssd130x =3D bl_get_data(bdev); + int brightness =3D backlight_get_brightness(bdev); + int ret; + + ssd130x->contrast =3D brightness; + + ret =3D ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST); + if (ret < 0) + return ret; + + ret =3D ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast); + if (ret < 0) + return ret; + + return 0; +} + +static const struct backlight_ops ssd130xfb_bl_ops =3D { + .update_status =3D ssd130x_update_bl, +}; + +static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) +{ + struct device *dev =3D ssd130x->dev; + + if (device_property_read_u32(dev, "solomon,width", &ssd130x->width)) + ssd130x->width =3D 96; + + if (device_property_read_u32(dev, "solomon,height", &ssd130x->height)) + ssd130x->height =3D 16; + + if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_o= ffset)) + ssd130x->page_offset =3D 1; + + if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_off= set)) + ssd130x->col_offset =3D 0; + + if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_off= set)) + ssd130x->com_offset =3D 0; + + if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->precha= rgep1)) + ssd130x->prechargep1 =3D 2; + + if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->precha= rgep2)) + ssd130x->prechargep2 =3D 2; + + if (!device_property_read_u8_array(dev, "solomon,lookup-table", + ssd130x->lookup_table, + ARRAY_SIZE(ssd130x->lookup_table))) + ssd130x->lookup_table_set =3D 1; + + ssd130x->seg_remap =3D !device_property_read_bool(dev, "solomon,segment-n= o-remap"); + ssd130x->com_seq =3D device_property_read_bool(dev, "solomon,com-seq"); + ssd130x->com_lrremap =3D device_property_read_bool(dev, "solomon,com-lrre= map"); + ssd130x->com_invdir =3D device_property_read_bool(dev, "solomon,com-invdi= r"); + ssd130x->area_color_enable =3D + device_property_read_bool(dev, "solomon,area-color-enable"); + ssd130x->low_power =3D device_property_read_bool(dev, "solomon,low-power"= ); + + ssd130x->contrast =3D 127; + ssd130x->vcomh =3D ssd130x->device_info->default_vcomh; + + /* Setup display timing */ + if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div)) + ssd130x->dclk_div =3D ssd130x->device_info->default_dclk_div; + if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq)) + ssd130x->dclk_frq =3D ssd130x->device_info->default_dclk_frq; +} + +static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) +{ + struct drm_display_mode *mode =3D &ssd130x->mode; + struct device *dev =3D ssd130x->dev; + struct drm_device *drm =3D &ssd130x->drm; + unsigned long max_width, max_height; + int ret; + + ret =3D drmm_mode_config_init(drm); + if (ret) { + dev_err(dev, "DRM mode config init failed: %d\n", ret); + return ret; + } + + mode->type =3D DRM_MODE_TYPE_DRIVER; + mode->clock =3D 1; + mode->hdisplay =3D mode->htotal =3D ssd130x->width; + mode->hsync_start =3D mode->hsync_end =3D ssd130x->width; + mode->vdisplay =3D mode->vtotal =3D ssd130x->height; + mode->vsync_start =3D mode->vsync_end =3D ssd130x->height; + mode->width_mm =3D 27; + mode->height_mm =3D 27; + + max_width =3D max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_W= IDTH); + max_height =3D max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_= HEIGHT); + + drm->mode_config.min_width =3D mode->hdisplay; + drm->mode_config.max_width =3D max_width; + drm->mode_config.min_height =3D mode->vdisplay; + drm->mode_config.max_height =3D max_height; + drm->mode_config.preferred_depth =3D 32; + drm->mode_config.funcs =3D &ssd130x_mode_config_funcs; + + ret =3D drm_connector_init(drm, &ssd130x->connector, &ssd130x_connector_f= uncs, + 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_f= uncs); + + ret =3D drm_simple_display_pipe_init(drm, &ssd130x->pipe, &ssd130x_pipe_f= uncs, + 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 =3D ssd130x->dev; + int ret; + + ssd130x->reset =3D 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->vbat_reg =3D devm_regulator_get_optional(dev, "vbat"); + if (IS_ERR(ssd130x->vbat_reg)) { + ret =3D PTR_ERR(ssd130x->vbat_reg); + if (ret =3D=3D -ENODEV) + ssd130x->vbat_reg =3D NULL; + else + return dev_err_probe(dev, ret, "Failed to get VBAT regulator\n"); + } + + return 0; +} + +struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *re= gmap) +{ + struct ssd130x_device *ssd130x; + struct backlight_device *bl; + struct drm_device *drm; + int ret; + + ssd130x =3D devm_drm_dev_alloc(dev, &ssd130x_drm_driver, + struct ssd130x_device, drm); + if (IS_ERR(ssd130x)) { + dev_err(dev, "Failed to allocate DRM device: %d\n", ret); + return ssd130x; + } + + drm =3D &ssd130x->drm; + + ssd130x->dev =3D dev; + ssd130x->regmap =3D regmap; + ssd130x->device_info =3D device_get_match_data(dev); + + ssd130x_parse_properties(ssd130x); + + ret =3D ssd130x_get_resources(ssd130x); + if (ret) + return ERR_PTR(ret); + + bl =3D devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x, + &ssd130xfb_bl_ops, NULL); + if (IS_ERR(bl)) { + ret =3D PTR_ERR(bl); + dev_err(dev, "Unable to register backlight device: %d\n", ret); + return ERR_PTR(ret); + } + + bl->props.brightness =3D ssd130x->contrast; + bl->props.max_brightness =3D MAX_CONTRAST; + ssd130x->bl_dev =3D bl; + + ret =3D ssd130x_init_modeset(ssd130x); + if (ret) + return ERR_PTR(ret); + + ret =3D drm_dev_register(drm, 0); + if (ret) { + dev_err(dev, "DRM device register failed: %d\n", ret); + return ERR_PTR(ret); + } + + 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/ss= d130x.h new file mode 100644 index 000000000000..bc760fdf0dfe --- /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. + * Authors: 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 *vbat_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 *re= gmap); +int ssd130x_remove(struct ssd130x_device *ssd130x); +void ssd130x_shutdown(struct ssd130x_device *ssd130x); + +#endif /* __SSD1307X_H__ */ --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3997CC433EF for ; Wed, 9 Feb 2022 09:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234393AbiBIJik (ORCPT ); Wed, 9 Feb 2022 04:38:40 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:40892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237500AbiBIJcM (ORCPT ); Wed, 9 Feb 2022 04:32:12 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 47780E056589 for ; Wed, 9 Feb 2022 01:32:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399072; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uXHl6zWfNshnr52NE5ioPZcgRmeozRVAlTsdeYXbxCY=; b=AMIUJZZkK96AMsYFDDz4armYSNDV4QSJ1EysebTNFZ9qbPCMwrjw+BK0Q60pi+yjRfO85u j1X7Ut2C7uhnFlmIy6vUfbAZ0BkHNg5CF7MSPOs+5I2ghiCxmkwVGbHZIEIwoufJ4NgGck Caoz93xdGd5DksHb8etNZKQuoe0I/9w= 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-652-gqk7bWj8NmORQvsIyzQ31w-1; Wed, 09 Feb 2022 04:03:33 -0500 X-MC-Unique: gqk7bWj8NmORQvsIyzQ31w-1 Received: by mail-wm1-f71.google.com with SMTP id j39-20020a05600c1c2700b0037becd18addso222981wms.4 for ; Wed, 09 Feb 2022 01:03:33 -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=uXHl6zWfNshnr52NE5ioPZcgRmeozRVAlTsdeYXbxCY=; b=Uqhm6Awfhe8uSoHDI1Ma0i/enTNS6TZqDUWURwlOrnsxnuZOuHu9VT1jyawu3iPRSi sjlSmHJruPWGg9CAQq58wrNUKrKuUrCAWer6xeN8IFj0dXUi8GKwOONilgC9gbBg3w5s 984/mhs09hYN50Pv22wU8Q73jJQitjRJPoPMey0ZiBNaYTTR9gC0hQxaAg+1acu9FHwA fSmSo9P1hn51oNyVBl7uc46xAyCdnXkkPYdOFCz0b07F26fC8gyxoNvA+FY/otQryY17 /fRF7ZDJmxTvmE/Gq8RIew1UyNjYv3RipovTCjvt8z/S6Ws4weroynGaxCMg6zZGJazm X1gg== X-Gm-Message-State: AOAM532x3t1yzYNdow1hZf09uUY8LOz9B3ciQDj/OGfM5xtsekexF1nu M79QU3SUr5ujvV0exLCiVKPGmBBLwiqyav9gsaN32Zu+NnnbjD0djE9+a51jCBEOT1yvQp5DyPF Q84OlhjtCUYjNhMtPXLp8iYVQbNLVYTxTTlRYr5jgENgSFF/Ti/7y4x29ZVGJLfMUfvZx9AZ0Vj Q= X-Received: by 2002:a05:600c:2251:: with SMTP id a17mr1662586wmm.166.1644397411453; Wed, 09 Feb 2022 01:03:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJxT7Pib7rdcqP+VtxNfxLQQztTdcyWavTVBGg58Xcbl17d1EFyRBBvpQE+HBcC8rsWkQwEpBw== X-Received: by 2002:a05:600c:2251:: with SMTP id a17mr1662550wmm.166.1644397411097; Wed, 09 Feb 2022 01:03:31 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id z1sm4058866wmk.32.2022.02.09.01.03.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:03:30 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Thomas Zimmermann , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , Maxime Ripard , Geert Uytterhoeven , linux-fbdev@vger.kernel.org, Daniel Vetter , Sam Ravnborg , dri-devel@lists.freedesktop.org, Javier Martinez Canillas , Daniel Vetter , David Airlie Subject: [PATCH v3 4/7] drm/solomon: Add SSD130X OLED displays I2C support Date: Wed, 9 Feb 2022 10:03:11 +0100 Message-Id: <20220209090314.2511959-5-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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 | 117 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 drivers/gpu/drm/solomon/ssd130x-i2c.c diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kcon= fig index c969c358a4a7..47e16bc20e0d 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. =20 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/Mak= efile index f685addb19fe..4bfc5acb0447 100644 --- a/drivers/gpu/drm/solomon/Makefile +++ b/drivers/gpu/drm/solomon/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_DRM_SSD130X) +=3D ssd130x.o +obj-$(CONFIG_DRM_SSD130X_I2C) +=3D ssd130x-i2c.o diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomo= n/ssd130x-i2c.c new file mode 100644 index 000000000000..ff5f8992b2ff --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130X OLED displays (I2C bus) + * + * Copyright 2022 Red Hat Inc. + * Authors: 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 =3D { + .reg_bits =3D 8, + .val_bits =3D 8, +}; + +static int ssd130x_i2c_probe(struct i2c_client *client) +{ + struct ssd130x_device *ssd130x; + struct regmap *regmap; + + regmap =3D devm_regmap_init_i2c(client, &ssd130x_i2c_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ssd130x =3D 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 =3D i2c_get_clientdata(client); + + return ssd130x_remove(ssd130x); +} + +static void ssd130x_i2c_shutdown(struct i2c_client *client) +{ + struct ssd130x_device *ssd130x =3D i2c_get_clientdata(client); + + ssd130x_shutdown(ssd130x); +} + +static struct ssd130x_deviceinfo ssd130x_ssd1305_deviceinfo =3D { + .default_vcomh =3D 0x34, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 7, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1306_deviceinfo =3D { + .default_vcomh =3D 0x20, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 8, + .need_chargepump =3D 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1307_deviceinfo =3D { + .default_vcomh =3D 0x20, + .default_dclk_div =3D 2, + .default_dclk_frq =3D 12, + .need_pwm =3D 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1309_deviceinfo =3D { + .default_vcomh =3D 0x34, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 10, +}; + +static const struct of_device_id ssd130x_of_match[] =3D { + { + .compatible =3D "solomon,ssd1305fb-i2c", + .data =3D (void *)&ssd130x_ssd1305_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1306fb-i2c", + .data =3D (void *)&ssd130x_ssd1306_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1307fb-i2c", + .data =3D (void *)&ssd130x_ssd1307_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1309fb-i2c", + .data =3D (void *)&ssd130x_ssd1309_deviceinfo, + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ssd130x_of_match); + +static struct i2c_driver ssd130x_i2c_driver =3D { + .driver =3D { + .name =3D DRIVER_NAME, + .of_match_table =3D ssd130x_of_match, + }, + .probe_new =3D ssd130x_i2c_probe, + .remove =3D ssd130x_i2c_remove, + .shutdown =3D ssd130x_i2c_shutdown, +}; +module_i2c_driver(ssd130x_i2c_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Javier Martinez Canillas "); +MODULE_LICENSE("GPL v2"); --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03975C4167E for ; Wed, 9 Feb 2022 09:41:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239583AbiBIJlE (ORCPT ); Wed, 9 Feb 2022 04:41:04 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:36172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240050AbiBIJhs (ORCPT ); Wed, 9 Feb 2022 04:37:48 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0C020E061E55 for ; Wed, 9 Feb 2022 01:37:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399426; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IVaOePIAiXFw8U75tAHDUKWkv70g1B3730fSEy8H3OQ=; b=R+z3d5sDCkwHxdajQw+n9V4AQmWf6u+QhFA5jLTRilTiYwalzZLdMaJNdRmfbqkHe43njD 2TUPm0UBNdAERuysN66r/Y6qE5Jsi7S5xBCmNRo2Y2tF6KJYgdbnyLRU8lxsq6NEmoGYbx EwWvLQLN0QJmrW/JImBJbzD+ntG/4Rg= 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-325-kKIjC3YcM1us5W9RYokvmg-1; Wed, 09 Feb 2022 04:12:24 -0500 X-MC-Unique: kKIjC3YcM1us5W9RYokvmg-1 Received: by mail-wr1-f70.google.com with SMTP id b8-20020adfc748000000b001e333edbe40so851098wrh.6 for ; Wed, 09 Feb 2022 01:12:24 -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=IVaOePIAiXFw8U75tAHDUKWkv70g1B3730fSEy8H3OQ=; b=X5++nWcnAbgmOQYwlp2RVshBBjgAs8AVxJeSsKXAVcDpPwsySelzp0YJLNOztYlZET wJRagoJUAIcXl09E3oxZ7mctpTnLiRihrrfdOhYKYiG/C14qfFbz0ZB4C7e3RbKVCWD0 oWQbSEpZsd1X6z4ZHpPRvvSyTDuHy3hx5Pul31alOy2tUsvgmBReti4Tlj62MQ3Fmpue K2s/Nr0Ie7pBzFsyH6GWWpxypKRad2FW1y/GobRyBnJaF2T3CYa95lLu4ltHCK6zDR7N vuFE/lloAS+fYFJeMQo53tfFFKAKIyE/oer37yRMhyDCdlq+o/HDtpi7rOHMO1b7rJcP z4qw== X-Gm-Message-State: AOAM530t0qKDIta8XgdWqWniet5hxneyfayQte4b0HMAapIOyTYCIDxz mSDOqmZVWORfz1rd6/Q9jsknGSDs9fNn0F2nzCCNfLxkP2wPMAULLvUiBlGALI9Y8KqD2SJ3gD9 uUBBLzA/yu7b34HKBtDjZZ6O9gXxxPrOkiWBMcz88CfB+2GkXVQbDouY8hq2uZa80cqIJjLrUFB 0= X-Received: by 2002:a05:600c:3b97:: with SMTP id n23mr116359wms.116.1644397943155; Wed, 09 Feb 2022 01:12:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJxmy9te2m+nFf5NChLb1Oyfbsc9hQqFDn/UG2mRdylATQQhkHE0nZ3daEy/SuR9+qJRmFJzGg== X-Received: by 2002:a05:600c:3b97:: with SMTP id n23mr116329wms.116.1644397942870; Wed, 09 Feb 2022 01:12:22 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id m30sm4588068wms.34.2022.02.09.01.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:12:22 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Daniel Vetter , Geert Uytterhoeven , Maxime Ripard , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, Javier Martinez Canillas Subject: [PATCH v3 5/7] (WIP) drm/solomon: Add SSD130X OLED displays SPI support Date: Wed, 9 Feb 2022 10:12:04 +0100 Message-Id: <20220209091204.2513437-1-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 SPI. Signed-off-by: Javier Martinez Canillas --- Changes in v3: - Add a separate driver for SSD130X chips SPI support (Andy Shevchenko) drivers/gpu/drm/solomon/Kconfig | 9 ++ drivers/gpu/drm/solomon/Makefile | 1 + drivers/gpu/drm/solomon/ssd130x-spi.c | 114 ++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 drivers/gpu/drm/solomon/ssd130x-spi.c diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kcon= fig index 47e16bc20e0d..16a2098f438c 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -19,3 +19,12 @@ config DRM_SSD130X_I2C Say Y here if the SSD130X OLED display is connected via I2C bus. =20 If M is selected the module will be called ssd130x-i2c. + +config DRM_SSD130X_SPI + tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)" + depends on DRM_SSD130X && SPI + select REGMAP_SPI + help + Say Y here if the SSD130X OLED display is connected via SPI bus. + + If M is selected the module will be called ssd130x-spi. diff --git a/drivers/gpu/drm/solomon/Makefile b/drivers/gpu/drm/solomon/Mak= efile index 4bfc5acb0447..b5fc792257d7 100644 --- a/drivers/gpu/drm/solomon/Makefile +++ b/drivers/gpu/drm/solomon/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_DRM_SSD130X) +=3D ssd130x.o obj-$(CONFIG_DRM_SSD130X_I2C) +=3D ssd130x-i2c.o +obj-$(CONFIG_DRM_SSD130X_SPI) +=3D ssd130x-spi.o diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomo= n/ssd130x-spi.c new file mode 100644 index 000000000000..ccc56d2f3026 --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130X OLED displays (SPI bus) + * + * Copyright 2022 Red Hat Inc. + * Authors: Javier Martinez Canillas + */ +#include +#include + +#include "ssd130x.h" + +#define DRIVER_NAME "ssd130x-spi" +#define DRIVER_DESC "DRM driver for Solomon SSD130X OLED displays (SPI)" + +static const struct regmap_config ssd130x_spi_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, +}; + +static int ssd130x_spi_probe(struct spi_device *spi) +{ + struct ssd130x_device *ssd130x; + struct regmap *regmap; + + regmap =3D devm_regmap_init_spi(spi, &ssd130x_spi_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ssd130x =3D ssd130x_probe(&spi->dev, regmap); + + if (IS_ERR(ssd130x)) + return PTR_ERR(ssd130x); + + spi_set_drvdata(spi, ssd130x); + + return 0; +} + +static int ssd130x_spi_remove(struct spi_device *spi) +{ + struct ssd130x_device *ssd130x =3D spi_get_drvdata(spi); + + return ssd130x_remove(ssd130x); +} + +static void ssd130x_spi_shutdown(struct spi_device *spi) +{ + struct ssd130x_device *ssd130x =3D spi_get_drvdata(spi); + + ssd130x_shutdown(ssd130x); +} + +static struct ssd130x_deviceinfo ssd130x_ssd1305_deviceinfo =3D { + .default_vcomh =3D 0x34, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 7, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1306_deviceinfo =3D { + .default_vcomh =3D 0x20, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 8, + .need_chargepump =3D 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1307_deviceinfo =3D { + .default_vcomh =3D 0x20, + .default_dclk_div =3D 2, + .default_dclk_frq =3D 12, + .need_pwm =3D 1, +}; + +static struct ssd130x_deviceinfo ssd130x_ssd1309_deviceinfo =3D { + .default_vcomh =3D 0x34, + .default_dclk_div =3D 1, + .default_dclk_frq =3D 10, +}; + +static const struct of_device_id ssd130x_of_match[] =3D { + { + .compatible =3D "solomon,ssd1305fb-spi", + .data =3D (void *)&ssd130x_ssd1305_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1306fb-spi", + .data =3D (void *)&ssd130x_ssd1306_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1307fb-spi", + .data =3D (void *)&ssd130x_ssd1307_deviceinfo, + }, + { + .compatible =3D "solomon,ssd1309fb-spi", + .data =3D (void *)&ssd130x_ssd1309_deviceinfo, + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ssd130x_of_match); + +static struct spi_driver ssd130x_spi_driver =3D { + .driver =3D { + .name =3D DRIVER_NAME, + .of_match_table =3D ssd130x_of_match, + }, + .probe =3D ssd130x_spi_probe, + .remove =3D ssd130x_spi_remove, + .shutdown =3D ssd130x_spi_shutdown, +}; +module_spi_driver(ssd130x_spi_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Javier Martinez Canillas "); +MODULE_LICENSE("GPL v2"); --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52BFAC433F5 for ; Wed, 9 Feb 2022 09:41:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236396AbiBIJjd (ORCPT ); Wed, 9 Feb 2022 04:39:33 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:57816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234515AbiBIJgO (ORCPT ); Wed, 9 Feb 2022 04:36:14 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 136E3E01093B for ; Wed, 9 Feb 2022 01:36:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wrfi96tJIccNwtHX6q8UuWpfNu6nXOBFJNAE84+M6EA=; b=NXYCUyrllwnceB+AqA6ul4AvQbz1UcNL/Lq0aq6qyn1F8r8uOGZoeF9dIDhtZPmI0fDn+N 5uyEDejEbENLCbfQPmrF9Drc1AmM9zsmJyaRQKp4UNaUzsidx98ZBqObIAuXRM6Rm1zWew Ag3tAR41nB1TpnV7CG7Hbvt9BSIQA8M= 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-2-h0x2qF6PNvGRMTqw_ZM_zQ-1; Wed, 09 Feb 2022 04:13:19 -0500 X-MC-Unique: h0x2qF6PNvGRMTqw_ZM_zQ-1 Received: by mail-wr1-f69.google.com with SMTP id v9-20020adfa1c9000000b001e33e5dbd5fso839382wrv.17 for ; Wed, 09 Feb 2022 01:13:19 -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=wrfi96tJIccNwtHX6q8UuWpfNu6nXOBFJNAE84+M6EA=; b=SiMtshxSWq2CTSBS5O9H+az8VzNr7WEiGp6i1PP9B6oygMycXohYydi2SwcGa+yzXX J1411Fp/yPIR8FrwSa9NAnz1SK/ElKy8QvcWyrGRARE4QTPJ2qv961CJ4t1XeS+rLxAv lKgL6bC8X9MeSZID6nKENEITv2MB1CrgAVufOGoCTQq/jBdrZIWRgOs/6VjiydGF3LXo ts5+vxeQw4et8vCkV4Tbm/H/gxGcHV2b6KaJW6t51ohpwewMI4Euv1p0jeaeWUhDNQpZ we7LYNz/Gg4sHeaKxDs1rJIvhOyKQbiRVWWWeGSuP8X4T3OrDT5qMTAFTh17b+RoEh7E grPQ== X-Gm-Message-State: AOAM531limZ6QLEyoO1nNPfz05gLiRI3PndTtmQepGku83B2kWr6KYRD VI7WY/5+LUnu5ND3rbeFls3mjHdlPmZRR9H0UW/4W5d8/ARhIYqVeoKkLY3FHN8v203D/pXGT59 qeJRUgE09p03PH6ecRyhIirWKfKkFrGcKSnm3uBqeKr+YmKsJL5L+hPjY4YEAFq8EY6WOrNaLA7 Y= X-Received: by 2002:a5d:52c9:: with SMTP id r9mr1258313wrv.449.1644397998241; Wed, 09 Feb 2022 01:13:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJy1zTRH9HjYG3ft4LFcDrPluM5RwDLJLwWrjz45XS9D+PYh5QbVpYPQLAEhlqGKHQNAri0OMg== X-Received: by 2002:a5d:52c9:: with SMTP id r9mr1258299wrv.449.1644397998026; Wed, 09 Feb 2022 01:13:18 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id v18sm11942013wrm.105.2022.02.09.01.13.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:13:17 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Daniel Vetter , Geert Uytterhoeven , Maxime Ripard , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, Javier Martinez Canillas , Sam Ravnborg Subject: [PATCH v3 6/7] MAINTAINERS: Add entry for Solomon SSD130X OLED displays DRM driver Date: Wed, 9 Feb 2022 10:13:12 +0100 Message-Id: <20220209091312.2513575-1-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- Changes in v3: - Adapt MAINTAINERS entry to point to the new drivers/gpu/drm/solomon direc= tory. Changes in v2: - Add Sam Ravnborg's acked-by to patch adding a MAINTAINERS entry (Sam Ravn= borg) MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e3dad0d898f5..8e6e892f99f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6163,6 +6163,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/repaper.txt F: drivers/gpu/drm/tiny/repaper.c =20 +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 --=20 2.34.1 From nobody Sun Jun 28 09:38:45 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A1DDC433F5 for ; Wed, 9 Feb 2022 09:44:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231578AbiBIJoP (ORCPT ); Wed, 9 Feb 2022 04:44:15 -0500 Received: from gmail-smtp-in.l.google.com ([23.128.96.19]:33446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229972AbiBIJoO (ORCPT ); Wed, 9 Feb 2022 04:44:14 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 24F9DE06A602 for ; Wed, 9 Feb 2022 01:44:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644399609; 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=HkjkJCV3RnHyv5DSE+jtNb73ClQ4fv7HXl/dV01kYKA=; b=bC/4gKYS6sT2hAWsps87ucYKPUMCaEA72CXkrCkX2Qj2hBk8sV/FCDNUlt1TcipAZwaPcX jGHEWGTTmflXCnZjb8YTMSCFRm8u7zHCuQocXiblRdNOOSOdOokHjPYtl0yR52qrUxDNFs yxrvUdt+X59TykT4isw5+4zklhmIJ4I= 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-357-kOzwFI8MOgOsnHzbSMiIzA-1; Wed, 09 Feb 2022 04:13:57 -0500 X-MC-Unique: kOzwFI8MOgOsnHzbSMiIzA-1 Received: by mail-wr1-f70.google.com with SMTP id c9-20020adfa709000000b001dde29c3202so833707wrd.22 for ; Wed, 09 Feb 2022 01:13:56 -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=HkjkJCV3RnHyv5DSE+jtNb73ClQ4fv7HXl/dV01kYKA=; b=x2DGWRCAjoHIIL4yqazupyep0VVbFI+cAfGjHkT+JE9fJGT69EZZbFO4xD8T9382Wo d7j2jL39X5nqUhhyjvQhURpsqP088gWIDcOHejtYg4EAnbgvHVGENrOwW3D0V9ZQHyV4 ulFW58wwVIZl8AeQRSe4SZfccL6tpsiyjew0CcBHhTREx26KZvFOsD6KY7VktWtn0R4B UrQchgExomcZ18U8HPgt4ujrmkN2Ni/a4dm25U8BPcDTNqI4QMcVqztsjeeuPT8BIn4z 5JUJdhw8YDTouHqRRVSx2bFbyxRGVQgmTbFHSkBgAodsK0Y7jIkaQKhwVoUopEdJSoSz RgDg== X-Gm-Message-State: AOAM530HKj5VkEyOWXrQ1dWn55ypr0wlDTO3aIxspAdxEhBo7cXTxXgf bbt2C33w4HMDLAOivRHmi/soJAv0HvNICUjPEYY7C3uLqU482jnJtktgjObjDCOj7UMfehtRH7m WytjV6q4x+8aSAYRydXqol4Lf8tX7mDxzn351JvhMP/tjqHuveekAyeFbwMR5aOaGI8ozReZ2Pd Q= X-Received: by 2002:a5d:53c9:: with SMTP id a9mr1221614wrw.672.1644398035804; Wed, 09 Feb 2022 01:13:55 -0800 (PST) X-Google-Smtp-Source: ABdhPJwN9IG1QALjH1ZUKqnf6ckKETjeoTD+yjoTXUPxM8Hq+sCkIBChwrk3c3nzhT8/h+bVv4FVsQ== X-Received: by 2002:a5d:53c9:: with SMTP id a9mr1221588wrw.672.1644398035459; Wed, 09 Feb 2022 01:13:55 -0800 (PST) Received: from minerva.home ([92.176.231.205]) by smtp.gmail.com with ESMTPSA id w6sm13557623wrp.51.2022.02.09.01.13.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 01:13:55 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Andy Shevchenko , Daniel Vetter , Geert Uytterhoeven , Maxime Ripard , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, Javier Martinez Canillas , Sam Ravnborg Subject: [PATCH v3 7/7] dt-bindings: display: ssd1307fb: Add myself as binding co-maintainer Date: Wed, 9 Feb 2022 10:13:44 +0100 Message-Id: <20220209091344.2513662-1-javierm@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220209090314.2511959-1-javierm@redhat.com> References: <20220209090314.2511959-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- (no changes since v2) 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.ya= ml 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 =20 maintainers: - Maxime Ripard + - Javier Martinez Canillas =20 properties: compatible: --=20 2.34.1