173cfbfa9SSimon Trimmer // SPDX-License-Identifier: GPL-2.0-only
273cfbfa9SSimon Trimmer //
373cfbfa9SSimon Trimmer // CS35L56 HDA audio driver SPI binding
473cfbfa9SSimon Trimmer //
573cfbfa9SSimon Trimmer // Copyright (C) 2023 Cirrus Logic, Inc. and
673cfbfa9SSimon Trimmer // Cirrus Logic International Semiconductor Ltd.
773cfbfa9SSimon Trimmer
873cfbfa9SSimon Trimmer #include <linux/module.h>
973cfbfa9SSimon Trimmer #include <linux/regmap.h>
1073cfbfa9SSimon Trimmer #include <linux/spi/spi.h>
1173cfbfa9SSimon Trimmer
1273cfbfa9SSimon Trimmer #include "cs35l56_hda.h"
1373cfbfa9SSimon Trimmer
cs35l56_hda_spi_probe(struct spi_device * spi)1473cfbfa9SSimon Trimmer static int cs35l56_hda_spi_probe(struct spi_device *spi)
1573cfbfa9SSimon Trimmer {
1673cfbfa9SSimon Trimmer struct cs35l56_hda *cs35l56;
1773cfbfa9SSimon Trimmer int ret;
1873cfbfa9SSimon Trimmer
1973cfbfa9SSimon Trimmer cs35l56 = devm_kzalloc(&spi->dev, sizeof(*cs35l56), GFP_KERNEL);
2073cfbfa9SSimon Trimmer if (!cs35l56)
2173cfbfa9SSimon Trimmer return -ENOMEM;
2273cfbfa9SSimon Trimmer
2373cfbfa9SSimon Trimmer cs35l56->base.dev = &spi->dev;
2473cfbfa9SSimon Trimmer cs35l56->base.regmap = devm_regmap_init_spi(spi, &cs35l56_regmap_spi);
2573cfbfa9SSimon Trimmer if (IS_ERR(cs35l56->base.regmap)) {
2673cfbfa9SSimon Trimmer ret = PTR_ERR(cs35l56->base.regmap);
2773cfbfa9SSimon Trimmer dev_err(cs35l56->base.dev, "Failed to allocate register map: %d\n",
2873cfbfa9SSimon Trimmer ret);
2973cfbfa9SSimon Trimmer return ret;
3073cfbfa9SSimon Trimmer }
3173cfbfa9SSimon Trimmer
3273cfbfa9SSimon Trimmer ret = cs35l56_hda_common_probe(cs35l56, spi->chip_select);
3373cfbfa9SSimon Trimmer if (ret)
3473cfbfa9SSimon Trimmer return ret;
3573cfbfa9SSimon Trimmer ret = cs35l56_irq_request(&cs35l56->base, spi->irq);
3673cfbfa9SSimon Trimmer if (ret < 0)
3773cfbfa9SSimon Trimmer cs35l56_hda_remove(cs35l56->base.dev);
3873cfbfa9SSimon Trimmer
3973cfbfa9SSimon Trimmer return ret;
4073cfbfa9SSimon Trimmer }
4173cfbfa9SSimon Trimmer
cs35l56_hda_spi_remove(struct spi_device * spi)4273cfbfa9SSimon Trimmer static void cs35l56_hda_spi_remove(struct spi_device *spi)
4373cfbfa9SSimon Trimmer {
4473cfbfa9SSimon Trimmer cs35l56_hda_remove(&spi->dev);
4573cfbfa9SSimon Trimmer }
4673cfbfa9SSimon Trimmer
4773cfbfa9SSimon Trimmer static const struct spi_device_id cs35l56_hda_spi_id[] = {
4873cfbfa9SSimon Trimmer { "cs35l56-hda", 0 },
4973cfbfa9SSimon Trimmer {}
5073cfbfa9SSimon Trimmer };
5173cfbfa9SSimon Trimmer
52*4930d7a4SSimon Trimmer static const struct acpi_device_id cs35l56_acpi_hda_match[] = {
53*4930d7a4SSimon Trimmer { "CSC3554", 0 },
54*4930d7a4SSimon Trimmer { "CSC3556", 0 },
55*4930d7a4SSimon Trimmer { "CSC3557", 0 },
56*4930d7a4SSimon Trimmer {}
57*4930d7a4SSimon Trimmer };
58*4930d7a4SSimon Trimmer MODULE_DEVICE_TABLE(acpi, cs35l56_acpi_hda_match);
59*4930d7a4SSimon Trimmer
6073cfbfa9SSimon Trimmer static struct spi_driver cs35l56_hda_spi_driver = {
6173cfbfa9SSimon Trimmer .driver = {
6273cfbfa9SSimon Trimmer .name = "cs35l56-hda",
63*4930d7a4SSimon Trimmer .acpi_match_table = cs35l56_acpi_hda_match,
6473cfbfa9SSimon Trimmer .pm = &cs35l56_hda_pm_ops,
6573cfbfa9SSimon Trimmer },
6673cfbfa9SSimon Trimmer .id_table = cs35l56_hda_spi_id,
6773cfbfa9SSimon Trimmer .probe = cs35l56_hda_spi_probe,
6873cfbfa9SSimon Trimmer .remove = cs35l56_hda_spi_remove,
6973cfbfa9SSimon Trimmer };
7073cfbfa9SSimon Trimmer module_spi_driver(cs35l56_hda_spi_driver);
7173cfbfa9SSimon Trimmer
7273cfbfa9SSimon Trimmer MODULE_DESCRIPTION("HDA CS35L56 SPI driver");
7373cfbfa9SSimon Trimmer MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L56);
7473cfbfa9SSimon Trimmer MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
7573cfbfa9SSimon Trimmer MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
7673cfbfa9SSimon Trimmer MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
7773cfbfa9SSimon Trimmer MODULE_LICENSE("GPL");
78