Received: by 2002:a05:6358:489b:b0:bb:da1:e618 with SMTP id x27csp576280rwn; Thu, 15 Sep 2022 03:24:24 -0700 (PDT) X-Google-Smtp-Source: AA6agR7Lz09mouZ1q71fqRXHGb2vuyhrSBnHuBv9n/LssjYjwd4Iv/I3CK66KsrCUuETXfSGFwMN X-Received: by 2002:a63:e14c:0:b0:439:2e24:e014 with SMTP id h12-20020a63e14c000000b004392e24e014mr13149802pgk.173.1663237463841; Thu, 15 Sep 2022 03:24:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663237463; cv=none; d=google.com; s=arc-20160816; b=eCKAkY9I6uUp9EFOmYeZpPTayuIuLSUzNGK8vNitFRHAH5chbACd5UQcx075qdC8Ip hkqPCQgXLUIOkSacgBJ5j0eEE5Ae2JBbsEIR61AEdR/r1h0ZDDA0sSmKvLt8dltgKnJ8 O7aAuspdYMC92NMBuKajTGDHSLi4Iev4IOO6pCddfgwadlARi/n7zoIvA0X8eTdbA4Be HgGOm2GOxnIHXJBkblG0WFb+KMF8UEfkXIWBs+8QF5MB5hG9SrAqjNwmGjduE8dV8C8i 4+mH0yNfIPbVnMmXN1b3CfTP6gVjtSgXNnflpWT/ZQWOu2QBzKF4I73LMbugPshQ+/no HYAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:dkim-signature :from; bh=OLGXRggUDIiP3mnJth2XvBZYxJ1dwFnJNU+C03Y2VVs=; b=GrqdmT5Az3ZqHIWXufRcWZfDDHTm0nTJMu0ynyGU/LsCpYNm2hKxMeLTgId93Ja4sv DjC2dvZBupXfOuIM+ZZhpVa+Q702hjzH66I6R5zKS0h1nS8dJWIfcR8fH7rTGh/aRk4v IF31w8IqcAXwOchjfwnq/k7G7h3WXyuTxNHXALSl1YPwbLJuSf8LR6ApebCeZR6y00en kszcoFwNe7cOOorJ6l8wqQGir7x8hF8XcdnZQ13pkWInaN/5nKFTRCkF0d7vkxSDRkCu Nk38Tx5AmcTsNLjS/zf+IUbBLHZzVaCKTDdKr4FhFdpKNPCHza8613F6gUkn1sa192Ez tpOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cutebit.org header.s=mail header.b="t+Ix2/wJ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cutebit.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ja21-20020a170902efd500b00177e5c1d5d0si16046150plb.347.2022.09.15.03.24.10; Thu, 15 Sep 2022 03:24:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cutebit.org header.s=mail header.b="t+Ix2/wJ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cutebit.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229931AbiIOJq7 (ORCPT + 99 others); Thu, 15 Sep 2022 05:46:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229907AbiIOJpo (ORCPT ); Thu, 15 Sep 2022 05:45:44 -0400 Received: from hutie.ust.cz (hutie.ust.cz [185.8.165.127]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9547252AD; Thu, 15 Sep 2022 02:45:40 -0700 (PDT) From: =?UTF-8?q?Martin=20Povi=C5=A1er?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cutebit.org; s=mail; t=1663235135; bh=OLGXRggUDIiP3mnJth2XvBZYxJ1dwFnJNU+C03Y2VVs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=t+Ix2/wJshqeH5BwHlleGvCuBHvmGBnqqVoeB4/XYxHZArshouUqOiXywUqoqh9Gd YWO4Vtpii//gN8PyL5eoNDDtNMZWpPI/8FcVGhSoifR5YncbIthVJfq+juy6WZvIcU fZba768+1tf2EdeOnC9lTEgFae7M2WpCr8ILsaTk= To: James Schulman , David Rhodes , Lucas Tanure , Richard Fitzgerald , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , =?UTF-8?q?Martin=20Povi=C5=A1er?= Cc: Charles Keepax , ChiYuan Huang , Matt Flax , Lukas Bulwahn , Pierre-Louis Bossart , - , alsa-devel@alsa-project.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev Subject: [PATCH v2 07/11] ASoC: cs42l42: Split I2C identity into separate module Date: Thu, 15 Sep 2022 11:44:40 +0200 Message-Id: <20220915094444.11434-8-povik+lin@cutebit.org> In-Reply-To: <20220915094444.11434-1-povik+lin@cutebit.org> References: <20220915094444.11434-1-povik+lin@cutebit.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Richard Fitzgerald Split the I2C bus driver definition and probe()/remove() into a separate module so that a SoundWire build of CS42L42 support does not have a spurious dependency on I2C. Signed-off-by: Richard Fitzgerald Signed-off-by: Martin PoviĊĦer --- sound/soc/codecs/Kconfig | 8 ++- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/cs42l42-i2c.c | 107 +++++++++++++++++++++++++++++++ sound/soc/codecs/cs42l42.c | 111 ++++++--------------------------- sound/soc/codecs/cs42l42.h | 15 +++++ 5 files changed, 152 insertions(+), 93 deletions(-) create mode 100644 sound/soc/codecs/cs42l42-i2c.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index c7d83fe999e9..01725d0a9500 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -692,9 +692,15 @@ config SND_SOC_CS35L45_I2C Enable support for Cirrus Logic CS35L45 smart speaker amplifier with I2C control. +config SND_SOC_CS42L42_CORE + tristate + config SND_SOC_CS42L42 - tristate "Cirrus Logic CS42L42 CODEC" + tristate "Cirrus Logic CS42L42 CODEC (I2C)" depends on I2C + select REGMAP + select REGMAP_I2C + select SND_SOC_CS42L42_CORE config SND_SOC_CS42L51 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 16a01635dd04..5b7020a0b234 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -65,6 +65,7 @@ snd-soc-cs35l45-objs := cs35l45.o snd-soc-cs35l45-spi-objs := cs35l45-spi.o snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o snd-soc-cs42l42-objs := cs42l42.o +snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o @@ -422,7 +423,8 @@ obj-$(CONFIG_SND_SOC_CS35L45_TABLES) += snd-soc-cs35l45-tables.o obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o -obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o +obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o +obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/codecs/cs42l42-i2c.c b/sound/soc/codecs/cs42l42-i2c.c new file mode 100644 index 000000000000..5f01b6adc17e --- /dev/null +++ b/sound/soc/codecs/cs42l42-i2c.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cs42l42-i2c.c -- CS42L42 ALSA SoC audio driver for I2C + * + * Copyright 2016, 2022 Cirrus Logic, Inc. + */ + +#include +#include +#include +#include +#include + +#include "cs42l42.h" + +static int cs42l42_i2c_probe(struct i2c_client *i2c_client) +{ + struct device *dev = &i2c_client->dev; + struct cs42l42_private *cs42l42; + struct regmap *regmap; + int ret; + + cs42l42 = devm_kzalloc(dev, sizeof(*cs42l42), GFP_KERNEL); + if (!cs42l42) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + cs42l42->dev = dev; + cs42l42->regmap = regmap; + cs42l42->irq = i2c_client->irq; + + ret = cs42l42_common_probe(cs42l42, &cs42l42_soc_component, &cs42l42_dai); + if (ret) + return ret; + + return cs42l42_init(cs42l42); +} + +static int cs42l42_i2c_remove(struct i2c_client *i2c_client) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&i2c_client->dev); + + cs42l42_common_remove(cs42l42); + + return 0; +} + +static int __maybe_unused cs42l42_i2c_resume(struct device *dev) +{ + int ret; + + ret = cs42l42_resume(dev); + if (ret) + return ret; + + cs42l42_resume_restore(dev); + + return 0; +} + +static const struct dev_pm_ops cs42l42_i2c_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) +}; + +static const struct of_device_id __maybe_unused cs42l42_of_match[] = { + { .compatible = "cirrus,cs42l42", }, + {} +}; +MODULE_DEVICE_TABLE(of, cs42l42_of_match); + +static const struct acpi_device_id __maybe_unused cs42l42_acpi_match[] = { + {"10134242", 0,}, + {} +}; +MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match); + +static const struct i2c_device_id cs42l42_id[] = { + {"cs42l42", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs42l42_id); + +static struct i2c_driver cs42l42_i2c_driver = { + .driver = { + .name = "cs42l42", + .pm = &cs42l42_i2c_pm_ops, + .of_match_table = of_match_ptr(cs42l42_of_match), + .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), + }, + .id_table = cs42l42_id, + .probe_new = cs42l42_i2c_probe, + .remove = cs42l42_i2c_remove, +}; + +module_i2c_driver(cs42l42_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS42L42 I2C driver"); +MODULE_AUTHOR("Richard Fitzgerald "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index a4bb6f5d2267..3ace16259d1a 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -375,7 +374,7 @@ static const struct regmap_range_cfg cs42l42_page_range = { .window_len = 256, }; -static const struct regmap_config cs42l42_regmap = { +const struct regmap_config cs42l42_regmap = { .reg_bits = 8, .val_bits = 8, @@ -393,6 +392,7 @@ static const struct regmap_config cs42l42_regmap = { .use_single_read = true, .use_single_write = true, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_regmap, SND_SOC_CS42L42_CORE); static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true); static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true); @@ -579,7 +579,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ return 0; } -static const struct snd_soc_component_driver cs42l42_soc_component = { +const struct snd_soc_component_driver cs42l42_soc_component = { .set_jack = cs42l42_set_jack, .dapm_widgets = cs42l42_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), @@ -590,6 +590,7 @@ static const struct snd_soc_component_driver cs42l42_soc_component = { .idle_bias_on = 1, .endianness = 1, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_soc_component, SND_SOC_CS42L42_CORE); /* Switch to SCLK. Atomic delay after the write to allow the switch to complete. */ static const struct reg_sequence cs42l42_to_sclk_seq[] = { @@ -1086,7 +1087,7 @@ static const struct snd_soc_dai_ops cs42l42_ops = { .mute_stream = cs42l42_mute_stream, }; -static struct snd_soc_dai_driver cs42l42_dai = { +struct snd_soc_dai_driver cs42l42_dai = { .name = "cs42l42", .playback = { .stream_name = "Playback", @@ -1106,6 +1107,7 @@ static struct snd_soc_dai_driver cs42l42_dai = { .symmetric_sample_bits = 1, .ops = &cs42l42_ops, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_dai, SND_SOC_CS42L42_CORE); static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) { @@ -2100,7 +2102,7 @@ static const struct reg_sequence __maybe_unused cs42l42_shutdown_seq[] = { REG_SEQ0(CS42L42_PWR_CTL1, 0xFF) }; -static int __maybe_unused cs42l42_suspend(struct device *dev) +int cs42l42_suspend(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); unsigned int reg; @@ -2160,8 +2162,9 @@ static int __maybe_unused cs42l42_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_NS_GPL(cs42l42_suspend, SND_SOC_CS42L42_CORE); -static int __maybe_unused cs42l42_resume(struct device *dev) +int cs42l42_resume(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); int ret; @@ -2187,8 +2190,9 @@ static int __maybe_unused cs42l42_resume(struct device *dev) return 0; } +EXPORT_SYMBOL_NS_GPL(cs42l42_resume, SND_SOC_CS42L42_CORE); -static void __maybe_unused cs42l42_resume_restore(struct device *dev) +void cs42l42_resume_restore(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); @@ -2205,6 +2209,7 @@ static void __maybe_unused cs42l42_resume_restore(struct device *dev) dev_dbg(dev, "System resumed\n"); } +EXPORT_SYMBOL_NS_GPL(cs42l42_resume_restore, SND_SOC_CS42L42_CORE); static int __maybe_unused cs42l42_i2c_resume(struct device *dev) { @@ -2219,9 +2224,9 @@ static int __maybe_unused cs42l42_i2c_resume(struct device *dev) return 0; } -static int cs42l42_common_probe(struct cs42l42_private *cs42l42, - const struct snd_soc_component_driver *component_drv, - struct snd_soc_dai_driver *dai) +int cs42l42_common_probe(struct cs42l42_private *cs42l42, + const struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver *dai) { int ret, i; @@ -2294,8 +2299,9 @@ static int cs42l42_common_probe(struct cs42l42_private *cs42l42, return ret; } +EXPORT_SYMBOL_NS_GPL(cs42l42_common_probe, SND_SOC_CS42L42_CORE); -static int cs42l42_init(struct cs42l42_private *cs42l42) +int cs42l42_init(struct cs42l42_private *cs42l42) { unsigned int reg; int devid, ret; @@ -2374,8 +2380,9 @@ static int cs42l42_init(struct cs42l42_private *cs42l42) cs42l42->supplies); return ret; } +EXPORT_SYMBOL_NS_GPL(cs42l42_init, SND_SOC_CS42L42_CORE); -static void cs42l42_common_remove(struct cs42l42_private *cs42l42) +void cs42l42_common_remove(struct cs42l42_private *cs42l42) { if (cs42l42->irq) free_irq(cs42l42->irq, cs42l42); @@ -2393,85 +2400,7 @@ static void cs42l42_common_remove(struct cs42l42_private *cs42l42) gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); } - -static int cs42l42_i2c_probe(struct i2c_client *i2c_client) -{ - struct device *dev = &i2c_client->dev; - struct cs42l42_private *cs42l42; - struct regmap *regmap; - int ret; - - cs42l42 = devm_kzalloc(dev, sizeof(struct cs42l42_private), GFP_KERNEL); - if (!cs42l42) - return -ENOMEM; - - regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); - return ret; - } - - cs42l42->dev = dev; - cs42l42->regmap = regmap; - cs42l42->irq = i2c_client->irq; - - ret = cs42l42_common_probe(cs42l42, &cs42l42_soc_component, &cs42l42_dai); - if (ret) - return ret; - - return cs42l42_init(cs42l42); -} - -static int cs42l42_i2c_remove(struct i2c_client *i2c_client) -{ - struct cs42l42_private *cs42l42 = dev_get_drvdata(&i2c_client->dev); - - cs42l42_common_remove(cs42l42); - - return 0; -} - -static const struct dev_pm_ops cs42l42_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) -}; - -#ifdef CONFIG_OF -static const struct of_device_id cs42l42_of_match[] = { - { .compatible = "cirrus,cs42l42", }, - {} -}; -MODULE_DEVICE_TABLE(of, cs42l42_of_match); -#endif - -#ifdef CONFIG_ACPI -static const struct acpi_device_id cs42l42_acpi_match[] = { - {"10134242", 0,}, - {} -}; -MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match); -#endif - -static const struct i2c_device_id cs42l42_id[] = { - {"cs42l42", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, cs42l42_id); - -static struct i2c_driver cs42l42_i2c_driver = { - .driver = { - .name = "cs42l42", - .pm = &cs42l42_pm_ops, - .of_match_table = of_match_ptr(cs42l42_of_match), - .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), - }, - .id_table = cs42l42_id, - .probe_new = cs42l42_i2c_probe, - .remove = cs42l42_i2c_remove, -}; - -module_i2c_driver(cs42l42_i2c_driver); +EXPORT_SYMBOL_NS_GPL(cs42l42_common_remove, SND_SOC_CS42L42_CORE); MODULE_DESCRIPTION("ASoC CS42L42 driver"); MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, "); diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index a8e0d5b414a5..2a9f178f6190 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include struct cs42l42_private { struct regmap *regmap; @@ -50,4 +52,17 @@ struct cs42l42_private { bool init_done; }; +extern const struct regmap_config cs42l42_regmap; +extern const struct snd_soc_component_driver cs42l42_soc_component; +extern struct snd_soc_dai_driver cs42l42_dai; + +int cs42l42_suspend(struct device *dev); +int cs42l42_resume(struct device *dev); +void cs42l42_resume_restore(struct device *dev); +int cs42l42_common_probe(struct cs42l42_private *cs42l42, + const struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver *dai); +int cs42l42_init(struct cs42l42_private *cs42l42); +void cs42l42_common_remove(struct cs42l42_private *cs42l42); + #endif /* __CS42L42_H__ */ -- 2.33.0