From patchwork Fri Feb 28 06:35:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Reid X-Patchwork-Id: 3739011 X-Patchwork-Delegate: tiwai@suse.de Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BF1279F2ED for ; Fri, 28 Feb 2014 06:48:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9B59D20263 for ; Fri, 28 Feb 2014 06:48:06 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id DBDCD20138 for ; Fri, 28 Feb 2014 06:48:04 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id C4BAF265D15; Fri, 28 Feb 2014 07:48:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id E6A5426596F; Fri, 28 Feb 2014 07:38:25 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 1958E2651A2; Fri, 28 Feb 2014 07:38:20 +0100 (CET) Received: from mail-pa0-f74.google.com (mail-pa0-f74.google.com [209.85.220.74]) by alsa0.perex.cz (Postfix) with ESMTP id 159782650CA for ; Fri, 28 Feb 2014 07:37:13 +0100 (CET) Received: by mail-pa0-f74.google.com with SMTP id fa1so33962pad.3 for ; Thu, 27 Feb 2014 22:37:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FSr5QQxYKoYOpcXw0NDnBMh1GMtnGYBDTF5xt9E+sZ8=; b=e3J9DCjvb1pxu7muX2C198k/6oHLiIC9nCM7o6hJmZRH58Szr6qkH8MKUmW05dUkVX Bj5QG6FqWF/ioShoOPi0T/KDfS56GGpECYi8wMQC/EI8EbMEUZguhYl4TGzxHurld8uC 58sM8kmn/hmqMdWaXMbpluVDzojrnugabYgVOLAo5R6ICuz14t87b4rBMT4G1a3WFtH1 vD9w77exyUCa6yn503afQ04Q7gl7rrrw7Bl49/4FTpB9O1hEXevyEMjr4oAoPgsUYnSr znn50l/yQMra/At01pInmFYS9Tcy+89o+uFEBH2c6HJ2z5HmBQ3z/x78gZkxH2dLfVl7 dbFA== X-Gm-Message-State: ALoCoQkMCyGM8NZOyuqTnPI1S2gsRezGZnk7V0u5JfXv3pU9jW5fBgeWhef4Ep0qXNxOyvWEQKSdwlgdUavFGOnVbAJNIFFRtTNB0I/FCvVcZpssBgZX/E6KsX9y3MhfOm1dYO5ugWbdl5N8ARicx2X74P9u3XA3A1rBleORJvmZrQGbzQAvut54a/HzHwsS17AZ70rs9RA46sCRMpdJabEpJ1wKBNJ8c7DpS/7lfiD8AbpeuEUqtZk= X-Received: by 10.66.140.8 with SMTP id rc8mr443916pab.41.1393569432711; Thu, 27 Feb 2014 22:37:12 -0800 (PST) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id x29si115739yha.0.2014.02.27.22.37.12 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Feb 2014 22:37:12 -0800 (PST) Received: from hojo20.mtv.corp.google.com (hojo20.mtv.corp.google.com [172.22.72.28]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 7394C31C1B2; Thu, 27 Feb 2014 22:37:12 -0800 (PST) Received: by hojo20.mtv.corp.google.com (Postfix, from userid 123195) id 203DF180361; Thu, 27 Feb 2014 22:37:12 -0800 (PST) From: Dylan Reid To: alsa-devel@alsa-project.org Date: Thu, 27 Feb 2014 22:35:54 -0800 Message-Id: <1393569362-27285-12-git-send-email-dgreid@chromium.org> X-Mailer: git-send-email 1.8.1.3.605.g02339dd In-Reply-To: <1393569362-27285-1-git-send-email-dgreid@chromium.org> References: <1393569362-27285-1-git-send-email-dgreid@chromium.org> Cc: tiwai@suse.de, Dylan Reid , swarren@wwwdotorg.org Subject: [alsa-devel] [RFC 11/19] ALSA: hda - Move low level functions to hda_shared X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Share more code from hda_intel. This moves the link control and initialization to hda_shared. The code will also be used by an hda platform driver. Signed-off-by: Dylan Reid --- sound/pci/hda/hda_intel.c | 175 -------------------------------------------- sound/pci/hda/hda_shared.c | 177 ++++++++++++++++++++++++++++++++++++++++++++- sound/pci/hda/hda_shared.h | 7 +- 3 files changed, 180 insertions(+), 179 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ab3c015..7797f01 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -320,159 +320,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect); static void azx_power_notify(struct hda_bus *bus, bool power_up); #endif -/* enter link reset */ -static void azx_enter_link_reset(struct azx *chip) -{ - unsigned long timeout; - - /* reset controller */ - azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); - - timeout = jiffies + msecs_to_jiffies(100); - while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) && - time_before(jiffies, timeout)) - usleep_range(500, 1000); -} - -/* exit link reset */ -static void azx_exit_link_reset(struct azx *chip) -{ - unsigned long timeout; - - azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); - - timeout = jiffies + msecs_to_jiffies(100); - while (!azx_readb(chip, GCTL) && - time_before(jiffies, timeout)) - usleep_range(500, 1000); -} - -/* reset codec link */ -static int azx_reset(struct azx *chip, int full_reset) -{ - if (!full_reset) - goto __skip; - - /* clear STATESTS */ - azx_writew(chip, STATESTS, STATESTS_INT_MASK); - - /* reset controller */ - azx_enter_link_reset(chip); - - /* delay for >= 100us for codec PLL to settle per spec - * Rev 0.9 section 5.5.1 - */ - usleep_range(500, 1000); - - /* Bring controller out of reset */ - azx_exit_link_reset(chip); - - /* Brent Chartrand said to wait >= 540us for codecs to initialize */ - usleep_range(1000, 1200); - - __skip: - /* check to see if controller is ready */ - if (!azx_readb(chip, GCTL)) { - dev_dbg(chip->card->dev, "azx_reset: controller not ready!\n"); - return -EBUSY; - } - - /* Accept unsolicited responses */ - if (!chip->single_cmd) - azx_writel(chip, GCTL, azx_readl(chip, GCTL) | - ICH6_GCTL_UNSOL); - - /* detect codecs */ - if (!chip->codec_mask) { - chip->codec_mask = azx_readw(chip, STATESTS); - dev_dbg(chip->card->dev, "codec_mask = 0x%x\n", - chip->codec_mask); - } - - return 0; -} - - -/* - * Lowlevel interface - */ - -/* enable interrupts */ -static void azx_int_enable(struct azx *chip) -{ - /* enable controller CIE and GIE */ - azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) | - ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN); -} - -/* disable interrupts */ -static void azx_int_disable(struct azx *chip) -{ - int i; - - /* disable interrupts in stream descriptor */ - for (i = 0; i < chip->num_streams; i++) { - struct azx_dev *azx_dev = &chip->azx_dev[i]; - azx_sd_writeb(chip, azx_dev, SD_CTL, - azx_sd_readb(chip, azx_dev, SD_CTL) & - ~SD_INT_MASK); - } - - /* disable SIE for all streams */ - azx_writeb(chip, INTCTL, 0); - - /* disable controller CIE and GIE */ - azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) & - ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN)); -} - -/* clear interrupts */ -static void azx_int_clear(struct azx *chip) -{ - int i; - - /* clear stream status */ - for (i = 0; i < chip->num_streams; i++) { - struct azx_dev *azx_dev = &chip->azx_dev[i]; - azx_sd_writeb(chip, azx_dev, SD_STS, SD_INT_MASK); - } - - /* clear STATESTS */ - azx_writew(chip, STATESTS, STATESTS_INT_MASK); - - /* clear rirb status */ - azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); - - /* clear int status */ - azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM); -} - -/* - * reset and start the controller registers - */ -static void azx_init_chip(struct azx *chip, int full_reset) -{ - if (chip->initialized) - return; - - /* reset controller */ - azx_reset(chip, full_reset); - - /* initialize interrupts */ - azx_int_clear(chip); - azx_int_enable(chip); - - /* initialize the codec command I/O */ - if (!chip->single_cmd) - azx_init_cmd_io(chip); - - /* program the position buffer */ - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); - azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); - - chip->initialized = 1; -} - /* * initialize the PCI registers */ @@ -643,8 +490,6 @@ static int probe_codec(struct azx *chip, int addr) return 0; } -static void azx_stop_chip(struct azx *chip); - static void azx_bus_reset(struct hda_bus *bus) { struct azx *chip = bus->private_data; @@ -895,26 +740,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) return 0; } - -static void azx_stop_chip(struct azx *chip) -{ - if (!chip->initialized) - return; - - /* disable interrupts */ - azx_int_disable(chip); - azx_int_clear(chip); - - /* disable CORB/RIRB */ - azx_free_cmd_io(chip); - - /* disable position buffer */ - azx_writel(chip, DPLBASE, 0); - azx_writel(chip, DPUBASE, 0); - - chip->initialized = 0; -} - #ifdef CONFIG_PM /* power-up/down the controller */ static void azx_power_notify(struct hda_bus *bus, bool power_up) diff --git a/sound/pci/hda/hda_shared.c b/sound/pci/hda/hda_shared.c index 1f307a8..de39752 100644 --- a/sound/pci/hda/hda_shared.c +++ b/sound/pci/hda/hda_shared.c @@ -1136,7 +1136,7 @@ static int azx_alloc_cmd_io(struct azx *chip) return 0; } -void azx_init_cmd_io(struct azx *chip) +static void azx_init_cmd_io(struct azx *chip) { spin_lock_irq(&chip->reg_lock); /* CORB set up */ @@ -1176,7 +1176,7 @@ void azx_init_cmd_io(struct azx *chip) spin_unlock_irq(&chip->reg_lock); } -void azx_free_cmd_io(struct azx *chip) +static void azx_free_cmd_io(struct azx *chip) { spin_lock_irq(&chip->reg_lock); /* disable ringbuffer DMAs */ @@ -1653,5 +1653,178 @@ void azx_free_stream_pages(struct azx *chip) } EXPORT_SYMBOL_GPL(azx_free_stream_pages); +/* + * Lowlevel interface + */ + +/* enter link reset */ +void azx_enter_link_reset(struct azx *chip) +{ + unsigned long timeout; + + /* reset controller */ + azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); + + timeout = jiffies + msecs_to_jiffies(100); + while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) && + time_before(jiffies, timeout)) + usleep_range(500, 1000); +} +EXPORT_SYMBOL_GPL(azx_enter_link_reset); + +/* exit link reset */ +static void azx_exit_link_reset(struct azx *chip) +{ + unsigned long timeout; + + azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); + + timeout = jiffies + msecs_to_jiffies(100); + while (!azx_readb(chip, GCTL) && + time_before(jiffies, timeout)) + usleep_range(500, 1000); +} + +/* reset codec link */ +static int azx_reset(struct azx *chip, int full_reset) +{ + if (!full_reset) + goto __skip; + + /* clear STATESTS */ + azx_writew(chip, STATESTS, STATESTS_INT_MASK); + + /* reset controller */ + azx_enter_link_reset(chip); + + /* delay for >= 100us for codec PLL to settle per spec + * Rev 0.9 section 5.5.1 + */ + usleep_range(500, 1000); + + /* Bring controller out of reset */ + azx_exit_link_reset(chip); + + /* Brent Chartrand said to wait >= 540us for codecs to initialize */ + usleep_range(1000, 1200); + + __skip: + /* check to see if controller is ready */ + if (!azx_readb(chip, GCTL)) { + dev_dbg(chip->card->dev, "azx_reset: controller not ready!\n"); + return -EBUSY; + } + + /* Accept unsolicited responses */ + if (!chip->single_cmd) + azx_writel(chip, GCTL, azx_readl(chip, GCTL) | + ICH6_GCTL_UNSOL); + + /* detect codecs */ + if (!chip->codec_mask) { + chip->codec_mask = azx_readw(chip, STATESTS); + dev_dbg(chip->card->dev, "codec_mask = 0x%x\n", + chip->codec_mask); + } + + return 0; +} + +/* enable interrupts */ +static void azx_int_enable(struct azx *chip) +{ + /* enable controller CIE and GIE */ + azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) | + ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN); +} + +/* disable interrupts */ +static void azx_int_disable(struct azx *chip) +{ + int i; + + /* disable interrupts in stream descriptor */ + for (i = 0; i < chip->num_streams; i++) { + struct azx_dev *azx_dev = &chip->azx_dev[i]; + azx_sd_writeb(chip, azx_dev, SD_CTL, + azx_sd_readb(chip, azx_dev, SD_CTL) & + ~SD_INT_MASK); + } + + /* disable SIE for all streams */ + azx_writeb(chip, INTCTL, 0); + + /* disable controller CIE and GIE */ + azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) & + ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN)); +} + +/* clear interrupts */ +static void azx_int_clear(struct azx *chip) +{ + int i; + + /* clear stream status */ + for (i = 0; i < chip->num_streams; i++) { + struct azx_dev *azx_dev = &chip->azx_dev[i]; + azx_sd_writeb(chip, azx_dev, SD_STS, SD_INT_MASK); + } + + /* clear STATESTS */ + azx_writew(chip, STATESTS, STATESTS_INT_MASK); + + /* clear rirb status */ + azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); + + /* clear int status */ + azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM); +} + +/* + * reset and start the controller registers + */ +void azx_init_chip(struct azx *chip, int full_reset) +{ + if (chip->initialized) + return; + + /* reset controller */ + azx_reset(chip, full_reset); + + /* initialize interrupts */ + azx_int_clear(chip); + azx_int_enable(chip); + + /* initialize the codec command I/O */ + if (!chip->single_cmd) + azx_init_cmd_io(chip); + + /* program the position buffer */ + azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); + azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); + + chip->initialized = 1; +} +EXPORT_SYMBOL_GPL(azx_init_chip); + +void azx_stop_chip(struct azx *chip) +{ + if (!chip->initialized) + return; + + /* disable interrupts */ + azx_int_disable(chip); + azx_int_clear(chip); + + /* disable CORB/RIRB */ + azx_free_cmd_io(chip); + + /* disable position buffer */ + azx_writel(chip, DPLBASE, 0); + azx_writel(chip, DPUBASE, 0); + + chip->initialized = 0; +} + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Common HDA driver funcitons"); diff --git a/sound/pci/hda/hda_shared.h b/sound/pci/hda/hda_shared.h index 8fed6ea..4a35b46 100644 --- a/sound/pci/hda/hda_shared.h +++ b/sound/pci/hda/hda_shared.h @@ -51,8 +51,11 @@ void azx_free_stream_pages(struct azx *chip); int azx_send_cmd(struct hda_bus *bus, unsigned int val); unsigned int azx_get_response(struct hda_bus *bus, unsigned int addr); -void azx_init_cmd_io(struct azx *chip); -void azx_free_cmd_io(struct azx *chip); void azx_update_rirb(struct azx *chip); +/* Low level azx interface */ +void azx_init_chip(struct azx *chip, int full_reset); +void azx_stop_chip(struct azx *chip); +void azx_enter_link_reset(struct azx *chip); + #endif /* __SOUND_HDA_SHARED_H */