From patchwork Fri Feb 28 23:41:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Reid X-Patchwork-Id: 3745461 X-Patchwork-Delegate: tiwai@suse.de Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 66A35BF13A for ; Fri, 28 Feb 2014 23:49:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3F6F3202AE for ; Fri, 28 Feb 2014 23:49:40 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 92CCD201BA for ; Fri, 28 Feb 2014 23:49:38 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 60288265FDA; Sat, 1 Mar 2014 00:49:37 +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 71E7E2659D3; Sat, 1 Mar 2014 00:43:22 +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 C12EC265A96; Sat, 1 Mar 2014 00:43:19 +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 AF8192659C9 for ; Sat, 1 Mar 2014 00:42:52 +0100 (CET) Received: by mail-pa0-f74.google.com with SMTP id fa1so173458pad.1 for ; Fri, 28 Feb 2014 15:42:51 -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=GvYNIzvAegrH6ksO9sZM2nlwX3ZW1r4GwMisobf1OJA=; b=NZ6RO3de4HOBFRa4ufvNgb+5cJ8A+M5ennR7ATzPuSwUxIA/u4IM4cMkfmkZYu5Vrq Lt9/njvzSG7zg11tJu7jy5uktW0Fq6DKQhCusMmemMnliP4w1US7fwV+pNbbyuoDPAPT gopzvJsG/LyuJtafwiAlnMELpDuDcZ2SbsN4CpiyUEPnFz2ocSK/xKC6aoBiYhpBqQNu TSrU67ICJLEWCyJaDIks2wLMhVfY0d9DlxSi+75S8JMv4jNiBWW6a0gBhlX18am5XRIw 6whBHIj7QC9ZnbQZtFLKVjnmRkc75cx66PfhZ4qngsDmrFKF3x15Vus6iMQJiXlQEH++ 7O4A== X-Gm-Message-State: ALoCoQk9W+nl5tcSP+8AP7LyLIocxNQql31XaGmYqtnzSIhVLY+ALtpxLuBIVGV0iuMSTwnzIwMrzJadyL4Asf8VXhkTkAyzDEQ12WAXsbRMpOwmRT3Y1g9/H8RC2Q0LTiC8/z+D6t4O79eEjzdNgxO5B7JOaDzg31+6xfNzLpAwEsiRrYQAfcpkzUQfbEGmeUAO1K+8ji2JJzniF99hX96/GApySEhFli81ehcT3yqfYiKtjgvzxUQ= X-Received: by 10.66.141.231 with SMTP id rr7mr2383589pab.47.1393630971758; Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id d9si544676yhl.2.2014.02.28.15.42.51 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: from hojo20.mtv.corp.google.com (hojo20.mtv.corp.google.com [172.22.72.28]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 7CB565A42F5; Fri, 28 Feb 2014 15:42:51 -0800 (PST) Received: by hojo20.mtv.corp.google.com (Postfix, from userid 123195) id 54EAC18113D; Fri, 28 Feb 2014 15:42:51 -0800 (PST) From: Dylan Reid To: alsa-devel@alsa-project.org Date: Fri, 28 Feb 2014 15:41:27 -0800 Message-Id: <1393630893-29010-17-git-send-email-dgreid@chromium.org> X-Mailer: git-send-email 1.8.1.3.605.g02339dd In-Reply-To: <1393630893-29010-1-git-send-email-dgreid@chromium.org> References: <1393630893-29010-1-git-send-email-dgreid@chromium.org> Cc: tiwai@suse.de, Dylan Reid , swarren@wwwdotorg.org Subject: [alsa-devel] [RFCv2 16/22] ALSA: hda - Move low level functions to hda_controller 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_controller. The code will also be used by an hda platform driver. Signed-off-by: Dylan Reid --- sound/pci/hda/hda_controller.c | 177 ++++++++++++++++++++++++++++++++++++++++- sound/pci/hda/hda_controller.h | 7 +- sound/pci/hda/hda_intel.c | 175 ---------------------------------------- 3 files changed, 180 insertions(+), 179 deletions(-) diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index a7c5a5d..bde4935 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1039,7 +1039,7 @@ static int azx_alloc_cmd_io(struct azx *chip) } EXPORT_SYMBOL_GPL(azx_alloc_cmd_io); -void azx_init_cmd_io(struct azx *chip) +static void azx_init_cmd_io(struct azx *chip) { int timeout; @@ -1102,7 +1102,7 @@ void azx_init_cmd_io(struct azx *chip) } EXPORT_SYMBOL_GPL(azx_init_cmd_io); -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 */ @@ -1574,5 +1574,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_controller.h b/sound/pci/hda/hda_controller.h index 3a3d78e..67d9f28 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -50,11 +50,14 @@ void azx_free_stream_pages(struct azx *chip); /* * CORB / RIRB interface */ -void azx_init_cmd_io(struct azx *chip); -void azx_free_cmd_io(struct azx *chip); void azx_update_rirb(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); +/* 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_CONTROLLER_H */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3d6ccb8..4f693ef 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -340,159 +340,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 */ @@ -660,8 +507,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; @@ -942,26 +787,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)