Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / mfd / max8925-i2c.c
1 /*
2  * I2C driver for Maxim MAX8925
3  *
4  * Copyright (C) 2009 Marvell International Ltd.
5  *      Haojian Zhuang <haojian.zhuang@marvell.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/i2c.h>
15 #include <linux/mfd/max8925.h>
16
17 #define RTC_I2C_ADDR            0x68
18 #define ADC_I2C_ADDR            0x47
19
20 static inline int max8925_read_device(struct i2c_client *i2c,
21                                       int reg, int bytes, void *dest)
22 {
23         int ret;
24
25         if (bytes > 1)
26                 ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
27         else {
28                 ret = i2c_smbus_read_byte_data(i2c, reg);
29                 if (ret < 0)
30                         return ret;
31                 *(unsigned char *)dest = (unsigned char)ret;
32         }
33         return ret;
34 }
35
36 static inline int max8925_write_device(struct i2c_client *i2c,
37                                        int reg, int bytes, void *src)
38 {
39         unsigned char buf[bytes + 1];
40         int ret;
41
42         buf[0] = (unsigned char)reg;
43         memcpy(&buf[1], src, bytes);
44
45         ret = i2c_master_send(i2c, buf, bytes + 1);
46         if (ret < 0)
47                 return ret;
48         return 0;
49 }
50
51 int max8925_reg_read(struct i2c_client *i2c, int reg)
52 {
53         struct max8925_chip *chip = i2c_get_clientdata(i2c);
54         unsigned char data = 0;
55         int ret;
56
57         mutex_lock(&chip->io_lock);
58         ret = max8925_read_device(i2c, reg, 1, &data);
59         mutex_unlock(&chip->io_lock);
60
61         if (ret < 0)
62                 return ret;
63         else
64                 return (int)data;
65 }
66 EXPORT_SYMBOL(max8925_reg_read);
67
68 int max8925_reg_write(struct i2c_client *i2c, int reg,
69                 unsigned char data)
70 {
71         struct max8925_chip *chip = i2c_get_clientdata(i2c);
72         int ret;
73
74         mutex_lock(&chip->io_lock);
75         ret = max8925_write_device(i2c, reg, 1, &data);
76         mutex_unlock(&chip->io_lock);
77
78         return ret;
79 }
80 EXPORT_SYMBOL(max8925_reg_write);
81
82 int max8925_bulk_read(struct i2c_client *i2c, int reg,
83                 int count, unsigned char *buf)
84 {
85         struct max8925_chip *chip = i2c_get_clientdata(i2c);
86         int ret;
87
88         mutex_lock(&chip->io_lock);
89         ret = max8925_read_device(i2c, reg, count, buf);
90         mutex_unlock(&chip->io_lock);
91
92         return ret;
93 }
94 EXPORT_SYMBOL(max8925_bulk_read);
95
96 int max8925_bulk_write(struct i2c_client *i2c, int reg,
97                 int count, unsigned char *buf)
98 {
99         struct max8925_chip *chip = i2c_get_clientdata(i2c);
100         int ret;
101
102         mutex_lock(&chip->io_lock);
103         ret = max8925_write_device(i2c, reg, count, buf);
104         mutex_unlock(&chip->io_lock);
105
106         return ret;
107 }
108 EXPORT_SYMBOL(max8925_bulk_write);
109
110 int max8925_set_bits(struct i2c_client *i2c, int reg,
111                 unsigned char mask, unsigned char data)
112 {
113         struct max8925_chip *chip = i2c_get_clientdata(i2c);
114         unsigned char value;
115         int ret;
116
117         mutex_lock(&chip->io_lock);
118         ret = max8925_read_device(i2c, reg, 1, &value);
119         if (ret < 0)
120                 goto out;
121         value &= ~mask;
122         value |= data;
123         ret = max8925_write_device(i2c, reg, 1, &value);
124 out:
125         mutex_unlock(&chip->io_lock);
126         return ret;
127 }
128 EXPORT_SYMBOL(max8925_set_bits);
129
130
131 static const struct i2c_device_id max8925_id_table[] = {
132         { "max8925", 0 },
133         { },
134 };
135 MODULE_DEVICE_TABLE(i2c, max8925_id_table);
136
137 static int __devinit max8925_probe(struct i2c_client *client,
138                                    const struct i2c_device_id *id)
139 {
140         struct max8925_platform_data *pdata = client->dev.platform_data;
141         static struct max8925_chip *chip;
142
143         if (!pdata) {
144                 pr_info("%s: platform data is missing\n", __func__);
145                 return -EINVAL;
146         }
147
148         chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
149         if (chip == NULL)
150                 return -ENOMEM;
151         chip->i2c = client;
152         chip->dev = &client->dev;
153         i2c_set_clientdata(client, chip);
154         dev_set_drvdata(chip->dev, chip);
155         mutex_init(&chip->io_lock);
156
157         chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
158         i2c_set_clientdata(chip->rtc, chip);
159
160         chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
161         i2c_set_clientdata(chip->adc, chip);
162
163         max8925_device_init(chip, pdata);
164
165         return 0;
166 }
167
168 static int __devexit max8925_remove(struct i2c_client *client)
169 {
170         struct max8925_chip *chip = i2c_get_clientdata(client);
171
172         max8925_device_exit(chip);
173         i2c_unregister_device(chip->adc);
174         i2c_unregister_device(chip->rtc);
175         i2c_set_clientdata(chip->adc, NULL);
176         i2c_set_clientdata(chip->rtc, NULL);
177         i2c_set_clientdata(chip->i2c, NULL);
178         kfree(chip);
179         return 0;
180 }
181
182 static struct i2c_driver max8925_driver = {
183         .driver = {
184                 .name   = "max8925",
185                 .owner  = THIS_MODULE,
186         },
187         .probe          = max8925_probe,
188         .remove         = __devexit_p(max8925_remove),
189         .id_table       = max8925_id_table,
190 };
191
192 static int __init max8925_i2c_init(void)
193 {
194         int ret;
195
196         ret = i2c_add_driver(&max8925_driver);
197         if (ret != 0)
198                 pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
199         return ret;
200 }
201 subsys_initcall(max8925_i2c_init);
202
203 static void __exit max8925_i2c_exit(void)
204 {
205         i2c_del_driver(&max8925_driver);
206 }
207 module_exit(max8925_i2c_exit);
208
209 MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
210 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
211 MODULE_LICENSE("GPL");