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.c99
1 files changed, 69 insertions, 30 deletions
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index e4ca5909e424..53ebfee548fa 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -19,7 +19,7 @@
19#include <linux/debugfs.h> 19#include <linux/debugfs.h>
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/mfd/ab3100.h> 22#include <linux/mfd/abx500.h>
23 23
24/* These are the only registers inside AB3100 used in this main file */ 24/* These are the only registers inside AB3100 used in this main file */
25 25
@@ -59,24 +59,15 @@
59 * The AB3100 is usually assigned address 0x48 (7-bit) 59 * The AB3100 is usually assigned address 0x48 (7-bit)
60 * The chip is defined in the platform i2c_board_data section. 60 * The chip is defined in the platform i2c_board_data section.
61 */ 61 */
62 62static int ab3100_get_chip_id(struct device *dev)
63u8 ab3100_get_chip_type(struct ab3100 *ab3100)
64{ 63{
65 u8 chip = ABUNKNOWN; 64 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
66 65
67 switch (ab3100->chip_id & 0xf0) { 66 return (int)ab3100->chip_id;
68 case 0xa0:
69 chip = AB3000;
70 break;
71 case 0xc0:
72 chip = AB3100;
73 break;
74 }
75 return chip;
76} 67}
77EXPORT_SYMBOL(ab3100_get_chip_type);
78 68
79int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval) 69static int ab3100_set_register_interruptible(struct ab3100 *ab3100,
70 u8 reg, u8 regval)
80{ 71{
81 u8 regandval[2] = {reg, regval}; 72 u8 regandval[2] = {reg, regval};
82 int err; 73 int err;
@@ -108,8 +99,14 @@ int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval)
108 mutex_unlock(&ab3100->access_mutex); 99 mutex_unlock(&ab3100->access_mutex);
109 return err; 100 return err;
110} 101}
111EXPORT_SYMBOL(ab3100_set_register_interruptible);
112 102
103static int set_register_interruptible(struct device *dev,
104 u8 bank, u8 reg, u8 value)
105{
106 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
107
108 return ab3100_set_register_interruptible(ab3100, reg, value);
109}
113 110
114/* 111/*
115 * The test registers exist at an I2C bus address up one 112 * The test registers exist at an I2C bus address up one
@@ -148,8 +145,8 @@ static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100,
148 return err; 145 return err;
149} 146}
150 147
151 148static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
152int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval) 149 u8 reg, u8 *regval)
153{ 150{
154 int err; 151 int err;
155 152
@@ -203,10 +200,16 @@ int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval)
203 mutex_unlock(&ab3100->access_mutex); 200 mutex_unlock(&ab3100->access_mutex);
204 return err; 201 return err;
205} 202}
206EXPORT_SYMBOL(ab3100_get_register_interruptible);
207 203
204static int get_register_interruptible(struct device *dev, u8 bank, u8 reg,
205 u8 *value)
206{
207 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
208
209 return ab3100_get_register_interruptible(ab3100, reg, value);
210}
208 211
209int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, 212static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
210 u8 first_reg, u8 *regvals, u8 numregs) 213 u8 first_reg, u8 *regvals, u8 numregs)
211{ 214{
212 int err; 215 int err;
@@ -260,10 +263,17 @@ int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
260 mutex_unlock(&ab3100->access_mutex); 263 mutex_unlock(&ab3100->access_mutex);
261 return err; 264 return err;
262} 265}
263EXPORT_SYMBOL(ab3100_get_register_page_interruptible);
264 266
267static int get_register_page_interruptible(struct device *dev, u8 bank,
268 u8 first_reg, u8 *regvals, u8 numregs)
269{
270 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
271
272 return ab3100_get_register_page_interruptible(ab3100,
273 first_reg, regvals, numregs);
274}
265 275
266int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, 276static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
267 u8 reg, u8 andmask, u8 ormask) 277 u8 reg, u8 andmask, u8 ormask)
268{ 278{
269 u8 regandval[2] = {reg, 0}; 279 u8 regandval[2] = {reg, 0};
@@ -331,8 +341,15 @@ int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
331 mutex_unlock(&ab3100->access_mutex); 341 mutex_unlock(&ab3100->access_mutex);
332 return err; 342 return err;
333} 343}
334EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible);
335 344
345static int mask_and_set_register_interruptible(struct device *dev, u8 bank,
346 u8 reg, u8 bitmask, u8 bitvalues)
347{
348 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
349
350 return ab3100_mask_and_set_register_interruptible(ab3100,
351 reg, bitmask, (bitmask & bitvalues));
352}
336 353
337/* 354/*
338 * Register a simple callback for handling any AB3100 events. 355 * Register a simple callback for handling any AB3100 events.
@@ -357,15 +374,27 @@ int ab3100_event_unregister(struct ab3100 *ab3100,
357EXPORT_SYMBOL(ab3100_event_unregister); 374EXPORT_SYMBOL(ab3100_event_unregister);
358 375
359 376
360int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, 377static int ab3100_event_registers_startup_state_get(struct device *dev,
361 u32 *fatevent) 378 u8 *event)
362{ 379{
380 struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
363 if (!ab3100->startup_events_read) 381 if (!ab3100->startup_events_read)
364 return -EAGAIN; /* Try again later */ 382 return -EAGAIN; /* Try again later */
365 *fatevent = ab3100->startup_events; 383 memcpy(event, ab3100->startup_events, 3);
366 return 0; 384 return 0;
367} 385}
368EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); 386
387static struct abx500_ops ab3100_ops = {
388 .get_chip_id = ab3100_get_chip_id,
389 .set_register = set_register_interruptible,
390 .get_register = get_register_interruptible,
391 .get_register_page = get_register_page_interruptible,
392 .set_register_page = NULL,
393 .mask_and_set_register = mask_and_set_register_interruptible,
394 .event_registers_startup_state_get =
395 ab3100_event_registers_startup_state_get,
396 .startup_irq_enabled = NULL,
397};
369 398
370/* 399/*
371 * This is a threaded interrupt handler so we can make some 400 * This is a threaded interrupt handler so we can make some
@@ -390,7 +419,9 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data)
390 event_regs[2]; 419 event_regs[2];
391 420
392 if (!ab3100->startup_events_read) { 421 if (!ab3100->startup_events_read) {
393 ab3100->startup_events = fatevent; 422 ab3100->startup_events[0] = event_regs[0];
423 ab3100->startup_events[1] = event_regs[1];
424 ab3100->startup_events[2] = event_regs[2];
394 ab3100->startup_events_read = true; 425 ab3100->startup_events_read = true;
395 } 426 }
396 /* 427 /*
@@ -703,7 +734,8 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
703 dev_warn(ab3100->dev, 734 dev_warn(ab3100->dev,
704 "AB3100 P1E variant detected, " 735 "AB3100 P1E variant detected, "
705 "forcing chip to 32KHz\n"); 736 "forcing chip to 32KHz\n");
706 err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08); 737 err = ab3100_set_test_register_interruptible(ab3100,
738 0x02, 0x08);
707 } 739 }
708 740
709 exit_no_setup: 741 exit_no_setup:
@@ -898,6 +930,10 @@ static int __init ab3100_probe(struct i2c_client *client,
898 if (err) 930 if (err)
899 goto exit_no_irq; 931 goto exit_no_irq;
900 932
933 err = abx500_register_ops(&client->dev, &ab3100_ops);
934 if (err)
935 goto exit_no_ops;
936
901 /* Set parent and a pointer back to the container in device data */ 937 /* Set parent and a pointer back to the container in device data */
902 for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) { 938 for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) {
903 ab3100_platform_devs[i]->dev.parent = 939 ab3100_platform_devs[i]->dev.parent =
@@ -915,11 +951,13 @@ static int __init ab3100_probe(struct i2c_client *client,
915 951
916 return 0; 952 return 0;
917 953
954 exit_no_ops:
918 exit_no_irq: 955 exit_no_irq:
919 exit_no_setup: 956 exit_no_setup:
920 i2c_unregister_device(ab3100->testreg_client); 957 i2c_unregister_device(ab3100->testreg_client);
921 exit_no_testreg_client: 958 exit_no_testreg_client:
922 exit_no_detect: 959 exit_no_detect:
960 i2c_set_clientdata(client, NULL);
923 kfree(ab3100); 961 kfree(ab3100);
924 return err; 962 return err;
925} 963}
@@ -941,6 +979,7 @@ static int __exit ab3100_remove(struct i2c_client *client)
941 * their notifiers so deactivate IRQ 979 * their notifiers so deactivate IRQ
942 */ 980 */
943 free_irq(client->irq, ab3100); 981 free_irq(client->irq, ab3100);
982 i2c_set_clientdata(client, NULL);
944 kfree(ab3100); 983 kfree(ab3100);
945 return 0; 984 return 0;
946} 985}