From patchwork Thu Dec 15 22:14:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcel Hasler X-Patchwork-Id: 9477057 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 4C74760571 for ; Thu, 15 Dec 2016 22:33:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DCF928868 for ; Thu, 15 Dec 2016 22:33:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 30AEE2886F; Thu, 15 Dec 2016 22:33:52 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 AF8A128868 for ; Thu, 15 Dec 2016 22:33:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756342AbcLOWdb (ORCPT ); Thu, 15 Dec 2016 17:33:31 -0500 Received: from mail-wj0-f194.google.com ([209.85.210.194]:35249 "EHLO mail-wj0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753973AbcLOWd3 (ORCPT ); Thu, 15 Dec 2016 17:33:29 -0500 Received: by mail-wj0-f194.google.com with SMTP id he10so11989538wjc.2 for ; Thu, 15 Dec 2016 14:32:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :in-reply-to:user-agent; bh=IGxpgwYmWKlNb/OPi5lYMJJ4d696soQcZrsVpIxVVFA=; b=ZTHBpqUHVKscDBX92o4Ct9Tksaa68I7GQHSn9Gt5ch99ihhVqH6dPZiuyJQh7LZ1qT u9iupmvvf54rrJwNstR4SiF2hTTr6RW9nhPTGV6ElUjpbH0ruBUifBwAzMh2JYip/bzE CEIdAn3Et1IYdcH4uMoVL3Vx4vDY6CmfHSD22sm7jxkS3ry2gmJCBKB3iA/lZrWw/YWy YodYCKue1JJ/GTc8bTdDn5pIL5KJArPU83wI+4YPGhSPk1Gjnu2AMvkZdF4tiJnjEI5y mlM2iWbHAKfRzCscLkv1ClH9ibvfMEuofhavo8zFzIF5gaP56wsDEBiPpCPniHWMt+p/ miOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:in-reply-to:user-agent; bh=IGxpgwYmWKlNb/OPi5lYMJJ4d696soQcZrsVpIxVVFA=; b=qj9XJn30iwzKLxZcH9mXYyVqTuJLOWp5lYLPzUPL9sM0xtjV9qDZXFI4qpG2lhWiGD MDpHyOyyh9wtvt8+siYcbL8KBeQA+/byte/KH1LKpB7EZ67ivjeIfJaowwxRpxqq7RRZ orGpmHTLBXerJVNCMsxeUis4eEJzIwncfLMUKhPQjDxQGdODRk7pK4Zym08dbGZBgknD 9fyFvXpFoA0l22I7BcOdnULbMKQO2kR7zCwntR+XfqTkjPBNmdHSftjct2bIEWNybYIc /16o01Ed+UvqWPOGfUMLNNAmmaVqO1LXShxVFRes8qXQdlaM05C/1pnU63gjHcXhm9oE nODg== X-Gm-Message-State: AKaTC01aIi9149Jx3j6ErskNzHehEFXYxYudFMDQbk4Tm0taGXKdpV15fBZmHRslGfZNhQ== X-Received: by 10.194.178.170 with SMTP id cz10mr3378581wjc.224.1481840048544; Thu, 15 Dec 2016 14:14:08 -0800 (PST) Received: from arch-desktop ([2a02:908:670:1a80:728b:cdff:fe7f:6af7]) by smtp.gmail.com with ESMTPSA id f126sm438863wme.22.2016.12.15.14.14.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Dec 2016 14:14:08 -0800 (PST) Date: Thu, 15 Dec 2016 23:14:03 +0100 From: Marcel Hasler To: Ezequiel Garcia , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org Subject: [PATCH v4 3/3] stk1160: Wait for completion of transfers to and from AC97 codec. Message-ID: <20161215221403.GA18007@arch-desktop> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20161215221146.GA9398@arch-desktop> User-Agent: Mutt/1.7.2 (2016-11-26) Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The STK1160 needs some time to transfer data to and from the AC97 codec. The transfer completion is indicated by command read/write bits in the chip's audio control register. The driver should poll these bits and wait until they have been cleared by hardware before trying to retrive the results of a read operation or setting a new write command. Signed-off-by: Marcel Hasler --- drivers/media/usb/stk1160/stk1160-ac97.c | 39 +++++++++++++++++++++++++------- drivers/media/usb/stk1160/stk1160-reg.h | 2 ++ drivers/media/usb/stk1160/stk1160.h | 2 ++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/stk1160/stk1160-ac97.c b/drivers/media/usb/stk1160/stk1160-ac97.c index 5e9b76e..439d1b7 100644 --- a/drivers/media/usb/stk1160/stk1160-ac97.c +++ b/drivers/media/usb/stk1160/stk1160-ac97.c @@ -23,9 +23,30 @@ * */ +#include + #include "stk1160.h" #include "stk1160-reg.h" +static int stk1160_ac97_wait_transfer_complete(struct stk1160 *dev) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(STK1160_AC97_TIMEOUT); + u8 value; + + /* Wait for AC97 transfer to complete */ + while (time_is_after_jiffies(timeout)) { + stk1160_read_reg(dev, STK1160_AC97CTL_0, &value); + + if (!(value & (STK1160_AC97CTL_0_CR | STK1160_AC97CTL_0_CW))) + return 0; + + usleep_range(50, 100); + } + + stk1160_err("AC97 transfer took too long, this should never happen!"); + return -EBUSY; +} + static void stk1160_write_ac97(struct stk1160 *dev, u16 reg, u16 value) { /* Set codec register address */ @@ -35,11 +56,11 @@ static void stk1160_write_ac97(struct stk1160 *dev, u16 reg, u16 value) stk1160_write_reg(dev, STK1160_AC97_CMD, value & 0xff); stk1160_write_reg(dev, STK1160_AC97_CMD + 1, (value & 0xff00) >> 8); - /* - * Set command write bit to initiate write operation. - * The bit will be cleared when transfer is done. - */ + /* Set command write bit to initiate write operation */ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c); + + /* Wait for command write bit to be cleared */ + stk1160_ac97_wait_transfer_complete(dev); } #ifdef DEBUG @@ -51,12 +72,14 @@ static u16 stk1160_read_ac97(struct stk1160 *dev, u16 reg) /* Set codec register address */ stk1160_write_reg(dev, STK1160_AC97_ADDR, reg); - /* - * Set command read bit to initiate read operation. - * The bit will be cleared when transfer is done. - */ + /* Set command read bit to initiate read operation */ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8b); + /* Wait for command read bit to be cleared */ + if (stk1160_ac97_wait_transfer_complete(dev) < 0) { + return 0; + } + /* Retrieve register value */ stk1160_read_reg(dev, STK1160_AC97_CMD, &vall); stk1160_read_reg(dev, STK1160_AC97_CMD + 1, &valh); diff --git a/drivers/media/usb/stk1160/stk1160-reg.h b/drivers/media/usb/stk1160/stk1160-reg.h index 296a9e7..7b08a3c 100644 --- a/drivers/media/usb/stk1160/stk1160-reg.h +++ b/drivers/media/usb/stk1160/stk1160-reg.h @@ -122,6 +122,8 @@ /* AC97 Audio Control */ #define STK1160_AC97CTL_0 0x500 #define STK1160_AC97CTL_1 0x504 +#define STK1160_AC97CTL_0_CR BIT(1) +#define STK1160_AC97CTL_0_CW BIT(2) /* Use [0:6] bits of register 0x504 to set codec command address */ #define STK1160_AC97_ADDR 0x504 diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h index e85e12e..acd1c81 100644 --- a/drivers/media/usb/stk1160/stk1160.h +++ b/drivers/media/usb/stk1160/stk1160.h @@ -50,6 +50,8 @@ #define STK1160_MAX_INPUT 4 #define STK1160_SVIDEO_INPUT 4 +#define STK1160_AC97_TIMEOUT 50 + #define STK1160_I2C_TIMEOUT 100 /* TODO: Print helpers