xref: /openbmc/linux/drivers/mfd/arizona-i2c.c (revision 9816d859)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c6f75622SMark Brown /*
3c6f75622SMark Brown  * Arizona-i2c.c  --  Arizona I2C bus interface
4c6f75622SMark Brown  *
5c6f75622SMark Brown  * Copyright 2012 Wolfson Microelectronics plc
6c6f75622SMark Brown  *
7c6f75622SMark Brown  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8c6f75622SMark Brown  */
9c6f75622SMark Brown 
10c6f75622SMark Brown #include <linux/err.h>
11c6f75622SMark Brown #include <linux/i2c.h>
12c6f75622SMark Brown #include <linux/module.h>
13c6f75622SMark Brown #include <linux/pm_runtime.h>
14c6f75622SMark Brown #include <linux/regmap.h>
15c6f75622SMark Brown #include <linux/regulator/consumer.h>
16c6f75622SMark Brown #include <linux/slab.h>
173d6d1d1cSSachin Kamat #include <linux/of.h>
18c6f75622SMark Brown 
19c6f75622SMark Brown #include <linux/mfd/arizona/core.h>
20c6f75622SMark Brown 
21c6f75622SMark Brown #include "arizona.h"
22c6f75622SMark Brown 
arizona_i2c_probe(struct i2c_client * i2c)236cb7ac1cSUwe Kleine-König static int arizona_i2c_probe(struct i2c_client *i2c)
24c6f75622SMark Brown {
256cb7ac1cSUwe Kleine-König 	const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
26039da225SHans de Goede 	const void *match_data;
27c6f75622SMark Brown 	struct arizona *arizona;
28b61c1ec0SRichard Fitzgerald 	const struct regmap_config *regmap_config = NULL;
29039da225SHans de Goede 	unsigned long type = 0;
30942786e6SLee Jones 	int ret;
31c6f75622SMark Brown 
32039da225SHans de Goede 	match_data = device_get_match_data(&i2c->dev);
33039da225SHans de Goede 	if (match_data)
34039da225SHans de Goede 		type = (unsigned long)match_data;
35039da225SHans de Goede 	else if (id)
36d781009cSMark Brown 		type = id->driver_data;
37d781009cSMark Brown 
38d781009cSMark Brown 	switch (type) {
39c6f75622SMark Brown 	case WM5102:
40b61c1ec0SRichard Fitzgerald 		if (IS_ENABLED(CONFIG_MFD_WM5102))
41c6f75622SMark Brown 			regmap_config = &wm5102_i2c_regmap;
42c6f75622SMark Brown 		break;
43e102befeSMark Brown 	case WM5110:
44e5d4ef0dSRichard Fitzgerald 	case WM8280:
45b61c1ec0SRichard Fitzgerald 		if (IS_ENABLED(CONFIG_MFD_WM5110))
46e102befeSMark Brown 			regmap_config = &wm5110_i2c_regmap;
47e102befeSMark Brown 		break;
48dc7d4863SCharles Keepax 	case WM8997:
49b61c1ec0SRichard Fitzgerald 		if (IS_ENABLED(CONFIG_MFD_WM8997))
50dc7d4863SCharles Keepax 			regmap_config = &wm8997_i2c_regmap;
51dc7d4863SCharles Keepax 		break;
526887b042SRichard Fitzgerald 	case WM8998:
536887b042SRichard Fitzgerald 	case WM1814:
54b61c1ec0SRichard Fitzgerald 		if (IS_ENABLED(CONFIG_MFD_WM8998))
556887b042SRichard Fitzgerald 			regmap_config = &wm8998_i2c_regmap;
566887b042SRichard Fitzgerald 		break;
57c6f75622SMark Brown 	default:
582e44e28aSRichard Fitzgerald 		dev_err(&i2c->dev, "Unknown device type %ld\n", type);
59c6f75622SMark Brown 		return -EINVAL;
60c6f75622SMark Brown 	}
61c6f75622SMark Brown 
62b61c1ec0SRichard Fitzgerald 	if (!regmap_config) {
63b61c1ec0SRichard Fitzgerald 		dev_err(&i2c->dev,
64b61c1ec0SRichard Fitzgerald 			"No kernel support for device type %ld\n", type);
65b61c1ec0SRichard Fitzgerald 		return -EINVAL;
66b61c1ec0SRichard Fitzgerald 	}
67b61c1ec0SRichard Fitzgerald 
68c6f75622SMark Brown 	arizona = devm_kzalloc(&i2c->dev, sizeof(*arizona), GFP_KERNEL);
69c6f75622SMark Brown 	if (arizona == NULL)
70c6f75622SMark Brown 		return -ENOMEM;
71c6f75622SMark Brown 
72c6f75622SMark Brown 	arizona->regmap = devm_regmap_init_i2c(i2c, regmap_config);
73c6f75622SMark Brown 	if (IS_ERR(arizona->regmap)) {
74c6f75622SMark Brown 		ret = PTR_ERR(arizona->regmap);
75c6f75622SMark Brown 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
76c6f75622SMark Brown 			ret);
77c6f75622SMark Brown 		return ret;
78c6f75622SMark Brown 	}
79c6f75622SMark Brown 
802e44e28aSRichard Fitzgerald 	arizona->type = type;
81c6f75622SMark Brown 	arizona->dev = &i2c->dev;
82c6f75622SMark Brown 	arizona->irq = i2c->irq;
83c6f75622SMark Brown 
84c6f75622SMark Brown 	return arizona_dev_init(arizona);
85c6f75622SMark Brown }
86c6f75622SMark Brown 
arizona_i2c_remove(struct i2c_client * i2c)87ed5c2f5fSUwe Kleine-König static void arizona_i2c_remove(struct i2c_client *i2c)
88c6f75622SMark Brown {
89c6f75622SMark Brown 	struct arizona *arizona = dev_get_drvdata(&i2c->dev);
909f6e872aSLee Jones 
91c6f75622SMark Brown 	arizona_dev_exit(arizona);
92c6f75622SMark Brown }
93c6f75622SMark Brown 
94c6f75622SMark Brown static const struct i2c_device_id arizona_i2c_id[] = {
95c6f75622SMark Brown 	{ "wm5102", WM5102 },
96e102befeSMark Brown 	{ "wm5110", WM5110 },
97e5d4ef0dSRichard Fitzgerald 	{ "wm8280", WM8280 },
98dc7d4863SCharles Keepax 	{ "wm8997", WM8997 },
996887b042SRichard Fitzgerald 	{ "wm8998", WM8998 },
1006887b042SRichard Fitzgerald 	{ "wm1814", WM1814 },
101c6f75622SMark Brown 	{ }
102c6f75622SMark Brown };
103c6f75622SMark Brown MODULE_DEVICE_TABLE(i2c, arizona_i2c_id);
104c6f75622SMark Brown 
1053f65555cSCharles Keepax #ifdef CONFIG_OF
10610377bb2SCharles Keepax static const struct of_device_id arizona_i2c_of_match[] = {
1073f65555cSCharles Keepax 	{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
1083f65555cSCharles Keepax 	{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
1093f65555cSCharles Keepax 	{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
1103f65555cSCharles Keepax 	{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
1113f65555cSCharles Keepax 	{ .compatible = "wlf,wm8998", .data = (void *)WM8998 },
1123f65555cSCharles Keepax 	{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
1133f65555cSCharles Keepax 	{},
1143f65555cSCharles Keepax };
11588165679SAndré Apitzsch MODULE_DEVICE_TABLE(of, arizona_i2c_of_match);
1163f65555cSCharles Keepax #endif
1173f65555cSCharles Keepax 
118c6f75622SMark Brown static struct i2c_driver arizona_i2c_driver = {
119c6f75622SMark Brown 	.driver = {
120c6f75622SMark Brown 		.name	= "arizona",
12150d3ac7dSPaul Cercueil 		.pm	= pm_ptr(&arizona_pm_ops),
1223f65555cSCharles Keepax 		.of_match_table	= of_match_ptr(arizona_i2c_of_match),
123c6f75622SMark Brown 	},
124*9816d859SUwe Kleine-König 	.probe		= arizona_i2c_probe,
12584449216SBill Pemberton 	.remove		= arizona_i2c_remove,
126c6f75622SMark Brown 	.id_table	= arizona_i2c_id,
127c6f75622SMark Brown };
128c6f75622SMark Brown 
129c6f75622SMark Brown module_i2c_driver(arizona_i2c_driver);
130c6f75622SMark Brown 
13106e577b4SHans de Goede MODULE_SOFTDEP("pre: arizona_ldo1");
132c6f75622SMark Brown MODULE_DESCRIPTION("Arizona I2C bus interface");
133c6f75622SMark Brown MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
134c6f75622SMark Brown MODULE_LICENSE("GPL");
135