Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284571
b: refs/heads/master
c: aeb5032
h: refs/heads/master
i:
  284569: 8c12d7c
  284567: ac0abfd
v: v3
  • Loading branch information
Benoit Cousson authored and Samuel Ortiz committed Jan 8, 2012
1 parent 8c0f3dc commit 4c2d374
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 3 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: 5391b5c645a86d4657c2175acbf21c6461d34849
refs/heads/master: aeb5032b3f8b9ab69daa545777433fa94b3494c4
47 changes: 47 additions & 0 deletions trunk/Documentation/devicetree/bindings/mfd/twl-familly.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Texas Instruments TWL family

The TWLs are Integrated Power Management Chips.
Some version might contain much more analog function like
USB transceiver or Audio amplifier.
These chips are connected to an i2c bus.


Required properties:
- compatible : Must be "ti,twl4030";
For Integrated power-management/audio CODEC device used in OMAP3
based boards
- compatible : Must be "ti,twl6030";
For Integrated power-management used in OMAP4 based boards
- interrupts : This i2c device has an IRQ line connected to the main SoC
- interrupt-controller : Since the twl support several interrupts internally,
it is considered as an interrupt controller cascaded to the SoC one.
- #interrupt-cells = <1>;
- interrupt-parent : The parent interrupt controller.

Optional node:
- Child nodes contain in the twl. The twl family is made of several variants
that support a different number of features.
The children nodes will thus depend of the capability of the variant.


Example:
/*
* Integrated Power Management Chip
* http://www.ti.com/lit/ds/symlink/twl6030.pdf
*/
twl@48 {
compatible = "ti,twl6030";
reg = <0x48>;
interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&gic>;
#address-cells = <1>;
#size-cells = <0>;

twl_rtc {
compatible = "ti,twl_rtc";
interrupts = <11>;
reg = <0>;
};
};
2 changes: 1 addition & 1 deletion trunk/drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ config MENELAUS

config TWL4030_CORE
bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
depends on I2C=y && GENERIC_HARDIRQS
depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
help
Say yes here if you have TWL4030 / TWL6030 family chip on your board.
This core driver provides register access and IRQ handling
Expand Down
51 changes: 50 additions & 1 deletion trunk/drivers/mfd/twl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/irqdomain.h>

#include <linux/regulator/machine.h>

Expand Down Expand Up @@ -144,6 +149,9 @@

#define TWL_MODULE_LAST TWL4030_MODULE_LAST

#define TWL4030_NR_IRQS 8
#define TWL6030_NR_IRQS 20

/* Base Address defns for twl4030_map[] */

/* subchip/slave 0 - USB ID */
Expand Down Expand Up @@ -255,6 +263,7 @@ struct twl_client {

static struct twl_client twl_modules[TWL_NUM_SLAVES];

static struct irq_domain domain;

/* mapping the module id to slave id and base address */
struct twl_mapping {
Expand Down Expand Up @@ -1183,14 +1192,48 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status;
unsigned i;
struct twl4030_platform_data *pdata = client->dev.platform_data;
struct device_node *node = client->dev.of_node;
u8 temp;
int ret = 0;
int nr_irqs = TWL4030_NR_IRQS;

if ((id->driver_data) & TWL6030_CLASS)
nr_irqs = TWL6030_NR_IRQS;

if (node && !pdata) {
/*
* XXX: Temporary pdata until the information is correctly
* retrieved by every TWL modules from DT.
*/
pdata = devm_kzalloc(&client->dev,
sizeof(struct twl4030_platform_data),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
}

if (!pdata) {
dev_dbg(&client->dev, "no platform data?\n");
return -EINVAL;
}

status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0);
if (IS_ERR_VALUE(status)) {
dev_err(&client->dev, "Fail to allocate IRQ descs\n");
return status;
}

pdata->irq_base = status;
pdata->irq_end = pdata->irq_base + nr_irqs;

domain.irq_base = pdata->irq_base;
domain.nr_irq = nr_irqs;
#ifdef CONFIG_OF_IRQ
domain.of_node = of_node_get(node);
domain.ops = &irq_domain_simple_ops;
#endif
irq_domain_add(&domain);

if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
return -EIO;
Expand Down Expand Up @@ -1270,7 +1313,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
}

status = add_children(pdata, id->driver_data);
#ifdef CONFIG_OF_DEVICE
if (node)
status = of_platform_populate(node, NULL, NULL, &client->dev);
else
#endif
status = add_children(pdata, id->driver_data);

fail:
if (status < 0)
twl_remove(client);
Expand Down

0 comments on commit 4c2d374

Please sign in to comment.