Skip to content

Commit

Permalink
mfd: Remove gpio support from tps6586x core driver
Browse files Browse the repository at this point in the history
The GPIO functionality of device tps6586x is added through
platform gpio driver and it can be register as the mfd sub
device and hence removing the duplicates code which register
the gpio functionality from core driver.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Laxman Dewangan authored and Samuel Ortiz committed Jul 24, 2012
1 parent 05f3ad2 commit 7a7487c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 87 deletions.
2 changes: 1 addition & 1 deletion drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ config MFD_TPS65217

config MFD_TPS6586X
bool "TPS6586x Power Management chips"
depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
depends on REGULATOR
Expand Down
107 changes: 21 additions & 86 deletions drivers/mfd/tps6586x.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,13 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>

#include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h>

/* GPIO control registers */
#define TPS6586X_GPIOSET1 0x5d
#define TPS6586X_GPIOSET2 0x5e

/* interrupt control registers */
#define TPS6586X_INT_ACK1 0xb5
#define TPS6586X_INT_ACK2 0xb6
Expand Down Expand Up @@ -94,12 +89,23 @@ static const struct tps6586x_irq_data tps6586x_irqs[] = {
[TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1),
};

static struct mfd_cell tps6586x_cell[] = {
{
.name = "tps6586x-gpio",
},
{
.name = "tps6586x-rtc",
},
{
.name = "tps6586x-onkey",
},
};

struct tps6586x {
struct device *dev;
struct i2c_client *client;
struct regmap *regmap;

struct gpio_chip gpio;
struct irq_chip irq_chip;
struct mutex irq_lock;
int irq_base;
Expand Down Expand Up @@ -173,63 +179,6 @@ int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
}
EXPORT_SYMBOL_GPL(tps6586x_update);

static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset)
{
struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio);
uint8_t val;
int ret;

ret = tps6586x_read(tps6586x->dev, TPS6586X_GPIOSET2, &val);
if (ret)
return ret;

return !!(val & (1 << offset));
}


static void tps6586x_gpio_set(struct gpio_chip *chip, unsigned offset,
int value)
{
struct tps6586x *tps6586x = container_of(chip, struct tps6586x, gpio);

tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET2,
value << offset, 1 << offset);
}

static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
int value)
{
struct tps6586x *tps6586x = container_of(gc, struct tps6586x, gpio);
uint8_t val, mask;

tps6586x_gpio_set(gc, offset, value);

val = 0x1 << (offset * 2);
mask = 0x3 << (offset * 2);

return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask);
}

static int tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
{
if (!gpio_base)
return 0;

tps6586x->gpio.owner = THIS_MODULE;
tps6586x->gpio.label = tps6586x->client->name;
tps6586x->gpio.dev = tps6586x->dev;
tps6586x->gpio.base = gpio_base;
tps6586x->gpio.ngpio = 4;
tps6586x->gpio.can_sleep = 1;

/* FIXME: add handling of GPIOs as dedicated inputs */
tps6586x->gpio.direction_output = tps6586x_gpio_output;
tps6586x->gpio.set = tps6586x_gpio_set;
tps6586x->gpio.get = tps6586x_gpio_get;

return gpiochip_add(&tps6586x->gpio);
}

static int __remove_subdev(struct device *dev, void *unused)
{
platform_device_unregister(to_platform_device(dev));
Expand Down Expand Up @@ -543,10 +492,11 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
}
}

ret = tps6586x_gpio_init(tps6586x, pdata->gpio_base);
if (ret) {
dev_err(&client->dev, "GPIO registration failed: %d\n", ret);
goto err_gpio_init;
ret = mfd_add_devices(tps6586x->dev, -1,
tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0);
if (ret < 0) {
dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);
goto err_mfd_add;
}

ret = tps6586x_add_subdevs(tps6586x, pdata);
Expand All @@ -558,36 +508,21 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
return 0;

err_add_devs:
if (pdata->gpio_base) {
ret = gpiochip_remove(&tps6586x->gpio);
if (ret)
dev_err(&client->dev, "Can't remove gpio chip: %d\n",
ret);
}
err_gpio_init:
mfd_remove_devices(tps6586x->dev);
err_mfd_add:
if (client->irq)
free_irq(client->irq, tps6586x);

return ret;
}

static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
{
struct tps6586x *tps6586x = i2c_get_clientdata(client);
struct tps6586x_platform_data *pdata = client->dev.platform_data;
int ret;

tps6586x_remove_subdevs(tps6586x);
mfd_remove_devices(tps6586x->dev);
if (client->irq)
free_irq(client->irq, tps6586x);

if (pdata->gpio_base) {
ret = gpiochip_remove(&tps6586x->gpio);
if (ret)
dev_err(&client->dev, "Can't remove gpio chip: %d\n",
ret);
}

tps6586x_remove_subdevs(tps6586x);
return 0;
}

Expand Down

0 comments on commit 7a7487c

Please sign in to comment.