David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // |
| 3 | // cs35l41-spi.c -- CS35l41 SPI driver |
| 4 | // |
| 5 | // Copyright 2017-2021 Cirrus Logic, Inc. |
| 6 | // |
| 7 | // Author: David Rhodes <david.rhodes@cirrus.com> |
| 8 | |
| 9 | #include <linux/acpi.h> |
| 10 | #include <linux/delay.h> |
| 11 | #include <linux/init.h> |
| 12 | #include <linux/kernel.h> |
| 13 | #include <linux/module.h> |
| 14 | #include <linux/moduleparam.h> |
| 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/spi/spi.h> |
| 17 | |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 18 | #include "cs35l41.h" |
| 19 | |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 20 | static const struct spi_device_id cs35l41_id_spi[] = { |
| 21 | { "cs35l40", 0 }, |
| 22 | { "cs35l41", 0 }, |
David Rhodes | dcf8213 | 2022-01-05 11:30:19 +0000 | [diff] [blame] | 23 | { "cs35l51", 0 }, |
| 24 | { "cs35l53", 0 }, |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 25 | {} |
| 26 | }; |
| 27 | |
| 28 | MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); |
| 29 | |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 30 | static int cs35l41_spi_probe(struct spi_device *spi) |
| 31 | { |
| 32 | const struct regmap_config *regmap_config = &cs35l41_regmap_spi; |
Charles Keepax | 4295c8c | 2021-09-14 15:13:49 +0100 | [diff] [blame] | 33 | struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 34 | struct cs35l41_private *cs35l41; |
| 35 | int ret; |
| 36 | |
Charles Keepax | 4295c8c | 2021-09-14 15:13:49 +0100 | [diff] [blame] | 37 | cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL); |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 38 | if (!cs35l41) |
| 39 | return -ENOMEM; |
| 40 | |
Lucas Tanure | 872fc0b6 | 2021-11-23 16:31:39 +0000 | [diff] [blame] | 41 | spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; |
| 42 | spi_setup(spi); |
| 43 | |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 44 | spi_set_drvdata(spi, cs35l41); |
| 45 | cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); |
| 46 | if (IS_ERR(cs35l41->regmap)) { |
| 47 | ret = PTR_ERR(cs35l41->regmap); |
Charles Keepax | 4295c8c | 2021-09-14 15:13:49 +0100 | [diff] [blame] | 48 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret); |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 49 | return ret; |
| 50 | } |
| 51 | |
| 52 | cs35l41->dev = &spi->dev; |
| 53 | cs35l41->irq = spi->irq; |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 54 | |
| 55 | return cs35l41_probe(cs35l41, pdata); |
| 56 | } |
| 57 | |
| 58 | static int cs35l41_spi_remove(struct spi_device *spi) |
| 59 | { |
| 60 | struct cs35l41_private *cs35l41 = spi_get_drvdata(spi); |
| 61 | |
Uwe Kleine-König | ca7270a | 2021-10-20 15:24:16 +0200 | [diff] [blame] | 62 | cs35l41_remove(cs35l41); |
| 63 | |
| 64 | return 0; |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | #ifdef CONFIG_OF |
| 68 | static const struct of_device_id cs35l41_of_match[] = { |
| 69 | { .compatible = "cirrus,cs35l40" }, |
| 70 | { .compatible = "cirrus,cs35l41" }, |
| 71 | {}, |
| 72 | }; |
| 73 | MODULE_DEVICE_TABLE(of, cs35l41_of_match); |
| 74 | #endif |
| 75 | |
| 76 | #ifdef CONFIG_ACPI |
| 77 | static const struct acpi_device_id cs35l41_acpi_match[] = { |
| 78 | { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ |
| 79 | {}, |
| 80 | }; |
| 81 | MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); |
| 82 | #endif |
| 83 | |
| 84 | static struct spi_driver cs35l41_spi_driver = { |
| 85 | .driver = { |
| 86 | .name = "cs35l41", |
Charles Keepax | f517ba4 | 2022-01-07 16:06:36 +0000 | [diff] [blame] | 87 | .pm = &cs35l41_pm_ops, |
David Rhodes | 6450ef5 | 2021-09-07 17:57:18 -0500 | [diff] [blame] | 88 | .of_match_table = of_match_ptr(cs35l41_of_match), |
| 89 | .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), |
| 90 | }, |
| 91 | .id_table = cs35l41_id_spi, |
| 92 | .probe = cs35l41_spi_probe, |
| 93 | .remove = cs35l41_spi_remove, |
| 94 | }; |
| 95 | |
| 96 | module_spi_driver(cs35l41_spi_driver); |
| 97 | |
| 98 | MODULE_DESCRIPTION("SPI CS35L41 driver"); |
| 99 | MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>"); |
| 100 | MODULE_LICENSE("GPL"); |