aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ab3100-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/ab3100-core.c')
-rw-r--r--drivers/mfd/ab3100-core.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 13e7d7bfe85f..c533f86ff5ea 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -14,7 +14,6 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/workqueue.h>
18#include <linux/debugfs.h> 17#include <linux/debugfs.h>
19#include <linux/seq_file.h> 18#include <linux/seq_file.h>
20#include <linux/uaccess.h> 19#include <linux/uaccess.h>
@@ -77,7 +76,7 @@ u8 ab3100_get_chip_type(struct ab3100 *ab3100)
77} 76}
78EXPORT_SYMBOL(ab3100_get_chip_type); 77EXPORT_SYMBOL(ab3100_get_chip_type);
79 78
80int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval) 79int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval)
81{ 80{
82 u8 regandval[2] = {reg, regval}; 81 u8 regandval[2] = {reg, regval};
83 int err; 82 int err;
@@ -107,9 +106,10 @@ int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval)
107 err = 0; 106 err = 0;
108 } 107 }
109 mutex_unlock(&ab3100->access_mutex); 108 mutex_unlock(&ab3100->access_mutex);
110 return 0; 109 return err;
111} 110}
112EXPORT_SYMBOL(ab3100_set_register); 111EXPORT_SYMBOL(ab3100_set_register_interruptible);
112
113 113
114/* 114/*
115 * The test registers exist at an I2C bus address up one 115 * The test registers exist at an I2C bus address up one
@@ -118,7 +118,7 @@ EXPORT_SYMBOL(ab3100_set_register);
118 * anyway. It's currently only used from this file so declare 118 * anyway. It's currently only used from this file so declare
119 * it static and do not export. 119 * it static and do not export.
120 */ 120 */
121static int ab3100_set_test_register(struct ab3100 *ab3100, 121static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100,
122 u8 reg, u8 regval) 122 u8 reg, u8 regval)
123{ 123{
124 u8 regandval[2] = {reg, regval}; 124 u8 regandval[2] = {reg, regval};
@@ -148,7 +148,8 @@ static int ab3100_set_test_register(struct ab3100 *ab3100,
148 return err; 148 return err;
149} 149}
150 150
151int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval) 151
152int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval)
152{ 153{
153 int err; 154 int err;
154 155
@@ -202,9 +203,10 @@ int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval)
202 mutex_unlock(&ab3100->access_mutex); 203 mutex_unlock(&ab3100->access_mutex);
203 return err; 204 return err;
204} 205}
205EXPORT_SYMBOL(ab3100_get_register); 206EXPORT_SYMBOL(ab3100_get_register_interruptible);
206 207
207int ab3100_get_register_page(struct ab3100 *ab3100, 208
209int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
208 u8 first_reg, u8 *regvals, u8 numregs) 210 u8 first_reg, u8 *regvals, u8 numregs)
209{ 211{
210 int err; 212 int err;
@@ -258,9 +260,10 @@ int ab3100_get_register_page(struct ab3100 *ab3100,
258 mutex_unlock(&ab3100->access_mutex); 260 mutex_unlock(&ab3100->access_mutex);
259 return err; 261 return err;
260} 262}
261EXPORT_SYMBOL(ab3100_get_register_page); 263EXPORT_SYMBOL(ab3100_get_register_page_interruptible);
264
262 265
263int ab3100_mask_and_set_register(struct ab3100 *ab3100, 266int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
264 u8 reg, u8 andmask, u8 ormask) 267 u8 reg, u8 andmask, u8 ormask)
265{ 268{
266 u8 regandval[2] = {reg, 0}; 269 u8 regandval[2] = {reg, 0};
@@ -328,7 +331,8 @@ int ab3100_mask_and_set_register(struct ab3100 *ab3100,
328 mutex_unlock(&ab3100->access_mutex); 331 mutex_unlock(&ab3100->access_mutex);
329 return err; 332 return err;
330} 333}
331EXPORT_SYMBOL(ab3100_mask_and_set_register); 334EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible);
335
332 336
333/* 337/*
334 * Register a simple callback for handling any AB3100 events. 338 * Register a simple callback for handling any AB3100 events.
@@ -371,7 +375,7 @@ static void ab3100_work(struct work_struct *work)
371 u32 fatevent; 375 u32 fatevent;
372 int err; 376 int err;
373 377
374 err = ab3100_get_register_page(ab3100, AB3100_EVENTA1, 378 err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
375 event_regs, 3); 379 event_regs, 3);
376 if (err) 380 if (err)
377 goto err_event_wq; 381 goto err_event_wq;
@@ -417,7 +421,7 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data)
417 * stuff and we will re-enable the interrupts once th 421 * stuff and we will re-enable the interrupts once th
418 * worker has finished. 422 * worker has finished.
419 */ 423 */
420 disable_irq(ab3100->i2c_client->irq); 424 disable_irq_nosync(irq);
421 schedule_work(&ab3100->work); 425 schedule_work(&ab3100->work);
422 return IRQ_HANDLED; 426 return IRQ_HANDLED;
423} 427}
@@ -435,7 +439,7 @@ static int ab3100_registers_print(struct seq_file *s, void *p)
435 seq_printf(s, "AB3100 registers:\n"); 439 seq_printf(s, "AB3100 registers:\n");
436 440
437 for (reg = 0; reg < 0xff; reg++) { 441 for (reg = 0; reg < 0xff; reg++) {
438 ab3100_get_register(ab3100, reg, &value); 442 ab3100_get_register_interruptible(ab3100, reg, &value);
439 seq_printf(s, "[0x%x]: 0x%x\n", reg, value); 443 seq_printf(s, "[0x%x]: 0x%x\n", reg, value);
440 } 444 }
441 return 0; 445 return 0;
@@ -465,14 +469,14 @@ static int ab3100_get_set_reg_open_file(struct inode *inode, struct file *file)
465 return 0; 469 return 0;
466} 470}
467 471
468static int ab3100_get_set_reg(struct file *file, 472static ssize_t ab3100_get_set_reg(struct file *file,
469 const char __user *user_buf, 473 const char __user *user_buf,
470 size_t count, loff_t *ppos) 474 size_t count, loff_t *ppos)
471{ 475{
472 struct ab3100_get_set_reg_priv *priv = file->private_data; 476 struct ab3100_get_set_reg_priv *priv = file->private_data;
473 struct ab3100 *ab3100 = priv->ab3100; 477 struct ab3100 *ab3100 = priv->ab3100;
474 char buf[32]; 478 char buf[32];
475 int buf_size; 479 ssize_t buf_size;
476 int regp; 480 int regp;
477 unsigned long user_reg; 481 unsigned long user_reg;
478 int err; 482 int err;
@@ -515,7 +519,7 @@ static int ab3100_get_set_reg(struct file *file,
515 u8 reg = (u8) user_reg; 519 u8 reg = (u8) user_reg;
516 u8 regvalue; 520 u8 regvalue;
517 521
518 ab3100_get_register(ab3100, reg, &regvalue); 522 ab3100_get_register_interruptible(ab3100, reg, &regvalue);
519 523
520 dev_info(ab3100->dev, 524 dev_info(ab3100->dev,
521 "debug read AB3100 reg[0x%02x]: 0x%02x\n", 525 "debug read AB3100 reg[0x%02x]: 0x%02x\n",
@@ -547,8 +551,8 @@ static int ab3100_get_set_reg(struct file *file,
547 return -EINVAL; 551 return -EINVAL;
548 552
549 value = (u8) user_value; 553 value = (u8) user_value;
550 ab3100_set_register(ab3100, reg, value); 554 ab3100_set_register_interruptible(ab3100, reg, value);
551 ab3100_get_register(ab3100, reg, &regvalue); 555 ab3100_get_register_interruptible(ab3100, reg, &regvalue);
552 556
553 dev_info(ab3100->dev, 557 dev_info(ab3100->dev,
554 "debug write reg[0x%02x] with 0x%02x, " 558 "debug write reg[0x%02x] with 0x%02x, "
@@ -662,7 +666,7 @@ ab3100_init_settings[] = {
662 .setting = 0x01 666 .setting = 0x01
663 }, { 667 }, {
664 .abreg = AB3100_IMRB1, 668 .abreg = AB3100_IMRB1,
665 .setting = 0xFF 669 .setting = 0xBF
666 }, { 670 }, {
667 .abreg = AB3100_IMRB2, 671 .abreg = AB3100_IMRB2,
668 .setting = 0xFF 672 .setting = 0xFF
@@ -696,7 +700,7 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
696 int i; 700 int i;
697 701
698 for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) { 702 for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) {
699 err = ab3100_set_register(ab3100, 703 err = ab3100_set_register_interruptible(ab3100,
700 ab3100_init_settings[i].abreg, 704 ab3100_init_settings[i].abreg,
701 ab3100_init_settings[i].setting); 705 ab3100_init_settings[i].setting);
702 if (err) 706 if (err)
@@ -705,14 +709,14 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
705 709
706 /* 710 /*
707 * Special trick to make the AB3100 use the 32kHz clock (RTC) 711 * Special trick to make the AB3100 use the 32kHz clock (RTC)
708 * bit 3 in test registe 0x02 is a special, undocumented test 712 * bit 3 in test register 0x02 is a special, undocumented test
709 * register bit that only exist in AB3100 P1E 713 * register bit that only exist in AB3100 P1E
710 */ 714 */
711 if (ab3100->chip_id == 0xc4) { 715 if (ab3100->chip_id == 0xc4) {
712 dev_warn(ab3100->dev, 716 dev_warn(ab3100->dev,
713 "AB3100 P1E variant detected, " 717 "AB3100 P1E variant detected, "
714 "forcing chip to 32KHz\n"); 718 "forcing chip to 32KHz\n");
715 err = ab3100_set_test_register(ab3100, 0x02, 0x08); 719 err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08);
716 } 720 }
717 721
718 exit_no_setup: 722 exit_no_setup:
@@ -833,6 +837,8 @@ static int __init ab3100_probe(struct i2c_client *client,
833 const struct i2c_device_id *id) 837 const struct i2c_device_id *id)
834{ 838{
835 struct ab3100 *ab3100; 839 struct ab3100 *ab3100;
840 struct ab3100_platform_data *ab3100_plf_data =
841 client->dev.platform_data;
836 int err; 842 int err;
837 int i; 843 int i;
838 844
@@ -852,8 +858,8 @@ static int __init ab3100_probe(struct i2c_client *client,
852 i2c_set_clientdata(client, ab3100); 858 i2c_set_clientdata(client, ab3100);
853 859
854 /* Read chip ID register */ 860 /* Read chip ID register */
855 err = ab3100_get_register(ab3100, AB3100_CID, 861 err = ab3100_get_register_interruptible(ab3100, AB3100_CID,
856 &ab3100->chip_id); 862 &ab3100->chip_id);
857 if (err) { 863 if (err) {
858 dev_err(&client->dev, 864 dev_err(&client->dev,
859 "could not communicate with the AB3100 analog " 865 "could not communicate with the AB3100 analog "
@@ -916,6 +922,8 @@ static int __init ab3100_probe(struct i2c_client *client,
916 for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) { 922 for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) {
917 ab3100_platform_devs[i]->dev.parent = 923 ab3100_platform_devs[i]->dev.parent =
918 &client->dev; 924 &client->dev;
925 ab3100_platform_devs[i]->dev.platform_data =
926 ab3100_plf_data;
919 platform_set_drvdata(ab3100_platform_devs[i], ab3100); 927 platform_set_drvdata(ab3100_platform_devs[i], ab3100);
920 } 928 }
921 929