diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-04 11:35:03 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-04 11:35:03 -0700 |
commit | 8bd8fd0a29bfd5ad8e1976edd8c4c40cdb39aa4f (patch) | |
tree | 1d7b2e30083194cc4223d9b150583fc2924bd032 /drivers/mfd/arizona-core.c | |
parent | 352712274507645b6f82b8763977ad87321919a3 (diff) | |
parent | 5a688c455066c21c133bc8ffa7b11f8c66b7fe0b (diff) | |
download | lwn-8bd8fd0a29bfd5ad8e1976edd8c4c40cdb39aa4f.tar.gz lwn-8bd8fd0a29bfd5ad8e1976edd8c4c40cdb39aa4f.zip |
Merge tag 'mfd-for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"New Device Support:
- New Clocksource driver from ST
- New MFD/ACPI/DMA drivers for Intel's Sunrisepoint PCH based platforms
- Add support for Arizona WM8998 and WM1814
- Add support for Dialog Semi DA9062 and DA9063
- Add support for Kontron COMe-bBL6 and COMe-cBW6
- Add support for X-Powers AXP152
- Add support for Atmel, many
- Add support for STMPE, many
- Add support for USB in X-Powers AXP22X
Core Frameworks:
- New Base API to traverse devices and their children in reverse order
Bug Fixes:
- Fix race between runtime-suspend and IRQs
- Obtain platform data form more reliable source
Fix-ups:
- Constifying things
- Variable signage changes
- Kconfig depends|selects changes
- Make use of BIT() macro
- Do not supply .owner attribute in *_driver structures
- MAINTAINERS entries
- Stop using set_irq_flags()
- Start using irq_set_chained_handler_and_data()
- Export DT device ID structures"
* tag 'mfd-for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits)
mfd: jz4740-adc: Init mask cache in generic IRQ chip
mfd: cros_ec: spi: Add OF match table
mfd: stmpe: Add OF match table
mfd: max77686: Split out regulator part from the DT binding
mfd: Add DT binding for Maxim MAX77802 IC
mfd: max77686: Use a generic name for the PMIC node in the example
mfd: max77686: Don't suggest in binding to use a deprecated property
mfd: Add MFD_CROS_EC dependencies
mfd: cros_ec: Remove CROS_EC_PROTO dependency for SPI and I2C drivers
mfd: axp20x: Add a cell for the usb power_supply part of the axp20x PMICs
mfd: axp20x: Add missing registers, and mark more registers volatile
mfd: arizona: Fixup some formatting/white space errors
mfd: wm8994: Fix NULL pointer exception on missing pdata
of: Add vendor prefix for Nuvoton
mfd: mt6397: Implement wake handler and suspend/resume to handle wake up event
mfd: atmel-hlcdc: Add support for new SoCs
mfd: Export OF module alias information in missing drivers
mfd: stw481x: Export I2C module alias information
mfd: da9062: Support for the DA9063 OnKey in the DA9062 core
mfd: max899x: Avoid redundant irq_data lookup
...
Diffstat (limited to 'drivers/mfd/arizona-core.c')
-rw-r--r-- | drivers/mfd/arizona-core.c | 138 |
1 files changed, 113 insertions, 25 deletions
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index a72ddb295078..08b36fa5b0c5 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -30,7 +30,7 @@ #include "arizona.h" -static const char *wm5102_core_supplies[] = { +static const char * const wm5102_core_supplies[] = { "AVDD", "DBVDD1", }; @@ -146,17 +146,31 @@ static irqreturn_t arizona_underclocked(int irq, void *data) static irqreturn_t arizona_overclocked(int irq, void *data) { struct arizona *arizona = data; - unsigned int val[2]; + unsigned int val[3]; int ret; - + ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6, - &val[0], 2); + &val[0], 3); if (ret != 0) { dev_err(arizona->dev, "Failed to read overclock status: %d\n", ret); return IRQ_NONE; } + switch (arizona->type) { + case WM8998: + case WM1814: + /* Some bits are shifted on WM8998, + * rearrange to match the standard bit layout + */ + val[0] = ((val[0] & 0x60e0) >> 1) | + ((val[0] & 0x1e00) >> 2) | + (val[0] & 0x000f); + break; + default: + break; + } + if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS) dev_err(arizona->dev, "PWM overclocked\n"); if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS) @@ -201,6 +215,9 @@ static irqreturn_t arizona_overclocked(int irq, void *data) if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS) dev_err(arizona->dev, "ISRC1 overclocked\n"); + if (val[2] & ARIZONA_SPDIF_OVERCLOCKED_STS) + dev_err(arizona->dev, "SPDIF overclocked\n"); + return IRQ_HANDLED; } @@ -550,9 +567,8 @@ static int arizona_runtime_resume(struct device *dev) break; default: ret = arizona_wait_for_boot(arizona); - if (ret != 0) { + if (ret != 0) goto err; - } if (arizona->external_dcvdd) { ret = regmap_update_bits(arizona->regmap, @@ -759,8 +775,8 @@ static int arizona_of_get_core_pdata(struct arizona *arizona) ret = of_property_read_u32_array(arizona->dev->of_node, "wlf,gpio-defaults", - arizona->pdata.gpio_defaults, - ARRAY_SIZE(arizona->pdata.gpio_defaults)); + pdata->gpio_defaults, + ARRAY_SIZE(pdata->gpio_defaults)); if (ret >= 0) { /* * All values are literal except out of range values @@ -768,11 +784,11 @@ static int arizona_of_get_core_pdata(struct arizona *arizona) * data which uses 0 as chip default and out of range * as zero. */ - for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { - if (arizona->pdata.gpio_defaults[i] > 0xffff) - arizona->pdata.gpio_defaults[i] = 0; - else if (arizona->pdata.gpio_defaults[i] == 0) - arizona->pdata.gpio_defaults[i] = 0x10000; + for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { + if (pdata->gpio_defaults[i] > 0xffff) + pdata->gpio_defaults[i] = 0; + else if (pdata->gpio_defaults[i] == 0) + pdata->gpio_defaults[i] = 0x10000; } } else { dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n", @@ -781,20 +797,20 @@ static int arizona_of_get_core_pdata(struct arizona *arizona) of_property_for_each_u32(arizona->dev->of_node, "wlf,inmode", prop, cur, val) { - if (count == ARRAY_SIZE(arizona->pdata.inmode)) + if (count == ARRAY_SIZE(pdata->inmode)) break; - arizona->pdata.inmode[count] = val; + pdata->inmode[count] = val; count++; } count = 0; of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop, cur, val) { - if (count == ARRAY_SIZE(arizona->pdata.dmic_ref)) + if (count == ARRAY_SIZE(pdata->dmic_ref)) break; - arizona->pdata.dmic_ref[count] = val; + pdata->dmic_ref[count] = val; count++; } @@ -806,6 +822,8 @@ const struct of_device_id arizona_of_match[] = { { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, { .compatible = "wlf,wm8997", .data = (void *)WM8997 }, + { .compatible = "wlf,wm8998", .data = (void *)WM8998 }, + { .compatible = "wlf,wm1814", .data = (void *)WM1814 }, {}, }; EXPORT_SYMBOL_GPL(arizona_of_match); @@ -820,7 +838,7 @@ static const struct mfd_cell early_devs[] = { { .name = "arizona-ldo1" }, }; -static const char *wm5102_supplies[] = { +static const char * const wm5102_supplies[] = { "MICVDD", "DBVDD2", "DBVDD3", @@ -863,7 +881,7 @@ static const struct mfd_cell wm5110_devs[] = { }, }; -static const char *wm8997_supplies[] = { +static const char * const wm8997_supplies[] = { "MICVDD", "DBVDD2", "CPVDD", @@ -887,11 +905,28 @@ static const struct mfd_cell wm8997_devs[] = { }, }; +static const struct mfd_cell wm8998_devs[] = { + { + .name = "arizona-extcon", + .parent_supplies = wm5102_supplies, + .num_parent_supplies = 1, /* We only need MICVDD */ + }, + { .name = "arizona-gpio" }, + { .name = "arizona-haptics" }, + { .name = "arizona-pwm" }, + { + .name = "wm8998-codec", + .parent_supplies = wm5102_supplies, + .num_parent_supplies = ARRAY_SIZE(wm5102_supplies), + }, + { .name = "arizona-micsupp" }, +}; + int arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; - unsigned int reg, val; + unsigned int reg, val, mask; int (*apply_patch)(struct arizona *) = NULL; int ret, i; @@ -911,6 +946,8 @@ int arizona_dev_init(struct arizona *arizona) case WM5110: case WM8280: case WM8997: + case WM8998: + case WM1814: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; @@ -992,6 +1029,7 @@ int arizona_dev_init(struct arizona *arizona) switch (reg) { case 0x5102: case 0x5110: + case 0x6349: case 0x8997: break; default: @@ -1093,6 +1131,27 @@ int arizona_dev_init(struct arizona *arizona) apply_patch = wm8997_patch; break; #endif +#ifdef CONFIG_MFD_WM8998 + case 0x6349: + switch (arizona->type) { + case WM8998: + type_name = "WM8998"; + 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; + } + + apply_patch = wm8998_patch; + break; +#endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; @@ -1204,14 +1263,38 @@ int arizona_dev_init(struct arizona *arizona) << ARIZONA_IN1_DMIC_SUP_SHIFT; if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC) val |= 1 << ARIZONA_IN1_MODE_SHIFT; - if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE) - val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT; + + switch (arizona->type) { + case WM8998: + case WM1814: + regmap_update_bits(arizona->regmap, + ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8), + ARIZONA_IN1L_SRC_SE_MASK, + (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE) + << ARIZONA_IN1L_SRC_SE_SHIFT); + + regmap_update_bits(arizona->regmap, + ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8), + ARIZONA_IN1R_SRC_SE_MASK, + (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE) + << ARIZONA_IN1R_SRC_SE_SHIFT); + + mask = ARIZONA_IN1_DMIC_SUP_MASK | + ARIZONA_IN1_MODE_MASK; + break; + default: + if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE) + val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT; + + mask = ARIZONA_IN1_DMIC_SUP_MASK | + ARIZONA_IN1_MODE_MASK | + ARIZONA_IN1_SINGLE_ENDED_MASK; + break; + } regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), - ARIZONA_IN1_DMIC_SUP_MASK | - ARIZONA_IN1_MODE_MASK | - ARIZONA_IN1_SINGLE_ENDED_MASK, val); + mask, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { @@ -1273,6 +1356,11 @@ int arizona_dev_init(struct arizona *arizona) 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; } if (ret != 0) { |