printk: fixup declaration of kmsg_reasons
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / mfd / tps6586x.c
blob4cde31e6a2521863b434260e5651f340f4bfec58
1 /*
2 * Core driver for TI TPS6586x PMIC family
4 * Copyright (c) 2010 CompuLab Ltd.
5 * Mike Rapoport <mike@compulab.co.il>
7 * Based on da903x.c.
8 * Copyright (C) 2008 Compulab, Ltd.
9 * Mike Rapoport <mike@compulab.co.il>
10 * Copyright (C) 2006-2008 Marvell International Ltd.
11 * Eric Miao <eric.miao@marvell.com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/mutex.h>
21 #include <linux/slab.h>
22 #include <linux/gpio.h>
23 #include <linux/i2c.h>
25 #include <linux/mfd/core.h>
26 #include <linux/mfd/tps6586x.h>
28 /* GPIO control registers */
29 #define TPS6586X_GPIOSET1 0x5d
30 #define TPS6586X_GPIOSET2 0x5e
32 /* device id */
33 #define TPS6586X_VERSIONCRC 0xcd
34 #define TPS658621A_VERSIONCRC 0x15
36 struct tps6586x {
37 struct mutex lock;
38 struct device *dev;
39 struct i2c_client *client;
41 struct gpio_chip gpio;
44 static inline int __tps6586x_read(struct i2c_client *client,
45 int reg, uint8_t *val)
47 int ret;
49 ret = i2c_smbus_read_byte_data(client, reg);
50 if (ret < 0) {
51 dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
52 return ret;
55 *val = (uint8_t)ret;
57 return 0;
60 static inline int __tps6586x_reads(struct i2c_client *client, int reg,
61 int len, uint8_t *val)
63 int ret;
65 ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);
66 if (ret < 0) {
67 dev_err(&client->dev, "failed reading from 0x%02x\n", reg);
68 return ret;
71 return 0;
74 static inline int __tps6586x_write(struct i2c_client *client,
75 int reg, uint8_t val)
77 int ret;
79 ret = i2c_smbus_write_byte_data(client, reg, val);
80 if (ret < 0) {
81 dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
82 val, reg);
83 return ret;
86 return 0;
89 static inline int __tps6586x_writes(struct i2c_client *client, int reg,
90 int len, uint8_t *val)
92 int ret;
94 ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);
95 if (ret < 0) {
96 dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
97 return ret;
100 return 0;
103 int tps6586x_write(struct device *dev, int reg, uint8_t val)
105 return __tps6586x_write(to_i2c_client(dev), reg, val);
107 EXPORT_SYMBOL_GPL(tps6586x_write);
109 int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val)
111 return __tps6586x_writes(to_i2c_client(dev), reg, len, val);
113 EXPORT_SYMBOL_GPL(tps6586x_writes);
115 int tps6586x_read(struct device *dev, int reg, uint8_t *val)
117 return __tps6586x_read(to_i2c_client(dev), reg, val);
119 EXPORT_SYMBOL_GPL(tps6586x_read);
121 int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val)
123 return __tps6586x_reads(to_i2c_client(dev), reg, len, val);
125 EXPORT_SYMBOL_GPL(tps6586x_reads);
127 int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
129 struct tps6586x *tps6586x = dev_get_drvdata(dev);
130 uint8_t reg_val;
131 int ret = 0;
133 mutex_lock(&tps6586x->lock);
135 ret = __tps6586x_read(to_i2c_client(dev), reg, &reg_val);
136 if (ret)
137 goto out;
139 if ((reg_val & bit_mask) == 0) {
140 reg_val |= bit_mask;
141 ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val);
143 out:
144 mutex_unlock(&tps6586x->lock);
145 return ret;
147 EXPORT_SYMBOL_GPL(tps6586x_set_bits);
149 int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
151 struct tps6586x *tps6586x = dev_get_drvdata(dev);
152 uint8_t reg_val;
153 int ret = 0;
155 mutex_lock(&tps6586x->lock);
157 ret = __tps6586x_read(to_i2c_client(dev), reg, &reg_val);
158 if (ret)
159 goto out;
161 if (reg_val & bit_mask) {
162 reg_val &= ~bit_mask;
163 ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val);
165 out:
166 mutex_unlock(&tps6586x->lock);
167 return ret;
169 EXPORT_SYMBOL_GPL(tps6586x_clr_bits);
171 int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
173 struct tps6586x *tps6586x = dev_get_drvdata(dev);
174 uint8_t reg_val;
175 int ret = 0;
177 mutex_lock(&tps6586x->lock);
179 ret = __tps6586x_read(tps6586x->client, reg, &reg_val);
180 if (ret)
181 goto out;
183 if ((reg_val & mask) != val) {
184 reg_val = (reg_val & ~mask) | val;
185 ret = __tps6586x_write(tps6586x->client, reg, reg_val);
187 out:
188 mutex_unlock(&tps6586x->lock);
189 return ret;
191 EXPORT_SYMBOL_GPL(tps6586x_update);
193 static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset)
195 struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio);
196 uint8_t val;
197 int ret;
199 ret = __tps6586x_read(tps6586x->client, TPS6586X_GPIOSET2, &val);
200 if (ret)
201 return ret;
203 return !!(val & (1 << offset));
207 static void tps6586x_gpio_set(struct gpio_chip *chip, unsigned offset,
208 int value)
210 struct tps6586x *tps6586x = container_of(chip, struct tps6586x, gpio);
212 __tps6586x_write(tps6586x->client, TPS6586X_GPIOSET2,
213 value << offset);
216 static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
217 int value)
219 struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio);
220 uint8_t val, mask;
222 tps6586x_gpio_set(gc, offset, value);
224 val = 0x1 << (offset * 2);
225 mask = 0x3 << (offset * 2);
227 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask);
230 static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
232 int ret;
234 if (!gpio_base)
235 return;
237 tps6586x->gpio.owner = THIS_MODULE;
238 tps6586x->gpio.label = tps6586x->client->name;
239 tps6586x->gpio.dev = tps6586x->dev;
240 tps6586x->gpio.base = gpio_base;
241 tps6586x->gpio.ngpio = 4;
242 tps6586x->gpio.can_sleep = 1;
244 /* FIXME: add handling of GPIOs as dedicated inputs */
245 tps6586x->gpio.direction_output = tps6586x_gpio_output;
246 tps6586x->gpio.set = tps6586x_gpio_set;
247 tps6586x->gpio.get = tps6586x_gpio_get;
249 ret = gpiochip_add(&tps6586x->gpio);
250 if (ret)
251 dev_warn(tps6586x->dev, "GPIO registration failed: %d\n", ret);
254 static int __remove_subdev(struct device *dev, void *unused)
256 platform_device_unregister(to_platform_device(dev));
257 return 0;
260 static int tps6586x_remove_subdevs(struct tps6586x *tps6586x)
262 return device_for_each_child(tps6586x->dev, NULL, __remove_subdev);
265 static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
266 struct tps6586x_platform_data *pdata)
268 struct tps6586x_subdev_info *subdev;
269 struct platform_device *pdev;
270 int i, ret = 0;
272 for (i = 0; i < pdata->num_subdevs; i++) {
273 subdev = &pdata->subdevs[i];
275 pdev = platform_device_alloc(subdev->name, subdev->id);
277 pdev->dev.parent = tps6586x->dev;
278 pdev->dev.platform_data = subdev->platform_data;
280 ret = platform_device_add(pdev);
281 if (ret)
282 goto failed;
284 return 0;
286 failed:
287 tps6586x_remove_subdevs(tps6586x);
288 return ret;
291 static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
292 const struct i2c_device_id *id)
294 struct tps6586x_platform_data *pdata = client->dev.platform_data;
295 struct tps6586x *tps6586x;
296 int ret;
298 if (!pdata) {
299 dev_err(&client->dev, "tps6586x requires platform data\n");
300 return -ENOTSUPP;
303 ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
304 if (ret < 0) {
305 dev_err(&client->dev, "Chip ID read failed: %d\n", ret);
306 return -EIO;
309 if (ret != TPS658621A_VERSIONCRC) {
310 dev_err(&client->dev, "Unsupported chip ID: %x\n", ret);
311 return -ENODEV;
314 tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL);
315 if (tps6586x == NULL)
316 return -ENOMEM;
318 tps6586x->client = client;
319 tps6586x->dev = &client->dev;
320 i2c_set_clientdata(client, tps6586x);
322 mutex_init(&tps6586x->lock);
324 ret = tps6586x_add_subdevs(tps6586x, pdata);
325 if (ret) {
326 dev_err(&client->dev, "add devices failed: %d\n", ret);
327 goto err_add_devs;
330 tps6586x_gpio_init(tps6586x, pdata->gpio_base);
332 return 0;
334 err_add_devs:
335 kfree(tps6586x);
336 return ret;
339 static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
341 return 0;
344 static const struct i2c_device_id tps6586x_id_table[] = {
345 { "tps6586x", 0 },
346 { },
348 MODULE_DEVICE_TABLE(i2c, tps6586x_id_table);
350 static struct i2c_driver tps6586x_driver = {
351 .driver = {
352 .name = "tps6586x",
353 .owner = THIS_MODULE,
355 .probe = tps6586x_i2c_probe,
356 .remove = __devexit_p(tps6586x_i2c_remove),
357 .id_table = tps6586x_id_table,
360 static int __init tps6586x_init(void)
362 return i2c_add_driver(&tps6586x_driver);
364 subsys_initcall(tps6586x_init);
366 static void __exit tps6586x_exit(void)
368 i2c_del_driver(&tps6586x_driver);
370 module_exit(tps6586x_exit);
372 MODULE_DESCRIPTION("TPS6586X core driver");
373 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
374 MODULE_LICENSE("GPL");