xref: /openbmc/linux/sound/soc/codecs/cs35l41-spi.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
16450ef55SDavid Rhodes // SPDX-License-Identifier: GPL-2.0
26450ef55SDavid Rhodes //
36450ef55SDavid Rhodes // cs35l41-spi.c -- CS35l41 SPI driver
46450ef55SDavid Rhodes //
56450ef55SDavid Rhodes // Copyright 2017-2021 Cirrus Logic, Inc.
66450ef55SDavid Rhodes //
76450ef55SDavid Rhodes // Author: David Rhodes	<david.rhodes@cirrus.com>
86450ef55SDavid Rhodes 
96450ef55SDavid Rhodes #include <linux/acpi.h>
106450ef55SDavid Rhodes #include <linux/delay.h>
116450ef55SDavid Rhodes #include <linux/init.h>
126450ef55SDavid Rhodes #include <linux/kernel.h>
136450ef55SDavid Rhodes #include <linux/module.h>
146450ef55SDavid Rhodes #include <linux/moduleparam.h>
156450ef55SDavid Rhodes #include <linux/platform_device.h>
166450ef55SDavid Rhodes #include <linux/spi/spi.h>
176450ef55SDavid Rhodes 
186450ef55SDavid Rhodes #include "cs35l41.h"
196450ef55SDavid Rhodes 
206450ef55SDavid Rhodes static const struct spi_device_id cs35l41_id_spi[] = {
216450ef55SDavid Rhodes 	{ "cs35l40", 0 },
226450ef55SDavid Rhodes 	{ "cs35l41", 0 },
23dcf82131SDavid Rhodes 	{ "cs35l51", 0 },
24dcf82131SDavid Rhodes 	{ "cs35l53", 0 },
256450ef55SDavid Rhodes 	{}
266450ef55SDavid Rhodes };
276450ef55SDavid Rhodes 
286450ef55SDavid Rhodes MODULE_DEVICE_TABLE(spi, cs35l41_id_spi);
296450ef55SDavid Rhodes 
cs35l41_spi_probe(struct spi_device * spi)306450ef55SDavid Rhodes static int cs35l41_spi_probe(struct spi_device *spi)
316450ef55SDavid Rhodes {
326450ef55SDavid Rhodes 	const struct regmap_config *regmap_config = &cs35l41_regmap_spi;
33f7f20737SLucas Tanure 	struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev);
346450ef55SDavid Rhodes 	struct cs35l41_private *cs35l41;
356450ef55SDavid Rhodes 	int ret;
366450ef55SDavid Rhodes 
374295c8ccSCharles Keepax 	cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL);
386450ef55SDavid Rhodes 	if (!cs35l41)
396450ef55SDavid Rhodes 		return -ENOMEM;
406450ef55SDavid Rhodes 
41872fc0b6SLucas Tanure 	spi->max_speed_hz = CS35L41_SPI_MAX_FREQ;
42872fc0b6SLucas Tanure 	spi_setup(spi);
43872fc0b6SLucas Tanure 
446450ef55SDavid Rhodes 	spi_set_drvdata(spi, cs35l41);
456450ef55SDavid Rhodes 	cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config);
466450ef55SDavid Rhodes 	if (IS_ERR(cs35l41->regmap)) {
476450ef55SDavid Rhodes 		ret = PTR_ERR(cs35l41->regmap);
484295c8ccSCharles Keepax 		dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret);
496450ef55SDavid Rhodes 		return ret;
506450ef55SDavid Rhodes 	}
516450ef55SDavid Rhodes 
526450ef55SDavid Rhodes 	cs35l41->dev = &spi->dev;
536450ef55SDavid Rhodes 	cs35l41->irq = spi->irq;
546450ef55SDavid Rhodes 
55f7f20737SLucas Tanure 	return cs35l41_probe(cs35l41, hw_cfg);
566450ef55SDavid Rhodes }
576450ef55SDavid Rhodes 
cs35l41_spi_remove(struct spi_device * spi)58a0386bbaSUwe Kleine-König static void cs35l41_spi_remove(struct spi_device *spi)
596450ef55SDavid Rhodes {
606450ef55SDavid Rhodes 	struct cs35l41_private *cs35l41 = spi_get_drvdata(spi);
616450ef55SDavid Rhodes 
62ca7270a7SUwe Kleine-König 	cs35l41_remove(cs35l41);
636450ef55SDavid Rhodes }
646450ef55SDavid Rhodes 
656450ef55SDavid Rhodes #ifdef CONFIG_OF
666450ef55SDavid Rhodes static const struct of_device_id cs35l41_of_match[] = {
676450ef55SDavid Rhodes 	{ .compatible = "cirrus,cs35l40" },
686450ef55SDavid Rhodes 	{ .compatible = "cirrus,cs35l41" },
696450ef55SDavid Rhodes 	{},
706450ef55SDavid Rhodes };
716450ef55SDavid Rhodes MODULE_DEVICE_TABLE(of, cs35l41_of_match);
726450ef55SDavid Rhodes #endif
736450ef55SDavid Rhodes 
746450ef55SDavid Rhodes #ifdef CONFIG_ACPI
756450ef55SDavid Rhodes static const struct acpi_device_id cs35l41_acpi_match[] = {
766450ef55SDavid Rhodes 	{ "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */
77*658e9595SCristian Ciocaltea 	{ "CLSA3541", 0 }, /* Cirrus Logic PnP ID + part ID */
786450ef55SDavid Rhodes 	{},
796450ef55SDavid Rhodes };
806450ef55SDavid Rhodes MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match);
816450ef55SDavid Rhodes #endif
826450ef55SDavid Rhodes 
836450ef55SDavid Rhodes static struct spi_driver cs35l41_spi_driver = {
846450ef55SDavid Rhodes 	.driver = {
856450ef55SDavid Rhodes 		.name		= "cs35l41",
86f517ba49SCharles Keepax 		.pm		= &cs35l41_pm_ops,
876450ef55SDavid Rhodes 		.of_match_table = of_match_ptr(cs35l41_of_match),
886450ef55SDavid Rhodes 		.acpi_match_table = ACPI_PTR(cs35l41_acpi_match),
896450ef55SDavid Rhodes 	},
906450ef55SDavid Rhodes 	.id_table	= cs35l41_id_spi,
916450ef55SDavid Rhodes 	.probe		= cs35l41_spi_probe,
926450ef55SDavid Rhodes 	.remove		= cs35l41_spi_remove,
936450ef55SDavid Rhodes };
946450ef55SDavid Rhodes 
956450ef55SDavid Rhodes module_spi_driver(cs35l41_spi_driver);
966450ef55SDavid Rhodes 
976450ef55SDavid Rhodes MODULE_DESCRIPTION("SPI CS35L41 driver");
986450ef55SDavid Rhodes MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
996450ef55SDavid Rhodes MODULE_LICENSE("GPL");
100