WM8994 MFD updates for 3.3
Subsystems (5)
cover WM8994 MFD updates for 3.3
The following patch series (and pull request) contains a bunch of updates I've previously posted for wm8994 but which haven't been merged plus a big update adding register cache support for the wm8994 driver which hasn't previously been posted. As there's a matching update for the ASoC driver for WM8994 removing the copy of the register cache there it'd be great if it were possible to merge this via the ASoC tree.
I've also got one more patch which depends on this lot converting the IRQ controller over to use the generic regmap IRQ controller which I'll post as well - that also depends on this series as the regmap interrupt controller relies on the register cache - so I'd also like to either pull the same branch into the regmap tree or merge both this and the regmap IRQ stuff via ASoC.
This seems like the easiest route from the point of view of bisection and cross tree issues - does that all sound OK to you?
The following changes since commit caca6a03d365883564885f2c1da3e88dcf65d139:
Linux 3.2-rc3 (2011-11-23 20:20:28 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git mfd/wm8994
Mark Brown (8):
mfd: Remove some unused functions in wm8894-irq
mfd: Add basic device tree binding for wm8994
mfd: Convert wm8994 to devm_kzalloc()
mfd: Disable more pulls on WM8994
mfd: Don't hard code the reset value for WM8994 devices
mfd: Define some additional wm8994 registers
mfd: Add wm8994 register access and default information
mfd: Enable register cache for wm8994 devices
Documentation/devicetree/bindings/sound/wm8994.txt | 18 + drivers/mfd/Makefile | 2 +- drivers/mfd/wm8994-core.c | 121 +-- drivers/mfd/wm8994-irq.c | 10 - drivers/mfd/wm8994-regmap.c | 1218 ++++++++++++++++++++ drivers/mfd/wm8994.h | 24 + include/linux/mfd/wm8994/core.h | 2 - include/linux/mfd/wm8994/pdata.h | 6 + include/linux/mfd/wm8994/registers.h | 96 ++ sound/soc/codecs/wm8994-tables.c | 12 +- 10 files changed, 1423 insertions(+), 86 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/wm8994.txt create mode 100644 drivers/mfd/wm8994-regmap.c create mode 100644 drivers/mfd/wm8994.h
PATCH 1/8 mfd: Remove some unused functions in wm8894-irq
--- drivers/mfd/wm8994-irq.c | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-)
drivers/mfd/wm8994-irq.c +0 -10
@@ -140,16 +140,6 @@ static struct wm8994_irq_data wm8994_irqs[] = { }, }; -static inline int irq_data_to_status_reg (struct wm8994_irq_data *irq_data) -{ -return WM8994_INTERRUPT_STATUS_1 -1 + irq_data->reg; -} - -static inline int irq_data_to_mask_reg (struct wm8994_irq_data *irq_data) -{ -return WM8994_INTERRUPT_STATUS_1_MASK -1 + irq_data->reg; -} -static inline struct wm8994_irq_data *irq_to_wm8994_irq (struct wm8994 *wm8994,int irq) {
Signature · 1 line
1.7.7.3
PATCH 2/8 mfd: Add basic device tree binding for wm8994
Add a placeholder device tree binding for the wm8994 driver. At present the binding is essentially null as none of the platform data is supported, and at least some of that will depend on the pending regulator bindings.
--- Documentation/devicetree/bindings/sound/wm8994.txt | 18 ++++++++++++++++++ drivers/mfd/wm8994-core.c | 9 +++++++++ 2 files changed, 27 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/wm8994.txt
Documentation/devicetree/bindings/sound/wm8994.txt new file +18 -0
@@ -0,0 +1,18 @@ +WM1811/WM8994/WM8958 audio CODEC + +These devices support both I2C and SPI (configured with pin strapping +on the board). + +Required properties: + + - compatible : "wlf,wm1811", "wlf,wm8994", "wlf,wm8958" + + - reg : the I2C address of the device for I2C, the chip select + number for SPI. + +Example: + +codec: wm8994@1a { + compatible = "wlf,wm8994"; + reg = <0x1a>; +};
drivers/mfd/wm8994-core.c +9 -0
@@ -581,6 +581,14 @@ static void wm8994_device_exit(struct wm8994 *wm8994)kfree (wm8994); } +static const struct of_device_id wm8994_of_match[] = { + { .compatible ="wlf,wm1811" , }, + { .compatible ="wlf,wm8994" , }, + { .compatible ="wlf,wm8958" , }, + { } +}; +MODULE_DEVICE_TABLE (of, wm8994_of_match); +static int wm8994_i2c_probe (struct i2c_client *i2c,const struct i2c_device_id *id) {
@@ -633,6 +641,7 @@ static struct i2c_driver wm8994_i2c_driver = { .name = "wm8994", .owner = THIS_MODULE, .pm = &wm8994_pm_ops, + .of_match_table = wm8994_of_match, }, .probe = wm8994_i2c_probe, .remove = wm8994_i2c_remove,
Signature · 1 line
1.7.7.3
PATCH 3/8 mfd: Convert wm8994 to devm_kzalloc()
In reply to Mark Brown--- drivers/mfd/wm8994-core.c | 16 +++++----------- 1 files changed, 5 insertions(+), 11 deletions(-)
drivers/mfd/wm8994-core.c +5 -11
@@ -401,9 +401,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) goto err_regmap; } - wm8994->supplies =kzalloc (sizeof (struct regulator_bulk_data ) * - wm8994->num_supplies, -GFP_KERNEL ); + wm8994->supplies =devm_kzalloc (wm8994->dev, +sizeof (struct regulator_bulk_data ) * + wm8994->num_supplies,GFP_KERNEL );if (!wm8994->supplies) { ret = -ENOMEM ; goto err_regmap;
@@ -431,7 +431,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) wm8994->supplies);if (ret !=0 ) {dev_err (wm8994->dev,"Failed to get supplies: %d\n" , ret); - goto err_supplies; + goto err_regmap; } ret = regulator_bulk_enable(wm8994->num_supplies,
@@ -559,12 +559,9 @@ err_enable: wm8994->supplies); err_get:regulator_bulk_free (wm8994->num_supplies, wm8994->supplies); -err_supplies: -kfree (wm8994->supplies); err_regmap:regmap_exit (wm8994->regmap);mfd_remove_devices (wm8994->dev); -kfree (wm8994);return ret; }
@@ -576,9 +573,7 @@ static void wm8994_device_exit(struct wm8994 *wm8994)regulator_bulk_disable (wm8994->num_supplies, wm8994->supplies);regulator_bulk_free (wm8994->num_supplies, wm8994->supplies); -kfree (wm8994->supplies);regmap_exit (wm8994->regmap); -kfree (wm8994); }static const struct of_device_id wm8994_of_match[] = {
@@ -595,7 +590,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,struct wm8994 *wm8994;int ret; - wm8994 =kzalloc (sizeof (struct wm8994 ),GFP_KERNEL ); + wm8994 =devm_kzalloc (&i2c->dev,sizeof (struct wm8994 ),GFP_KERNEL );if (wm8994 ==NULL )return -ENOMEM ;
@@ -609,7 +604,6 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, ret =PTR_ERR (wm8994->regmap);dev_err (wm8994->dev,"Failed to allocate register map: %d\n" , ret); -kfree (wm8994);return ret; }
Signature · 1 line
1.7.7.3
PATCH 4/8 mfd: Disable more pulls on WM8994
In reply to Mark BrownDisable more pulls by default on WM8994 for a small current saving. Since some designs do leave SPKMODE floating provide platform data to allow that to be left enabled.
--- drivers/mfd/wm8994-core.c | 11 ++++++++--- include/linux/mfd/wm8994/pdata.h | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-)
drivers/mfd/wm8994-core.c +8 -3
@@ -373,6 +373,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)struct wm8994_pdata *pdata = wm8994->dev->platform_data;const char *devname;int ret, i; +int pulls =0 ;dev_set_drvdata (wm8994->dev, wm8994);
@@ -515,12 +516,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) } wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; + +if (pdata->spkmode_pu) + pulls |=WM8994_SPKMODE_PU ; } -/* Disable LDO pulldowns while the device is active */ +/* Disable unneeded pulls */ wm8994_set_bits (wm8994,WM8994_PULL_CONTROL_2 , -WM8994_LDO1ENA_PD |WM8994_LDO2ENA_PD , -0 ); +WM8994_LDO1ENA_PD |WM8994_LDO2ENA_PD | +WM8994_SPKMODE_PU |WM8994_CSNADDR_PD , + pulls);/* In some system designs where the regulators are not in use, * we can achieve a small reduction in leakage currents by
include/linux/mfd/wm8994/pdata.h +6 -0
@@ -174,6 +174,12 @@ struct wm8994_pdata {* consumption will rise. */ bool ldo_ena_always_driven; + +/* +* SPKMODE must be pulled internally by the device on this +* system. +*/ + bool spkmode_pu; };#endif
Signature · 1 line
1.7.7.3
PATCH 5/8 mfd: Don't hard code the reset value for WM8994 devices
In reply to Mark Brown--- drivers/mfd/wm8994-core.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/mfd/wm8994-core.c +2 -1
@@ -276,7 +276,8 @@ static int wm8994_suspend(struct device *dev)/* Explicitly put the device into reset in case regulators * don't get disabled in order to ensure consistent restart. */ -wm8994_reg_write (wm8994,WM8994_SOFTWARE_RESET ,0x8994 ); +wm8994_reg_write (wm8994,WM8994_SOFTWARE_RESET , +wm8994_reg_read (wm8994,WM8994_SOFTWARE_RESET )); wm8994->suspended = true;
Signature · 1 line
1.7.7.3
PATCH 6/8 mfd: Define some additional wm8994 registers
In reply to Mark BrownAdd a bunch of definitions for wm8994 registers that are not currently used by software.
--- include/linux/mfd/wm8994/registers.h | 96 ++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994-tables.c | 12 ++-- 2 files changed, 102 insertions(+), 6 deletions(-)
include/linux/mfd/wm8994/registers.h +96 -0
@@ -95,11 +95,15 @@#define WM8994_FLL1_CONTROL_3 0x222#define WM8994_FLL1_CONTROL_4 0x223#define WM8994_FLL1_CONTROL_5 0x224 +#define WM8958_FLL1_EFS_1 0x226 +#define WM8958_FLL1_EFS_2 0x227#define WM8994_FLL2_CONTROL_1 0x240#define WM8994_FLL2_CONTROL_2 0x241#define WM8994_FLL2_CONTROL_3 0x242#define WM8994_FLL2_CONTROL_4 0x243#define WM8994_FLL2_CONTROL_5 0x244 +#define WM8958_FLL2_EFS_1 0x246 +#define WM8958_FLL2_EFS_2 0x247#define WM8994_AIF1_CONTROL_1 0x300#define WM8994_AIF1_CONTROL_2 0x301#define WM8994_AIF1_MASTER_SLAVE 0x302
@@ -116,6 +120,7 @@#define WM8994_AIF2DAC_LRCLK 0x315#define WM8994_AIF2DAC_DATA 0x316#define WM8994_AIF2ADC_DATA 0x317 +#define WM1811_AIF2TX_CONTROL 0x318#define WM8958_AIF3_CONTROL_1 0x320#define WM8958_AIF3_CONTROL_2 0x321#define WM8958_AIF3DAC_DATA 0x322
@@ -166,6 +171,7 @@#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493 +#define WM8994_AIF1_DAC1_EQ_BAND_1_C 0x494#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2
@@ -186,6 +192,7 @@#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3 +#define WM8994_AIF1_DAC2_EQ_BAND_1_C 0x4B4#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502
@@ -219,6 +226,7 @@#define WM8994_AIF2_EQ_BAND_5_A 0x591#define WM8994_AIF2_EQ_BAND_5_B 0x592#define WM8994_AIF2_EQ_BAND_5_PG 0x593 +#define WM8994_AIF2_EQ_BAND_1_C 0x594#define WM8994_DAC1_MIXER_VOLUMES 0x600#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602
@@ -264,7 +272,43 @@#define WM8958_DSP2_RELEASETIME 0xA03#define WM8958_DSP2_VERMAJMIN 0xA04#define WM8958_DSP2_VERBUILD 0xA05 +#define WM8958_DSP2_TESTREG 0xA06 +#define WM8958_DSP2_XORREG 0xA07 +#define WM8958_DSP2_SHIFTMAXX 0xA08 +#define WM8958_DSP2_SHIFTMAXY 0xA09 +#define WM8958_DSP2_SHIFTMAXZ 0xA0A +#define WM8958_DSP2_SHIFTMAXEXTLO 0xA0B +#define WM8958_DSP2_AESSELECT 0xA0C#define WM8958_DSP2_EXECCONTROL 0xA0D +#define WM8958_DSP2_SAMPLEBREAK 0xA0E +#define WM8958_DSP2_COUNTBREAK 0xA0F +#define WM8958_DSP2_INTSTATUS 0xA10 +#define WM8958_DSP2_EVENTSTATUS 0xA11 +#define WM8958_DSP2_INTMASK 0xA12 +#define WM8958_DSP2_CONFIGDWIDTH 0xA13 +#define WM8958_DSP2_CONFIGINSTR 0xA14 +#define WM8958_DSP2_CONFIGDMEM 0xA15 +#define WM8958_DSP2_CONFIGDELAYS 0xA16 +#define WM8958_DSP2_CONFIGNUMIO 0xA17 +#define WM8958_DSP2_CONFIGEXTDEPTH 0xA18 +#define WM8958_DSP2_CONFIGMULTIPLIER 0xA19 +#define WM8958_DSP2_CONFIGCTRLDWIDTH 0xA1A +#define WM8958_DSP2_CONFIGPIPELINE 0xA1B +#define WM8958_DSP2_SHIFTMAXEXTHI 0xA1C +#define WM8958_DSP2_SWVERSIONREG 0xA1D +#define WM8958_DSP2_CONFIGXMEM 0xA1E +#define WM8958_DSP2_CONFIGYMEM 0xA1F +#define WM8958_DSP2_CONFIGZMEM 0xA20 +#define WM8958_FW_BUILD_1 0x2000 +#define WM8958_FW_BUILD_0 0x2001 +#define WM8958_FW_ID_1 0x2002 +#define WM8958_FW_ID_0 0x2003 +#define WM8958_FW_MAJOR_1 0x2004 +#define WM8958_FW_MAJOR_0 0x2005 +#define WM8958_FW_MINOR_1 0x2006 +#define WM8958_FW_MINOR_0 0x2007 +#define WM8958_FW_PATCH_1 0x2008 +#define WM8958_FW_PATCH_0 0x2009#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 0x2200#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_2 0x2201#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_1 0x2202
@@ -333,6 +377,14 @@#define WM8958_MBC_B2_PG2_2 0x242D#define WM8958_MBC_B1_PG2_1 0x242E#define WM8958_MBC_B1_PG2_2 0x242F +#define WM8958_MBC_CROSSOVER_1 0x2600 +#define WM8958_MBC_CROSSOVER_2 0x2601 +#define WM8958_MBC_HPF_1 0x2602 +#define WM8958_MBC_HPF_2 0x2603 +#define WM8958_MBC_LPF_1 0x2606 +#define WM8958_MBC_LPF_2 0x2607 +#define WM8958_MBC_RMS_LIMIT_1 0x260A +#define WM8958_MBC_RMS_LIMIT_2 0x260B#define WM8994_WRITE_SEQUENCER_0 0x3000#define WM8994_WRITE_SEQUENCER_1 0x3001#define WM8994_WRITE_SEQUENCER_2 0x3002
@@ -2389,6 +2441,10 @@/* * R548 (0x224) - FLL1 Control (5) */ +#define WM8958_FLL1_BYP 0x8000/* FLL1_BYP */ +#define WM8958_FLL1_BYP_MASK 0x8000/* FLL1_BYP */ +#define WM8958_FLL1_BYP_SHIFT 15/* FLL1_BYP */ +#define WM8958_FLL1_BYP_WIDTH 1/* FLL1_BYP */ #define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80/* FLL1_FRC_NCO_VAL - [12:7] */ #define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7/* FLL1_FRC_NCO_VAL - [12:7] */ #define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6/* FLL1_FRC_NCO_VAL - [12:7] */
@@ -2404,6 +2460,24 @@#define WM8994_FLL1_REFCLK_SRC_WIDTH 2/* FLL1_REFCLK_SRC - [1:0] */ /* +* R550 (0x226) - FLL1 EFS 1 +*/ +#define WM8958_FLL1_LAMBDA_MASK 0xFFFF/* FLL1_LAMBDA - [15:0] */ +#define WM8958_FLL1_LAMBDA_SHIFT 0/* FLL1_LAMBDA - [15:0] */ +#define WM8958_FLL1_LAMBDA_WIDTH 16/* FLL1_LAMBDA - [15:0] */ + +/* +* R551 (0x227) - FLL1 EFS 2 +*/ +#define WM8958_FLL1_LFSR_SEL_MASK 0x0006/* FLL1_LFSR_SEL - [2:1] */ +#define WM8958_FLL1_LFSR_SEL_SHIFT 1/* FLL1_LFSR_SEL - [2:1] */ +#define WM8958_FLL1_LFSR_SEL_WIDTH 2/* FLL1_LFSR_SEL - [2:1] */ +#define WM8958_FLL1_EFS_ENA 0x0001/* FLL1_EFS_ENA */ +#define WM8958_FLL1_EFS_ENA_MASK 0x0001/* FLL1_EFS_ENA */ +#define WM8958_FLL1_EFS_ENA_SHIFT 0/* FLL1_EFS_ENA */ +#define WM8958_FLL1_EFS_ENA_WIDTH 1/* FLL1_EFS_ENA */ + +/* * R576 (0x240) - FLL2 Control (1) */ #define WM8994_FLL2_FRAC 0x0004/* FLL2_FRAC */
@@ -2452,6 +2526,10 @@/* * R580 (0x244) - FLL2 Control (5) */ +#define WM8958_FLL2_BYP 0x8000/* FLL2_BYP */ +#define WM8958_FLL2_BYP_MASK 0x8000/* FLL2_BYP */ +#define WM8958_FLL2_BYP_SHIFT 15/* FLL2_BYP */ +#define WM8958_FLL2_BYP_WIDTH 1/* FLL2_BYP */ #define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80/* FLL2_FRC_NCO_VAL - [12:7] */ #define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7/* FLL2_FRC_NCO_VAL - [12:7] */ #define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6/* FLL2_FRC_NCO_VAL - [12:7] */
@@ -2467,6 +2545,24 @@#define WM8994_FLL2_REFCLK_SRC_WIDTH 2/* FLL2_REFCLK_SRC - [1:0] */ /* +* R582 (0x246) - FLL2 EFS 1 +*/ +#define WM8958_FLL2_LAMBDA_MASK 0xFFFF/* FLL2_LAMBDA - [15:0] */ +#define WM8958_FLL2_LAMBDA_SHIFT 0/* FLL2_LAMBDA - [15:0] */ +#define WM8958_FLL2_LAMBDA_WIDTH 16/* FLL2_LAMBDA - [15:0] */ + +/* +* R583 (0x247) - FLL2 EFS 2 +*/ +#define WM8958_FLL2_LFSR_SEL_MASK 0x0006/* FLL2_LFSR_SEL - [2:1] */ +#define WM8958_FLL2_LFSR_SEL_SHIFT 1/* FLL2_LFSR_SEL - [2:1] */ +#define WM8958_FLL2_LFSR_SEL_WIDTH 2/* FLL2_LFSR_SEL - [2:1] */ +#define WM8958_FLL2_EFS_ENA 0x0001/* FLL2_EFS_ENA */ +#define WM8958_FLL2_EFS_ENA_MASK 0x0001/* FLL2_EFS_ENA */ +#define WM8958_FLL2_EFS_ENA_SHIFT 0/* FLL2_EFS_ENA */ +#define WM8958_FLL2_EFS_ENA_WIDTH 1/* FLL2_EFS_ENA */ + +/* * R768 (0x300) - AIF1 Control (1) */ #define WM8994_AIF1ADCL_SRC 0x8000/* AIF1ADCL_SRC */
sound/soc/codecs/wm8994-tables.c +6 -6
@@ -78,7 +78,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { { 0x0000, 0x0000 }, /* R74 */ { 0x0000, 0x0000 }, /* R75 */ { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ - { 0x0000, 0x0000 }, /* R77 */ + { 0x8000, 0x8000 }, /* R77 - Charge Pump (2) */ { 0x0000, 0x0000 }, /* R78 */ { 0x0000, 0x0000 }, /* R79 */ { 0x0000, 0x0000 }, /* R80 */
@@ -1651,7 +1651,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {0x0000 ,/* R74 */ 0x0000 ,/* R75 */ 0x1F25 ,/* R76 - Charge Pump (1) */ -0x0000 ,/* R77 */ +0xAB19 ,/* R77 - Charge Pump (2) */ 0x0000 ,/* R78 */ 0x0000 ,/* R79 */ 0x0000, /* R80 */
@@ -2124,8 +2124,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {0x0000 ,/* R547 - FLL1 Control (4) */ 0x0C80 ,/* R548 - FLL1 Control (5) */ 0x0000 ,/* R549 */ -0x0000 ,/* R550 */ -0x0000 ,/* R551 */ +0x0000 ,/* R550 - FLL1 EFS 1 */ +0x0006 ,/* R551 - FLL1 EFS 2 */ 0x0000 ,/* R552 */ 0x0000 ,/* R553 */ 0x0000, /* R554 */
@@ -2156,8 +2156,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {0x0000 ,/* R579 - FLL2 Control (4) */ 0x0C80 ,/* R580 - FLL2 Control (5) */ 0x0000 ,/* R581 */ -0x0000 ,/* R582 */ -0x0000 ,/* R583 */ +0x0000 ,/* R582 - FLL2 EFS 1 */ +0x0006 ,/* R583 - FLL2 EFS 2 */ 0x0000 ,/* R584 */ 0x0000 ,/* R585 */ 0x0000, /* R586 */
Signature · 1 line
1.7.7.3
PATCH 7/8 mfd: Add wm8994 register access and default information
In reply to Mark BrownDescribe the register map to the regmap core so that we can use its diagnostic features and cache support. This is split out from the patch using it due to the size so that the actual code change is a bit clearer.
As the various devices are supersets of each other the access maps are built up by layering the functions on top of each other, though the interface for specifying the register defaults isn't currently amenable to this.
--- drivers/mfd/Makefile | 2 +- drivers/mfd/wm8994-regmap.c | 1218 +++++++++++++++++++++++++++++++++++++++++++ drivers/mfd/wm8994.h | 24 + 3 files changed, 1243 insertions(+), 1 deletions(-) create mode 100644 drivers/mfd/wm8994-regmap.c create mode 100644 drivers/mfd/wm8994.h
drivers/mfd/Makefile +1 -1
@@ -31,7 +31,7 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o wm8350-objs += wm8350-irq.o obj-$(CONFIG_MFD_WM8350) += wm8350.o obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o -obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o +obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o obj-$(CONFIG_TPS6105X) += tps6105x.o obj-$(CONFIG_TPS65010) += tps65010.o
drivers/mfd/wm8994-regmap.c new file +1218 -0
1,218 lines not on this page · raw message
drivers/mfd/wm8994.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +* wm8994.h -- WM8994 MFD internals +* +* Copyright 2011 Wolfson Microelectronics PLC. +* +* Author: Mark Brown <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +*/ + +#ifndef __MFD_WM8994_H__ +#define __MFD_WM8994_H__ + +#include <linux/regmap.h> + +extern struct regmap_config wm1811_regmap_config; +extern struct regmap_config wm8994_regmap_config; +extern struct regmap_config wm8958_regmap_config; + +#endif
Signature · 1 line
1.7.7.3
PATCH 8/8 mfd: Enable register cache for wm8994 devices
In reply to Mark BrownAs part of this we provide information about the registers that exist in the device to the regmap core, drop the small amount of cache that the core had been using and let regmap do the sync.
--- drivers/mfd/wm8994-core.c | 82 ++++++++++++++------------------------ include/linux/mfd/wm8994/core.h | 2 - 2 files changed, 30 insertions(+), 54 deletions(-)
drivers/mfd/wm8994-core.c +30 -52
@@ -28,11 +28,7 @@#include <linux/mfd/wm8994/pdata.h> #include <linux/mfd/wm8994/registers.h> -static int wm8994_read (struct wm8994 *wm8994,unsigned short reg, -int bytes,void *dest) -{ -return regmap_raw_read (wm8994->regmap, reg, dest, bytes); -} +#include "wm8994.h" /** * wm8994_reg_read: Read a single WM8994 register.
@@ -68,12 +64,6 @@ int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,return regmap_bulk_read (wm8994->regmap, reg, buf, count); } -static int wm8994_write (struct wm8994 *wm8994,unsigned short reg, -int bytes,const void *src) -{ -return regmap_raw_write (wm8994->regmap, reg, src, bytes); -} -/** * wm8994_reg_write: Write a single WM8994 register. *
@@ -258,27 +248,14 @@ static int wm8994_suspend(struct device *dev)WM8994_LDO1ENA_PD |WM8994_LDO2ENA_PD , WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD); -/* GPIO configuration state is saved here since we may be configuring -* the GPIO alternate functions even if we're not using the gpiolib -* driver for them. -*/ - ret =wm8994_read (wm8994,WM8994_GPIO_1 ,WM8994_NUM_GPIO_REGS *2 , - &wm8994->gpio_regs); -if (ret <0 ) -dev_err (dev,"Failed to save GPIO registers: %d\n" , ret); - -/* For similar reasons we also stash the regulator states */ - ret =wm8994_read (wm8994,WM8994_LDO_1 ,WM8994_NUM_LDO_REGS *2 , - &wm8994->ldo_regs); -if (ret <0 ) -dev_err (dev,"Failed to save LDO registers: %d\n" , ret); -/* Explicitly put the device into reset in case regulators * don't get disabled in order to ensure consistent restart. */ wm8994_reg_write (wm8994,WM8994_SOFTWARE_RESET ,wm8994_reg_read (wm8994,WM8994_SOFTWARE_RESET )); +regcache_mark_dirty (wm8994->regmap); + wm8994->suspended = true; ret = regulator_bulk_disable(wm8994->num_supplies,
@@ -294,7 +271,7 @@ static int wm8994_suspend(struct device *dev)static int wm8994_resume (struct device *dev) {struct wm8994 *wm8994 =dev_get_drvdata (dev); -int ret, i; +int ret;/* We may have lied to the PM core about suspending */ if (!wm8994->suspended)
@@ -307,27 +284,12 @@ static int wm8994_resume(struct device *dev)return ret; } -/* Write register at a time as we use the cache on the CPU so store -* it in native endian. -*/ -for (i =0 ; i <ARRAY_SIZE (wm8994->irq_masks_cur); i++) { - ret =wm8994_reg_write (wm8994,WM8994_INTERRUPT_STATUS_1_MASK - + i, wm8994->irq_masks_cur[i]); -if (ret <0 ) -dev_err (dev,"Failed to restore interrupt masks: %d\n" , - ret); + ret =regcache_sync (wm8994->regmap); +if (ret !=0 ) { +dev_err (dev,"Failed to restore register map: %d\n" , ret); + goto err_enable; } - ret =wm8994_write (wm8994,WM8994_LDO_1 ,WM8994_NUM_LDO_REGS *2 , - &wm8994->ldo_regs); -if (ret <0 ) -dev_err (dev,"Failed to restore LDO registers: %d\n" , ret); - - ret =wm8994_write (wm8994,WM8994_GPIO_1 ,WM8994_NUM_GPIO_REGS *2 , - &wm8994->gpio_regs); -if (ret <0 ) -dev_err (dev,"Failed to restore GPIO registers: %d\n" , ret); -/* Disable LDO pulldowns while the device is active */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
@@ -336,6 +298,11 @@ static int wm8994_resume(struct device *dev) wm8994->suspended = false;return 0 ; + +err_enable: +regulator_bulk_disable (wm8994->num_supplies, wm8994->supplies); + + return ret; }#endif
@@ -361,11 +328,6 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) }#endif -static struct regmap_config wm8994_regmap_config = { - .reg_bits =16 , - .val_bits =16 , -}; -/* * Instantiate the generic non-control parts of the device. */
@@ -594,6 +556,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) {struct wm8994 *wm8994; +struct regmap_config *regmap_config;int ret; wm8994 =devm_kzalloc (&i2c->dev,sizeof (struct wm8994 ),GFP_KERNEL );
@@ -605,7 +568,22 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, wm8994->irq = i2c->irq; wm8994->type = id->driver_data; - wm8994->regmap =regmap_init_i2c (i2c, &wm8994_regmap_config); +switch (wm8994->type) { +case WM1811 : + regmap_config = &wm1811_regmap_config; +break ; +case WM8994 : + regmap_config = &wm8994_regmap_config; +break ; +case WM8958 : + regmap_config = &wm8958_regmap_config; +break ; +default : +dev_err (wm8994->dev,"Unknown device type %d\n" , wm8994->type); +return -EINVAL ; + } + + wm8994->regmap =regmap_init_i2c (i2c, regmap_config);if (IS_ERR (wm8994->regmap)) { ret =PTR_ERR (wm8994->regmap); dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
include/linux/mfd/wm8994/core.h +0 -2
@@ -70,8 +70,6 @@ struct wm8994 {/* Used over suspend/resume */ bool suspended; -u16 ldo_regs[WM8994_NUM_LDO_REGS ]; -u16 gpio_regs[WM8994_NUM_GPIO_REGS ];struct regulator_dev *dbvdd;int num_supplies;
Signature · 1 line
1.7.7.3
Re: [PATCH 8/8] mfd: Enable register cache for wm8994 devices
Quoted 3 lines · Mark Brown
As part of this we provide information about the registers that exist in the device to the regmap core, drop the small amount of cache that the core had been using and let regmap do the sync.
Oh, and I forgot that this one depends on a regmap patch (regmap: Track if the register cache is dirty and suppress unneeded syncs). I've rebuilt the branch with the appropriate merge in it.
PATCH 1/1 mfd: Convert wm8994 to use generic regmap irq_chip
In reply to Mark BrownFactor out the irq_chip implementation, substantially reducing the code size for the driver.
--- drivers/mfd/Kconfig | 1 + drivers/mfd/wm8994-irq.c | 196 +++++++-------------------------------- include/linux/mfd/wm8994/core.h | 3 +- 3 files changed, 35 insertions(+), 165 deletions(-)
drivers/mfd/Kconfig +1 -0
@@ -477,6 +477,7 @@ config MFD_WM8994 bool "Support Wolfson Microelectronics WM8994" select MFD_CORE select REGMAP_I2C + select REGMAP_IRQ depends on I2C=y && GENERIC_HARDIRQS help The WM8994 is a highly integrated hi-fi CODEC designed for
drivers/mfd/wm8994-irq.c +33 -163
307 lines not on this page · raw message
include/linux/mfd/wm8994/core.h +1 -2
@@ -65,8 +65,7 @@ struct wm8994 {int irq_base;int irq; -u16 irq_masks_cur[WM8994_NUM_IRQ_REGS ]; -u16 irq_masks_cache[WM8994_NUM_IRQ_REGS ]; +struct regmap_irq_chip_data *irq_data;/* Used over suspend/resume */ bool suspended;
Signature · 1 line
1.7.7.3
Hi Mark,
Quoted 14 lines · Mark Brown
The following patch series (and pull request) contains a bunch of updates I've previously posted for wm8994 but which haven't been merged plus a big update adding register cache support for the wm8994 driver which hasn't previously been posted. As there's a matching update for the ASoC driver for WM8994 removing the copy of the register cache there it'd be great if it were possible to merge this via the ASoC tree.
I've also got one more patch which depends on this lot converting the IRQ controller over to use the generic regmap IRQ controller which I'll post as well - that also depends on this series as the regmap interrupt controller relies on the register cache - so I'd also like to either pull the same branch into the regmap tree or merge both this and the regmap IRQ stuff via ASoC.
Quoted 2 lines
This seems like the easiest route from the point of view of bisection and cross tree issues - does that all sound OK to you?
Yes, that sounds good. Please add my:
to this patchset.
Cheers,
Samuel.
Signature · 2 lines
Intel Open Source Technology Centre http://oss.intel.com/