-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 261870 b: refs/heads/master c: 36e5287 h: refs/heads/master v: v3
- Loading branch information
Margarita Olaya
authored and
Samuel Ortiz
committed
Jul 31, 2011
1 parent
d3cd6bf
commit fe127fd
Showing
7 changed files
with
793 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 8504d638041d50901b8bfba4fe646bd0bbb5cbb9 | ||
refs/heads/master: 36e52873c6393b569f2befcdd1847929211892b8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/* | ||
* tps65912-core.c -- TI TPS65912x | ||
* | ||
* Copyright 2011 Texas Instruments Inc. | ||
* | ||
* Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. | ||
* | ||
* This driver is based on wm8350 implementation. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/moduleparam.h> | ||
#include <linux/init.h> | ||
#include <linux/slab.h> | ||
#include <linux/gpio.h> | ||
#include <linux/mfd/core.h> | ||
#include <linux/mfd/tps65912.h> | ||
|
||
static struct mfd_cell tps65912s[] = { | ||
{ | ||
.name = "tps65912-pmic", | ||
}, | ||
}; | ||
|
||
int tps65912_set_bits(struct tps65912 *tps65912, u8 reg, u8 mask) | ||
{ | ||
u8 data; | ||
int err; | ||
|
||
mutex_lock(&tps65912->io_mutex); | ||
|
||
err = tps65912->read(tps65912, reg, 1, &data); | ||
if (err) { | ||
dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | ||
goto out; | ||
} | ||
|
||
data |= mask; | ||
err = tps65912->write(tps65912, reg, 1, &data); | ||
if (err) | ||
dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); | ||
|
||
out: | ||
mutex_unlock(&tps65912->io_mutex); | ||
return err; | ||
} | ||
EXPORT_SYMBOL_GPL(tps65912_set_bits); | ||
|
||
int tps65912_clear_bits(struct tps65912 *tps65912, u8 reg, u8 mask) | ||
{ | ||
u8 data; | ||
int err; | ||
|
||
mutex_lock(&tps65912->io_mutex); | ||
err = tps65912->read(tps65912, reg, 1, &data); | ||
if (err) { | ||
dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | ||
goto out; | ||
} | ||
|
||
data &= ~mask; | ||
err = tps65912->write(tps65912, reg, 1, &data); | ||
if (err) | ||
dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg); | ||
|
||
out: | ||
mutex_unlock(&tps65912->io_mutex); | ||
return err; | ||
} | ||
EXPORT_SYMBOL_GPL(tps65912_clear_bits); | ||
|
||
static inline int tps65912_read(struct tps65912 *tps65912, u8 reg) | ||
{ | ||
u8 val; | ||
int err; | ||
|
||
err = tps65912->read(tps65912, reg, 1, &val); | ||
if (err < 0) | ||
return err; | ||
|
||
return val; | ||
} | ||
|
||
static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val) | ||
{ | ||
return tps65912->write(tps65912, reg, 1, &val); | ||
} | ||
|
||
int tps65912_reg_read(struct tps65912 *tps65912, u8 reg) | ||
{ | ||
int data; | ||
|
||
mutex_lock(&tps65912->io_mutex); | ||
|
||
data = tps65912_read(tps65912, reg); | ||
if (data < 0) | ||
dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg); | ||
|
||
mutex_unlock(&tps65912->io_mutex); | ||
return data; | ||
} | ||
EXPORT_SYMBOL_GPL(tps65912_reg_read); | ||
|
||
int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val) | ||
{ | ||
int err; | ||
|
||
mutex_lock(&tps65912->io_mutex); | ||
|
||
err = tps65912_write(tps65912, reg, val); | ||
if (err < 0) | ||
dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg); | ||
|
||
mutex_unlock(&tps65912->io_mutex); | ||
return err; | ||
} | ||
EXPORT_SYMBOL_GPL(tps65912_reg_write); | ||
|
||
int tps65912_device_init(struct tps65912 *tps65912) | ||
{ | ||
struct tps65912_board *pmic_plat_data = tps65912->dev->platform_data; | ||
int ret, dcdc_avs, value; | ||
|
||
mutex_init(&tps65912->io_mutex); | ||
dev_set_drvdata(tps65912->dev, tps65912); | ||
|
||
dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 | | ||
pmic_plat_data->is_dcdc2_avs << 1 | | ||
pmic_plat_data->is_dcdc3_avs << 2 | | ||
pmic_plat_data->is_dcdc4_avs << 3); | ||
if (dcdc_avs) { | ||
tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value); | ||
dcdc_avs |= value; | ||
tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs); | ||
} | ||
|
||
ret = mfd_add_devices(tps65912->dev, -1, | ||
tps65912s, ARRAY_SIZE(tps65912s), | ||
NULL, 0); | ||
if (ret < 0) | ||
goto err; | ||
|
||
return ret; | ||
|
||
err: | ||
mfd_remove_devices(tps65912->dev); | ||
kfree(tps65912); | ||
return ret; | ||
} | ||
|
||
void tps65912_device_exit(struct tps65912 *tps65912) | ||
{ | ||
mfd_remove_devices(tps65912->dev); | ||
kfree(tps65912); | ||
} | ||
|
||
MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); | ||
MODULE_DESCRIPTION("TPS65912x chip family multi-function driver"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* tps65912-i2c.c -- I2C access for TI TPS65912x PMIC | ||
* | ||
* Copyright 2011 Texas Instruments Inc. | ||
* | ||
* Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. | ||
* | ||
* This driver is based on wm8350 implementation. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/moduleparam.h> | ||
#include <linux/init.h> | ||
#include <linux/slab.h> | ||
#include <linux/gpio.h> | ||
#include <linux/i2c.h> | ||
#include <linux/mfd/core.h> | ||
#include <linux/mfd/tps65912.h> | ||
|
||
static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg, | ||
int bytes, void *dest) | ||
{ | ||
struct i2c_client *i2c = tps65912->control_data; | ||
struct i2c_msg xfer[2]; | ||
int ret; | ||
|
||
/* Write register */ | ||
xfer[0].addr = i2c->addr; | ||
xfer[0].flags = 0; | ||
xfer[0].len = 1; | ||
xfer[0].buf = ® | ||
|
||
/* Read data */ | ||
xfer[1].addr = i2c->addr; | ||
xfer[1].flags = I2C_M_RD; | ||
xfer[1].len = bytes; | ||
xfer[1].buf = dest; | ||
|
||
ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
if (ret == 2) | ||
ret = 0; | ||
else if (ret >= 0) | ||
ret = -EIO; | ||
return ret; | ||
} | ||
|
||
static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg, | ||
int bytes, void *src) | ||
{ | ||
struct i2c_client *i2c = tps65912->control_data; | ||
/* we add 1 byte for device register */ | ||
u8 msg[TPS6591X_MAX_REGISTER + 1]; | ||
int ret; | ||
|
||
if (bytes > (TPS6591X_MAX_REGISTER + 1)) | ||
return -EINVAL; | ||
|
||
msg[0] = reg; | ||
memcpy(&msg[1], src, bytes); | ||
|
||
ret = i2c_master_send(i2c, msg, bytes + 1); | ||
if (ret < 0) | ||
return ret; | ||
if (ret != bytes + 1) | ||
return -EIO; | ||
|
||
return 0; | ||
} | ||
|
||
static int tps65912_i2c_probe(struct i2c_client *i2c, | ||
const struct i2c_device_id *id) | ||
{ | ||
struct tps65912 *tps65912; | ||
|
||
tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); | ||
if (tps65912 == NULL) | ||
return -ENOMEM; | ||
|
||
i2c_set_clientdata(i2c, tps65912); | ||
tps65912->dev = &i2c->dev; | ||
tps65912->control_data = i2c; | ||
tps65912->read = tps65912_i2c_read; | ||
tps65912->write = tps65912_i2c_write; | ||
|
||
return tps65912_device_init(tps65912); | ||
} | ||
|
||
static int tps65912_i2c_remove(struct i2c_client *i2c) | ||
{ | ||
struct tps65912 *tps65912 = i2c_get_clientdata(i2c); | ||
|
||
tps65912_device_exit(tps65912); | ||
|
||
return 0; | ||
} | ||
|
||
static const struct i2c_device_id tps65912_i2c_id[] = { | ||
{"tps65912", 0 }, | ||
{ } | ||
}; | ||
MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id); | ||
|
||
static struct i2c_driver tps65912_i2c_driver = { | ||
.driver = { | ||
.name = "tps65912", | ||
.owner = THIS_MODULE, | ||
}, | ||
.probe = tps65912_i2c_probe, | ||
.remove = tps65912_i2c_remove, | ||
.id_table = tps65912_i2c_id, | ||
}; | ||
|
||
static int __init tps65912_i2c_init(void) | ||
{ | ||
int ret; | ||
|
||
ret = i2c_add_driver(&tps65912_i2c_driver); | ||
if (ret != 0) | ||
pr_err("Failed to register TPS65912 I2C driver: %d\n", ret); | ||
|
||
return ret; | ||
} | ||
/* init early so consumer devices can complete system boot */ | ||
subsys_initcall(tps65912_i2c_init); | ||
|
||
static void __exit tps65912_i2c_exit(void) | ||
{ | ||
i2c_del_driver(&tps65912_i2c_driver); | ||
} | ||
module_exit(tps65912_i2c_exit); | ||
|
||
MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); | ||
MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); | ||
MODULE_LICENSE("GPL"); |
Oops, something went wrong.