From patchwork Wed Nov 2 01:18:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 9411707 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 D10B160585 for ; Fri, 4 Nov 2016 01:14:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3BF62A397 for ; Fri, 4 Nov 2016 01:14:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A80CE2B035; Fri, 4 Nov 2016 01:14:03 +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=-3.6 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D10E52A397 for ; Fri, 4 Nov 2016 01:14:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A161E6E895; Fri, 4 Nov 2016 01:13:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relmlie1.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by gabe.freedesktop.org (Postfix) with ESMTP id 7F6946E422 for ; Wed, 2 Nov 2016 01:18:42 +0000 (UTC) Received: from unknown (HELO relmlir1.idc.renesas.com) ([10.200.68.151]) by relmlie1.idc.renesas.com with ESMTP; 02 Nov 2016 10:18:40 +0900 Received: from relmlac2.idc.renesas.com (relmlac2.idc.renesas.com [10.200.69.22]) by relmlir1.idc.renesas.com (Postfix) with ESMTP id F10394C4A1; Wed, 2 Nov 2016 10:18:40 +0900 (JST) Received: by relmlac2.idc.renesas.com (Postfix, from userid 0) id EB18E28084; Wed, 2 Nov 2016 10:18:40 +0900 (JST) Received: from relmlac2.idc.renesas.com (localhost [127.0.0.1]) by relmlac2.idc.renesas.com (Postfix) with ESMTP id D43F228076; Wed, 2 Nov 2016 10:18:40 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac2.idc.renesas.com with ESMTP id LAP24743; Wed, 2 Nov 2016 10:18:40 +0900 X-IronPort-AV: E=Sophos;i="5.31,582,1473087600"; d="scan'";a="224560721" Received: from mail-pu1apc01lp0017.outbound.protection.outlook.com (HELO APC01-PU1-obe.outbound.protection.outlook.com) ([65.55.88.17]) by relmlii2.idc.renesas.com with ESMTP/TLS/AES256-SHA; 02 Nov 2016 10:18: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=+EgRb9FYYdLSWP9EKL3u464LdN9pP8lIGVjLEWW+lVk=; b=lgmOWYHQ8epTuZ4OGe9tjbbDjMe+2Z8bqKgCtaI+BgPB0N5xQ6XKVBygWlOVQwEGZsfpmZ3pTCosHhtMQvAGjsNcbCYSElD0b6IyZyzLb3XEr7sc/UgqQ1/H8NhdqJ0HLprssURTG8vlxbFfJETaRbZFx2MTuEn+2buAnyq23xQ= 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 KL1PR0601MB1446.apcprd06.prod.outlook.com (10.169.69.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.693.12; Wed, 2 Nov 2016 01:18:35 +0000 Message-ID: <871syu4r3x.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH v3] 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 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Wed, 2 Nov 2016 01:18:35 +0000 X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: TY1PR01CA0123.jpnprd01.prod.outlook.com (10.167.154.41) To KL1PR0601MB1446.apcprd06.prod.outlook.com (10.169.69.24) X-MS-Office365-Filtering-Correlation-Id: 020bdf29-31d3-414f-027c-08d402be2c27 X-Microsoft-Exchange-Diagnostics: 1; KL1PR0601MB1446; 2:qwuMLpyPudSqu8czT3kBm0jZ7WXNlI39FiG7HFj2Hub7ez0XwfDrm05FemfliDxYJa/yT+CCUs6dE93U5ClLZR+uT6S3x1FL1OHbhCK2r87LDRIKHr7kBeXnXoO3kRrIs39p+dm+BLDdc4W9b4nje3mE3bexHfx9mLbBegY8ch0FqRJ0yw3da8EcAH7xelere5NhPXxKRYdvG9hNmMNQNg==; 3:QdrqmfuropgPTknTC+sr8LoHYlq2A+FzMq7TbSHx/U9bjQLvL8fk2aSO5odKKiLwdTAROi8ZObUxREca79F5MDitDxD+pH5+Rmf3KcqpzdhknfvIWbR1IC/exmNIvHheRKpxdIRF5dp59VHsQ84jmQ==; 25:1wkY0GxHSfGWjzCmVIBj0E0bqyOsFWKLbAR6WjE/PUHoKxWchngu6G3CpJ31Kd5eR7bHJixfT7Fao/2+sUcaSy67x+GUKQQYU5nhYZrfYU2nHP/P3HFtRo6z4GZgwr+j+wmKUb1RRA/te89wqi28eJpfPyut0s+wv6qZYdyLr6fNK55eLlxCl9ydRMdMpnfITUEQgnN7vm5tVBEKvZ0HIjjLe+IzL/iA9oJLY2ImJdoPl2kSasl5u5KZK338BN0jrOz3PcRTNNMFxyL500dzJddaOAlPmjQt+dWrU2D4y5x8g+zNqXv8eeUZpy8KECsjWSTsnMGXIueo2i9LzrmufPDCwS3b/QHdMfxxivL6ltBybVvLdcT26vT50QzU4YK7ZbsetDsL/4g5Coe3U8Lfur+l+JZlz79UPo03xI9V3SXuxZvsyq5hJPl1F4XG0jLe X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:KL1PR0601MB1446; X-Microsoft-Exchange-Diagnostics: 1; KL1PR0601MB1446; 31:Nv5r+ArnDrSy1K1tG3QMLowOrraJakPPhIj1bpOX9Ch8WYNogmUZKwO0w43Fy4z9aXpUz/k8k/sx/udP56Cynrz6LNKY6kfzi+NSvCNA+PZbndMSGf4X2q9yyHWkYJRFSU820MRRfA/rOQwfU7FiEqb4GQdlBUA+vvwP2LSsOc0fGc5Xz1LmAj2beIxBJlvQM9ZAja7gWb1yyMKXN2UPTMVJZ52tJa133c6VzKdhtm6HSezacokEE0caQeiEQ/tg; 20:jFdzvzNlhkU8RhEktqtj13Lt0oTyxDGahAK7C/lO1DFrFg9kEloEbRdGPwYMsUO3SQQdeJ2Mmn7UYWW+DOCDLkbiWNTZ5EvrbSWUvl7FG0zLkFXJj7uti3+ZpQ7Egmq1MyPfVEMhqaFizDi4CtO/5Rq7BuFWJe53dvXVU9LtZV+TPUlEIlwFaz+8cRnOe/uujCzIp48rV6bqi06fmn/F/cYuXvsgV5MUx4E1mXrQ3qmAvqKrFpfEuDEs4ylgyR9/0CQ4/RrRQCdchbI98+J8zsOtBRe/i6/g3Q5MwMcra9ElBKqay9xZSeWr1g/HL+QrEmjh7T61bIC/Xwv6OHasfhsgAmw4rAA/L9nOF6zh3cnwo/7xncWUpHoFYNU5uR82g8Hn41ub8SYxBKB/3jgiVXm5iLIArzn+eHKbqnZIiboYhWB4cjt8stmVXwCVaKBC9pN0KIFU/2rFu8lbPlqGkcWPd8vsshqUhfuBG5UbxeJvmcUA/a222nCqdgcXkzWK X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026); SRVR:KL1PR0601MB1446; BCL:0; PCL:0; RULEID:; SRVR:KL1PR0601MB1446; X-Microsoft-Exchange-Diagnostics: 1; KL1PR0601MB1446; 4:pnAKpMAqlSouTYOKS7s0BztYX8sDT1jEQeebovlLqZ5iQ9j//M1Y0AvOQTC8bV5U6DSYQ2LUJNiplMC2wkFi63EzSJPjFxPXw2uPymKai8tsBcmFHiFeQknyxTH0Fql4ZWtRIcLVIdXxqF3RK+rUJLdoejzFL8KrqYJEhjFuOmkTb1uvPyeyK1cQH7f5/gkIJ9iPPTbOH5eblD6VWT75CObozIUEHKcUiFbY3UM5z5uqFb0WGB1XhaLGXS69Zq3Bsc5A74jS9QpRnfrSF+nNa/MmGAUPgCO5JdjsSmabb+dvjMiyiia09+pBZnVvrv4NwADmWm4eudEJugZz2eDflsQZN7dp5XTJJKFrXFZrk9fOHf4p3pLuvDgvYQqrbecrEgWVA79MtwefG3vy9CiKu+C4sVNDx+uo8gDIwSOLnHA= X-Forefront-PRVS: 0114FF88F6 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(305945005)(36756003)(81166006)(81156014)(50466002)(92566002)(33646002)(42186005)(69596002)(19580405001)(229853001)(8666005)(5660300001)(19580395003)(23726003)(3846002)(8676002)(586003)(68736007)(53416004)(7736002)(7846002)(106356001)(46406003)(6116002)(189998001)(4001350100001)(50986999)(77096005)(5001770100001)(105586002)(83506001)(54356999)(66066001)(7416002)(2906002)(101416001)(47776003)(97736004)(4326007)(86362001)(575784001)(7059030)(2004002)(16060500001); DIR:OUT; SFP:1102; SCL:1; SRVR:KL1PR0601MB1446; H:morimoto-PC.renesas.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; KL1PR0601MB1446; 23:1UxvuDQu5/N0+wpeWZ/ME6hXT0ZSX+a28+L+IBF?= =?us-ascii?Q?yAcfygnDYBguu1LYHMdLQRuB29WIORfxBOZ+NoxFqoN8T692sdk8Kom5fraO?= =?us-ascii?Q?d9HVjnw7pwDm6zB4AimF7rYwguNkRd/OMIFJ6CZn4SAD/fVA43kFEtDA1RUQ?= =?us-ascii?Q?QlNyozjJ2jc4mApbJTJF3uMsIGgolCyVnTHtpYrMCRiG2SPUQsTZAxL/C6C/?= =?us-ascii?Q?6IGnLjLrLd/HhOz8VD3WdRv1R4BkqpZW7GwHFEESIoNRTRzfewhM3KMkzvBi?= =?us-ascii?Q?HrDk5bWNb8f1wTEJy0+YMTmLycWNWf6m/LUyA9RIBWNLFpFcVXoW2ePcmMpZ?= =?us-ascii?Q?6LdCMy/ZkK/j/P8aUTB1zsCORwUc2+YFbOna6tWw4BzU7vE3KaZnHhjmRkDy?= =?us-ascii?Q?lgjXOTOVpzR58ORqdxSLCvf+uK/FdeY1TNDKcx5sPYglXbmo90WUpcwJeV+L?= =?us-ascii?Q?4VP5JxX+2dqhRGcZqizneX+9xytFlaA0eoiACBx6QGVyC3JGNb1Xk96vBObI?= =?us-ascii?Q?ZX+rdJTHHj25wZyb7vtxRzuFftx1AmwSXK+e9sBxnKmd4QIe91e3GlBZLd/x?= =?us-ascii?Q?3BQxk9ZyUYzq8tlv43ksSwBB8x+JTeCdYHu6APF6I4k8r0Z/AQ+ZJ8eUNAP7?= =?us-ascii?Q?5mw9k8eNF/xdkcE83cTZCUBQdolqPQzHQpN63sqoH7GQuyKF9NfWm69ZxbjM?= =?us-ascii?Q?n/G76ZrOxdDP3m5SDtsaq9ABg9ykSHJyaBmS3geN5ovsW/uMXhqDZRA9aTff?= =?us-ascii?Q?hyuTG94penO97eE2FkcaJxO+KzHqW+6CsIPRzQKQ1Q98YOMwAnDf8vTMFvZr?= =?us-ascii?Q?nKHZgcrmKG06nvDm5SayMoPqJp3Lj15VTtUC/9VNB5M2daLumN8N9i9RG9g3?= =?us-ascii?Q?R/3w0UyogB/Dm3R4gRDXdh0et84fChT5Q3INBhzmraMdGjzoZh3CsG2UBmhN?= =?us-ascii?Q?Me5kzuAsbREep0g2rjmSzsRDMCGzEgX5u2+mgOoSiBF6L3klIxXhLw4nhqZa?= =?us-ascii?Q?5iaJkaGshRCUOwKztzVz1EPrf+EvV2CTcCyRliAfTL3OmEOHp6Qm1fa01jEl?= =?us-ascii?Q?vply6EU1r2/AXHl8o4cIYIekSFbuVR3Dd0fGyO+/wPPbYzf9k/6RMRPQI6yn?= =?us-ascii?Q?sPd0j4VJRcLnmWCZPILM6KoR4S2k1Nr1J4qUiQoOjZU3ndBBG1+wkF3IO8i6?= =?us-ascii?Q?3lozob8BBePUg0cDH/sr9BbV7Lv1jQAFkGczw2PGcIW2AblUA2jjbmWK0iVg?= =?us-ascii?Q?mAZEurnl+lCggRzPQKPs=3D?= X-Microsoft-Exchange-Diagnostics: 1; KL1PR0601MB1446; 6:TNEc0MLUfXnm4K8n8ZtlciWCkWHB66uM76VkI3zsedXRdZUq3LPySvf8AUHOrTN+RgoszccWXJcYfqrwleI/3+sUpMktEA+kPqvxyDGovLamsLvMt7zKjWvV64vppm6+Vk8IuF5FHBwsz6JL4+/BXGJrKcaLTgvlfS3qsHSZ+iwp8BdETOc2ZF5yzXbQFBuK9nqdyQ0BKVq7hf9nr4OpNzvOZa6QfIcPFPnyJqkR+wsJ4PBGDUaFoCRXBThvpAUauip7nwbtcrWWwKuYU4XQOc7TX/2vVNwXIyrgiB5Vh+UBou+XqsOMZ6WtrjkG1wo369Ttl2lyFn9F3fERk0aJXPnyXeSAIrGLLThSV9bxKEw=; 5:fgbwkBWFJVpxXJ84dx9NSG98E/dqMYvoTzjJpgWluXcy4zVuT7hDMOXj1uOZITBHk3GZ2IynLwbKXOAQFULvtjGUaFkgHkn9QHt12vQ8P5b1rcIvC5elLprYYjPw+4P1calQqd09kFHw+EpkHrWLjQ==; 24:cw41jPrde4Bj5jWHjRiS1TXKHMSmFPcukjdgyISbFKx53U7x/MwaCVTMasd8ftSW9V1uqf/btIeqDE+r3v8fRPY/JTASAOlz3JBepwdFL5Y= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; KL1PR0601MB1446; 7:xeYbyUZ9Hb7X+0Q12mv8Sg+GHgFvoV+ySdeOnL/J2NDPR4EgejHR6+fwpvHXCpegpCEPV+X4CH8LXK++iWIX9pDM/xkPMpKne3UvUMAi2wX5tlnh+jclbqLhKDO9nNA5kqIU62KsaQbZIWbhpwBQ1pfT6BAarovfgEm9YPPwpHduDUYEb/OnRmHcdnIL81vU3AcblZRnaLjBFSxbuiZqUnMbuxDNl74SSR4tSjAbuSYMejEDcPQkBWokW7xOVIVPhatZ163B/2YmHkzBGYGBI7B6Jw5kLC29ijHT+9wCk41IGjrv5iKi+CvTD/vOQwuSWO3DlFJO9PIghlUm3cNdne0Q/ybHaaSaeLUkM4Fsxww=; 20:f1D9I5zQPhEJyHAkGPz/Tnt4rAUsuHhWslrZ7lIRU9GtNJx5dCq9JtTBvlOv4nGmWK6ehBZ8G3skjGPDRVV7mAqLvx1UiJ/Jr7u3xcm7mnlCe3Ir6P2r2HuoquzFAInGoAXivxqc4m5Xzev3nQfY4WZ7/Xg6G2O0vOXWkz4sz/8= X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Nov 2016 01:18:35.4470 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: KL1PR0601MB1446 X-Mailman-Approved-At: Fri, 04 Nov 2016 01:13:04 +0000 Cc: Jose Abreu , Linux-ALSA , Liam Girdwood , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 --- v2 -> v3 - add .remove and call platform_device_unregister() - add missing Tested-by: Jose Abreu on log 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..44880d8 --- /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_OR_NULL(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,