From patchwork Sat Feb 19 13:15:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752297 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 C6B02C433F5 for ; Sat, 19 Feb 2022 13:21:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231447AbiBSNVy (ORCPT ); Sat, 19 Feb 2022 08:21:54 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:37968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229685AbiBSNVx (ORCPT ); Sat, 19 Feb 2022 08:21:53 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9767B1005; Sat, 19 Feb 2022 05:21:32 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id m3so14225470eda.10; Sat, 19 Feb 2022 05:21:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=RjPMctKZVhoEtXai563y+o3AHHthI9KS32P039dLMfk=; b=p5g7EqTNRVEGJHBm+irbcgUZNOH9MJijO1bkbt1rfpzfDq9RUEvYTxpQcSK/PZ+BPs VzbLF20uY5UmkO67j5Ne01IDs1HjTAZNygX5DC7kj57Ky4mqKpP0LJKOKAXDIJjvmy+q AC+m2FV/7kgtLiII/lamTyYIuHGSfsttmztZrGfYyG+0uqaqBjQUiRQYJJ62hM+/d9hN hO15Vtqw9L9heD36fmqYalqodZQY7nyWlxmF64AUIgeqhhZGngy0pNYSLwWgyS/dfk5Y +mx+aDqFSsEpxndlXnW9ehLWWBJc5zsLV9DoPvS34jEHHUiTaa0/0u4/9M0IsHL4BSEt mSeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=RjPMctKZVhoEtXai563y+o3AHHthI9KS32P039dLMfk=; b=JKbaJVs0GZRjaFW8nDM5ovnoi1gErypRVuI8ZhmWySaZKfjgU3KDKBMBnaSYK2iRpr aAUfrtapshJLa3oBCLsa+wkGK6CmqwBCYPct4YJXPSLNXquwNY0brACEqlt7KGG27XRp cktl+kaUltXePpJXLk50cIx7KdFW876/UrEdrBJTmjOMg1cV69vtw7MNGWVT2Ze/Fk4W J2PLhyiSuGjy3We85almvFMuutxCwdMgTTbSw4Yf0BpwsAvukGjnqzv/mBQCquPsokQu wahErrdt1G0PyZ380eCPOG06eAEIr+oCJlc/aWfqxzIuCQM4by8GwKUBRL0E74K+FT9n TtcQ== X-Gm-Message-State: AOAM530DUd6KtXgHzzZHShhCteIo62B+7Zoo/skUU57Lpt4sr5k0jib9 q5cmzckZ2fC8Eh4I6XiW7XM= X-Google-Smtp-Source: ABdhPJy28n6lGEbuHefJ/j2tXDefEJrO4AuySKKkPDOs7GpEnD5En7td3ozqZSJw/cLIAucF12KaPg== X-Received: by 2002:aa7:df1a:0:b0:409:5174:68a9 with SMTP id c26-20020aa7df1a000000b00409517468a9mr13048317edy.145.1645276890948; Sat, 19 Feb 2022 05:21:30 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id eq19sm5538204edb.36.2022.02.19.05.21.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:30 -0800 (PST) Message-ID: Date: Sat, 19 Feb 2022 14:15:48 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 1/6] spi: gpio: Implement LSB First bitbang support Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org From: Andreas Färber Add support for slave DT property spi-lsb-first, i.e., SPI_LSB_FIRST mode. Duplicate the inline helpers bitbang_txrx_be_cpha{0,1} as LE versions. Conditionally call them from all the spi-gpio txrx_word callbacks. Some alternatives to this implementation approach were discussed back then [0], but eventually it was considered reasonable. [0] https://lore.kernel.org/linux-arm-kernel/20191212033952.5967-8-afaerber@suse.de/ Signed-off-by: Andreas Färber Signed-off-by: Heiner Kallweit --- drivers/spi/spi-bitbang-txrx.h | 66 ++++++++++++++++++++++++++++++++++ drivers/spi/spi-gpio.c | 42 +++++++++++++++++----- 2 files changed, 99 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-bitbang-txrx.h b/drivers/spi/spi-bitbang-txrx.h index ae61d72c7..267342dfa 100644 --- a/drivers/spi/spi-bitbang-txrx.h +++ b/drivers/spi/spi-bitbang-txrx.h @@ -41,6 +41,8 @@ * chips need ... there may be several reasons you'd need to tweak timings * in these routines, not just to make it faster or slower to match a * particular CPU clock rate. + * + * ToDo: Maybe the bitrev macros can be used to improve the code? */ static inline u32 @@ -106,3 +108,67 @@ bitbang_txrx_be_cpha1(struct spi_device *spi, } return word; } + +static inline u32 +bitbang_txrx_le_cpha0(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on trailing edge */ + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on leading edge */ + word >>= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi) << (bits - 1); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_le_cpha1(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on trailing edge */ + word >>= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi) << (bits - 1); + } + return word; +} diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0584f4d2f..4b12c4964 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -135,25 +135,37 @@ static inline int getmiso(const struct spi_device *spi) static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { - return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); } static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { - return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); } static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { - return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); } static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { - return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); } /* @@ -170,28 +182,40 @@ static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { flags = spi->master->flags; - return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); } static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { flags = spi->master->flags; - return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); } static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { flags = spi->master->flags; - return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha0(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); } static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, unsigned flags) { flags = spi->master->flags; - return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); + if (unlikely(spi->mode & SPI_LSB_FIRST)) + return bitbang_txrx_le_cpha1(spi, nsecs, 1, flags, word, bits); + else + return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); } /*----------------------------------------------------------------------*/ @@ -378,7 +402,7 @@ static int spi_gpio_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL | - SPI_CS_HIGH; + SPI_CS_HIGH | SPI_LSB_FIRST; if (!spi_gpio->mosi) { /* HW configuration without MOSI pin * From patchwork Sat Feb 19 13:16:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752298 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 1F000C4332F for ; Sat, 19 Feb 2022 13:21:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229685AbiBSNVy (ORCPT ); Sat, 19 Feb 2022 08:21:54 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:37984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230342AbiBSNVx (ORCPT ); Sat, 19 Feb 2022 08:21:53 -0500 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CAA57BD6; Sat, 19 Feb 2022 05:21:33 -0800 (PST) Received: by mail-ej1-x632.google.com with SMTP id a8so21496662ejc.8; Sat, 19 Feb 2022 05:21:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=fvuoOelNYUnuMw3RclEAhuWky9HY1ItIURN9LiLCtBE=; b=A9baqpgIaLoiyIClgnlI8nQkXVzJwoe0eugY7NROFOJ6j8QraPv2HwSPS/Z323hdck KavmMKJuF6uLw59HQ9kMEyaEGryARBpJXKIW3mu6/G75KoOVw6U2NG1dH5toDfhnxFLA pF4h1GyD+88QxRW2+8oyG3rShvVYC3jdoSB73HcZ6iHRjFm54hRrQtAxveTXRkqWKmFc NUgFVy2HEZV8iRguDefeh0sj97PKbvK2KnxCjyAM2qE9qW1zUayw9Vyl31M/01U/iWPh TrkVZvfxCoygGUKgzysP3PA+x97+LTYB492XeYz5DTFWjw5F2w66DpFVa93gOtHxeDAw kK6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=fvuoOelNYUnuMw3RclEAhuWky9HY1ItIURN9LiLCtBE=; b=4Kk/q2UMpdlsD3/ZUewWU20bXCmtu2KQfjitb2JYK7/6duI5AJJES0R3iAPp13AWTs G3jwryQEdfw9zZLIX/GOIliUcZMuW9pIEZtj4Csc/QMxl6N7GwxFHaQa/FUM8wjKLXHM DzlDKy8ngQZEPbu83hqV/zSlkkO26E8k91RB7ek6+mplQuGmVHC/k2iHQ98JPY75GlxN j/0syTWzOj4AdFTduR7FDzOBZEVv4lSnOYQB/YjwyZSSUzTDssDPgC4Nk/shCfR5Oh/z kGPsA7FitXka4KRzCTrjA1ryrPA4APup9tRu64monE+DwN4MNvB9e5XZCcB7Bd7EGyiy dHOw== X-Gm-Message-State: AOAM5308XI95BX95/I/2gl5lOp+OAMDangR3oiUlov+hhtfNFMSSlkDs q2jU5hQIAqPVvIs6zJKCuL4= X-Google-Smtp-Source: ABdhPJzqpPkqjcbqzzs0Iy+XWNBKleezaBJfKQY7AcpRwS61+T49RYqYpFuYKzO7oARcEK8qWX0Sjg== X-Received: by 2002:a17:906:ad90:b0:6cf:74f1:a34 with SMTP id la16-20020a170906ad9000b006cf74f10a34mr9780970ejb.175.1645276892319; Sat, 19 Feb 2022 05:21:32 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id o21sm1302818ejh.114.2022.02.19.05.21.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:31 -0800 (PST) Message-ID: Date: Sat, 19 Feb 2022 14:16:50 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 2/6] dt-bindings: vendor-prefixes: Add Titan Micro Electronics Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org From: Andreas Färber Assign vendor prefix "titanmec", matching their domain name. Acked-by: Rob Herring Signed-off-by: Andreas Färber Signed-off-by: Heiner Kallweit --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index ebe294516..38bfb462c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1229,6 +1229,8 @@ patternProperties: description: Texas Instruments "^tianma,.*": description: Tianma Micro-electronics Co., Ltd. + "^titanmec,.*": + description: Shenzhen Titan Micro Electronics Co., Ltd. "^tlm,.*": description: Trusted Logic Mobility "^tmt,.*": From patchwork Sat Feb 19 13:17:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752300 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 35845C43217 for ; Sat, 19 Feb 2022 13:21:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234755AbiBSNV5 (ORCPT ); Sat, 19 Feb 2022 08:21:57 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:38122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233128AbiBSNVz (ORCPT ); Sat, 19 Feb 2022 08:21:55 -0500 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F663100A; Sat, 19 Feb 2022 05:21:35 -0800 (PST) Received: by mail-ed1-x533.google.com with SMTP id m3so14225626eda.10; Sat, 19 Feb 2022 05:21:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=fpauG+TRD67lEqkFOUl8ovsHrrNt32JAGPgb9gRTuM8=; b=I/9sZ1OlbKLvWG4qtIMulQQCHX0woCYxCWVD+KGU+EVfwIa6zMU8zx4F83avXtbBQ6 f01FSr/FPuSp8Ipyy5Y+HkHOmsiS4V0DLXhC8YHCBWPvze4MnUs5QoaOpJjKf7FI+o1S Vuin6ENVt8OBCEfS0OQpSqoG16g58qzQImmEjAzAqWlz0KGAcwz703LG32JhWzWmbrYp d4oXy4FGqOBwOp3yMy4iNHlBk1H4sZ5SvMphtk/XCFCyejKkZVUv/mx5YyYcgo3xCngL 79z+yRe8gujGZYFXO3uvDaHkREF9m6nxdi3H8ksBjYYU9BZVRS4EjetYRwsdjy5VCtzn 108w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=fpauG+TRD67lEqkFOUl8ovsHrrNt32JAGPgb9gRTuM8=; b=fqmeL5n4lRlgzMEkX3ytWvZbp4eI7DvJxQmdP56Mn9hcKC5zoog5EzWzUmkbvCyMP/ 2xYYclTWVkxVPisNIeJJO2HJEIVNGOTerFYBJi2JK5xqjTrxbO8oCoJ2/ltkl2pa4uzd vFRg4L9x5KE7ImsWH7ekjx2qJZ8wy9iNL7edjslOCxkAQ8akNxwdos6pQOzptokkpPBY kGerE2DrsTacDJBvTGbSQCwOiPUuow9zqlcwTXojfogGxmhz4lY4RCY0ghD6vL+X4vJf Xm68j4PuD+rM/MBuqBL6I2r/ytvo073V4tR1Qt4VSPG0R0K9tY20oxcN8ln8fB+pKLuK //jg== X-Gm-Message-State: AOAM531HylMc4P5M/Unldu31+9esJ4QXeWUmgYWQtwM8t+WVoCMIAjBS CP1G6sbuX9u6lKPThsJhuNg= X-Google-Smtp-Source: ABdhPJyMdwhFMviXX9vaz5IRwMK3brlTzx8iFzc1fr7HKR2rhSXRpPUyZaN8i6BBGVmPmevkmF7BpA== X-Received: by 2002:a50:8713:0:b0:410:db7a:4b2a with SMTP id i19-20020a508713000000b00410db7a4b2amr12665564edb.140.1645276893863; Sat, 19 Feb 2022 05:21:33 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id y23sm3287387ejk.153.2022.02.19.05.21.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:33 -0800 (PST) Message-ID: Date: Sat, 19 Feb 2022 14:17:54 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 3/6] dt-bindings: auxdisplay: Add Titan Micro Electronics TM1628 Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Add a YAML schema binding for TM1628 auxdisplay (7/11-segment LED) controller. This patch is partially based on previous RFC work from Andreas Färber . Signed-off-by: Heiner Kallweit --- .../bindings/auxdisplay/titanmec,tm1628.yaml | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml diff --git a/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml new file mode 100644 index 000000000..d9cbbc950 --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/titanmec,tm1628.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Titan Micro Electronics TM1628 LED controller + +properties: + compatible: + enum: + - titanmec,tm1628 + + reg: + maxItems: 1 + + grid: + description: + Mapping of display digit position to grid number. + This implicitly defines the display size. + $ref: /schemas/types.yaml#/definitions/uint8-array + minItems: 1 + maxItems: 7 + + segment-mapping: + description: + Mapping of 7 segment display segments A-G to bit numbers 1-12. + $ref: /schemas/types.yaml#/definitions/uint8-array + minItems: 7 + maxItems: 7 + + "#address-cells": + const: 2 + + "#size-cells": + const: 0 + +required: + - compatible + - reg + +patternProperties: + "^.*@[1-7],([1-9]|1[0-6])$": + type: object + description: | + Properties for a single LED. + + properties: + reg: + description: | + 1-based grid number, followed by 1-based segment bit number. + maxItems: 1 + + required: + - reg + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@0 { + compatible = "titanmec,tm1628"; + reg = <0>; + spi-3-wire; + spi-lsb-first; + spi-max-frequency = <500000>; + grid = /bits/ 8 <4 3 2 1>; + segment-mapping = /bits/ 8 <4 5 6 1 2 3 7>; + #address-cells = <2>; + #size-cells = <0>; + + alarmn@5,4 { + reg = <5 4>; + function = LED_FUNCTION_ALARM; + }; + }; + }; +... From patchwork Sat Feb 19 13:18:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752299 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 22947C4321E for ; Sat, 19 Feb 2022 13:21:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234098AbiBSNV4 (ORCPT ); Sat, 19 Feb 2022 08:21:56 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:38124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230342AbiBSNVz (ORCPT ); Sat, 19 Feb 2022 08:21:55 -0500 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A48A2BD6; Sat, 19 Feb 2022 05:21:36 -0800 (PST) Received: by mail-ej1-x633.google.com with SMTP id lw4so21434992ejb.12; Sat, 19 Feb 2022 05:21:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=6/CbbKb963ZeCrGB3DpHf3S/LmT0OSOkIfiP6ix0yNw=; b=g8yJlYskzqTuBRAAEoQM+HWpp7cbLRi4aY04uw1k85i8g9VrN7PveuKbxE0xjXz4W4 0m8evUE7XQDbQU2cJ/aNI445xwopOp7kGMWScIfUk9veu3ArqpGJ4skEVEV4M7czBpdJ HZVLz0XIreUBuFamppgdxrnMECREn1Nw2b8TeOcc6WmwgnmdWYPKlTb3nW3w778z+FrG 1wMKa7bVwyw8ke4zopRSHWr4XCEV+19sHsOqDY7CBrIwTFReTdSdG/TvSVYJ4AshYgsA t9HyUZi+py5V9U9rKO8qcYoy/lHN8XeJsoLit22RP2uMU4w+jnswk+NZysuVCJ7NNVLn cj3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=6/CbbKb963ZeCrGB3DpHf3S/LmT0OSOkIfiP6ix0yNw=; b=DV4KRANqozRvInbNa09HqcnbR/sRwKrq5ogsWpgKrvDv3bVZ9ebQaWzlF75aoKnOcu 0fufG7gSpwpCNXglvQNf7FyuRREtazFnL2NTNUONmzXQwTgW0lsgo/cezy2oafwuWA3e 7EKlCOEI9qU1ZnPG6RdbJ62KfUGqzuQkgWbDd10MoOaWlXzsOxzVvC2k/hqrxOh7qOH3 E6xnuIYAzubYl7R1Xwo27uePhINW0JYw8/wdEGwSP5MappzaZ/lZ5WQrgmyE8olvqLsv +EaW90C+d70vI17UfC3BroDa+yu8QeBx0TNq6Y30TPsk9drri/liWacVg6tFkHOYiE3i Jyhg== X-Gm-Message-State: AOAM530/RzBjk6ix6MQohq7TKZu3a8Dep2c81UakpyvmzDoiEQ8aRZgL JPwCmogGI89IYR88bsujPOU= X-Google-Smtp-Source: ABdhPJzhAyytukio3fsv22UT9/mGIL0fYpo82E0oO6KLYaHugboccaHhai7rq9lexRYpVBewgQTSaA== X-Received: by 2002:a17:906:6b8e:b0:6cd:7d22:e5b6 with SMTP id l14-20020a1709066b8e00b006cd7d22e5b6mr10437171ejr.259.1645276895195; Sat, 19 Feb 2022 05:21:35 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id p9sm3272675ejn.104.2022.02.19.05.21.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:34 -0800 (PST) Message-ID: Date: Sat, 19 Feb 2022 14:18:30 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 4/6] docs: ABI: document tm1628 attribute display-text Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Document the attribute for reading / writing the text to be displayed on the 7 segment display. Signed-off-by: Heiner Kallweit --- Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 diff --git a/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 b/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 new file mode 100644 index 000000000..382757e72 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-auxdisplay-tm1628 @@ -0,0 +1,7 @@ +What: /sys/devices/.../display-text +Date: February 2022 +Contact: Heiner Kallweit +Description: + The text to be displayed on the 7 segment display. + Any printable character is allowed as input, but some + can not be displayed in a readable way with 7 segments. From patchwork Sat Feb 19 13:19:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752301 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 6AD5BC433F5 for ; Sat, 19 Feb 2022 13:21:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234964AbiBSNWC (ORCPT ); Sat, 19 Feb 2022 08:22:02 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:38402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234934AbiBSNWB (ORCPT ); Sat, 19 Feb 2022 08:22:01 -0500 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 230BF13CD4; Sat, 19 Feb 2022 05:21:38 -0800 (PST) Received: by mail-ej1-x630.google.com with SMTP id qk11so21521528ejb.2; Sat, 19 Feb 2022 05:21:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=KpQK1gfePu1e2tBX2grUcsGjzBBgRCeFnQOH8xBSly4=; b=N33+xmC05XyjZ7JqPO53Tl5+bN+omEhOoSoHrGodc4YDdJ2hdF2O1T6ybNcgO4Ri3S sMmbb5pdN3oGapsNfAQWveuL/ad7dSRuLuyTagF3uKVkVNfdYOEYz+uLk+0raJ/irzBS HBZKZLvWetxKM0NY5QM17MkCqtpTp6JuWfYUmIUXkpnjOZNWC2knvECHIyyAqKFu5O2L f7JP+XkhViGsxr6zXA/4Bthw6RpakTqqrAIhTqV4sCplC3ojGQ6iZ94rYBEIPpxFnL6G O+igroZ08sQDeGynHxeR2al3gcWC15TB6+ZaBAmMgLDj7nMvHRxiAPxBreqb6pZCeC/l fcwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=KpQK1gfePu1e2tBX2grUcsGjzBBgRCeFnQOH8xBSly4=; b=4AZJdycfZFtDtyezAS9dN5unTTmICOnxHQpZ1jM7HqmyOyAhdF445JkYFPVJD3rXeV ScyowkY3jvdihPjquAdhriCTJkJXgorhlhsfEoQxvddfHzffD+e2WjURwg/wHhXVV8pC xnL9zl6gMYe5scKSP/4T7H5Gx86AnpdBpS2uZFJJyetXuHcJv430mFJYY0f9vcR35mB+ /pnWyu8WBP44D3l9rr61EQWlnzPBERPMNUvF54zM3G/+8e8CSv3wEsnMOLaiipfi6EGF 5V5ERnrLDc+0bn82Xq7s9fSquANWJOgs0yGHEDJRYaME3X5woh/Yv0SwYNaIhOTct9UN 5Lkw== X-Gm-Message-State: AOAM532zsgzLRNxtEQaIGTqJLGUTqZkr+jgM51rK1JTujyDO89mRMYWn BdpWxHsAOE1dbND7/m1P6TU= X-Google-Smtp-Source: ABdhPJyQUYYa50pDp0HZpcKIg/sd7iNu5qS06WWWtvShT3O8EdTQh0geqDD0oXQHImOYAq9H3Vw/cA== X-Received: by 2002:a17:906:3905:b0:6cf:7ef5:fee0 with SMTP id f5-20020a170906390500b006cf7ef5fee0mr9721904eje.307.1645276896577; Sat, 19 Feb 2022 05:21:36 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id bl12sm3208813ejb.75.2022.02.19.05.21.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:36 -0800 (PST) Message-ID: Date: Sat, 19 Feb 2022 14:19:30 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 5/6] auxdisplay: add support for Titanmec TM1628 7 segment display controller Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This patch adds support for the Titanmec TM1628 7 segment display controller. It's based on previous RFC work from Andreas Färber. The RFC version placed the driver in the LED subsystem, but this was NAK'ed by the LED maintainer. Therefore I moved the driver to /drivers/auxdisplay what seems most reasonable to me. Further changes to the RFC version: - Driver can be built also w/o LED class support, for displays that don't have any symbols to be exposed as LED's. - Simplified the code and rewrote a lot of it. - Driver is now kind of a MVP, but functionality should be sufficient for most use cases. - Use the existing 7 segment support in uapi/linux/map_to_7segment.h as suggested by Geert Uytterhoeven. Note: There's a number of chips from other manufacturers that are almost identical, e.g. FD628, SM1628. Only difference I saw so far is that they partially support other display modes. TM1628: 6x12, 7x11 SM1628C: 4x13, 5x12, 6x11, 7x10 For typical displays on devices using these chips this difference shouldn't matter. Successfully tested on a TX3 Mini TV box that has an SM1628C and a display with 4 digits and 7 symbols. Signed-off-by: Heiner Kallweit --- drivers/auxdisplay/Kconfig | 10 + drivers/auxdisplay/Makefile | 1 + drivers/auxdisplay/tm1628.c | 368 ++++++++++++++++++++++++++++++++++++ 3 files changed, 379 insertions(+) create mode 100644 drivers/auxdisplay/tm1628.c diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index 64012cda4..25ef2e452 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -203,6 +203,16 @@ config ARM_CHARLCD line and the Linux version on the second line, but that's still useful. +config TM1628 + tristate "TM1628 driver for LED 7/11 segment displays" + depends on SPI + depends on OF || COMPILE_TEST + help + Say Y to enable support for Titan Micro Electronics TM1628 + LED controller. + It's a 3-wire SPI device controlling a two-dimensional grid of + LEDs. Dimming is applied to all outputs through an internal PWM. + menuconfig PARPORT_PANEL tristate "Parallel port LCD/Keypad Panel support" depends on PARPORT diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index 6968ed4d3..7728e17e1 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_HT16K33) += ht16k33.o obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_LCD2S) += lcd2s.o obj-$(CONFIG_LINEDISP) += line-display.o +obj-$(CONFIG_TM1628) += tm1628.o diff --git a/drivers/auxdisplay/tm1628.c b/drivers/auxdisplay/tm1628.c new file mode 100644 index 000000000..a39b63828 --- /dev/null +++ b/drivers/auxdisplay/tm1628.c @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Titan Micro Electronics TM1628 LED controller + * + * Copyright (c) 2019 Andreas Färber + */ + +#include +#include +#include +#include +#include +#include + +#define TM1628_CMD_DISPLAY_MODE (0 << 6) +#define TM1628_DISPLAY_MODE_6_12 0x02 +#define TM1628_DISPLAY_MODE_7_11 0x03 + +#define TM1628_CMD_DATA (1 << 6) +#define TM1628_DATA_TEST_MODE BIT(3) +#define TM1628_DATA_FIXED_ADDR BIT(2) +#define TM1628_DATA_WRITE_DATA 0x00 +#define TM1628_DATA_READ_DATA 0x02 + +#define TM1628_CMD_DISPLAY_CTRL (2 << 6) +#define TM1628_DISPLAY_CTRL_DISPLAY_ON BIT(3) + +#define TM1628_CMD_SET_ADDRESS (3 << 6) + +#define TM1628_BRIGHTNESS_MAX 7 + +/* Physical limits, depending on the mode the chip may support less */ +#define MAX_GRID_SIZE 7 +#define MAX_SEGMENT_NUM 16 + +struct tm1628_led { + struct led_classdev leddev; + struct tm1628 *ctrl; + u32 grid; + u32 seg; +}; + +struct tm1628 { + struct spi_device *spi; + __le16 data[MAX_GRID_SIZE]; + struct mutex disp_lock; + char text[MAX_GRID_SIZE + 1]; + u8 segment_mapping[7]; + u8 grid[MAX_GRID_SIZE]; + int grid_size; + struct tm1628_led leds[]; +}; + +/* Command 1: Display Mode Setting */ +static int tm1628_set_display_mode(struct spi_device *spi, u8 grid_mode) +{ + u8 cmd = TM1628_CMD_DISPLAY_MODE | grid_mode; + + return spi_write(spi, &cmd, 1); +} + +/* Command 3: Address Setting */ +static int tm1628_set_address(struct spi_device *spi, u8 offset) +{ + u8 cmd = TM1628_CMD_SET_ADDRESS | (offset * sizeof(__le16)); + + return spi_write(spi, &cmd, 1); +} + +/* Command 2: Data Setting */ +static int tm1628_write_data(struct spi_device *spi, unsigned int offset, + unsigned int len) +{ + struct tm1628 *s = spi_get_drvdata(spi); + u8 cmd = TM1628_CMD_DATA | TM1628_DATA_WRITE_DATA; + struct spi_transfer xfers[] = { + { + .tx_buf = &cmd, + .len = 1, + }, + { + .tx_buf = (__force void *)(s->data + offset), + .len = len * sizeof(__le16), + }, + }; + + if (offset + len > MAX_GRID_SIZE) { + dev_err(&spi->dev, "Invalid data address offset %u len %u\n", + offset, len); + return -EINVAL; + } + + tm1628_set_address(spi, offset); + + return spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); +} + +/* Command 4: Display Control */ +static int tm1628_set_display_ctrl(struct spi_device *spi, bool on) +{ + u8 cmd = TM1628_CMD_DISPLAY_CTRL | TM1628_BRIGHTNESS_MAX; + + if (on) + cmd |= TM1628_DISPLAY_CTRL_DISPLAY_ON; + + return spi_write(spi, &cmd, 1); +} + +static int tm1628_show_text(struct tm1628 *s) +{ + static SEG7_CONVERSION_MAP(map_seg7, MAP_ASCII7SEG_ALPHANUM); + int i, ret; + + int msg_len = strlen(s->text); + + mutex_lock(&s->disp_lock); + + for (i = 0; i < s->grid_size; i++) { + int pos = s->grid[i] - 1; + + if (i < msg_len) { + int char7_raw = map_to_seg7(&map_seg7, s->text[i]); + int j, char7; + + for (j = 0, char7 = 0; j < 7; j++) { + if (char7_raw & BIT(j)) + char7 |= BIT(s->segment_mapping[j] - 1); + } + + s->data[pos] = cpu_to_le16(char7); + } else { + s->data[pos] = 0; + } + } + + ret = tm1628_write_data(s->spi, 0, s->grid_size); + + mutex_unlock(&s->disp_lock); + + return ret; +} + +static int tm1628_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct tm1628_led *led = container_of(led_cdev, struct tm1628_led, leddev); + struct tm1628 *s = led->ctrl; + int offset, ret; + __le16 bit; + + offset = led->grid - 1; + bit = cpu_to_le16(BIT(led->seg - 1)); + + mutex_lock(&s->disp_lock); + + if (brightness == LED_OFF) + s->data[offset] &= ~bit; + else + s->data[offset] |= bit; + + ret = tm1628_write_data(s->spi, offset, 1); + + mutex_unlock(&s->disp_lock); + + return ret; +} + +static enum led_brightness tm1628_led_get_brightness(struct led_classdev *led_cdev) +{ + struct tm1628_led *led = container_of(led_cdev, struct tm1628_led, leddev); + struct tm1628 *s = led->ctrl; + int offset; + __le16 bit; + bool on; + + offset = led->grid - 1; + bit = cpu_to_le16(BIT(led->seg - 1)); + + mutex_lock(&s->disp_lock); + on = s->data[offset] & bit; + mutex_unlock(&s->disp_lock); + + return on ? LED_ON : LED_OFF; +} + +static int tm1628_register_led(struct tm1628 *s, struct fwnode_handle *node, + u32 grid, u32 seg, struct tm1628_led *led) +{ + struct device *dev = &s->spi->dev; + struct led_init_data init_data = { .fwnode = node }; + + led->ctrl = s; + led->grid = grid; + led->seg = seg; + led->leddev.max_brightness = LED_ON; + led->leddev.brightness_set_blocking = tm1628_led_set_brightness; + led->leddev.brightness_get = tm1628_led_get_brightness; + + return devm_led_classdev_register_ext(dev, &led->leddev, &init_data); +} + +static ssize_t display_text_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tm1628 *s = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%s\n", s->text); +} + +static ssize_t display_text_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tm1628 *s = dev_get_drvdata(dev); + int ret, i; + + if (count > s->grid_size + 1) /* consider trailing newline */ + return -E2BIG; + + for (i = 0; i < count && isprint(buf[i]); i++) + s->text[i] = buf[i]; + + s->text[i] = '\0'; + + ret = tm1628_show_text(s); + if (ret < 0) + return ret; + + return count; +} + +static const DEVICE_ATTR_RW(display_text); + +static int tm1628_spi_probe(struct spi_device *spi) +{ + struct fwnode_handle *child; + struct tm1628_led *leds; + unsigned int num_leds; + struct tm1628 *s; + int ret, i; + + num_leds = device_get_child_node_count(&spi->dev); + + s = devm_kzalloc(&spi->dev, struct_size(s, leds, num_leds), GFP_KERNEL); + if (!s) + return -ENOMEM; + + s->spi = spi; + spi_set_drvdata(spi, s); + + mutex_init(&s->disp_lock); + + msleep(200); /* according to TM1628 datasheet */ + + /* clear screen */ + ret = tm1628_write_data(spi, 0, MAX_GRID_SIZE); + if (ret) + return ret; + /* Assume that subsequent SPI transfers will be ok if first was ok */ + + /* For now we support 6x12 mode only. This should be sufficient for most use cases */ + tm1628_set_display_mode(spi, TM1628_DISPLAY_MODE_6_12); + + tm1628_set_display_ctrl(spi, true); + + if (!IS_REACHABLE(CONFIG_LEDS_CLASS)) + goto no_leds; + + leds = s->leds; + + device_for_each_child_node(&spi->dev, child) { + u32 reg[2]; + + ret = fwnode_property_read_u32_array(child, "reg", reg, 2); + if (ret) { + dev_err(&spi->dev, "Reading %s reg property failed (%d)\n", + fwnode_get_name(child), ret); + continue; + } + + if (reg[0] == 0 || reg[0] > MAX_GRID_SIZE) { + dev_err(&spi->dev, "Invalid grid %u at %s\n", + reg[0], fwnode_get_name(child)); + continue; + } + + if (reg[1] == 0 || reg[1] > MAX_SEGMENT_NUM) { + dev_err(&spi->dev, "Invalid segment %u at %s\n", + reg[1], fwnode_get_name(child)); + continue; + } + + ret = tm1628_register_led(s, child, reg[0], reg[1], leds++); + if (ret) { + dev_err(&spi->dev, "Failed to register LED %s (%d)\n", + fwnode_get_name(child), ret); + continue; + } + } + +no_leds: + ret = device_property_count_u8(&spi->dev, "grid"); + if (ret < 1 || ret > MAX_GRID_SIZE) { + dev_err(&spi->dev, "Invalid display length (%d)\n", ret); + return -EINVAL; + } + + s->grid_size = ret; + + ret = device_property_read_u8_array(&spi->dev, "grid", s->grid, s->grid_size); + if (ret < 0) + return ret; + + for (i = 0; i < s->grid_size; i++) { + if (s->grid[i] < 1 || s->grid[i] > s->grid_size) + return -EINVAL; + } + + ret = device_property_read_u8_array(&spi->dev, "segment-mapping", s->segment_mapping, 7); + if (ret < 0) + return ret; + + for (i = 0; i < 7; i++) { + if (s->segment_mapping[i] < 1 || s->segment_mapping[i] > MAX_SEGMENT_NUM) + return -EINVAL; + } + + return device_create_file(&spi->dev, &dev_attr_display_text); +} + +static void tm1628_spi_remove(struct spi_device *spi) +{ + device_remove_file(&spi->dev, &dev_attr_display_text); + tm1628_set_display_ctrl(spi, false); +} + +static void tm1628_spi_shutdown(struct spi_device *spi) +{ + tm1628_set_display_ctrl(spi, false); +} + +static const struct of_device_id tm1628_spi_of_matches[] = { + { .compatible = "titanmec,tm1628" }, + {} +}; +MODULE_DEVICE_TABLE(of, tm1628_spi_of_matches); + +static const struct spi_device_id tm1628_spi_id_table[] = { + { "tm1628" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, tm1628_spi_id_table); + +static struct spi_driver tm1628_spi_driver = { + .probe = tm1628_spi_probe, + .remove = tm1628_spi_remove, + .shutdown = tm1628_spi_shutdown, + .id_table = tm1628_spi_id_table, + + .driver = { + .name = "tm1628", + .of_match_table = tm1628_spi_of_matches, + }, +}; +module_spi_driver(tm1628_spi_driver); + +MODULE_DESCRIPTION("TM1628 LED controller driver"); +MODULE_AUTHOR("Andreas Färber"); +MODULE_LICENSE("GPL"); From patchwork Sat Feb 19 13:21:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 12752302 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 595B4C433FE for ; Sat, 19 Feb 2022 13:21:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235699AbiBSNWE (ORCPT ); Sat, 19 Feb 2022 08:22:04 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:38432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237208AbiBSNWC (ORCPT ); Sat, 19 Feb 2022 08:22:02 -0500 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FAC245789; Sat, 19 Feb 2022 05:21:39 -0800 (PST) Received: by mail-ed1-x536.google.com with SMTP id m3so14225869eda.10; Sat, 19 Feb 2022 05:21:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language :from:to:cc:references:in-reply-to:content-transfer-encoding; bh=kKy0SIhSKIu0kr4V4JEIbxoglz4OmTrfglh5tt6nsYg=; b=HvdT9JAucpWhsLeiyKmZWgMiivw42j1g4brDgT0HYkHdFm7cuv08RqQ+Yd7vR0Am++ eniGJ6ZcwKrAnunlIdeCJXU+CjPjTpl2zpBARlxoLXIARrfRdv8neQr7BLaE6r9+irr1 ACXnsYsARFhvAIbZCqmGVB+57xjfnRFtrpPTm+2BvIwgepvw+QvR+CdIHrMs8cvmrvYc 9t+W1y11Ppjg6LwczhsFqJjtXrMRwUWliOP6oTIxfWbJ8mbP6e2Txa3FM56WwoSx7+ZF HZ7eaSq61l4YPu7po20/tBL6w8LN9cqSNExUf8/VzCNBMLf2xo0gD9fadPzDq3s8yWgG GsSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:from:to:cc:references:in-reply-to :content-transfer-encoding; bh=kKy0SIhSKIu0kr4V4JEIbxoglz4OmTrfglh5tt6nsYg=; b=B2Zrf6JviwidKZQsJmQw3EEQU+n+d6UeMoN6eEHtAnqG6q+W/Qy6xqOBfjGjDebXFi 1UxVl/K6DlK3L8PEq5Je/R/50cOgk+Pr6p5xDBwItYnXaL7AG34hGHKULaXmeDaWt1w2 LQPE5jDrYtl6fxoxtN8BZH9NrxL/xo1/3SjC4EzNqru0CzWGEN6RuwonuSiDX33XdOf0 8vrJYdD8vLPcbKu48gHKBKzP/KImubtM/3aQLBwPr+pTRGlmqymC2ynoGgw1Aea7VKP4 uvUkKCdnYlgrkQHeRZlW1ngp8FGQfYTuXExwU0hwmfGmV5EFV+RsE/LKJb8yUW5OSODt 5Hzw== X-Gm-Message-State: AOAM5301YOhszkM49lYLCOtGRBV6V9nPCHy0amakWVRh6kvGrVYl7qjI xN5rI1wT6RBN+oLi6IMbMd8= X-Google-Smtp-Source: ABdhPJxRPAPD6aXevcaRSr1YCJIxTII7mV9dKRp/d1qVz1sKSq4robgQqCvKDvV7unC3MvnXWu+JOA== X-Received: by 2002:aa7:d592:0:b0:410:b9f9:90f2 with SMTP id r18-20020aa7d592000000b00410b9f990f2mr12921325edq.327.1645276897910; Sat, 19 Feb 2022 05:21:37 -0800 (PST) Received: from ?IPV6:2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d? (p200300ea8f4d2b005cf9df09c1b3d44d.dip0.t-ipconnect.de. [2003:ea:8f4d:2b00:5cf9:df09:c1b3:d44d]) by smtp.googlemail.com with ESMTPSA id h5sm3194476ejo.124.2022.02.19.05.21.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 05:21:37 -0800 (PST) Message-ID: <251a8c26-4b6e-e0ac-059e-94bb40c673f2@gmail.com> Date: Sat, 19 Feb 2022 14:21:14 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: [PATCH 6/6] arm64: dts: meson-gxl-s905w-tx3-mini: add support for the 7 segment display Content-Language: en-US From: Heiner Kallweit To: Mark Brown , Rob Herring , Krzysztof Kozlowski , =?utf-8?q?Andreas_?= =?utf-8?q?F=C3=A4rber?= , Geert Uytterhoeven , Miguel Ojeda , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: "linux-spi@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "open list:ARM/Amlogic Meson..." References: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> In-Reply-To: <4172e59f-b9d5-d87d-9dbd-a6f683a2173c@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This patch adds support for the 7 segment display of the device. Signed-off-by: Heiner Kallweit --- .../dts/amlogic/meson-gxl-s905w-tx3-mini.dts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts index 6705c2082..20bbd931e 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts @@ -10,6 +10,7 @@ #include "meson-gxl-s905x.dtsi" #include "meson-gx-p23x-q20x.dtsi" +#include / { compatible = "oranth,tx3-mini", "amlogic,s905w", "amlogic,meson-gxl"; @@ -19,6 +20,64 @@ memory@0 { device_type = "memory"; reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */ }; + + spi { + compatible = "spi-gpio"; + sck-gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&gpio GPIODV_26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>; + num-chipselects = <1>; + #address-cells = <1>; + #size-cells = <0>; + + tm1628: led-controller@0 { + compatible = "titanmec,tm1628"; + reg = <0>; + spi-3wire; + spi-lsb-first; + spi-rx-delay-us = <1>; + spi-max-frequency = <500000>; + #address-cells = <2>; + #size-cells = <0>; + + segment-mapping = /bits/ 8 <4 5 6 1 2 3 7>; + grid = /bits/ 8 <4 3 2 1>; + + alarm@5,1 { + reg = <5 1>; + function = LED_FUNCTION_ALARM; + }; + + usb@5,2 { + reg = <5 2>; + function = LED_FUNCTION_USB; + }; + play@5,3 { + reg = <5 3>; + function = "play"; + }; + + pause@5,4 { + reg = <5 4>; + function = "pause"; + }; + + colon@5,5 { + reg = <5 5>; + function = "colon"; + }; + + lan@5,6 { + reg = <5 6>; + function = LED_FUNCTION_LAN; + }; + + wlan@5,7 { + reg = <5 7>; + function = LED_FUNCTION_WLAN; + }; + }; + }; }; &ir {