From patchwork Fri May 25 12:34:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Codrin Ciubotariu X-Patchwork-Id: 10427351 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1B8046025B for ; Fri, 25 May 2018 12:52:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 07734293DF for ; Fri, 25 May 2018 12:52:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F04812941E; Fri, 25 May 2018 12:52:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D39B0293DF for ; Fri, 25 May 2018 12:52:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Sgn5KF9tus30RhtvC6f3xDrMEXAEGE1Gym9K7pEI8yE=; b=C9BC2y5+r5F/1t MlEk+HEQ84CKvWFFsb0s3NBS9e0B+J7kzJ/vF6UxSjOP25SnhmhnCYaLGD4kxyVOcAl9gV0fpDFd/ GTro+GWgMF1B2KMLhcvKNP79W6EQu+vRhSn2MHTPfELmbkiQXQcvmtY9/WuyhFTwBFCoFiwFjPlAU nr0poqNmbhghqGfQ0RAagRdnF63j1eBe2hx1h8Ow1L73nPS5km6JSktw8dnxME/f+2tBHTMH/0JCb eA86JvOJRtmldXobiF3/TkUVcuRG6hUuJ32eCLeh1I50n+BZWo8EbjWDr2Qlgw8RQC3qIs4g1QFRs WR1hmIt6QG7vraxsmTjA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fMCCr-0004kW-R1; Fri, 25 May 2018 12:52:29 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fMBxC-00019F-0B for linux-arm-kernel@bombadil.infradead.org; Fri, 25 May 2018 12:36:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=uK5PtGTxb8WdrMUed6eNJATFg3uRJBZke2fcNc2aXGo=; b=S4t4d7fJG+UfVYONPsXeZCw8m 4c5b0YZv8tLOQxA1wV0VM8YPD22efW5vvDL1HqMjqvI1xZ076b9g8H3WvnseR1iLXWFNZId1/sBBC V1jAsITtojXnZCKEcgCo/8pvPz5WralUatjTWSled1PTHrPRFe/EhLGHmDcJETtz4NqjiflUH9zc6 VRXrO6bKRdWQ8Vcp9xU9AYYtHtRuHBxhJqbMDbWqWGtRJFjc1oyvDSWr/4dIMgMiKiIgfYjDRSoaJ PbC38NxMqsj9iF97k3Shb6ugLBANNdCI0Z04nrtCxBCa+VVIHm1rsKHVWBbHmZazzc3JjCkDz5n48 YuwlErrUA==; Received: from esa1.microchip.iphmx.com ([68.232.147.91]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fMBwI-0005EH-G3 for linux-arm-kernel@lists.infradead.org; Fri, 25 May 2018 12:35:24 +0000 X-IronPort-AV: E=Sophos;i="5.49,440,1520924400"; d="scan'208";a="15314123" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 25 May 2018 05:35:04 -0700 Received: from rob-ult-m19940.mchp-main.com (10.10.76.4) by chn-sv-exch02.mchp-main.com (10.10.76.38) with Microsoft SMTP Server id 14.3.352.0; Fri, 25 May 2018 05:35:04 -0700 From: Codrin Ciubotariu To: , , , , , , , , , Subject: [PATCH v4 2/7] clk: at91: add I2S clock mux driver Date: Fri, 25 May 2018 15:34:23 +0300 Message-ID: <1527251668-31396-3-git-send-email-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com> References: <1527251668-31396-1-git-send-email-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180525_133522_958806_3D11E736 X-CRM114-Status: GOOD ( 17.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cristian.Birsan@microchip.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This driver is a simple muxing driver that controls the I2S's clock input by using syscon/regmap to change the parrent. The available inputs can be Peripheral clock and Generated clock. Signed-off-by: Codrin Ciubotariu --- arch/arm/mach-at91/Kconfig | 4 ++ drivers/clk/at91/Makefile | 1 + drivers/clk/at91/clk-i2s-mux.c | 117 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 drivers/clk/at91/clk-i2s-mux.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 1254bf9..903f23c 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -27,6 +27,7 @@ config SOC_SAMA5D2 select HAVE_AT91_H32MX select HAVE_AT91_GENERATED_CLK select HAVE_AT91_AUDIO_PLL + select HAVE_AT91_I2S_MUX_CLK select PINCTRL_AT91PIO4 help Select this if ou are using one of Microchip's SAMA5D2 family SoC. @@ -129,6 +130,9 @@ config HAVE_AT91_GENERATED_CLK config HAVE_AT91_AUDIO_PLL bool +config HAVE_AT91_I2S_MUX_CLK + bool + config SOC_SAM_V4_V5 bool diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 082596f..facc169 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o +obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c new file mode 100644 index 0000000..2d56ded --- /dev/null +++ b/drivers/clk/at91/clk-i2s-mux.c @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Microchip Technology Inc, + * Codrin Ciubotariu + * + * + */ + +#include +#include +#include +#include +#include + +#include + +#define I2S_BUS_NR 2 + +struct clk_i2s_mux { + struct clk_hw hw; + struct regmap *regmap; + u32 bus_id; +}; + +#define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw) + +static u8 clk_i2s_mux_get_parent(struct clk_hw *hw) +{ + struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); + u32 val; + + regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val); + + return (val & BIT(mux->bus_id)) >> mux->bus_id; +} + +static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); + + return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL, + BIT(mux->bus_id), index << mux->bus_id); +} + +const struct clk_ops clk_i2s_mux_ops = { + .get_parent = clk_i2s_mux_get_parent, + .set_parent = clk_i2s_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; + +static struct clk_hw * __init +at91_clk_i2s_mux_register(struct regmap *regmap, const char *name, + const char * const *parent_names, + unsigned int num_parents, u32 bus_id) +{ + struct clk_init_data init = {}; + struct clk_i2s_mux *i2s_ck; + int ret; + + i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL); + if (!i2s_ck) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_i2s_mux_ops; + init.parent_names = parent_names; + init.num_parents = num_parents; + init.flags = CLK_IGNORE_UNUSED; + + i2s_ck->hw.init = &init; + i2s_ck->bus_id = bus_id; + i2s_ck->regmap = regmap; + + ret = clk_hw_register(NULL, &i2s_ck->hw); + if (ret) { + kfree(i2s_ck); + return ERR_PTR(ret); + } + + return &i2s_ck->hw; +} + +static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) +{ + struct regmap *regmap_sfr; + u32 bus_id; + const char *parent_names[2]; + struct device_node *i2s_mux_np; + struct clk_hw *hw; + int ret; + + regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); + if (IS_ERR(regmap_sfr)) + return; + + for_each_child_of_node(np, i2s_mux_np) { + if (of_property_read_u32(i2s_mux_np, "reg", &bus_id)) + continue; + + if (bus_id > I2S_BUS_NR) + continue; + + ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2); + if (ret != 2) + continue; + + hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name, + parent_names, 2, bus_id); + if (IS_ERR(hw)) + continue; + + of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw); + } +} + +CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux", + of_sama5d2_clk_i2s_mux_setup);