1 /* 2 * Core driver for TI TPS6586x PMIC family 3 * 4 * Copyright (c) 2010 CompuLab Ltd. 5 * Mike Rapoport <mike@compulab.co.il> 6 * 7 * Based on da903x.c. 8 * Copyright (C) 2008 Compulab, Ltd. 9 * Mike Rapoport <mike@compulab.co.il> 10 * Copyright (C) 2006-2008 Marvell International Ltd. 11 * Eric Miao <eric.miao@marvell.com> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License version 2 as 15 * published by the Free Software Foundation. 16 */ 17 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/mutex.h> 21 #include <linux/slab.h> 22 #include <linux/gpio.h> 23 #include <linux/i2c.h> 24 25 #include <linux/mfd/core.h> 26 #include <linux/mfd/tps6586x.h> 27 28 /* GPIO control registers */ 29 #define TPS6586X_GPIOSET1 0x5d 30 #define TPS6586X_GPIOSET2 0x5e 31 32 /* device id */ 33 #define TPS6586X_VERSIONCRC 0xcd 34 #define TPS658621A_VERSIONCRC 0x15 35 36 struct tps6586x { 37 struct mutex lock; 38 struct device *dev; 39 struct i2c_client *client; 40 41 struct gpio_chip gpio; 42 }; 43 44 static inline int __tps6586x_read(struct i2c_client *client, 45 int reg, uint8_t *val) 46 { 47 int ret; 48 49 ret = i2c_smbus_read_byte_data(client, reg); 50 if (ret < 0) { 51 dev_err(&client->dev, "failed reading at 0x%02x\n", reg); 52 return ret; 53 } 54 55 *val = (uint8_t)ret; 56 57 return 0; 58 } 59 60 static inline int __tps6586x_reads(struct i2c_client *client, int reg, 61 int len, uint8_t *val) 62 { 63 int ret; 64 65 ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); 66 if (ret < 0) { 67 dev_err(&client->dev, "failed reading from 0x%02x\n", reg); 68 return ret; 69 } 70 71 return 0; 72 } 73 74 static inline int __tps6586x_write(struct i2c_client *client, 75 int reg, uint8_t val) 76 { 77 int ret; 78 79 ret = i2c_smbus_write_byte_data(client, reg, val); 80 if (ret < 0) { 81 dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", 82 val, reg); 83 return ret; 84 } 85 86 return 0; 87 } 88 89 static inline int __tps6586x_writes(struct i2c_client *client, int reg, 90 int len, uint8_t *val) 91 { 92 int ret; 93 94 ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); 95 if (ret < 0) { 96 dev_err(&client->dev, "failed writings to 0x%02x\n", reg); 97 return ret; 98 } 99 100 return 0; 101 } 102 103 int tps6586x_write(struct device *dev, int reg, uint8_t val) 104 { 105 return __tps6586x_write(to_i2c_client(dev), reg, val); 106 } 107 EXPORT_SYMBOL_GPL(tps6586x_write); 108 109 int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val) 110 { 111 return __tps6586x_writes(to_i2c_client(dev), reg, len, val); 112 } 113 EXPORT_SYMBOL_GPL(tps6586x_writes); 114 115 int tps6586x_read(struct device *dev, int reg, uint8_t *val) 116 { 117 return __tps6586x_read(to_i2c_client(dev), reg, val); 118 } 119 EXPORT_SYMBOL_GPL(tps6586x_read); 120 121 int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val) 122 { 123 return __tps6586x_reads(to_i2c_client(dev), reg, len, val); 124 } 125 EXPORT_SYMBOL_GPL(tps6586x_reads); 126 127 int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) 128 { 129 struct tps6586x *tps6586x = dev_get_drvdata(dev); 130 uint8_t reg_val; 131 int ret = 0; 132 133 mutex_lock(&tps6586x->lock); 134 135 ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); 136 if (ret) 137 goto out; 138 139 if ((reg_val & bit_mask) == 0) { 140 reg_val |= bit_mask; 141 ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); 142 } 143 out: 144 mutex_unlock(&tps6586x->lock); 145 return ret; 146 } 147 EXPORT_SYMBOL_GPL(tps6586x_set_bits); 148 149 int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) 150 { 151 struct tps6586x *tps6586x = dev_get_drvdata(dev); 152 uint8_t reg_val; 153 int ret = 0; 154 155 mutex_lock(&tps6586x->lock); 156 157 ret = __tps6586x_read(to_i2c_client(dev), reg, ®_val); 158 if (ret) 159 goto out; 160 161 if (reg_val & bit_mask) { 162 reg_val &= ~bit_mask; 163 ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); 164 } 165 out: 166 mutex_unlock(&tps6586x->lock); 167 return ret; 168 } 169 EXPORT_SYMBOL_GPL(tps6586x_clr_bits); 170 171 int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) 172 { 173 struct tps6586x *tps6586x = dev_get_drvdata(dev); 174 uint8_t reg_val; 175 int ret = 0; 176 177 mutex_lock(&tps6586x->lock); 178 179 ret = __tps6586x_read(tps6586x->client, reg, ®_val); 180 if (ret) 181 goto out; 182 183 if ((reg_val & mask) != val) { 184 reg_val = (reg_val & ~mask) | val; 185 ret = __tps6586x_write(tps6586x->client, reg, reg_val); 186 } 187 out: 188 mutex_unlock(&tps6586x->lock); 189 return ret; 190 } 191 EXPORT_SYMBOL_GPL(tps6586x_update); 192 193 static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) 194 { 195 struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio); 196 uint8_t val; 197 int ret; 198 199 ret = __tps6586x_read(tps6586x->client, TPS6586X_GPIOSET2, &val); 200 if (ret) 201 return ret; 202 203 return !!(val & (1 << offset)); 204 } 205 206 207 static void tps6586x_gpio_set(struct gpio_chip *chip, unsigned offset, 208 int value) 209 { 210 struct tps6586x *tps6586x = container_of(chip, struct tps6586x, gpio); 211 212 __tps6586x_write(tps6586x->client, TPS6586X_GPIOSET2, 213 value << offset); 214 } 215 216 static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, 217 int value) 218 { 219 struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio); 220 uint8_t val, mask; 221 222 tps6586x_gpio_set(gc, offset, value); 223 224 val = 0x1 << (offset * 2); 225 mask = 0x3 << (offset * 2); 226 227 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask); 228 } 229 230 static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) 231 { 232 int ret; 233 234 if (!gpio_base) 235 return; 236 237 tps6586x->gpio.owner = THIS_MODULE; 238 tps6586x->gpio.label = tps6586x->client->name; 239 tps6586x->gpio.dev = tps6586x->dev; 240 tps6586x->gpio.base = gpio_base; 241 tps6586x->gpio.ngpio = 4; 242 tps6586x->gpio.can_sleep = 1; 243 244 /* FIXME: add handling of GPIOs as dedicated inputs */ 245 tps6586x->gpio.direction_output = tps6586x_gpio_output; 246 tps6586x->gpio.set = tps6586x_gpio_set; 247 tps6586x->gpio.get = tps6586x_gpio_get; 248 249 ret = gpiochip_add(&tps6586x->gpio); 250 if (ret) 251 dev_warn(tps6586x->dev, "GPIO registration failed: %d\n", ret); 252 } 253 254 static int __remove_subdev(struct device *dev, void *unused) 255 { 256 platform_device_unregister(to_platform_device(dev)); 257 return 0; 258 } 259 260 static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) 261 { 262 return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); 263 } 264 265 static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, 266 struct tps6586x_platform_data *pdata) 267 { 268 struct tps6586x_subdev_info *subdev; 269 struct platform_device *pdev; 270 int i, ret = 0; 271 272 for (i = 0; i < pdata->num_subdevs; i++) { 273 subdev = &pdata->subdevs[i]; 274 275 pdev = platform_device_alloc(subdev->name, subdev->id); 276 277 pdev->dev.parent = tps6586x->dev; 278 pdev->dev.platform_data = subdev->platform_data; 279 280 ret = platform_device_add(pdev); 281 if (ret) 282 goto failed; 283 } 284 return 0; 285 286 failed: 287 tps6586x_remove_subdevs(tps6586x); 288 return ret; 289 } 290 291 static int __devinit tps6586x_i2c_probe(struct i2c_client *client, 292 const struct i2c_device_id *id) 293 { 294 struct tps6586x_platform_data *pdata = client->dev.platform_data; 295 struct tps6586x *tps6586x; 296 int ret; 297 298 if (!pdata) { 299 dev_err(&client->dev, "tps6586x requires platform data\n"); 300 return -ENOTSUPP; 301 } 302 303 ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC); 304 if (ret < 0) { 305 dev_err(&client->dev, "Chip ID read failed: %d\n", ret); 306 return -EIO; 307 } 308 309 if (ret != TPS658621A_VERSIONCRC) { 310 dev_err(&client->dev, "Unsupported chip ID: %x\n", ret); 311 return -ENODEV; 312 } 313 314 tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); 315 if (tps6586x == NULL) 316 return -ENOMEM; 317 318 tps6586x->client = client; 319 tps6586x->dev = &client->dev; 320 i2c_set_clientdata(client, tps6586x); 321 322 mutex_init(&tps6586x->lock); 323 324 ret = tps6586x_add_subdevs(tps6586x, pdata); 325 if (ret) { 326 dev_err(&client->dev, "add devices failed: %d\n", ret); 327 goto err_add_devs; 328 } 329 330 tps6586x_gpio_init(tps6586x, pdata->gpio_base); 331 332 return 0; 333 334 err_add_devs: 335 kfree(tps6586x); 336 return ret; 337 } 338 339 static int __devexit tps6586x_i2c_remove(struct i2c_client *client) 340 { 341 return 0; 342 } 343 344 static const struct i2c_device_id tps6586x_id_table[] = { 345 { "tps6586x", 0 }, 346 { }, 347 }; 348 MODULE_DEVICE_TABLE(i2c, tps6586x_id_table); 349 350 static struct i2c_driver tps6586x_driver = { 351 .driver = { 352 .name = "tps6586x", 353 .owner = THIS_MODULE, 354 }, 355 .probe = tps6586x_i2c_probe, 356 .remove = __devexit_p(tps6586x_i2c_remove), 357 .id_table = tps6586x_id_table, 358 }; 359 360 static int __init tps6586x_init(void) 361 { 362 return i2c_add_driver(&tps6586x_driver); 363 } 364 subsys_initcall(tps6586x_init); 365 366 static void __exit tps6586x_exit(void) 367 { 368 i2c_del_driver(&tps6586x_driver); 369 } 370 module_exit(tps6586x_exit); 371 372 MODULE_DESCRIPTION("TPS6586X core driver"); 373 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 374 MODULE_LICENSE("GPL"); 375 376