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