1 /* 2 * linux/drivers/mfd/aat2870-core.c 3 * 4 * Copyright (c) 2011, NVIDIA Corporation. 5 * Author: Jin Park <jinyoungp@nvidia.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * version 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19 * 02110-1301 USA 20 */ 21 22 #include <linux/kernel.h> 23 #include <linux/module.h> 24 #include <linux/init.h> 25 #include <linux/debugfs.h> 26 #include <linux/slab.h> 27 #include <linux/uaccess.h> 28 #include <linux/i2c.h> 29 #include <linux/delay.h> 30 #include <linux/gpio.h> 31 #include <linux/mfd/core.h> 32 #include <linux/mfd/aat2870.h> 33 #include <linux/regulator/machine.h> 34 35 static struct aat2870_register aat2870_regs[AAT2870_REG_NUM] = { 36 /* readable, writeable, value */ 37 { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */ 38 { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */ 39 { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */ 40 { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */ 41 { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */ 42 { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */ 43 { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */ 44 { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */ 45 { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */ 46 { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */ 47 { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */ 48 { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */ 49 { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */ 50 { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */ 51 { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */ 52 { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */ 53 { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */ 54 { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */ 55 { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */ 56 { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */ 57 { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */ 58 { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */ 59 { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */ 60 { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */ 61 { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */ 62 { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */ 63 { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */ 64 { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */ 65 { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */ 66 { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */ 67 { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */ 68 { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */ 69 { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */ 70 { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */ 71 { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */ 72 { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */ 73 { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */ 74 { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */ 75 { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */ 76 }; 77 78 static struct mfd_cell aat2870_devs[] = { 79 { 80 .name = "aat2870-backlight", 81 .id = AAT2870_ID_BL, 82 .pdata_size = sizeof(struct aat2870_bl_platform_data), 83 }, 84 { 85 .name = "aat2870-regulator", 86 .id = AAT2870_ID_LDOA, 87 .pdata_size = sizeof(struct regulator_init_data), 88 }, 89 { 90 .name = "aat2870-regulator", 91 .id = AAT2870_ID_LDOB, 92 .pdata_size = sizeof(struct regulator_init_data), 93 }, 94 { 95 .name = "aat2870-regulator", 96 .id = AAT2870_ID_LDOC, 97 .pdata_size = sizeof(struct regulator_init_data), 98 }, 99 { 100 .name = "aat2870-regulator", 101 .id = AAT2870_ID_LDOD, 102 .pdata_size = sizeof(struct regulator_init_data), 103 }, 104 }; 105 106 static int __aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val) 107 { 108 int ret; 109 110 if (addr >= AAT2870_REG_NUM) { 111 dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr); 112 return -EINVAL; 113 } 114 115 if (!aat2870->reg_cache[addr].readable) { 116 *val = aat2870->reg_cache[addr].value; 117 goto out; 118 } 119 120 ret = i2c_master_send(aat2870->client, &addr, 1); 121 if (ret < 0) 122 return ret; 123 if (ret != 1) 124 return -EIO; 125 126 ret = i2c_master_recv(aat2870->client, val, 1); 127 if (ret < 0) 128 return ret; 129 if (ret != 1) 130 return -EIO; 131 132 out: 133 dev_dbg(aat2870->dev, "read: addr=0x%02x, val=0x%02x\n", addr, *val); 134 return 0; 135 } 136 137 static int __aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val) 138 { 139 u8 msg[2]; 140 int ret; 141 142 if (addr >= AAT2870_REG_NUM) { 143 dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr); 144 return -EINVAL; 145 } 146 147 if (!aat2870->reg_cache[addr].writeable) { 148 dev_err(aat2870->dev, "Address 0x%02x is not writeable\n", 149 addr); 150 return -EINVAL; 151 } 152 153 msg[0] = addr; 154 msg[1] = val; 155 ret = i2c_master_send(aat2870->client, msg, 2); 156 if (ret < 0) 157 return ret; 158 if (ret != 2) 159 return -EIO; 160 161 aat2870->reg_cache[addr].value = val; 162 163 dev_dbg(aat2870->dev, "write: addr=0x%02x, val=0x%02x\n", addr, val); 164 return 0; 165 } 166 167 static int aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val) 168 { 169 int ret; 170 171 mutex_lock(&aat2870->io_lock); 172 ret = __aat2870_read(aat2870, addr, val); 173 mutex_unlock(&aat2870->io_lock); 174 175 return ret; 176 } 177 178 static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val) 179 { 180 int ret; 181 182 mutex_lock(&aat2870->io_lock); 183 ret = __aat2870_write(aat2870, addr, val); 184 mutex_unlock(&aat2870->io_lock); 185 186 return ret; 187 } 188 189 static int aat2870_update(struct aat2870_data *aat2870, u8 addr, u8 mask, 190 u8 val) 191 { 192 int change; 193 u8 old_val, new_val; 194 int ret; 195 196 mutex_lock(&aat2870->io_lock); 197 198 ret = __aat2870_read(aat2870, addr, &old_val); 199 if (ret) 200 goto out_unlock; 201 202 new_val = (old_val & ~mask) | (val & mask); 203 change = old_val != new_val; 204 if (change) 205 ret = __aat2870_write(aat2870, addr, new_val); 206 207 out_unlock: 208 mutex_unlock(&aat2870->io_lock); 209 210 return ret; 211 } 212 213 static inline void aat2870_enable(struct aat2870_data *aat2870) 214 { 215 if (aat2870->en_pin >= 0) 216 gpio_set_value(aat2870->en_pin, 1); 217 218 aat2870->is_enable = 1; 219 } 220 221 static inline void aat2870_disable(struct aat2870_data *aat2870) 222 { 223 if (aat2870->en_pin >= 0) 224 gpio_set_value(aat2870->en_pin, 0); 225 226 aat2870->is_enable = 0; 227 } 228 229 #ifdef CONFIG_DEBUG_FS 230 static ssize_t aat2870_dump_reg(struct aat2870_data *aat2870, char *buf) 231 { 232 u8 addr, val; 233 ssize_t count = 0; 234 int ret; 235 236 count += sprintf(buf, "aat2870 registers\n"); 237 for (addr = 0; addr < AAT2870_REG_NUM; addr++) { 238 count += sprintf(buf + count, "0x%02x: ", addr); 239 if (count >= PAGE_SIZE - 1) 240 break; 241 242 ret = aat2870->read(aat2870, addr, &val); 243 if (ret == 0) 244 count += snprintf(buf + count, PAGE_SIZE - count, 245 "0x%02x", val); 246 else 247 count += snprintf(buf + count, PAGE_SIZE - count, 248 "<read fail: %d>", ret); 249 250 if (count >= PAGE_SIZE - 1) 251 break; 252 253 count += snprintf(buf + count, PAGE_SIZE - count, "\n"); 254 if (count >= PAGE_SIZE - 1) 255 break; 256 } 257 258 /* Truncate count; min() would cause a warning */ 259 if (count >= PAGE_SIZE) 260 count = PAGE_SIZE - 1; 261 262 return count; 263 } 264 265 static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf, 266 size_t count, loff_t *ppos) 267 { 268 struct aat2870_data *aat2870 = file->private_data; 269 char *buf; 270 ssize_t ret; 271 272 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 273 if (!buf) 274 return -ENOMEM; 275 276 ret = aat2870_dump_reg(aat2870, buf); 277 if (ret >= 0) 278 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 279 280 kfree(buf); 281 282 return ret; 283 } 284 285 static ssize_t aat2870_reg_write_file(struct file *file, 286 const char __user *user_buf, size_t count, 287 loff_t *ppos) 288 { 289 struct aat2870_data *aat2870 = file->private_data; 290 char buf[32]; 291 ssize_t buf_size; 292 char *start = buf; 293 unsigned long addr, val; 294 int ret; 295 296 buf_size = min(count, (sizeof(buf)-1)); 297 if (copy_from_user(buf, user_buf, buf_size)) { 298 dev_err(aat2870->dev, "Failed to copy from user\n"); 299 return -EFAULT; 300 } 301 buf[buf_size] = 0; 302 303 while (*start == ' ') 304 start++; 305 306 addr = simple_strtoul(start, &start, 16); 307 if (addr >= AAT2870_REG_NUM) { 308 dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr); 309 return -EINVAL; 310 } 311 312 while (*start == ' ') 313 start++; 314 315 if (strict_strtoul(start, 16, &val)) 316 return -EINVAL; 317 318 ret = aat2870->write(aat2870, (u8)addr, (u8)val); 319 if (ret) 320 return ret; 321 322 return buf_size; 323 } 324 325 static const struct file_operations aat2870_reg_fops = { 326 .open = simple_open, 327 .read = aat2870_reg_read_file, 328 .write = aat2870_reg_write_file, 329 }; 330 331 static void aat2870_init_debugfs(struct aat2870_data *aat2870) 332 { 333 aat2870->dentry_root = debugfs_create_dir("aat2870", NULL); 334 if (!aat2870->dentry_root) { 335 dev_warn(aat2870->dev, 336 "Failed to create debugfs root directory\n"); 337 return; 338 } 339 340 aat2870->dentry_reg = debugfs_create_file("regs", 0644, 341 aat2870->dentry_root, 342 aat2870, &aat2870_reg_fops); 343 if (!aat2870->dentry_reg) 344 dev_warn(aat2870->dev, 345 "Failed to create debugfs register file\n"); 346 } 347 348 static void aat2870_uninit_debugfs(struct aat2870_data *aat2870) 349 { 350 debugfs_remove_recursive(aat2870->dentry_root); 351 } 352 #else 353 static inline void aat2870_init_debugfs(struct aat2870_data *aat2870) 354 { 355 } 356 357 static inline void aat2870_uninit_debugfs(struct aat2870_data *aat2870) 358 { 359 } 360 #endif /* CONFIG_DEBUG_FS */ 361 362 static int aat2870_i2c_probe(struct i2c_client *client, 363 const struct i2c_device_id *id) 364 { 365 struct aat2870_platform_data *pdata = client->dev.platform_data; 366 struct aat2870_data *aat2870; 367 int i, j; 368 int ret = 0; 369 370 aat2870 = kzalloc(sizeof(struct aat2870_data), GFP_KERNEL); 371 if (!aat2870) { 372 dev_err(&client->dev, 373 "Failed to allocate memory for aat2870\n"); 374 ret = -ENOMEM; 375 goto out; 376 } 377 378 aat2870->dev = &client->dev; 379 dev_set_drvdata(aat2870->dev, aat2870); 380 381 aat2870->client = client; 382 i2c_set_clientdata(client, aat2870); 383 384 aat2870->reg_cache = aat2870_regs; 385 386 if (pdata->en_pin < 0) 387 aat2870->en_pin = -1; 388 else 389 aat2870->en_pin = pdata->en_pin; 390 391 aat2870->init = pdata->init; 392 aat2870->uninit = pdata->uninit; 393 aat2870->read = aat2870_read; 394 aat2870->write = aat2870_write; 395 aat2870->update = aat2870_update; 396 397 mutex_init(&aat2870->io_lock); 398 399 if (aat2870->init) 400 aat2870->init(aat2870); 401 402 if (aat2870->en_pin >= 0) { 403 ret = gpio_request_one(aat2870->en_pin, GPIOF_OUT_INIT_HIGH, 404 "aat2870-en"); 405 if (ret < 0) { 406 dev_err(&client->dev, 407 "Failed to request GPIO %d\n", aat2870->en_pin); 408 goto out_kfree; 409 } 410 } 411 412 aat2870_enable(aat2870); 413 414 for (i = 0; i < pdata->num_subdevs; i++) { 415 for (j = 0; j < ARRAY_SIZE(aat2870_devs); j++) { 416 if ((pdata->subdevs[i].id == aat2870_devs[j].id) && 417 !strcmp(pdata->subdevs[i].name, 418 aat2870_devs[j].name)) { 419 aat2870_devs[j].platform_data = 420 pdata->subdevs[i].platform_data; 421 break; 422 } 423 } 424 } 425 426 ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, 427 ARRAY_SIZE(aat2870_devs), NULL, 0, NULL); 428 if (ret != 0) { 429 dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); 430 goto out_disable; 431 } 432 433 aat2870_init_debugfs(aat2870); 434 435 return 0; 436 437 out_disable: 438 aat2870_disable(aat2870); 439 if (aat2870->en_pin >= 0) 440 gpio_free(aat2870->en_pin); 441 out_kfree: 442 kfree(aat2870); 443 out: 444 return ret; 445 } 446 447 static int aat2870_i2c_remove(struct i2c_client *client) 448 { 449 struct aat2870_data *aat2870 = i2c_get_clientdata(client); 450 451 aat2870_uninit_debugfs(aat2870); 452 453 mfd_remove_devices(aat2870->dev); 454 aat2870_disable(aat2870); 455 if (aat2870->en_pin >= 0) 456 gpio_free(aat2870->en_pin); 457 if (aat2870->uninit) 458 aat2870->uninit(aat2870); 459 kfree(aat2870); 460 461 return 0; 462 } 463 464 #ifdef CONFIG_PM_SLEEP 465 static int aat2870_i2c_suspend(struct device *dev) 466 { 467 struct i2c_client *client = to_i2c_client(dev); 468 struct aat2870_data *aat2870 = i2c_get_clientdata(client); 469 470 aat2870_disable(aat2870); 471 472 return 0; 473 } 474 475 static int aat2870_i2c_resume(struct device *dev) 476 { 477 struct i2c_client *client = to_i2c_client(dev); 478 struct aat2870_data *aat2870 = i2c_get_clientdata(client); 479 struct aat2870_register *reg = NULL; 480 int i; 481 482 aat2870_enable(aat2870); 483 484 /* restore registers */ 485 for (i = 0; i < AAT2870_REG_NUM; i++) { 486 reg = &aat2870->reg_cache[i]; 487 if (reg->writeable) 488 aat2870->write(aat2870, i, reg->value); 489 } 490 491 return 0; 492 } 493 #endif /* CONFIG_PM_SLEEP */ 494 495 static SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend, 496 aat2870_i2c_resume); 497 498 static const struct i2c_device_id aat2870_i2c_id_table[] = { 499 { "aat2870", 0 }, 500 { } 501 }; 502 MODULE_DEVICE_TABLE(i2c, aat2870_i2c_id_table); 503 504 static struct i2c_driver aat2870_i2c_driver = { 505 .driver = { 506 .name = "aat2870", 507 .owner = THIS_MODULE, 508 .pm = &aat2870_pm_ops, 509 }, 510 .probe = aat2870_i2c_probe, 511 .remove = aat2870_i2c_remove, 512 .id_table = aat2870_i2c_id_table, 513 }; 514 515 static int __init aat2870_init(void) 516 { 517 return i2c_add_driver(&aat2870_i2c_driver); 518 } 519 subsys_initcall(aat2870_init); 520 521 static void __exit aat2870_exit(void) 522 { 523 i2c_del_driver(&aat2870_i2c_driver); 524 } 525 module_exit(aat2870_exit); 526 527 MODULE_DESCRIPTION("Core support for the AnalogicTech AAT2870"); 528 MODULE_LICENSE("GPL"); 529 MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); 530