1
0
Fork 0

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>
hifive-unleashed-5.1
Haojian Zhuang 2010-01-25 06:26:34 -05:00 committed by Samuel Ortiz
parent 1ea933f4cd
commit b13c0df517
1 changed files with 29 additions and 28 deletions

View File

@ -14,27 +14,23 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mfd/max8925.h> #include <linux/mfd/max8925.h>
#define RTC_I2C_ADDR 0x68
#define ADC_I2C_ADDR 0x47
static inline int max8925_read_device(struct i2c_client *i2c, static inline int max8925_read_device(struct i2c_client *i2c,
int reg, int bytes, void *dest) int reg, int bytes, void *dest)
{ {
unsigned char data;
unsigned char *buf;
int ret; int ret;
buf = kzalloc(bytes + 1, GFP_KERNEL); if (bytes > 1)
if (!buf) ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
return -ENOMEM; else {
ret = i2c_smbus_read_byte_data(i2c, reg);
data = (unsigned char)reg; if (ret < 0)
ret = i2c_master_send(i2c, &data, 1); return ret;
if (ret < 0) *(unsigned char *)dest = (unsigned char)ret;
return ret; }
return ret;
ret = i2c_master_recv(i2c, buf, bytes + 1);
if (ret < 0)
return ret;
memcpy(dest, buf, bytes);
return 0;
} }
static inline int max8925_write_device(struct i2c_client *i2c, static inline int max8925_write_device(struct i2c_client *i2c,
@ -55,7 +51,7 @@ static inline int max8925_write_device(struct i2c_client *i2c,
int max8925_reg_read(struct i2c_client *i2c, int reg) int max8925_reg_read(struct i2c_client *i2c, int reg)
{ {
struct max8925_chip *chip = i2c_get_clientdata(i2c); struct max8925_chip *chip = i2c_get_clientdata(i2c);
unsigned char data; unsigned char data = 0;
int ret; int ret;
mutex_lock(&chip->io_lock); mutex_lock(&chip->io_lock);
@ -134,7 +130,7 @@ EXPORT_SYMBOL(max8925_set_bits);
static const struct i2c_device_id max8925_id_table[] = { static const struct i2c_device_id max8925_id_table[] = {
{ "max8925", 0 }, { "max8925", 0 },
{} { },
}; };
MODULE_DEVICE_TABLE(i2c, max8925_id_table); MODULE_DEVICE_TABLE(i2c, max8925_id_table);
@ -142,27 +138,28 @@ static int __devinit max8925_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct max8925_platform_data *pdata = client->dev.platform_data; struct max8925_platform_data *pdata = client->dev.platform_data;
struct max8925_chip *chip; static struct max8925_chip *chip;
if (!pdata) { if (!pdata) {
pr_info("%s: platform data is missing\n", __func__); pr_info("%s: platform data is missing\n", __func__);
return -EINVAL; return -EINVAL;
} }
if ((pdata->chip_id <= MAX8925_INVALID)
|| (pdata->chip_id >= MAX8925_MAX)) {
pr_info("#%s: wrong chip identification\n", __func__);
return -EINVAL;
}
chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
if (chip == NULL) if (chip == NULL)
return -ENOMEM; return -ENOMEM;
chip->i2c = client; chip->i2c = client;
chip->chip_id = pdata->chip_id;
i2c_set_clientdata(client, chip);
chip->dev = &client->dev; chip->dev = &client->dev;
mutex_init(&chip->io_lock); i2c_set_clientdata(client, chip);
dev_set_drvdata(chip->dev, chip); dev_set_drvdata(chip->dev, chip);
mutex_init(&chip->io_lock);
chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
i2c_set_clientdata(chip->rtc, chip);
chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
i2c_set_clientdata(chip->adc, chip);
max8925_device_init(chip, pdata); max8925_device_init(chip, pdata);
return 0; return 0;
@ -173,7 +170,11 @@ static int __devexit max8925_remove(struct i2c_client *client)
struct max8925_chip *chip = i2c_get_clientdata(client); struct max8925_chip *chip = i2c_get_clientdata(client);
max8925_device_exit(chip); max8925_device_exit(chip);
i2c_set_clientdata(client, NULL); i2c_unregister_device(chip->adc);
i2c_unregister_device(chip->rtc);
i2c_set_clientdata(chip->adc, NULL);
i2c_set_clientdata(chip->rtc, NULL);
i2c_set_clientdata(chip->i2c, NULL);
kfree(chip); kfree(chip);
return 0; return 0;
} }