- New Device Support

- Add support for 88pm860; 88pm80x
    - Add support for 24c08 EEPROM; at24
    - Add support for Broxton Whiskey Cove; intel*
    - Add support for RTS522A; rts5227
    - Add support for I2C devices; intel_quark_i2c_gpio
  - New Functionality
    - Add microphone support; arizona
    - Add general purpose switch support; arizona
    - Add fuel-gauge support; da9150-core
    - Add shutdown support; sec-core
    - Add charger support; tps65217
    - Add flexible serial communication unit support; atmel-flexcom
    - Add power button support; axp20x
    - Add led-flash support; rt5033
  - Core Frameworks
    - Supply a generic macro for defining Regmap IRQs
    - Rework ACPI child device matching
  - Fix-ups
    - Use Regmap to access registers; tps6105x
    - Use DEFINE_RES_IRQ_NAMED() macro; da9150
    - Re-arrange device registration order; intel_quark_i2c_gpio
    - Allow OF matching; cros_ec_i2c, atmel-hlcdc, hi6421-pmic, max8997, sm501
    - Handle deferred probe; twl6040
    - Improve accuracy of headphone detect; arizona
    - Unnecessary MODULE_ALIAS() removal; bcm590xx, rt5033
    - Remove unused code; htc-i2cpld, arizona, pcf50633-irq, sec-core
    - Simplify code; kempld, rts5209, da903x, lm3533, da9052, arizona
    - Remove #iffery; arizona
    - DT binding adaptions; many
  - Bug Fixes
    - Fix possible NULL pointer dereference; wm831x, tps6105x
    - Fix 64bit bug; intel_soc_pmic_bxtwc
    - Fix signedness issue; arizona
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWOzEbAAoJEFGvii+H/HdhbUEQAIBHvNaunWp362L2D2lOOQMa
 cBlGiR2yXCpsFGAcvpr50zX5soFuNITGea1CidJmp/ZIHIG7hVUz5E8wQZ8HdiyG
 03UKsa6xkVx9i+PhV5agUjxi6MDgUvxsPwdbVw6LTw1wQejIrfxq7ObdcPo30OTI
 4r0tjLonQkGaFFdGqC4Jr7Grs7pvzmKzHu08AaknaoTyhUl/E9Wtq12HJFr8kUCw
 WNgEyiPzNk0h9EByCUiG7iFwyg1EJLsF1U973Th8Utvl7PFe8REQVZ46v9iYAM9J
 1OeSrsKhtyhQqAP/FJ5odZCXwTy9q6ifGfELyyS26/okCYWDzxDcF+hAp0VNbzb4
 zYvEnKue101Y+WEsF9bNaya3avf45obJuRaRukoGMZ/brW6+d1ub0kwUKMD8MqOn
 UFL3oZwfPQ8mWB5ddELl97dzJDwHbEIhWe7yKQVpTaJ2pCm6JSS5Vb0TU+A1Zywp
 Hie1Yr0y36npnCbml4W74O9H/rblpNpgFlaupfB6mHRWZyTsyQNeKJ6FWTirncgQ
 xy8Ti+ZsXlMTvWCzzS3GcjP9rAK0e5dKurOE8t+krZmTul96+OYsnvxRC0nyo7XC
 1PKomkWO+3if2DsnurFX/QKfE55PCKermJRO5mDZbsWp6aJAhKW5UwxAgkHpUHsJ
 hHaT+npBczXbq8jvEMTt
 =99/D
 -----END PGP SIGNATURE-----

Merge tag 'mfd-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Device Support:
   - Add support for 88pm860; 88pm80x
   - Add support for 24c08 EEPROM; at24
   - Add support for Broxton Whiskey Cove; intel*
   - Add support for RTS522A; rts5227
   - Add support for I2C devices; intel_quark_i2c_gpio

  New Functionality:
   - Add microphone support; arizona
   - Add general purpose switch support; arizona
   - Add fuel-gauge support; da9150-core
   - Add shutdown support; sec-core
   - Add charger support; tps65217
   - Add flexible serial communication unit support; atmel-flexcom
   - Add power button support; axp20x
   - Add led-flash support; rt5033

  Core Frameworks:
   - Supply a generic macro for defining Regmap IRQs
   - Rework ACPI child device matching

  Fix-ups:
   - Use Regmap to access registers; tps6105x
   - Use DEFINE_RES_IRQ_NAMED() macro; da9150
   - Re-arrange device registration order; intel_quark_i2c_gpio
   - Allow OF matching; cros_ec_i2c, atmel-hlcdc, hi6421-pmic, max8997, sm501
   - Handle deferred probe; twl6040
   - Improve accuracy of headphone detect; arizona
   - Unnecessary MODULE_ALIAS() removal; bcm590xx, rt5033
   - Remove unused code; htc-i2cpld, arizona, pcf50633-irq, sec-core
   - Simplify code; kempld, rts5209, da903x, lm3533, da9052, arizona
   - Remove #iffery; arizona
   - DT binding adaptions; many

  Bug Fixes:
   - Fix possible NULL pointer dereference; wm831x, tps6105x
   - Fix 64bit bug; intel_soc_pmic_bxtwc
   - Fix signedness issue; arizona"

* tag 'mfd-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (73 commits)
  bindings: mfd: s2mps11: Add documentation for s2mps15 PMIC
  mfd: sec-core: Remove unused s2mpu02-rtc and s2mpu02-clk children
  extcon: arizona: Add extcon specific device tree binding document
  MAINTAINERS: Add binding docs for Cirrus Logic/Wolfson Arizona devices
  mfd: arizona: Remove bindings covered in new subsystem specific docs
  mfd: rt5033: Add RT5033 Flash led sub device
  mfd: lpss: Add Intel Broxton PCI IDs
  mfd: lpss: Add Broxton ACPI IDs
  mfd: arizona: Signedness bug in arizona_runtime_suspend()
  mfd: axp20x: Add a cell for the power button part of the, axp288 PMICs
  mfd: dt-bindings: Document pulled down WRSTBI pin on S2MPS1X
  mfd: sec-core: Disable buck voltage reset on watchdog falling edge
  mfd: sec-core: Dump PMIC revision to find out the HW
  mfd: arizona: Use correct type ID for device tree config
  mfd: arizona: Remove use of codec build config #ifdefs
  mfd: arizona: Simplify adding subdevices
  mfd: arizona: Downgrade type mismatch messages to dev_warn
  mfd: arizona: Factor out checking of jack detection state
  mfd: arizona: Factor out DCVDD isolation control
  mfd: Make TPS6105X select REGMAP_I2C
  ...
This commit is contained in:
Linus Torvalds 2015-11-06 10:23:50 -08:00
commit bc914532a0
74 changed files with 2531 additions and 410 deletions

View file

@ -33,6 +33,8 @@ static struct pm80x_chip_mapping chip_mapping[] = {
{0x3, CHIP_PM800},
/* 88PM805 chip id number */
{0x0, CHIP_PM805},
/* 88PM860 chip id number */
{0x4, CHIP_PM860},
};
/*

View file

@ -60,6 +60,17 @@ config MFD_AAT2870_CORE
additional drivers must be enabled in order to use the
functionality of the device.
config MFD_ATMEL_FLEXCOM
tristate "Atmel Flexcom (Flexible Serial Communication Unit)"
select MFD_CORE
depends on OF
help
Select this to get support for Atmel Flexcom. This is a wrapper
which embeds a SPI controller, a I2C controller and a USART. Only
one function can be used at a time. The choice is done at boot time
by the probe function of this MFD driver according to a device tree
property.
config MFD_ATMEL_HLCDC
tristate "Atmel HLCDC (High-end LCD Controller)"
select MFD_CORE
@ -725,9 +736,10 @@ config MFD_RTSX_PCI
select MFD_CORE
help
This supports for Realtek PCI-Express card reader including rts5209,
rts5229, rtl8411, etc. Realtek card reader supports access to many
types of memory cards, such as Memory Stick, Memory Stick Pro,
Secure Digital and MultiMediaCard.
rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc.
Realtek card reader supports access to many types of memory cards,
such as Memory Stick, Memory Stick Pro, Secure Digital and
MultiMediaCard.
config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
@ -1059,6 +1071,7 @@ config MFD_PALMAS
config TPS6105X
tristate "TI TPS61050/61052 Boost Converters"
depends on I2C
select REGMAP_I2C
select REGULATOR
select MFD_CORE
select REGULATOR_FIXED_VOLTAGE
@ -1471,7 +1484,7 @@ config MFD_WM8994
config MFD_STW481X
tristate "Support for ST Microelectronics STw481x"
depends on I2C && ARCH_NOMADIK
depends on I2C && (ARCH_NOMADIK || COMPILE_TEST)
select REGMAP_I2C
select MFD_CORE
help

View file

@ -164,6 +164,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o
obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o
obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o
obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o
@ -190,5 +191,6 @@ obj-$(CONFIG_MFD_RT5033) += rt5033.o
obj-$(CONFIG_MFD_SKY81452) += sky81452.o
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o

View file

@ -24,6 +24,7 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mfd/arizona/core.h>
#include <linux/mfd/arizona/registers.h>
@ -69,8 +70,6 @@ EXPORT_SYMBOL_GPL(arizona_clk32k_enable);
int arizona_clk32k_disable(struct arizona *arizona)
{
int ret = 0;
mutex_lock(&arizona->clk_lock);
BUG_ON(arizona->clk32k_ref <= 0);
@ -90,7 +89,7 @@ int arizona_clk32k_disable(struct arizona *arizona)
mutex_unlock(&arizona->clk_lock);
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(arizona_clk32k_disable);
@ -462,6 +461,50 @@ static int wm5102_clear_write_sequencer(struct arizona *arizona)
}
#ifdef CONFIG_PM
static int arizona_isolate_dcvdd(struct arizona *arizona)
{
int ret;
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1,
ARIZONA_ISOLATE_DCVDD1);
if (ret != 0)
dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n", ret);
return ret;
}
static int arizona_connect_dcvdd(struct arizona *arizona)
{
int ret;
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1, 0);
if (ret != 0)
dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret);
return ret;
}
static int arizona_is_jack_det_active(struct arizona *arizona)
{
unsigned int val;
int ret;
ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
if (ret) {
dev_err(arizona->dev,
"Failed to check jack det status: %d\n", ret);
return ret;
} else if (val & ARIZONA_JD1_ENA) {
return 1;
} else {
return 0;
}
}
static int arizona_runtime_resume(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
@ -501,14 +544,9 @@ static int arizona_runtime_resume(struct device *dev)
switch (arizona->type) {
case WM5102:
if (arizona->external_dcvdd) {
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1, 0);
if (ret != 0) {
dev_err(arizona->dev,
"Failed to connect DCVDD: %d\n", ret);
ret = arizona_connect_dcvdd(arizona);
if (ret != 0)
goto err;
}
}
ret = wm5102_patch(arizona);
@ -533,14 +571,9 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
if (arizona->external_dcvdd) {
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1, 0);
if (ret) {
dev_err(arizona->dev,
"Failed to connect DCVDD: %d\n", ret);
ret = arizona_connect_dcvdd(arizona);
if (ret != 0)
goto err;
}
} else {
/*
* As this is only called for the internal regulator
@ -571,14 +604,9 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
if (arizona->external_dcvdd) {
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1, 0);
if (ret != 0) {
dev_err(arizona->dev,
"Failed to connect DCVDD: %d\n", ret);
ret = arizona_connect_dcvdd(arizona);
if (ret != 0)
goto err;
}
}
break;
}
@ -600,49 +628,50 @@ err:
static int arizona_runtime_suspend(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
unsigned int val;
int jd_active = 0;
int ret;
dev_dbg(arizona->dev, "Entering AoD mode\n");
ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
if (ret) {
dev_err(dev, "Failed to check jack det status: %d\n", ret);
return ret;
}
if (arizona->external_dcvdd) {
ret = regmap_update_bits(arizona->regmap,
ARIZONA_ISOLATION_CONTROL,
ARIZONA_ISOLATE_DCVDD1,
ARIZONA_ISOLATE_DCVDD1);
if (ret != 0) {
dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
ret);
return ret;
}
}
switch (arizona->type) {
case WM5110:
case WM8280:
if (arizona->external_dcvdd)
break;
jd_active = arizona_is_jack_det_active(arizona);
if (jd_active < 0)
return jd_active;
/*
* As this is only called for the internal regulator
* (where we know voltage ranges available) it is ok
* to request an exact range.
*/
ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000);
if (ret < 0) {
dev_err(arizona->dev,
"Failed to set suspend voltage: %d\n", ret);
return ret;
if (arizona->external_dcvdd) {
ret = arizona_isolate_dcvdd(arizona);
if (ret != 0)
return ret;
} else {
/*
* As this is only called for the internal regulator
* (where we know voltage ranges available) it is ok
* to request an exact range.
*/
ret = regulator_set_voltage(arizona->dcvdd,
1175000, 1175000);
if (ret < 0) {
dev_err(arizona->dev,
"Failed to set suspend voltage: %d\n",
ret);
return ret;
}
}
break;
case WM5102:
if (!(val & ARIZONA_JD1_ENA)) {
jd_active = arizona_is_jack_det_active(arizona);
if (jd_active < 0)
return jd_active;
if (arizona->external_dcvdd) {
ret = arizona_isolate_dcvdd(arizona);
if (ret != 0)
return ret;
}
if (!jd_active) {
ret = regmap_write(arizona->regmap,
ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
if (ret) {
@ -654,6 +683,15 @@ static int arizona_runtime_suspend(struct device *dev)
}
break;
default:
jd_active = arizona_is_jack_det_active(arizona);
if (jd_active < 0)
return jd_active;
if (arizona->external_dcvdd) {
ret = arizona_isolate_dcvdd(arizona);
if (ret != 0)
return ret;
}
break;
}
@ -662,7 +700,7 @@ static int arizona_runtime_suspend(struct device *dev)
regulator_disable(arizona->dcvdd);
/* Allow us to completely power down if no jack detection */
if (!(val & ARIZONA_JD1_ENA)) {
if (!jd_active) {
dev_dbg(arizona->dev, "Fully powering off\n");
arizona->has_fully_powered_off = true;
@ -928,7 +966,8 @@ int arizona_dev_init(struct arizona *arizona)
const char *type_name;
unsigned int reg, val, mask;
int (*apply_patch)(struct arizona *) = NULL;
int ret, i;
const struct mfd_cell *subdevs = NULL;
int n_subdevs, ret, i;
dev_set_drvdata(arizona->dev, arizona);
mutex_init(&arizona->clk_lock);
@ -1089,74 +1128,95 @@ int arizona_dev_init(struct arizona *arizona)
arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
switch (reg) {
#ifdef CONFIG_MFD_WM5102
case 0x5102:
type_name = "WM5102";
if (arizona->type != WM5102) {
dev_err(arizona->dev, "WM5102 registered as %d\n",
arizona->type);
arizona->type = WM5102;
if (IS_ENABLED(CONFIG_MFD_WM5102)) {
type_name = "WM5102";
if (arizona->type != WM5102) {
dev_warn(arizona->dev,
"WM5102 registered as %d\n",
arizona->type);
arizona->type = WM5102;
}
apply_patch = wm5102_patch;
arizona->rev &= 0x7;
subdevs = wm5102_devs;
n_subdevs = ARRAY_SIZE(wm5102_devs);
}
apply_patch = wm5102_patch;
arizona->rev &= 0x7;
break;
#endif
#ifdef CONFIG_MFD_WM5110
case 0x5110:
switch (arizona->type) {
case WM5110:
type_name = "WM5110";
break;
case WM8280:
type_name = "WM8280";
break;
default:
type_name = "WM5110";
dev_err(arizona->dev, "WM5110 registered as %d\n",
arizona->type);
arizona->type = WM5110;
break;
if (IS_ENABLED(CONFIG_MFD_WM5110)) {
switch (arizona->type) {
case WM5110:
type_name = "WM5110";
break;
case WM8280:
type_name = "WM8280";
break;
default:
type_name = "WM5110";
dev_warn(arizona->dev,
"WM5110 registered as %d\n",
arizona->type);
arizona->type = WM5110;
break;
}
apply_patch = wm5110_patch;
subdevs = wm5110_devs;
n_subdevs = ARRAY_SIZE(wm5110_devs);
}
apply_patch = wm5110_patch;
break;
#endif
#ifdef CONFIG_MFD_WM8997
case 0x8997:
type_name = "WM8997";
if (arizona->type != WM8997) {
dev_err(arizona->dev, "WM8997 registered as %d\n",
arizona->type);
arizona->type = WM8997;
if (IS_ENABLED(CONFIG_MFD_WM8997)) {
type_name = "WM8997";
if (arizona->type != WM8997) {
dev_warn(arizona->dev,
"WM8997 registered as %d\n",
arizona->type);
arizona->type = WM8997;
}
apply_patch = wm8997_patch;
subdevs = wm8997_devs;
n_subdevs = ARRAY_SIZE(wm8997_devs);
}
apply_patch = wm8997_patch;
break;
#endif
#ifdef CONFIG_MFD_WM8998
case 0x6349:
switch (arizona->type) {
case WM8998:
type_name = "WM8998";
break;
if (IS_ENABLED(CONFIG_MFD_WM8998)) {
switch (arizona->type) {
case WM8998:
type_name = "WM8998";
break;
case WM1814:
type_name = "WM1814";
break;
case WM1814:
type_name = "WM1814";
break;
default:
type_name = "WM8998";
dev_err(arizona->dev, "WM8998 registered as %d\n",
arizona->type);
arizona->type = WM8998;
default:
type_name = "WM8998";
dev_warn(arizona->dev,
"WM8998 registered as %d\n",
arizona->type);
arizona->type = WM8998;
}
apply_patch = wm8998_patch;
subdevs = wm8998_devs;
n_subdevs = ARRAY_SIZE(wm8998_devs);
}
apply_patch = wm8998_patch;
break;
#endif
default:
dev_err(arizona->dev, "Unknown device ID %x\n", reg);
goto err_reset;
}
if (!subdevs) {
dev_err(arizona->dev,
"No kernel support for device ID %x\n", reg);
goto err_reset;
}
dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
if (apply_patch) {
@ -1342,28 +1402,10 @@ int arizona_dev_init(struct arizona *arizona)
arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked",
arizona_underclocked, arizona);
switch (arizona->type) {
case WM5102:
ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
break;
case WM5110:
case WM8280:
ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
break;
case WM8997:
ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
break;
case WM8998:
case WM1814:
ret = mfd_add_devices(arizona->dev, -1, wm8998_devs,
ARRAY_SIZE(wm8998_devs), NULL, 0, NULL);
break;
}
ret = mfd_add_devices(arizona->dev, PLATFORM_DEVID_NONE,
subdevs, n_subdevs, NULL, 0, NULL);
if (ret != 0) {
if (ret) {
dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret);
goto err_irq;
}

View file

@ -27,7 +27,7 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct arizona *arizona;
const struct regmap_config *regmap_config;
const struct regmap_config *regmap_config = NULL;
unsigned long type;
int ret;
@ -37,31 +37,32 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
type = id->driver_data;
switch (type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
regmap_config = &wm5102_i2c_regmap;
if (IS_ENABLED(CONFIG_MFD_WM5102))
regmap_config = &wm5102_i2c_regmap;
break;
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
case WM8280:
regmap_config = &wm5110_i2c_regmap;
if (IS_ENABLED(CONFIG_MFD_WM5110))
regmap_config = &wm5110_i2c_regmap;
break;
#endif
#ifdef CONFIG_MFD_WM8997
case WM8997:
regmap_config = &wm8997_i2c_regmap;
if (IS_ENABLED(CONFIG_MFD_WM8997))
regmap_config = &wm8997_i2c_regmap;
break;
#endif
#ifdef CONFIG_MFD_WM8998
case WM8998:
case WM1814:
regmap_config = &wm8998_i2c_regmap;
if (IS_ENABLED(CONFIG_MFD_WM8998))
regmap_config = &wm8998_i2c_regmap;
break;
#endif
default:
dev_err(&i2c->dev, "Unknown device type %ld\n",
id->driver_data);
dev_err(&i2c->dev, "Unknown device type %ld\n", type);
return -EINVAL;
}
if (!regmap_config) {
dev_err(&i2c->dev,
"No kernel support for device type %ld\n", type);
return -EINVAL;
}
@ -77,7 +78,7 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
return ret;
}
arizona->type = id->driver_data;
arizona->type = type;
arizona->dev = &i2c->dev;
arizona->irq = i2c->irq;

View file

@ -169,7 +169,7 @@ static struct irq_chip arizona_irq_chip = {
static int arizona_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct regmap_irq_chip_data *data = h->host_data;
struct arizona *data = h->host_data;
irq_set_chip_data(virq, data);
irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq);

View file

@ -27,7 +27,7 @@ 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;
const struct regmap_config *regmap_config = NULL;
unsigned long type;
int ret;
@ -37,20 +37,23 @@ static int arizona_spi_probe(struct spi_device *spi)
type = id->driver_data;
switch (type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
regmap_config = &wm5102_spi_regmap;
if (IS_ENABLED(CONFIG_MFD_WM5102))
regmap_config = &wm5102_spi_regmap;
break;
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
case WM8280:
regmap_config = &wm5110_spi_regmap;
if (IS_ENABLED(CONFIG_MFD_WM5110))
regmap_config = &wm5110_spi_regmap;
break;
#endif
default:
dev_err(&spi->dev, "Unknown device type %ld\n",
id->driver_data);
dev_err(&spi->dev, "Unknown device type %ld\n", type);
return -EINVAL;
}
if (!regmap_config) {
dev_err(&spi->dev,
"No kernel support for device type %ld\n", type);
return -EINVAL;
}
@ -66,7 +69,7 @@ static int arizona_spi_probe(struct spi_device *spi)
return ret;
}
arizona->type = id->driver_data;
arizona->type = type;
arizona->dev = &spi->dev;
arizona->irq = spi->irq;

104
drivers/mfd/atmel-flexcom.c Normal file
View file

@ -0,0 +1,104 @@
/*
* Driver for Atmel Flexcom
*
* Copyright (C) 2015 Atmel Corporation
*
* Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <dt-bindings/mfd/atmel-flexcom.h>
/* I/O register offsets */
#define FLEX_MR 0x0 /* Mode Register */
#define FLEX_VERSION 0xfc /* Version Register */
/* Mode Register bit fields */
#define FLEX_MR_OPMODE_OFFSET (0) /* Operating Mode */
#define FLEX_MR_OPMODE_MASK (0x3 << FLEX_MR_OPMODE_OFFSET)
#define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \
FLEX_MR_OPMODE_MASK)
static int atmel_flexcom_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct clk *clk;
struct resource *res;
void __iomem *base;
u32 opmode;
int err;
err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode);
if (err)
return err;
if (opmode < ATMEL_FLEXCOM_MODE_USART ||
opmode > ATMEL_FLEXCOM_MODE_TWI)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
err = clk_prepare_enable(clk);
if (err)
return err;
/*
* Set the Operating Mode in the Mode Register: only the selected device
* is clocked. Hence, registers of the other serial devices remain
* inaccessible and are read as zero. Also the external I/O lines of the
* Flexcom are muxed to reach the selected device.
*/
writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR);
clk_disable_unprepare(clk);
return of_platform_populate(np, NULL, NULL, &pdev->dev);
}
static const struct of_device_id atmel_flexcom_of_match[] = {
{ .compatible = "atmel,sama5d2-flexcom" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
static struct platform_driver atmel_flexcom_driver = {
.probe = atmel_flexcom_probe,
.driver = {
.name = "atmel_flexcom",
.of_match_table = atmel_flexcom_of_match,
},
};
module_platform_driver(atmel_flexcom_driver);
MODULE_AUTHOR("Cyrille Pitchen <[email protected]>");
MODULE_DESCRIPTION("Atmel Flexcom MFD driver");
MODULE_LICENSE("GPL v2");

View file

@ -148,6 +148,7 @@ static const struct of_device_id atmel_hlcdc_match[] = {
{ .compatible = "atmel,sama5d4-hlcdc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);
static struct platform_driver atmel_hlcdc_driver = {
.probe = atmel_hlcdc_probe,

View file

@ -161,6 +161,21 @@ static struct resource axp22x_pek_resources[] = {
},
};
static struct resource axp288_power_button_resources[] = {
{
.name = "PEK_DBR",
.start = AXP288_IRQ_POKN,
.end = AXP288_IRQ_POKN,
.flags = IORESOURCE_IRQ,
},
{
.name = "PEK_DBF",
.start = AXP288_IRQ_POKP,
.end = AXP288_IRQ_POKP,
.flags = IORESOURCE_IRQ,
},
};
static struct resource axp288_fuel_gauge_resources[] = {
{
.start = AXP288_IRQ_QWBTU,
@ -571,6 +586,11 @@ static struct mfd_cell axp288_cells[] = {
.num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources),
.resources = axp288_fuel_gauge_resources,
},
{
.name = "axp20x-pek",
.num_resources = ARRAY_SIZE(axp288_power_button_resources),
.resources = axp288_power_button_resources,
},
{
.name = "axp288_pmic_acpi",
},

View file

@ -128,4 +128,3 @@ module_i2c_driver(bcm590xx_i2c_driver);
MODULE_AUTHOR("Matt Porter <[email protected]>");
MODULE_DESCRIPTION("BCM590xx multi-function driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("i2c:bcm590xx");

View file

@ -344,6 +344,12 @@ static int cros_ec_i2c_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend,
cros_ec_i2c_resume);
static const struct of_device_id cros_ec_i2c_of_match[] = {
{ .compatible = "google,cros-ec-i2c", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
static const struct i2c_device_id cros_ec_i2c_id[] = {
{ "cros-ec-i2c", 0 },
{ }
@ -353,6 +359,7 @@ MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id);
static struct i2c_driver cros_ec_driver = {
.driver = {
.name = "cros-ec-i2c",
.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
.pm = &cros_ec_i2c_pm_ops,
},
.probe = cros_ec_i2c_probe,

View file

@ -532,11 +532,7 @@ static int da903x_probe(struct i2c_client *client,
return ret;
}
ret = da903x_add_subdevs(chip, pdata);
if (ret)
return ret;
return 0;
return da903x_add_subdevs(chip, pdata);
}
static int da903x_remove(struct i2c_client *client)

View file

@ -51,6 +51,9 @@ static bool da9052_reg_readable(struct device *dev, unsigned int reg)
case DA9052_GPIO_2_3_REG:
case DA9052_GPIO_4_5_REG:
case DA9052_GPIO_6_7_REG:
case DA9052_GPIO_8_9_REG:
case DA9052_GPIO_10_11_REG:
case DA9052_GPIO_12_13_REG:
case DA9052_GPIO_14_15_REG:
case DA9052_ID_0_1_REG:
case DA9052_ID_2_3_REG:
@ -178,6 +181,9 @@ static bool da9052_reg_writeable(struct device *dev, unsigned int reg)
case DA9052_GPIO_2_3_REG:
case DA9052_GPIO_4_5_REG:
case DA9052_GPIO_6_7_REG:
case DA9052_GPIO_8_9_REG:
case DA9052_GPIO_10_11_REG:
case DA9052_GPIO_12_13_REG:
case DA9052_GPIO_14_15_REG:
case DA9052_ID_0_1_REG:
case DA9052_ID_2_3_REG:

View file

@ -174,11 +174,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
return ret;
}
ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0)
return ret;
return 0;
return da9052_device_init(da9052, id->driver_data);
}
static int da9052_i2c_remove(struct i2c_client *client)

View file

@ -56,11 +56,7 @@ static int da9052_spi_probe(struct spi_device *spi)
return ret;
}
ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0)
return ret;
return 0;
return da9052_device_init(da9052, id->driver_data);
}
static int da9052_spi_remove(struct spi_device *spi)

View file

@ -198,7 +198,7 @@ static int da9062_clear_fault_log(struct da9062 *chip)
return ret;
}
int get_device_type(struct da9062 *chip)
static int da9062_get_device_type(struct da9062 *chip)
{
int device_id, variant_id, variant_mrc;
int ret;
@ -466,7 +466,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
if (ret < 0)
dev_warn(chip->dev, "Cannot clear fault log\n");
ret = get_device_type(chip);
ret = da9062_get_device_type(chip);
if (ret)
return ret;

View file

@ -23,6 +23,77 @@
#include <linux/mfd/da9150/core.h>
#include <linux/mfd/da9150/registers.h>
/* Raw device access, used for QIF */
static int da9150_i2c_read_device(struct i2c_client *client, u8 addr, int count,
u8 *buf)
{
struct i2c_msg xfer;
int ret;
/*
* Read is split into two transfers as device expects STOP/START rather
* than repeated start to carry out this kind of access.
*/
/* Write address */
xfer.addr = client->addr;
xfer.flags = 0;
xfer.len = 1;
xfer.buf = &addr;
ret = i2c_transfer(client->adapter, &xfer, 1);
if (ret != 1) {
if (ret < 0)
return ret;
else
return -EIO;
}
/* Read data */
xfer.addr = client->addr;
xfer.flags = I2C_M_RD;
xfer.len = count;
xfer.buf = buf;
ret = i2c_transfer(client->adapter, &xfer, 1);
if (ret == 1)
return 0;
else if (ret < 0)
return ret;
else
return -EIO;
}
static int da9150_i2c_write_device(struct i2c_client *client, u8 addr,
int count, const u8 *buf)
{
struct i2c_msg xfer;
u8 *reg_data;
int ret;
reg_data = kzalloc(1 + count, GFP_KERNEL);
if (!reg_data)
return -ENOMEM;
reg_data[0] = addr;
memcpy(&reg_data[1], buf, count);
/* Write address & data */
xfer.addr = client->addr;
xfer.flags = 0;
xfer.len = 1 + count;
xfer.buf = reg_data;
ret = i2c_transfer(client->adapter, &xfer, 1);
kfree(reg_data);
if (ret == 1)
return 0;
else if (ret < 0)
return ret;
else
return -EIO;
}
static bool da9150_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@ -107,6 +178,28 @@ static const struct regmap_config da9150_regmap_config = {
.volatile_reg = da9150_volatile_reg,
};
void da9150_read_qif(struct da9150 *da9150, u8 addr, int count, u8 *buf)
{
int ret;
ret = da9150_i2c_read_device(da9150->core_qif, addr, count, buf);
if (ret < 0)
dev_err(da9150->dev, "Failed to read from QIF 0x%x: %d\n",
addr, ret);
}
EXPORT_SYMBOL_GPL(da9150_read_qif);
void da9150_write_qif(struct da9150 *da9150, u8 addr, int count, const u8 *buf)
{
int ret;
ret = da9150_i2c_write_device(da9150->core_qif, addr, count, buf);
if (ret < 0)
dev_err(da9150->dev, "Failed to write to QIF 0x%x: %d\n",
addr, ret);
}
EXPORT_SYMBOL_GPL(da9150_write_qif);
u8 da9150_reg_read(struct da9150 *da9150, u16 reg)
{
int val, ret;
@ -262,54 +355,45 @@ static const struct regmap_irq_chip da9150_regmap_irq_chip = {
};
static struct resource da9150_gpadc_resources[] = {
{
.name = "GPADC",
.start = DA9150_IRQ_GPADC,
.end = DA9150_IRQ_GPADC,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_GPADC, "GPADC"),
};
static struct resource da9150_charger_resources[] = {
{
.name = "CHG_STATUS",
.start = DA9150_IRQ_CHG,
.end = DA9150_IRQ_CHG,
.flags = IORESOURCE_IRQ,
},
{
.name = "CHG_TJUNC",
.start = DA9150_IRQ_TJUNC,
.end = DA9150_IRQ_TJUNC,
.flags = IORESOURCE_IRQ,
},
{
.name = "CHG_VFAULT",
.start = DA9150_IRQ_VFAULT,
.end = DA9150_IRQ_VFAULT,
.flags = IORESOURCE_IRQ,
},
{
.name = "CHG_VBUS",
.start = DA9150_IRQ_VBUS,
.end = DA9150_IRQ_VBUS,
.flags = IORESOURCE_IRQ,
},
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_CHG, "CHG_STATUS"),
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_TJUNC, "CHG_TJUNC"),
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VFAULT, "CHG_VFAULT"),
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VBUS, "CHG_VBUS"),
};
static struct resource da9150_fg_resources[] = {
DEFINE_RES_IRQ_NAMED(DA9150_IRQ_FG, "FG"),
};
enum da9150_dev_idx {
DA9150_GPADC_IDX = 0,
DA9150_CHARGER_IDX,
DA9150_FG_IDX,
};
static struct mfd_cell da9150_devs[] = {
{
[DA9150_GPADC_IDX] = {
.name = "da9150-gpadc",
.of_compatible = "dlg,da9150-gpadc",
.resources = da9150_gpadc_resources,
.num_resources = ARRAY_SIZE(da9150_gpadc_resources),
},
{
[DA9150_CHARGER_IDX] = {
.name = "da9150-charger",
.of_compatible = "dlg,da9150-charger",
.resources = da9150_charger_resources,
.num_resources = ARRAY_SIZE(da9150_charger_resources),
},
[DA9150_FG_IDX] = {
.name = "da9150-fuel-gauge",
.of_compatible = "dlg,da9150-fuel-gauge",
.resources = da9150_fg_resources,
.num_resources = ARRAY_SIZE(da9150_fg_resources),
},
};
static int da9150_probe(struct i2c_client *client,
@ -317,6 +401,7 @@ static int da9150_probe(struct i2c_client *client,
{
struct da9150 *da9150;
struct da9150_pdata *pdata = dev_get_platdata(&client->dev);
int qif_addr;
int ret;
da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL);
@ -335,16 +420,41 @@ static int da9150_probe(struct i2c_client *client,
return ret;
}
da9150->irq_base = pdata ? pdata->irq_base : -1;
/* Setup secondary I2C interface for QIF access */
qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A);
qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1;
qif_addr |= DA9150_QIF_I2C_ADDR_LSB;
da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr);
if (!da9150->core_qif) {
dev_err(da9150->dev, "Failed to attach QIF client\n");
return -ENODEV;
}
i2c_set_clientdata(da9150->core_qif, da9150);
if (pdata) {
da9150->irq_base = pdata->irq_base;
da9150_devs[DA9150_FG_IDX].platform_data = pdata->fg_pdata;
da9150_devs[DA9150_FG_IDX].pdata_size =
sizeof(struct da9150_fg_pdata);
} else {
da9150->irq_base = -1;
}
ret = regmap_add_irq_chip(da9150->regmap, da9150->irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
da9150->irq_base, &da9150_regmap_irq_chip,
&da9150->regmap_irq_data);
if (ret)
return ret;
if (ret) {
dev_err(da9150->dev, "Failed to add regmap irq chip: %d\n",
ret);
goto regmap_irq_fail;
}
da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data);
enable_irq_wake(da9150->irq);
ret = mfd_add_devices(da9150->dev, -1, da9150_devs,
@ -352,11 +462,17 @@ static int da9150_probe(struct i2c_client *client,
da9150->irq_base, NULL);
if (ret) {
dev_err(da9150->dev, "Failed to add child devices: %d\n", ret);
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
return ret;
goto mfd_fail;
}
return 0;
mfd_fail:
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
regmap_irq_fail:
i2c_unregister_device(da9150->core_qif);
return ret;
}
static int da9150_remove(struct i2c_client *client)
@ -365,6 +481,7 @@ static int da9150_remove(struct i2c_client *client)
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
mfd_remove_devices(da9150->dev);
i2c_unregister_device(da9150->core_qif);
return 0;
}

View file

@ -97,6 +97,7 @@ static const struct of_device_id of_hi6421_pmic_match_tbl[] = {
{ .compatible = "hisilicon,hi6421-pmic", },
{ },
};
MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match_tbl);
static struct platform_driver hi6421_pmic_driver = {
.driver = {

View file

@ -318,7 +318,6 @@ static int htcpld_setup_chip_irq(
struct htcpld_data *htcpld;
struct htcpld_chip *chip;
unsigned int irq, irq_end;
int ret = 0;
/* Get the platform and driver data */
htcpld = platform_get_drvdata(pdev);
@ -333,7 +332,7 @@ static int htcpld_setup_chip_irq(
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
}
return ret;
return 0;
}
static int htcpld_register_chip_i2c(

View file

@ -25,10 +25,26 @@ static const struct intel_lpss_platform_info spt_info = {
.clk_rate = 120000000,
};
static const struct intel_lpss_platform_info bxt_info = {
.clk_rate = 100000000,
};
static const struct intel_lpss_platform_info bxt_i2c_info = {
.clk_rate = 133000000,
};
static const struct acpi_device_id intel_lpss_acpi_ids[] = {
/* SPT */
{ "INT3446", (kernel_ulong_t)&spt_info },
{ "INT3447", (kernel_ulong_t)&spt_info },
/* BXT */
{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
{ "80860ABC", (kernel_ulong_t)&bxt_info },
{ "80860AC2", (kernel_ulong_t)&bxt_info },
/* APL */
{ "80865AAC", (kernel_ulong_t)&bxt_i2c_info },
{ "80865ABC", (kernel_ulong_t)&bxt_info },
{ "80865AC2", (kernel_ulong_t)&bxt_info },
{ }
};
MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids);

View file

@ -70,7 +70,52 @@ static const struct intel_lpss_platform_info spt_uart_info = {
.clk_con_id = "baudclk",
};
static const struct intel_lpss_platform_info bxt_info = {
.clk_rate = 100000000,
};
static const struct intel_lpss_platform_info bxt_uart_info = {
.clk_rate = 100000000,
.clk_con_id = "baudclk",
};
static const struct intel_lpss_platform_info bxt_i2c_info = {
.clk_rate = 133000000,
};
static const struct pci_device_id intel_lpss_pci_ids[] = {
/* BXT */
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab0), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab2), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab4), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab6), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0ab8), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0aba), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x0abc), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x0abe), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x0ac0), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x0ac2), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info },
/* APL */
{ PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x5ac2), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info },
/* SPT-LP */
{ PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info },

View file

@ -26,6 +26,8 @@
#include <linux/pm_runtime.h>
#include <linux/seq_file.h>
#include <asm-generic/io-64-nonatomic-lo-hi.h>
#include "intel-lpss.h"
#define LPSS_DEV_OFFSET 0x000
@ -52,8 +54,7 @@
#define LPSS_PRIV_SSP_REG 0x20
#define LPSS_PRIV_SSP_REG_DIS_DMA_FIN BIT(0)
#define LPSS_PRIV_REMAP_ADDR_LO 0x40
#define LPSS_PRIV_REMAP_ADDR_HI 0x44
#define LPSS_PRIV_REMAP_ADDR 0x40
#define LPSS_PRIV_CAPS 0xfc
#define LPSS_PRIV_CAPS_NO_IDMA BIT(8)
@ -250,12 +251,7 @@ static void intel_lpss_set_remap_addr(const struct intel_lpss *lpss)
{
resource_size_t addr = lpss->info->mem->start;
writel(addr, lpss->priv + LPSS_PRIV_REMAP_ADDR_LO);
#if BITS_PER_LONG > 32
writel(addr >> 32, lpss->priv + LPSS_PRIV_REMAP_ADDR_HI);
#else
writel(0, lpss->priv + LPSS_PRIV_REMAP_ADDR_HI);
#endif
lo_hi_writeq(addr, lpss->priv + LPSS_PRIV_REMAP_ADDR);
}
static void intel_lpss_deassert_reset(const struct intel_lpss *lpss)

View file

@ -31,6 +31,10 @@
#define MFD_I2C_BAR 0
#define MFD_GPIO_BAR 1
/* ACPI _ADR value to match the child node */
#define MFD_ACPI_MATCH_GPIO 0ULL
#define MFD_ACPI_MATCH_I2C 1ULL
/* The base GPIO number under GPIOLIB framework */
#define INTEL_QUARK_MFD_GPIO_BASE 8
@ -82,27 +86,37 @@ static struct resource intel_quark_i2c_res[] = {
},
};
static struct mfd_cell_acpi_match intel_quark_acpi_match_i2c = {
.adr = MFD_ACPI_MATCH_I2C,
};
static struct resource intel_quark_gpio_res[] = {
[INTEL_QUARK_IORES_MEM] = {
.flags = IORESOURCE_MEM,
},
};
static struct mfd_cell_acpi_match intel_quark_acpi_match_gpio = {
.adr = MFD_ACPI_MATCH_GPIO,
};
static struct mfd_cell intel_quark_mfd_cells[] = {
{
.id = MFD_I2C_BAR,
.name = "i2c_designware",
.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
.resources = intel_quark_i2c_res,
.ignore_resource_conflicts = true,
},
{
.id = MFD_GPIO_BAR,
.name = "gpio-dwapb",
.acpi_match = &intel_quark_acpi_match_gpio,
.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
.resources = intel_quark_gpio_res,
.ignore_resource_conflicts = true,
},
{
.id = MFD_I2C_BAR,
.name = "i2c_designware",
.acpi_match = &intel_quark_acpi_match_i2c,
.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
.resources = intel_quark_i2c_res,
.ignore_resource_conflicts = true,
},
};
static const struct pci_device_id intel_quark_mfd_ids[] = {
@ -248,12 +262,11 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
dev_set_drvdata(&pdev->dev, quark_mfd);
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
if (ret)
return ret;
ret = intel_quark_gpio_setup(pdev,
&intel_quark_mfd_cells[MFD_GPIO_BAR]);
ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
if (ret)
return ret;

View file

@ -0,0 +1,477 @@
/*
* MFD core driver for Intel Broxton Whiskey Cove PMIC
*
* Copyright (C) 2015 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*/
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/intel_bxtwc.h>
#include <asm/intel_pmc_ipc.h>
/* PMIC device registers */
#define REG_ADDR_MASK 0xFF00
#define REG_ADDR_SHIFT 8
#define REG_OFFSET_MASK 0xFF
/* Interrupt Status Registers */
#define BXTWC_IRQLVL1 0x4E02
#define BXTWC_PWRBTNIRQ 0x4E03
#define BXTWC_THRM0IRQ 0x4E04
#define BXTWC_THRM1IRQ 0x4E05
#define BXTWC_THRM2IRQ 0x4E06
#define BXTWC_BCUIRQ 0x4E07
#define BXTWC_ADCIRQ 0x4E08
#define BXTWC_CHGR0IRQ 0x4E09
#define BXTWC_CHGR1IRQ 0x4E0A
#define BXTWC_GPIOIRQ0 0x4E0B
#define BXTWC_GPIOIRQ1 0x4E0C
#define BXTWC_CRITIRQ 0x4E0D
/* Interrupt MASK Registers */
#define BXTWC_MIRQLVL1 0x4E0E
#define BXTWC_MPWRTNIRQ 0x4E0F
#define BXTWC_MTHRM0IRQ 0x4E12
#define BXTWC_MTHRM1IRQ 0x4E13
#define BXTWC_MTHRM2IRQ 0x4E14
#define BXTWC_MBCUIRQ 0x4E15
#define BXTWC_MADCIRQ 0x4E16
#define BXTWC_MCHGR0IRQ 0x4E17
#define BXTWC_MCHGR1IRQ 0x4E18
#define BXTWC_MGPIO0IRQ 0x4E19
#define BXTWC_MGPIO1IRQ 0x4E1A
#define BXTWC_MCRITIRQ 0x4E1B
/* Whiskey Cove PMIC share same ACPI ID between different platforms */
#define BROXTON_PMIC_WC_HRV 4
/* Manage in two IRQ chips since mask registers are not consecutive */
enum bxtwc_irqs {
/* Level 1 */
BXTWC_PWRBTN_LVL1_IRQ = 0,
BXTWC_TMU_LVL1_IRQ,
BXTWC_THRM_LVL1_IRQ,
BXTWC_BCU_LVL1_IRQ,
BXTWC_ADC_LVL1_IRQ,
BXTWC_CHGR_LVL1_IRQ,
BXTWC_GPIO_LVL1_IRQ,
BXTWC_CRIT_LVL1_IRQ,
/* Level 2 */
BXTWC_PWRBTN_IRQ,
};
enum bxtwc_irqs_level2 {
/* Level 2 */
BXTWC_THRM0_IRQ = 0,
BXTWC_THRM1_IRQ,
BXTWC_THRM2_IRQ,
BXTWC_BCU_IRQ,
BXTWC_ADC_IRQ,
BXTWC_CHGR0_IRQ,
BXTWC_CHGR1_IRQ,
BXTWC_GPIO0_IRQ,
BXTWC_GPIO1_IRQ,
BXTWC_CRIT_IRQ,
};
static const struct regmap_irq bxtwc_regmap_irqs[] = {
REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03),
};
static const struct regmap_irq bxtwc_regmap_irqs_level2[] = {
REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff),
REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf),
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
};
static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
.name = "bxtwc_irq_chip",
.status_base = BXTWC_IRQLVL1,
.mask_base = BXTWC_MIRQLVL1,
.irqs = bxtwc_regmap_irqs,
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
.num_regs = 2,
};
static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = {
.name = "bxtwc_irq_chip_level2",
.status_base = BXTWC_THRM0IRQ,
.mask_base = BXTWC_MTHRM0IRQ,
.irqs = bxtwc_regmap_irqs_level2,
.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2),
.num_regs = 10,
};
static struct resource gpio_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"),
DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"),
};
static struct resource adc_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
};
static struct resource charger_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
};
static struct resource thermal_resources[] = {
DEFINE_RES_IRQ(BXTWC_THRM0_IRQ),
DEFINE_RES_IRQ(BXTWC_THRM1_IRQ),
DEFINE_RES_IRQ(BXTWC_THRM2_IRQ),
};
static struct resource bcu_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
};
static struct mfd_cell bxt_wc_dev[] = {
{
.name = "bxt_wcove_gpadc",
.num_resources = ARRAY_SIZE(adc_resources),
.resources = adc_resources,
},
{
.name = "bxt_wcove_thermal",
.num_resources = ARRAY_SIZE(thermal_resources),
.resources = thermal_resources,
},
{
.name = "bxt_wcove_ext_charger",
.num_resources = ARRAY_SIZE(charger_resources),
.resources = charger_resources,
},
{
.name = "bxt_wcove_bcu",
.num_resources = ARRAY_SIZE(bcu_resources),
.resources = bcu_resources,
},
{
.name = "bxt_wcove_gpio",
.num_resources = ARRAY_SIZE(gpio_resources),
.resources = gpio_resources,
},
{
.name = "bxt_wcove_region",
},
};
static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
unsigned int *val)
{
int ret;
int i2c_addr;
u8 ipc_in[2];
u8 ipc_out[4];
struct intel_soc_pmic *pmic = context;
if (reg & REG_ADDR_MASK)
i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
else {
i2c_addr = BXTWC_DEVICE1_ADDR;
if (!i2c_addr) {
dev_err(pmic->dev, "I2C address not set\n");
return -EINVAL;
}
}
reg &= REG_OFFSET_MASK;
ipc_in[0] = reg;
ipc_in[1] = i2c_addr;
ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
PMC_IPC_PMIC_ACCESS_READ,
ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
if (ret) {
dev_err(pmic->dev, "Failed to read from PMIC\n");
return ret;
}
*val = ipc_out[0];
return 0;
}
static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
unsigned int val)
{
int ret;
int i2c_addr;
u8 ipc_in[3];
struct intel_soc_pmic *pmic = context;
if (reg & REG_ADDR_MASK)
i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
else {
i2c_addr = BXTWC_DEVICE1_ADDR;
if (!i2c_addr) {
dev_err(pmic->dev, "I2C address not set\n");
return -EINVAL;
}
}
reg &= REG_OFFSET_MASK;
ipc_in[0] = reg;
ipc_in[1] = i2c_addr;
ipc_in[2] = val;
ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
PMC_IPC_PMIC_ACCESS_WRITE,
ipc_in, sizeof(ipc_in), NULL, 0);
if (ret) {
dev_err(pmic->dev, "Failed to write to PMIC\n");
return ret;
}
return 0;
}
/* sysfs interfaces to r/w PMIC registers, required by initial script */
static unsigned long bxtwc_reg_addr;
static ssize_t bxtwc_reg_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
}
static ssize_t bxtwc_reg_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
dev_err(dev, "Invalid register address\n");
return -EINVAL;
}
return (ssize_t)count;
}
static ssize_t bxtwc_val_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
unsigned int val;
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
if (ret < 0) {
dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
return -EIO;
}
return sprintf(buf, "0x%02x\n", val);
}
static ssize_t bxtwc_val_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int ret;
unsigned int val;
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
ret = kstrtouint(buf, 0, &val);
if (ret)
return ret;
ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
if (ret) {
dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
val, bxtwc_reg_addr);
return -EIO;
}
return count;
}
static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store);
static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store);
static struct attribute *bxtwc_attrs[] = {
&dev_attr_addr.attr,
&dev_attr_val.attr,
NULL
};
static const struct attribute_group bxtwc_group = {
.attrs = bxtwc_attrs,
};
static const struct regmap_config bxtwc_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.reg_write = regmap_ipc_byte_reg_write,
.reg_read = regmap_ipc_byte_reg_read,
};
static int bxtwc_probe(struct platform_device *pdev)
{
int ret;
acpi_handle handle;
acpi_status status;
unsigned long long hrv;
struct intel_soc_pmic *pmic;
handle = ACPI_HANDLE(&pdev->dev);
status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
if (ACPI_FAILURE(status)) {
dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
return -ENODEV;
}
if (hrv != BROXTON_PMIC_WC_HRV) {
dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
hrv);
return -ENODEV;
}
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
dev_err(&pdev->dev, "Invalid IRQ\n");
return ret;
}
pmic->irq = ret;
dev_set_drvdata(&pdev->dev, pmic);
pmic->dev = &pdev->dev;
pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
&bxtwc_regmap_config);
if (IS_ERR(pmic->regmap)) {
ret = PTR_ERR(pmic->regmap);
dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
return ret;
}
ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
IRQF_ONESHOT | IRQF_SHARED,
0, &bxtwc_regmap_irq_chip,
&pmic->irq_chip_data);
if (ret) {
dev_err(&pdev->dev, "Failed to add IRQ chip\n");
return ret;
}
ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
IRQF_ONESHOT | IRQF_SHARED,
0, &bxtwc_regmap_irq_chip_level2,
&pmic->irq_chip_data_level2);
if (ret) {
dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n");
goto err_irq_chip_level2;
}
ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
ARRAY_SIZE(bxt_wc_dev), NULL, 0,
NULL);
if (ret) {
dev_err(&pdev->dev, "Failed to add devices\n");
goto err_mfd;
}
ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
if (ret) {
dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
goto err_sysfs;
}
return 0;
err_sysfs:
mfd_remove_devices(&pdev->dev);
err_mfd:
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
err_irq_chip_level2:
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
return ret;
}
static int bxtwc_remove(struct platform_device *pdev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
mfd_remove_devices(&pdev->dev);
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2);
return 0;
}
static void bxtwc_shutdown(struct platform_device *pdev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
disable_irq(pmic->irq);
}
#ifdef CONFIG_PM_SLEEP
static int bxtwc_suspend(struct device *dev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
disable_irq(pmic->irq);
return 0;
}
static int bxtwc_resume(struct device *dev)
{
struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
enable_irq(pmic->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
static const struct acpi_device_id bxtwc_acpi_ids[] = {
{ "INT34D3", },
{ }
};
MODULE_DEVICE_TABLE(acpi, pmic_acpi_ids);
static struct platform_driver bxtwc_driver = {
.probe = bxtwc_probe,
.remove = bxtwc_remove,
.shutdown = bxtwc_shutdown,
.driver = {
.name = "BXTWC PMIC",
.pm = &bxtwc_pm_ops,
.acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
},
};
module_platform_driver(bxtwc_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Qipeng Zha<[email protected]>");

View file

@ -448,7 +448,6 @@ static int kempld_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct kempld_device_data *pld;
struct resource *ioport;
int ret;
pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL);
if (!pld)
@ -471,11 +470,7 @@ static int kempld_probe(struct platform_device *pdev)
mutex_init(&pld->lock);
platform_set_drvdata(pdev, pld);
ret = kempld_detect_device(pld);
if (ret)
return ret;
return 0;
return kempld_detect_device(pld);
}
static int kempld_remove(struct platform_device *pdev)
@ -756,7 +751,6 @@ MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
static int __init kempld_init(void)
{
const struct dmi_system_id *id;
int ret;
if (force_device_id[0]) {
for (id = kempld_dmi_table;
@ -771,11 +765,7 @@ static int __init kempld_init(void)
return -ENODEV;
}
ret = platform_driver_register(&kempld_driver);
if (ret)
return ret;
return 0;
return platform_driver_register(&kempld_driver);
}
static void __exit kempld_exit(void)

View file

@ -472,11 +472,7 @@ static int lm3533_device_setup(struct lm3533 *lm3533,
if (ret)
return ret;
ret = lm3533_set_boost_ovp(lm3533, pdata->boost_ovp);
if (ret)
return ret;
return 0;
return lm3533_set_boost_ovp(lm3533, pdata->boost_ovp);
}
static int lm3533_device_init(struct lm3533 *lm3533)
@ -596,7 +592,6 @@ static int lm3533_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct lm3533 *lm3533;
int ret;
dev_dbg(&i2c->dev, "%s\n", __func__);
@ -613,11 +608,7 @@ static int lm3533_i2c_probe(struct i2c_client *i2c,
lm3533->dev = &i2c->dev;
lm3533->irq = i2c->irq;
ret = lm3533_device_init(lm3533);
if (ret)
return ret;
return 0;
return lm3533_device_init(lm3533);
}
static int lm3533_i2c_remove(struct i2c_client *i2c)

View file

@ -132,24 +132,18 @@ static struct resource gpio_ich_res[] = {
},
};
enum lpc_cells {
LPC_WDT = 0,
LPC_GPIO,
static struct mfd_cell lpc_ich_wdt_cell = {
.name = "iTCO_wdt",
.num_resources = ARRAY_SIZE(wdt_ich_res),
.resources = wdt_ich_res,
.ignore_resource_conflicts = true,
};
static struct mfd_cell lpc_ich_cells[] = {
[LPC_WDT] = {
.name = "iTCO_wdt",
.num_resources = ARRAY_SIZE(wdt_ich_res),
.resources = wdt_ich_res,
.ignore_resource_conflicts = true,
},
[LPC_GPIO] = {
.name = "gpio_ich",
.num_resources = ARRAY_SIZE(gpio_ich_res),
.resources = gpio_ich_res,
.ignore_resource_conflicts = true,
},
static struct mfd_cell lpc_ich_gpio_cell = {
.name = "gpio_ich",
.num_resources = ARRAY_SIZE(gpio_ich_res),
.resources = gpio_ich_res,
.ignore_resource_conflicts = true,
};
/* chipset related info */
@ -841,7 +835,7 @@ static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev)
struct itco_wdt_platform_data *pdata;
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
struct lpc_ich_info *info;
struct mfd_cell *cell = &lpc_ich_cells[LPC_WDT];
struct mfd_cell *cell = &lpc_ich_wdt_cell;
pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@ -860,7 +854,7 @@ static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev)
static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev)
{
struct lpc_ich_priv *priv = pci_get_drvdata(dev);
struct mfd_cell *cell = &lpc_ich_cells[LPC_GPIO];
struct mfd_cell *cell = &lpc_ich_gpio_cell;
cell->platform_data = &lpc_chipset_info[priv->chipset];
cell->pdata_size = sizeof(struct lpc_ich_info);
@ -904,7 +898,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
base_addr = base_addr_cfg & 0x0000ff80;
if (!base_addr) {
dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
lpc_ich_cells[LPC_GPIO].num_resources--;
lpc_ich_gpio_cell.num_resources--;
goto gpe0_done;
}
@ -918,7 +912,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
* the platform_device subsystem doesn't see this resource
* or it will register an invalid region.
*/
lpc_ich_cells[LPC_GPIO].num_resources--;
lpc_ich_gpio_cell.num_resources--;
acpi_conflict = true;
} else {
lpc_ich_enable_acpi_space(dev);
@ -958,12 +952,12 @@ gpe0_done:
lpc_ich_finalize_gpio_cell(dev);
ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
&lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL);
&lpc_ich_gpio_cell, 1, NULL, 0, NULL);
gpio_done:
if (acpi_conflict)
pr_warn("Resource conflict(s) found affecting %s\n",
lpc_ich_cells[LPC_GPIO].name);
lpc_ich_gpio_cell.name);
return ret;
}
@ -1007,7 +1001,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
*/
if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
/* Don't register iomem for TCO ver 1 */
lpc_ich_cells[LPC_WDT].num_resources--;
lpc_ich_wdt_cell.num_resources--;
} else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) {
pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
base_addr = base_addr_cfg & 0xffffc000;
@ -1035,7 +1029,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
goto wdt_done;
ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
&lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL);
&lpc_ich_wdt_cell, 1, NULL, 0, NULL);
wdt_done:
return ret;

View file

@ -55,6 +55,7 @@ static const struct of_device_id max8997_pmic_dt_match[] = {
{ .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
{},
};
MODULE_DEVICE_TABLE(of, max8997_pmic_dt_match);
#endif
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)

View file

@ -82,29 +82,49 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
static void mfd_acpi_add_device(const struct mfd_cell *cell,
struct platform_device *pdev)
{
struct acpi_device *parent_adev;
const struct mfd_cell_acpi_match *match = cell->acpi_match;
struct acpi_device *parent, *child;
struct acpi_device *adev;
parent_adev = ACPI_COMPANION(pdev->dev.parent);
if (!parent_adev)
parent = ACPI_COMPANION(pdev->dev.parent);
if (!parent)
return;
/*
* MFD child device gets its ACPI handle either from the ACPI
* device directly under the parent that matches the acpi_pnpid or
* it will use the parent handle if is no acpi_pnpid is given.
* MFD child device gets its ACPI handle either from the ACPI device
* directly under the parent that matches the either _HID or _CID, or
* _ADR or it will use the parent handle if is no ID is given.
*
* Note that use of _ADR is a grey area in the ACPI specification,
* though Intel Galileo Gen2 is using it to distinguish the children
* devices.
*/
adev = parent_adev;
if (cell->acpi_pnpid) {
struct acpi_device_id ids[2] = {};
struct acpi_device *child_adev;
adev = parent;
if (match) {
if (match->pnpid) {
struct acpi_device_id ids[2] = {};
strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
list_for_each_entry(child_adev, &parent_adev->children, node)
if (acpi_match_device_ids(child_adev, ids)) {
adev = child_adev;
break;
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
list_for_each_entry(child, &parent->children, node) {
if (acpi_match_device_ids(child, ids)) {
adev = child;
break;
}
}
} else {
unsigned long long adr;
acpi_status status;
list_for_each_entry(child, &parent->children, node) {
status = acpi_evaluate_integer(child->handle,
"_ADR", NULL,
&adr);
if (ACPI_SUCCESS(status) && match->adr == adr) {
adev = child;
break;
}
}
}
}
ACPI_COMPANION_SET(&pdev->dev, adev);

View file

@ -55,7 +55,7 @@ EXPORT_SYMBOL_GPL(pcf50633_free_irq);
static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
{
u8 reg, bit;
int ret = 0, idx;
int idx;
idx = irq >> 3;
reg = PCF50633_REG_INT1M + idx;
@ -72,7 +72,7 @@ static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
mutex_unlock(&pcf->lock);
return ret;
return 0;
}
int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)

View file

@ -550,7 +550,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev,
irq_ack,
qcom_rpm_ack_interrupt,
IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
IRQF_TRIGGER_RISING,
"qcom_rpm_ack",
rpm);
if (ret) {

View file

@ -47,6 +47,9 @@ static const struct mfd_cell rt5033_devs[] = {
}, {
.name = "rt5033-battery",
.of_compatible = "richtek,rt5033-battery",
}, {
.name = "rt5033-led",
.of_compatible = "richtek,rt5033-led",
},
};
@ -137,7 +140,6 @@ static struct i2c_driver rt5033_driver = {
};
module_i2c_driver(rt5033_driver);
MODULE_ALIAS("i2c:rt5033");
MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
MODULE_AUTHOR("Beomho Seo <[email protected]>");
MODULE_LICENSE("GPL");

View file

@ -138,11 +138,7 @@ static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, pwr_mask, pwr_on);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
LDO3318_PWR_MASK, 0x00);
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
return 0;
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)

View file

@ -26,6 +26,14 @@
#include "rtsx_pcr.h"
static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr)
{
u8 val;
rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
return val & 0x0F;
}
static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
{
u8 driving_3v3[4][3] = {
@ -88,7 +96,7 @@ static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
if (pm_state == HOST_ENTER_S3)
rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10);
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
}
@ -121,7 +129,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00);
return rtsx_pci_send_cmd(pcr, 100);
}
@ -179,11 +187,7 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
SD_POWER_MASK, SD_POWER_ON);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
LDO3318_PWR_MASK, 0x06);
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
return 0;
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
@ -298,8 +302,73 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
pcr->ic_version = rts5227_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
pcr->reg_pm_ctrl3 = PM_CTRL3;
}
static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN,
0x00);
if (err < 0)
return err;
if (is_version(pcr, 0x522A, IC_VER_A)) {
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
PHY_RCR2_INIT_27S);
if (err)
return err;
rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S);
rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S);
rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S);
rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S);
}
return 0;
}
static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
{
rts5227_extra_init_hw(pcr);
rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG,
FUNC_FORCE_UPME_XMT_DBG);
rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04);
rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11);
return 0;
}
/* rts522a operations mainly derived from rts5227, except phy/hw init setting.
*/
static const struct pcr_ops rts522a_pcr_ops = {
.fetch_vendor_settings = rts5227_fetch_vendor_settings,
.extra_init_hw = rts522a_extra_init_hw,
.optimize_phy = rts522a_optimize_phy,
.turn_on_led = rts5227_turn_on_led,
.turn_off_led = rts5227_turn_off_led,
.enable_auto_blink = rts5227_enable_auto_blink,
.disable_auto_blink = rts5227_disable_auto_blink,
.card_power_on = rts5227_card_power_on,
.card_power_off = rts5227_card_power_off,
.switch_output_voltage = rts5227_switch_output_voltage,
.cd_deglitch = NULL,
.conv_clk_and_div_n = NULL,
.force_power_down = rts5227_force_power_down,
};
void rts522a_init_params(struct rtsx_pcr *pcr)
{
rts5227_init_params(pcr);
pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
}

View file

@ -129,11 +129,7 @@ static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card)
SD_POWER_MASK, SD_POWER_ON);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
LDO3318_PWR_MASK, 0x06);
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
return 0;
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)

View file

@ -234,11 +234,7 @@ static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
SD_POWER_MASK, SD_VCC_POWER_ON);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
LDO3318_PWR_MASK, 0x06);
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
return 0;
return rtsx_pci_send_cmd(pcr, 100);
}
static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)

View file

@ -55,6 +55,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x522A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
@ -571,11 +572,7 @@ static int rtsx_pci_set_pull_ctl(struct rtsx_pcr *pcr, const u32 *tbl)
tbl++;
}
err = rtsx_pci_send_cmd(pcr, 100);
if (err < 0)
return err;
return 0;
return rtsx_pci_send_cmd(pcr, 100);
}
int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card)
@ -1102,6 +1099,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
rts5227_init_params(pcr);
break;
case 0x522A:
rts522a_init_params(pcr);
break;
case 0x5249:
rts5249_init_params(pcr);
break;

View file

@ -27,6 +27,8 @@
#define MIN_DIV_N_PCR 80
#define MAX_DIV_N_PCR 208
#define RTS522A_PM_CTRL3 0xFF7E
#define RTS524A_PME_FORCE_CTL 0xFF78
#define RTS524A_PM_CTRL3 0xFF7E
@ -38,6 +40,7 @@ void rts5229_init_params(struct rtsx_pcr *pcr);
void rtl8411_init_params(struct rtsx_pcr *pcr);
void rtl8402_init_params(struct rtsx_pcr *pcr);
void rts5227_init_params(struct rtsx_pcr *pcr);
void rts522a_init_params(struct rtsx_pcr *pcr);
void rts5249_init_params(struct rtsx_pcr *pcr);
void rts524a_init_params(struct rtsx_pcr *pcr);
void rts525a_init_params(struct rtsx_pcr *pcr);

View file

@ -103,12 +103,9 @@ static const struct mfd_cell s2mpa01_devs[] = {
};
static const struct mfd_cell s2mpu02_devs[] = {
{ .name = "s2mpu02-pmic", },
{ .name = "s2mpu02-rtc", },
{
.name = "s2mpu02-clk",
.of_compatible = "samsung,s2mpu02-clk",
}
.name = "s2mpu02-pmic",
},
};
#ifdef CONFIG_OF
@ -253,6 +250,38 @@ static const struct regmap_config s5m8767_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
{
unsigned int val;
/* For each device type, the REG_ID is always the first register */
if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
}
static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
{
int err;
if (sec_pmic->device_type != S2MPS13X)
return;
if (sec_pmic->pdata->disable_wrstbi) {
/*
* If WRSTBI pin is pulled down this feature must be disabled
* because each Suspend to RAM will trigger buck voltage reset
* to default values.
*/
err = regmap_update_bits(sec_pmic->regmap_pmic,
S2MPS13_REG_WRSTBI,
S2MPS13_REG_WRSTBI_MASK, 0x0);
if (err)
dev_warn(sec_pmic->dev,
"Cannot initialize WRSTBI config: %d\n",
err);
}
}
#ifdef CONFIG_OF
/*
* Only the common platform data elements for s5m8767 are parsed here from the
@ -278,6 +307,10 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
* not parsed here.
*/
pd->manual_poweroff = of_property_read_bool(dev->of_node,
"samsung,s2mps11-acokb-ground");
pd->disable_wrstbi = of_property_read_bool(dev->of_node,
"samsung,s2mps11-wrstbi-ground");
return pd;
}
#else
@ -423,6 +456,8 @@ static int sec_pmic_probe(struct i2c_client *i2c,
goto err_mfd;
device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
sec_pmic_configure(sec_pmic);
sec_pmic_dump_rev(sec_pmic);
return ret;
@ -440,6 +475,33 @@ static int sec_pmic_remove(struct i2c_client *i2c)
return 0;
}
static void sec_pmic_shutdown(struct i2c_client *i2c)
{
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
unsigned int reg, mask;
if (!sec_pmic->pdata->manual_poweroff)
return;
switch (sec_pmic->device_type) {
case S2MPS11X:
reg = S2MPS11_REG_CTRL1;
mask = S2MPS11_CTRL1_PWRHOLD_MASK;
break;
default:
/*
* Currently only one board with S2MPS11 needs this, so just
* ignore the rest.
*/
dev_warn(sec_pmic->dev,
"Unsupported device %lu for manual power off\n",
sec_pmic->device_type);
return;
}
regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
}
#ifdef CONFIG_PM_SLEEP
static int sec_pmic_suspend(struct device *dev)
{
@ -491,6 +553,7 @@ static struct i2c_driver sec_pmic_driver = {
},
.probe = sec_pmic_probe,
.remove = sec_pmic_remove,
.shutdown = sec_pmic_shutdown,
.id_table = sec_pmic_id,
};

View file

@ -1719,6 +1719,7 @@ static const struct of_device_id of_sm501_match_tbl[] = {
{ .compatible = "smi,sm501", },
{ /* end */ }
};
MODULE_DEVICE_TABLE(of, of_sm501_match_tbl);
static struct platform_driver sm501_plat_driver = {
.driver = {

View file

@ -795,6 +795,7 @@ static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block)
return 2;
case STMPE_BLOCK_KEYPAD:
case STMPE_BLOCK_PWM:
return 1;
case STMPE_BLOCK_GPIO:

View file

@ -64,27 +64,47 @@ static int tps6105x_startup(struct tps6105x *tps6105x)
}
/*
* MFD cells - we have one cell which is selected operation
* mode, and we always have a GPIO cell.
* MFD cells - we always have a GPIO cell and we have one cell
* which is selected operation mode.
*/
static struct mfd_cell tps6105x_cells[] = {
{
/* name will be runtime assigned */
.id = -1,
},
{
.name = "tps6105x-gpio",
.id = -1,
},
static struct mfd_cell tps6105x_gpio_cell = {
.name = "tps6105x-gpio",
};
static struct mfd_cell tps6105x_leds_cell = {
.name = "tps6105x-leds",
};
static struct mfd_cell tps6105x_flash_cell = {
.name = "tps6105x-flash",
};
static struct mfd_cell tps6105x_regulator_cell = {
.name = "tps6105x-regulator",
};
static int tps6105x_add_device(struct tps6105x *tps6105x,
struct mfd_cell *cell)
{
cell->platform_data = tps6105x;
cell->pdata_size = sizeof(*tps6105x);
return mfd_add_devices(&tps6105x->client->dev,
PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL);
}
static int tps6105x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps6105x *tps6105x;
struct tps6105x_platform_data *pdata;
int ret;
int i;
pdata = dev_get_platdata(&client->dev);
if (!pdata) {
dev_err(&client->dev, "missing platform data\n");
return -ENODEV;
}
tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL);
if (!tps6105x)
@ -96,7 +116,6 @@ static int tps6105x_probe(struct i2c_client *client,
i2c_set_clientdata(client, tps6105x);
tps6105x->client = client;
pdata = dev_get_platdata(&client->dev);
tps6105x->pdata = pdata;
ret = tps6105x_startup(tps6105x);
@ -105,38 +124,33 @@ static int tps6105x_probe(struct i2c_client *client,
return ret;
}
/* Remove warning texts when you implement new cell drivers */
ret = tps6105x_add_device(tps6105x, &tps6105x_gpio_cell);
if (ret)
return ret;
switch (pdata->mode) {
case TPS6105X_MODE_SHUTDOWN:
dev_info(&client->dev,
"present, not used for anything, only GPIO\n");
break;
case TPS6105X_MODE_TORCH:
tps6105x_cells[0].name = "tps6105x-leds";
dev_warn(&client->dev,
"torch mode is unsupported\n");
ret = tps6105x_add_device(tps6105x, &tps6105x_leds_cell);
break;
case TPS6105X_MODE_TORCH_FLASH:
tps6105x_cells[0].name = "tps6105x-flash";
dev_warn(&client->dev,
"flash mode is unsupported\n");
ret = tps6105x_add_device(tps6105x, &tps6105x_flash_cell);
break;
case TPS6105X_MODE_VOLTAGE:
tps6105x_cells[0].name ="tps6105x-regulator";
ret = tps6105x_add_device(tps6105x, &tps6105x_regulator_cell);
break;
default:
dev_warn(&client->dev, "invalid mode: %d\n", pdata->mode);
break;
}
/* Set up and register the platform devices. */
for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) {
/* One state holder for all drivers, this is simple */
tps6105x_cells[i].platform_data = tps6105x;
tps6105x_cells[i].pdata_size = sizeof(*tps6105x);
}
if (ret)
mfd_remove_devices(&client->dev);
return mfd_add_devices(&client->dev, 0, tps6105x_cells,
ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);
return ret;
}
static int tps6105x_remove(struct i2c_client *client)

View file

@ -39,6 +39,10 @@ static const struct mfd_cell tps65217s[] = {
.name = "tps65217-bl",
.of_compatible = "ti,tps65217-bl",
},
{
.name = "tps65217-charger",
.of_compatible = "ti,tps65217-charger",
},
};
/**

View file

@ -647,6 +647,8 @@ static int twl6040_probe(struct i2c_client *client,
twl6040->clk32k = devm_clk_get(&client->dev, "clk32k");
if (IS_ERR(twl6040->clk32k)) {
if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_info(&client->dev, "clk32k is not handled\n");
twl6040->clk32k = NULL;
}

View file

@ -250,7 +250,7 @@ static const struct reg_sequence wm5110_revd_patch[] = {
};
/* Add extra headphone write sequence locations */
static const struct reg_default wm5110_reve_patch[] = {
static const struct reg_sequence wm5110_reve_patch[] = {
{ 0x80, 0x3 },
{ 0x80, 0x3 },
{ 0x4b, 0x138 },
@ -1633,6 +1633,185 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000EF8, 0x0000 }, /* R3832 - ISRC 3 CTRL 3 */
{ 0x00000F00, 0x0000 }, /* R3840 - Clock Control */
{ 0x00000F01, 0x0000 }, /* R3841 - ANC_SRC */
{ 0x00000F08, 0x001c }, /* R3848 - ANC Coefficient */
{ 0x00000F09, 0x0000 }, /* R3849 - ANC Coefficient */
{ 0x00000F0A, 0x0000 }, /* R3850 - ANC Coefficient */
{ 0x00000F0B, 0x0000 }, /* R3851 - ANC Coefficient */
{ 0x00000F0C, 0x0000 }, /* R3852 - ANC Coefficient */
{ 0x00000F0D, 0x0000 }, /* R3853 - ANC Coefficient */
{ 0x00000F0E, 0x0000 }, /* R3854 - ANC Coefficient */
{ 0x00000F0F, 0x0000 }, /* R3855 - ANC Coefficient */
{ 0x00000F10, 0x0000 }, /* R3856 - ANC Coefficient */
{ 0x00000F11, 0x0000 }, /* R3857 - ANC Coefficient */
{ 0x00000F12, 0x0000 }, /* R3858 - ANC Coefficient */
{ 0x00000F15, 0x0000 }, /* R3861 - FCL Filter Control */
{ 0x00000F17, 0x0004 }, /* R3863 - FCL ADC Reformatter Control */
{ 0x00000F18, 0x0004 }, /* R3864 - ANC Coefficient */
{ 0x00000F19, 0x0002 }, /* R3865 - ANC Coefficient */
{ 0x00000F1A, 0x0000 }, /* R3866 - ANC Coefficient */
{ 0x00000F1B, 0x0010 }, /* R3867 - ANC Coefficient */
{ 0x00000F1C, 0x0000 }, /* R3868 - ANC Coefficient */
{ 0x00000F1D, 0x0000 }, /* R3869 - ANC Coefficient */
{ 0x00000F1E, 0x0000 }, /* R3870 - ANC Coefficient */
{ 0x00000F1F, 0x0000 }, /* R3871 - ANC Coefficient */
{ 0x00000F20, 0x0000 }, /* R3872 - ANC Coefficient */
{ 0x00000F21, 0x0000 }, /* R3873 - ANC Coefficient */
{ 0x00000F22, 0x0000 }, /* R3874 - ANC Coefficient */
{ 0x00000F23, 0x0000 }, /* R3875 - ANC Coefficient */
{ 0x00000F24, 0x0000 }, /* R3876 - ANC Coefficient */
{ 0x00000F25, 0x0000 }, /* R3877 - ANC Coefficient */
{ 0x00000F26, 0x0000 }, /* R3878 - ANC Coefficient */
{ 0x00000F27, 0x0000 }, /* R3879 - ANC Coefficient */
{ 0x00000F28, 0x0000 }, /* R3880 - ANC Coefficient */
{ 0x00000F29, 0x0000 }, /* R3881 - ANC Coefficient */
{ 0x00000F2A, 0x0000 }, /* R3882 - ANC Coefficient */
{ 0x00000F2B, 0x0000 }, /* R3883 - ANC Coefficient */
{ 0x00000F2C, 0x0000 }, /* R3884 - ANC Coefficient */
{ 0x00000F2D, 0x0000 }, /* R3885 - ANC Coefficient */
{ 0x00000F2E, 0x0000 }, /* R3886 - ANC Coefficient */
{ 0x00000F2F, 0x0000 }, /* R3887 - ANC Coefficient */
{ 0x00000F30, 0x0000 }, /* R3888 - ANC Coefficient */
{ 0x00000F31, 0x0000 }, /* R3889 - ANC Coefficient */
{ 0x00000F32, 0x0000 }, /* R3890 - ANC Coefficient */
{ 0x00000F33, 0x0000 }, /* R3891 - ANC Coefficient */
{ 0x00000F34, 0x0000 }, /* R3892 - ANC Coefficient */
{ 0x00000F35, 0x0000 }, /* R3893 - ANC Coefficient */
{ 0x00000F36, 0x0000 }, /* R3894 - ANC Coefficient */
{ 0x00000F37, 0x0000 }, /* R3895 - ANC Coefficient */
{ 0x00000F38, 0x0000 }, /* R3896 - ANC Coefficient */
{ 0x00000F39, 0x0000 }, /* R3897 - ANC Coefficient */
{ 0x00000F3A, 0x0000 }, /* R3898 - ANC Coefficient */
{ 0x00000F3B, 0x0000 }, /* R3899 - ANC Coefficient */
{ 0x00000F3C, 0x0000 }, /* R3900 - ANC Coefficient */
{ 0x00000F3D, 0x0000 }, /* R3901 - ANC Coefficient */
{ 0x00000F3E, 0x0000 }, /* R3902 - ANC Coefficient */
{ 0x00000F3F, 0x0000 }, /* R3903 - ANC Coefficient */
{ 0x00000F40, 0x0000 }, /* R3904 - ANC Coefficient */
{ 0x00000F41, 0x0000 }, /* R3905 - ANC Coefficient */
{ 0x00000F42, 0x0000 }, /* R3906 - ANC Coefficient */
{ 0x00000F43, 0x0000 }, /* R3907 - ANC Coefficient */
{ 0x00000F44, 0x0000 }, /* R3908 - ANC Coefficient */
{ 0x00000F45, 0x0000 }, /* R3909 - ANC Coefficient */
{ 0x00000F46, 0x0000 }, /* R3910 - ANC Coefficient */
{ 0x00000F47, 0x0000 }, /* R3911 - ANC Coefficient */
{ 0x00000F48, 0x0000 }, /* R3912 - ANC Coefficient */
{ 0x00000F49, 0x0000 }, /* R3913 - ANC Coefficient */
{ 0x00000F4A, 0x0000 }, /* R3914 - ANC Coefficient */
{ 0x00000F4B, 0x0000 }, /* R3915 - ANC Coefficient */
{ 0x00000F4C, 0x0000 }, /* R3916 - ANC Coefficient */
{ 0x00000F4D, 0x0000 }, /* R3917 - ANC Coefficient */
{ 0x00000F4E, 0x0000 }, /* R3918 - ANC Coefficient */
{ 0x00000F4F, 0x0000 }, /* R3919 - ANC Coefficient */
{ 0x00000F50, 0x0000 }, /* R3920 - ANC Coefficient */
{ 0x00000F51, 0x0000 }, /* R3921 - ANC Coefficient */
{ 0x00000F52, 0x0000 }, /* R3922 - ANC Coefficient */
{ 0x00000F53, 0x0000 }, /* R3923 - ANC Coefficient */
{ 0x00000F54, 0x0000 }, /* R3924 - ANC Coefficient */
{ 0x00000F55, 0x0000 }, /* R3925 - ANC Coefficient */
{ 0x00000F56, 0x0000 }, /* R3926 - ANC Coefficient */
{ 0x00000F57, 0x0000 }, /* R3927 - ANC Coefficient */
{ 0x00000F58, 0x0000 }, /* R3928 - ANC Coefficient */
{ 0x00000F59, 0x0000 }, /* R3929 - ANC Coefficient */
{ 0x00000F5A, 0x0000 }, /* R3930 - ANC Coefficient */
{ 0x00000F5B, 0x0000 }, /* R3931 - ANC Coefficient */
{ 0x00000F5C, 0x0000 }, /* R3932 - ANC Coefficient */
{ 0x00000F5D, 0x0000 }, /* R3933 - ANC Coefficient */
{ 0x00000F5E, 0x0000 }, /* R3934 - ANC Coefficient */
{ 0x00000F5F, 0x0000 }, /* R3935 - ANC Coefficient */
{ 0x00000F60, 0x0000 }, /* R3936 - ANC Coefficient */
{ 0x00000F61, 0x0000 }, /* R3937 - ANC Coefficient */
{ 0x00000F62, 0x0000 }, /* R3938 - ANC Coefficient */
{ 0x00000F63, 0x0000 }, /* R3939 - ANC Coefficient */
{ 0x00000F64, 0x0000 }, /* R3940 - ANC Coefficient */
{ 0x00000F65, 0x0000 }, /* R3941 - ANC Coefficient */
{ 0x00000F66, 0x0000 }, /* R3942 - ANC Coefficient */
{ 0x00000F67, 0x0000 }, /* R3943 - ANC Coefficient */
{ 0x00000F68, 0x0000 }, /* R3944 - ANC Coefficient */
{ 0x00000F69, 0x0000 }, /* R3945 - ANC Coefficient */
{ 0x00000F70, 0x0000 }, /* R3952 - FCR Filter Control */
{ 0x00000F72, 0x0004 }, /* R3954 - FCR ADC Reformatter Control */
{ 0x00000F73, 0x0004 }, /* R3955 - ANC Coefficient */
{ 0x00000F74, 0x0002 }, /* R3956 - ANC Coefficient */
{ 0x00000F75, 0x0000 }, /* R3957 - ANC Coefficient */
{ 0x00000F76, 0x0010 }, /* R3958 - ANC Coefficient */
{ 0x00000F77, 0x0000 }, /* R3959 - ANC Coefficient */
{ 0x00000F78, 0x0000 }, /* R3960 - ANC Coefficient */
{ 0x00000F79, 0x0000 }, /* R3961 - ANC Coefficient */
{ 0x00000F7A, 0x0000 }, /* R3962 - ANC Coefficient */
{ 0x00000F7B, 0x0000 }, /* R3963 - ANC Coefficient */
{ 0x00000F7C, 0x0000 }, /* R3964 - ANC Coefficient */
{ 0x00000F7D, 0x0000 }, /* R3965 - ANC Coefficient */
{ 0x00000F7E, 0x0000 }, /* R3966 - ANC Coefficient */
{ 0x00000F7F, 0x0000 }, /* R3967 - ANC Coefficient */
{ 0x00000F80, 0x0000 }, /* R3968 - ANC Coefficient */
{ 0x00000F81, 0x0000 }, /* R3969 - ANC Coefficient */
{ 0x00000F82, 0x0000 }, /* R3970 - ANC Coefficient */
{ 0x00000F83, 0x0000 }, /* R3971 - ANC Coefficient */
{ 0x00000F84, 0x0000 }, /* R3972 - ANC Coefficient */
{ 0x00000F85, 0x0000 }, /* R3973 - ANC Coefficient */
{ 0x00000F86, 0x0000 }, /* R3974 - ANC Coefficient */
{ 0x00000F87, 0x0000 }, /* R3975 - ANC Coefficient */
{ 0x00000F88, 0x0000 }, /* R3976 - ANC Coefficient */
{ 0x00000F89, 0x0000 }, /* R3977 - ANC Coefficient */
{ 0x00000F8A, 0x0000 }, /* R3978 - ANC Coefficient */
{ 0x00000F8B, 0x0000 }, /* R3979 - ANC Coefficient */
{ 0x00000F8C, 0x0000 }, /* R3980 - ANC Coefficient */
{ 0x00000F8D, 0x0000 }, /* R3981 - ANC Coefficient */
{ 0x00000F8E, 0x0000 }, /* R3982 - ANC Coefficient */
{ 0x00000F8F, 0x0000 }, /* R3983 - ANC Coefficient */
{ 0x00000F90, 0x0000 }, /* R3984 - ANC Coefficient */
{ 0x00000F91, 0x0000 }, /* R3985 - ANC Coefficient */
{ 0x00000F92, 0x0000 }, /* R3986 - ANC Coefficient */
{ 0x00000F93, 0x0000 }, /* R3987 - ANC Coefficient */
{ 0x00000F94, 0x0000 }, /* R3988 - ANC Coefficient */
{ 0x00000F95, 0x0000 }, /* R3989 - ANC Coefficient */
{ 0x00000F96, 0x0000 }, /* R3990 - ANC Coefficient */
{ 0x00000F97, 0x0000 }, /* R3991 - ANC Coefficient */
{ 0x00000F98, 0x0000 }, /* R3992 - ANC Coefficient */
{ 0x00000F99, 0x0000 }, /* R3993 - ANC Coefficient */
{ 0x00000F9A, 0x0000 }, /* R3994 - ANC Coefficient */
{ 0x00000F9B, 0x0000 }, /* R3995 - ANC Coefficient */
{ 0x00000F9C, 0x0000 }, /* R3996 - ANC Coefficient */
{ 0x00000F9D, 0x0000 }, /* R3997 - ANC Coefficient */
{ 0x00000F9E, 0x0000 }, /* R3998 - ANC Coefficient */
{ 0x00000F9F, 0x0000 }, /* R3999 - ANC Coefficient */
{ 0x00000FA0, 0x0000 }, /* R4000 - ANC Coefficient */
{ 0x00000FA1, 0x0000 }, /* R4001 - ANC Coefficient */
{ 0x00000FA2, 0x0000 }, /* R4002 - ANC Coefficient */
{ 0x00000FA3, 0x0000 }, /* R4003 - ANC Coefficient */
{ 0x00000FA4, 0x0000 }, /* R4004 - ANC Coefficient */
{ 0x00000FA5, 0x0000 }, /* R4005 - ANC Coefficient */
{ 0x00000FA6, 0x0000 }, /* R4006 - ANC Coefficient */
{ 0x00000FA7, 0x0000 }, /* R4007 - ANC Coefficient */
{ 0x00000FA8, 0x0000 }, /* R4008 - ANC Coefficient */
{ 0x00000FA9, 0x0000 }, /* R4009 - ANC Coefficient */
{ 0x00000FAA, 0x0000 }, /* R4010 - ANC Coefficient */
{ 0x00000FAB, 0x0000 }, /* R4011 - ANC Coefficient */
{ 0x00000FAC, 0x0000 }, /* R4012 - ANC Coefficient */
{ 0x00000FAD, 0x0000 }, /* R4013 - ANC Coefficient */
{ 0x00000FAE, 0x0000 }, /* R4014 - ANC Coefficient */
{ 0x00000FAF, 0x0000 }, /* R4015 - ANC Coefficient */
{ 0x00000FB0, 0x0000 }, /* R4016 - ANC Coefficient */
{ 0x00000FB1, 0x0000 }, /* R4017 - ANC Coefficient */
{ 0x00000FB2, 0x0000 }, /* R4018 - ANC Coefficient */
{ 0x00000FB3, 0x0000 }, /* R4019 - ANC Coefficient */
{ 0x00000FB4, 0x0000 }, /* R4020 - ANC Coefficient */
{ 0x00000FB5, 0x0000 }, /* R4021 - ANC Coefficient */
{ 0x00000FB6, 0x0000 }, /* R4022 - ANC Coefficient */
{ 0x00000FB7, 0x0000 }, /* R4023 - ANC Coefficient */
{ 0x00000FB8, 0x0000 }, /* R4024 - ANC Coefficient */
{ 0x00000FB9, 0x0000 }, /* R4025 - ANC Coefficient */
{ 0x00000FBA, 0x0000 }, /* R4026 - ANC Coefficient */
{ 0x00000FBB, 0x0000 }, /* R4027 - ANC Coefficient */
{ 0x00000FBC, 0x0000 }, /* R4028 - ANC Coefficient */
{ 0x00000FBD, 0x0000 }, /* R4029 - ANC Coefficient */
{ 0x00000FBE, 0x0000 }, /* R4030 - ANC Coefficient */
{ 0x00000FBF, 0x0000 }, /* R4031 - ANC Coefficient */
{ 0x00000FC0, 0x0000 }, /* R4032 - ANC Coefficient */
{ 0x00000FC1, 0x0000 }, /* R4033 - ANC Coefficient */
{ 0x00000FC2, 0x0000 }, /* R4034 - ANC Coefficient */
{ 0x00000FC3, 0x0000 }, /* R4035 - ANC Coefficient */
{ 0x00000FC4, 0x0000 }, /* R4036 - ANC Coefficient */
{ 0x00001100, 0x0010 }, /* R4352 - DSP1 Control 1 */
{ 0x00001200, 0x0010 }, /* R4608 - DSP2 Control 1 */
{ 0x00001300, 0x0010 }, /* R4864 - DSP3 Control 1 */
@ -2710,6 +2889,13 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_CLOCK_CONTROL:
case ARIZONA_ANC_SRC:
case ARIZONA_DSP_STATUS:
case ARIZONA_ANC_COEFF_START ... ARIZONA_ANC_COEFF_END:
case ARIZONA_FCL_FILTER_CONTROL:
case ARIZONA_FCL_ADC_REFORMATTER_CONTROL:
case ARIZONA_FCL_COEFF_START ... ARIZONA_FCL_COEFF_END:
case ARIZONA_FCR_FILTER_CONTROL:
case ARIZONA_FCR_ADC_REFORMATTER_CONTROL:
case ARIZONA_FCR_COEFF_START ... ARIZONA_FCR_COEFF_END:
case ARIZONA_DSP1_CONTROL_1:
case ARIZONA_DSP1_CLOCKING_1:
case ARIZONA_DSP1_STATUS_1:

View file

@ -1626,7 +1626,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
mutex_init(&wm831x->io_lock);
mutex_init(&wm831x->key_lock);
dev_set_drvdata(wm831x->dev, wm831x);
wm831x->soft_shutdown = pdata->soft_shutdown;
if (pdata)
wm831x->soft_shutdown = pdata->soft_shutdown;
ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
if (ret < 0) {

View file

@ -21,7 +21,7 @@
#define WM8998_NUM_AOD_ISR 2
#define WM8998_NUM_ISR 5
static const struct reg_default wm8998_rev_a_patch[] = {
static const struct reg_sequence wm8998_rev_a_patch[] = {
{ 0x0212, 0x0000 },
{ 0x0211, 0x0014 },
{ 0x04E4, 0x0E0D },
@ -199,8 +199,6 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */
{ 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */
{ 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */
{ 0x0000006E, 0x01FF }, /* R110 - Trigger Sequence Select 32 */
{ 0x0000006F, 0x01FF }, /* R111 - Trigger Sequence Select 33 */
{ 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */
{ 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */
{ 0x00000092, 0x0000 }, /* R146 - Haptics phase 1 intensity */
@ -270,16 +268,13 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */
{ 0x00000293, 0x0080 }, /* R659 - Accessory Detect Mode 1 */
{ 0x0000029B, 0x0000 }, /* R667 - Headphone Detect 1 */
{ 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */
{ 0x000002A2, 0x0000 }, /* R674 - Micd Clamp control */
{ 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */
{ 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */
{ 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */
{ 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */
{ 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */
{ 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */
{ 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */
{ 0x000002AB, 0x0000 }, /* R683 - Mic Detect 4 */
{ 0x000002CB, 0x0000 }, /* R715 - Isolation control */
{ 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */
{ 0x00000300, 0x0000 }, /* R768 - Input Enables */
@ -707,13 +702,11 @@ static const struct reg_default wm8998_reg_default[] = {
{ 0x00000D1A, 0xFFFF }, /* R3354 - IRQ2 Status 3 Mask */
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
{ 0x00000D1C, 0xFEFF }, /* R3356 - IRQ2 Status 5 Mask */
{ 0x00000D1D, 0xFFFF }, /* R3357 - IRQ2 Status 6 Mask */
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
{ 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */
{ 0x00000E00, 0x0000 }, /* R3584 - FX_Ctrl1 */
{ 0x00000E01, 0x0000 }, /* R3585 - FX_Ctrl2 */
{ 0x00000E10, 0x6318 }, /* R3600 - EQ1_1 */
{ 0x00000E11, 0x6300 }, /* R3601 - EQ1_2 */
{ 0x00000E12, 0x0FC8 }, /* R3602 - EQ1_3 */
@ -833,7 +826,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg)
switch (reg) {
case ARIZONA_SOFTWARE_RESET:
case ARIZONA_DEVICE_REVISION:
case ARIZONA_CTRL_IF_SPI_CFG_1:
case ARIZONA_CTRL_IF_I2C1_CFG_1:
case ARIZONA_CTRL_IF_I2C1_CFG_2:
case ARIZONA_WRITE_SEQUENCER_CTRL_0: