mfd: AB3100 register access change to abx500 API

The interface for the AB3100 is changed to make way for the
ABX500 family of chips: AB3550, AB5500 and future ST-Ericsson
Analog Baseband chips. The register access functions are moved
out to a separate struct abx500_ops. In this way the interface
is moved from the implementation and the sub functionality drivers
can keep their interface intact when chip infrastructure and
communication mechanisms changes. We also define the AB3550
device IDs and the AB3550 platform data struct and convert
the catenated 32bit event to an array of 3 x 8bits.

Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Mattias Wallin
2010-05-01 18:26:20 +02:00
committed by Samuel Ortiz
parent 812f9e9d42
commit fa661258a2
8 changed files with 389 additions and 91 deletions
+65 -28
View File
@@ -59,24 +59,15 @@
* The AB3100 is usually assigned address 0x48 (7-bit)
* The chip is defined in the platform i2c_board_data section.
*/
u8 ab3100_get_chip_type(struct ab3100 *ab3100)
static int ab3100_get_chip_id(struct device *dev)
{
u8 chip = ABUNKNOWN;
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
switch (ab3100->chip_id & 0xf0) {
case 0xa0:
chip = AB3000;
break;
case 0xc0:
chip = AB3100;
break;
}
return chip;
return (int)ab3100->chip_id;
}
EXPORT_SYMBOL(ab3100_get_chip_type);
int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval)
static int ab3100_set_register_interruptible(struct ab3100 *ab3100,
u8 reg, u8 regval)
{
u8 regandval[2] = {reg, regval};
int err;
@@ -108,8 +99,14 @@ int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval)
mutex_unlock(&ab3100->access_mutex);
return err;
}
EXPORT_SYMBOL(ab3100_set_register_interruptible);
static int set_register_interruptible(struct device *dev,
u8 bank, u8 reg, u8 value)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
return ab3100_set_register_interruptible(ab3100, reg, value);
}
/*
* 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,
return err;
}
int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval)
static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
u8 reg, u8 *regval)
{
int err;
@@ -203,10 +200,16 @@ int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval)
mutex_unlock(&ab3100->access_mutex);
return err;
}
EXPORT_SYMBOL(ab3100_get_register_interruptible);
static int get_register_interruptible(struct device *dev, u8 bank, u8 reg,
u8 *value)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
return ab3100_get_register_interruptible(ab3100, reg, value);
}
static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
u8 first_reg, u8 *regvals, u8 numregs)
{
int err;
@@ -260,10 +263,17 @@ int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
mutex_unlock(&ab3100->access_mutex);
return err;
}
EXPORT_SYMBOL(ab3100_get_register_page_interruptible);
static int get_register_page_interruptible(struct device *dev, u8 bank,
u8 first_reg, u8 *regvals, u8 numregs)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
return ab3100_get_register_page_interruptible(ab3100,
first_reg, regvals, numregs);
}
static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
u8 reg, u8 andmask, u8 ormask)
{
u8 regandval[2] = {reg, 0};
@@ -331,8 +341,15 @@ int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
mutex_unlock(&ab3100->access_mutex);
return err;
}
EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible);
static int mask_and_set_register_interruptible(struct device *dev, u8 bank,
u8 reg, u8 bitmask, u8 bitvalues)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
return ab3100_mask_and_set_register_interruptible(ab3100,
reg, bitmask, (bitmask & bitvalues));
}
/*
* Register a simple callback for handling any AB3100 events.
@@ -357,15 +374,27 @@ int ab3100_event_unregister(struct ab3100 *ab3100,
EXPORT_SYMBOL(ab3100_event_unregister);
int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100,
u32 *fatevent)
static int ab3100_event_registers_startup_state_get(struct device *dev,
u8 *event)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
if (!ab3100->startup_events_read)
return -EAGAIN; /* Try again later */
*fatevent = ab3100->startup_events;
memcpy(event, ab3100->startup_events, 3);
return 0;
}
EXPORT_SYMBOL(ab3100_event_registers_startup_state_get);
static struct abx500_ops ab3100_ops = {
.get_chip_id = ab3100_get_chip_id,
.set_register = set_register_interruptible,
.get_register = get_register_interruptible,
.get_register_page = get_register_page_interruptible,
.set_register_page = NULL,
.mask_and_set_register = mask_and_set_register_interruptible,
.event_registers_startup_state_get =
ab3100_event_registers_startup_state_get,
.startup_irq_enabled = NULL,
};
/*
* 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)
event_regs[2];
if (!ab3100->startup_events_read) {
ab3100->startup_events = fatevent;
ab3100->startup_events[0] = event_regs[0];
ab3100->startup_events[1] = event_regs[1];
ab3100->startup_events[2] = event_regs[2];
ab3100->startup_events_read = true;
}
/*
@@ -703,7 +734,8 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
dev_warn(ab3100->dev,
"AB3100 P1E variant detected, "
"forcing chip to 32KHz\n");
err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08);
err = ab3100_set_test_register_interruptible(ab3100,
0x02, 0x08);
}
exit_no_setup:
@@ -898,6 +930,10 @@ static int __init ab3100_probe(struct i2c_client *client,
if (err)
goto exit_no_irq;
err = abx500_register_ops(&client->dev, &ab3100_ops);
if (err)
goto exit_no_ops;
/* Set parent and a pointer back to the container in device data */
for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) {
ab3100_platform_devs[i]->dev.parent =
@@ -915,6 +951,7 @@ static int __init ab3100_probe(struct i2c_client *client,
return 0;
exit_no_ops:
exit_no_irq:
exit_no_setup:
i2c_unregister_device(ab3100->testreg_client);