1/* 2 * tps65912-i2c.c -- I2C access for TI TPS65912x PMIC 3 * 4 * Copyright 2011 Texas Instruments Inc. 5 * 6 * Author: Margarita Olaya Cabrera <magi@slimlogic.co.uk> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This driver is based on wm8350 implementation. 14 */ 15 16#include <linux/module.h> 17#include <linux/moduleparam.h> 18#include <linux/init.h> 19#include <linux/slab.h> 20#include <linux/gpio.h> 21#include <linux/i2c.h> 22#include <linux/mfd/core.h> 23#include <linux/mfd/tps65912.h> 24 25static int tps65912_i2c_read(struct tps65912 *tps65912, u8 reg, 26 int bytes, void *dest) 27{ 28 struct i2c_client *i2c = tps65912->control_data; 29 struct i2c_msg xfer[2]; 30 int ret; 31 32 /* Write register */ 33 xfer[0].addr = i2c->addr; 34 xfer[0].flags = 0; 35 xfer[0].len = 1; 36 xfer[0].buf = ® 37 38 /* Read data */ 39 xfer[1].addr = i2c->addr; 40 xfer[1].flags = I2C_M_RD; 41 xfer[1].len = bytes; 42 xfer[1].buf = dest; 43 44 ret = i2c_transfer(i2c->adapter, xfer, 2); 45 if (ret == 2) 46 ret = 0; 47 else if (ret >= 0) 48 ret = -EIO; 49 return ret; 50} 51 52static int tps65912_i2c_write(struct tps65912 *tps65912, u8 reg, 53 int bytes, void *src) 54{ 55 struct i2c_client *i2c = tps65912->control_data; 56 /* we add 1 byte for device register */ 57 u8 msg[TPS6591X_MAX_REGISTER + 1]; 58 int ret; 59 60 if (bytes > TPS6591X_MAX_REGISTER) 61 return -EINVAL; 62 63 msg[0] = reg; 64 memcpy(&msg[1], src, bytes); 65 66 ret = i2c_master_send(i2c, msg, bytes + 1); 67 if (ret < 0) 68 return ret; 69 if (ret != bytes + 1) 70 return -EIO; 71 72 return 0; 73} 74 75static int tps65912_i2c_probe(struct i2c_client *i2c, 76 const struct i2c_device_id *id) 77{ 78 struct tps65912 *tps65912; 79 80 tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); 81 if (tps65912 == NULL) 82 return -ENOMEM; 83 84 i2c_set_clientdata(i2c, tps65912); 85 tps65912->dev = &i2c->dev; 86 tps65912->control_data = i2c; 87 tps65912->read = tps65912_i2c_read; 88 tps65912->write = tps65912_i2c_write; 89 90 return tps65912_device_init(tps65912); 91} 92 93static int tps65912_i2c_remove(struct i2c_client *i2c) 94{ 95 struct tps65912 *tps65912 = i2c_get_clientdata(i2c); 96 97 tps65912_device_exit(tps65912); 98 99 return 0; 100} 101 102static const struct i2c_device_id tps65912_i2c_id[] = { 103 {"tps65912", 0 }, 104 { } 105}; 106MODULE_DEVICE_TABLE(i2c, tps65912_i2c_id); 107 108static struct i2c_driver tps65912_i2c_driver = { 109 .driver = { 110 .name = "tps65912", 111 .owner = THIS_MODULE, 112 }, 113 .probe = tps65912_i2c_probe, 114 .remove = tps65912_i2c_remove, 115 .id_table = tps65912_i2c_id, 116}; 117 118static int __init tps65912_i2c_init(void) 119{ 120 int ret; 121 122 ret = i2c_add_driver(&tps65912_i2c_driver); 123 if (ret != 0) 124 pr_err("Failed to register TPS65912 I2C driver: %d\n", ret); 125 126 return ret; 127} 128/* init early so consumer devices can complete system boot */ 129subsys_initcall(tps65912_i2c_init); 130 131static void __exit tps65912_i2c_exit(void) 132{ 133 i2c_del_driver(&tps65912_i2c_driver); 134} 135module_exit(tps65912_i2c_exit); 136 137MODULE_AUTHOR("Margarita Olaya <magi@slimlogic.co.uk>"); 138MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); 139MODULE_LICENSE("GPL"); 140