1*cb626376SJames Ogletree // SPDX-License-Identifier: GPL-2.0 2*cb626376SJames Ogletree /* 3*cb626376SJames Ogletree * CS40L50 Advanced Haptic Driver with waveform memory, 4*cb626376SJames Ogletree * integrated DSP, and closed-loop algorithms 5*cb626376SJames Ogletree * 6*cb626376SJames Ogletree * Copyright 2024 Cirrus Logic, Inc. 7*cb626376SJames Ogletree * 8*cb626376SJames Ogletree * Author: James Ogletree <james.ogletree@cirrus.com> 9*cb626376SJames Ogletree */ 10*cb626376SJames Ogletree 11*cb626376SJames Ogletree #include <linux/mfd/cs40l50.h> 12*cb626376SJames Ogletree #include <linux/spi/spi.h> 13*cb626376SJames Ogletree 14*cb626376SJames Ogletree static int cs40l50_spi_probe(struct spi_device *spi) 15*cb626376SJames Ogletree { 16*cb626376SJames Ogletree struct cs40l50 *cs40l50; 17*cb626376SJames Ogletree 18*cb626376SJames Ogletree cs40l50 = devm_kzalloc(&spi->dev, sizeof(*cs40l50), GFP_KERNEL); 19*cb626376SJames Ogletree if (!cs40l50) 20*cb626376SJames Ogletree return -ENOMEM; 21*cb626376SJames Ogletree 22*cb626376SJames Ogletree spi_set_drvdata(spi, cs40l50); 23*cb626376SJames Ogletree 24*cb626376SJames Ogletree cs40l50->dev = &spi->dev; 25*cb626376SJames Ogletree cs40l50->irq = spi->irq; 26*cb626376SJames Ogletree 27*cb626376SJames Ogletree cs40l50->regmap = devm_regmap_init_spi(spi, &cs40l50_regmap); 28*cb626376SJames Ogletree if (IS_ERR(cs40l50->regmap)) 29*cb626376SJames Ogletree return dev_err_probe(cs40l50->dev, PTR_ERR(cs40l50->regmap), 30*cb626376SJames Ogletree "Failed to initialize register map\n"); 31*cb626376SJames Ogletree 32*cb626376SJames Ogletree return cs40l50_probe(cs40l50); 33*cb626376SJames Ogletree } 34*cb626376SJames Ogletree 35*cb626376SJames Ogletree static void cs40l50_spi_remove(struct spi_device *spi) 36*cb626376SJames Ogletree { 37*cb626376SJames Ogletree struct cs40l50 *cs40l50 = spi_get_drvdata(spi); 38*cb626376SJames Ogletree 39*cb626376SJames Ogletree cs40l50_remove(cs40l50); 40*cb626376SJames Ogletree } 41*cb626376SJames Ogletree 42*cb626376SJames Ogletree static const struct spi_device_id cs40l50_id_spi[] = { 43*cb626376SJames Ogletree { "cs40l50" }, 44*cb626376SJames Ogletree {} 45*cb626376SJames Ogletree }; 46*cb626376SJames Ogletree MODULE_DEVICE_TABLE(spi, cs40l50_id_spi); 47*cb626376SJames Ogletree 48*cb626376SJames Ogletree static const struct of_device_id cs40l50_of_match[] = { 49*cb626376SJames Ogletree { .compatible = "cirrus,cs40l50" }, 50*cb626376SJames Ogletree {} 51*cb626376SJames Ogletree }; 52*cb626376SJames Ogletree MODULE_DEVICE_TABLE(of, cs40l50_of_match); 53*cb626376SJames Ogletree 54*cb626376SJames Ogletree static struct spi_driver cs40l50_spi_driver = { 55*cb626376SJames Ogletree .driver = { 56*cb626376SJames Ogletree .name = "cs40l50", 57*cb626376SJames Ogletree .of_match_table = cs40l50_of_match, 58*cb626376SJames Ogletree .pm = pm_ptr(&cs40l50_pm_ops), 59*cb626376SJames Ogletree }, 60*cb626376SJames Ogletree .id_table = cs40l50_id_spi, 61*cb626376SJames Ogletree .probe = cs40l50_spi_probe, 62*cb626376SJames Ogletree .remove = cs40l50_spi_remove, 63*cb626376SJames Ogletree }; 64*cb626376SJames Ogletree module_spi_driver(cs40l50_spi_driver); 65*cb626376SJames Ogletree 66*cb626376SJames Ogletree MODULE_DESCRIPTION("CS40L50 SPI Driver"); 67*cb626376SJames Ogletree MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. <james.ogletree@cirrus.com>"); 68*cb626376SJames Ogletree MODULE_LICENSE("GPL"); 69