From 6450ef55905688602175fae4ed1bfbfef6a14dde Mon Sep 17 00:00:00 2001 From: David Rhodes Date: Tue, 7 Sep 2021 17:57:18 -0500 Subject: ASoC: cs35l41: CS35L41 Boosted Smart Amplifier SoC Audio driver for the Cirrus Logic CS35L41 amplifier Signed-off-by: David Rhodes Tested-by: Charles Keepax Link: https://lore.kernel.org/r/20210907225719.2018115-2-drhodes@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-i2c.c | 114 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 sound/soc/codecs/cs35l41-i2c.c (limited to 'sound/soc/codecs/cs35l41-i2c.c') diff --git a/sound/soc/codecs/cs35l41-i2c.c b/sound/soc/codecs/cs35l41-i2c.c new file mode 100644 index 000000000000..dc9da78df412 --- /dev/null +++ b/sound/soc/codecs/cs35l41-i2c.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// cs35l41-i2c.c -- CS35l41 I2C driver +// +// Copyright 2017-2021 Cirrus Logic, Inc. +// +// Author: David Rhodes + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "cs35l41.h" + +static struct regmap_config cs35l41_regmap_i2c = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = CS35L41_REGSTRIDE, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .val_format_endian = REGMAP_ENDIAN_BIG, + .max_register = CS35L41_LASTREG, + .reg_defaults = cs35l41_reg, + .num_reg_defaults = ARRAY_SIZE(cs35l41_reg), + .volatile_reg = cs35l41_volatile_reg, + .readable_reg = cs35l41_readable_reg, + .precious_reg = cs35l41_precious_reg, + .cache_type = REGCACHE_RBTREE, +}; + +static const struct i2c_device_id cs35l41_id_i2c[] = { + { "cs35l40", 0 }, + { "cs35l41", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); + +static int cs35l41_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs35l41_private *cs35l41; + struct device *dev = &client->dev; + struct cs35l41_platform_data *pdata = dev_get_platdata(dev); + const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; + int ret; + + cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL); + + if (!cs35l41) + return -ENOMEM; + + cs35l41->dev = dev; + cs35l41->irq = client->irq; + + i2c_set_clientdata(client, cs35l41); + cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); + if (IS_ERR(cs35l41->regmap)) { + ret = PTR_ERR(cs35l41->regmap); + dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + return cs35l41_probe(cs35l41, pdata); +} + +static int cs35l41_i2c_remove(struct i2c_client *client) +{ + struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); + + return cs35l41_remove(cs35l41); +} + +#ifdef CONFIG_OF +static const struct of_device_id cs35l41_of_match[] = { + { .compatible = "cirrus,cs35l40" }, + { .compatible = "cirrus,cs35l41" }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l41_of_match); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id cs35l41_acpi_match[] = { + { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ + {}, +}; +MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); +#endif + +static struct i2c_driver cs35l41_i2c_driver = { + .driver = { + .name = "cs35l41", + .of_match_table = of_match_ptr(cs35l41_of_match), + .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), + }, + .id_table = cs35l41_id_i2c, + .probe = cs35l41_i2c_probe, + .remove = cs35l41_i2c_remove, +}; + +module_i2c_driver(cs35l41_i2c_driver); + +MODULE_DESCRIPTION("I2C CS35L41 driver"); +MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3