diff options
author | Haojian Zhuang <haojian.zhuang@marvell.com> | 2010-01-25 06:26:34 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-03-07 16:17:15 -0500 |
commit | b13c0df517bedbc40cff4ab5f797b08b1111918b (patch) | |
tree | ec46400a6ea0b85c72901ce5ace06b8f3d4d635b /drivers/mfd/max8925-i2c.c | |
parent | 1ea933f4cdbb88197139b9e62778beba0120e229 (diff) |
mfd: Update i2c driver for max8925
Update I2C driver in order to fit all of three I2C components in max8925.
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/max8925-i2c.c')
-rw-r--r-- | drivers/mfd/max8925-i2c.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 942068e730f9..c0b883c14f41 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c | |||
@@ -14,27 +14,23 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/mfd/max8925.h> | 15 | #include <linux/mfd/max8925.h> |
16 | 16 | ||
17 | #define RTC_I2C_ADDR 0x68 | ||
18 | #define ADC_I2C_ADDR 0x47 | ||
19 | |||
17 | static inline int max8925_read_device(struct i2c_client *i2c, | 20 | static inline int max8925_read_device(struct i2c_client *i2c, |
18 | int reg, int bytes, void *dest) | 21 | int reg, int bytes, void *dest) |
19 | { | 22 | { |
20 | unsigned char data; | ||
21 | unsigned char *buf; | ||
22 | int ret; | 23 | int ret; |
23 | 24 | ||
24 | buf = kzalloc(bytes + 1, GFP_KERNEL); | 25 | if (bytes > 1) |
25 | if (!buf) | 26 | ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest); |
26 | return -ENOMEM; | 27 | else { |
27 | 28 | ret = i2c_smbus_read_byte_data(i2c, reg); | |
28 | data = (unsigned char)reg; | 29 | if (ret < 0) |
29 | ret = i2c_master_send(i2c, &data, 1); | 30 | return ret; |
30 | if (ret < 0) | 31 | *(unsigned char *)dest = (unsigned char)ret; |
31 | return ret; | 32 | } |
32 | 33 | return ret; | |
33 | ret = i2c_master_recv(i2c, buf, bytes + 1); | ||
34 | if (ret < 0) | ||
35 | return ret; | ||
36 | memcpy(dest, buf, bytes); | ||
37 | return 0; | ||
38 | } | 34 | } |
39 | 35 | ||
40 | static inline int max8925_write_device(struct i2c_client *i2c, | 36 | static inline int max8925_write_device(struct i2c_client *i2c, |
@@ -55,7 +51,7 @@ static inline int max8925_write_device(struct i2c_client *i2c, | |||
55 | int max8925_reg_read(struct i2c_client *i2c, int reg) | 51 | int max8925_reg_read(struct i2c_client *i2c, int reg) |
56 | { | 52 | { |
57 | struct max8925_chip *chip = i2c_get_clientdata(i2c); | 53 | struct max8925_chip *chip = i2c_get_clientdata(i2c); |
58 | unsigned char data; | 54 | unsigned char data = 0; |
59 | int ret; | 55 | int ret; |
60 | 56 | ||
61 | mutex_lock(&chip->io_lock); | 57 | mutex_lock(&chip->io_lock); |
@@ -134,7 +130,7 @@ EXPORT_SYMBOL(max8925_set_bits); | |||
134 | 130 | ||
135 | static const struct i2c_device_id max8925_id_table[] = { | 131 | static const struct i2c_device_id max8925_id_table[] = { |
136 | { "max8925", 0 }, | 132 | { "max8925", 0 }, |
137 | {} | 133 | { }, |
138 | }; | 134 | }; |
139 | MODULE_DEVICE_TABLE(i2c, max8925_id_table); | 135 | MODULE_DEVICE_TABLE(i2c, max8925_id_table); |
140 | 136 | ||
@@ -142,27 +138,28 @@ static int __devinit max8925_probe(struct i2c_client *client, | |||
142 | const struct i2c_device_id *id) | 138 | const struct i2c_device_id *id) |
143 | { | 139 | { |
144 | struct max8925_platform_data *pdata = client->dev.platform_data; | 140 | struct max8925_platform_data *pdata = client->dev.platform_data; |
145 | struct max8925_chip *chip; | 141 | static struct max8925_chip *chip; |
146 | 142 | ||
147 | if (!pdata) { | 143 | if (!pdata) { |
148 | pr_info("%s: platform data is missing\n", __func__); | 144 | pr_info("%s: platform data is missing\n", __func__); |
149 | return -EINVAL; | 145 | return -EINVAL; |
150 | } | 146 | } |
151 | if ((pdata->chip_id <= MAX8925_INVALID) | ||
152 | || (pdata->chip_id >= MAX8925_MAX)) { | ||
153 | pr_info("#%s: wrong chip identification\n", __func__); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | 147 | ||
157 | chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); | 148 | chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); |
158 | if (chip == NULL) | 149 | if (chip == NULL) |
159 | return -ENOMEM; | 150 | return -ENOMEM; |
160 | chip->i2c = client; | 151 | chip->i2c = client; |
161 | chip->chip_id = pdata->chip_id; | ||
162 | i2c_set_clientdata(client, chip); | ||
163 | chip->dev = &client->dev; | 152 | chip->dev = &client->dev; |
164 | mutex_init(&chip->io_lock); | 153 | i2c_set_clientdata(client, chip); |
165 | dev_set_drvdata(chip->dev, 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 | |||
166 | max8925_device_init(chip, pdata); | 163 | max8925_device_init(chip, pdata); |
167 | 164 | ||
168 | return 0; | 165 | return 0; |
@@ -173,7 +170,11 @@ static int __devexit max8925_remove(struct i2c_client *client) | |||
173 | struct max8925_chip *chip = i2c_get_clientdata(client); | 170 | struct max8925_chip *chip = i2c_get_clientdata(client); |
174 | 171 | ||
175 | max8925_device_exit(chip); | 172 | max8925_device_exit(chip); |
176 | i2c_set_clientdata(client, NULL); | 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); | ||
177 | kfree(chip); | 178 | kfree(chip); |
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |