From patchwork Tue Feb 2 14:31:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andreas Irestal X-Patchwork-Id: 8190891 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id F151F9F37A for ; Tue, 2 Feb 2016 14:34:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CEE42202FF for ; Tue, 2 Feb 2016 14:34:14 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 7F215202F0 for ; Tue, 2 Feb 2016 14:34:08 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 4657F26571B; Tue, 2 Feb 2016 15:34:07 +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,NO_DNS_FOR_FROM, RCVD_IN_DNSWL_NONE,UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 2912226536C; Tue, 2 Feb 2016 15:32:40 +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 6835626533D; Tue, 2 Feb 2016 15:32:38 +0100 (CET) Received: from bes.se.axis.com (bes.se.axis.com [195.60.68.10]) by alsa0.perex.cz (Postfix) with ESMTP id 453102651CF for ; Tue, 2 Feb 2016 15:32:29 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by bes.se.axis.com (Postfix) with ESMTP id 0B6CD2E173 for ; Tue, 2 Feb 2016 15:32:29 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at bes.se.axis.com Received: from bes.se.axis.com ([IPv6:::ffff:127.0.0.1]) by localhost (bes.se.axis.com [::ffff:127.0.0.1]) (amavisd-new, port 10024) with LMTP id K-M1-yAh-AD6 for ; Tue, 2 Feb 2016 15:32:27 +0100 (CET) Received: from boulder.se.axis.com (boulder.se.axis.com [10.0.2.104]) by bes.se.axis.com (Postfix) with ESMTP id 528862E343 for ; Tue, 2 Feb 2016 15:32:27 +0100 (CET) Received: from boulder.se.axis.com (localhost [127.0.0.1]) by postfix.imss71 (Postfix) with ESMTP id 2FE3416C2 for ; Tue, 2 Feb 2016 15:32:27 +0100 (CET) Received: from seth.se.axis.com (seth.se.axis.com [10.0.2.172]) by boulder.se.axis.com (Postfix) with ESMTP id 222171623 for ; Tue, 2 Feb 2016 15:32:27 +0100 (CET) Received: from lnxandire1.se.axis.com (lnxandire1.se.axis.com [10.88.50.2]) by seth.se.axis.com (Postfix) with ESMTP id 1C4ED3E4A2; Tue, 2 Feb 2016 15:32:27 +0100 (CET) Received: by lnxandire1.se.axis.com (Postfix, from userid 20496) id 1766480204; Tue, 2 Feb 2016 15:32:27 +0100 (CET) From: =?UTF-8?q?Andreas=20Irest=C3=A5l?= To: alsa-devel@alsa-project.org Date: Tue, 2 Feb 2016 15:31:50 +0100 Message-Id: <1454423510-1330-5-git-send-email-andire@axis.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1454423510-1330-1-git-send-email-andire@axis.com> References: <1454423510-1330-1-git-send-email-andire@axis.com> MIME-Version: 1.0 Cc: =?UTF-8?q?Andreas=20Irest=C3=A5l?= Subject: [alsa-devel] [PATCH 4/4] ASoC: adau17x1: Add option to provide platform data via DT 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Andreas Irestål --- .../devicetree/bindings/sound/adi,adau17x1.txt | 33 ++++++ include/dt-bindings/sound/adau17x1.h | 14 +++ sound/soc/codecs/adau1761.c | 131 +++++++++++++++++++++ sound/soc/codecs/adau1781.c | 57 +++++++++ 4 files changed, 235 insertions(+) create mode 100644 include/dt-bindings/sound/adau17x1.h diff --git a/Documentation/devicetree/bindings/sound/adi,adau17x1.txt b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt index 90f3ac3..296b417 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau17x1.txt +++ b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt @@ -12,10 +12,43 @@ Required properties: - reg: The i2c address. Value depends on the state of ADDR0 and ADDR1, as wired in hardware. +Optional properties: + + - input-differential bool to set if the input is differential + - digital-microphone bool to set if there is a digital microphone connected + to the digmic/jackdet pin. + - micbias-vg Microphone bias voltage + MICBIAS_0_90_AVDD - 0.9 * AVDD + MICBIAS_0_65_AVDD - 0.65 * AVDD + +Optional properties (ADAU1361/ADAU1461/ADAU1761/ADAU1961 only) + + - jack-detection If present, configures codec to use the digmic/jackdet + pin for jack detection. must provide one of + JACKDETECT_ACTIVE_LO or JACKDETECT_ACTIVE_HI followed + by debounce time in ms, which must be 5, 10, 20, or 40. + + - lineout-mode Set output mode of the lineout pins. + - headphone-mode Set output mode of the headphone pins. + +The output mode must be one of: + OUTPUT_MODE_HEADPHONE - Headphone output + OUTPUT_MODE_HEADPHONE_CAPLESS - Capless headphone output + OUTPUT_MODE_LINE - Line output + + + Example: +#include + i2c_bus { adau1361@38 { compatible = "adi,adau1361"; reg = <0x38>; + input-differential; + jack-detection = ; + lineout-mode = ; + headphone-mode = ; + micbias-vg = ; }; }; diff --git a/include/dt-bindings/sound/adau17x1.h b/include/dt-bindings/sound/adau17x1.h new file mode 100644 index 0000000..3152019 --- /dev/null +++ b/include/dt-bindings/sound/adau17x1.h @@ -0,0 +1,14 @@ +#ifndef __DT_ADAU17X1_H +#define __DT_ADAU17X1_H + +#define MICBIAS_0_90_AVDD 0 +#define MICBIAS_0_65_AVDD 1 + +#define OUTPUT_MODE_HEADPHONE 0 +#define OUTPUT_MODE_HEADPHONE_CAPLESS 1 +#define OUTPUT_MODE_LINE 2 + +#define JACKDETECT_ACTIVE_HI 0 +#define JACKDETECT_ACTIVE_LO 1 + +#endif diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 16fed36..22106b2 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "adau17x1.h" #include "adau1761.h" @@ -636,13 +637,143 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg) return adau17x1_readable_register(dev, reg); } +#ifdef CONFIG_OF +static inline void adau1761_parse_of_outmode(struct snd_soc_codec *codec, + uint32_t of_val, + enum adau1761_output_mode *mode) +{ + switch (of_val) { + case OUTPUT_MODE_HEADPHONE: + *mode = ADAU1761_OUTPUT_MODE_HEADPHONE; + break; + case OUTPUT_MODE_HEADPHONE_CAPLESS: + *mode = ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS; + break; + case OUTPUT_MODE_LINE: + *mode = ADAU1761_OUTPUT_MODE_LINE; + break; + default: + dev_warn(codec->dev, "Invalid output mode %d\n", of_val); + *mode = ADAU1761_OUTPUT_MODE_LINE; + break; + } +} + +static void adau1761_pdata_from_of(struct snd_soc_codec *codec, + struct adau1761_platform_data *pdata) +{ + struct device_node *np = codec->dev->of_node; + uint32_t val; + uint32_t debounce_pars[2]; + + if (of_get_property(np, "input-differential", NULL)) + pdata->input_differential = 1; + else + pdata->input_differential = 0; + + if (of_get_property(np, "jack-detection", NULL)) { + pdata->digmic_jackdetect_pin_mode = + ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT; + if (!of_property_read_u32_array(np, "jack-detection", + debounce_pars, 2)) { + pdata->jackdetect_active_low = + debounce_pars[0] == JACKDETECT_ACTIVE_LO; + switch (debounce_pars[1]) { + case 5: + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_5MS; + break; + case 10: + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_10MS; + break; + case 20: + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_20MS; + break; + case 40: + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_40MS; + break; + default: + dev_warn(codec->dev, "Invalid debounce_time %d\n", + debounce_pars[1]); + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_40MS; + break; + } + } else if (!of_property_read_u32_array(np, "jack-detection", + debounce_pars, 1)) { + dev_warn(codec->dev, "Debounce time not provided\n"); + pdata->jackdetect_active_low = + debounce_pars[0] == JACKDETECT_ACTIVE_LO; + } else { + dev_warn(codec->dev, "No jack detection settings found\n"); + pdata->jackdetect_active_low = 0; + pdata->jackdetect_debounce_time = + ADAU1761_JACKDETECT_DEBOUNCE_40MS; + } + } else if (of_get_property(np, "digital-microphone", NULL)) { + pdata->digmic_jackdetect_pin_mode = + ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC; + } else { + pdata->digmic_jackdetect_pin_mode = + ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE; + } + + if (!of_property_read_u32(np, "headphone-mode", &val)) + adau1761_parse_of_outmode(codec, val, &pdata->headphone_mode); + else + pdata->headphone_mode = ADAU1761_OUTPUT_MODE_LINE; + + if (!of_property_read_u32(np, "lineout-mode", &val)) + adau1761_parse_of_outmode(codec, val, &pdata->lineout_mode); + else + pdata->lineout_mode = ADAU1761_OUTPUT_MODE_LINE; + + if (!of_property_read_u32(np, "micbias-vg", &val)) { + switch (val) { + case MICBIAS_0_65_AVDD: + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_65_AVDD; + break; + case MICBIAS_0_90_AVDD: + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + break; + default: + dev_warn(codec->dev, "Invalid micbias voltage setting\n"); + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + break; + } + } else { + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + } +} +#else +static void adau1761_pdata_from_of(struct snd_soc_codec *codec, + struct adau1761_platform_data *pdata) +{ +} +#endif + static int adau1761_codec_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau *adau = snd_soc_codec_get_drvdata(codec); + struct device_node *np = codec->dev->of_node; + struct adau1761_platform_data *of_pdata; int ret; + if (!pdata && np && of_device_is_available(np)) { + of_pdata = devm_kzalloc(codec->dev, sizeof(*of_pdata), + GFP_KERNEL); + if (!of_pdata) + return -ENOMEM; + adau1761_pdata_from_of(codec, of_pdata); + pdata = of_pdata; + codec->dev->platform_data = pdata; + } + ret = adau17x1_add_widgets(codec); if (ret < 0) return ret; diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index bc1bb56..b207911 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "adau17x1.h" #include "adau1781.h" @@ -380,13 +381,69 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg, ADAU1781_INPUT_DIFFERNTIAL, val); } +#ifdef CONFIG_OF +static void adau1781_pdata_from_of(struct snd_soc_codec *codec, + struct adau1781_platform_data *pdata) +{ + struct device_node *np = codec->dev->of_node; + uint32_t val; + + if (of_get_property(np, "input-differential", NULL)) { + pdata->left_input_differential = 1; + pdata->right_input_differential = 1; + } else { + pdata->left_input_differential = 0; + pdata->right_input_differential = 0; + } + + if (of_get_property(np, "digital-microphone", NULL)) + pdata->use_dmic = 1; + else + pdata->use_dmic = 0; + + if (!of_property_read_u32(np, "micbias-vg", &val)) { + switch (val) { + case MICBIAS_0_65_AVDD: + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_65_AVDD; + break; + case MICBIAS_0_90_AVDD: + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + break; + default: + dev_warn(codec->dev, "Invalid micbias voltage setting\n"); + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + break; + } + } else { + pdata->micbias_voltage = ADAU17X1_MICBIAS_0_90_AVDD; + } +} +#else +static void adau1781_pdata_from_of(struct snd_soc_codec *codec, + struct adau1781_platform_data *pdata) +{ +} +#endif + static int adau1781_codec_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev); struct adau *adau = snd_soc_codec_get_drvdata(codec); + struct device_node *np = codec->dev->of_node; + struct adau1781_platform_data *of_pdata; int ret; + if (!pdata && np && of_device_is_available(np)) { + of_pdata = devm_kzalloc(codec->dev, sizeof(*of_pdata), + GFP_KERNEL); + if (!of_pdata) + return -ENOMEM; + adau1781_pdata_from_of(codec, of_pdata); + pdata = of_pdata; + codec->dev->platform_data = pdata; + } + ret = adau17x1_add_widgets(codec); if (ret) return ret;