Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 319787
b: refs/heads/master
c: 7a7487c
h: refs/heads/master
i:
  319785: 4b23a46
  319783: 02c1a45
v: v3
  • Loading branch information
Laxman Dewangan authored and Samuel Ortiz committed Jul 24, 2012
1 parent 02fede3 commit 610e3ab
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 88 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 05f3ad2b8ae50fbf6e44094dbcd39dc25a1c80ae
refs/heads/master: 7a7487cb55a263d5c0893e2a8c2d7e8f33fcd1f0
2 changes: 1 addition & 1 deletion trunk/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 trunk/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 610e3ab

Please sign in to comment.