xref: /openbmc/linux/drivers/mfd/arizona-i2c.c (revision d781009c)
1c6f75622SMark Brown /*
2c6f75622SMark Brown  * Arizona-i2c.c  --  Arizona I2C bus interface
3c6f75622SMark Brown  *
4c6f75622SMark Brown  * Copyright 2012 Wolfson Microelectronics plc
5c6f75622SMark Brown  *
6c6f75622SMark Brown  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7c6f75622SMark Brown  *
8c6f75622SMark Brown  * This program is free software; you can redistribute it and/or modify
9c6f75622SMark Brown  * it under the terms of the GNU General Public License version 2 as
10c6f75622SMark Brown  * published by the Free Software Foundation.
11c6f75622SMark Brown  */
12c6f75622SMark Brown 
13c6f75622SMark Brown #include <linux/err.h>
14c6f75622SMark Brown #include <linux/i2c.h>
15c6f75622SMark Brown #include <linux/module.h>
16c6f75622SMark Brown #include <linux/pm_runtime.h>
17c6f75622SMark Brown #include <linux/regmap.h>
18c6f75622SMark Brown #include <linux/regulator/consumer.h>
19c6f75622SMark Brown #include <linux/slab.h>
20c6f75622SMark Brown 
21c6f75622SMark Brown #include <linux/mfd/arizona/core.h>
22c6f75622SMark Brown 
23c6f75622SMark Brown #include "arizona.h"
24c6f75622SMark Brown 
25f791be49SBill Pemberton static int arizona_i2c_probe(struct i2c_client *i2c,
26c6f75622SMark Brown 					  const struct i2c_device_id *id)
27c6f75622SMark Brown {
28c6f75622SMark Brown 	struct arizona *arizona;
29c6f75622SMark Brown 	const struct regmap_config *regmap_config;
30d781009cSMark Brown 	int ret, type;
31c6f75622SMark Brown 
32d781009cSMark Brown 	if (i2c->dev.of_node)
33d781009cSMark Brown 		type = arizona_of_get_type(&i2c->dev);
34d781009cSMark Brown 	else
35d781009cSMark Brown 		type = id->driver_data;
36d781009cSMark Brown 
37d781009cSMark Brown 	switch (type) {
38863df8d5SMark Brown #ifdef CONFIG_MFD_WM5102
39c6f75622SMark Brown 	case WM5102:
40c6f75622SMark Brown 		regmap_config = &wm5102_i2c_regmap;
41c6f75622SMark Brown 		break;
42863df8d5SMark Brown #endif
43e102befeSMark Brown #ifdef CONFIG_MFD_WM5110
44e102befeSMark Brown 	case WM5110:
45e102befeSMark Brown 		regmap_config = &wm5110_i2c_regmap;
46e102befeSMark Brown 		break;
47e102befeSMark Brown #endif
48c6f75622SMark Brown 	default:
49c6f75622SMark Brown 		dev_err(&i2c->dev, "Unknown device type %ld\n",
50c6f75622SMark Brown 			id->driver_data);
51c6f75622SMark Brown 		return -EINVAL;
52c6f75622SMark Brown 	}
53c6f75622SMark Brown 
54c6f75622SMark Brown 	arizona = devm_kzalloc(&i2c->dev, sizeof(*arizona), GFP_KERNEL);
55c6f75622SMark Brown 	if (arizona == NULL)
56c6f75622SMark Brown 		return -ENOMEM;
57c6f75622SMark Brown 
58c6f75622SMark Brown 	arizona->regmap = devm_regmap_init_i2c(i2c, regmap_config);
59c6f75622SMark Brown 	if (IS_ERR(arizona->regmap)) {
60c6f75622SMark Brown 		ret = PTR_ERR(arizona->regmap);
61c6f75622SMark Brown 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
62c6f75622SMark Brown 			ret);
63c6f75622SMark Brown 		return ret;
64c6f75622SMark Brown 	}
65c6f75622SMark Brown 
66c6f75622SMark Brown 	arizona->type = id->driver_data;
67c6f75622SMark Brown 	arizona->dev = &i2c->dev;
68c6f75622SMark Brown 	arizona->irq = i2c->irq;
69c6f75622SMark Brown 
70c6f75622SMark Brown 	return arizona_dev_init(arizona);
71c6f75622SMark Brown }
72c6f75622SMark Brown 
734740f73fSBill Pemberton static int arizona_i2c_remove(struct i2c_client *i2c)
74c6f75622SMark Brown {
75c6f75622SMark Brown 	struct arizona *arizona = dev_get_drvdata(&i2c->dev);
76c6f75622SMark Brown 	arizona_dev_exit(arizona);
77c6f75622SMark Brown 	return 0;
78c6f75622SMark Brown }
79c6f75622SMark Brown 
80c6f75622SMark Brown static const struct i2c_device_id arizona_i2c_id[] = {
81c6f75622SMark Brown 	{ "wm5102", WM5102 },
82e102befeSMark Brown 	{ "wm5110", WM5110 },
83c6f75622SMark Brown 	{ }
84c6f75622SMark Brown };
85c6f75622SMark Brown MODULE_DEVICE_TABLE(i2c, arizona_i2c_id);
86c6f75622SMark Brown 
87c6f75622SMark Brown static struct i2c_driver arizona_i2c_driver = {
88c6f75622SMark Brown 	.driver = {
89c6f75622SMark Brown 		.name	= "arizona",
90c6f75622SMark Brown 		.owner	= THIS_MODULE,
91c6f75622SMark Brown 		.pm	= &arizona_pm_ops,
92d781009cSMark Brown 		.of_match_table	= of_match_ptr(arizona_of_match),
93c6f75622SMark Brown 	},
94c6f75622SMark Brown 	.probe		= arizona_i2c_probe,
9584449216SBill Pemberton 	.remove		= arizona_i2c_remove,
96c6f75622SMark Brown 	.id_table	= arizona_i2c_id,
97c6f75622SMark Brown };
98c6f75622SMark Brown 
99c6f75622SMark Brown module_i2c_driver(arizona_i2c_driver);
100c6f75622SMark Brown 
101c6f75622SMark Brown MODULE_DESCRIPTION("Arizona I2C bus interface");
102c6f75622SMark Brown MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
103c6f75622SMark Brown MODULE_LICENSE("GPL");
104