From patchwork Thu Oct 27 08:19:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcel Hasler X-Patchwork-Id: 9399497 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 CAB1560588 for ; Thu, 27 Oct 2016 14:25:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B0AD72A2FA for ; Thu, 27 Oct 2016 14:25:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A58EE2A2FB; Thu, 27 Oct 2016 14:25:45 +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 443592A311 for ; Thu, 27 Oct 2016 14:25:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S942063AbcJ0OYr (ORCPT ); Thu, 27 Oct 2016 10:24:47 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:34415 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S942563AbcJ0OYi (ORCPT ); Thu, 27 Oct 2016 10:24:38 -0400 Received: by mail-wm0-f68.google.com with SMTP id y138so2973731wme.1 for ; Thu, 27 Oct 2016 07:24:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=+/l4/8Zosdx+k0XYB49tdaJD0A9O0RnLt8nvU2+JX0E=; b=tj0HiwQ4z0NZy23Al1w7MbJMNeXh2L5ZZtnhY2OhoPIUsBUXCYI/QdszNiAACgooFl aA58a/q2RD4BQd9x3N15BpE72t5IG0FXZvljRVNdaeMxsMsIRonmTkSDSy9kMZYp1oJf 0GN3jvWxC4x896ntNl4mEdCTM9rIma/dVqti85/5C/doqsVNEDbcKVL4xMkM8QTgkt0b PGwxcmNyoFHyUhEajP1MDk97iN4odVr8mttG+ldL0U1NHEXF/+FYAknQ6j6238ytaLhh plZlUHmjUXv5Q5CE1fcI4k0IGAh30s4qb5T+SiVEwiSDySXm4Lv0OjONBlUGRmpjvBKK jViA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=+/l4/8Zosdx+k0XYB49tdaJD0A9O0RnLt8nvU2+JX0E=; b=ewus56nNFf6g+9jA7XqGAbzXfZbVQ8ef40B9FD0poMms4yl3Qj4YIES2i1ZzxwTXtd CDu/0ICBN7dxhFVwe7Zg0YWrIx92yH0Hj0VaqnlVpeKxlXSvZ7ZzRdJqWLDbiI1f7q1I Si+n60TrdOcg0SOxaO9q++DXHWIFBshyWg9MA9ZbNbPzyEsnCEDEe6BYbj3NEuzJf9Pu seocMyhSCDznu06HqTzrCEs05zrGdefCV8bZwqLgcHXoZnAXTsw0DT2Pk5Z3jWaK08GC 4cRYO48M/EsVHXUCeXT7M5j50allsPcnsm62vJrw8qoE+/fRzhUUAtv39LyGZz1NeoBF mJHQ== X-Gm-Message-State: ABUngveeiIYEeKVmynqc5D9BCUMU+ollcBCG7Fq3VZ/T2Fd39EANHcYSSR7LUrcN4Fxx9g== X-Received: by 10.194.99.69 with SMTP id eo5mr5508919wjb.138.1477556388755; Thu, 27 Oct 2016 01:19:48 -0700 (PDT) Received: from arch-desktop ([2a02:908:672:a420:922b:34ff:fe11:2b9f]) by smtp.gmail.com with ESMTPSA id p9sm7082451wjs.11.2016.10.27.01.19.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Oct 2016 01:19:48 -0700 (PDT) Date: Thu, 27 Oct 2016 10:19:42 +0200 From: Marcel Hasler To: linux-media@vger.kernel.org Subject: [PATCH 1/2] stk1160: Remove stk1160-mixer and setup AC97 codec automatically. Message-ID: <20161027081942.GA1511@arch-desktop> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) 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 Exposing the device's internal AC97 codec to userspace seems rather pointless. Instead the driver should setup the codec with proper values. This patch removes the mixer and sets up the codec using optimal values, i.e. the same values set by the Windows driver. This also makes the device work out-of-the-box, without the need for the user to reconfigure the device every time it's plugged in. Signed-off-by: Marcel Hasler --- drivers/media/usb/stk1160/Kconfig | 7 -- drivers/media/usb/stk1160/stk1160-ac97.c | 121 +++++++++++-------------------- drivers/media/usb/stk1160/stk1160-core.c | 5 +- drivers/media/usb/stk1160/stk1160.h | 9 +-- 4 files changed, 45 insertions(+), 97 deletions(-) diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig index 95584c1..53617da 100644 --- a/drivers/media/usb/stk1160/Kconfig +++ b/drivers/media/usb/stk1160/Kconfig @@ -8,13 +8,6 @@ config VIDEO_STK1160_COMMON To compile this driver as a module, choose M here: the module will be called stk1160 -config VIDEO_STK1160_AC97 - bool "STK1160 AC97 codec support" - depends on VIDEO_STK1160_COMMON && SND - - ---help--- - Enables AC97 codec support for stk1160 driver. - config VIDEO_STK1160 tristate depends on (!VIDEO_STK1160_AC97 || (SND='n') || SND) && VIDEO_STK1160_COMMON diff --git a/drivers/media/usb/stk1160/stk1160-ac97.c b/drivers/media/usb/stk1160/stk1160-ac97.c index 2dd308f..d3665ce 100644 --- a/drivers/media/usb/stk1160/stk1160-ac97.c +++ b/drivers/media/usb/stk1160/stk1160-ac97.c @@ -21,19 +21,12 @@ */ #include -#include -#include -#include #include "stk1160.h" #include "stk1160-reg.h" -static struct snd_ac97 *stk1160_ac97; - -static void stk1160_write_ac97(struct snd_ac97 *ac97, u16 reg, u16 value) +static void stk1160_write_ac97(struct stk1160 *dev, u16 reg, u16 value) { - struct stk1160 *dev = ac97->private_data; - /* Set codec register address */ stk1160_write_reg(dev, STK1160_AC97_ADDR, reg); @@ -48,9 +41,9 @@ static void stk1160_write_ac97(struct snd_ac97 *ac97, u16 reg, u16 value) stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c); } -static u16 stk1160_read_ac97(struct snd_ac97 *ac97, u16 reg) +#ifdef DEBUG +static u16 stk1160_read_ac97(struct stk1160 *dev, u16 reg) { - struct stk1160 *dev = ac97->private_data; u8 vall = 0; u8 valh = 0; @@ -70,81 +63,53 @@ static u16 stk1160_read_ac97(struct snd_ac97 *ac97, u16 reg) return (valh << 8) | vall; } -static void stk1160_reset_ac97(struct snd_ac97 *ac97) +void stk1160_ac97_dump_regs(struct stk1160 *dev) { - struct stk1160 *dev = ac97->private_data; - /* Two-step reset AC97 interface and hardware codec */ - stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x94); - stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x88); + u16 value; - /* Set 16-bit audio data and choose L&R channel*/ - stk1160_write_reg(dev, STK1160_AC97CTL_1 + 2, 0x01); -} + value = stk1160_read_ac97(dev, 0x12); /* CD volume */ + stk1160_dbg("0x12 == 0x%04x", value); -static struct snd_ac97_bus_ops stk1160_ac97_ops = { - .read = stk1160_read_ac97, - .write = stk1160_write_ac97, - .reset = stk1160_reset_ac97, -}; + value = stk1160_read_ac97(dev, 0x10); /* Line-in volume */ + stk1160_dbg("0x10 == 0x%04x", value); -int stk1160_ac97_register(struct stk1160 *dev) -{ - struct snd_card *card = NULL; - struct snd_ac97_bus *ac97_bus; - struct snd_ac97_template ac97_template; - int rc; + value = stk1160_read_ac97(dev, 0x0e); /* MIC volume (mono) */ + stk1160_dbg("0x0e == 0x%04x", value); - /* - * Just want a card to access ac96 controls, - * the actual capture interface will be handled by snd-usb-audio - */ - rc = snd_card_new(dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (rc < 0) - return rc; - - /* TODO: I'm not sure where should I get these names :-( */ - snprintf(card->shortname, sizeof(card->shortname), - "stk1160-mixer"); - snprintf(card->longname, sizeof(card->longname), - "stk1160 ac97 codec mixer control"); - strlcpy(card->driver, dev->dev->driver->name, sizeof(card->driver)); - - rc = snd_ac97_bus(card, 0, &stk1160_ac97_ops, NULL, &ac97_bus); - if (rc) - goto err; - - /* We must set private_data before calling snd_ac97_mixer */ - memset(&ac97_template, 0, sizeof(ac97_template)); - ac97_template.private_data = dev; - ac97_template.scaps = AC97_SCAP_SKIP_MODEM; - rc = snd_ac97_mixer(ac97_bus, &ac97_template, &stk1160_ac97); - if (rc) - goto err; - - dev->snd_card = card; - rc = snd_card_register(card); - if (rc) - goto err; - - return 0; - -err: - dev->snd_card = NULL; - snd_card_free(card); - return rc; + value = stk1160_read_ac97(dev, 0x16); /* Aux volume */ + stk1160_dbg("0x16 == 0x%04x", value); + + value = stk1160_read_ac97(dev, 0x1a); /* Record select */ + stk1160_dbg("0x1a == 0x%04x", value); + + value = stk1160_read_ac97(dev, 0x02); /* Master volume */ + stk1160_dbg("0x02 == 0x%04x", value); + + value = stk1160_read_ac97(dev, 0x1c); /* Record gain */ + stk1160_dbg("0x1c == 0x%04x", value); } +#endif -int stk1160_ac97_unregister(struct stk1160 *dev) +void stk1160_ac97_setup(struct stk1160 *dev) { - struct snd_card *card = dev->snd_card; - - /* - * We need to check usb_device, - * because ac97 release attempts to communicate with codec - */ - if (card && dev->udev) - snd_card_free(card); + /* Two-step reset AC97 interface and hardware codec */ + stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x94); + stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c); - return 0; + /* Set 16-bit audio data and choose L&R channel*/ + stk1160_write_reg(dev, STK1160_AC97CTL_1 + 2, 0x01); + stk1160_write_reg(dev, STK1160_AC97CTL_1 + 3, 0x00); + + /* Setup channels */ + stk1160_write_ac97(dev, 0x12, 0x8808); /* CD volume */ + stk1160_write_ac97(dev, 0x10, 0x0808); /* Line-in volume */ + stk1160_write_ac97(dev, 0x0e, 0x0008); /* MIC volume (mono) */ + stk1160_write_ac97(dev, 0x16, 0x0808); /* Aux volume */ + stk1160_write_ac97(dev, 0x1a, 0x0404); /* Record select */ + stk1160_write_ac97(dev, 0x02, 0x0000); /* Master volume */ + stk1160_write_ac97(dev, 0x1c, 0x0808); /* Record gain */ + +#ifdef DEBUG + stk1160_ac97_dump_regs(dev); +#endif } diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c index bc02947..f3c9b8a 100644 --- a/drivers/media/usb/stk1160/stk1160-core.c +++ b/drivers/media/usb/stk1160/stk1160-core.c @@ -373,7 +373,7 @@ static int stk1160_probe(struct usb_interface *interface, /* select default input */ stk1160_select_input(dev); - stk1160_ac97_register(dev); + stk1160_ac97_setup(dev); rc = stk1160_video_register(dev); if (rc < 0) @@ -411,9 +411,6 @@ static void stk1160_disconnect(struct usb_interface *interface) /* Here is the only place where isoc get released */ stk1160_uninit_isoc(dev); - /* ac97 unregister needs to be done before usb_device is cleared */ - stk1160_ac97_unregister(dev); - stk1160_clear_queue(dev); video_unregister_device(&dev->vdev); diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h index 1ed1cc4..e85e12e 100644 --- a/drivers/media/usb/stk1160/stk1160.h +++ b/drivers/media/usb/stk1160/stk1160.h @@ -197,11 +197,4 @@ int stk1160_read_reg_req_len(struct stk1160 *dev, u8 req, u16 reg, void stk1160_select_input(struct stk1160 *dev); /* Provided by stk1160-ac97.c */ -#ifdef CONFIG_VIDEO_STK1160_AC97 -int stk1160_ac97_register(struct stk1160 *dev); -int stk1160_ac97_unregister(struct stk1160 *dev); -#else -static inline int stk1160_ac97_register(struct stk1160 *dev) { return 0; } -static inline int stk1160_ac97_unregister(struct stk1160 *dev) { return 0; } -#endif - +void stk1160_ac97_setup(struct stk1160 *dev);