mfd: Add device tree bindings for Arizona class devices
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
67c9929691
commit
d781009ca6
62
Documentation/devicetree/bindings/mfd/arizona.txt
Normal file
62
Documentation/devicetree/bindings/mfd/arizona.txt
Normal file
|
@ -0,0 +1,62 @@
|
|||
Wolfson Arizona class audio SoCs
|
||||
|
||||
These devices are audio SoCs with extensive digital capabilites and a range
|
||||
of analogue I/O.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : one of the following chip-specific strings:
|
||||
"wlf,wm5102"
|
||||
"wlf,wm5110"
|
||||
- reg : I2C slave address when connected using I2C, chip select number when
|
||||
using SPI.
|
||||
|
||||
- interrupts : The interrupt line the /IRQ signal for the device is
|
||||
connected to.
|
||||
- interrupt-controller : Arizona class devices contain interrupt controllers
|
||||
and may provide interrupt services to other devices.
|
||||
- interrupt-parent : The parent interrupt controller.
|
||||
- #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
|
||||
The first cell is the IRQ number.
|
||||
The second cell is the flags, encoded as the trigger masks from
|
||||
Documentation/devicetree/bindings/interrupts.txt
|
||||
|
||||
- gpio-controller : Indicates this device is a GPIO controller.
|
||||
- #gpio-cells : Must be 2. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
|
||||
- AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
|
||||
SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
|
||||
in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
Optional properties:
|
||||
|
||||
- wlf,reset : GPIO specifier for the GPIO controlling /RESET
|
||||
- wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
|
||||
|
||||
- wlf,gpio-defaults : A list of GPIO configuration register values. If
|
||||
absent, no configuration of these registers is performed. If any
|
||||
entry has a value that is out of range for a 16 bit register then
|
||||
the chip default will be used. If present exactly five values must
|
||||
be specified.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm5102@1a {
|
||||
compatible = "wlf,wm5102";
|
||||
reg = <0x1a>;
|
||||
interrupts = <347>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-parent = <&gic>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
wlf,gpio-defaults = <
|
||||
0x00000000, /* AIF1TXLRCLK */
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
>;
|
||||
};
|
|
@ -16,6 +16,9 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
@ -462,6 +465,70 @@ const struct dev_pm_ops arizona_pm_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(arizona_pm_ops);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
int arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
const struct of_device_id *id = of_match_device(arizona_of_match, dev);
|
||||
|
||||
if (id)
|
||||
return (int)id->data;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_of_get_type);
|
||||
|
||||
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
|
||||
"wlf,reset", 0);
|
||||
if (arizona->pdata.reset < 0)
|
||||
arizona->pdata.reset = 0;
|
||||
|
||||
arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
|
||||
"wlf,ldoena", 0);
|
||||
if (arizona->pdata.ldoena < 0)
|
||||
arizona->pdata.ldoena = 0;
|
||||
|
||||
ret = of_property_read_u32_array(arizona->dev->of_node,
|
||||
"wlf,gpio-defaults",
|
||||
arizona->pdata.gpio_defaults,
|
||||
ARRAY_SIZE(arizona->pdata.gpio_defaults));
|
||||
if (ret >= 0) {
|
||||
/*
|
||||
* All values are literal except out of range values
|
||||
* which are chip default, translate into platform
|
||||
* data which uses 0 as chip default and out of range
|
||||
* as zero.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
|
||||
if (arizona->pdata.gpio_defaults[i] > 0xffff)
|
||||
arizona->pdata.gpio_defaults[i] = 0;
|
||||
if (arizona->pdata.gpio_defaults[i] == 0)
|
||||
arizona->pdata.gpio_defaults[i] = 0x10000;
|
||||
}
|
||||
} else {
|
||||
dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct of_device_id arizona_of_match[] = {
|
||||
{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
|
||||
{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
|
||||
{},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(arizona_of_match);
|
||||
#else
|
||||
static inline int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct mfd_cell early_devs[] = {
|
||||
{ .name = "arizona-ldo1" },
|
||||
};
|
||||
|
@ -495,6 +562,8 @@ int arizona_dev_init(struct arizona *arizona)
|
|||
dev_set_drvdata(arizona->dev, arizona);
|
||||
mutex_init(&arizona->clk_lock);
|
||||
|
||||
arizona_of_get_core_pdata(arizona);
|
||||
|
||||
if (dev_get_platdata(arizona->dev))
|
||||
memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
|
||||
sizeof(arizona->pdata));
|
||||
|
|
|
@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
|
|||
{
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config;
|
||||
int ret;
|
||||
int ret, type;
|
||||
|
||||
switch (id->driver_data) {
|
||||
if (i2c->dev.of_node)
|
||||
type = arizona_of_get_type(&i2c->dev);
|
||||
else
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
#ifdef CONFIG_MFD_WM5102
|
||||
case WM5102:
|
||||
regmap_config = &wm5102_i2c_regmap;
|
||||
|
@ -84,6 +89,7 @@ static struct i2c_driver arizona_i2c_driver = {
|
|||
.name = "arizona",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &arizona_pm_ops,
|
||||
.of_match_table = of_match_ptr(arizona_of_match),
|
||||
},
|
||||
.probe = arizona_i2c_probe,
|
||||
.remove = arizona_i2c_remove,
|
||||
|
|
|
@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_device *spi)
|
|||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config;
|
||||
int ret;
|
||||
int ret, type;
|
||||
|
||||
switch (id->driver_data) {
|
||||
if (spi->dev.of_node)
|
||||
type = arizona_of_get_type(&spi->dev);
|
||||
else
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
#ifdef CONFIG_MFD_WM5102
|
||||
case WM5102:
|
||||
regmap_config = &wm5102_spi_regmap;
|
||||
|
@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_driver = {
|
|||
.name = "arizona",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &arizona_pm_ops,
|
||||
.of_match_table = of_match_ptr(arizona_of_match),
|
||||
},
|
||||
.probe = arizona_spi_probe,
|
||||
.remove = arizona_spi_remove,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef _WM5102_H
|
||||
#define _WM5102_H
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
|
@ -26,6 +27,8 @@ extern const struct regmap_config wm5110_spi_regmap;
|
|||
|
||||
extern const struct dev_pm_ops arizona_pm_ops;
|
||||
|
||||
extern const struct of_device_id arizona_of_match[];
|
||||
|
||||
extern const struct regmap_irq_chip wm5102_aod;
|
||||
extern const struct regmap_irq_chip wm5102_irq;
|
||||
|
||||
|
@ -37,4 +40,13 @@ int arizona_dev_exit(struct arizona *arizona);
|
|||
int arizona_irq_init(struct arizona *arizona);
|
||||
int arizona_irq_exit(struct arizona *arizona);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
int arizona_of_get_type(struct device *dev);
|
||||
#else
|
||||
static inline int arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user