1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // |
3 | // cs35l41-i2c.c -- CS35l41 I2C 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/i2c.h> |
12 | #include <linux/init.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/slab.h> |
19 | |
20 | #include "cs35l41.h" |
21 | |
22 | static const struct i2c_device_id cs35l41_id_i2c[] = { |
23 | { "cs35l40" , 0 }, |
24 | { "cs35l41" , 0 }, |
25 | { "cs35l51" , 0 }, |
26 | { "cs35l53" , 0 }, |
27 | {} |
28 | }; |
29 | |
30 | MODULE_DEVICE_TABLE(i2c, cs35l41_id_i2c); |
31 | |
32 | static int cs35l41_i2c_probe(struct i2c_client *client) |
33 | { |
34 | struct cs35l41_private *cs35l41; |
35 | struct device *dev = &client->dev; |
36 | struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(dev); |
37 | const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; |
38 | |
39 | cs35l41 = devm_kzalloc(dev, size: sizeof(struct cs35l41_private), GFP_KERNEL); |
40 | |
41 | if (!cs35l41) |
42 | return -ENOMEM; |
43 | |
44 | cs35l41->dev = dev; |
45 | cs35l41->irq = client->irq; |
46 | |
47 | i2c_set_clientdata(client, data: cs35l41); |
48 | cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config); |
49 | if (IS_ERR(ptr: cs35l41->regmap)) |
50 | return dev_err_probe(dev: cs35l41->dev, err: PTR_ERR(ptr: cs35l41->regmap), |
51 | fmt: "Failed to allocate register map\n" ); |
52 | |
53 | return cs35l41_probe(cs35l41, hw_cfg); |
54 | } |
55 | |
56 | static void cs35l41_i2c_remove(struct i2c_client *client) |
57 | { |
58 | struct cs35l41_private *cs35l41 = i2c_get_clientdata(client); |
59 | |
60 | cs35l41_remove(cs35l41); |
61 | } |
62 | |
63 | #ifdef CONFIG_OF |
64 | static const struct of_device_id cs35l41_of_match[] = { |
65 | { .compatible = "cirrus,cs35l40" }, |
66 | { .compatible = "cirrus,cs35l41" }, |
67 | {}, |
68 | }; |
69 | MODULE_DEVICE_TABLE(of, cs35l41_of_match); |
70 | #endif |
71 | |
72 | #ifdef CONFIG_ACPI |
73 | static const struct acpi_device_id cs35l41_acpi_match[] = { |
74 | { "CSC3541" , 0 }, /* Cirrus Logic PnP ID + part ID */ |
75 | {}, |
76 | }; |
77 | MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); |
78 | #endif |
79 | |
80 | static struct i2c_driver cs35l41_i2c_driver = { |
81 | .driver = { |
82 | .name = "cs35l41" , |
83 | .pm = pm_ptr(&cs35l41_pm_ops), |
84 | .of_match_table = of_match_ptr(cs35l41_of_match), |
85 | .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), |
86 | }, |
87 | .id_table = cs35l41_id_i2c, |
88 | .probe = cs35l41_i2c_probe, |
89 | .remove = cs35l41_i2c_remove, |
90 | }; |
91 | |
92 | module_i2c_driver(cs35l41_i2c_driver); |
93 | |
94 | MODULE_DESCRIPTION("I2C CS35L41 driver" ); |
95 | MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>" ); |
96 | MODULE_LICENSE("GPL" ); |
97 | |