From patchwork Fri Jun 24 02:40:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 9196451 X-Patchwork-Delegate: geert@linux-m68k.org 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 736AD60756 for ; Fri, 24 Jun 2016 02:47:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 672C128483 for ; Fri, 24 Jun 2016 02:47:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59A9828487; Fri, 24 Jun 2016 02:47:46 +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=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B4A628483 for ; Fri, 24 Jun 2016 02:47:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752071AbcFXCro (ORCPT ); Thu, 23 Jun 2016 22:47:44 -0400 Received: from relmlor1.renesas.com ([210.160.252.171]:6658 "EHLO relmlie4.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751642AbcFXCrm (ORCPT ); Thu, 23 Jun 2016 22:47:42 -0400 Received: from unknown (HELO relmlir1.idc.renesas.com) ([10.200.68.151]) by relmlie4.idc.renesas.com with ESMTP; 24 Jun 2016 11:47:41 +0900 Received: from relmlac1.idc.renesas.com (relmlac1.idc.renesas.com [10.200.69.21]) by relmlir1.idc.renesas.com (Postfix) with ESMTP id 1345144E53; Fri, 24 Jun 2016 11:47:41 +0900 (JST) Received: by relmlac1.idc.renesas.com (Postfix, from userid 0) id EEE7A8002E; Fri, 24 Jun 2016 11:47:40 +0900 (JST) Received: from relmlac1.idc.renesas.com (localhost [127.0.0.1]) by relmlac1.idc.renesas.com (Postfix) with ESMTP id E905C8002D; Fri, 24 Jun 2016 11:47:40 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac1.idc.renesas.com with ESMTP id MBB20239; Fri, 24 Jun 2016 11:47:40 +0900 X-IronPort-AV: E=Sophos;i="5.22,559,1449500400"; d="scan'";a="213670933" Received: from mail-pu1apc01lp0020.outbound.protection.outlook.com (HELO APC01-PU1-obe.outbound.protection.outlook.com) ([65.55.88.20]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 24 Jun 2016 11:47:39 +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; bh=v1mHMy/7Nw4g9gMPwuKt7w6vwA71XlLpqF+tNomzA9o=; b=JQ+phjGXux08bFimwiQKRelME/8JccxUMSFqqbe1IADjadSK3dZdYxRzKFjs4nWqifkbdxoKfWYldcs8b9UzAhSA1Qav/a45BhxBKzr4z43OWuOl2OzdjGk/qv1FM8H/GFfm+Rte9lpB1uLYuKswrKO9k+Op1pQA+YYP37AUn1g= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=kuninori.morimoto.gx@renesas.com; Received: from morimoto-PC.renesas.com (211.11.155.144) by KL1PR06MB1704.apcprd06.prod.outlook.com (10.167.63.18) with Microsoft SMTP Server (TLS) id 15.1.523.12; Fri, 24 Jun 2016 02:47:35 +0000 Date: Fri, 24 Jun 2016 11:40:44 +0900 Message-ID: <8737o3xqab.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH 1/3] drm: bridge: add DesignWare HDMI I2S audio support User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 To: Mark Brown , David Airlie , Russell King , Fabio Estevam , Daniel Vetter , Koji Matsuoka , Thierry Reding CC: Linux-ALSA , Liam Girdwood , Simon , , , In-Reply-To: <874m8jxqcy.wl%kuninori.morimoto.gx@renesas.com> References: <874m8jxqcy.wl%kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: TYXPR01CA0005.jpnprd01.prod.outlook.com (10.168.40.15) To KL1PR06MB1704.apcprd06.prod.outlook.com (10.167.63.18) X-MS-Office365-Filtering-Correlation-Id: 0549d21e-116d-4b22-5207-08d39bd9e6dd X-Microsoft-Exchange-Diagnostics: 1; KL1PR06MB1704; 2:uPwSJs+bO+MzC981Ya+HSUuWAQWcL/vFHFhrKNTjq13Hn8FuxZPe3fPm0RM8bJSIdnWqXFE4ay+ng83HjYikPFoTtgLiVCScTYyQeb1x3xLX+3zwBO6upSN7xNitSgo0e1MzfWBxRZw/reeGeclm8GNL8n8z8FEjtZEYWs0z8vfPRZcZt44XR1Wwf67lzf1r; 3:YigyiSzoE98FljY41VeYjTrXR1VAT8oZ4xRjseS9Gw4SyP4mgbBiYgq5A5NjfpaNVhe43sLGqmoYWg7EFusXmkaAbn6eZX9DizDcm/i0cZQslduYYG6Z2Kb+p5hAeeBB X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:KL1PR06MB1704; X-Microsoft-Exchange-Diagnostics: 1; KL1PR06MB1704; 25:Pv8f6h8mNWKkUTOKqkwPF53C5AJGPaUYlTCboFlqO8GR/LBEjl4bUFL22Qwl4BZUDBKQsci+acb5v4AqQIAO9f1hS0vxSU/o/gdoDOIYCf4ifq+obZLNC2psLIIqt5Z9NG6+yYrdsr1x9/uzOEYQk/PeGZ9Fo+MSDlRjU6KHRzISyjA/s/j+uvJLOPuV4+5CRGGambwCVAcdamumcvjAVxKHR386xLk0u3ze1qBkktnjJqYbERAJYOP1v8ForzzJ4h1316uqBs1SqMo7HLoTms1DLK0Pbw0RrkLQtdtfsfG4BCcFViTwvWm3IAwZvZQMuF+pOs5XaK9TyxW1JWhxcsdFexeT/ZDvWgaIiA6HoWh8VS/mNPkB15IUu9FcNshL3u6EHmH+vVTDgWdzzkvIWv1jCf2WYCFESTLGzz2H1urFL/p9CmKzzY1WaslitirpyZgyWxG/dy9fMlfesg6SLMzDZRAoICpE3OMhGJBZjUupnwyNzwjC7yH2Se88BhBTYfZkH4zdIxJyTK8297q+vdsrgQxRiyUsN1YJZbjYHcVjY+uT/7QG12ChErm2q+eTzlHK4rPNrFu1tkHC9cBaZMP67FFo4EGkBGoN6HM274pJBD1K8z6tcndjPqDtbjXEeZd0qaNIzIpNLFKzhoqtNAUbC8EDzBanhL6rhBVyrZ6eaFPsw7dXYjSP1gv2YZEH X-Microsoft-Exchange-Diagnostics: 1; KL1PR06MB1704; 20:7YLVd4J0FCVTiHnY1HfeUC6tXL9psqI2SFZjn6e20sRv3oU3IjofM4IDYbRVFeep9IUPN9EWYoEEpNEgXpznaL5y0TH9QKkpaxmbzcPUGSl1vXdiCCd9k8CqjWr2vz+eLesGm1Hpz98xtNYIDqUcHkk44mwEDY3IuzkoQfcErex0u18w5iyYAzY2Ukk1FNpL/TZuTQ6+f9DL+CIOnYSDJdo3uQRaj0upi1WC6aDs3/ksrMSLqytGB07bl16zSaME6btwZ65K3kJCP7Ny/3iFlJ+VzpW9wY/EH2wrGSdPw9hk8g6gCWzEnN/gdwQOg9dmrnVa4IflZXSgcNcNGvxXy7paV7XZMHJ34OgWjE6lCj7JqHLzAAjArH++yIeSNVd09EIrlRgcqhNkV2twcKfoAyJJTVyV7GcVGMjfLl293f/bqDLEUEVemz1msxe4ZHX71gYUuRz/YHcWrGOKLemuG4fw+5O4Meue4TGvQP+CvEEpM+cV9RJboLDwQPDu2s92; 4:nuRiSf/xDrvmesjvmebPn9n6lyqug+Zm0lFfaiAkjvXMAh489QdiL9ZTvlamCXMHYWSvQLxICQxXg6hjgN1yZtpp08erSp5QZtmlzOkPMnoYMVDKuMizJasp+JSACM5P1sLN1O6h7PUKD5jlJq5w9Q4ybFFWL97O14CxpRGSsAg7h1I6B+ERGzNZYKLabemy91/7WMrE6Ts7SwIH+/Cn1rZiKiBbBwXzdrJE34Ucd9FM/KGzBRfgFnAcliSJB/zW5IpVuQFA6+NXteN458p5rGqYkslZucchXLeRcYI5nkss+pxcj3LBATHolh5Ba1niCdhUNiAWpTPFL+rPXEp768l9hLE8Ypip/h+VMjLpTE8MB34GzGbtF6PQ+y8hYSoagmL29e8JlVtDWMz4ZXs4xA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:KL1PR06MB1704; BCL:0; PCL:0; RULEID:; SRVR:KL1PR06MB1704; X-Forefront-PRVS: 0983EAD6B2 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(54356999)(66066001)(47776003)(50986999)(86362001)(106356001)(105586002)(76176999)(19580395003)(36756003)(81156014)(575784001)(4326007)(23726003)(77096005)(19580405001)(305945005)(2906002)(586003)(81166006)(3846002)(7736002)(6116002)(69596002)(83506001)(8676002)(8666005)(92566002)(7846002)(53416004)(5001770100001)(46406003)(42186005)(189998001)(101416001)(68736007)(33646002)(50466002)(4001350100001)(97736004)(2950100001)(229853001)(7059030)(2004002)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:KL1PR06MB1704; H:morimoto-PC.renesas.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; KL1PR06MB1704; 23:zLnvUcopRNAIOBg0EJG3vRc4dg7zSsBP+tCafsRpi?= =?us-ascii?Q?9pbD4rdWFAjM52jjBhTHEWdEXyRvlxDCskPXvaSZtFpZ28cG4PhH2zmVqDg/?= =?us-ascii?Q?o65ztLn6OrshHi737SDS7RNQyUzxdQVVU8sFmZTY3wUWcT5fo3lmg7+17y8d?= =?us-ascii?Q?GH/vLu6VbDFRotbYcziamtiQaGNzrREBgYh27GG8djrC8O26OrQEN5F00cmu?= =?us-ascii?Q?oiqmJKFZtiQXcEfdRj3k58M7keZuZVaFodasc/AX2jY3wvf/izfRtwQopSGS?= =?us-ascii?Q?aNDUZdKXHmQ0F9l84XmBqNh3RxwuoaffODlSai7heemysVkGGV8ZmAGaFxNM?= =?us-ascii?Q?EImG/8FDZBLBEjzyrnyNx97ePq2WR8Ok0Ofav5mgfHg+yEyGjrxxFs+p2izZ?= =?us-ascii?Q?4vf1KM0jhwYQvveg3+SjCH64SIk7mHRfbeUrj/tohXRArT7DA0Rq1uL16xjC?= =?us-ascii?Q?FID3svTVzUm0VqCuX6VYMLv7+piyZtJTs+pDf53ii2LR1mgYNC3tjH3S4NuV?= =?us-ascii?Q?3XwGaTsoTjWAXgRia7hPGwmCAImKQOJI+FcQcJAZhM1g60MFdzpVA9r/ys+Q?= =?us-ascii?Q?eDh46JPwCjdudwkiyUvmpKxpi7SUEXlFFm86bBRLl0in/c6ay9BtJzW399kU?= =?us-ascii?Q?0R19CN8ycEyqxnNkMwdQ6vGJm4Vptls1PnIi18CT9x1MkmGvaI0XPeEdXScB?= =?us-ascii?Q?SrfqwfKBAi8LXR1CoCWuESZcwT0N8RmwF+oRv5KqCHfNXQ3wXxEgz/GfIoUb?= =?us-ascii?Q?ocGwsNaAM0vH67uItufTgyaZaIrRJrotm1Zh4+ipzw2EGyJAVXW9WFnoWvhv?= =?us-ascii?Q?PEXRkcxYmz2Vj4lX/lXJswn8jYJry79guJx/6qMbEKzXpip+IG42ClIlAJRR?= =?us-ascii?Q?ct6dFmNrppT3+/bW4XmAPNtSlWiq79U7h0DgCR9fdDs9BqILEaVTT7v/jnnL?= =?us-ascii?Q?ZKZArcOIpGEbKAuqzhze1agSSQUtqFiQXLJ7Xie3JPwqhsegSwvKmKeuDxrp?= =?us-ascii?Q?5VNTzqvh+O4K4ZIZBv6ClJzSR5PufJVszqzBG6L5903nMJpYAjedgIWdQWdO?= =?us-ascii?Q?UwULj3feBteKXBWxO4Hyh+ZwO9QPuz51xnnedVZUGVZWw98Ww/lGEjEaHorC?= =?us-ascii?Q?R7P/YAFSw4rzBbgacvirBvm21S3QyKdNQ7wBKqfIt+CAnQ9RdCTCR9MIKQu+?= =?us-ascii?Q?odOJplNeNj8yIqdEtspter3PAZaHQBhq2S0I5JpX8G2bvhweifepxFL5NR0d?= =?us-ascii?Q?uBgskaOXu6OXmC0S9U=3D?= X-Microsoft-Exchange-Diagnostics: 1; KL1PR06MB1704; 6:19Nz7OgEynirZtdpnGWQVW24E4UtKSdYXLAJU6Akdf9MZpM8qUQmZBL+iqrvpvu4zHxSwd7BjU2IgoMaDdbrIVY6QGfJ4me1VgpzngJhSjIPyfZOTUXrvGagZusxcuyrrXOr4+gujS1w4VlYe/LcFJI+0Zjgyi0v50BBe+G/WrSFWHmIVEEJ7j4ElNg38w4/3dqE2PlP/EoH8dzXhW1r0nLBp9epg6rDXWGDrYRtKWxJnXsI+yOAVP4CFywuTSxdiYLKa4Qs1xXZdEOcX/NELwMB0um48Ry2cQB056AyAwKK8PFeF4yrjACZLZX9eIkfghdHvUJDxerB8D/K1lGQH0I6i20akrk59grj6lyleEY=; 5:C6J9n8D2+Sil6Qw2olqYQE7pf74+2r3Z7BDrIb0LHeY+dn60IbFfu2mREoalXN+8xYwWnf50Hv0rubszLJNeJYBQdPax+QY7z7mhJz6AjXrtnp1WxsHRxMdzOfbJJNOCkVyetieALLw75CghiA6l2Q==; 24:1TpXI0CeahUlVu3ShXDsAJFSuPifsLsWwJph751wx/ZxckFwk01aNH/ctOo5LDifdFslYERAXG8vMictp8ADyL/XVLL2xOxNC5hMYIYRMHE=; 7:t63rFu3PX2nGSol4p/qalsfMFv7RFjgwoljXvyFZr2atTVncef1oed1kiO3s2ZkNtbdNuTL+WCCf6nAMSD2EDLtExVnaKfmKdxYBl4pfnSbZGwipHviVPVzYVFVzDtroRLd/KVtQ/CEz24TBXYDTmzD3IUd2800AZDE/eusX/ICUd7EuxU+t13vzqR9aFI2sJRp9wlm8FBpBt1Qe6BmBPlxnyPbK50lAPzriZOd3qfaK9gZPTcSVGT5DihLUK/caeZeFyj06C7z1GEy+oX3J1w== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; KL1PR06MB1704; 20:2qof9utj02Re+6WaA2hvX3xuAydZ+FdvGYKUr0/qUqDT+dCFR6zGlESVkrdFA18lbhkINUhvR62PtaGwhqdvRtcb4p8GGWG3I/0NyoYSznWadjRRMzpa0ZT+6s9aGZu6C5HzEP+IuoySNIBvp0e0cGax4RyAmJnOZlei0ehaC+o= X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jun 2016 02:47:35.9853 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: KL1PR06MB1704 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto Current dw-hdmi is supporting sound via AHB bus, but it has I2S audio feature too. This patch adds I2S audio support to dw-hdmi. This HDMI I2S is supported by using ALSA SoC common HDMI encoder driver. Signed-off-by: Kuninori Morimoto Tested-by: Jose Abreu --- drivers/gpu/drm/bridge/Kconfig | 8 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/dw-hdmi-audio.h | 7 ++ drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 123 +++++++++++++++++++++++++++++ drivers/gpu/drm/bridge/dw-hdmi.c | 22 +++++- drivers/gpu/drm/bridge/dw-hdmi.h | 21 +++++ 6 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 8f7423f..8e2a22d 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -32,6 +32,14 @@ config DRM_DW_HDMI_AHB_AUDIO Designware HDMI block. This is used in conjunction with the i.MX6 HDMI driver. +config DRM_DW_HDMI_I2S_AUDIO + tristate "Synopsis Designware I2S Audio interface" + depends on DRM_DW_HDMI + select SND_SOC_HDMI_CODEC + help + Support the I2S Audio interface which is part of the Synopsis + Designware HDMI block. + config DRM_NXP_PTN3460 tristate "NXP PTN3460 DP/LVDS bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 96b13b3..1af92ad 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -3,6 +3,7 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o +obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/dw-hdmi-audio.h index 91f631b..fd1f745 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi-audio.h +++ b/drivers/gpu/drm/bridge/dw-hdmi-audio.h @@ -11,4 +11,11 @@ struct dw_hdmi_audio_data { u8 *eld; }; +struct dw_hdmi_i2s_audio_data { + struct dw_hdmi *hdmi; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); +}; + #endif diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c new file mode 100644 index 0000000..df1519c --- /dev/null +++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c @@ -0,0 +1,123 @@ +/* + * dw-hdmi-i2s-audio.c + * + * Copyright (c) 2016 Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include + +#include + +#include "dw-hdmi.h" +#include "dw-hdmi-audio.h" + +#define DRIVER_NAME "dw-hdmi-i2s-audio" + +static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, u8 val, int offset) +{ + struct dw_hdmi *hdmi = audio->hdmi; + + audio->write(hdmi, val, offset); +} + +static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset) +{ + struct dw_hdmi *hdmi = audio->hdmi; + + return audio->read(hdmi, offset); +} + +static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *fmt, + struct hdmi_codec_params *hparms) +{ + struct dw_hdmi_i2s_audio_data *audio = data; + struct dw_hdmi *hdmi = audio->hdmi; + u8 conf0 = 0; + u8 conf1 = 0; + u8 inputclkfs = 0; + + /* it cares I2S only */ + if ((fmt->fmt != HDMI_I2S) || + (fmt->bit_clk_master | fmt->frame_clk_master)) { + dev_err(dev, "unsupported format/settings\n"); + return -EINVAL; + } + + inputclkfs = HDMI_AUD_INPUTCLKFS_64FS; + conf0 = HDMI_AUD_CONF0_I2S_ALL_ENABLE; + + switch(hparms->sample_width) { + case 16: + conf1 = HDMI_AUD_CONF1_WIDTH_16; + break; + case 24: + case 32: + conf1 = HDMI_AUD_CONF1_WIDTH_24; + break; + } + + dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate); + + hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS); + hdmi_write(audio, conf0, HDMI_AUD_CONF0); + hdmi_write(audio, conf1, HDMI_AUD_CONF1); + + dw_hdmi_audio_enable(hdmi); + + return 0; +} + +static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) +{ + struct dw_hdmi_i2s_audio_data *audio = data; + struct dw_hdmi *hdmi = audio->hdmi; + + dw_hdmi_audio_disable(hdmi); + + hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); +} + +static struct hdmi_codec_ops dw_hdmi_i2s_ops = { + .hw_params = dw_hdmi_i2s_hw_params, + .audio_shutdown = dw_hdmi_i2s_audio_shutdown, +}; + +static int snd_dw_hdmi_probe(struct platform_device *pdev) +{ + struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; + struct platform_device_info pdevinfo; + struct hdmi_codec_pdata pdata; + + pdata.ops = &dw_hdmi_i2s_ops; + pdata.i2s = 1; + pdata.max_i2s_channels = 6; + pdata.data = audio; + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.parent = pdev->dev.parent; + pdevinfo.id = PLATFORM_DEVID_AUTO; + pdevinfo.name = HDMI_CODEC_DRV_NAME; + pdevinfo.data = &pdata; + pdevinfo.size_data = sizeof(pdata); + pdevinfo.dma_mask = DMA_BIT_MASK(32); + + return IS_ERR_OR_NULL(platform_device_register_full(&pdevinfo)); +} + +static struct platform_driver snd_dw_hdmi_driver = { + .probe = snd_dw_hdmi_probe, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; +module_platform_driver(snd_dw_hdmi_driver); + +MODULE_AUTHOR("Kuninori Morimoto "); +MODULE_DESCRIPTION("Synopsis Designware HDMI I2S ALSA SoC interface"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 55e73e8..e9ba59e 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -2013,10 +2013,11 @@ int dw_hdmi_bind(struct device *dev, struct device *master, struct device_node *np = dev->of_node; struct platform_device_info pdevinfo; struct device_node *ddc_node; - struct dw_hdmi_audio_data audio; struct dw_hdmi *hdmi; int ret; u32 val = 1; + u8 config0; + u8 config1; hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) @@ -2185,7 +2186,12 @@ int dw_hdmi_bind(struct device *dev, struct device *master, pdevinfo.parent = dev; pdevinfo.id = PLATFORM_DEVID_AUTO; - if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) { + config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); + config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID); + + if (config1 & HDMI_CONFIG1_AHB) { + struct dw_hdmi_audio_data audio; + audio.phys = iores->start; audio.base = hdmi->regs; audio.irq = irq; @@ -2197,6 +2203,18 @@ int dw_hdmi_bind(struct device *dev, struct device *master, pdevinfo.size_data = sizeof(audio); pdevinfo.dma_mask = DMA_BIT_MASK(32); hdmi->audio = platform_device_register_full(&pdevinfo); + } else if (config0 & HDMI_CONFIG0_I2S) { + struct dw_hdmi_i2s_audio_data audio; + + audio.hdmi = hdmi; + audio.write = hdmi_writeb; + audio.read = hdmi_readb; + + pdevinfo.name = "dw-hdmi-i2s-audio"; + pdevinfo.data = &audio; + pdevinfo.size_data = sizeof(audio); + pdevinfo.dma_mask = DMA_BIT_MASK(32); + hdmi->audio = platform_device_register_full(&pdevinfo); } /* Unmute I2CM interrupts and reset HDMI DDC I2C master controller */ diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h index fc9a560..c8bdbf2 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.h +++ b/drivers/gpu/drm/bridge/dw-hdmi.h @@ -545,6 +545,10 @@ #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 enum { + +/* CONFIG0_ID field values */ + HDMI_CONFIG0_I2S = 0x10, + /* CONFIG1_ID field values */ HDMI_CONFIG1_AHB = 0x01, @@ -887,6 +891,17 @@ enum { HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, +/* AUD_CONF0 field values */ + HDMI_AUD_CONF0_SW_RESET = 0x80, + HDMI_AUD_CONF0_I2S_ALL_ENABLE = 0x2F, + +/* AUD_CONF1 field values */ + HDMI_AUD_CONF1_MODE_I2S = 0x00, + HDMI_AUD_CONF1_MODE_RIGHT_J = 0x02, + HDMI_AUD_CONF1_MODE_LEFT_J = 0x04, + HDMI_AUD_CONF1_WIDTH_16 = 0x10, + HDMI_AUD_CONF1_WIDTH_24 = 0x18, + /* AUD_CTS3 field values */ HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, @@ -901,6 +916,12 @@ enum { HDMI_AUD_CTS3_CTS_MANUAL = 0x10, HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, +/* HDMI_AUD_INPUTCLKFS field values */ + HDMI_AUD_INPUTCLKFS_128FS = 0, + HDMI_AUD_INPUTCLKFS_256FS = 1, + HDMI_AUD_INPUTCLKFS_512FS = 2, + HDMI_AUD_INPUTCLKFS_64FS = 4, + /* AHB_DMA_CONF0 field values */ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,