Skip to content

Commit

Permalink
mfd: AB3100 register access change to abx500 API
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mattias Wallin authored and Samuel Ortiz committed May 27, 2010
1 parent 812f9e9 commit fa66125
Show file tree
Hide file tree
Showing 8 changed files with 390 additions and 92 deletions.
12 changes: 11 additions & 1 deletion drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,19 @@ config PCF50633_GPIO
Say yes here if you want to include support GPIO for pins on
the PCF50633 chip.

config ABX500_CORE
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
default y if ARCH_U300
help
Say yes here if you have the ABX500 Mixed Signal IC family
chips. This core driver expose register access functions.
Functionality specific drivers using these functions can
remain unchanged when IC changes. Binding of the functions to
actual register access is done by the IC core driver.

config AB3100_CORE
bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
depends on I2C=y
depends on I2C=y && ABX500_CORE
default y if ARCH_U300
help
Select this to enable the AB3100 Mixed Signal IC core
Expand Down
1 change: 1 addition & 0 deletions drivers/mfd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
obj-$(CONFIG_AB4500_CORE) += ab4500-core.o
Expand Down
95 changes: 66 additions & 29 deletions drivers/mfd/ab3100-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

switch (ab3100->chip_id & 0xf0) {
case 0xa0:
chip = AB3000;
break;
case 0xc0:
chip = AB3100;
break;
}
return chip;
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);

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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);

return ab3100_get_register_interruptible(ab3100, reg, value);
}

int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
u8 first_reg, u8 *regvals, u8 numregs)
{
int err;
Expand Down Expand Up @@ -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);

return ab3100_get_register_page_interruptible(ab3100,
first_reg, regvals, numregs);
}

int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
u8 reg, u8 andmask, u8 ormask)
{
u8 regandval[2] = {reg, 0};
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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;
}
/*
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 =
Expand All @@ -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);
Expand Down
11 changes: 4 additions & 7 deletions drivers/mfd/ab3100-otp.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
/**
* struct ab3100_otp
* @dev containing device
* @ab3100 a pointer to the parent ab3100 device struct
* @locked whether the OTP is locked, after locking, no more bits
* can be changed but before locking it is still possible
* to change bits from 1->0.
Expand All @@ -49,7 +48,6 @@
*/
struct ab3100_otp {
struct device *dev;
struct ab3100 *ab3100;
bool locked;
u32 freq;
bool paf;
Expand All @@ -63,19 +61,19 @@ struct ab3100_otp {

static int __init ab3100_otp_read(struct ab3100_otp *otp)
{
struct ab3100 *ab = otp->ab3100;
u8 otpval[8];
u8 otpp;
int err;

err = ab3100_get_register_interruptible(ab, AB3100_OTPP, &otpp);
err = abx500_get_register_interruptible(otp->dev, 0,
AB3100_OTPP, &otpp);
if (err) {
dev_err(otp->dev, "unable to read OTPP register\n");
return err;
}

err = ab3100_get_register_page_interruptible(ab, AB3100_OTP0,
otpval, 8);
err = abx500_get_register_page_interruptible(otp->dev, 0,
AB3100_OTP0, otpval, 8);
if (err) {
dev_err(otp->dev, "unable to read OTP register page\n");
return err;
Expand Down Expand Up @@ -197,7 +195,6 @@ static int __init ab3100_otp_probe(struct platform_device *pdev)
otp->dev = &pdev->dev;

/* Replace platform data coming in with a local struct */
otp->ab3100 = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, otp);

err = ab3100_otp_read(otp);
Expand Down
Loading

0 comments on commit fa66125

Please sign in to comment.