From patchwork Tue Nov 8 01:00:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 9416295 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 1759D6048F for ; Tue, 8 Nov 2016 01:01:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0914B28E56 for ; Tue, 8 Nov 2016 01:01:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1A1728E7A; Tue, 8 Nov 2016 01:01:10 +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 AF86028E56 for ; Tue, 8 Nov 2016 01:01:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751227AbcKHBBJ (ORCPT ); Mon, 7 Nov 2016 20:01:09 -0500 Received: from relmlor4.renesas.com ([210.160.252.174]:19206 "EHLO relmlie3.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751175AbcKHBBH (ORCPT ); Mon, 7 Nov 2016 20:01:07 -0500 Received: from unknown (HELO relmlir3.idc.renesas.com) ([10.200.68.153]) by relmlie3.idc.renesas.com with ESMTP; 08 Nov 2016 10:01:02 +0900 Received: from relmlac4.idc.renesas.com (relmlac4.idc.renesas.com [10.200.69.24]) by relmlir3.idc.renesas.com (Postfix) with ESMTP id E851644117; Tue, 8 Nov 2016 10:01:02 +0900 (JST) Received: by relmlac4.idc.renesas.com (Postfix, from userid 0) id C1AB3480A7; Tue, 8 Nov 2016 10:01:02 +0900 (JST) Received: from relmlac4.idc.renesas.com (localhost [127.0.0.1]) by relmlac4.idc.renesas.com (Postfix) with ESMTP id 80C63480A8; Tue, 8 Nov 2016 10:01:02 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac4.idc.renesas.com with ESMTP id LAD26837; Tue, 8 Nov 2016 10:01:02 +0900 X-IronPort-AV: E=Sophos;i="5.31,459,1473087600"; d="scan'208";a="224745084" Received: from mail-sg2apc01lp0240.outbound.protection.outlook.com (HELO APC01-SG2-obe.outbound.protection.outlook.com) ([65.55.88.240]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 08 Nov 2016 10:01:00 +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=xDsR7jGbmDe2P+na1X2WVl2QsJh/g0lEpDwllfOFEzE=; b=ISVZy4q18JAPI1uBhXd4yO9MaKR3ZolLems6TO2xHo3r6ftixNx7ZDaWAGEtpD6uHzignFyKVs3F2vWIxodbYUSeGKWeD5d4w9SAosub6N5dWvGi2vLixpfiVBvNAZchyrf1LQFAtkTM/6pzXFHhX8HMMrIYLxLSqTLnxIFmD6E= 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 HK2PR0601MB1443.apcprd06.prod.outlook.com (10.165.182.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.707.6; Tue, 8 Nov 2016 01:00:57 +0000 Message-ID: <8737j2bxba.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH v4] drm: bridge: add DesignWare HDMI I2S audio support User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 To: Archit Taneja , Mark Brown , David Airlie , Russell King , Fabio Estevam , Daniel Vetter , Koji Matsuoka , Thierry Reding CC: Linux-ALSA , Liam Girdwood , Simon , , , , Jose Abreu MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Tue, 8 Nov 2016 01:00:57 +0000 X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: TY1PR0201CA0034.apcprd02.prod.outlook.com (10.164.90.172) To HK2PR0601MB1443.apcprd06.prod.outlook.com (10.165.182.149) X-MS-Office365-Filtering-Correlation-Id: f5d35d1c-41da-41d9-624a-08d40772b377 X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 2:beroB0YJ9u2/qWcsDeFLxKL2JNt/Y0K3FqZ6L3PixLPr3oaUk6KwJSKTu96sB6U4UiusdKYpYtNzK4A9LPmSLK5Qv+VLnjOO5nkDBgoYX+EoWUTlQqnQOjxxRCl0tVSHfEC9SebJTjhQWkQIPC9EDa+kHb8VvKURvT4a1S4i+bWQlw1IsJVi72mAQGXDMg4GFl6uUE+Ci/jM4xIOiRfHAw==; 3:VwRy6xqbXyemYKZ160BVJqUnfc68YFBT199T4uSdC3TMk1jLzg349zu7b6XChLYsBPnZXyDd/I0wA2ymEzQ9BOL2ibSvSKnDjFVjZPCRoFUPF8ZdLmwwp5st4Oq2SMiXWpYKbMLVLQfMhyNVU6J/XQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HK2PR0601MB1443; X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 25:otZfJAYGoxZ2/pE9MWzy8+qxpqkQSltRlUjsmBX0CcWLDpr84pSCqME2EQHOhiK/wMlHQ2ghBdeaDvNhrBWrrAtaBdwSHrAU8fRDM5ehRTMs3we+yVytK2Wfals6Rsmlt9m6Kuyxnl/hoXdS9/NBZD+SbKRBLFA9qFqewSEnyHfAxu+I4NunDASTuTKK+RLikEM+KDw/oE9thH98YXsbsHxsgCVtKyFY1DoRYfsBrDLUq3JjYbF9y9zF8j+wRsLKDAmHPec4Qj1h5ynoYldFCTFD+VXBG1aYXZI9nzth9LCyLjf6Ova2PAWHmasXf63xaclBE+lQsWUzfTl4kGH08uv9mrJ1lx5JVIelktJdyIBVEEKNcncs7/k3iQWa19KjprnTv+8wqI/gKBtzPpcu5RQfZubS6qVv3sbmkeXW1wqntxngBJ3nUVkiEBmsEPyGiIcSnXwewiX0udnr2ZBbw/Co6i6fVMDnEPRvObujD2ZdwdjSTHgdPjVABuBUWYPiUZpaSC5pP4DAArno4AnGWIUstTkZhNvr7mhotK7BJSMxL7IjjnPoErRP2Rxhq19jzvTRLID1b8PTxEgzrg6cPE7cE65iwcTz43PFkin5vXJaAofDjOkxEb23QBF9IiFPF6TUfR6G4dChS7TYRulfEXmiHMTHBQDbmP9e2Ml6+zRhplcVccECOt4glwbELMHvZ7zBxfwF/TtnoD/MJK9vEA== X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 31:+1ovtiACMr7NWp/vrlozfIe/OQMrnbJHe3HkcCNjEvQ20G53CfCz2ydKFedk/MnaZqRcCcKzdR1HvffLbyEXNIBrkAvuEh6KZMWqvoQkcL1/llG9tHUy69XkHXelpGNpia3WajN9R+QK/F5n7QN0Btqghzf7VbiLvKblxHZIiRo95vg2NAdsnde/S20rkJCROQ5BXZ9ZgbVJbFdkHWwaxCQi4ubLrvd0DnBGwR8KOceyHFNCXf/+9/DdYU+kaLhl; 20:LWHv9TC0HQJgGtEoGLKMtuJ8X7ScwRBxoNNiCaRLur3ONWbJ2cTrZtG+CMhLEgX/yUHdKhlxi5TqoY3JRcfY0DPh1WwphImDHcW5h4gTV5EiMGgy5ZgBs61i2cFJjd6xz5H5DCYrPxo1VTId7r3gsKB23g+aQ/gaZ0Y1c5ryp0VyesJdgAYc1vTxDPggduocLEaYio2t529gBKWPqv4iGFW8J8k6PCX+AAAvRS68v1vP/TgVA4+/c/hbGTHe8GW0CVK3S773+TjynCSb9BmYCF8bj92g454y3egPd1mW9seueSHyZsIz1xB3uiUsY0mvlEZ+ZWy00hpPH5c93RNDySuOdcO0+WSTOjNsVnrYuThbOdRQvkB6221fz0heitx9RSShHJs312NasYQmoqidvAvqkLxorqgeOl+T050xcb+xm1iQkE6XF6qkSRNSzKGSZS5cVm18qT4P95Q8eTZBo8CGiziGtKVPg5FWvH+9VqcCSaOzSLbKBTTErXqkiRwm X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:HK2PR0601MB1443; BCL:0; PCL:0; RULEID:; SRVR:HK2PR0601MB1443; X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 4:HV+Nih3q839yQcAFlFGWbE3a2po6KsUsi+xkahzNII0R8ahE651EjlKIBKOqQ2RMpC2x6J/yIJ9crLxWoRX5EQhWKhL6rQF6X8oWqs9hjSAKL3yJ5ussNFeTuyyJWOXmImkTgZIl86fyA65kVvHcNkqCNYcGddaPaa3TSx8FwbtWcszJh1sxZVACUMQwZp/R8JmFPr+gkhb5ipRGkU9l08fYLhwwWtPuJ9PqEQzkMIPVWDJS7qjmD7zLJRDNW290j8xo0iJr++JOKgVnUSd/0hq/2V6PIentfN8cZdKwMzhBeIxbCJWf9IcMB1FvQ6SnOQ5okstKzbTeB5ljva0WoTHAuXw6Np9MoaZ2zZhhiZMq8z4TO01I5rwb61qq2R5PsLTRYasnrY5Xd2W8ScaGjjfB+qDs/tRVXOz6SUofxLc= X-Forefront-PRVS: 01208B1E18 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(7416002)(8676002)(83506001)(53416004)(305945005)(6116002)(5660300001)(23726003)(586003)(3846002)(7736002)(5001770100001)(97736004)(81166006)(46406003)(77096005)(92566002)(81156014)(189998001)(4001350100001)(68736007)(8666005)(50466002)(36756003)(33646002)(101416001)(47776003)(7846002)(69596002)(66066001)(54356999)(86362001)(575784001)(2906002)(4326007)(229853001)(105586002)(42186005)(106356001)(50986999)(7059030)(2004002)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:HK2PR0601MB1443; H:morimoto-PC.renesas.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HK2PR0601MB1443; 23:7SllqR9znzZIfmcfVcKPiWH8mUUGLra6QSWxB7C?= =?us-ascii?Q?Qo+E6LP/1HcoDEjcu3nkFy+ZKiFcQ5ZzoXIdp8FZahLb/vigaTIxux9EbLsY?= =?us-ascii?Q?ChLsMISjL8rI5ugDWKxBPh3RMxYZs9xbQV1vYKeP4D1qKWYG1zuJTeW/8wxG?= =?us-ascii?Q?B1NhP4YgeV3gjEdTMhkGVWrNm87CE+zwNyvxmICdIopwCg4m3fp/lQRDhd0k?= =?us-ascii?Q?qkQwn7CfErwvqI+OUwd0XgO6BVz1iE2lW1Jmn9yMMlMDLCUiytbvzUWa1FUo?= =?us-ascii?Q?d8e7HSwgElailj3Fp9Ku3hS7kzrLzPilFwb/vbAsqw7AKO+NG1LCJQgiLreh?= =?us-ascii?Q?duxwtORQpEKir0WniZg8d/2oAZSgL3nUqwfin5u2KnOzURViVjWkbonkLIzu?= =?us-ascii?Q?CDOjG2n5RXc3tQlESjGG+vBbVuHPSTKKRsarg3WDKzB943vs5PYqy8qINdxr?= =?us-ascii?Q?D5jJJrzKzchQXc7Za/IYg2imruSthLfZ9KDfkfvow+EsLjnacdysrENzHtnd?= =?us-ascii?Q?lhy2uP6o6DkQf/5URDj+g27vXg6eEH6TPwpAMf7bJbiAU4ewvdd9UxX0yIHS?= =?us-ascii?Q?9g4NzFKP1usoHyWYewWrdAs9sKBvsjyN/N2DRDSq3wc0l0KrVedMCYvwGVTC?= =?us-ascii?Q?sISKzpKfJojzy+AQiBrbdsoFV1FpZf550Dg7kXsjv5NMoaMY0otoEWsH85O7?= =?us-ascii?Q?KYCAChgRvLoVNw7gqpailH3tKfQFrUTCKy+fyeZVJ9p4vusFF7lF0iqYAGfj?= =?us-ascii?Q?RhZh6gE9/sIBghMRCD87scc/eZyRngT6EU+XrB0JfWNrJEvrPEsmkTz5Iipa?= =?us-ascii?Q?P9aeRrpHXoOqSwlqUeI5oYOTMoN7zstW9OHo29Brg8bTgvGwld+qkP20niEq?= =?us-ascii?Q?2BfdMnkxUOlm6VHK5oc+6LTDYM673CgVLDpn+QeJIwZk6K54aU1h78T7wVKt?= =?us-ascii?Q?/DNxMrwKYNC0BWbZYsBjRJ4oq9Tr91MuZV2o6QpLu8a+5nfHjD6TehthIhE+?= =?us-ascii?Q?wDqeKGcdPSHzuVgT8w5yD4PmvY2QYiFEMHCz3e1jqNN3Vv0OLi+5oGvFPa0w?= =?us-ascii?Q?sXowM8p0bdQUTj04KwapH1HmjXI1jlzcxCLtCYXaeqfmhBKY8r0xtVcQvzO4?= =?us-ascii?Q?dvFrdS8bSsENTnpgkJUgTjo8NeuLsy5u++/cna11uTNsOkMj66PIjVrB6jnc?= =?us-ascii?Q?53KpntDHmn6ICJs0wc+q9FHPmNv1vpyvOHyWD?= X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 6:hvz5LRGoKLz2sbAJPl9rn40Mb7RMrl1uo64yLNJQPFeL/p8RDx61kVi1aYA/U3MPGrPeZ+7zZ5cW/Lq+ygRK/AUoFI+5YFbxTWXnZpilJZN3nVv3rix3WpCQJl60AUorZmCYuUGf9iBypy/6GVurx2E6fXT2fnwxI5Weg7uTySVhOjey66CpVJbq3xWoaSCGsyrxicIsBa57P1vKPGLrxJ1O89EQVxoK1dsJljHXE4SedwdE34emJ99Dt7TuKual0SvRsHVkGQcpuWSuLOmzsuOYdqejoTHjdofv6TA70+W5ja5sZGP4LZJCzz6yhCvp9X1+o2NkEslufBujhRfHWBgfRP6CeQ4SslOa3bqCgyc=; 5:WmnpEuIWw6hqchBbWLKwGpM+YlFn8IbiDlAqhJFvC4TQBBZnoDnja1X75VbSVkUB+8vCSn5/sNI8kXUr6XL4NGbYgcRvtypyV5pUV39BtcEj3K0GlhbRsg7in47vJlm8cgfEj/QGsdRVpvpu+vPgRw==; 24:TARKvePjoiWJAglSDdhluWpt1T/m+VwI/+YjP0QSxrINkoYclnMsGMIhEVGlxdLnvIL0U61SY8PNsXXwOLTLN6y1wR9Ha8XXBJFc9SRWw8o= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; HK2PR0601MB1443; 7:mKWKyrrUvNyKbJ1WK5q1zlg+OrztR/dGmxg/wW7Lq7UDxAmjwCrpRn/AmDBQAqNIx7gRk53tF6L/M7McT0jHqlo5xLq8nPdmx+qRLdTMyfyhVFo4ydk+b/Xb4B5G9nhPhgqO73Y9+5LUQdKSIsDe/+nZExcREUrFwtGtDxJ6ltfpRS6NvE31vme8x5+ciywnEjrHjNcnDyHD3D+l9TjuhgPrm196IBkdkHCox6gMzoce4KrR6G1hM/HPAUrvlVBkSh/YkrGWaUxhNCSLeI+jiIV2PrcPz7GhWN1s7cxBHyS04BnHrqfC+SIEGVC3OmXQ3eLhe1x7FDm14UtskkHQIuJERWi4+Rr2sWHZCrhPHAA=; 20:TgXK1JkyOG5Bu8GqQraQcCvZ/UhnyYG9p/6pVuO1pnj/+kLZ50ckgBaTT8FJM245BJziBNpu6E3NZ7GaHaQ6VCSqRaqtiBMLxq0H4gBzbPSfDTnbAPcxdzbX8AwluTQCdj3ob7ssxY/ZdBcWk0CGHM8tiIb1AXeCC54FQnrCVKw= X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Nov 2016 01:00:57.4015 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HK2PR0601MB1443 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. Tested-by: Jose Abreu Signed-off-by: Kuninori Morimoto Acked-by: Russell King --- v3 -> v4 - use IS_ERR() instead of IS_ERR_OR_NULL() on probe() 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 | 142 +++++++++++++++++++++++++++++ drivers/gpu/drm/bridge/dw-hdmi.c | 22 ++++- drivers/gpu/drm/bridge/dw-hdmi.h | 21 +++++ 6 files changed, 199 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 10e12e7..3129f8d 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -39,6 +39,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 cdf3a3c..9a54f2a 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.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_SII902X) += sii902x.o 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..79391c0 --- /dev/null +++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c @@ -0,0 +1,142 @@ +/* + * 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; + struct platform_device *platform; + + + 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); + + platform = platform_device_register_full(&pdevinfo); + if (IS_ERR(platform)) + return PTR_ERR(platform); + + dev_set_drvdata(&pdev->dev, platform); + + return 0; +} + +static int snd_dw_hdmi_remove(struct platform_device *pdev) +{ + struct platform_device *platform = dev_get_drvdata(&pdev->dev); + + platform_device_unregister(platform); + + return 0; +} + +static struct platform_driver snd_dw_hdmi_driver = { + .probe = snd_dw_hdmi_probe, + .remove = snd_dw_hdmi_remove, + .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 ab7023e..30a2e16 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1639,10 +1639,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) @@ -1770,7 +1771,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; @@ -1782,6 +1788,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); } dev_set_drvdata(dev, hdmi); 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,