mfd-lee-3.13-1

MFD patches due for v3.13.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJSZ+qhAAoJEFGvii+H/Hdh3KwQAIKDelOPdhCMw4mOBrXr89GX
 4OLJhc2GuZEB49E1aJUEGAyJDsXz10eGWSSh/RT+N3Z3/R3ckW9Fej390fsIVQje
 U3aG4FgNU0gRPIsd0xl8MZjt1wIgfQ9mx5eSglyAvecrYYSVpofI6qEPVT524Q9Z
 wfo/D9VEePxOxcUForULNob/AT+dX2OhHsxEjufOwnOEiNbV4bI+FgIBWFLFyyTA
 gL9/q2CeW2RJbc+npudd9KDQYiSAv9BGESEEx/LQguBMgildr+xt7V8iwAFiG8na
 e+IJU5ULsxoR+Y5xi0Ghkx/a1k40lsLOOTQrpLSUJmAGXHjW7O6Ll7AKc/bdzhOD
 ym8HNaror9s2nUF/2msfXWda6e71pCl34+xIdVVfrMLrVMNhyIkGUjw/KCS34J7g
 ybChBscLLQ7ZwVljTmwyFRnmXQH4zSJqcinVvlBxGLAEaK3c6SH3aJch3HNa9kIo
 AYIEbUAUNLYTmizBZvZQp5X9Vn8MudQD7SgIOaNh3hImqdRbFIWg1YGHpBJ/4Ils
 Pk6SbXwrhGqmYbB+mqpjklZX/m2QDHMj9ho48hGHQ5ZucmsG8a4v8cBW9hpM5Dqi
 dz6TUICDjUm41hX1tyi5BIxxoMHUYLs689aqOq3QJ42ybK7FzEYbkp0HbexIXCiT
 ae/+DKjau5D6/ghMLpY8
 =6TTT
 -----END PGP SIGNATURE-----

Merge tag 'mfd-lee-3.13-1' of git://git.linaro.org/people/ljones/mfd

mfd-lee-3.13-1

MFD patches due for v3.13.
This commit is contained in:
Samuel Ortiz 2013-10-25 11:03:48 +02:00
commit 8df5a1ba67
56 changed files with 1826 additions and 208 deletions

View file

@ -1247,7 +1247,7 @@ static struct i2c_driver pm860x_driver = {
.name = "88PM860x",
.owner = THIS_MODULE,
.pm = &pm860x_pm_ops,
.of_match_table = of_match_ptr(pm860x_dt_ids),
.of_match_table = pm860x_dt_ids,
},
.probe = pm860x_probe,
.remove = pm860x_remove,

View file

@ -27,6 +27,18 @@ config MFD_AS3711
help
Support for the AS3711 PMIC from AMS
config MFD_AS3722
bool "ams AS3722 Power Management IC"
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
depends on I2C && OF
help
The ams AS3722 is a compact system PMU suitable for mobile phones,
tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down
controllers, 11 LDOs, RTC, automatic battery, temperature and
over current monitoring, GPIOs, ADC and a watchdog.
config PMIC_ADP5520
bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
depends on I2C=y
@ -1151,6 +1163,16 @@ config MFD_WM8994
core support for the WM8994, in order to use the actual
functionaltiy of the device other drivers must be enabled.
config MFD_STW481X
bool "Support for ST Microelectronics STw481x"
depends on I2C && ARCH_NOMADIK
select REGMAP_I2C
select MFD_CORE
help
Select this option to enable the STw481x chip driver used
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
endmenu
endif

View file

@ -162,3 +162,5 @@ obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
obj-$(CONFIG_MFD_RETU) += retu-mfd.o
obj-$(CONFIG_MFD_AS3711) += as3711.o
obj-$(CONFIG_MFD_AS3722) += as3722.o
obj-$(CONFIG_MFD_STW481X) += stw481x.o

View file

@ -293,7 +293,7 @@ static ssize_t aat2870_reg_write_file(struct file *file,
unsigned long addr, val;
int ret;
buf_size = min(count, (sizeof(buf)-1));
buf_size = min(count, (size_t)(sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size)) {
dev_err(aat2870->dev, "Failed to copy from user\n");
return -EFAULT;

View file

@ -540,7 +540,7 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
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)
else if (arizona->pdata.gpio_defaults[i] == 0)
arizona->pdata.gpio_defaults[i] = 0x10000;
}
} else {
@ -607,11 +607,11 @@ 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));
else
arizona_of_get_core_pdata(arizona);
regcache_cache_only(arizona->regmap, true);

View file

@ -17,6 +17,7 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/mfd/arizona/core.h>

View file

@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/of.h>
#include <linux/mfd/arizona/core.h>

View file

@ -17,6 +17,7 @@
#include <linux/mfd/as3711.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>

449
drivers/mfd/as3722.c Normal file
View file

@ -0,0 +1,449 @@
/*
* Core driver for ams AS3722 PMICs
*
* Copyright (C) 2013 AMS AG
* Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
*
* Author: Florian Lobmaier <florian.lobmaier@ams.com>
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
#include <linux/mfd/as3722.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#define AS3722_DEVICE_ID 0x0C
static const struct resource as3722_rtc_resource[] = {
{
.name = "as3722-rtc-alarm",
.start = AS3722_IRQ_RTC_ALARM,
.end = AS3722_IRQ_RTC_ALARM,
.flags = IORESOURCE_IRQ,
},
};
static const struct resource as3722_adc_resource[] = {
{
.name = "as3722-adc",
.start = AS3722_IRQ_ADC,
.end = AS3722_IRQ_ADC,
.flags = IORESOURCE_IRQ,
},
};
static struct mfd_cell as3722_devs[] = {
{
.name = "as3722-pinctrl",
},
{
.name = "as3722-regulator",
},
{
.name = "as3722-rtc",
.num_resources = ARRAY_SIZE(as3722_rtc_resource),
.resources = as3722_rtc_resource,
},
{
.name = "as3722-adc",
.num_resources = ARRAY_SIZE(as3722_adc_resource),
.resources = as3722_adc_resource,
},
{
.name = "as3722-power-off",
},
};
static const struct regmap_irq as3722_irqs[] = {
/* INT1 IRQs */
[AS3722_IRQ_LID] = {
.mask = AS3722_INTERRUPT_MASK1_LID,
},
[AS3722_IRQ_ACOK] = {
.mask = AS3722_INTERRUPT_MASK1_ACOK,
},
[AS3722_IRQ_ENABLE1] = {
.mask = AS3722_INTERRUPT_MASK1_ENABLE1,
},
[AS3722_IRQ_OCCUR_ALARM_SD0] = {
.mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0,
},
[AS3722_IRQ_ONKEY_LONG_PRESS] = {
.mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG,
},
[AS3722_IRQ_ONKEY] = {
.mask = AS3722_INTERRUPT_MASK1_ONKEY,
},
[AS3722_IRQ_OVTMP] = {
.mask = AS3722_INTERRUPT_MASK1_OVTMP,
},
[AS3722_IRQ_LOWBAT] = {
.mask = AS3722_INTERRUPT_MASK1_LOWBAT,
},
/* INT2 IRQs */
[AS3722_IRQ_SD0_LV] = {
.mask = AS3722_INTERRUPT_MASK2_SD0_LV,
.reg_offset = 1,
},
[AS3722_IRQ_SD1_LV] = {
.mask = AS3722_INTERRUPT_MASK2_SD1_LV,
.reg_offset = 1,
},
[AS3722_IRQ_SD2_LV] = {
.mask = AS3722_INTERRUPT_MASK2_SD2345_LV,
.reg_offset = 1,
},
[AS3722_IRQ_PWM1_OV_PROT] = {
.mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT,
.reg_offset = 1,
},
[AS3722_IRQ_PWM2_OV_PROT] = {
.mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT,
.reg_offset = 1,
},
[AS3722_IRQ_ENABLE2] = {
.mask = AS3722_INTERRUPT_MASK2_ENABLE2,
.reg_offset = 1,
},
[AS3722_IRQ_SD6_LV] = {
.mask = AS3722_INTERRUPT_MASK2_SD6_LV,
.reg_offset = 1,
},
[AS3722_IRQ_RTC_REP] = {
.mask = AS3722_INTERRUPT_MASK2_RTC_REP,
.reg_offset = 1,
},
/* INT3 IRQs */
[AS3722_IRQ_RTC_ALARM] = {
.mask = AS3722_INTERRUPT_MASK3_RTC_ALARM,
.reg_offset = 2,
},
[AS3722_IRQ_GPIO1] = {
.mask = AS3722_INTERRUPT_MASK3_GPIO1,
.reg_offset = 2,
},
[AS3722_IRQ_GPIO2] = {
.mask = AS3722_INTERRUPT_MASK3_GPIO2,
.reg_offset = 2,
},
[AS3722_IRQ_GPIO3] = {
.mask = AS3722_INTERRUPT_MASK3_GPIO3,
.reg_offset = 2,
},
[AS3722_IRQ_GPIO4] = {
.mask = AS3722_INTERRUPT_MASK3_GPIO4,
.reg_offset = 2,
},
[AS3722_IRQ_GPIO5] = {
.mask = AS3722_INTERRUPT_MASK3_GPIO5,
.reg_offset = 2,
},
[AS3722_IRQ_WATCHDOG] = {
.mask = AS3722_INTERRUPT_MASK3_WATCHDOG,
.reg_offset = 2,
},
[AS3722_IRQ_ENABLE3] = {
.mask = AS3722_INTERRUPT_MASK3_ENABLE3,
.reg_offset = 2,
},
/* INT4 IRQs */
[AS3722_IRQ_TEMP_SD0_SHUTDOWN] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN,
.reg_offset = 3,
},
[AS3722_IRQ_TEMP_SD1_SHUTDOWN] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN,
.reg_offset = 3,
},
[AS3722_IRQ_TEMP_SD2_SHUTDOWN] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN,
.reg_offset = 3,
},
[AS3722_IRQ_TEMP_SD0_ALARM] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM,
.reg_offset = 3,
},
[AS3722_IRQ_TEMP_SD1_ALARM] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM,
.reg_offset = 3,
},
[AS3722_IRQ_TEMP_SD6_ALARM] = {
.mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM,
.reg_offset = 3,
},
[AS3722_IRQ_OCCUR_ALARM_SD6] = {
.mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6,
.reg_offset = 3,
},
[AS3722_IRQ_ADC] = {
.mask = AS3722_INTERRUPT_MASK4_ADC,
.reg_offset = 3,
},
};
static const struct regmap_irq_chip as3722_irq_chip = {
.name = "as3722",
.irqs = as3722_irqs,
.num_irqs = ARRAY_SIZE(as3722_irqs),
.num_regs = 4,
.status_base = AS3722_INTERRUPT_STATUS1_REG,
.mask_base = AS3722_INTERRUPT_MASK1_REG,
};
static int as3722_check_device_id(struct as3722 *as3722)
{
u32 val;
int ret;
/* Check that this is actually a AS3722 */
ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val);
if (ret < 0) {
dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret);
return ret;
}
if (val != AS3722_DEVICE_ID) {
dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val);
return -ENODEV;
}
ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val);
if (ret < 0) {
dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret);
return ret;
}
dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val);
return 0;
}
static int as3722_configure_pullups(struct as3722 *as3722)
{
int ret;
u32 val = 0;
if (as3722->en_intern_int_pullup)
val |= AS3722_INT_PULL_UP;
if (as3722->en_intern_i2c_pullup)
val |= AS3722_I2C_PULL_UP;
ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG,
AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val);
if (ret < 0)
dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret);
return ret;
}
static const struct regmap_range as3722_readable_ranges[] = {
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG),
regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG),
regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG),
regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
};
static const struct regmap_access_table as3722_readable_table = {
.yes_ranges = as3722_readable_ranges,
.n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges),
};
static const struct regmap_range as3722_writable_ranges[] = {
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG),
regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG),
regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG),
regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG),
regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG),
regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG),
regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG,
AS3722_BATTERY_VOLTAGE_MONITOR2_REG),
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG),
regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG),
regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG),
regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG),
regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG,
AS3722_ADC_CONFIGURATION_REG),
regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
};
static const struct regmap_access_table as3722_writable_table = {
.yes_ranges = as3722_writable_ranges,
.n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges),
};
static const struct regmap_range as3722_cacheable_ranges[] = {
regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG),
regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG),
};
static const struct regmap_access_table as3722_volatile_table = {
.no_ranges = as3722_cacheable_ranges,
.n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges),
};
const struct regmap_config as3722_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AS3722_MAX_REGISTER,
.cache_type = REGCACHE_RBTREE,
.rd_table = &as3722_readable_table,
.wr_table = &as3722_writable_table,
.volatile_table = &as3722_volatile_table,
};
static int as3722_i2c_of_probe(struct i2c_client *i2c,
struct as3722 *as3722)
{
struct device_node *np = i2c->dev.of_node;
struct irq_data *irq_data;
if (!np) {
dev_err(&i2c->dev, "Device Tree not found\n");
return -EINVAL;
}
irq_data = irq_get_irq_data(i2c->irq);
if (!irq_data) {
dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
return -EINVAL;
}
as3722->en_intern_int_pullup = of_property_read_bool(np,
"ams,enable-internal-int-pullup");
as3722->en_intern_i2c_pullup = of_property_read_bool(np,
"ams,enable-internal-i2c-pullup");
as3722->irq_flags = irqd_get_trigger_type(irq_data);
dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags);
return 0;
}
static int as3722_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct as3722 *as3722;
unsigned long irq_flags;
int ret;
as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL);
if (!as3722)
return -ENOMEM;
as3722->dev = &i2c->dev;
as3722->chip_irq = i2c->irq;
i2c_set_clientdata(i2c, as3722);
ret = as3722_i2c_of_probe(i2c, as3722);
if (ret < 0)
return ret;
as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config);
if (IS_ERR(as3722->regmap)) {
ret = PTR_ERR(as3722->regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
ret = as3722_check_device_id(as3722);
if (ret < 0)
return ret;
irq_flags = as3722->irq_flags | IRQF_ONESHOT;
ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq,
irq_flags, -1, &as3722_irq_chip,
&as3722->irq_data);
if (ret < 0) {
dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret);
return ret;
}
ret = as3722_configure_pullups(as3722);
if (ret < 0)
goto scrub;
ret = mfd_add_devices(&i2c->dev, -1, as3722_devs,
ARRAY_SIZE(as3722_devs), NULL, 0,
regmap_irq_get_domain(as3722->irq_data));
if (ret) {
dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret);
goto scrub;
}
dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
return 0;
scrub:
regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
return ret;
}
static int as3722_i2c_remove(struct i2c_client *i2c)
{
struct as3722 *as3722 = i2c_get_clientdata(i2c);
mfd_remove_devices(as3722->dev);
regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data);
return 0;
}
static const struct of_device_id as3722_of_match[] = {
{ .compatible = "ams,as3722", },
{},
};
MODULE_DEVICE_TABLE(of, as3722_of_match);
static const struct i2c_device_id as3722_i2c_id[] = {
{ "as3722", 0 },
{},
};
MODULE_DEVICE_TABLE(i2c, as3722_i2c_id);
static struct i2c_driver as3722_i2c_driver = {
.driver = {
.name = "as3722",
.owner = THIS_MODULE,
.of_match_table = as3722_of_match,
},
.probe = as3722_i2c_probe,
.remove = as3722_i2c_remove,
.id_table = as3722_i2c_id,
};
module_i2c_driver(as3722_i2c_driver);
MODULE_DESCRIPTION("I2C support for AS3722 PMICs");
MODULE_AUTHOR("Florian Lobmaier <[email protected]>");
MODULE_AUTHOR("Laxman Dewangan <[email protected]>");
MODULE_LICENSE("GPL");

View file

@ -86,7 +86,11 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
return 0;
}
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
/*
* According to errata item 24, multiwrite mode should be avoided
* in order to prevent register data corruption after power-down.
*/
static int da9052_i2c_disable_multiwrite(struct da9052 *da9052)
{
int reg_val, ret;
@ -94,8 +98,8 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
if (ret < 0)
return ret;
if (reg_val & DA9052_CONTROL_B_WRITEMODE) {
reg_val &= ~DA9052_CONTROL_B_WRITEMODE;
if (!(reg_val & DA9052_CONTROL_B_WRITEMODE)) {
reg_val |= DA9052_CONTROL_B_WRITEMODE;
ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG,
reg_val);
if (ret < 0)
@ -154,7 +158,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
return ret;
}
ret = da9052_i2c_enable_multiwrite(da9052);
ret = da9052_i2c_disable_multiwrite(da9052);
if (ret < 0)
return ret;

View file

@ -394,16 +394,12 @@ static int pcap_add_subdev(struct pcap_chip *pcap,
static int ezx_pcap_remove(struct spi_device *spi)
{
struct pcap_chip *pcap = spi_get_drvdata(spi);
struct pcap_platform_data *pdata = dev_get_platdata(&spi->dev);
int i, adc_irq;
int i;
/* remove all registered subdevs */
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* cleanup ADC */
adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
devm_free_irq(&spi->dev, adc_irq, pcap);
mutex_lock(&pcap->adc_mutex);
for (i = 0; i < PCAP_ADC_MAXQ; i++)
kfree(pcap->adc_queue[i]);
@ -509,8 +505,6 @@ static int ezx_pcap_probe(struct spi_device *spi)
remove_subdevs:
device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
/* free_adc: */
devm_free_irq(&spi->dev, adc_irq, pcap);
free_irqchip:
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
irq_set_chip_and_handler(i, NULL, NULL);

View file

@ -969,7 +969,6 @@ static int lpc_ich_probe(struct pci_dev *dev,
if (!cell_added) {
dev_warn(&dev->dev, "No MFD cells added\n");
lpc_ich_restore_config_space(dev);
pci_set_drvdata(dev, NULL);
return -ENODEV;
}
@ -980,7 +979,6 @@ static void lpc_ich_remove(struct pci_dev *dev)
{
mfd_remove_devices(&dev->dev);
lpc_ich_restore_config_space(dev);
pci_set_drvdata(dev, NULL);
}
static struct pci_driver lpc_ich_driver = {

View file

@ -59,18 +59,21 @@ static struct mfd_cell isch_smbus_cell = {
.name = "isch_smbus",
.num_resources = 1,
.resources = &smbus_sch_resource,
.ignore_resource_conflicts = true,
};
static struct mfd_cell sch_gpio_cell = {
.name = "sch_gpio",
.num_resources = 1,
.resources = &gpio_sch_resource,
.ignore_resource_conflicts = true,
};
static struct mfd_cell wdt_sch_cell = {
.name = "ie6xx_wdt",
.num_resources = 1,
.resources = &wdt_sch_resource,
.ignore_resource_conflicts = true,
};
static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {

View file

@ -31,6 +31,7 @@
#include <linux/mfd/max77686.h>
#include <linux/mfd/max77686-private.h>
#include <linux/err.h>
#include <linux/of.h>
#define I2C_ADDR_RTC (0x0C >> 1)

View file

@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
@ -110,15 +111,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77693_dev *max77693;
struct max77693_platform_data *pdata = dev_get_platdata(&i2c->dev);
u8 reg_data;
int ret = 0;
if (!pdata) {
dev_err(&i2c->dev, "No platform data found.\n");
return -EINVAL;
}
max77693 = devm_kzalloc(&i2c->dev,
sizeof(struct max77693_dev), GFP_KERNEL);
if (max77693 == NULL)
@ -138,8 +133,6 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
return ret;
}
max77693->wakeup = pdata->wakeup;
ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
&reg_data);
if (ret < 0) {
@ -179,8 +172,6 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
if (ret < 0)
goto err_mfd;
device_init_wakeup(max77693->dev, pdata->wakeup);
return ret;
err_mfd:
@ -235,11 +226,19 @@ static const struct dev_pm_ops max77693_pm = {
.resume = max77693_resume,
};
#ifdef CONFIG_OF
static struct of_device_id max77693_dt_match[] = {
{ .compatible = "maxim,max77693" },
{},
};
#endif
static struct i2c_driver max77693_i2c_driver = {
.driver = {
.name = "max77693",
.owner = THIS_MODULE,
.pm = &max77693_pm,
.of_match_table = of_match_ptr(max77693_dt_match),
},
.probe = max77693_i2c_probe,
.remove = max77693_i2c_remove,

View file

@ -17,6 +17,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/max8907.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

View file

@ -238,7 +238,7 @@ static struct i2c_driver max8925_driver = {
.name = "max8925",
.owner = THIS_MODULE,
.pm = &max8925_pm_ops,
.of_match_table = of_match_ptr(max8925_dt_ids),
.of_match_table = max8925_dt_ids,
},
.probe = max8925_probe,
.remove = max8925_remove,

View file

@ -24,6 +24,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>

View file

@ -158,8 +158,6 @@ int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val)
{
int ret;
BUG_ON(!mutex_is_locked(&mc13xxx->lock));
if (offset > MC13XXX_NUMREGS)
return -EINVAL;
@ -172,8 +170,6 @@ EXPORT_SYMBOL(mc13xxx_reg_read);
int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val)
{
BUG_ON(!mutex_is_locked(&mc13xxx->lock));
dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val);
if (offset > MC13XXX_NUMREGS || val > 0xffffff)
@ -186,7 +182,6 @@ EXPORT_SYMBOL(mc13xxx_reg_write);
int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
u32 mask, u32 val)
{
BUG_ON(!mutex_is_locked(&mc13xxx->lock));
BUG_ON(val & ~mask);
dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x (mask: 0x%06x)\n",
offset, val, mask);

View file

@ -78,7 +78,6 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
ret = PTR_ERR(mc13xxx->regmap);
dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
ret);
dev_set_drvdata(&client->dev, NULL);
return ret;
}

View file

@ -94,10 +94,15 @@ static int mc13xxx_spi_write(void *context, const void *data, size_t count)
{
struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);
const char *reg = data;
if (count != 4)
return -ENOTSUPP;
/* include errata fix for spi audio problems */
if (*reg == MC13783_AUDIO_CODEC || *reg == MC13783_AUDIO_DAC)
spi_write(spi, data, count);
return spi_write(spi, data, count);
}

View file

@ -328,13 +328,13 @@ static int usbhs_runtime_resume(struct device *dev)
omap_tll_enable(pdata);
if (!IS_ERR(omap->ehci_logic_fck))
clk_enable(omap->ehci_logic_fck);
clk_prepare_enable(omap->ehci_logic_fck);
for (i = 0; i < omap->nports; i++) {
switch (pdata->port_mode[i]) {
case OMAP_EHCI_PORT_MODE_HSIC:
if (!IS_ERR(omap->hsic60m_clk[i])) {
r = clk_enable(omap->hsic60m_clk[i]);
r = clk_prepare_enable(omap->hsic60m_clk[i]);
if (r) {
dev_err(dev,
"Can't enable port %d hsic60m clk:%d\n",
@ -343,7 +343,7 @@ static int usbhs_runtime_resume(struct device *dev)
}
if (!IS_ERR(omap->hsic480m_clk[i])) {
r = clk_enable(omap->hsic480m_clk[i]);
r = clk_prepare_enable(omap->hsic480m_clk[i]);
if (r) {
dev_err(dev,
"Can't enable port %d hsic480m clk:%d\n",
@ -354,7 +354,7 @@ static int usbhs_runtime_resume(struct device *dev)
case OMAP_EHCI_PORT_MODE_TLL:
if (!IS_ERR(omap->utmi_clk[i])) {
r = clk_enable(omap->utmi_clk[i]);
r = clk_prepare_enable(omap->utmi_clk[i]);
if (r) {
dev_err(dev,
"Can't enable port %d clk : %d\n",
@ -382,15 +382,15 @@ static int usbhs_runtime_suspend(struct device *dev)
switch (pdata->port_mode[i]) {
case OMAP_EHCI_PORT_MODE_HSIC:
if (!IS_ERR(omap->hsic60m_clk[i]))
clk_disable(omap->hsic60m_clk[i]);
clk_disable_unprepare(omap->hsic60m_clk[i]);
if (!IS_ERR(omap->hsic480m_clk[i]))
clk_disable(omap->hsic480m_clk[i]);
clk_disable_unprepare(omap->hsic480m_clk[i]);
/* Fall through as utmi_clks were used in HSIC mode */
case OMAP_EHCI_PORT_MODE_TLL:
if (!IS_ERR(omap->utmi_clk[i]))
clk_disable(omap->utmi_clk[i]);
clk_disable_unprepare(omap->utmi_clk[i]);
break;
default:
break;
@ -398,7 +398,7 @@ static int usbhs_runtime_suspend(struct device *dev)
}
if (!IS_ERR(omap->ehci_logic_fck))
clk_disable(omap->ehci_logic_fck);
clk_disable_unprepare(omap->ehci_logic_fck);
omap_tll_disable(pdata);
@ -893,7 +893,7 @@ static struct platform_driver usbhs_omap_driver = {
.name = (char *)usbhs_driver_name,
.owner = THIS_MODULE,
.pm = &usbhsomap_dev_pm_ops,
.of_match_table = of_match_ptr(usbhs_omap_dt_ids),
.of_match_table = usbhs_omap_dt_ids,
},
.remove = usbhs_omap_remove,
};

View file

@ -320,7 +320,7 @@ static struct platform_driver usbtll_omap_driver = {
.driver = {
.name = (char *)usbtll_driver_name,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(usbtll_omap_dt_ids),
.of_match_table = usbtll_omap_dt_ids,
},
.probe = usbtll_omap_probe,
.remove = usbtll_omap_remove,
@ -429,7 +429,7 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
if (IS_ERR(tll->ch_clk[i]))
continue;
r = clk_enable(tll->ch_clk[i]);
r = clk_prepare_enable(tll->ch_clk[i]);
if (r) {
dev_err(tll_dev,
"Error enabling ch %d clock: %d\n", i, r);
@ -460,7 +460,7 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
for (i = 0; i < tll->nch; i++) {
if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
if (!IS_ERR(tll->ch_clk[i]))
clk_disable(tll->ch_clk[i]);
clk_disable_unprepare(tll->ch_clk[i]);
}
}

View file

@ -368,6 +368,7 @@ static const struct of_device_id of_palmas_match_tbl[] = {
},
{ },
};
MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
static int palmas_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
@ -402,7 +403,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
palmas->dev = &i2c->dev;
palmas->irq = i2c->irq;
match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev);
match = of_match_device(of_palmas_match_tbl, &i2c->dev);
if (!match)
return -ENODATA;
@ -421,7 +422,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
dev_err(palmas->dev,
"can't attach client %d\n", i);
ret = -ENOMEM;
goto err;
goto err_i2c;
}
palmas->i2c_clients[i]->dev.of_node = of_node_get(node);
}
@ -432,7 +433,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
dev_err(palmas->dev,
"Failed to allocate regmap %d, err: %d\n",
i, ret);
goto err;
goto err_i2c;
}
}
@ -451,7 +452,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
reg);
if (ret < 0) {
dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
goto err;
goto err_i2c;
}
/* Change IRQ into clear on read mode for efficiency */
@ -465,7 +466,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
&palmas->irq_data);
if (ret < 0)
goto err;
goto err_i2c;
no_irq:
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
@ -551,7 +552,6 @@ no_irq:
} else if (pdata->pm_off && !pm_power_off) {
palmas_dev = palmas;
pm_power_off = palmas_power_off;
return ret;
}
}
@ -559,17 +559,31 @@ no_irq:
err_irq:
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
err:
err_i2c:
for (i = 1; i < PALMAS_NUM_CLIENTS; i++) {
if (palmas->i2c_clients[i])
i2c_unregister_device(palmas->i2c_clients[i]);
}
return ret;
}
static int palmas_i2c_remove(struct i2c_client *i2c)
{
struct palmas *palmas = i2c_get_clientdata(i2c);
int i;
mfd_remove_devices(palmas->dev);
regmap_del_irq_chip(palmas->irq, palmas->irq_data);
for (i = 1; i < PALMAS_NUM_CLIENTS; i++) {
if (palmas->i2c_clients[i])
i2c_unregister_device(palmas->i2c_clients[i]);
}
if (palmas == palmas_dev) {
pm_power_off = NULL;
palmas_dev = NULL;
}
return 0;
}

View file

@ -130,13 +130,57 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV, 0xFE46);
err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
if (err < 0)
return err;
msleep(1);
return rtsx_pci_write_phy_register(pcr, PHY_BPCR, 0x05C0);
err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
PHY_PCR_RSSI_EN);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
PHY_FLD4_BER_CHK_EN);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
PHY_FLD3_RXDELINK);
if (err < 0)
return err;
return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
PHY_TUNE_TUNED12);
}
static int rts5249_turn_on_led(struct rtsx_pcr *pcr)

View file

@ -1149,7 +1149,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
pcr->remap_addr = ioremap_nocache(base, len);
if (!pcr->remap_addr) {
ret = -ENOMEM;
goto free_host;
goto free_handle;
}
pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
@ -1209,8 +1209,6 @@ disable_msi:
pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
unmap:
iounmap(pcr->remap_addr);
free_host:
dev_set_drvdata(&pcidev->dev, NULL);
free_handle:
kfree(handle);
free_pcr:
@ -1242,7 +1240,6 @@ static void rtsx_pci_remove(struct pci_dev *pcidev)
pci_disable_msi(pcr->pci);
iounmap(pcr->remap_addr);
dev_set_drvdata(&pcidev->dev, NULL);
pci_release_regions(pcidev);
pci_disable_device(pcidev);

View file

@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>

View file

@ -1232,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
}
static DEVICE_ATTR(dbg_regs, 0666, sm501_dbg_regs, NULL);
static DEVICE_ATTR(dbg_regs, 0444, sm501_dbg_regs, NULL);
/* sm501_init_reg
*
@ -1660,7 +1660,6 @@ static int sm501_pci_probe(struct pci_dev *dev,
err3:
pci_disable_device(dev);
err2:
pci_set_drvdata(dev, NULL);
kfree(sm);
err1:
return err;
@ -1695,7 +1694,6 @@ static void sm501_pci_remove(struct pci_dev *dev)
release_resource(sm->regs_claim);
kfree(sm->regs_claim);
pci_set_drvdata(dev, NULL);
pci_disable_device(dev);
}

250
drivers/mfd/stw481x.c Normal file
View file

@ -0,0 +1,250 @@
/*
* Core driver for STw4810/STw4811
*
* Copyright (C) 2013 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/mfd/stw481x.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
/*
* This driver can only access the non-USB portions of STw4811, the register
* range 0x00-0x10 dealing with USB is bound to the two special I2C pins used
* for USB control.
*/
/* Registers inside the power control address space */
#define STW_PC_VCORE_SEL 0x05U
#define STW_PC_VAUX_SEL 0x06U
#define STW_PC_VPLL_SEL 0x07U
/**
* stw481x_get_pctl_reg() - get a power control register
* @stw481x: handle to the stw481x chip
* @reg: power control register to fetch
*
* The power control registers is a set of one-time-programmable registers
* in its own register space, accessed by writing addess bits to these
* two registers: bits 7,6,5 of PCTL_REG_LO corresponds to the 3 LSBs of
* the address and bits 8,9 of PCTL_REG_HI corresponds to the 2 MSBs of
* the address, forming an address space of 5 bits, i.e. 32 registers
* 0x00 ... 0x1f can be obtained.
*/
static int stw481x_get_pctl_reg(struct stw481x *stw481x, u8 reg)
{
u8 msb = (reg >> 3) & 0x03;
u8 lsb = (reg << 5) & 0xe0;
unsigned int val;
u8 vrfy;
int ret;
ret = regmap_write(stw481x->map, STW_PCTL_REG_HI, msb);
if (ret)
return ret;
ret = regmap_write(stw481x->map, STW_PCTL_REG_LO, lsb);
if (ret)
return ret;
ret = regmap_read(stw481x->map, STW_PCTL_REG_HI, &val);
if (ret)
return ret;
vrfy = (val & 0x03) << 3;
ret = regmap_read(stw481x->map, STW_PCTL_REG_LO, &val);
if (ret)
return ret;
vrfy |= ((val >> 5) & 0x07);
if (vrfy != reg)
return -EIO;
return (val >> 1) & 0x0f;
}
static int stw481x_startup(struct stw481x *stw481x)
{
/* Voltages multiplied by 100 */
u8 vcore_val[] = { 100, 105, 110, 115, 120, 122, 124, 126, 128,
130, 132, 134, 136, 138, 140, 145 };
u8 vpll_val[] = { 105, 120, 130, 180 };
u8 vaux_val[] = { 15, 18, 25, 28 };
u8 vcore;
u8 vcore_slp;
u8 vpll;
u8 vaux;
bool vaux_en;
bool it_warn;
int ret;
unsigned int val;
ret = regmap_read(stw481x->map, STW_CONF1, &val);
if (ret)
return ret;
vaux_en = !!(val & STW_CONF1_PDN_VAUX);
it_warn = !!(val & STW_CONF1_IT_WARN);
dev_info(&stw481x->client->dev, "voltages %s\n",
(val & STW_CONF1_V_MONITORING) ? "OK" : "LOW");
dev_info(&stw481x->client->dev, "MMC level shifter %s\n",
(val & STW_CONF1_MMC_LS_STATUS) ? "high impedance" : "ON");
dev_info(&stw481x->client->dev, "VMMC: %s\n",
(val & STW_CONF1_PDN_VMMC) ? "ON" : "disabled");
dev_info(&stw481x->client->dev, "STw481x power control registers:\n");
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VCORE_SEL);
if (ret < 0)
return ret;
vcore = ret & 0x0f;
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VAUX_SEL);
if (ret < 0)
return ret;
vaux = (ret >> 2) & 3;
vpll = (ret >> 4) & 1; /* Save bit 4 */
ret = stw481x_get_pctl_reg(stw481x, STW_PC_VPLL_SEL);
if (ret < 0)
return ret;
vpll |= (ret >> 1) & 2;
dev_info(&stw481x->client->dev, "VCORE: %u.%uV %s\n",
vcore_val[vcore] / 100, vcore_val[vcore] % 100,
(ret & 4) ? "ON" : "OFF");
dev_info(&stw481x->client->dev, "VPLL: %u.%uV %s\n",
vpll_val[vpll] / 100, vpll_val[vpll] % 100,
(ret & 0x10) ? "ON" : "OFF");
dev_info(&stw481x->client->dev, "VAUX: %u.%uV %s\n",
vaux_val[vaux] / 10, vaux_val[vaux] % 10,
vaux_en ? "ON" : "OFF");
ret = regmap_read(stw481x->map, STW_CONF2, &val);
if (ret)
return ret;
dev_info(&stw481x->client->dev, "TWARN: %s threshold, %s\n",
it_warn ? "below" : "above",
(val & STW_CONF2_MASK_TWARN) ?
"enabled" : "mask through VDDOK");
dev_info(&stw481x->client->dev, "VMMC: %s\n",
(val & STW_CONF2_VMMC_EXT) ? "internal" : "external");
dev_info(&stw481x->client->dev, "IT WAKE UP: %s\n",
(val & STW_CONF2_MASK_IT_WAKE_UP) ? "enabled" : "masked");
dev_info(&stw481x->client->dev, "GPO1: %s\n",
(val & STW_CONF2_GPO1) ? "low" : "high impedance");
dev_info(&stw481x->client->dev, "GPO2: %s\n",
(val & STW_CONF2_GPO2) ? "low" : "high impedance");
ret = regmap_read(stw481x->map, STW_VCORE_SLEEP, &val);
if (ret)
return ret;
vcore_slp = val & 0x0f;
dev_info(&stw481x->client->dev, "VCORE SLEEP: %u.%uV\n",
vcore_val[vcore_slp] / 100, vcore_val[vcore_slp] % 100);
return 0;
}
/*
* MFD cells - we have one cell which is selected operation
* mode, and we always have a GPIO cell.
*/
static struct mfd_cell stw481x_cells[] = {
{
.of_compatible = "st,stw481x-vmmc",
.name = "stw481x-vmmc-regulator",
.id = -1,
},
};
const struct regmap_config stw481x_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int stw481x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct stw481x *stw481x;
int ret;
int i;
stw481x = devm_kzalloc(&client->dev, sizeof(*stw481x), GFP_KERNEL);
if (!stw481x)
return -ENOMEM;
i2c_set_clientdata(client, stw481x);
stw481x->client = client;
stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
ret = stw481x_startup(stw481x);
if (ret) {
dev_err(&client->dev, "chip initialization failed\n");
return ret;
}
/* Set up and register the platform devices. */
for (i = 0; i < ARRAY_SIZE(stw481x_cells); i++) {
/* One state holder for all drivers, this is simple */
stw481x_cells[i].platform_data = stw481x;
stw481x_cells[i].pdata_size = sizeof(*stw481x);
}
ret = mfd_add_devices(&client->dev, 0, stw481x_cells,
ARRAY_SIZE(stw481x_cells), NULL, 0, NULL);
if (ret)
return ret;
dev_info(&client->dev, "initialized STw481x device\n");
return ret;
}
static int stw481x_remove(struct i2c_client *client)
{
mfd_remove_devices(&client->dev);
return 0;
}
/*
* This ID table is completely unused, as this is a pure
* device-tree probed driver, but it has to be here due to
* the structure of the I2C core.
*/
static const struct i2c_device_id stw481x_id[] = {
{ "stw481x", 0 },
{ },
};
static const struct of_device_id stw481x_match[] = {
{ .compatible = "st,stw4810", },
{ .compatible = "st,stw4811", },
{ },
};
MODULE_DEVICE_TABLE(of, stw481x_match);
static struct i2c_driver stw481x_driver = {
.driver = {
.name = "stw481x",
.of_match_table = stw481x_match,
},
.probe = stw481x_probe,
.remove = stw481x_remove,
.id_table = stw481x_id,
};
module_i2c_driver(stw481x_driver);
MODULE_AUTHOR("Linus Walleij");
MODULE_DESCRIPTION("STw481x PMIC driver");
MODULE_LICENSE("GPL v2");

View file

@ -16,6 +16,19 @@
#include <linux/mfd/core.h>
#include <linux/mfd/tc3589x.h>
/**
* enum tc3589x_version - indicates the TC3589x version
*/
enum tc3589x_version {
TC3589X_TC35890,
TC3589X_TC35892,
TC3589X_TC35893,
TC3589X_TC35894,
TC3589X_TC35895,
TC3589X_TC35896,
TC3589X_UNKNOWN,
};
#define TC3589x_CLKMODE_MODCTL_SLEEP 0x0
#define TC3589x_CLKMODE_MODCTL_OPERATION (1 << 0)
@ -361,7 +374,21 @@ static int tc3589x_probe(struct i2c_client *i2c,
tc3589x->i2c = i2c;
tc3589x->pdata = pdata;
tc3589x->irq_base = pdata->irq_base;
tc3589x->num_gpio = id->driver_data;
switch (id->driver_data) {
case TC3589X_TC35893:
case TC3589X_TC35895:
case TC3589X_TC35896:
tc3589x->num_gpio = 20;
break;
case TC3589X_TC35890:
case TC3589X_TC35892:
case TC3589X_TC35894:
case TC3589X_UNKNOWN:
default:
tc3589x->num_gpio = 24;
break;
}
i2c_set_clientdata(i2c, tc3589x);
@ -432,7 +459,13 @@ static int tc3589x_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend, tc3589x_resume);
static const struct i2c_device_id tc3589x_id[] = {
{ "tc3589x", 24 },
{ "tc35890", TC3589X_TC35890 },
{ "tc35892", TC3589X_TC35892 },
{ "tc35893", TC3589X_TC35893 },
{ "tc35894", TC3589X_TC35894 },
{ "tc35895", TC3589X_TC35895 },
{ "tc35896", TC3589X_TC35896 },
{ "tc3589x", TC3589X_UNKNOWN },
{ }
};
MODULE_DEVICE_TABLE(i2c, tc3589x_id);

View file

@ -445,7 +445,6 @@ static int ti_ssp_remove(struct platform_device *pdev)
iounmap(ssp->regs);
release_mem_region(ssp->res->start, resource_size(ssp->res));
kfree(ssp);
dev_set_drvdata(dev, NULL);
return 0;
}

View file

@ -56,21 +56,25 @@ EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
{
spin_lock(&tsadc->reg_lock);
unsigned long flags;
spin_lock_irqsave(&tsadc->reg_lock, flags);
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
tsadc->reg_se_cache |= val;
am335x_tsc_se_update(tsadc);
spin_unlock(&tsadc->reg_lock);
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
}
EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
{
spin_lock(&tsadc->reg_lock);
unsigned long flags;
spin_lock_irqsave(&tsadc->reg_lock, flags);
tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
tsadc->reg_se_cache &= ~val;
am335x_tsc_se_update(tsadc);
spin_unlock(&tsadc->reg_lock);
spin_unlock_irqrestore(&tsadc->reg_lock, flags);
}
EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
@ -95,7 +99,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
const __be32 *cur;
u32 val;
int err, ctrl;
int clk_value, clock_rate;
int clock_rate;
int tsc_wires = 0, adc_channels = 0, total_channels;
int readouts = 0;
@ -196,11 +200,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
}
clock_rate = clk_get_rate(clk);
clk_put(clk);
clk_value = clock_rate / ADC_CLK;
tscadc->clk_div = clock_rate / ADC_CLK;
/* TSCADC_CLKDIV needs to be configured to the value minus 1 */
clk_value = clk_value - 1;
tscadc_writel(tscadc, REG_CLKDIV, clk_value);
tscadc->clk_div--;
tscadc_writel(tscadc, REG_CLKDIV, tscadc->clk_div);
/* Set the control register bits */
ctrl = CNTRLREG_STEPCONFIGWRT |
@ -303,6 +307,8 @@ static int tscadc_resume(struct device *dev)
tscadc_writel(tscadc_dev, REG_CTRL,
(restore | CNTRLREG_TSCSSENB));
tscadc_writel(tscadc_dev, REG_CLKDIV, tscadc_dev->clk_div);
return 0;
}
@ -326,7 +332,7 @@ static struct platform_driver ti_tscadc_driver = {
.name = "ti_am3359-tscadc",
.owner = THIS_MODULE,
.pm = TSCADC_PM_OPS,
.of_match_table = of_match_ptr(ti_tscadc_dt_ids),
.of_match_table = ti_tscadc_dt_ids,
},
.probe = ti_tscadc_probe,
.remove = ti_tscadc_remove,

View file

@ -678,7 +678,7 @@ static int timb_probe(struct pci_dev *dev,
priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
dev_err(&dev->dev, "Failed to request ctl mem\n");
goto err_request;
goto err_start;
}
priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
@ -828,13 +828,10 @@ err_config:
iounmap(priv->ctl_membase);
err_ioremap:
release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
err_request:
pci_set_drvdata(dev, NULL);
err_start:
pci_disable_device(dev);
err_enable:
kfree(priv);
pci_set_drvdata(dev, NULL);
return -ENODEV;
}
@ -851,7 +848,6 @@ static void timb_remove(struct pci_dev *dev)
pci_disable_msix(dev);
pci_disable_device(dev);
pci_set_drvdata(dev, NULL);
kfree(priv);
}

View file

@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps6507x.h>

View file

@ -245,7 +245,7 @@ static struct i2c_driver tps65217_driver = {
.driver = {
.name = "tps65217",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps65217_of_match),
.of_match_table = tps65217_of_match,
},
.id_table = tps65217_id_table,
.probe = tps65217_probe,

View file

@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h>
@ -124,6 +125,7 @@ struct tps6586x {
struct i2c_client *client;
struct regmap *regmap;
int irq;
struct irq_chip irq_chip;
struct mutex irq_lock;
int irq_base;
@ -261,12 +263,23 @@ static void tps6586x_irq_sync_unlock(struct irq_data *data)
mutex_unlock(&tps6586x->irq_lock);
}
#ifdef CONFIG_PM_SLEEP
static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on)
{
struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
return irq_set_irq_wake(tps6586x->irq, on);
}
#else
#define tps6586x_irq_set_wake NULL
#endif
static struct irq_chip tps6586x_irq_chip = {
.name = "tps6586x",
.irq_bus_lock = tps6586x_irq_lock,
.irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
.irq_disable = tps6586x_irq_disable,
.irq_enable = tps6586x_irq_enable,
.irq_set_wake = tps6586x_irq_set_wake,
};
static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
@ -331,6 +344,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
int new_irq_base;
int irq_num = ARRAY_SIZE(tps6586x_irqs);
tps6586x->irq = irq;
mutex_init(&tps6586x->irq_lock);
for (i = 0; i < 5; i++) {
tps6586x->mask_reg[i] = 0xff;
@ -360,10 +375,8 @@ static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
"tps6586x", tps6586x);
if (!ret) {
if (!ret)
device_init_wakeup(tps6586x->dev, 1);
enable_irq_wake(irq);
}
return ret;
}

View file

@ -25,6 +25,7 @@
#include <linux/mfd/core.h>
#include <linux/regmap.h>
#include <linux/mfd/tps65910.h>
#include <linux/of.h>
#include <linux/of_device.h>
static struct resource rtc_resources[] = {

View file

@ -619,7 +619,7 @@ static int twl6040_probe(struct i2c_client *client,
"twl6040_irq_th", twl6040);
if (ret) {
dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret);
goto thirq_err;
goto readyirq_err;
}
/* dual-access registers controlled by I2C only */
@ -659,14 +659,10 @@ static int twl6040_probe(struct i2c_client *client,
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
NULL, 0, NULL);
if (ret)
goto mfd_err;
goto readyirq_err;
return 0;
mfd_err:
devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
thirq_err:
devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
readyirq_err:
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
gpio_err:
@ -681,8 +677,6 @@ static int twl6040_remove(struct i2c_client *client)
if (twl6040->power_count)
twl6040_power(twl6040, 0);
devm_free_irq(&client->dev, twl6040->irq_ready, twl6040);
devm_free_irq(&client->dev, twl6040->irq_th, twl6040);
regmap_del_irq_chip(twl6040->irq, twl6040->irq_data);
mfd_remove_devices(&client->dev);

View file

@ -553,6 +553,7 @@ static int ucb1x00_probe(struct mcp *mcp)
if (ucb->irq_base < 0) {
dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
ucb->irq_base);
ret = ucb->irq_base;
goto err_irq_alloc;
}

View file

@ -903,7 +903,6 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
{ 0x00000D50, 0x0000 }, /* R3408 - AOD wkup and trig */
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */

View file

@ -592,7 +592,7 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
{ 0x00000458, 0x0001 }, /* R1112 - Noise Gate Control */
{ 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */
{ 0x00000480, 0x0040 }, /* R1152 - Class W ANC Threshold 1 */
{ 0x00000481, 0x0040 }, /* R1153 - Class W ANC Threshold 2 */
{ 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
@ -1204,7 +1204,6 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
{ 0x00000D50, 0x0000 }, /* R3408 - AOD wkup and trig */
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
@ -2291,21 +2290,37 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP1_SCRATCH_0:
case ARIZONA_DSP1_SCRATCH_1:
case ARIZONA_DSP1_SCRATCH_2:
case ARIZONA_DSP1_SCRATCH_3:
case ARIZONA_DSP2_CONTROL_1:
case ARIZONA_DSP2_CLOCKING_1:
case ARIZONA_DSP2_STATUS_1:
case ARIZONA_DSP2_STATUS_2:
case ARIZONA_DSP2_STATUS_3:
case ARIZONA_DSP2_SCRATCH_0:
case ARIZONA_DSP2_SCRATCH_1:
case ARIZONA_DSP2_SCRATCH_2:
case ARIZONA_DSP2_SCRATCH_3:
case ARIZONA_DSP3_CONTROL_1:
case ARIZONA_DSP3_CLOCKING_1:
case ARIZONA_DSP3_STATUS_1:
case ARIZONA_DSP3_STATUS_2:
case ARIZONA_DSP3_STATUS_3:
case ARIZONA_DSP3_SCRATCH_0:
case ARIZONA_DSP3_SCRATCH_1:
case ARIZONA_DSP3_SCRATCH_2:
case ARIZONA_DSP3_SCRATCH_3:
case ARIZONA_DSP4_CONTROL_1:
case ARIZONA_DSP4_CLOCKING_1:
case ARIZONA_DSP4_STATUS_1:
case ARIZONA_DSP4_STATUS_2:
case ARIZONA_DSP4_STATUS_3:
case ARIZONA_DSP4_SCRATCH_0:
case ARIZONA_DSP4_SCRATCH_1:
case ARIZONA_DSP4_SCRATCH_2:
case ARIZONA_DSP4_SCRATCH_3:
return true;
default:
return false;
@ -2347,25 +2362,41 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_INTERRUPT_RAW_STATUS_7:
case ARIZONA_INTERRUPT_RAW_STATUS_8:
case ARIZONA_IRQ_PIN_STATUS:
case ARIZONA_AOD_WKUP_AND_TRIG:
case ARIZONA_AOD_IRQ1:
case ARIZONA_AOD_IRQ2:
case ARIZONA_AOD_IRQ_RAW_STATUS:
case ARIZONA_FX_CTRL2:
case ARIZONA_ASRC_STATUS:
case ARIZONA_DSP_STATUS:
case ARIZONA_DSP1_CONTROL_1:
case ARIZONA_DSP1_CLOCKING_1:
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP1_SCRATCH_0:
case ARIZONA_DSP1_SCRATCH_1:
case ARIZONA_DSP1_SCRATCH_2:
case ARIZONA_DSP1_SCRATCH_3:
case ARIZONA_DSP2_STATUS_1:
case ARIZONA_DSP2_STATUS_2:
case ARIZONA_DSP2_STATUS_3:
case ARIZONA_DSP2_SCRATCH_0:
case ARIZONA_DSP2_SCRATCH_1:
case ARIZONA_DSP2_SCRATCH_2:
case ARIZONA_DSP2_SCRATCH_3:
case ARIZONA_DSP3_STATUS_1:
case ARIZONA_DSP3_STATUS_2:
case ARIZONA_DSP3_STATUS_3:
case ARIZONA_DSP3_SCRATCH_0:
case ARIZONA_DSP3_SCRATCH_1:
case ARIZONA_DSP3_SCRATCH_2:
case ARIZONA_DSP3_SCRATCH_3:
case ARIZONA_DSP4_STATUS_1:
case ARIZONA_DSP4_STATUS_2:
case ARIZONA_DSP4_STATUS_3:
case ARIZONA_DSP4_SCRATCH_0:
case ARIZONA_DSP4_SCRATCH_1:
case ARIZONA_DSP4_SCRATCH_2:
case ARIZONA_DSP4_SCRATCH_3:
return true;
default:
return false;

View file

@ -33,84 +33,6 @@
#include "wm8994.h"
/**
* wm8994_reg_read: Read a single WM8994 register.
*
* @wm8994: Device to read from.
* @reg: Register to read.
*/
int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
{
unsigned int val;
int ret;
ret = regmap_read(wm8994->regmap, reg, &val);
if (ret < 0)
return ret;
else
return val;
}
EXPORT_SYMBOL_GPL(wm8994_reg_read);
/**
* wm8994_bulk_read: Read multiple WM8994 registers
*
* @wm8994: Device to read from
* @reg: First register
* @count: Number of registers
* @buf: Buffer to fill. The data will be returned big endian.
*/
int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
int count, u16 *buf)
{
return regmap_bulk_read(wm8994->regmap, reg, buf, count);
}
/**
* wm8994_reg_write: Write a single WM8994 register.
*
* @wm8994: Device to write to.
* @reg: Register to write to.
* @val: Value to write.
*/
int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
unsigned short val)
{
return regmap_write(wm8994->regmap, reg, val);
}
EXPORT_SYMBOL_GPL(wm8994_reg_write);
/**
* wm8994_bulk_write: Write multiple WM8994 registers
*
* @wm8994: Device to write to
* @reg: First register
* @count: Number of registers
* @buf: Buffer to write from. Data must be big-endian formatted.
*/
int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
int count, const u16 *buf)
{
return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
}
EXPORT_SYMBOL_GPL(wm8994_bulk_write);
/**
* wm8994_set_bits: Set the value of a bitfield in a WM8994 register
*
* @wm8994: Device to write to.
* @reg: Register to write to.
* @mask: Mask of bits to set.
* @val: Value to set (unshifted)
*/
int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
unsigned short mask, unsigned short val)
{
return regmap_update_bits(wm8994->regmap, reg, mask, val);
}
EXPORT_SYMBOL_GPL(wm8994_set_bits);
static struct mfd_cell wm8994_regulator_devs[] = {
{
.name = "wm8994-ldo",