From patchwork Tue Mar 21 14:45:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Charles Keepax X-Patchwork-Id: 9636713 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 605BC602D6 for ; Tue, 21 Mar 2017 14:46:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52CC9262F2 for ; Tue, 21 Mar 2017 14:46:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46DEC2833B; Tue, 21 Mar 2017 14:46:13 +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=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 627C8262F2 for ; Tue, 21 Mar 2017 14:46:12 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 1CBE026734D; Tue, 21 Mar 2017 15:44:50 +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 60ED926734C; Tue, 21 Mar 2017 15:44:49 +0100 (CET) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) by alsa0.perex.cz (Postfix) with ESMTP id F419926733E for ; Tue, 21 Mar 2017 15:44:44 +0100 (CET) Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v2LEhpb7021657; Tue, 21 Mar 2017 09:44:44 -0500 Authentication-Results: ppops.net; spf=none smtp.mailfrom=ckeepax@opensource.wolfsonmicro.com Received: from mail3.cirrus.com ([87.246.76.56]) by mx0b-001ae601.pphosted.com with ESMTP id 2991ahxnnv-1; Tue, 21 Mar 2017 09:44:43 -0500 Received: from EX17.ad.cirrus.com (ex17.ad.cirrus.com [172.20.9.81]) by mail3.cirrus.com (Postfix) with ESMTP id 8B15C611CE76; Tue, 21 Mar 2017 09:46:13 -0500 (CDT) Received: from imbe.wolfsonmicro.main (198.61.95.81) by EX17.ad.cirrus.com (172.20.9.81) with Microsoft SMTP Server id 14.3.301.0; Tue, 21 Mar 2017 14:44:42 +0000 Received: from algalon.ad.cirrus.com (algalon.ad.cirrus.com [198.90.223.36]) by imbe.wolfsonmicro.main (8.14.4/8.14.4) with ESMTP id v2LEi2pZ024866; Tue, 21 Mar 2017 14:44:02 GMT From: Charles Keepax To: Date: Tue, 21 Mar 2017 14:45:36 +0000 Message-ID: <1490107539-23995-3-git-send-email-ckeepax@opensource.wolfsonmicro.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1490107539-23995-1-git-send-email-ckeepax@opensource.wolfsonmicro.com> References: <1490107539-23995-1-git-send-email-ckeepax@opensource.wolfsonmicro.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1702020001 definitions=main-1703210129 Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, patches@opensource.wolfsonmicro.com, lgirdwood@gmail.com, robh+dt@kernel.org, lee.jones@linaro.org Subject: [alsa-devel] [PATCH 3/6] regulator: arizona-micbias: Add regulator driver for Arizona micbiases 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 Add a driver for controlling the micbias regulators on the Arizona class audio CODECs. This will replace earlier fixed support that initialised the micbias's with fixed settings from platform data, although that platform data can still be used to configure the constraints on this new regulator. Signed-off-by: Charles Keepax --- drivers/regulator/Makefile | 2 +- drivers/regulator/arizona-micbias.c | 227 ++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 drivers/regulator/arizona-micbias.c diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ef7725e..b670e87 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -19,7 +19,7 @@ obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o -obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o +obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o arizona-micbias.o obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o diff --git a/drivers/regulator/arizona-micbias.c b/drivers/regulator/arizona-micbias.c new file mode 100644 index 0000000..4a361186 --- /dev/null +++ b/drivers/regulator/arizona-micbias.c @@ -0,0 +1,227 @@ +/* + * arizona-micbias.c -- Microphone bias supplies for Arizona devices + * + * Copyright 2017 Cirrus Logic Inc. + * + * Author: Charles Keepax + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define ARIZONA_MICBIAS_MAX_NAME 10 +#define ARIZONA_MICBIAS_MAX_SELECTOR 0xD + +struct arizona_micbias_priv { + int id; + char name[ARIZONA_MICBIAS_MAX_NAME]; + + struct regulator_dev *regulator; + struct arizona *arizona; + + struct regulator_consumer_supply supply; + struct regulator_init_data *init_data; + struct regulator_desc desc; +}; + +static const struct regulator_ops arizona_micbias_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_bypass = regulator_get_bypass_regmap, + .set_bypass = regulator_set_bypass_regmap, + .set_soft_start = regulator_set_soft_start_regmap, + .set_pull_down = regulator_set_pull_down_regmap, +}; + +static const struct regulator_desc arizona_micbias_desc_tmpl = { + .supply_name = "MICVDD", + .type = REGULATOR_VOLTAGE, + .ops = &arizona_micbias_ops, + + .min_uV = 1500000, + .uV_step = 100000, + .n_voltages = ARIZONA_MICBIAS_MAX_SELECTOR + 1, + + .vsel_reg = ARIZONA_MIC_BIAS_CTRL_1, + .vsel_mask = ARIZONA_MICB1_LVL_MASK, + .enable_reg = ARIZONA_MIC_BIAS_CTRL_1, + .enable_mask = ARIZONA_MICB1_ENA, + .bypass_reg = ARIZONA_MIC_BIAS_CTRL_1, + .bypass_mask = ARIZONA_MICB1_BYPASS, + .soft_start_reg = ARIZONA_MIC_BIAS_CTRL_1, + .soft_start_mask = ARIZONA_MICB1_RATE, + .pull_down_reg = ARIZONA_MIC_BIAS_CTRL_1, + .pull_down_mask = ARIZONA_MICB1_DISCH, + + .owner = THIS_MODULE, +}; + +static const struct regulator_init_data arizona_micbias_tmpl = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_BYPASS, + .min_uV = 1500000, + .max_uV = 2800000, + }, +}; + +static int arizona_micbias_of_get_pdata(struct regulator_config *config) +{ + struct arizona_micbias_priv *micbias = config->driver_data; + struct arizona *arizona = micbias->arizona; + struct arizona_micbias *pdata = &arizona->pdata.micbias[micbias->id]; + struct device_node *np; + + np = of_get_child_by_name(arizona->dev->of_node, micbias->name); + if (np) { + config->of_node = np; + + micbias->init_data = of_get_regulator_init_data(arizona->dev, + np, + &micbias->desc); + + pdata->ext_cap = of_property_read_bool(np, "wlf,ext-cap"); + } + + return 0; +} + +static int arizona_micbias_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + int id = pdev->id; + struct arizona_micbias *pdata = &arizona->pdata.micbias[id]; + struct arizona_micbias_priv *micbias; + struct regulator_config config = { }; + struct regulation_constraints *constraints; + unsigned int val; + int ret; + + micbias = devm_kzalloc(&pdev->dev, sizeof(*micbias), GFP_KERNEL); + if (micbias == NULL) + return -ENOMEM; + + micbias->arizona = arizona; + micbias->id = id; + snprintf(micbias->name, sizeof(micbias->name), "MICBIAS%d", id + 1); + + micbias->desc = arizona_micbias_desc_tmpl; + micbias->desc.name = micbias->name; + micbias->desc.vsel_reg += id; + micbias->desc.enable_reg += id; + micbias->desc.bypass_reg += id; + micbias->desc.soft_start_reg += id; + micbias->desc.pull_down_reg += id; + + micbias->supply.supply = micbias->name; + micbias->supply.dev_name = dev_name(arizona->dev); + + config.dev = arizona->dev; + config.regmap = arizona->regmap; + config.driver_data = micbias; + + if (IS_ENABLED(CONFIG_OF)) { + if (!dev_get_platdata(arizona->dev)) { + ret = arizona_micbias_of_get_pdata(&config); + if (ret < 0) + return ret; + } + } + + if (!micbias->init_data) { + micbias->init_data = devm_kmemdup(&pdev->dev, + &arizona_micbias_tmpl, + sizeof(arizona_micbias_tmpl), + GFP_KERNEL); + if (!micbias->init_data) + return -ENOMEM; + } + + micbias->init_data->consumer_supplies = &micbias->supply; + micbias->init_data->num_consumer_supplies = 1; + + config.init_data = micbias->init_data; + constraints = &micbias->init_data->constraints; + + if (pdata->mV) { + constraints->min_uV = pdata->mV * 1000; + constraints->max_uV = pdata->mV * 1000; + } + + if (pdata->soft_start) + constraints->soft_start = true; + + if (pdata->bypass) + constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; + + if (pdata->discharge) + constraints->pull_down = true; + + if (pdata->ext_cap) + val = ARIZONA_MICB1_EXT_CAP; + else + val = 0; + + /* + * The core expects the regulator to have pull_down (discharge) and + * bypass disabled by default so clear those here, whilst we set the + * external cap. + */ + regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + id, + ARIZONA_MICB1_EXT_CAP | ARIZONA_MICB1_DISCH | + ARIZONA_MICB1_BYPASS, val); + + micbias->regulator = devm_regulator_register(&pdev->dev, + &micbias->desc, + &config); + + of_node_put(config.of_node); + + if (IS_ERR(micbias->regulator)) { + ret = PTR_ERR(micbias->regulator); + dev_err(arizona->dev, "Failed to register %s supply: %d\n", + micbias->name, ret); + return ret; + } + + return 0; +} + +static struct platform_driver arizona_micbias_driver = { + .probe = arizona_micbias_probe, + .driver = { + .name = "arizona-micbias", + }, +}; + +module_platform_driver(arizona_micbias_driver); + +/* Module information */ +MODULE_AUTHOR("Charles Keepax "); +MODULE_DESCRIPTION("Arizona microphone bias supply driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:arizona-micbias");