From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29ACAC32788 for ; Wed, 10 Oct 2018 02:16:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BEE0F206B2 for ; Wed, 10 Oct 2018 02:16:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=renesasgroup.onmicrosoft.com header.i=@renesasgroup.onmicrosoft.com header.b="hMWWnw2q" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BEE0F206B2 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=renesas.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727375AbeJJJgp (ORCPT ); Wed, 10 Oct 2018 05:36:45 -0400 Received: from relmlor4.renesas.com ([210.160.252.174]:24720 "EHLO relmlie3.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727160AbeJJJgp (ORCPT ); Wed, 10 Oct 2018 05:36:45 -0400 Received: from unknown (HELO relmlir3.idc.renesas.com) ([10.200.68.153]) by relmlie3.idc.renesas.com with ESMTP; 10 Oct 2018 11:16:50 +0900 Received: from relmlii2.idc.renesas.com (relmlii2.idc.renesas.com [10.200.68.66]) by relmlir3.idc.renesas.com (Postfix) with ESMTP id E674078130; Wed, 10 Oct 2018 11:16:50 +0900 (JST) X-IronPort-AV: E=Sophos;i="5.54,362,1534777200"; d="scan'208";a="294715697" Received: from mail-os2jpn01lp0152.outbound.protection.outlook.com (HELO JPN01-OS2-obe.outbound.protection.outlook.com) ([23.103.139.152]) by relmlii2.idc.renesas.com with ESMTP/TLS/AES256-SHA256; 10 Oct 2018 11:16:50 +0900 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=renesasgroup.onmicrosoft.com; s=selector1-renesas-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2tz/COKT1TGQJDq2H5ier8QM2Ui9vC9MhROR2qZIMPA=; b=hMWWnw2qcwsht/vYR/8EjlEyIjwO4NOko+WHB70vfSQ5c2ZxGj7xlOt2mSybZ6Wd13AHGVv+HIMzRC1jYN2JXkw1TEb2p2l2RcNIXoSO4wcDbZVjd5i8NYKB4tdTkx1muuZeUyxHajh0HKk6Spe8+A7pIXEwi06CSV8ghTI7VEM= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=kuninori.morimoto.gx@renesas.com; Received: from morimoto-PC.renesas.com (211.11.155.130) by TY1PR01MB1866.jpnprd01.prod.outlook.com (2603:1096:403:2::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1207.23; Wed, 10 Oct 2018 02:16:48 +0000 Message-ID: <87bm821rkf.wl-kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH 2/2] clk: add 74aup1g157gw 2-input multiplexer as clock driver User-Agent: Wanderlust/2.15.9 Emacs/24.5 Mule/6.0 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") To: Michael Turquette , Stephen Boyd , Rob Herring , Mark Rutland Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <87efcy1rm4.wl-kuninori.morimoto.gx@renesas.com> References: <87efcy1rm4.wl-kuninori.morimoto.gx@renesas.com> Content-Type: text/plain; charset=US-ASCII Date: Wed, 10 Oct 2018 02:16:48 +0000 X-Originating-IP: [211.11.155.130] X-ClientProxiedBy: TY1PR01CA0184.jpnprd01.prod.outlook.com (2603:1096:403::14) To TY1PR01MB1866.jpnprd01.prod.outlook.com (2603:1096:403:2::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b4d7e77b-0d6c-452a-fc6d-08d62e566f0d X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);SRVR:TY1PR01MB1866; X-Microsoft-Exchange-Diagnostics: 1;TY1PR01MB1866;3:BIJRvNmsY5TeKIKPGUEbqtk+BbSB4C9ufiuZycaDM7W+2qQhe5vbko2JIAwvRVyz+REYbJritkqJ4Bi9USGTWgcwyHj1mL2xCqhL24a9AVh1waDgrRqR8Bmr3eOI2DGJgkDAK06jo9dd937RNXJCoBspSw5rVTVt96lZ8H3olV0MC/Ofk1Istf4Xz8MK9tTTwxbK9JSsYsNH7CzIDdD+ZOh2OVIFrBmFaCWJxs4Z+lnq9iIeoFPlLvZz0aSy00/v;25:8Lg0SRqX5Cq9tajbEbf5VGoWbgKU9FtdsY98ZaBW3wMcxPvp+gViNgQgg1spSH8M5UMlZ2ONrpRQTsjiK9xt5uXGfXKIqJoVC+ikN+jqAyxaOuroQpnRjEVemxB/zypAVae6ICymm2HxpO04Zgu8eK0kr7alF3bYT1vM7sX5I+AKIA8CgPlKBMYh0mAjVqv8Sj6FmfqIZbpjV9Wn/PIHM+5wFJMdbzaH48ZsXYzYJZI6AXPGtNnvJHQ5AiqPOvosb0AHCVVqyvZIkMO1kDCEbp3AlqQxnPtl3/OulzY5AX16AV+eyCqRbac312JRK/s8Ky7AVBezKficNKaz+Ubb5A==;31:a9tlbn5xP3E+SxUkdUdrjBh/dvEoT+ZAPosGIzDJyDM1eHCZdf8Za/4+i6jhMm/IQPnJZzTXlFzeRCGORp56UWGR//DNmnPutHOc7O+zkuxe/aXTQ+47876OTlImrBXlcpXEs+ax451uFTXjrRvcWTj1XAmtGL5DxzOqpMYg8Di7H0D4dQ70wxC4BGtuZqSLJh/vpEhQMIzkfjRodh6nEbO6eg+GrKLn+KQMB2x/U+g= X-MS-TrafficTypeDiagnostic: TY1PR01MB1866: X-Microsoft-Exchange-Diagnostics: 1;TY1PR01MB1866;20:9BDnRQs/KpqFFNtiw4DUlQl7v+IHskV8BpXHF+O2kA0kPTSDJ/C/ME0yYEw8FiKcVdlSmg8LsPBC6A5G2NgrVO++WyxPA0+lTJ20L5pfs1P93HY2MB/HaTYM8Uhao2rre9DARsAaDPQy5Hzy+QlZghxL/uedaj3PASq48xjjDL4XYjh79uHxWpAqQhie9zrR6FB4QyankRyiwWnamXTTYxzRj6J9FT8eSbBHIW3lAJv3MUIq7d3UVjwolQDDCtBfMFSpXLGdPnqMQQ6Of0iEbaQGBDCJwekBTWx6eAxvn+9A2efIzcvRHEdJdgwvZBnY2xHpqJoA+rdbcZvcGe19YXP8pil/xtkbnUSQVZ6sqBGFP1bYrP66Vc+q83PBiAMueSFzora14LTgZ87w/Pnj9GXVXxEk7CTQYQZkRAR9hGWf5OxS2y6ic/7m+tsivy7SymyvjwSz1177ISWlNEpnJcru8QMK+flnBTZnPLKoRZAFuVWjqHjKhwDaxY3sJ1Nz;4:TcUSTjARUyNj7F/DZnKZcP/fcl0AVRLkvLtiO11sZB/5hH5SH9HRdosSqw3+k0Wd37G12OEjyXvlhKEMtFh53kqKELihLRnXjKzKePmJ5sh5aHWUEHgaMapj/KFmbJiEAP6zPcWLawO//WsyWDenB7ofD2mA2JZjOek7Put9aGqDMuzoh2E558YulbRZrB041Oc/NU+rAufcqqKsuPRKkg4DL3LLPd8XePdwWqfkbCsA+Co22rmXo20smTTLLbQbzHaUHWLl9gNWt0u63TpPFA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3002001)(10201501046)(3231355)(944501410)(52105095)(6055026)(149066)(150057)(6041310)(20161123562045)(20161123558120)(20161123560045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699051);SRVR:TY1PR01MB1866;BCL:0;PCL:0;RULEID:;SRVR:TY1PR01MB1866; X-Forefront-PRVS: 08213D42D3 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(396003)(39860400002)(366004)(136003)(376002)(346002)(189003)(199004)(16526019)(8676002)(81166006)(7736002)(446003)(8936002)(575784001)(186003)(14444005)(81156014)(305945005)(4326008)(50466002)(486006)(36756003)(2616005)(26005)(86362001)(956004)(68736007)(476003)(47776003)(97736004)(11346002)(66066001)(386003)(478600001)(7696005)(23726003)(5660300001)(53936002)(3846002)(6116002)(110136005)(16586007)(316002)(106356001)(52116002)(76176011)(2906002)(58126008)(53416004)(105586002)(6486002)(25786009)(69596002)(16060500001);DIR:OUT;SFP:1102;SCL:1;SRVR:TY1PR01MB1866;H:morimoto-PC.renesas.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; Received-SPF: None (protection.outlook.com: renesas.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;TY1PR01MB1866;23:QQWZ+R0WekCvCmzxeBH1usXusBCrcrwJNeUCLdVSN?= =?us-ascii?Q?N3Bxwz/hvrXHvKAFxYQZK6iOIwsaSlm0hWKaiQHfHNj85WZMea90/TXTpN69?= =?us-ascii?Q?7Vv2lIDddizBzvQeW58076eJQQpNZwhWwmOlijieqaXtqy+zTFRAroASOTV4?= =?us-ascii?Q?tKVEvJjbQB3dycfZ8HGu7iQG9g9evrYx/Pm38cqIrOtQ79I4JiK/Au4cVQts?= =?us-ascii?Q?vHNlhqeT20MoK77cIhCPUg3P002PPmmR/GUfuIKNMQUMAwt4r36jFwDClPET?= =?us-ascii?Q?P4Ml+dAxHhDHndbDwp4aq4HHGhM2Pbk16p65BdhRWCjvUNDoIHyMOB1MmX+9?= =?us-ascii?Q?9Z6lYAGFr55uKHGobTeJQjmkRx+mE7KMq3WkJekNEIJdlpr6VrhO+WSFv3Gk?= =?us-ascii?Q?vRIh61mDshItwubV2j78ET/LI1WfYuFY5Zkn2WNCDeZ1ZJR8TMdKIMVUfHL8?= =?us-ascii?Q?VRAwUd9GCfd3WqJ2ZyL6ElZqp5yjgb4cjs1Qn/AMFa4l8235ewUkPlmB5Tes?= =?us-ascii?Q?xgGZo6qujLGwiqBv8RCTTMKcwI/DM4LER3aejbanJmqOktvjcJNZUlYSzQsE?= =?us-ascii?Q?1ppim6GjEIXV/J+bAIf7fGi6wgg2z3DTBwNlk4+N6E9UUxk5+yF1XTNhVVWK?= =?us-ascii?Q?jIAxV4v7X+8gq2ky1+Fby1uGglPhj7VWjD2nIQLkxE0v/M2j47IHBW+3n9qb?= =?us-ascii?Q?nStoKsxhTte0Bi5AC/JrkXPjWFqEnFF9amdhMh07w3SG8Hf6A1sDTzaG419D?= =?us-ascii?Q?JhDcd0Oa0xMmQMSA4mqBxVHpx3ej4FfJ/WBS5LLVZKOAUDqZFd3x9nVo2EM+?= =?us-ascii?Q?PH7M8gC+ZZNVMXjEPzPtUjGCig8L3ua6Q4PQ5e44sU7GFLmv9SodseAOBxbZ?= =?us-ascii?Q?o+D6Zim7gR9Sugt5Mc9DKVIIrJsWWUw2DMsxXtYUO1WP5TLqebjFqnub7cWM?= =?us-ascii?Q?hOF1YQHSqEVri+UhiJUZvWoAS2VDisHzWy80Bjhew8kYbnMwCCbgTE3i27zT?= =?us-ascii?Q?br/SjByie9ucCpo4lj8MYG0eieBBbk2v0mexbZwD16iqdRDw8nVVh7h5hSSn?= =?us-ascii?Q?bCr/VVCEkhTymff2ANseJa5iqHPwaNdfAVvEHXc1OVwIqXV3o13nz0VDLVaO?= =?us-ascii?Q?0rOPbLJXxeYVdhU/hjE9hBxgNDFC1bHBS539Wcg8E0Bk5i1eex2cwrM0oIfx?= =?us-ascii?Q?N7NfaqZ1rAS6EQ0iloC+CojzyupbIzzie12Vx4izD/Hza5rrCprKL/Wvw=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Antispam-Message-Info: 6VJMEnOXMeRz8Nx60sC2s5wGQqE27szDg23lVIbw5QD+PQPWJ6hrKF7MMoMa0zHIUFLfHtc+K5Wm7Id3dHnGg4HQu5KOkl/mWcuj2g+IT2Cjb4Ay2o3U+lv1RFX8c/Q9M/dRL6eg0WKUinPsOopK7nih4AeKhO1hqqNhUUYmcGXI8dtyAinqPvd2DZV3hHNZCjU0dxzh+2Wtj7ZPOLiFWIvRW5411smcJmomc06ioLq04xym3ExbzhJvrqpx9URvRlbeNSDcFqq0X6tR4SPjr7eJPPq87qKriGW1fy8HAKh+5o9EqGiHGlejf7DV4jNlJMA53dQN03EeizunHngOxULrzJ4ZmT+xPMGVXjNgRdw= X-Microsoft-Exchange-Diagnostics: 1;TY1PR01MB1866;6:riIwjtLU3ayuET3t8/G/ESYoLOoStaSIMzBUhUOG8jesvC9pyvjeKe5q8765XnNHKizXtRhnqHNbwjKgT3u9O6fAYmkRKAX1NFUTHjMzLUBhQbLoU0lD/kbmY2W98h1J+J/P820Io5kPl9ASdF7rzPyaSknJrGAvy5riROWMTu8yazLhGuwNnTIIdmxbfs4jO/Ha9kPPW1w4Xv5cPkJ6CYIXJ2/gnvvCxcgxcNmpaP1EjBmm0eXkUtAFiHO2zWML/a9lmu4ZBHqjyvESdfHkwMj89mQOvxaUv+sc3oj4ftKsKbfjtCTk9EOPdWZYV16Rj8i6iVqvxeQXlcNNECbX9mVRHTpo2PQvlAQVcpDEbIXMshCzrQIH68Lehm1oqpzOLv3IekRx16GEGxbWtiHkFryO6kpHhL9LxV7k5OQhAB9UmQIUiLO97wDX1kszRMoMOn1TWuY7gqlFz35QYqAxyw==;5:ZwQYzUugEmWADmRfbLHc4TqQ7sdClQb3oyoSUH4BVCo7bmJ7SYmlwmoV+rxsYJSAxULRaP+Fxgc3vbwPpAR8MuilmgtZbV+1bdKG3aUhN+pmlKBJYuKIT05X6USI3CsGRQqSTm4l2v+Xm2Z8vCxKaAaYM1Jp00KwMKTsC5IuTnY=;7:p1oc72vK9VHz2SeetK6pqCmeOVeczcFysr5fjj02oocy3tswLmSHGrl7IvEpKhg3mTvh7bgv69lyi9bl/2vVrq29lXKFwtlU8j7OvpGn8JcO7pJE5JyasiVAV8Z60DkuHmw8jGCL0oSQO6pgHZvqKPFSZNlt66K9iLpPmjOOhGr7WNm5EFJRoSFKu2ROiOekT7U3hnNxWdnUBgbXzt4MCTbJ/8HSEhkidk9nvAXL2i+RSAkJz7TsF/4iwIYYQroU SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;TY1PR01MB1866;20:JVH7FUvIkHeUWcibdUcomxh/hUoo5AfKtaLmthnCg9T9EZJ6OuOcPBzKCfwh+XjxL+c+lsVfTJmJlqj+OBQ8B3J3JMHexMtCzzPktfDlLEyIn+8ngZ73X+KezfulYrfalH1pxLG8dY0UBFmiJPGqz9lUm14ZjChSJieNnClG8l8= X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Oct 2018 02:16:48.3926 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b4d7e77b-0d6c-452a-fc6d-08d62e566f0d X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 53d82571-da19-47e4-9cb4-625a166a4a2a X-MS-Exchange-Transport-CrossTenantHeadersStamped: TY1PR01MB1866 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kuninori Morimoto 74aup1g157gw needs i0 and i1 pin as input, select and output it by sel gpio pin. This driver adds new 74aup1g157gw as clock multiplexer. "nxp,74aup1g157gw-clk" will select most closest input as output, "nxp,74aup1g157gw-audio-clk" will select 48kHz/44.1kHz categorized input as output. Signed-off-by: Kuninori Morimoto --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/nxp/Kconfig | 4 + drivers/clk/nxp/Makefile | 1 + drivers/clk/nxp/clk-74aup1g157gw.c | 213 +++++++++++++++++++++++++++++++++++++ 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/nxp/Kconfig create mode 100644 drivers/clk/nxp/clk-74aup1g157gw.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 292056b..9cfeb0e 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -299,5 +299,6 @@ source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/ti/Kconfig" source "drivers/clk/uniphier/Kconfig" +source "drivers/clk/nxp/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index ed344eb..fcfd42a 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -84,7 +84,7 @@ obj-$(CONFIG_ARCH_MMP) += mmp/ endif obj-y += mvebu/ obj-$(CONFIG_ARCH_MXS) += mxs/ -obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ +obj-y += nxp/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ diff --git a/drivers/clk/nxp/Kconfig b/drivers/clk/nxp/Kconfig new file mode 100644 index 0000000..44c8fed --- /dev/null +++ b/drivers/clk/nxp/Kconfig @@ -0,0 +1,4 @@ +config CLK_74AUP1G157GW + tristate "NXP 74AUP1G157GW Low-power 2-input multiplexer support as clock" + help + This enables NXP 74AUP1G157GW 2-input multiplexer as clock driver diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile index d456ee6..2965bdd 100644 --- a/drivers/clk/nxp/Makefile +++ b/drivers/clk/nxp/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-creg.o obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o +obj-$(CONFIG_CLK_74AUP1G157GW) += clk-74aup1g157gw.o diff --git a/drivers/clk/nxp/clk-74aup1g157gw.c b/drivers/clk/nxp/clk-74aup1g157gw.c new file mode 100644 index 0000000..78199bb --- /dev/null +++ b/drivers/clk/nxp/clk-74aup1g157gw.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 Renesas Solutions Corp. +// Kuninori Morimoto +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLK_I_NUM 2 +struct clk_priv { + struct clk_hw hw; + struct device *dev; + struct clk *i[CLK_I_NUM]; + struct gpio_desc *sel; + long (*round_rate)(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate); +}; +#define hw_to_priv(_hw) container_of(_hw, struct clk_priv, hw) +#define priv_to_dev(priv) priv->dev +#define for_each_iclk(i) \ + for ((i) = 0; (i) < CLK_I_NUM; (i)++) + +static int clk74_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_priv *priv = hw_to_priv(hw); + struct device *dev = priv_to_dev(priv); + int i; + + for_each_iclk(i) { + if (rate == clk_get_rate(priv->i[i])) { + dev_dbg(dev, "set rate %lu as i%d\n", rate, i); + gpiod_set_value_cansleep(priv->sel, i); + return 0; + } + } + + dev_err(dev, "unsupported rate %lu\n", rate); + return -EIO; +} + +static long clk74_round_rate_close(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_priv *priv = hw_to_priv(hw); + struct device *dev = priv_to_dev(priv); + unsigned long min = ~0; + unsigned long ret = 0; + int i; + + /* + * select closest rate + */ + for_each_iclk(i) { + unsigned long irate = clk_get_rate(priv->i[i]); + unsigned long diff = abs(rate - irate); + + if (min > diff) { + min = diff; + ret = irate; + } + } + + dev_dbg(dev, "(close)round rate %lu\n", ret); + + return ret; +} + +static long clk74_round_rate_audio(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_priv *priv = hw_to_priv(hw); + struct device *dev = priv_to_dev(priv); + unsigned long ret = 0; + int is_8k = 0; + int i; + + /* + * select 48kHz or 44.1kHz category rate + */ + if (!(rate % 8000)) + is_8k = 1; + + for_each_iclk(i) { + unsigned long irate = clk_get_rate(priv->i[i]); + + if (( is_8k && !(irate % 8000)) || + (!is_8k && (irate % 8000))) { + ret = irate; + } + } + + dev_dbg(dev, "(audio)round rate %lu\n", ret); + + return ret; +} + +static long clk74_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_priv *priv = hw_to_priv(hw); + + return priv->round_rate(hw, rate, parent_rate); +} + +static unsigned long clk74_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_priv *priv = hw_to_priv(hw); + struct device *dev = priv_to_dev(priv); + unsigned long rate; + int i = gpiod_get_raw_value_cansleep(priv->sel); + + rate = clk_get_rate(priv->i[i]); + + dev_dbg(dev, "recalc rate %lu as i%d\n", rate, i); + + return rate; +} + +static u8 clk74_get_parent(struct clk_hw *hw) +{ + struct clk_priv *priv = hw_to_priv(hw); + + return gpiod_get_raw_value_cansleep(priv->sel); +} + +static const struct clk_ops clk74_ops = { + .set_rate = clk74_set_rate, + .round_rate = clk74_round_rate, + .recalc_rate = clk74_recalc_rate, + .get_parent = clk74_get_parent, +}; + +static const char * const clk74_in_name[CLK_I_NUM] = { + "i0", + "i1", +}; + +static int clk74_probe(struct platform_device *pdev) +{ + struct clk *clk; + struct clk_init_data init; + struct clk_priv *priv; + struct device *dev = &pdev->dev; + const char *parent_names[CLK_I_NUM]; + int i, ret; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENODEV; + + for_each_iclk(i) { + clk = devm_clk_get(dev, clk74_in_name[i]); + if (IS_ERR(clk)) + return -EPROBE_DEFER; + priv->i[i] = clk; + parent_names[i] = __clk_get_name(clk); + } + + memset(&init, 0, sizeof(init)); + init.name = "74aup1g157gw"; + init.ops = &clk74_ops; + init.parent_names = parent_names; + init.num_parents = CLK_I_NUM; + + priv->hw.init = &init; + priv->dev = dev; + priv->round_rate = of_device_get_match_data(dev); + priv->sel = devm_gpiod_get(dev, "sel", 0); + if (IS_ERR(priv->sel)) + return -EPROBE_DEFER; + + gpiod_direction_output(priv->sel, 0); + + ret = devm_clk_hw_register(dev, &priv->hw); + if (ret < 0) + return ret; + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &priv->hw); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, priv); + + dev_info(dev, "probed\n"); + + return 0; +} + +#define OF_ID(name, func) { .compatible = name, .data = func } +static const struct of_device_id clk74_of_match[] = { + OF_ID("nxp,74aup1g157gw-clk", clk74_round_rate_close), + OF_ID("nxp,74aup1g157gw-audio-clk", clk74_round_rate_audio), + { } +}; +MODULE_DEVICE_TABLE(of, clk74_of_match); + +static struct platform_driver clk74_driver = { + .driver = { + .name = "74aup1g157gw", + .of_match_table = clk74_of_match, + }, + .probe = clk74_probe, +}; +builtin_platform_driver(clk74_driver); -- 2.7.4