From patchwork Wed Jan 5 11:25:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 453261 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p05BPUER026000 for ; Wed, 5 Jan 2011 11:25:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751692Ab1AELZ2 (ORCPT ); Wed, 5 Jan 2011 06:25:28 -0500 Received: from relmlor1.renesas.com ([210.160.252.171]:56055 "EHLO relmlor1.renesas.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751591Ab1AELZ2 (ORCPT ); Wed, 5 Jan 2011 06:25:28 -0500 Received: from relmlir3.idc.renesas.com ([10.200.68.153]) by relmlor1.idc.renesas.com ( SJSMS) with ESMTP id <0LEJ0015QRQE3D10@relmlor1.idc.renesas.com> for linux-sh@vger.kernel.org; Wed, 05 Jan 2011 20:25:26 +0900 (JST) Received: from relmlac2.idc.renesas.com ([10.200.69.22]) by relmlir3.idc.renesas.com ( SJSMS) with ESMTP id <0LEJ005V5RQED490@relmlir3.idc.renesas.com> for linux-sh@vger.kernel.org; Wed, 05 Jan 2011 20:25:26 +0900 (JST) Received: by relmlac2.idc.renesas.com (Postfix, from userid 0) id C8FBE2808A; Wed, 05 Jan 2011 20:25:26 +0900 (JST) Received: from relmlac2.idc.renesas.com (localhost [127.0.0.1]) by relmlac2.idc.renesas.com (Postfix) with ESMTP id C340D28088; Wed, 05 Jan 2011 20:25:26 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac2.idc.renesas.com with ESMTP id WAU17051; Wed, 05 Jan 2011 20:25:26 +0900 Date: Wed, 05 Jan 2011 20:25:26 +0900 X-IronPort-AV: E=Sophos;i="4.60,277,1291561200"; d="scan'208";a="4573091" Received: from unknown (HELO PG10870.renesas.com) ([172.30.8.159]) by relmlii2.idc.renesas.com with ESMTP; Wed, 05 Jan 2011 20:25:26 +0900 Message-id: To: Paul Mundt Cc: Magnus , Linux-SH In-reply-to: References: From: Kuninori Morimoto Subject: [PATCH 1/3] ARM: mach-shmobile: mackerel: Add fsi_set_rate User-Agent: SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-2022-JP-2?B?U2Fuag==?= =?ISO-2022-JP-2?B?GyQoRCtXGyhC?=) APEL/10.6 Emacs/23.2 (i386-mingw-nt5.1.2600) MULE/6.0 (HANACHIRUSATO) MIME-version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-type: text/plain; charset=US-ASCII Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 05 Jan 2011 11:25:31 +0000 (UTC) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 3e30a52..83e83e8 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -369,12 +369,93 @@ static struct platform_device leds_device = { /* FSI */ #define IRQ_FSI evt2irq(0x1840) +static int __fsi_set_rate(struct clk *clk, long rate, int enable) +{ + int ret = 0; + + if (rate <= 0) + return ret; + + if (enable) { + ret = clk_set_rate(clk, rate); + if (0 == ret) + ret = clk_enable(clk); + } else { + clk_disable(clk); + } + + return ret; +} + +static int __fsi_set_round_rate(struct clk *clk, long rate, int enable) +{ + return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable); +} + +static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable) +{ + struct clk *fsia_ick; + struct clk *fsiack; + int ret = -EIO; + + fsia_ick = clk_get(dev, "icka"); + if (IS_ERR(fsia_ick)) + return PTR_ERR(fsia_ick); + + /* + * FSIACK is connected to AK4642, + * and use external clock pin from it. + * it is parent of fsia_ick now. + */ + fsiack = clk_get_parent(fsia_ick); + if (!fsiack) + goto fsia_ick_out; + + /* + * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick + * + ** FIXME ** + * Because the freq_table of external clk (fsiack) are all 0, + * the return value of clk_round_rate became 0. + * So, it use __fsi_set_rate here. + */ + ret = __fsi_set_rate(fsiack, rate, enable); + if (ret < 0) + goto fsiack_out; + + ret = __fsi_set_round_rate(fsia_ick, rate, enable); + if ((ret < 0) && enable) + __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */ + +fsiack_out: + clk_put(fsiack); + +fsia_ick_out: + clk_put(fsia_ick); + + return 0; +} + +static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) +{ + int ret; + + if (is_porta) + ret = fsi_ak4642_set_rate(dev, rate, enable); + else + ret = -EINVAL; + + return ret; +} + static struct sh_fsi_platform_info fsi_info = { .porta_flags = SH_FSI_BRS_INV | SH_FSI_OUT_SLAVE_MODE | SH_FSI_IN_SLAVE_MODE | SH_FSI_OFMT(PCM) | SH_FSI_IFMT(PCM), + + .set_rate = fsi_set_rate, }; static struct resource fsi_resources[] = {